@jackuait/blok 0.4.1-beta.4 → 0.4.1-beta.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.
- package/README.md +136 -17
- package/codemod/README.md +16 -0
- package/codemod/migrate-editorjs-to-blok.js +868 -92
- package/codemod/test.js +682 -77
- package/dist/blok.mjs +5 -2
- package/dist/chunks/blok-B5qs7C5l.mjs +12838 -0
- package/dist/chunks/i18next-CugVlwWp.mjs +1292 -0
- package/dist/chunks/i18next-loader-CTrK3HzG.mjs +43 -0
- package/dist/{index-XWGz4gev.mjs → chunks/index-DDpzQn-0.mjs} +2 -2
- package/dist/chunks/inline-tool-convert-RBcopmCh.mjs +1988 -0
- package/dist/chunks/messages-2434tVOK.mjs +47 -0
- package/dist/chunks/messages-3DcCwXMF.mjs +47 -0
- package/dist/chunks/messages-4kMwVAKY.mjs +47 -0
- package/dist/chunks/messages-57uL5htT.mjs +47 -0
- package/dist/chunks/messages-76-iJV9Q.mjs +47 -0
- package/dist/chunks/messages-8p86Eyf2.mjs +47 -0
- package/dist/chunks/messages-BBX0p0Pi.mjs +47 -0
- package/dist/chunks/messages-BCm2eudQ.mjs +47 -0
- package/dist/chunks/messages-BFiUomgG.mjs +47 -0
- package/dist/chunks/messages-BIPNHHAV.mjs +47 -0
- package/dist/chunks/messages-BUlwu9mo.mjs +47 -0
- package/dist/chunks/messages-BX-DPa-z.mjs +47 -0
- package/dist/chunks/messages-BextV3Qh.mjs +47 -0
- package/dist/chunks/messages-BiPSFlUG.mjs +47 -0
- package/dist/chunks/messages-BiXe9G-O.mjs +47 -0
- package/dist/chunks/messages-Bl5z_Igo.mjs +47 -0
- package/dist/chunks/messages-BnsE97ku.mjs +47 -0
- package/dist/chunks/messages-BoO8gsVD.mjs +47 -0
- package/dist/chunks/messages-BqWaOGMn.mjs +47 -0
- package/dist/chunks/messages-BqkL2_Ro.mjs +47 -0
- package/dist/chunks/messages-BvCkXKX-.mjs +47 -0
- package/dist/chunks/messages-C6tbPLoj.mjs +47 -0
- package/dist/chunks/messages-CA6T3-gQ.mjs +47 -0
- package/dist/chunks/messages-CFFPFdWP.mjs +47 -0
- package/dist/chunks/messages-CFrKE-TN.mjs +47 -0
- package/dist/chunks/messages-CHz8VlG-.mjs +47 -0
- package/dist/chunks/messages-CLixzySl.mjs +47 -0
- package/dist/chunks/messages-CV7OM_qk.mjs +47 -0
- package/dist/chunks/messages-CXHt3eCC.mjs +47 -0
- package/dist/chunks/messages-CbmsBrB0.mjs +47 -0
- package/dist/chunks/messages-Ceo1KtFx.mjs +47 -0
- package/dist/chunks/messages-Cm0LJLtB.mjs +47 -0
- package/dist/chunks/messages-CmymP_Ar.mjs +47 -0
- package/dist/chunks/messages-D0ohMB5H.mjs +47 -0
- package/dist/chunks/messages-D3GrDwXh.mjs +47 -0
- package/dist/chunks/messages-D3vTzIpL.mjs +47 -0
- package/dist/chunks/messages-D5WeksbV.mjs +47 -0
- package/dist/chunks/messages-DGaab4EP.mjs +47 -0
- package/dist/chunks/messages-DKha57ZU.mjs +47 -0
- package/dist/chunks/messages-DOaujgMW.mjs +47 -0
- package/dist/chunks/messages-DVbPLd_0.mjs +47 -0
- package/dist/chunks/messages-D_FCyfW6.mjs +47 -0
- package/dist/chunks/messages-Dd5iZN3c.mjs +47 -0
- package/dist/chunks/messages-DehM7135.mjs +47 -0
- package/dist/chunks/messages-Dg1OHftD.mjs +47 -0
- package/dist/chunks/messages-Di6Flq-b.mjs +47 -0
- package/dist/chunks/messages-Dqhhex6e.mjs +47 -0
- package/dist/chunks/messages-DueVe0F1.mjs +47 -0
- package/dist/chunks/messages-Dx3eFwI0.mjs +47 -0
- package/dist/chunks/messages-FOtiUoKl.mjs +47 -0
- package/dist/chunks/messages-FTOZNhRD.mjs +47 -0
- package/dist/chunks/messages-IQxGfQIV.mjs +47 -0
- package/dist/chunks/messages-JF2fzCkK.mjs +47 -0
- package/dist/chunks/messages-MOGl7I5v.mjs +47 -0
- package/dist/chunks/messages-QgYhPL-3.mjs +47 -0
- package/dist/chunks/messages-WYWIbQwo.mjs +47 -0
- package/dist/chunks/messages-a6A_LgDv.mjs +47 -0
- package/dist/chunks/messages-bSf31LJi.mjs +47 -0
- package/dist/chunks/messages-diGozhTn.mjs +47 -0
- package/dist/chunks/messages-er-kd-VO.mjs +47 -0
- package/dist/chunks/messages-ez3w5NBn.mjs +47 -0
- package/dist/chunks/messages-f3uXjegd.mjs +47 -0
- package/dist/chunks/messages-ohwI1UGv.mjs +47 -0
- package/dist/chunks/messages-p9BZJaFV.mjs +47 -0
- package/dist/chunks/messages-qIQ4L4rw.mjs +47 -0
- package/dist/chunks/messages-qWkXPggi.mjs +47 -0
- package/dist/chunks/messages-w5foGze_.mjs +47 -0
- package/dist/full.mjs +50 -0
- package/dist/locales.mjs +227 -0
- package/dist/messages-2434tVOK.mjs +47 -0
- package/dist/messages-3DcCwXMF.mjs +47 -0
- package/dist/messages-4kMwVAKY.mjs +47 -0
- package/dist/messages-57uL5htT.mjs +47 -0
- package/dist/messages-76-iJV9Q.mjs +47 -0
- package/dist/messages-8p86Eyf2.mjs +47 -0
- package/dist/messages-BBX0p0Pi.mjs +47 -0
- package/dist/messages-BCm2eudQ.mjs +47 -0
- package/dist/messages-BFiUomgG.mjs +47 -0
- package/dist/messages-BIPNHHAV.mjs +47 -0
- package/dist/messages-BUlwu9mo.mjs +47 -0
- package/dist/messages-BX-DPa-z.mjs +47 -0
- package/dist/messages-BextV3Qh.mjs +47 -0
- package/dist/messages-BiPSFlUG.mjs +47 -0
- package/dist/messages-BiXe9G-O.mjs +47 -0
- package/dist/messages-Bl5z_Igo.mjs +47 -0
- package/dist/messages-BnsE97ku.mjs +47 -0
- package/dist/messages-BoO8gsVD.mjs +47 -0
- package/dist/messages-BqWaOGMn.mjs +47 -0
- package/dist/messages-BqkL2_Ro.mjs +47 -0
- package/dist/messages-BvCkXKX-.mjs +47 -0
- package/dist/messages-C6tbPLoj.mjs +47 -0
- package/dist/messages-CA6T3-gQ.mjs +47 -0
- package/dist/messages-CFFPFdWP.mjs +47 -0
- package/dist/messages-CFrKE-TN.mjs +47 -0
- package/dist/messages-CHz8VlG-.mjs +47 -0
- package/dist/messages-CLixzySl.mjs +47 -0
- package/dist/messages-CV7OM_qk.mjs +47 -0
- package/dist/messages-CXHt3eCC.mjs +47 -0
- package/dist/messages-CbmsBrB0.mjs +47 -0
- package/dist/messages-Ceo1KtFx.mjs +47 -0
- package/dist/messages-Cm0LJLtB.mjs +47 -0
- package/dist/messages-CmymP_Ar.mjs +47 -0
- package/dist/messages-D0ohMB5H.mjs +47 -0
- package/dist/messages-D3GrDwXh.mjs +47 -0
- package/dist/messages-D3vTzIpL.mjs +47 -0
- package/dist/messages-D5WeksbV.mjs +47 -0
- package/dist/messages-DGaab4EP.mjs +47 -0
- package/dist/messages-DKha57ZU.mjs +47 -0
- package/dist/messages-DOaujgMW.mjs +47 -0
- package/dist/messages-DVbPLd_0.mjs +47 -0
- package/dist/messages-D_FCyfW6.mjs +47 -0
- package/dist/messages-Dd5iZN3c.mjs +47 -0
- package/dist/messages-DehM7135.mjs +47 -0
- package/dist/messages-Dg1OHftD.mjs +47 -0
- package/dist/messages-Di6Flq-b.mjs +47 -0
- package/dist/messages-Dqhhex6e.mjs +47 -0
- package/dist/messages-DueVe0F1.mjs +47 -0
- package/dist/messages-Dx3eFwI0.mjs +47 -0
- package/dist/messages-FOtiUoKl.mjs +47 -0
- package/dist/messages-FTOZNhRD.mjs +47 -0
- package/dist/messages-IQxGfQIV.mjs +47 -0
- package/dist/messages-JF2fzCkK.mjs +47 -0
- package/dist/messages-MOGl7I5v.mjs +47 -0
- package/dist/messages-QgYhPL-3.mjs +47 -0
- package/dist/messages-WYWIbQwo.mjs +47 -0
- package/dist/messages-a6A_LgDv.mjs +47 -0
- package/dist/messages-bSf31LJi.mjs +47 -0
- package/dist/messages-diGozhTn.mjs +47 -0
- package/dist/messages-er-kd-VO.mjs +47 -0
- package/dist/messages-ez3w5NBn.mjs +47 -0
- package/dist/messages-f3uXjegd.mjs +47 -0
- package/dist/messages-ohwI1UGv.mjs +47 -0
- package/dist/messages-p9BZJaFV.mjs +47 -0
- package/dist/messages-qIQ4L4rw.mjs +47 -0
- package/dist/messages-qWkXPggi.mjs +47 -0
- package/dist/messages-w5foGze_.mjs +47 -0
- package/dist/tools.mjs +3073 -0
- package/dist/vendor.LICENSE.txt +26 -225
- package/package.json +49 -23
- package/src/blok.ts +267 -0
- package/src/components/__module.ts +139 -0
- package/src/components/block/api.ts +155 -0
- package/src/components/block/index.ts +1427 -0
- package/src/components/block-tunes/block-tune-delete.ts +51 -0
- package/src/components/blocks.ts +338 -0
- package/src/components/constants/data-attributes.ts +342 -0
- package/src/components/constants.ts +76 -0
- package/src/components/core.ts +392 -0
- package/src/components/dom.ts +773 -0
- package/src/components/domIterator.ts +189 -0
- package/src/components/errors/critical.ts +5 -0
- package/src/components/events/BlockChanged.ts +16 -0
- package/src/components/events/BlockHovered.ts +21 -0
- package/src/components/events/BlockSettingsClosed.ts +12 -0
- package/src/components/events/BlockSettingsOpened.ts +12 -0
- package/src/components/events/BlokMobileLayoutToggled.ts +15 -0
- package/src/components/events/FakeCursorAboutToBeToggled.ts +17 -0
- package/src/components/events/FakeCursorHaveBeenSet.ts +17 -0
- package/src/components/events/HistoryStateChanged.ts +19 -0
- package/src/components/events/RedactorDomChanged.ts +14 -0
- package/src/components/events/index.ts +46 -0
- package/src/components/flipper.ts +481 -0
- package/src/components/i18n/i18next-loader.ts +84 -0
- package/src/components/i18n/lightweight-i18n.ts +86 -0
- package/src/components/i18n/locales/TRANSLATION_GUIDELINES.md +113 -0
- package/src/components/i18n/locales/am/messages.json +44 -0
- package/src/components/i18n/locales/ar/messages.json +44 -0
- package/src/components/i18n/locales/az/messages.json +44 -0
- package/src/components/i18n/locales/bg/messages.json +44 -0
- package/src/components/i18n/locales/bn/messages.json +44 -0
- package/src/components/i18n/locales/bs/messages.json +44 -0
- package/src/components/i18n/locales/cs/messages.json +44 -0
- package/src/components/i18n/locales/da/messages.json +44 -0
- package/src/components/i18n/locales/de/messages.json +44 -0
- package/src/components/i18n/locales/dv/messages.json +44 -0
- package/src/components/i18n/locales/el/messages.json +44 -0
- package/src/components/i18n/locales/en/messages.json +44 -0
- package/src/components/i18n/locales/es/messages.json +44 -0
- package/src/components/i18n/locales/et/messages.json +44 -0
- package/src/components/i18n/locales/fa/messages.json +44 -0
- package/src/components/i18n/locales/fi/messages.json +44 -0
- package/src/components/i18n/locales/fil/messages.json +44 -0
- package/src/components/i18n/locales/fr/messages.json +44 -0
- package/src/components/i18n/locales/gu/messages.json +44 -0
- package/src/components/i18n/locales/he/messages.json +44 -0
- package/src/components/i18n/locales/hi/messages.json +44 -0
- package/src/components/i18n/locales/hr/messages.json +44 -0
- package/src/components/i18n/locales/hu/messages.json +44 -0
- package/src/components/i18n/locales/hy/messages.json +44 -0
- package/src/components/i18n/locales/id/messages.json +44 -0
- package/src/components/i18n/locales/index.ts +225 -0
- package/src/components/i18n/locales/it/messages.json +44 -0
- package/src/components/i18n/locales/ja/messages.json +44 -0
- package/src/components/i18n/locales/ka/messages.json +44 -0
- package/src/components/i18n/locales/km/messages.json +44 -0
- package/src/components/i18n/locales/kn/messages.json +44 -0
- package/src/components/i18n/locales/ko/messages.json +44 -0
- package/src/components/i18n/locales/ku/messages.json +44 -0
- package/src/components/i18n/locales/lo/messages.json +44 -0
- package/src/components/i18n/locales/lt/messages.json +44 -0
- package/src/components/i18n/locales/lv/messages.json +44 -0
- package/src/components/i18n/locales/mk/messages.json +44 -0
- package/src/components/i18n/locales/ml/messages.json +44 -0
- package/src/components/i18n/locales/mn/messages.json +44 -0
- package/src/components/i18n/locales/mr/messages.json +44 -0
- package/src/components/i18n/locales/ms/messages.json +44 -0
- package/src/components/i18n/locales/my/messages.json +44 -0
- package/src/components/i18n/locales/ne/messages.json +44 -0
- package/src/components/i18n/locales/nl/messages.json +44 -0
- package/src/components/i18n/locales/no/messages.json +44 -0
- package/src/components/i18n/locales/pa/messages.json +44 -0
- package/src/components/i18n/locales/pl/messages.json +44 -0
- package/src/components/i18n/locales/ps/messages.json +44 -0
- package/src/components/i18n/locales/pt/messages.json +44 -0
- package/src/components/i18n/locales/ro/messages.json +44 -0
- package/src/components/i18n/locales/ru/messages.json +44 -0
- package/src/components/i18n/locales/sd/messages.json +44 -0
- package/src/components/i18n/locales/si/messages.json +44 -0
- package/src/components/i18n/locales/sk/messages.json +44 -0
- package/src/components/i18n/locales/sl/messages.json +44 -0
- package/src/components/i18n/locales/sq/messages.json +44 -0
- package/src/components/i18n/locales/sr/messages.json +44 -0
- package/src/components/i18n/locales/sv/messages.json +44 -0
- package/src/components/i18n/locales/sw/messages.json +44 -0
- package/src/components/i18n/locales/ta/messages.json +44 -0
- package/src/components/i18n/locales/te/messages.json +44 -0
- package/src/components/i18n/locales/th/messages.json +44 -0
- package/src/components/i18n/locales/tr/messages.json +44 -0
- package/src/components/i18n/locales/ug/messages.json +44 -0
- package/src/components/i18n/locales/uk/messages.json +44 -0
- package/src/components/i18n/locales/ur/messages.json +44 -0
- package/src/components/i18n/locales/vi/messages.json +44 -0
- package/src/components/i18n/locales/yi/messages.json +44 -0
- package/src/components/i18n/locales/zh/messages.json +44 -0
- package/src/components/icons/index.ts +242 -0
- package/src/components/inline-tools/inline-tool-bold.ts +2213 -0
- package/src/components/inline-tools/inline-tool-convert.ts +141 -0
- package/src/components/inline-tools/inline-tool-italic.ts +500 -0
- package/src/components/inline-tools/inline-tool-link.ts +539 -0
- package/src/components/modules/api/blocks.ts +363 -0
- package/src/components/modules/api/caret.ts +125 -0
- package/src/components/modules/api/events.ts +51 -0
- package/src/components/modules/api/history.ts +73 -0
- package/src/components/modules/api/i18n.ts +33 -0
- package/src/components/modules/api/index.ts +39 -0
- package/src/components/modules/api/inlineToolbar.ts +33 -0
- package/src/components/modules/api/listeners.ts +56 -0
- package/src/components/modules/api/notifier.ts +46 -0
- package/src/components/modules/api/readonly.ts +39 -0
- package/src/components/modules/api/sanitizer.ts +30 -0
- package/src/components/modules/api/saver.ts +52 -0
- package/src/components/modules/api/selection.ts +48 -0
- package/src/components/modules/api/styles.ts +72 -0
- package/src/components/modules/api/toolbar.ts +79 -0
- package/src/components/modules/api/tools.ts +16 -0
- package/src/components/modules/api/tooltip.ts +67 -0
- package/src/components/modules/api/ui.ts +36 -0
- package/src/components/modules/blockEvents.ts +1375 -0
- package/src/components/modules/blockManager.ts +1348 -0
- package/src/components/modules/blockSelection.ts +708 -0
- package/src/components/modules/caret.ts +853 -0
- package/src/components/modules/crossBlockSelection.ts +329 -0
- package/src/components/modules/dragManager.ts +1141 -0
- package/src/components/modules/history.ts +1098 -0
- package/src/components/modules/i18n.ts +325 -0
- package/src/components/modules/index.ts +139 -0
- package/src/components/modules/modificationsObserver.ts +147 -0
- package/src/components/modules/paste.ts +1092 -0
- package/src/components/modules/readonly.ts +136 -0
- package/src/components/modules/rectangleSelection.ts +668 -0
- package/src/components/modules/renderer.ts +155 -0
- package/src/components/modules/saver.ts +283 -0
- package/src/components/modules/toolbar/blockSettings.ts +776 -0
- package/src/components/modules/toolbar/index.ts +1311 -0
- package/src/components/modules/toolbar/inline.ts +956 -0
- package/src/components/modules/tools.ts +589 -0
- package/src/components/modules/ui.ts +1179 -0
- package/src/components/polyfills.ts +113 -0
- package/src/components/selection.ts +1189 -0
- package/src/components/tools/base.ts +274 -0
- package/src/components/tools/block.ts +291 -0
- package/src/components/tools/collection.ts +67 -0
- package/src/components/tools/factory.ts +85 -0
- package/src/components/tools/inline.ts +71 -0
- package/src/components/tools/tune.ts +33 -0
- package/src/components/ui/toolbox.ts +497 -0
- package/src/components/utils/announcer.ts +205 -0
- package/src/components/utils/api.ts +20 -0
- package/src/components/utils/bem.ts +26 -0
- package/src/components/utils/blocks.ts +284 -0
- package/src/components/utils/caret.ts +1067 -0
- package/src/components/utils/data-model-transform.ts +382 -0
- package/src/components/utils/events.ts +117 -0
- package/src/components/utils/keyboard.ts +60 -0
- package/src/components/utils/listeners.ts +296 -0
- package/src/components/utils/mutations.ts +39 -0
- package/src/components/utils/notifier/draw.ts +190 -0
- package/src/components/utils/notifier/index.ts +66 -0
- package/src/components/utils/notifier/types.ts +1 -0
- package/src/components/utils/notifier.ts +77 -0
- package/src/components/utils/placeholder.ts +140 -0
- package/src/components/utils/popover/components/hint/hint.const.ts +10 -0
- package/src/components/utils/popover/components/hint/hint.ts +46 -0
- package/src/components/utils/popover/components/hint/index.ts +6 -0
- package/src/components/utils/popover/components/popover-header/index.ts +2 -0
- package/src/components/utils/popover/components/popover-header/popover-header.const.ts +8 -0
- package/src/components/utils/popover/components/popover-header/popover-header.ts +80 -0
- package/src/components/utils/popover/components/popover-header/popover-header.types.ts +14 -0
- package/src/components/utils/popover/components/popover-item/index.ts +13 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.const.ts +50 -0
- package/src/components/utils/popover/components/popover-item/popover-item-default/popover-item-default.ts +666 -0
- package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.const.ts +14 -0
- package/src/components/utils/popover/components/popover-item/popover-item-html/popover-item-html.ts +136 -0
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.const.ts +20 -0
- package/src/components/utils/popover/components/popover-item/popover-item-separator/popover-item-separator.ts +117 -0
- package/src/components/utils/popover/components/popover-item/popover-item.ts +187 -0
- package/src/components/utils/popover/components/search-input/index.ts +2 -0
- package/src/components/utils/popover/components/search-input/search-input.const.ts +8 -0
- package/src/components/utils/popover/components/search-input/search-input.ts +181 -0
- package/src/components/utils/popover/components/search-input/search-input.types.ts +30 -0
- package/src/components/utils/popover/index.ts +13 -0
- package/src/components/utils/popover/popover-abstract.ts +448 -0
- package/src/components/utils/popover/popover-desktop.ts +643 -0
- package/src/components/utils/popover/popover-inline.ts +338 -0
- package/src/components/utils/popover/popover-mobile.ts +201 -0
- package/src/components/utils/popover/popover.const.ts +81 -0
- package/src/components/utils/popover/utils/popover-states-history.ts +72 -0
- package/src/components/utils/promise-queue.ts +43 -0
- package/src/components/utils/sanitizer.ts +537 -0
- package/src/components/utils/scroll-locker.ts +87 -0
- package/src/components/utils/shortcut.ts +231 -0
- package/src/components/utils/shortcuts.ts +113 -0
- package/src/components/utils/tools.ts +105 -0
- package/src/components/utils/tooltip.ts +642 -0
- package/src/components/utils/tw.ts +241 -0
- package/src/components/utils.ts +1081 -0
- package/src/env.d.ts +13 -0
- package/src/full.ts +69 -0
- package/src/locales.ts +51 -0
- package/src/stories/Block.stories.ts +498 -0
- package/src/stories/EditorModes.stories.ts +505 -0
- package/src/stories/Header.stories.ts +137 -0
- package/src/stories/InlineToolbar.stories.ts +498 -0
- package/src/stories/List.stories.ts +259 -0
- package/src/stories/Notifier.stories.ts +340 -0
- package/src/stories/Paragraph.stories.ts +112 -0
- package/src/stories/Placeholder.stories.ts +319 -0
- package/src/stories/Popover.stories.ts +844 -0
- package/src/stories/Selection.stories.ts +250 -0
- package/src/stories/StubBlock.stories.ts +156 -0
- package/src/stories/Toolbar.stories.ts +223 -0
- package/src/stories/Toolbox.stories.ts +166 -0
- package/src/stories/Tooltip.stories.ts +198 -0
- package/src/stories/helpers.ts +463 -0
- package/src/styles/main.css +123 -0
- package/src/tools/header/index.ts +570 -0
- package/src/tools/index.ts +38 -0
- package/src/tools/list/index.ts +1803 -0
- package/src/tools/paragraph/index.ts +411 -0
- package/src/tools/stub/index.ts +107 -0
- package/src/types-internal/blok-modules.d.ts +87 -0
- package/src/types-internal/html-janitor.d.ts +28 -0
- package/src/types-internal/module-config.d.ts +11 -0
- package/src/variants/all-locales.ts +155 -0
- package/src/variants/blok-maximum.ts +20 -0
- package/src/variants/blok-minimum.ts +243 -0
- package/types/api/blocks.d.ts +1 -1
- package/types/api/i18n.d.ts +5 -3
- package/types/api/selection.d.ts +6 -0
- package/types/api/styles.d.ts +23 -10
- package/types/configs/blok-config.d.ts +29 -0
- package/types/configs/i18n-config.d.ts +52 -2
- package/types/configs/i18n-dictionary.d.ts +16 -90
- package/types/data-attributes.d.ts +169 -0
- package/types/data-formats/output-data.d.ts +15 -0
- package/types/full.d.ts +80 -0
- package/types/index.d.ts +9 -12
- package/types/locales.d.ts +59 -0
- package/types/tools/adapters/inline-tool-adapter.d.ts +10 -0
- package/types/tools/block-tool.d.ts +9 -0
- package/types/tools/header.d.ts +18 -0
- package/types/tools/index.d.ts +1 -0
- package/types/tools/list.d.ts +91 -0
- package/types/tools/paragraph.d.ts +71 -0
- package/types/tools/tool-settings.d.ts +16 -2
- package/types/tools/tool.d.ts +6 -0
- package/types/tools-entry.d.ts +49 -0
- package/types/utils/popover/popover-item.d.ts +6 -5
- package/dist/blok-B870U2fw.mjs +0 -25803
- package/dist/blok.umd.js +0 -181
package/codemod/test.js
CHANGED
|
@@ -5,7 +5,16 @@
|
|
|
5
5
|
const {
|
|
6
6
|
applyTransforms,
|
|
7
7
|
ensureBlokImport,
|
|
8
|
+
ensureToolsImport,
|
|
9
|
+
splitBlokImports,
|
|
10
|
+
normalizeKey,
|
|
11
|
+
flattenI18nDictionary,
|
|
12
|
+
transformI18nConfig,
|
|
13
|
+
removeI18nMessages,
|
|
14
|
+
I18N_KEY_MAPPINGS,
|
|
8
15
|
BUNDLED_TOOLS,
|
|
16
|
+
INLINE_TOOLS,
|
|
17
|
+
ALL_TOOLS,
|
|
9
18
|
IMPORT_TRANSFORMS,
|
|
10
19
|
TYPE_TRANSFORMS,
|
|
11
20
|
CLASS_NAME_TRANSFORMS,
|
|
@@ -40,28 +49,128 @@ function assertEqual(actual, expected, message = '') {
|
|
|
40
49
|
|
|
41
50
|
console.log('\n📦 Import Transformations\n');
|
|
42
51
|
|
|
43
|
-
test('transforms @editorjs/editorjs import', () => {
|
|
52
|
+
test('transforms @editorjs/editorjs default import to named import', () => {
|
|
44
53
|
const input = `import EditorJS from '@editorjs/editorjs';`;
|
|
45
54
|
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
46
|
-
assertEqual(result, `import
|
|
55
|
+
assertEqual(result, `import { Blok } from '@jackuait/blok';`);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('transforms @editorjs/editorjs aliased default import', () => {
|
|
59
|
+
const input = `import Editor from '@editorjs/editorjs';`;
|
|
60
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
61
|
+
assertEqual(result, `import { Blok as Editor } from '@jackuait/blok';`);
|
|
47
62
|
});
|
|
48
63
|
|
|
49
64
|
test('transforms require statement', () => {
|
|
50
65
|
const input = `const EditorJS = require('@editorjs/editorjs');`;
|
|
51
66
|
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
52
|
-
assertEqual(result, `const EditorJS = require('@jackuait/blok');`);
|
|
67
|
+
assertEqual(result, `const EditorJS = require('@jackuait/blok').Blok;`);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('transforms namespace import to named import', () => {
|
|
71
|
+
const input = `import * as EditorJS from '@editorjs/editorjs';`;
|
|
72
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
73
|
+
assertEqual(result, `import { Blok as EditorJS } from '@jackuait/blok';`);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('transforms destructured default require', () => {
|
|
77
|
+
const input = `const { default: EditorJS } = require('@editorjs/editorjs');`;
|
|
78
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
79
|
+
assertEqual(result, `const { Blok: EditorJS } = require('@jackuait/blok');`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('transforms dynamic import', () => {
|
|
83
|
+
const input = `const Editor = await import('@editorjs/editorjs');`;
|
|
84
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
85
|
+
assertEqual(result, `const Editor = await import('@jackuait/blok').then(m => ({ default: m.Blok }));`);
|
|
53
86
|
});
|
|
54
87
|
|
|
55
|
-
test('transforms
|
|
88
|
+
test('transforms dynamic import with .then(m => m.default) pattern', () => {
|
|
89
|
+
const input = `import('@editorjs/editorjs').then(m => m.default);`;
|
|
90
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
91
|
+
assertEqual(result, `import('@jackuait/blok').then(m => m.Blok);`);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('transforms type-only default import', () => {
|
|
95
|
+
const input = `import type EditorJS from '@editorjs/editorjs';`;
|
|
96
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
97
|
+
assertEqual(result, `import type { Blok as EditorJS } from '@jackuait/blok';`);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('transforms @editorjs/header import to named import', () => {
|
|
56
101
|
const input = `import Header from '@editorjs/header';`;
|
|
57
102
|
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
58
|
-
assertEqual(result,
|
|
103
|
+
assertEqual(result, `import { Header } from '@jackuait/blok';\n`);
|
|
59
104
|
});
|
|
60
105
|
|
|
61
|
-
test('transforms @editorjs/paragraph import', () => {
|
|
106
|
+
test('transforms @editorjs/paragraph import to named import', () => {
|
|
62
107
|
const input = `import Paragraph from '@editorjs/paragraph';`;
|
|
63
108
|
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
64
|
-
assertEqual(result,
|
|
109
|
+
assertEqual(result, `import { Paragraph } from '@jackuait/blok';\n`);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('transforms @editorjs/list import to named import', () => {
|
|
113
|
+
const input = `import List from '@editorjs/list';`;
|
|
114
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
115
|
+
assertEqual(result, `import { List } from '@jackuait/blok';\n`);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Combined default + named import tests
|
|
119
|
+
test('transforms combined default + named import', () => {
|
|
120
|
+
const input = `import EditorJS, { EditorConfig } from '@editorjs/editorjs';`;
|
|
121
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
122
|
+
assertEqual(result, `import { Blok, EditorConfig } from '@jackuait/blok';`);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('transforms aliased combined default + named import', () => {
|
|
126
|
+
const input = `import Editor, { EditorConfig } from '@editorjs/editorjs';`;
|
|
127
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
128
|
+
assertEqual(result, `import { Blok as Editor, EditorConfig } from '@jackuait/blok';`);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Re-export tests
|
|
132
|
+
test('transforms default re-export as named', () => {
|
|
133
|
+
const input = `export { default as Editor } from '@editorjs/editorjs';`;
|
|
134
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
135
|
+
assertEqual(result, `export { Blok as Editor } from '@jackuait/blok';`);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('transforms default re-export', () => {
|
|
139
|
+
const input = `export { default } from '@editorjs/editorjs';`;
|
|
140
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
141
|
+
assertEqual(result, `export { Blok } from '@jackuait/blok';`);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Dynamic import with destructuring
|
|
145
|
+
test('transforms destructured dynamic import', () => {
|
|
146
|
+
const input = `const { default: Editor } = await import('@editorjs/editorjs');`;
|
|
147
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
148
|
+
assertEqual(result, `const { Blok: Editor } = await import('@jackuait/blok');`);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Tool require statements
|
|
152
|
+
test('transforms Header require statement', () => {
|
|
153
|
+
const input = `const Header = require('@editorjs/header');`;
|
|
154
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
155
|
+
assertEqual(result, `const { Header } = require('@jackuait/blok');`);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('transforms aliased Header require statement', () => {
|
|
159
|
+
const input = `const MyHeader = require('@editorjs/header');`;
|
|
160
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
161
|
+
assertEqual(result, `const { Header: MyHeader } = require('@jackuait/blok');`);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('transforms Paragraph require statement', () => {
|
|
165
|
+
const input = `const Paragraph = require('@editorjs/paragraph');`;
|
|
166
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
167
|
+
assertEqual(result, `const { Paragraph } = require('@jackuait/blok');`);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('transforms List require statement', () => {
|
|
171
|
+
const input = `const List = require('@editorjs/list');`;
|
|
172
|
+
const { result } = applyTransforms(input, IMPORT_TRANSFORMS);
|
|
173
|
+
assertEqual(result, `const { List } = require('@jackuait/blok');`);
|
|
65
174
|
});
|
|
66
175
|
|
|
67
176
|
// ============================================================================
|
|
@@ -193,7 +302,7 @@ test('transforms .ce-popover class', () => {
|
|
|
193
302
|
test('transforms .ce-popover--opened class', () => {
|
|
194
303
|
const input = `.ce-popover--opened { display: block; }`;
|
|
195
304
|
const { result } = applyTransforms(input, CSS_CLASS_TRANSFORMS);
|
|
196
|
-
assertEqual(result, `[data-blok-popover
|
|
305
|
+
assertEqual(result, `[data-blok-popover-opened="true"] { display: block; }`);
|
|
197
306
|
});
|
|
198
307
|
|
|
199
308
|
test('transforms .ce-popover__container class', () => {
|
|
@@ -292,22 +401,40 @@ test('transforms getElementById call', () => {
|
|
|
292
401
|
|
|
293
402
|
console.log('\n🔧 Tool Config Transformations\n');
|
|
294
403
|
|
|
295
|
-
test('transforms class: Header to class:
|
|
296
|
-
const input = `{ class: Header, config: {} }`;
|
|
404
|
+
test('transforms class: Blok.Header to class: Header', () => {
|
|
405
|
+
const input = `{ class: Blok.Header, config: {} }`;
|
|
406
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
407
|
+
assertEqual(result, `{ class: Header, config: {} }`);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test('transforms class: Blok.Paragraph to class: Paragraph', () => {
|
|
411
|
+
const input = `{ class: Blok.Paragraph, config: {} }`;
|
|
412
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
413
|
+
assertEqual(result, `{ class: Paragraph, config: {} }`);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
test('transforms standalone Blok.Paragraph reference', () => {
|
|
417
|
+
const input = `tools: { paragraph: Blok.Paragraph, header: Blok.Header }`;
|
|
297
418
|
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
298
|
-
assertEqual(result, `{
|
|
419
|
+
assertEqual(result, `tools: { paragraph: Paragraph, header: Header }`);
|
|
299
420
|
});
|
|
300
421
|
|
|
301
|
-
test('transforms class:
|
|
302
|
-
const input = `{ class:
|
|
422
|
+
test('transforms class: Blok.List to class: List', () => {
|
|
423
|
+
const input = `{ class: Blok.List, config: {} }`;
|
|
303
424
|
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
304
|
-
assertEqual(result, `{ class:
|
|
425
|
+
assertEqual(result, `{ class: List, config: {} }`);
|
|
305
426
|
});
|
|
306
427
|
|
|
307
|
-
test('transforms standalone
|
|
308
|
-
const input = `tools: {
|
|
428
|
+
test('transforms standalone Blok.List reference', () => {
|
|
429
|
+
const input = `tools: { list: Blok.List }`;
|
|
309
430
|
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
310
|
-
assertEqual(result, `tools: {
|
|
431
|
+
assertEqual(result, `tools: { list: List }`);
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
test('does not transform ListConfig or ListItem', () => {
|
|
435
|
+
const input = `import { ListConfig, ListItem } from './types';`;
|
|
436
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
437
|
+
assertEqual(result, `import { ListConfig, ListItem } from './types';`);
|
|
311
438
|
});
|
|
312
439
|
|
|
313
440
|
// ============================================================================
|
|
@@ -347,8 +474,9 @@ const editor = new EditorJS({
|
|
|
347
474
|
if (!result.includes("holder: 'blok'")) {
|
|
348
475
|
throw new Error('Holder not transformed');
|
|
349
476
|
}
|
|
350
|
-
|
|
351
|
-
|
|
477
|
+
// Header is imported as named import, class: Header stays as-is (not Blok.Header anymore)
|
|
478
|
+
if (!result.includes('class: Header')) {
|
|
479
|
+
throw new Error('Tool class should remain Header (named import)');
|
|
352
480
|
}
|
|
353
481
|
});
|
|
354
482
|
|
|
@@ -365,116 +493,105 @@ test('does not transform unrelated EditorJS-like strings', () => {
|
|
|
365
493
|
|
|
366
494
|
console.log('\n📥 Ensure Blok Import\n');
|
|
367
495
|
|
|
368
|
-
test('adds
|
|
496
|
+
test('adds Header import when Header is used with no existing import', () => {
|
|
369
497
|
const input = `const editor = new Blok({
|
|
370
|
-
tools: { header:
|
|
498
|
+
tools: { header: Header }
|
|
371
499
|
});`;
|
|
372
500
|
const { result, changed } = ensureBlokImport(input);
|
|
373
501
|
assertEqual(changed, true, 'Should indicate change');
|
|
374
|
-
assertEqual(result.includes("import
|
|
502
|
+
assertEqual(result.includes("import { Header } from '@jackuait/blok';"), true, 'Should add Header import');
|
|
375
503
|
});
|
|
376
504
|
|
|
377
|
-
test('adds
|
|
505
|
+
test('adds tool imports after existing imports', () => {
|
|
378
506
|
const input = `import React from 'react';
|
|
379
507
|
import { useState } from 'react';
|
|
380
508
|
|
|
381
509
|
const editor = new Blok({
|
|
382
|
-
tools: { header:
|
|
510
|
+
tools: { header: Header }
|
|
383
511
|
});`;
|
|
384
512
|
const { result, changed } = ensureBlokImport(input);
|
|
385
513
|
assertEqual(changed, true, 'Should indicate change');
|
|
386
|
-
// Check that
|
|
387
|
-
const
|
|
514
|
+
// Check that import is added after existing imports
|
|
515
|
+
const headerImportIndex = result.indexOf("import { Header } from '@jackuait/blok';");
|
|
388
516
|
const lastReactImportIndex = result.indexOf("import { useState } from 'react';");
|
|
389
|
-
assertEqual(
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
test('adds Blok to named-only import from @jackuait/blok', () => {
|
|
393
|
-
const input = `import { BlokConfig } from '@jackuait/blok';
|
|
394
|
-
|
|
395
|
-
const config: BlokConfig = {
|
|
396
|
-
tools: { header: Blok.Header }
|
|
397
|
-
};`;
|
|
398
|
-
const { result, changed } = ensureBlokImport(input);
|
|
399
|
-
assertEqual(changed, true, 'Should indicate change');
|
|
400
|
-
assertEqual(result.includes("import Blok, { BlokConfig } from '@jackuait/blok';"), true, 'Should add Blok default import');
|
|
517
|
+
assertEqual(headerImportIndex > lastReactImportIndex, true, 'Header import should be after existing imports');
|
|
401
518
|
});
|
|
402
519
|
|
|
403
|
-
test('adds
|
|
404
|
-
const input = `import
|
|
520
|
+
test('adds missing tools to existing @jackuait/blok import', () => {
|
|
521
|
+
const input = `import { Blok } from '@jackuait/blok';
|
|
405
522
|
|
|
406
|
-
const
|
|
407
|
-
tools: { header:
|
|
408
|
-
};`;
|
|
523
|
+
const editor = new Blok({
|
|
524
|
+
tools: { header: Header }
|
|
525
|
+
});`;
|
|
409
526
|
const { result, changed } = ensureBlokImport(input);
|
|
410
527
|
assertEqual(changed, true, 'Should indicate change');
|
|
411
|
-
assertEqual(result.includes(
|
|
528
|
+
assertEqual(result.includes('Header, Blok'), true, 'Should add Header to existing import');
|
|
412
529
|
});
|
|
413
530
|
|
|
414
|
-
test('adds
|
|
415
|
-
const input = `import
|
|
531
|
+
test('adds multiple missing tools to existing import', () => {
|
|
532
|
+
const input = `import { Blok } from '@jackuait/blok';
|
|
416
533
|
|
|
417
|
-
const editor = new
|
|
418
|
-
tools: { header:
|
|
534
|
+
const editor = new Blok({
|
|
535
|
+
tools: { header: Header, paragraph: Paragraph }
|
|
419
536
|
});`;
|
|
420
537
|
const { result, changed } = ensureBlokImport(input);
|
|
421
538
|
assertEqual(changed, true, 'Should indicate change');
|
|
422
|
-
assertEqual(result.includes(
|
|
539
|
+
assertEqual(result.includes('Header'), true, 'Should include Header');
|
|
540
|
+
assertEqual(result.includes('Paragraph'), true, 'Should include Paragraph');
|
|
423
541
|
});
|
|
424
542
|
|
|
425
|
-
test('does not modify when
|
|
426
|
-
const input = `import Blok from '@jackuait/blok';
|
|
543
|
+
test('does not modify when tools are already imported', () => {
|
|
544
|
+
const input = `import { Blok, Header } from '@jackuait/blok';
|
|
427
545
|
|
|
428
546
|
const editor = new Blok({
|
|
429
|
-
tools: { header:
|
|
547
|
+
tools: { header: Header }
|
|
430
548
|
});`;
|
|
431
549
|
const { result, changed } = ensureBlokImport(input);
|
|
432
550
|
assertEqual(changed, false, 'Should not indicate change');
|
|
433
551
|
assertEqual(result, input, 'Content should be unchanged');
|
|
434
552
|
});
|
|
435
553
|
|
|
436
|
-
test('does not modify when
|
|
437
|
-
const input = `import
|
|
554
|
+
test('does not modify when no bundled tools are used', () => {
|
|
555
|
+
const input = `import { Blok } from '@jackuait/blok';
|
|
438
556
|
|
|
439
|
-
const editor = new Blok({
|
|
440
|
-
tools: { header: Blok.Header }
|
|
441
|
-
});`;
|
|
557
|
+
const editor = new Blok({});`;
|
|
442
558
|
const { result, changed } = ensureBlokImport(input);
|
|
443
|
-
assertEqual(changed, false, 'Should not indicate change');
|
|
559
|
+
assertEqual(changed, false, 'Should not indicate change when no tools used');
|
|
444
560
|
assertEqual(result, input, 'Content should be unchanged');
|
|
445
561
|
});
|
|
446
562
|
|
|
447
|
-
test('
|
|
448
|
-
const input = `
|
|
449
|
-
|
|
450
|
-
|
|
563
|
+
test('detects Paragraph usage', () => {
|
|
564
|
+
const input = `const editor = new Blok({
|
|
565
|
+
tools: { paragraph: Paragraph }
|
|
566
|
+
});`;
|
|
451
567
|
const { result, changed } = ensureBlokImport(input);
|
|
452
|
-
assertEqual(changed,
|
|
453
|
-
assertEqual(result,
|
|
568
|
+
assertEqual(changed, true, 'Should detect Paragraph');
|
|
569
|
+
assertEqual(result.includes("import { Paragraph } from '@jackuait/blok';"), true, 'Should add Paragraph import');
|
|
454
570
|
});
|
|
455
571
|
|
|
456
|
-
test('detects
|
|
572
|
+
test('detects List usage', () => {
|
|
457
573
|
const input = `const editor = new Blok({
|
|
458
|
-
tools: {
|
|
574
|
+
tools: { list: List }
|
|
459
575
|
});`;
|
|
460
576
|
const { result, changed } = ensureBlokImport(input);
|
|
461
|
-
assertEqual(changed, true, 'Should detect
|
|
462
|
-
assertEqual(result.includes("import
|
|
577
|
+
assertEqual(changed, true, 'Should detect List');
|
|
578
|
+
assertEqual(result.includes("import { List } from '@jackuait/blok';"), true, 'Should add List import');
|
|
463
579
|
});
|
|
464
580
|
|
|
465
|
-
test('handles multiple
|
|
581
|
+
test('handles multiple tool usage', () => {
|
|
466
582
|
const input = `const editor = new Blok({
|
|
467
583
|
tools: {
|
|
468
|
-
header:
|
|
469
|
-
paragraph:
|
|
584
|
+
header: Header,
|
|
585
|
+
paragraph: Paragraph
|
|
470
586
|
}
|
|
471
587
|
});`;
|
|
472
588
|
const { result, changed } = ensureBlokImport(input);
|
|
473
|
-
assertEqual(changed, true, 'Should detect multiple
|
|
474
|
-
assertEqual(result.includes(
|
|
589
|
+
assertEqual(changed, true, 'Should detect multiple tools');
|
|
590
|
+
assertEqual(result.includes('Header'), true, 'Should add Header import');
|
|
591
|
+
assertEqual(result.includes('Paragraph'), true, 'Should add Paragraph import');
|
|
475
592
|
});
|
|
476
593
|
|
|
477
|
-
test('full migration adds
|
|
594
|
+
test('full migration adds imports for bundled tools', () => {
|
|
478
595
|
// This simulates a complete migration from EditorJS with bundled tools
|
|
479
596
|
const input = `import EditorJS from '@editorjs/editorjs';
|
|
480
597
|
import Header from '@editorjs/header';
|
|
@@ -499,10 +616,498 @@ const editor = new EditorJS({
|
|
|
499
616
|
result = applyTransforms(result, TOOL_CONFIG_TRANSFORMS).result;
|
|
500
617
|
result = ensureBlokImport(result).result;
|
|
501
618
|
|
|
502
|
-
// After transformation, should have
|
|
619
|
+
// After transformation, should have @jackuait/blok imports
|
|
503
620
|
assertEqual(result.includes("from '@jackuait/blok'"), true, 'Should have @jackuait/blok import');
|
|
504
|
-
|
|
505
|
-
assertEqual(result.includes('class:
|
|
621
|
+
// With named exports, tools are imported directly, not as Blok.Header
|
|
622
|
+
assertEqual(result.includes('class: Header'), true, 'Should use Header (named import)');
|
|
623
|
+
assertEqual(result.includes('class: Paragraph'), true, 'Should use Paragraph (named import)');
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
// ============================================================================
|
|
627
|
+
// i18n Transformation Tests
|
|
628
|
+
// ============================================================================
|
|
629
|
+
|
|
630
|
+
console.log('\n🌐 i18n Transformations\n');
|
|
631
|
+
|
|
632
|
+
test('flattenI18nDictionary flattens simple nested object', () => {
|
|
633
|
+
const input = {
|
|
634
|
+
ui: {
|
|
635
|
+
toolbar: {
|
|
636
|
+
toolbox: {
|
|
637
|
+
Add: 'Добавить'
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
const result = flattenI18nDictionary(input);
|
|
643
|
+
// 'ui.toolbar.toolbox.Add' is mapped to 'toolbox.addBelow' by I18N_KEY_MAPPINGS
|
|
644
|
+
assertEqual(result['toolbox.addBelow'], 'Добавить');
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
test('flattenI18nDictionary flattens deeply nested object', () => {
|
|
648
|
+
const input = {
|
|
649
|
+
ui: {
|
|
650
|
+
blockTunes: {
|
|
651
|
+
toggler: {
|
|
652
|
+
'Drag to move': 'Перетащите'
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
const result = flattenI18nDictionary(input);
|
|
658
|
+
// Keys are normalized to camelCase and mapped to simplified keys
|
|
659
|
+
assertEqual(result['blockSettings.dragToMove'], 'Перетащите');
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
test('flattenI18nDictionary handles multiple namespaces', () => {
|
|
663
|
+
const input = {
|
|
664
|
+
toolNames: {
|
|
665
|
+
Text: 'Текст',
|
|
666
|
+
Bold: 'Жирный'
|
|
667
|
+
},
|
|
668
|
+
tools: {
|
|
669
|
+
link: {
|
|
670
|
+
'Add a link': 'Добавить ссылку'
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
const result = flattenI18nDictionary(input);
|
|
675
|
+
// Keys are normalized to camelCase
|
|
676
|
+
assertEqual(result['toolNames.text'], 'Текст');
|
|
677
|
+
assertEqual(result['toolNames.bold'], 'Жирный');
|
|
678
|
+
assertEqual(result['tools.link.addALink'], 'Добавить ссылку');
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
test('flattenI18nDictionary applies key mappings', () => {
|
|
682
|
+
const input = {
|
|
683
|
+
ui: {
|
|
684
|
+
blockTunes: {
|
|
685
|
+
toggler: {
|
|
686
|
+
'Click to tune': 'Нажмите для настройки'
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
const result = flattenI18nDictionary(input);
|
|
692
|
+
// 'Click to tune' should be mapped to 'blockSettings.clickToOpenMenu'
|
|
693
|
+
assertEqual(result['blockSettings.clickToOpenMenu'], 'Нажмите для настройки');
|
|
694
|
+
assertEqual(result['ui.blockTunes.toggler.Click to tune'], undefined);
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
test('flattenI18nDictionary handles empty object', () => {
|
|
698
|
+
const result = flattenI18nDictionary({});
|
|
699
|
+
assertEqual(Object.keys(result).length, 0);
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
test('transformI18nConfig transforms nested i18n config in JS', () => {
|
|
703
|
+
const input = `const editor = new Blok({
|
|
704
|
+
i18n: {
|
|
705
|
+
messages: {
|
|
706
|
+
toolNames: {
|
|
707
|
+
Text: "Текст",
|
|
708
|
+
Bold: "Жирный"
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
});`;
|
|
713
|
+
const { result, changed } = transformI18nConfig(input);
|
|
714
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
715
|
+
// Keys are normalized to camelCase
|
|
716
|
+
assertEqual(result.includes('"toolNames.text": "Текст"'), true, 'Should have flattened toolNames.text');
|
|
717
|
+
assertEqual(result.includes('"toolNames.bold": "Жирный"'), true, 'Should have flattened toolNames.bold');
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
test('transformI18nConfig transforms deeply nested messages', () => {
|
|
721
|
+
const input = `const config = {
|
|
722
|
+
i18n: {
|
|
723
|
+
messages: {
|
|
724
|
+
ui: {
|
|
725
|
+
popover: {
|
|
726
|
+
Search: "Поиск",
|
|
727
|
+
"Nothing found": "Ничего не найдено"
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
};`;
|
|
733
|
+
const { result, changed } = transformI18nConfig(input);
|
|
734
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
735
|
+
// Keys are normalized to camelCase and mapped to simplified keys
|
|
736
|
+
assertEqual(result.includes('"popover.search": "Поиск"'), true, 'Should have flattened popover.search');
|
|
737
|
+
assertEqual(result.includes('"popover.nothingFound": "Ничего не найдено"'), true, 'Should have flattened popover.nothingFound');
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
test('transformI18nConfig does not change content without i18n config', () => {
|
|
741
|
+
const input = `const editor = new Blok({
|
|
742
|
+
holder: 'blok',
|
|
743
|
+
tools: {}
|
|
744
|
+
});`;
|
|
745
|
+
const { result, changed } = transformI18nConfig(input);
|
|
746
|
+
assertEqual(changed, false, 'Should not indicate change');
|
|
747
|
+
assertEqual(result, input, 'Content should be unchanged');
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
test('transformI18nConfig skips dynamic content with functions', () => {
|
|
751
|
+
const input = `const editor = new Blok({
|
|
752
|
+
i18n: {
|
|
753
|
+
messages: {
|
|
754
|
+
toolNames: {
|
|
755
|
+
Text: () => getTranslation('text')
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
});`;
|
|
760
|
+
const { result, changed } = transformI18nConfig(input);
|
|
761
|
+
assertEqual(changed, false, 'Should not transform dynamic content');
|
|
762
|
+
assertEqual(result, input, 'Content should be unchanged');
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
test('transformI18nConfig handles single quotes', () => {
|
|
766
|
+
const input = `const editor = new Blok({
|
|
767
|
+
i18n: {
|
|
768
|
+
messages: {
|
|
769
|
+
toolNames: {
|
|
770
|
+
Text: 'Текст'
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
});`;
|
|
775
|
+
const { result, changed } = transformI18nConfig(input);
|
|
776
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
777
|
+
// Keys are normalized to camelCase
|
|
778
|
+
assertEqual(result.includes('"toolNames.text": "Текст"'), true, 'Should have flattened key with value');
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
test('I18N_KEY_MAPPINGS contains expected mappings', () => {
|
|
782
|
+
// UI key mappings (values use simplified key format)
|
|
783
|
+
assertEqual(I18N_KEY_MAPPINGS['ui.blockTunes.toggler.Click to tune'], 'blockSettings.clickToOpenMenu');
|
|
784
|
+
assertEqual(I18N_KEY_MAPPINGS['ui.blockTunes.toggler.or drag to move'], 'blockSettings.dragToMove');
|
|
785
|
+
assertEqual(I18N_KEY_MAPPINGS['ui.toolbar.toolbox.Add'], 'toolbox.addBelow');
|
|
786
|
+
assertEqual(I18N_KEY_MAPPINGS['ui.inlineToolbar.converter.Convert to'], 'popover.convertTo');
|
|
787
|
+
assertEqual(I18N_KEY_MAPPINGS['ui.popover.Filter'], 'popover.search');
|
|
788
|
+
|
|
789
|
+
// Tool names mappings (values are now camelCase)
|
|
790
|
+
assertEqual(I18N_KEY_MAPPINGS['toolNames.Ordered List'], 'toolNames.numberedList');
|
|
791
|
+
assertEqual(I18N_KEY_MAPPINGS['toolNames.Unordered List'], 'toolNames.bulletedList');
|
|
792
|
+
|
|
793
|
+
// Tools messages mappings (values are now camelCase)
|
|
794
|
+
assertEqual(I18N_KEY_MAPPINGS['tools.stub.The block can not be displayed correctly'], 'tools.stub.blockCannotBeDisplayed');
|
|
795
|
+
|
|
796
|
+
// Block tunes mappings
|
|
797
|
+
assertEqual(I18N_KEY_MAPPINGS['blockTunes.delete.Delete'], 'blockSettings.delete');
|
|
798
|
+
|
|
799
|
+
// Removed keys (mapped to null)
|
|
800
|
+
assertEqual(I18N_KEY_MAPPINGS['blockTunes.moveUp.Move up'], null);
|
|
801
|
+
assertEqual(I18N_KEY_MAPPINGS['blockTunes.moveDown.Move down'], null);
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
test('flattenI18nDictionary applies tool name mappings', () => {
|
|
805
|
+
const input = {
|
|
806
|
+
toolNames: {
|
|
807
|
+
'Ordered List': 'Нумерованный список',
|
|
808
|
+
'Unordered List': 'Маркированный список',
|
|
809
|
+
},
|
|
810
|
+
};
|
|
811
|
+
const result = flattenI18nDictionary(input);
|
|
812
|
+
// Keys are mapped and normalized to camelCase
|
|
813
|
+
assertEqual(result['toolNames.numberedList'], 'Нумерованный список');
|
|
814
|
+
assertEqual(result['toolNames.bulletedList'], 'Маркированный список');
|
|
815
|
+
assertEqual(result['toolNames.Ordered List'], undefined);
|
|
816
|
+
assertEqual(result['toolNames.Unordered List'], undefined);
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
test('flattenI18nDictionary applies Filter to Search mapping', () => {
|
|
820
|
+
const input = {
|
|
821
|
+
ui: {
|
|
822
|
+
popover: {
|
|
823
|
+
Filter: 'Фильтр',
|
|
824
|
+
'Nothing found': 'Ничего не найдено',
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
};
|
|
828
|
+
const result = flattenI18nDictionary(input);
|
|
829
|
+
// Keys are mapped to simplified keys
|
|
830
|
+
assertEqual(result['popover.search'], 'Фильтр');
|
|
831
|
+
assertEqual(result['popover.nothingFound'], 'Ничего не найдено');
|
|
832
|
+
assertEqual(result['ui.popover.Filter'], undefined);
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
test('flattenI18nDictionary removes moveUp/moveDown keys', () => {
|
|
836
|
+
const input = {
|
|
837
|
+
blockTunes: {
|
|
838
|
+
delete: {
|
|
839
|
+
Delete: 'Удалить',
|
|
840
|
+
},
|
|
841
|
+
moveUp: {
|
|
842
|
+
'Move up': 'Переместить вверх',
|
|
843
|
+
},
|
|
844
|
+
moveDown: {
|
|
845
|
+
'Move down': 'Переместить вниз',
|
|
846
|
+
},
|
|
847
|
+
},
|
|
848
|
+
};
|
|
849
|
+
const result = flattenI18nDictionary(input);
|
|
850
|
+
// Keys are mapped to simplified keys, moveUp/moveDown are removed
|
|
851
|
+
assertEqual(result['blockSettings.delete'], 'Удалить');
|
|
852
|
+
assertEqual(result['blockTunes.moveUp.Move up'], undefined);
|
|
853
|
+
assertEqual(result['blockTunes.moveDown.Move down'], undefined);
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
test('flattenI18nDictionary applies stub message mapping', () => {
|
|
857
|
+
const input = {
|
|
858
|
+
tools: {
|
|
859
|
+
stub: {
|
|
860
|
+
'The block can not be displayed correctly': 'Блок не может быть отображен',
|
|
861
|
+
},
|
|
862
|
+
},
|
|
863
|
+
};
|
|
864
|
+
const result = flattenI18nDictionary(input);
|
|
865
|
+
// Key is mapped and normalized to camelCase
|
|
866
|
+
assertEqual(result['tools.stub.blockCannotBeDisplayed'], 'Блок не может быть отображен');
|
|
867
|
+
assertEqual(result['tools.stub.The block can not be displayed correctly'], undefined);
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
console.log('\n🔤 normalizeKey\n');
|
|
871
|
+
|
|
872
|
+
test('normalizeKey converts single word to lowercase', () => {
|
|
873
|
+
assertEqual(normalizeKey('toolNames.Text'), 'toolNames.text');
|
|
874
|
+
assertEqual(normalizeKey('toolNames.Bold'), 'toolNames.bold');
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
test('normalizeKey converts multi-word keys to camelCase', () => {
|
|
878
|
+
assertEqual(normalizeKey('popover.Nothing found'), 'popover.nothingFound');
|
|
879
|
+
assertEqual(normalizeKey('toolbox.Click to add below'), 'toolbox.clickToAddBelow');
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
test('normalizeKey handles keys with multiple spaces', () => {
|
|
883
|
+
assertEqual(normalizeKey('tools.stub.The block can not be displayed'), 'tools.stub.theBlockCanNotBeDisplayed');
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
test('normalizeKey preserves namespace segments', () => {
|
|
887
|
+
assertEqual(normalizeKey('blockSettings.Drag to move'), 'blockSettings.dragToMove');
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
console.log('\n🗑️ removeI18nMessages (--use-library-i18n)\n');
|
|
891
|
+
|
|
892
|
+
test('removeI18nMessages removes messages property from i18n config', () => {
|
|
893
|
+
const input = `const editor = new Blok({
|
|
894
|
+
i18n: {
|
|
895
|
+
messages: {
|
|
896
|
+
toolNames: {
|
|
897
|
+
Text: "Текст"
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
});`;
|
|
902
|
+
const { result, changed } = removeI18nMessages(input);
|
|
903
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
904
|
+
assertEqual(result.includes('messages'), false, 'Should not contain messages property');
|
|
905
|
+
assertEqual(result.includes('i18n: {}'), true, 'Should have empty i18n config');
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
test('removeI18nMessages preserves locale property', () => {
|
|
909
|
+
const input = `const editor = new Blok({
|
|
910
|
+
i18n: {
|
|
911
|
+
messages: {
|
|
912
|
+
toolNames: { Text: "Текст" }
|
|
913
|
+
},
|
|
914
|
+
locale: 'ru'
|
|
915
|
+
}
|
|
916
|
+
});`;
|
|
917
|
+
const { result, changed } = removeI18nMessages(input);
|
|
918
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
919
|
+
assertEqual(result.includes('messages'), false, 'Should not contain messages property');
|
|
920
|
+
assertEqual(result.includes("locale: 'ru'"), true, 'Should preserve locale property');
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
test('removeI18nMessages preserves direction property', () => {
|
|
924
|
+
const input = `const editor = new Blok({
|
|
925
|
+
i18n: {
|
|
926
|
+
direction: 'rtl',
|
|
927
|
+
messages: {
|
|
928
|
+
toolNames: { Text: "نص" }
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
});`;
|
|
932
|
+
const { result, changed } = removeI18nMessages(input);
|
|
933
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
934
|
+
assertEqual(result.includes('messages'), false, 'Should not contain messages property');
|
|
935
|
+
assertEqual(result.includes("direction: 'rtl'"), true, 'Should preserve direction property');
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
test('removeI18nMessages does not change content without messages', () => {
|
|
939
|
+
const input = `const editor = new Blok({
|
|
940
|
+
i18n: {
|
|
941
|
+
locale: 'ru'
|
|
942
|
+
}
|
|
943
|
+
});`;
|
|
944
|
+
const { result, changed } = removeI18nMessages(input);
|
|
945
|
+
assertEqual(changed, false, 'Should not indicate change');
|
|
946
|
+
assertEqual(result, input, 'Content should be unchanged');
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
test('removeI18nMessages does not change content without i18n', () => {
|
|
950
|
+
const input = `const editor = new Blok({
|
|
951
|
+
holder: 'blok',
|
|
952
|
+
tools: {}
|
|
953
|
+
});`;
|
|
954
|
+
const { result, changed } = removeI18nMessages(input);
|
|
955
|
+
assertEqual(changed, false, 'Should not indicate change');
|
|
956
|
+
assertEqual(result, input, 'Content should be unchanged');
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
// ============================================================================
|
|
960
|
+
// Modular Import Tests (Strategy 5)
|
|
961
|
+
// ============================================================================
|
|
962
|
+
|
|
963
|
+
console.log('\n📦 Modular Import Transformations (Strategy 5)\n');
|
|
964
|
+
|
|
965
|
+
test('ALL_TOOLS contains block and inline tools', () => {
|
|
966
|
+
assertEqual(ALL_TOOLS.includes('Header'), true, 'Should include Header');
|
|
967
|
+
assertEqual(ALL_TOOLS.includes('Paragraph'), true, 'Should include Paragraph');
|
|
968
|
+
assertEqual(ALL_TOOLS.includes('List'), true, 'Should include List');
|
|
969
|
+
assertEqual(ALL_TOOLS.includes('Bold'), true, 'Should include Bold');
|
|
970
|
+
assertEqual(ALL_TOOLS.includes('Italic'), true, 'Should include Italic');
|
|
971
|
+
assertEqual(ALL_TOOLS.includes('Link'), true, 'Should include Link');
|
|
972
|
+
assertEqual(ALL_TOOLS.includes('Convert'), true, 'Should include Convert');
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
test('splitBlokImports splits combined import with Blok and Header', () => {
|
|
976
|
+
const input = `import { Blok, Header } from '@jackuait/blok';`;
|
|
977
|
+
const { result, changed } = splitBlokImports(input);
|
|
978
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
979
|
+
assertEqual(result.includes("from '@jackuait/blok';"), true, 'Should have core import');
|
|
980
|
+
assertEqual(result.includes("from '@jackuait/blok/tools';"), true, 'Should have tools import');
|
|
981
|
+
assertEqual(result.includes('Blok'), true, 'Should include Blok');
|
|
982
|
+
assertEqual(result.includes('Header'), true, 'Should include Header');
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
test('splitBlokImports splits combined import with multiple tools', () => {
|
|
986
|
+
const input = `import { Blok, Header, Paragraph, Bold } from '@jackuait/blok';`;
|
|
987
|
+
const { result, changed } = splitBlokImports(input);
|
|
988
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
989
|
+
assertEqual(result.includes("import { Blok } from '@jackuait/blok';"), true, 'Should have core-only import');
|
|
990
|
+
assertEqual(result.includes("import { Header, Paragraph, Bold } from '@jackuait/blok/tools';"), true, 'Should have tools import');
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
test('splitBlokImports handles tools-only import', () => {
|
|
994
|
+
const input = `import { Header, Paragraph } from '@jackuait/blok';`;
|
|
995
|
+
const { result, changed } = splitBlokImports(input);
|
|
996
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
997
|
+
assertEqual(result.includes("import { Header, Paragraph } from '@jackuait/blok/tools';"), true, 'Should move to tools');
|
|
998
|
+
assertEqual(result.includes("from '@jackuait/blok';") && !result.includes("/tools"), false, 'Should not have empty core import');
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
test('splitBlokImports does not change core-only import', () => {
|
|
1002
|
+
const input = `import { Blok, BlokConfig } from '@jackuait/blok';`;
|
|
1003
|
+
const { result, changed } = splitBlokImports(input);
|
|
1004
|
+
assertEqual(changed, false, 'Should not indicate change');
|
|
1005
|
+
assertEqual(result, input, 'Content should be unchanged');
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
test('splitBlokImports handles aliased imports', () => {
|
|
1009
|
+
const input = `import { Blok, Header as MyHeader } from '@jackuait/blok';`;
|
|
1010
|
+
const { result, changed } = splitBlokImports(input);
|
|
1011
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
1012
|
+
assertEqual(result.includes("import { Blok } from '@jackuait/blok';"), true, 'Should have core import');
|
|
1013
|
+
assertEqual(result.includes("Header as MyHeader"), true, 'Should preserve alias');
|
|
1014
|
+
assertEqual(result.includes("@jackuait/blok/tools"), true, 'Should have tools import');
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
test('ensureToolsImport adds tools import when no import exists', () => {
|
|
1018
|
+
const input = `const editor = new Blok({
|
|
1019
|
+
tools: { header: Header }
|
|
1020
|
+
});`;
|
|
1021
|
+
const { result, changed } = ensureToolsImport(input);
|
|
1022
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
1023
|
+
assertEqual(result.includes("from '@jackuait/blok/tools';"), true, 'Should add tools import');
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
test('ensureToolsImport adds to existing /tools import', () => {
|
|
1027
|
+
const input = `import { Header } from '@jackuait/blok/tools';
|
|
1028
|
+
|
|
1029
|
+
const editor = new Blok({
|
|
1030
|
+
tools: { header: Header, paragraph: Paragraph }
|
|
1031
|
+
});`;
|
|
1032
|
+
const { result, changed } = ensureToolsImport(input);
|
|
1033
|
+
assertEqual(changed, true, 'Should indicate change');
|
|
1034
|
+
assertEqual(result.includes('Paragraph'), true, 'Should add Paragraph');
|
|
1035
|
+
assertEqual(result.includes("from '@jackuait/blok/tools';"), true, 'Should use tools path');
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
test('ensureToolsImport does not duplicate when tools are in main import', () => {
|
|
1039
|
+
const input = `import { Blok, Header } from '@jackuait/blok';
|
|
1040
|
+
|
|
1041
|
+
const editor = new Blok({
|
|
1042
|
+
tools: { header: Header }
|
|
1043
|
+
});`;
|
|
1044
|
+
const { result, changed } = ensureToolsImport(input);
|
|
1045
|
+
// Tools are in main import, will be moved by splitBlokImports later
|
|
1046
|
+
assertEqual(changed, false, 'Should not add duplicate');
|
|
1047
|
+
});
|
|
1048
|
+
|
|
1049
|
+
test('ensureToolsImport detects inline tools', () => {
|
|
1050
|
+
const input = `const editor = new Blok({
|
|
1051
|
+
tools: { bold: Bold, italic: Italic }
|
|
1052
|
+
});`;
|
|
1053
|
+
const { result, changed } = ensureToolsImport(input);
|
|
1054
|
+
assertEqual(changed, true, 'Should detect inline tools');
|
|
1055
|
+
assertEqual(result.includes('Bold'), true, 'Should add Bold');
|
|
1056
|
+
assertEqual(result.includes('Italic'), true, 'Should add Italic');
|
|
1057
|
+
assertEqual(result.includes("from '@jackuait/blok/tools';"), true, 'Should use tools path');
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
test('transforms Blok.Bold to Bold', () => {
|
|
1061
|
+
const input = `{ class: Blok.Bold, config: {} }`;
|
|
1062
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
1063
|
+
assertEqual(result, `{ class: Bold, config: {} }`);
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
test('transforms Blok.Italic to Italic', () => {
|
|
1067
|
+
const input = `{ class: Blok.Italic, config: {} }`;
|
|
1068
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
1069
|
+
assertEqual(result, `{ class: Italic, config: {} }`);
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
test('transforms Blok.Link to Link', () => {
|
|
1073
|
+
const input = `{ class: Blok.Link, config: {} }`;
|
|
1074
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
1075
|
+
assertEqual(result, `{ class: Link, config: {} }`);
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
test('transforms Blok.Convert to Convert', () => {
|
|
1079
|
+
const input = `{ class: Blok.Convert, config: {} }`;
|
|
1080
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
1081
|
+
assertEqual(result, `{ class: Convert, config: {} }`);
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
test('transforms standalone inline tool references', () => {
|
|
1085
|
+
const input = `tools: { bold: Blok.Bold, italic: Blok.Italic }`;
|
|
1086
|
+
const { result } = applyTransforms(input, TOOL_CONFIG_TRANSFORMS);
|
|
1087
|
+
assertEqual(result, `tools: { bold: Bold, italic: Italic }`);
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
test('full modular migration: old Blok import to new structure', () => {
|
|
1091
|
+
const input = `import { Blok, Header, Paragraph, Bold, Italic } from '@jackuait/blok';
|
|
1092
|
+
|
|
1093
|
+
const editor = new Blok({
|
|
1094
|
+
holder: 'blok',
|
|
1095
|
+
tools: {
|
|
1096
|
+
header: { class: Header },
|
|
1097
|
+
paragraph: { class: Paragraph },
|
|
1098
|
+
},
|
|
1099
|
+
inlineTools: {
|
|
1100
|
+
bold: { class: Bold },
|
|
1101
|
+
italic: { class: Italic },
|
|
1102
|
+
},
|
|
1103
|
+
});`;
|
|
1104
|
+
|
|
1105
|
+
// Apply splitBlokImports
|
|
1106
|
+
const { result: splitResult, changed } = splitBlokImports(input);
|
|
1107
|
+
|
|
1108
|
+
assertEqual(changed, true, 'Should split imports');
|
|
1109
|
+
assertEqual(splitResult.includes("import { Blok } from '@jackuait/blok';"), true, 'Should have core import');
|
|
1110
|
+
assertEqual(splitResult.includes("import { Header, Paragraph, Bold, Italic } from '@jackuait/blok/tools';"), true, 'Should have tools import');
|
|
506
1111
|
});
|
|
507
1112
|
|
|
508
1113
|
// ============================================================================
|