@kodaeditor/core 1.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.
Files changed (55) hide show
  1. package/LICENSE.md +83 -0
  2. package/README.md +94 -0
  3. package/THIRD-PARTY-LICENSES.txt +1811 -0
  4. package/dist/commands.d.ts +15 -0
  5. package/dist/docx-alignment.d.ts +14 -0
  6. package/dist/docx-breaks.d.ts +31 -0
  7. package/dist/docx-forms.d.ts +28 -0
  8. package/dist/docx-headers.d.ts +22 -0
  9. package/dist/docx-images.d.ts +41 -0
  10. package/dist/docx-import.d.ts +36 -0
  11. package/dist/docx-math.d.ts +18 -0
  12. package/dist/docx-styles.d.ts +53 -0
  13. package/dist/docx-symbols.d.ts +19 -0
  14. package/dist/docx-text-styles.d.ts +27 -0
  15. package/dist/editor.d.ts +372 -0
  16. package/dist/fallback.d.ts +13 -0
  17. package/dist/floatingToolbar.d.ts +7 -0
  18. package/dist/group-icons.d.ts +17 -0
  19. package/dist/i18n.d.ts +214 -0
  20. package/dist/icons.d.ts +1 -0
  21. package/dist/image-view.d.ts +27 -0
  22. package/dist/import-formats.d.ts +41 -0
  23. package/dist/index.d.ts +15 -0
  24. package/dist/kodaeditor-core.umd.cjs +1 -0
  25. package/dist/kodaeditor.js +1 -0
  26. package/dist/kodaeditor.umd.cjs +1 -0
  27. package/dist/license.d.ts +90 -0
  28. package/dist/markdown.d.ts +4 -0
  29. package/dist/menubar.d.ts +60 -0
  30. package/dist/offline-license.d.ts +36 -0
  31. package/dist/pagination.d.ts +11 -0
  32. package/dist/paste.d.ts +54 -0
  33. package/dist/pdf-import-cdn.d.ts +2 -0
  34. package/dist/pdf-import.d.ts +8 -0
  35. package/dist/print.d.ts +18 -0
  36. package/dist/rtf-images.d.ts +24 -0
  37. package/dist/schema.d.ts +14 -0
  38. package/dist/search.d.ts +17 -0
  39. package/dist/serialize.d.ts +20 -0
  40. package/dist/slashMenu.d.ts +8 -0
  41. package/dist/styles.d.ts +8 -0
  42. package/dist/table-split.d.ts +26 -0
  43. package/dist/table-view.d.ts +34 -0
  44. package/dist/tableColumnTrade.d.ts +15 -0
  45. package/dist/tableToolbar.d.ts +14 -0
  46. package/dist/toc-view.d.ts +23 -0
  47. package/dist/toolbar-editor.d.ts +89 -0
  48. package/dist/validate-signature.d.ts +64 -0
  49. package/dist/vendor/pdf.min.mjs +29 -0
  50. package/dist/vendor/pdf.worker.min.mjs +29 -0
  51. package/dist/vendor/xlsx.full.min.js +24 -0
  52. package/dist/web-component.d.ts +383 -0
  53. package/dist/xlsx-import-cdn.d.ts +1 -0
  54. package/dist/xlsx-import.d.ts +2 -0
  55. package/package.json +88 -0
@@ -0,0 +1,383 @@
1
+ import type { DocxImportResult } from './docx-import';
2
+ import { type Strings } from './i18n';
3
+ /**
4
+ * База класса. В браузере это HTMLElement, в среде без DOM - пустой класс.
5
+ *
6
+ * Нужно потому, что `class X extends HTMLElement` исполняется при ЗАГРУЗКЕ
7
+ * модуля, а не при создании элемента: без подмены сам факт
8
+ * `import '@kodaeditor/core'` падал с «HTMLElement is not defined» при
9
+ * серверном рендеринге (Next.js, Nuxt, SvelteKit импортируют модули хоста в
10
+ * Node). Регистрация <koda-editor> и без того выполняется только при наличии
11
+ * window - см. index.ts, - так что на сервере этот класс просто никогда не
12
+ * используется.
13
+ */
14
+ declare const ElementBase: typeof HTMLElement;
15
+ export declare class KodaEditorElement extends ElementBase {
16
+ static formAssociated: boolean;
17
+ private editor?;
18
+ private buttons;
19
+ private contentEl?;
20
+ private stringsValue;
21
+ private internals?;
22
+ private pendingValue?;
23
+ /** Словарь клиента, заданный свойством до монтирования. */
24
+ private pendingStrings?;
25
+ private suppressChange;
26
+ private fsKeyHandler?;
27
+ /**
28
+ * Номер цикла монтирования. Нужен, чтобы асинхронная проверка лицензии
29
+ * знала, тот ли редактор она застала: при реконсиляции во фреймворках
30
+ * элемент отключают и тут же подключают снова, и результаты проверок
31
+ * прошлых циклов приходили в уже новый редактор - водяные знаки копились
32
+ * (проверено: три знака после трёх циклов remove/append).
33
+ */
34
+ private mountGeneration;
35
+ /**
36
+ * Запасное поле формы для браузеров без ElementInternals.
37
+ *
38
+ * attachInternals появился в Safari только в 16.4 (март 2023), а корпоративные
39
+ * маки застревают на старых версиях macOS надолго. Там Shadow DOM есть, то
40
+ * есть редактор поднимается полноценно и откат на textarea НЕ срабатывает -
41
+ * а значение в форму не попадает, потому что некому его туда положить.
42
+ * Пользователь печатает, жмёт «Отправить», на сервер не уходит ничего. Тот же
43
+ * молчаливый класс, что и потерянный name в откате (исправлено 11.09.2026).
44
+ */
45
+ private shadowFormInput?;
46
+ private searchBar?;
47
+ private searchFindInput?;
48
+ constructor();
49
+ private selects;
50
+ private toolbarEditor?;
51
+ private menubar?;
52
+ private formatPainterArmed;
53
+ private readonly onSelectionMaybeChanged;
54
+ private readonly onPasteRich;
55
+ static get observedAttributes(): string[];
56
+ /**
57
+ * Реакция на смену атрибутов после монтирования.
58
+ *
59
+ * Раньше observedAttributes был объявлен, а самого коллбэка в пакете не было
60
+ * вовсе: интегратор менял placeholder или aria-label и получал молчаливое
61
+ * бездействие вместо заявленного спецификацией поведения.
62
+ *
63
+ * До монтирования значения подхватываются в connectedCallback, поэтому
64
+ * ранние вызовы (браузер дёргает коллбэк и при разборе разметки) игнорируем.
65
+ */
66
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
67
+ connectedCallback(): void;
68
+ disconnectedCallback(): void;
69
+ private buildToolbar;
70
+ private layoutId;
71
+ private layoutKey;
72
+ private getSavedLayout;
73
+ private saveLayout;
74
+ private clearLayout;
75
+ /** Токены текущей раскладки (для редактора). Дефолт - из TOOLBAR + выпадашки.
76
+ * Без 'style' (выпадашка «Абзац») - её заменяет галерея «Стили» в TOOLBAR;
77
+ * 'style' остаётся доступной в палитре карандаша. */
78
+ private defaultTokens;
79
+ /** Человекочитаемая подпись токена для диалога настройки. */
80
+ private tokenLabel;
81
+ /** Иконка токена (HTML svg) - для палитры/превью карандаша. '' если без иконки. */
82
+ private tokenIcon;
83
+ /** Все токены, доступные для добавления в палитре карандаша (без разделителя). */
84
+ private allTokens;
85
+ /**
86
+ * Разбор сохранённой раскладки. Поддерживает два формата (обратносовместимо):
87
+ * - строка токенов: "style | bold italic | export" (старый, конфиг интегратора)
88
+ * - JSON-массив LayoutEntry с группами (новый, карандаш) - начинается с '['
89
+ */
90
+ private parseLayout;
91
+ /** Нормализация одной записи раскладки из недоверенного JSON. */
92
+ private normalizeEntry;
93
+ /** Текущая раскладка как записи (для карандаша). Дефолт - плоский список токенов. */
94
+ private currentEntries;
95
+ /** Сериализовать раскладку: JSON если есть группы, иначе компактная строка токенов. */
96
+ private serializeEntries;
97
+ /** Сохранить раскладку (из карандаша) и пересобрать панель. */
98
+ private saveEntries;
99
+ private appendCustomizeButton;
100
+ /** Запуск редактора панели «карандаш» (drag-and-drop прямо на тулбаре). */
101
+ private openToolbarEditor;
102
+ /**
103
+ * Кнопка-группа: обложка + название + ▾, по клику раскрывает меню с вложенными
104
+ * кнопками. Сами кнопки внутри выполняют свои команды (как на панели).
105
+ */
106
+ private appendGroupButton;
107
+ /** Выпадающее меню кнопки-группы со вложенными кнопками. */
108
+ private openGroupMenu;
109
+ /** Выполнить действие редактора и обновить состояние тулбара. */
110
+ private menuRun;
111
+ /** Пункты меню «Таблица» - переиспользуются и в верхнем меню, и в контекстном. */
112
+ private tableMenuItems;
113
+ /** Декларативная структура верхнего меню. Действия переиспуют методы редактора. */
114
+ private buildMenus;
115
+ /** Контекстное меню по элементу под курсором (правый клик). */
116
+ private buildContextMenu;
117
+ private onContextMenu;
118
+ /** Вырезать/копировать через нативную команду (выделение редактора). */
119
+ private execEdit;
120
+ /** Запомнить формат текущей позиции и включить «кисть» (следующее выделение - применит). */
121
+ private armFormatPainter;
122
+ private disarmFormatPainter;
123
+ /** Анализ документа на типичные проблемы доступности (WCAG-ориентировочно). */
124
+ checkAccessibility(): {
125
+ issue: string;
126
+ count: number;
127
+ }[];
128
+ /** Диалог результатов проверки доступности. */
129
+ private openAccessibilityCheck;
130
+ private spellcheckOn;
131
+ /** Включить/выключить браузерную проверку орфографии (язык - из locale). */
132
+ setSpellcheck(on: boolean): void;
133
+ isSpellcheckOn(): boolean;
134
+ setPagination(on: boolean): void;
135
+ isPaginated(): boolean;
136
+ /** Строка диалога свойств: подпись + поле. */
137
+ private propRow;
138
+ private propSelect;
139
+ private propInput;
140
+ /**
141
+ * Word-подобная вставка таблицы: сетка с наведением (динамически расширяется
142
+ * до 20×20) + ручной ввод числа строк/столбцов для больших таблиц.
143
+ */
144
+ private openTableGridPicker;
145
+ /**
146
+ * Словарь интерфейса клиента: СВОЙ язык без нашего участия.
147
+ *
148
+ * Зачем: встроенных локалей две (en, ru), а редактор встраивают в системы,
149
+ * где с документами весь день работают люди, английского не знающие -
150
+ * госуслуги, банки, страховые, медицина. Держать в ядре словари всех рынков
151
+ * означало бы поддерживать их вечно и всё равно не угадать. Поэтому клиент
152
+ * может задать свой словарь сам: полный перевод или несколько переименованных
153
+ * кнопок.
154
+ *
155
+ * Два способа, оба читаются при монтировании (как и атрибут locale):
156
+ * - свойство: el.strings = { bold: 'Negrita', ... } ДО вставки в DOM;
157
+ * - атрибут strings-ref="id" -> <script type="application/json"> с тем же
158
+ * объектом; удобно для серверного рендера и разметки без JS.
159
+ *
160
+ * Переопределения накладываются ПОВЕРХ выбранной локали, поэтому переводить
161
+ * всё необязательно: незаданные ключи остаются как были. Тип Strings
162
+ * экспортируется пакетом, так что у клиента на TypeScript есть проверка имён.
163
+ */
164
+ set strings(overrides: Partial<Strings>);
165
+ get strings(): Strings;
166
+ /** Собрать переопределения из свойства и из strings-ref. Только строки. */
167
+ private collectStringOverrides;
168
+ /**
169
+ * Кладёт значение в форму там, где ElementInternals недоступен: скрытым
170
+ * полем с тем же именем. Ничего не делает, если internals есть (современные
171
+ * браузеры) или если имя не задано - без имени поле всё равно не отправится.
172
+ */
173
+ private syncFallbackFormValue;
174
+ /** Транзиентная подсказка внизу редактора (автоисчезает). */
175
+ private flashNotice;
176
+ /**
177
+ * Разделить ячейку как в Word. Объединённую - сразу разъединяем (понятное
178
+ * действие). Обычную - диалог «Столбцов × Строк».
179
+ */
180
+ private openSplitCellDialog;
181
+ /** Объединить ячейки; при одиночном выделении - понятная подсказка. */
182
+ private mergeCellsWithHint;
183
+ /** Каркас диалога свойств: backdrop + заголовок + строки + Отмена/Применить. */
184
+ private buildPropsDialog;
185
+ private openTablePropsDialog;
186
+ private openCellPropsDialog;
187
+ /** Доступные поля: из атрибута merge-fields (JSON) или дефолтный набор реквизитов. */
188
+ private getMergeFields;
189
+ /** Диалог вставки поля шаблона. */
190
+ private openMergeFieldPicker;
191
+ /** Публичный API: вставить поле шаблона программно. */
192
+ insertMergeField(key: string, label?: string): void;
193
+ /** Публичный API: HTML с полями, развёрнутыми в {{key}} (для ЭДО-подстановки). */
194
+ getMergeText(): string;
195
+ /** Диалог ввода текста сноски, затем вставка маркера. */
196
+ private openFootnotePrompt;
197
+ /** Публичный API: вставить сноску / получить тексты сносок / вставить оглавление. */
198
+ insertFootnote(text: string): void;
199
+ getFootnotes(): string[];
200
+ insertTableOfContents(): void;
201
+ /** Набор быстрых стилей: тип блока + интервалы + превью для галереи. */
202
+ private styleGallery;
203
+ /** Галерея стилей - выпадающая панель с превью каждого стиля. */
204
+ private openStyleGallery;
205
+ /** Диалог ввода комментария к выделению. */
206
+ private openCommentPrompt;
207
+ private onCommentClick;
208
+ /** Попап комментария: текст + кнопка «Разрешить». */
209
+ private openCommentPopup;
210
+ /** Публичный API комментариев. */
211
+ addComment(text: string, author?: string): string | null;
212
+ getComments(): {
213
+ id: string;
214
+ text: string;
215
+ author: string | null;
216
+ }[];
217
+ resolveComment(id: string): void;
218
+ setTrackChanges(on: boolean): void;
219
+ isTrackingChanges(): boolean;
220
+ markDeletion(): void;
221
+ acceptAllChanges(): void;
222
+ rejectAllChanges(): void;
223
+ getChangeCount(): {
224
+ insertions: number;
225
+ deletions: number;
226
+ };
227
+ private versionSeq;
228
+ private versionsKey;
229
+ private readVersions;
230
+ private writeVersions;
231
+ /** Сохранить снимок текущего документа как именованную версию. */
232
+ saveVersion(name?: string): void;
233
+ getVersions(): {
234
+ id: string;
235
+ name: string;
236
+ ts: number;
237
+ html: string;
238
+ }[];
239
+ restoreVersion(id: string): void;
240
+ deleteVersion(id: string): void;
241
+ /** Диалог истории версий: сохранить текущую, восстановить/удалить прошлые. */
242
+ private openVersionHistory;
243
+ /** Пересобирает панель из текущей раскладки (после сохранения/сброса). */
244
+ private rebuildToolbar;
245
+ /** Один токен спецификации `toolbar="..."` -> элемент панели. Неизвестный - пропуск. */
246
+ private appendToolbarToken;
247
+ /** Рендер одной записи панели (разделитель / контрол цвета / кнопка). */
248
+ private appendEntry;
249
+ private onToolbarKeydown;
250
+ private refreshToolbar;
251
+ /** Общий конструктор выпадашки панели. */
252
+ private makeSelect;
253
+ private buildStyleSelect;
254
+ private buildFontSelect;
255
+ private buildSizeSelect;
256
+ /** Кнопка выбора цвета (текст/выделение): иконка + скрытый input[type=color]. */
257
+ private buildColorControl;
258
+ /** Простой диалог ссылки (URL): ставит/снимает ссылку на выделении. */
259
+ private openLinkPrompt;
260
+ /**
261
+ * Диалог выбора режима импорта PDF: текст (редактируемо) / картинки (точный
262
+ * растр) / как PDF (встроить файл). Возвращает выбор или null (отмена).
263
+ */
264
+ private pickPdfMode;
265
+ /**
266
+ * Меню экспорта: PDF / Word / HTML / Markdown / TXT / CSV. Всё client-side -
267
+ * содержимое не уходит на сервер. Выбор формата вызывает нужный метод Editor.
268
+ */
269
+ private openExportPicker;
270
+ /**
271
+ * Чекер импорта: «Файл с компьютера» или «По ссылке (URL)». Оба пути -
272
+ * client-side: файл читается в браузере, URL загружается fetch-ом самого
273
+ * браузера (наш сервер не участвует).
274
+ */
275
+ private openImportPicker;
276
+ /**
277
+ * Импорт файла по URL (client-side fetch браузером). Картинки вставляются
278
+ * по ссылке напрямую (без скачивания - обходит CORS на отображение).
279
+ * Документы скачиваются в Blob и идут тем же путём, что файл с диска;
280
+ * PDF спрашивает режим (текст/картинки/встроить). Ошибки CORS/сети -
281
+ * понятное событие importerror.
282
+ */
283
+ importFromUrl(url: string): Promise<void>;
284
+ /** Единое событие об ошибке импорта. */
285
+ private emitImportError;
286
+ /**
287
+ * Показывает оверлей «Обработка…» поверх редактора на время долгой операции
288
+ * (парсинг PDF/конвертация). Возвращает функцию-скрывалку. Без него медленные
289
+ * импорты выглядят как «клик не сработал».
290
+ */
291
+ private showLoading;
292
+ private static readonly IMPORT_ACCEPT_ALL;
293
+ /**
294
+ * Открыть системный диалог выбора файла с заданным accept и импортировать
295
+ * выбранный файл. Используется и атомарными кнопками (Word/PDF/Excel/Текст),
296
+ * и общей кнопкой (полный accept).
297
+ */
298
+ private openFilePicker;
299
+ /**
300
+ * Общая обработка импортируемого файла: PDF - с выбором режима (текст/картинки/
301
+ * встроить), остальное - автодетект. Индикатор загрузки + события change/importerror.
302
+ */
303
+ private handleImportedFile;
304
+ /** Общая кнопка импорта «Файл с компьютера» (legacy): полный accept. */
305
+ private pickImportFile;
306
+ /**
307
+ * Публичный API: программный импорт .docx (File/ArrayBuffer). Возвращает
308
+ * предупреждения движка (неподдержанные стили, текст в текстовых полях
309
+ * и т.п.) - раньше терялись здесь молча (Promise<void>), хотя editor.ts
310
+ * их уже собирал; хост может их показать пользователю или проигнорировать.
311
+ */
312
+ importDocx(source: File | ArrayBuffer): Promise<DocxImportResult | undefined>;
313
+ /** Публичный API: импорт файла (.docx/.csv/.txt/.md/картинка) с автодетектом. */
314
+ importFile(file: File): Promise<void>;
315
+ /** Публичный API: экспорт в Markdown (скачивание .md). */
316
+ exportMarkdown(): void;
317
+ /** Публичный API: экспорт в HTML / TXT / CSV / Word (.doc). Client-side. */
318
+ exportHtml(): void;
319
+ exportText(): void;
320
+ exportCsv(): void;
321
+ exportWord(): void;
322
+ /** Публичный API: импорт PDF как картинок (страницы -> изображения). */
323
+ importPdfAsImages(file: File): Promise<void>;
324
+ /** Публичный API: встроить PDF «как есть» (iframe, client-side). */
325
+ importPdfAsEmbed(file: File): Promise<void>;
326
+ /** Публичный API: следующая вставка - только текст. */
327
+ armPlainPaste(): void;
328
+ /**
329
+ * Публичный API: вставка «богатого» буфера из companion-расширения
330
+ * (полный HTML + RTF в обход песочницы). Расширение зовёт этот метод
331
+ * напрямую или через DOM-событие `koda-paste-rich`.
332
+ */
333
+ pasteRich(html: string, rtf?: string): void;
334
+ /** Диалог вставки картинки: по ссылке/пути или загрузкой файла. */
335
+ private openImageDialog;
336
+ /**
337
+ * Загрузка картинки: на сервер клиента (upload-url) или встраивание base64.
338
+ *
339
+ * Две вещи, которых здесь раньше не было:
340
+ * - проверка типа и размера ДО отправки. Атрибут accept у поля выбора -
341
+ * только подсказка, перетаскивание его не спрашивает;
342
+ * - отказ сервера больше не подменяется тихо на data-URI. Раньше клиент,
343
+ * отклонивший файл на 20 МБ, получал ровно тот же файл, но внутри
344
+ * документа в base64: пользователь видел успех, а в базу уезжал
345
+ * многомегабайтный кусок. Если upload-url задан, встраивание base64 -
346
+ * это не «запасной путь», а тихая подмена договорённости.
347
+ */
348
+ private handleImageFile;
349
+ /** Вставка картинки в редактор (ProseMirror). */
350
+ private insertImageSmart;
351
+ private checkLicense;
352
+ /**
353
+ * Агрессивный демо-знак: диагональное замощение по всей канве (фон листа,
354
+ * растёт с документом и покрывает все страницы) + sticky-пилюля сверху для
355
+ * доступности. Не блокирует ввод (pointer-events:none / фон).
356
+ */
357
+ private applyDemoWatermark;
358
+ /** SVG-тайл с диагональным текстом знака → data-URI для background-image. */
359
+ private demoWatermarkUri;
360
+ getContent(): string;
361
+ setContent(html: string): void;
362
+ getJSON(): unknown;
363
+ /** Экспорт документа в PDF (печать средствами браузера, client-side). */
364
+ exportPdf(): void;
365
+ /** value - как у нативного поля: чтение/запись HTML. Работает с v-model. */
366
+ get value(): string;
367
+ set value(html: string);
368
+ /** Сброс формы (<form>.reset() или кнопка type=reset) - очищаем редактор. */
369
+ formResetCallback(): void;
370
+ /** Переключить полноэкранный режим (на весь экран, без сервера/прав). */
371
+ toggleFullscreen(): void;
372
+ /** Панель найти/заменить (скрыта по умолчанию). */
373
+ private buildSearchBar;
374
+ /** Показать/скрыть панель поиска. */
375
+ toggleSearch(show?: boolean): void;
376
+ }
377
+ /**
378
+ * Регистрирует <koda-editor>. Идемпотентно по конкретному тегу.
379
+ * Для произвольного тега используется анонимный подкласс - один класс
380
+ * нельзя зарегистрировать под двумя именами (define бросит ошибку).
381
+ */
382
+ export declare function defineKodaEditor(tag?: string): void;
383
+ export {};
@@ -0,0 +1 @@
1
+ export declare function xlsxToHtml(data: ArrayBuffer): Promise<string>;
@@ -0,0 +1,2 @@
1
+ /** .xlsx/.xls -> HTML (таблица на лист). */
2
+ export declare function xlsxToHtml(data: ArrayBuffer): Promise<string>;
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "@kodaeditor/core",
3
+ "version": "1.0.0",
4
+ "description": "WYSIWYG rich-text editor as a web component. Pastes Word, Excel and Google Docs content without losing tables, lists or formatting. Self-hosted, framework-agnostic.",
5
+ "keywords": [
6
+ "wysiwyg",
7
+ "rich-text-editor",
8
+ "editor",
9
+ "word-paste",
10
+ "docx",
11
+ "html-editor",
12
+ "prosemirror",
13
+ "web-component",
14
+ "custom-element",
15
+ "xlsx",
16
+ "pdf-import",
17
+ "self-hosted"
18
+ ],
19
+ "homepage": "https://kodaeditor.com",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/mynameisilhom/editoruz-core.git",
23
+ "directory": "packages/core"
24
+ },
25
+ "bugs": {
26
+ "email": "support@kodaeditor.com"
27
+ },
28
+ "type": "module",
29
+ "main": "./dist/kodaeditor.umd.cjs",
30
+ "module": "./dist/kodaeditor.js",
31
+ "types": "./dist/index.d.ts",
32
+ "//exports": "Два варианта поставки в ОДНОМ пакете, выбор за покупателем и без переписки с нами. По умолчанию (\".\") - полная сборка: всё внутри, ни одного обращения в сеть, это важнее веса для закрытых контуров. \"./light\" - сборка без pdf.js и xlsx (1,1 МБ вместо 3,1): их файлы лежат в \"./vendor\" и грузятся только когда пользователь реально открывает PDF или Excel. Оба варианта обфусцируются при публикации.",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/kodaeditor.js",
37
+ "require": "./dist/kodaeditor.umd.cjs"
38
+ },
39
+ "./light": {
40
+ "types": "./dist/index.d.ts",
41
+ "default": "./dist/kodaeditor-core.umd.cjs"
42
+ },
43
+ "./vendor/*": "./dist/vendor/*"
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "THIRD-PARTY-LICENSES.txt",
48
+ "LICENSE.md"
49
+ ],
50
+ "scripts": {
51
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
52
+ "build": "npm run clean && tsc -p tsconfig.json && vite build",
53
+ "build:split": "vite build --config vite.config.split.ts && node ../../scripts/copy-vendor.mjs",
54
+ "build:protected": "npm run build:split && node ../../scripts/obfuscate.mjs dist/kodaeditor-core.umd.cjs dist/kodaeditor-core.obf.umd.cjs",
55
+ "build:standalone-protected": "npm run build && node ../../scripts/obfuscate.mjs dist/kodaeditor.js dist/kodaeditor.js && node ../../scripts/obfuscate.mjs dist/kodaeditor.umd.cjs dist/kodaeditor.umd.cjs",
56
+ "typecheck": "tsc --noEmit",
57
+ "test": "vitest run",
58
+ "prepack": "npm run build:standalone-protected && npm run build:split && node ../../scripts/obfuscate.mjs dist/kodaeditor-core.umd.cjs dist/kodaeditor-core.umd.cjs && node -e \"require('fs').copyFileSync('../../LICENSE.md','LICENSE.md')\" && node ../../scripts/check-ssr-import.mjs",
59
+ "//postpack": "Возвращает ОБА варианта сборки читаемыми. Оба - потому что npm run build начинается с clean и стирает лёгкую сборку вместе с vendor: после упаковки в рабочем каталоге не оставалось того, что уехало в пакет, и \"./light\" переставал резолвиться локально. prepack обфусцирует dist ПРЯМО В РАБОЧЕМ КАТАЛОГЕ. Тарбол уже собран, на его содержимое это не влияет, но разработчик остаётся с нечитаемой сборкой и теряет время, не понимая почему. Возвращаем обычную сборку сразу, а не помним об этом.",
60
+ "postpack": "npm run build && npm run build:split"
61
+ },
62
+ "comment": "ВСЕ библиотеки ВСТРОЕНЫ в dist (один файл, inlineDynamicImports). Поэтому у пакета НЕТ runtime-зависимостей: npm i тарболла НЕ тянет ничего из npm/CDN. Сборочные либы - в devDependencies. build:protected/build:split - отдельный, сейчас НЕ используемый нигде путь поставки (лёгкий CDN-вариант без pdf.js/xlsx, грузит их с внешнего CDN vendor-хостинга) - ссылается на chayxonajon.uz, который больше не наш домен; не трогаем, не часть текущей npm-поставки. Для npm publish защищённость обеспечивает НОВЫЙ build:standalone-protected - обфусцирует именно те файлы (dist/kodaeditor.js, dist/kodaeditor.umd.cjs), на которые ссылаются main/module/exports; запускается автоматически через prepack перед npm pack/publish, поэтому руками вызывать не обязательно.",
63
+ "devDependencies": {
64
+ "@types/turndown": "^5.0.6",
65
+ "dompurify": "^3.4.15",
66
+ "javascript-obfuscator": "^5.7.0",
67
+ "jsdom": "^29.1.1",
68
+ "jszip": "^3.10.2",
69
+ "mammoth": "^1.12.0",
70
+ "marked": "^18.0.12",
71
+ "pdfjs-dist": "^6.0.227",
72
+ "prosemirror-commands": "^1.6.0",
73
+ "prosemirror-history": "^1.4.1",
74
+ "prosemirror-keymap": "^1.2.2",
75
+ "prosemirror-model": "^1.23.0",
76
+ "prosemirror-schema-basic": "^1.2.3",
77
+ "prosemirror-schema-list": "^1.4.1",
78
+ "prosemirror-state": "^1.4.3",
79
+ "prosemirror-tables": "^1.8.5",
80
+ "prosemirror-view": "^1.34.3",
81
+ "turndown": "^7.2.4",
82
+ "turndown-plugin-gfm": "^1.0.2",
83
+ "typescript": "^7.0.2",
84
+ "vitest": "^5.0.0",
85
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
86
+ },
87
+ "license": "SEE LICENSE IN LICENSE.md"
88
+ }