mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-23 08:48:01 +00:00
UBERF-8968: Get rid of prosemirror in transactor (#7746)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
0534c2b90e
commit
4ec92d94b7
common/config/rush
packages
platform
text-core
text
plugins
pods/server/src
rush.jsonserver-plugins
activity-resources
chunter-resources
controlled-documents-resources
gmail-resources
notification-resources
notification/src
telegram-resources
time-resources
tracker-resources
server
services/ses/pod-ses
workers/transactor
@ -1069,6 +1069,9 @@ importers:
|
||||
'@rush-temp/text':
|
||||
specifier: file:./projects/text.tgz
|
||||
version: file:projects/text.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(bufferutil@4.0.8)(esbuild@0.24.2)(prosemirror-inputrules@1.4.0)(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.34.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))(utf-8-validate@6.0.4)
|
||||
'@rush-temp/text-core':
|
||||
specifier: file:./projects/text-core.tgz
|
||||
version: file:projects/text-core.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(bufferutil@4.0.8)(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))(utf-8-validate@6.0.4)
|
||||
'@rush-temp/text-editor':
|
||||
specifier: file:./projects/text-editor.tgz
|
||||
version: file:projects/text-editor.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))
|
||||
@ -1273,9 +1276,6 @@ importers:
|
||||
'@types/cors':
|
||||
specifier: ^2.8.12
|
||||
version: 2.8.17
|
||||
'@types/crypto-js':
|
||||
specifier: ^4.1.1
|
||||
version: 4.2.2
|
||||
'@types/csvtojson':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.3
|
||||
@ -1394,8 +1394,8 @@ importers:
|
||||
specifier: ^8.3.1
|
||||
version: 8.3.4
|
||||
'@types/web-push':
|
||||
specifier: ~3.6.3
|
||||
version: 3.6.3
|
||||
specifier: ^3.6.4
|
||||
version: 3.6.4
|
||||
'@types/ws':
|
||||
specifier: ^8.5.11
|
||||
version: 8.5.11
|
||||
@ -1490,7 +1490,7 @@ importers:
|
||||
specifier: ^3.1.5
|
||||
version: 3.1.8(encoding@0.1.13)
|
||||
crypto-js:
|
||||
specifier: ^4.1.1
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
css-loader:
|
||||
specifier: ^5.2.1
|
||||
@ -1667,8 +1667,8 @@ importers:
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1
|
||||
intl-messageformat:
|
||||
specifier: ^9.7.1
|
||||
version: 9.13.0
|
||||
specifier: ^10.7.14
|
||||
version: 10.7.14
|
||||
itty-router:
|
||||
specifier: ^5.0.18
|
||||
version: 5.0.18
|
||||
@ -1729,6 +1729,9 @@ importers:
|
||||
markdown-it:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
md5.js:
|
||||
specifier: ^1.3.5
|
||||
version: 1.3.5
|
||||
mermaid:
|
||||
specifier: ~11.4.1
|
||||
version: 11.4.1
|
||||
@ -1928,7 +1931,7 @@ importers:
|
||||
specifier: ^8.3.2
|
||||
version: 8.3.2
|
||||
web-push:
|
||||
specifier: ~3.6.7
|
||||
specifier: ^3.6.7
|
||||
version: 3.6.7
|
||||
webpack:
|
||||
specifier: ^5.97.1
|
||||
@ -2928,20 +2931,20 @@ packages:
|
||||
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@formatjs/ecma402-abstract@1.11.4':
|
||||
resolution: {integrity: sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==}
|
||||
'@formatjs/ecma402-abstract@2.3.2':
|
||||
resolution: {integrity: sha512-6sE5nyvDloULiyOMbOTJEEgWL32w+VHkZQs8S02Lnn8Y/O5aQhjOEXwWzvR7SsBE/exxlSpY2EsWZgqHbtLatg==}
|
||||
|
||||
'@formatjs/fast-memoize@1.2.1':
|
||||
resolution: {integrity: sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==}
|
||||
'@formatjs/fast-memoize@2.2.6':
|
||||
resolution: {integrity: sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw==}
|
||||
|
||||
'@formatjs/icu-messageformat-parser@2.1.0':
|
||||
resolution: {integrity: sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==}
|
||||
'@formatjs/icu-messageformat-parser@2.11.0':
|
||||
resolution: {integrity: sha512-Hp81uTjjdTk3FLh/dggU5NK7EIsVWc5/ZDWrIldmf2rBuPejuZ13CZ/wpVE2SToyi4EiroPTQ1XJcJuZFIxTtw==}
|
||||
|
||||
'@formatjs/icu-skeleton-parser@1.3.6':
|
||||
resolution: {integrity: sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==}
|
||||
'@formatjs/icu-skeleton-parser@1.8.12':
|
||||
resolution: {integrity: sha512-QRAY2jC1BomFQHYDMcZtClqHR55EEnB96V7Xbk/UiBodsuFc5kujybzt87+qj1KqmJozFhk6n4KiT1HKwAkcfg==}
|
||||
|
||||
'@formatjs/intl-localematcher@0.2.25':
|
||||
resolution: {integrity: sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==}
|
||||
'@formatjs/intl-localematcher@0.5.10':
|
||||
resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==}
|
||||
|
||||
'@gar/promisify@1.1.3':
|
||||
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
|
||||
@ -3808,7 +3811,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/account@file:projects/account.tgz':
|
||||
resolution: {integrity: sha512-aFUxA1twR0m+7sDVFXyKoeVQtVLMrr973LpLK6LHrRa+PD010X6+AyoOkkyVJKFN0Q6zu2Oqz88PsEt50Z2Mjg==, tarball: file:projects/account.tgz}
|
||||
resolution: {integrity: sha512-xWdmeIZiSKL5eyvVHNUEnn/GXGsaNkayjxoDW+ydFB1GwUWExvSTA7OOs9mfG+IwLNU08GNKNGBYGM3XKZ2PsA==, tarball: file:projects/account.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/activity-assets@file:projects/activity-assets.tgz':
|
||||
@ -3936,7 +3939,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/cloud-transactor@file:projects/cloud-transactor.tgz':
|
||||
resolution: {integrity: sha512-sz4uAEfFOZfE7TOae+sv+RWlxunC4WlsQ7GTOX+kE+KDTNJK/r3d7+yIR/O3iDd4nsbLO/Al/9Z+wMZDXsmJcw==, tarball: file:projects/cloud-transactor.tgz}
|
||||
resolution: {integrity: sha512-RmuejZDmaNRcHOCurZBKIHOgqyfTwUNtJdhzJEANVw3XAbuapCjlaCwmtK5bad2D6S1+VrHrXoF4vw4FamxZkw==, tarball: file:projects/cloud-transactor.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/collaboration@file:projects/collaboration.tgz':
|
||||
@ -3956,11 +3959,11 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/contact-resources@file:projects/contact-resources.tgz':
|
||||
resolution: {integrity: sha512-NwGEZHpomoqLYe2i/Z3Wm9xLB1Cl7okFToLBn51JWhFebje+20w47PFde2tUX77f5bfYuLJ0ykZbKnfDbFz9TA==, tarball: file:projects/contact-resources.tgz}
|
||||
resolution: {integrity: sha512-sOoou1UaCHSN/qYHhEiWyiPICxmqP2p+ACDAeVzhU8fuUa5tejlzuANOdiEYqz4c8+u/NhlCQHd7G7G5WjMPpg==, tarball: file:projects/contact-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/contact@file:projects/contact.tgz':
|
||||
resolution: {integrity: sha512-sjRtgKszoagGm79PFQKes/sfRMcddH1qEMG3/xKuRLKlVcVJJ56twJaCCUeXP+7MsXMH5eEcS3sNCIdtznuASg==, tarball: file:projects/contact.tgz}
|
||||
resolution: {integrity: sha512-59CabCDtmhSMmziQMA8E7sB/xLjRibcfTjx/EuYh4trtpfOawQ6lVZSljJ3Fr3huHHg4A8A14L71MC4PgPSepQ==, tarball: file:projects/contact.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/controlled-documents-assets@file:projects/controlled-documents-assets.tgz':
|
||||
@ -4536,7 +4539,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/platform@file:projects/platform.tgz':
|
||||
resolution: {integrity: sha512-GyVd1NUl00O73Bwq0b/KFXhAfrko5BnqcN9ak+WWmDjHqi4CsWUfYm6ol5B7rbC38dqXXD4yBad/iEgywLliXA==, tarball: file:projects/platform.tgz}
|
||||
resolution: {integrity: sha512-BlslXnvEEebr3t7GEdTHD5HcoOTdez1j6Fb8Q6KctCunFjTeRtN5vtsutv2ZR+ChIGgZ5seZ6DOUFNM1MJf4ew==, tarball: file:projects/platform.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/pod-account@file:projects/pod-account.tgz':
|
||||
@ -4592,7 +4595,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/pod-ses@file:projects/pod-ses.tgz':
|
||||
resolution: {integrity: sha512-P+HVwQR4SO6F4EXl5ReGR6hbng8CKsl4IK6Ww6u7yhNh1x7YGKzmV7UMRjSUc7qsNu4CzOhF7AYatCB602ANjA==, tarball: file:projects/pod-ses.tgz}
|
||||
resolution: {integrity: sha512-gVCpGeUc+IsGfdCD84Sp+PcY21yRBkUhwfMUUC8VXcjf5MiayypLcc8pIGD2ufGGRJRAI3+clxIfiVc29ofBxw==, tarball: file:projects/pod-ses.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/pod-sign@file:projects/pod-sign.tgz':
|
||||
@ -4740,7 +4743,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-activity-resources@file:projects/server-activity-resources.tgz':
|
||||
resolution: {integrity: sha512-+UU7f65uCYtxuk56pj1bJ2ZaE6YHxVubtTfbsrLa8ZAGUOvWjrxY37B8j8GfcgGioL6PESsB12uEZIvghnNNaQ==, tarball: file:projects/server-activity-resources.tgz}
|
||||
resolution: {integrity: sha512-pzbXI3TbbMXYv/qVmx97uHJD8IOrI7glY8HsD1Np0PAGqzGpWBOm1j6oHKjO/WvfXPCvbmBRBvir22/+IdeXKA==, tarball: file:projects/server-activity-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-activity@file:projects/server-activity.tgz':
|
||||
@ -4784,7 +4787,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-chunter-resources@file:projects/server-chunter-resources.tgz':
|
||||
resolution: {integrity: sha512-Kpp8RTEJ+z5d8Rq7HbOhui8ZyV8OvKEXVkAXT80Ju/qhVnZ5Mnw/jk33dgwur1NPVjCWOK2SPECHf+eqzwXpBg==, tarball: file:projects/server-chunter-resources.tgz}
|
||||
resolution: {integrity: sha512-anzs0C7AXicSpf9F+jjqdokc3cZunw5O8gC0095fQmEoOW94OmvTyboGrx8iK3i+iYam4Z6Bkt60rXRo3JvXZQ==, tarball: file:projects/server-chunter-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-chunter@file:projects/server-chunter.tgz':
|
||||
@ -4812,7 +4815,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-controlled-documents-resources@file:projects/server-controlled-documents-resources.tgz':
|
||||
resolution: {integrity: sha512-g27+rhbyGhRdYikNstWia5wPng1EUiDp4DoEu51KVFrE4MOeaEXvB85Zb/4Jxg1RL4H7P6o7VRABeVqv6fkqsg==, tarball: file:projects/server-controlled-documents-resources.tgz}
|
||||
resolution: {integrity: sha512-mYK9xbNtII74MyRDJjutIBvUvdXfVeGwaixq9uRTVlqQsmb8oYvqVsTLLfmjL/e/eb1nmUPtnWh7sogkGYU/yA==, tarball: file:projects/server-controlled-documents-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-controlled-documents@file:projects/server-controlled-documents.tgz':
|
||||
@ -4860,7 +4863,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-gmail-resources@file:projects/server-gmail-resources.tgz':
|
||||
resolution: {integrity: sha512-V9M3+rquV4MPbPtmwWPdekguzA5WKJRDvU7xtpYKQSJ7J7hkLPKNah4GtSjin0opg6lTgtoAJUQaYLKheeCCbA==, tarball: file:projects/server-gmail-resources.tgz}
|
||||
resolution: {integrity: sha512-B+iAjGb/dbs1BhVc2MmYZxv2LrHQk/IH3UazglCC7v3Nu5x6ny4oMPCHXqv7W7MMVjIzqt60Wsw7spkvyS1CSA==, tarball: file:projects/server-gmail-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-gmail@file:projects/server-gmail.tgz':
|
||||
@ -4912,7 +4915,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-notification-resources@file:projects/server-notification-resources.tgz':
|
||||
resolution: {integrity: sha512-DhxiRHwKgwqkX4WP2ZmqGL7fHs0Ev3rtxHT/uylk5SPCPbKmBe20xyEzheSahP0Vm6kIS9XerGQuxGrI31eVBw==, tarball: file:projects/server-notification-resources.tgz}
|
||||
resolution: {integrity: sha512-sLf+6eAqeGkx+28mefySh7RB9mMnEh5Cuw/Q036PALbzj/1tihPIIxlst9kMZAYgGr7WRaZGDGK4Pq2yxfCrPQ==, tarball: file:projects/server-notification-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-notification@file:projects/server-notification.tgz':
|
||||
@ -4972,7 +4975,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-telegram-resources@file:projects/server-telegram-resources.tgz':
|
||||
resolution: {integrity: sha512-VsEVxoPM/hyelQa9/rQFzo+vbS8ixxU4RvVWdM0ae9HJuaEyszX4y9GheG/SDMa0NzCtyOOLf9KqL3ohGpkWRg==, tarball: file:projects/server-telegram-resources.tgz}
|
||||
resolution: {integrity: sha512-2zGK/gI0mG8ZvEUYDK0lt8m525blawYUmk64vMfYF0K7hkOmKaE+aSECh6UJozxuxURpyNNzi/9R0SNnMyfXKw==, tarball: file:projects/server-telegram-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-telegram@file:projects/server-telegram.tgz':
|
||||
@ -4984,7 +4987,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-time-resources@file:projects/server-time-resources.tgz':
|
||||
resolution: {integrity: sha512-WePYLAz/QHfFL+jMa/ZE6JQIvNYK4tGBs4ur6UBG3inJigtt9p7AR4PO+nr7dtGZqG8RT0T0TrGREcdV7pX5Gw==, tarball: file:projects/server-time-resources.tgz}
|
||||
resolution: {integrity: sha512-N9YLO1krTVoyAYV78E8sW2mDjSuJ/wHD9EHPAZO6AHxtoFmzlMPJaLprjGf7bWIemiGyAZKcAFhmpu0RSlaYGA==, tarball: file:projects/server-time-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-time@file:projects/server-time.tgz':
|
||||
@ -5000,7 +5003,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-tracker-resources@file:projects/server-tracker-resources.tgz':
|
||||
resolution: {integrity: sha512-VmLhXIzNRo1VeABIkcyYrRK7P2+OtDpXpYCrutGgmUqT+ioPHxaefntsS+wzItpblY78u4DJYSIkfOhtQXCTtg==, tarball: file:projects/server-tracker-resources.tgz}
|
||||
resolution: {integrity: sha512-Npz6QfpPLP18rNxIGzNvjKf4QEhT8ywVdlYNt7e4QGvA1zetFDava2Cg0QpN31LZue8pTDCC3T94kBQMUiUfqg==, tarball: file:projects/server-tracker-resources.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/server-tracker@file:projects/server-tracker.tgz':
|
||||
@ -5139,6 +5142,10 @@ packages:
|
||||
resolution: {integrity: sha512-noV3nlBP0OvM6i4C5YUevkhltHxG/2bct4pusP3O3AEQ7Za+A4qwzpsE08pHfA9f9pedEG677GE4EmG9x61rVQ==, tarball: file:projects/tests-sanity.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/text-core@file:projects/text-core.tgz':
|
||||
resolution: {integrity: sha512-piWZZp7T/zx+IKTP7fQGdY2schRbTEF2k0YuwXHkipp5MCA3BQLfy9VaZxAo5D4jhg0xySc1grVUfAqoOJIv8g==, tarball: file:projects/text-core.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/text-editor-assets@file:projects/text-editor-assets.tgz':
|
||||
resolution: {integrity: sha512-HrJXNpWkSNwguy4rSL6Cihc3/1eTmi0KQAmyLix1ci88uOK/9kKga7lMnKAsuobrB9DjbuLgPpcEMNpavMi13w==, tarball: file:projects/text-editor-assets.tgz}
|
||||
version: 0.0.0
|
||||
@ -5156,7 +5163,7 @@ packages:
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/text@file:projects/text.tgz':
|
||||
resolution: {integrity: sha512-p2TRL6FgtqVBooDf+E5A4HB+45VS03IvNxudhC9gCotewS726ZLOxl2XdfeuYB2rHYbzdmmiG2zb8GbPwqTkOw==, tarball: file:projects/text.tgz}
|
||||
resolution: {integrity: sha512-3aISTkQPGhn/Af7odByrglZazlbus1nu5kHvq77BZ0LJZ2lVZDZ5eTf0/EH6IpvGkmSvkEmkVJUl/bG/5Z7urA==, tarball: file:projects/text.tgz}
|
||||
version: 0.0.0
|
||||
|
||||
'@rush-temp/theme@file:projects/theme.tgz':
|
||||
@ -6254,8 +6261,8 @@ packages:
|
||||
'@types/verror@1.10.10':
|
||||
resolution: {integrity: sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==}
|
||||
|
||||
'@types/web-push@3.6.3':
|
||||
resolution: {integrity: sha512-v3oT4mMJsHeJ/rraliZ+7TbZtr5bQQuxcgD7C3/1q/zkAj29c8RE0F9lVZVu3hiQe5Z9fYcBreV7TLnfKR+4mg==}
|
||||
'@types/web-push@3.6.4':
|
||||
resolution: {integrity: sha512-GnJmSr40H3RAnj0s34FNTcJi1hmWFV5KXugE0mYWnYhgTAHLJ/dJKAwDmvPJYMke0RplY2XE9LnM4hqSqKIjhQ==}
|
||||
|
||||
'@types/webidl-conversions@7.0.3':
|
||||
resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==}
|
||||
@ -9137,6 +9144,10 @@ packages:
|
||||
has-unicode@2.0.1:
|
||||
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
|
||||
|
||||
hash-base@3.1.0:
|
||||
resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
hasown@2.0.1:
|
||||
resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -9283,10 +9294,6 @@ packages:
|
||||
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
https-proxy-agent@7.0.4:
|
||||
resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
https-proxy-agent@7.0.5:
|
||||
resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==}
|
||||
engines: {node: '>= 14'}
|
||||
@ -9398,8 +9405,8 @@ packages:
|
||||
resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
intl-messageformat@9.13.0:
|
||||
resolution: {integrity: sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==}
|
||||
intl-messageformat@10.7.14:
|
||||
resolution: {integrity: sha512-mMGnE4E1otdEutV5vLUdCxRJygHB5ozUBxsPB5qhitewssrS/qGruq9bmvIRkkGsNeK5ZWLfYRld18UHGTIifQ==}
|
||||
|
||||
invert-kv@2.0.0:
|
||||
resolution: {integrity: sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==}
|
||||
@ -10351,6 +10358,9 @@ packages:
|
||||
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
md5.js@1.3.5:
|
||||
resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
|
||||
|
||||
md5@2.3.0:
|
||||
resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==}
|
||||
|
||||
@ -13590,7 +13600,7 @@ snapshots:
|
||||
'@smithy/util-middleware': 3.0.0
|
||||
'@smithy/util-retry': 3.0.0
|
||||
'@smithy/util-utf8': 3.0.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.7.0
|
||||
transitivePeerDependencies:
|
||||
- aws-crt
|
||||
|
||||
@ -13891,7 +13901,7 @@ snapshots:
|
||||
'@smithy/property-provider': 3.0.0
|
||||
'@smithy/shared-ini-file-loader': 3.0.0
|
||||
'@smithy/types': 3.0.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.7.0
|
||||
|
||||
'@aws-sdk/types@3.577.0':
|
||||
dependencies:
|
||||
@ -14541,29 +14551,31 @@ snapshots:
|
||||
|
||||
'@fastify/busboy@2.1.1': {}
|
||||
|
||||
'@formatjs/ecma402-abstract@1.11.4':
|
||||
'@formatjs/ecma402-abstract@2.3.2':
|
||||
dependencies:
|
||||
'@formatjs/intl-localematcher': 0.2.25
|
||||
tslib: 2.6.2
|
||||
'@formatjs/fast-memoize': 2.2.6
|
||||
'@formatjs/intl-localematcher': 0.5.10
|
||||
decimal.js: 10.4.3
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/fast-memoize@1.2.1':
|
||||
'@formatjs/fast-memoize@2.2.6':
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/icu-messageformat-parser@2.1.0':
|
||||
'@formatjs/icu-messageformat-parser@2.11.0':
|
||||
dependencies:
|
||||
'@formatjs/ecma402-abstract': 1.11.4
|
||||
'@formatjs/icu-skeleton-parser': 1.3.6
|
||||
tslib: 2.6.2
|
||||
'@formatjs/ecma402-abstract': 2.3.2
|
||||
'@formatjs/icu-skeleton-parser': 1.8.12
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/icu-skeleton-parser@1.3.6':
|
||||
'@formatjs/icu-skeleton-parser@1.8.12':
|
||||
dependencies:
|
||||
'@formatjs/ecma402-abstract': 1.11.4
|
||||
tslib: 2.6.2
|
||||
'@formatjs/ecma402-abstract': 2.3.2
|
||||
tslib: 2.7.0
|
||||
|
||||
'@formatjs/intl-localematcher@0.2.25':
|
||||
'@formatjs/intl-localematcher@0.5.10':
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
tslib: 2.7.0
|
||||
|
||||
'@gar/promisify@1.1.3': {}
|
||||
|
||||
@ -15760,10 +15772,12 @@ snapshots:
|
||||
|
||||
'@rush-temp/account@file:projects/account.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(gcp-metadata@5.3.0(encoding@0.1.13))(snappy@7.2.2)(socks@2.8.3)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))':
|
||||
dependencies:
|
||||
'@types/crypto-js': 4.2.2
|
||||
'@types/jest': 29.5.12
|
||||
'@types/otp-generator': 4.0.2
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
|
||||
crypto-js: 4.2.0
|
||||
eslint: 8.56.0
|
||||
eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.3.3)
|
||||
eslint-plugin-import: 2.29.1(eslint@8.56.0)
|
||||
@ -16925,9 +16939,11 @@ snapshots:
|
||||
|
||||
'@rush-temp/contact-resources@file:projects/contact-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))':
|
||||
dependencies:
|
||||
'@types/crypto-js': 4.2.2
|
||||
'@types/jest': 29.5.12
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
|
||||
crypto-js: 4.2.0
|
||||
eslint: 8.56.0
|
||||
eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.3.3)
|
||||
eslint-plugin-import: 2.29.1(eslint@8.56.0)
|
||||
@ -16969,13 +16985,13 @@ snapshots:
|
||||
'@types/jest': 29.5.12
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
|
||||
crypto-js: 4.2.0
|
||||
eslint: 8.56.0
|
||||
eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.3.3)
|
||||
eslint-plugin-import: 2.29.1(eslint@8.56.0)
|
||||
eslint-plugin-n: 15.7.0(eslint@8.56.0)
|
||||
eslint-plugin-promise: 6.1.1(eslint@8.56.0)
|
||||
jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))
|
||||
md5.js: 1.3.5
|
||||
prettier: 3.2.5
|
||||
ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
@ -20207,7 +20223,7 @@ snapshots:
|
||||
eslint-plugin-import: 2.29.1(eslint@8.56.0)
|
||||
eslint-plugin-n: 15.7.0(eslint@8.56.0)
|
||||
eslint-plugin-promise: 6.1.1(eslint@8.56.0)
|
||||
intl-messageformat: 9.13.0
|
||||
intl-messageformat: 10.7.14
|
||||
jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))
|
||||
prettier: 3.2.5
|
||||
ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3)
|
||||
@ -20816,6 +20832,7 @@ snapshots:
|
||||
'@types/express': 4.17.21
|
||||
'@types/jest': 29.5.12
|
||||
'@types/node': 20.11.19
|
||||
'@types/web-push': 3.6.4
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
|
||||
aws-sdk: 2.1664.0
|
||||
@ -20835,6 +20852,7 @@ snapshots:
|
||||
ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3)
|
||||
ts-node: 10.9.2(@types/node@20.11.19)(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
web-push: 3.6.7
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- '@jest/types'
|
||||
@ -23122,7 +23140,6 @@ snapshots:
|
||||
'@rush-temp/server-notification-resources@file:projects/server-notification-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))':
|
||||
dependencies:
|
||||
'@types/jest': 29.5.12
|
||||
'@types/web-push': 3.6.3
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
|
||||
eslint: 8.56.0
|
||||
@ -23134,7 +23151,6 @@ snapshots:
|
||||
prettier: 3.2.5
|
||||
ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
web-push: 3.6.7
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- '@jest/types'
|
||||
@ -24705,6 +24721,37 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@rush-temp/text-core@file:projects/text-core.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(bufferutil@4.0.8)(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))(utf-8-validate@6.0.4)':
|
||||
dependencies:
|
||||
'@types/jest': 29.5.12
|
||||
'@types/markdown-it': 13.0.8
|
||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.6.2)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.2)
|
||||
eslint: 8.56.0
|
||||
eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.6.2)
|
||||
eslint-plugin-import: 2.29.1(eslint@8.56.0)
|
||||
eslint-plugin-n: 15.7.0(eslint@8.56.0)
|
||||
eslint-plugin-promise: 6.1.1(eslint@8.56.0)
|
||||
fast-equals: 5.0.1
|
||||
jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))
|
||||
jest-environment-jsdom: 29.7.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
prettier: 3.2.5
|
||||
ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.6.2)
|
||||
typescript: 5.6.2
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- '@jest/types'
|
||||
- '@types/node'
|
||||
- babel-jest
|
||||
- babel-plugin-macros
|
||||
- bufferutil
|
||||
- canvas
|
||||
- esbuild
|
||||
- node-notifier
|
||||
- supports-color
|
||||
- ts-node
|
||||
- utf-8-validate
|
||||
|
||||
'@rush-temp/text-editor-assets@file:projects/text-editor-assets.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))':
|
||||
dependencies:
|
||||
'@types/jest': 29.5.12
|
||||
@ -25866,7 +25913,7 @@ snapshots:
|
||||
'@aws-crypto/crc32': 3.0.0
|
||||
'@smithy/types': 3.0.0
|
||||
'@smithy/util-hex-encoding': 3.0.0
|
||||
tslib: 2.6.2
|
||||
tslib: 2.7.0
|
||||
|
||||
'@smithy/eventstream-serde-browser@3.0.0':
|
||||
dependencies:
|
||||
@ -26952,7 +26999,7 @@ snapshots:
|
||||
'@types/verror@1.10.10':
|
||||
optional: true
|
||||
|
||||
'@types/web-push@3.6.3':
|
||||
'@types/web-push@3.6.4':
|
||||
dependencies:
|
||||
'@types/node': 20.11.19
|
||||
|
||||
@ -29182,7 +29229,7 @@ snapshots:
|
||||
dot-case@3.0.4:
|
||||
dependencies:
|
||||
no-case: 3.0.4
|
||||
tslib: 2.6.2
|
||||
tslib: 2.7.0
|
||||
|
||||
dot-prop@6.0.1:
|
||||
dependencies:
|
||||
@ -30656,6 +30703,12 @@ snapshots:
|
||||
|
||||
has-unicode@2.0.1: {}
|
||||
|
||||
hash-base@3.1.0:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
readable-stream: 3.6.2
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
hasown@2.0.1:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
@ -30849,13 +30902,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
https-proxy-agent@7.0.4:
|
||||
dependencies:
|
||||
agent-base: 7.1.1
|
||||
debug: 4.3.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
https-proxy-agent@7.0.5:
|
||||
dependencies:
|
||||
agent-base: 7.1.1
|
||||
@ -30956,12 +31002,12 @@ snapshots:
|
||||
|
||||
interpret@3.1.1: {}
|
||||
|
||||
intl-messageformat@9.13.0:
|
||||
intl-messageformat@10.7.14:
|
||||
dependencies:
|
||||
'@formatjs/ecma402-abstract': 1.11.4
|
||||
'@formatjs/fast-memoize': 1.2.1
|
||||
'@formatjs/icu-messageformat-parser': 2.1.0
|
||||
tslib: 2.6.2
|
||||
'@formatjs/ecma402-abstract': 2.3.2
|
||||
'@formatjs/fast-memoize': 2.2.6
|
||||
'@formatjs/icu-messageformat-parser': 2.11.0
|
||||
tslib: 2.7.0
|
||||
|
||||
invert-kv@2.0.0: {}
|
||||
|
||||
@ -32189,6 +32235,12 @@ snapshots:
|
||||
escape-string-regexp: 4.0.0
|
||||
optional: true
|
||||
|
||||
md5.js@1.3.5:
|
||||
dependencies:
|
||||
hash-base: 3.1.0
|
||||
inherits: 2.0.4
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
md5@2.3.0:
|
||||
dependencies:
|
||||
charenc: 0.0.2
|
||||
@ -32911,7 +32963,7 @@ snapshots:
|
||||
pascal-case@3.1.2:
|
||||
dependencies:
|
||||
no-case: 3.0.4
|
||||
tslib: 2.6.2
|
||||
tslib: 2.7.0
|
||||
|
||||
passport-custom@1.1.1:
|
||||
dependencies:
|
||||
@ -35104,7 +35156,7 @@ snapshots:
|
||||
dependencies:
|
||||
asn1.js: 5.4.1
|
||||
http_ece: 1.2.0
|
||||
https-proxy-agent: 7.0.4
|
||||
https-proxy-agent: 7.0.5
|
||||
jws: 4.0.0
|
||||
minimist: 1.2.8
|
||||
transitivePeerDependencies:
|
||||
|
@ -37,7 +37,7 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"intl-messageformat": "^9.7.1"
|
||||
"intl-messageformat": "^10.7.14"
|
||||
},
|
||||
"repository": "https://github.com/hcengineering/platform",
|
||||
"publishConfig": {
|
||||
|
7
packages/text-core/.eslintrc.js
Normal file
7
packages/text-core/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
4
packages/text-core/config/rig.json
Normal file
4
packages/text-core/config/rig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
7
packages/text-core/jest.config.js
Normal file
7
packages/text-core/jest.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
|
||||
roots: ["./src"],
|
||||
coverageReporters: ["text-summary", "html"]
|
||||
}
|
49
packages/text-core/package.json
Normal file
49
packages/text-core/package.json
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "@hcengineering/text-core",
|
||||
"version": "0.6.0",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"author": "Anticrm Platform Contributors",
|
||||
"license": "EPL-2.0",
|
||||
"scripts": {
|
||||
"build": "compile",
|
||||
"test": "jest --passWithNoTests --silent",
|
||||
"build:watch": "compile",
|
||||
"format": "format src",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:test": "jest --passWithNoTests --silent",
|
||||
"_phase:format": "format src",
|
||||
"_phase:validate": "compile validate"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hcengineering/platform-rig": "^0.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint": "^8.54.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.3.3",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@types/markdown-it": "~13.0.0",
|
||||
"jest-environment-jsdom": "^29.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/core": "^0.6.32",
|
||||
"fast-equals": "^5.0.1"
|
||||
},
|
||||
"repository": "https://github.com/hcengineering/platform",
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
}
|
||||
}
|
20
packages/text-core/src/index.ts
Normal file
20
packages/text-core/src/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
export * from './markup/dsl'
|
||||
export * from './markup/model'
|
||||
export * from './markup/reference'
|
||||
export * from './markup/traverse'
|
||||
export * from './markup/utils'
|
402
packages/text-core/src/markup/utils.ts
Normal file
402
packages/text-core/src/markup/utils.ts
Normal file
@ -0,0 +1,402 @@
|
||||
//
|
||||
// Copyright © 2024 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Markup } from '@hcengineering/core'
|
||||
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { nodeDoc, nodeParagraph, nodeText } from './dsl'
|
||||
import { MarkupMark, MarkupMarkType, MarkupNode, MarkupNodeType, emptyMarkupNode, type AttrValue } from './model'
|
||||
import { traverseNode } from './traverse'
|
||||
|
||||
/** @public */
|
||||
export const EmptyMarkup: Markup = jsonToMarkup(emptyMarkupNode())
|
||||
|
||||
/** @public */
|
||||
export function isEmptyMarkup (markup: Markup | undefined): boolean {
|
||||
if (markup === undefined || markup === null || markup === '') {
|
||||
return true
|
||||
}
|
||||
return isEmptyNode(markupToJSON(markup))
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function areEqualMarkups (markup1: Markup, markup2: Markup): boolean {
|
||||
if (markup1 === markup2) {
|
||||
return true
|
||||
}
|
||||
|
||||
const node1 = markupToJSON(markup1)
|
||||
const node2 = markupToJSON(markup2)
|
||||
|
||||
if (isEmptyNode(node1) && isEmptyNode(node2)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return equalNodes(node1, node2)
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function areEqualJson (json1: MarkupNode, json2: MarkupNode): boolean {
|
||||
return equalNodes(json1, json2)
|
||||
}
|
||||
|
||||
function equalNodes (node1: MarkupNode, node2: MarkupNode): boolean {
|
||||
if (node1.type !== node2.type) return false
|
||||
|
||||
const text1 = node1.text ?? ''
|
||||
const text2 = node2.text ?? ''
|
||||
if (text1 !== text2) return false
|
||||
|
||||
if (!equalArrays(node1.content, node2.content, equalNodes)) return false
|
||||
if (!equalArrays(node1.marks, node2.marks, equalMarks)) return false
|
||||
if (!equalRecords(node1.attrs, node2.attrs)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function equalArrays<T> (a: T[] | undefined, b: T[] | undefined, equal: (a: T, b: T) => boolean): boolean {
|
||||
if (a === b) return true
|
||||
const arr1 = a ?? []
|
||||
const arr2 = b ?? []
|
||||
if (arr1.length !== arr2.length) return false
|
||||
return arr1.every((item1, i) => equal(item1, arr2[i]))
|
||||
}
|
||||
|
||||
function equalRecords (a: Record<string, any> | undefined, b: Record<string, any> | undefined): boolean {
|
||||
if (a === b) return true
|
||||
a = Object.fromEntries(Object.entries(a ?? {}).filter(([_, v]) => v != null))
|
||||
b = Object.fromEntries(Object.entries(b ?? {}).filter(([_, v]) => v != null))
|
||||
return deepEqual(a, b)
|
||||
}
|
||||
|
||||
export function equalMarks (a: MarkupMark, b: MarkupMark): boolean {
|
||||
return a.type === b.type && equalRecords(a.attrs, b.attrs)
|
||||
}
|
||||
|
||||
const emptyNodes = [MarkupNodeType.hard_break]
|
||||
|
||||
const nonEmptyNodes = [
|
||||
MarkupNodeType.horizontal_rule,
|
||||
MarkupNodeType.image,
|
||||
MarkupNodeType.reference,
|
||||
MarkupNodeType.subLink,
|
||||
MarkupNodeType.table
|
||||
]
|
||||
|
||||
/** @public */
|
||||
export function isEmptyNode (node: MarkupNode): boolean {
|
||||
if (emptyNodes.includes(node.type)) return true
|
||||
if (nonEmptyNodes.includes(node.type)) return false
|
||||
if (node.text !== undefined && node.text?.trim().length > 0) return false
|
||||
|
||||
const content = node.content ?? []
|
||||
return content.every(isEmptyNode)
|
||||
}
|
||||
|
||||
// Markup
|
||||
|
||||
/** @public */
|
||||
export function jsonToMarkup (json: MarkupNode): Markup {
|
||||
return JSON.stringify(json)
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function markupToJSON (markup: Markup): MarkupNode {
|
||||
if (markup == null || markup === '') {
|
||||
return emptyMarkupNode()
|
||||
}
|
||||
|
||||
try {
|
||||
// Ideally Markup should contain only serialized JSON
|
||||
// But there seem to be some cases when it contains HTML or plain text
|
||||
// So we need to handle those cases and produce valid MarkupNode
|
||||
if (markup.startsWith('{')) {
|
||||
return JSON.parse(markup) as MarkupNode
|
||||
} else {
|
||||
return nodeDoc(nodeParagraph(nodeText(markup)))
|
||||
}
|
||||
} catch (error) {
|
||||
return emptyMarkupNode()
|
||||
}
|
||||
}
|
||||
|
||||
// UTILS
|
||||
|
||||
const ELLIPSIS_CHAR = '…'
|
||||
const WHITESPACE = ' '
|
||||
|
||||
/** @public */
|
||||
export function stripTags (markup: Markup, textLimit = 0): string {
|
||||
const parsed = markupToJSON(markup)
|
||||
|
||||
const textParts: string[] = []
|
||||
let charCount = 0
|
||||
let isHardStop = false
|
||||
|
||||
const pushText = (text: string): void => {
|
||||
if (textLimit > 0 && charCount + text.length > textLimit) {
|
||||
const toAddCount = textLimit - charCount
|
||||
const textPart = text.substring(0, toAddCount)
|
||||
textParts.push(textPart)
|
||||
textParts.push(ELLIPSIS_CHAR)
|
||||
isHardStop = true
|
||||
} else {
|
||||
textParts.push(text)
|
||||
charCount += text.length
|
||||
}
|
||||
}
|
||||
|
||||
traverseNode(parsed, (node, parent): boolean => {
|
||||
if (isHardStop) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (node.type === MarkupNodeType.text) {
|
||||
const text = node.text ?? ''
|
||||
pushText(text)
|
||||
return false
|
||||
} else if (
|
||||
node.type === MarkupNodeType.paragraph ||
|
||||
node.type === MarkupNodeType.table ||
|
||||
node.type === MarkupNodeType.doc ||
|
||||
node.type === MarkupNodeType.blockquote
|
||||
) {
|
||||
if (textParts.length > 0 && textParts[textParts.length - 1] !== WHITESPACE) {
|
||||
textParts.push(WHITESPACE)
|
||||
charCount++
|
||||
}
|
||||
} else if (node.type === MarkupNodeType.reference) {
|
||||
const label = `${node.attrs?.label ?? ''}`
|
||||
pushText(label.length > 0 ? `@${label}` : '')
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
const result = textParts.join('')
|
||||
return result
|
||||
}
|
||||
|
||||
class NodeBuilder {
|
||||
textParts: string[] = []
|
||||
|
||||
constructor (private readonly addTags: boolean) {}
|
||||
|
||||
addText (text: string): void {
|
||||
this.textParts.push(text)
|
||||
}
|
||||
|
||||
addTag (text: string, newLine: boolean = false): void {
|
||||
if (this.addTags) {
|
||||
this.textParts.push(text)
|
||||
}
|
||||
if (!this.addTags && newLine) {
|
||||
this.textParts.push('\n')
|
||||
}
|
||||
}
|
||||
|
||||
toText (): string {
|
||||
return this.textParts.join('')
|
||||
}
|
||||
}
|
||||
|
||||
function addMark (builder: NodeBuilder, mark?: MarkupMark, next?: () => void): void {
|
||||
if (mark != null) {
|
||||
const attrs = mark.attrs ?? {}
|
||||
|
||||
if (mark.type === MarkupMarkType.bold) {
|
||||
builder.addTag('<strong>')
|
||||
next?.()
|
||||
builder.addTag('</strong>')
|
||||
} else if (mark.type === MarkupMarkType.code) {
|
||||
builder.addTag('<code class="proseCode">')
|
||||
next?.()
|
||||
builder.addTag('</code>')
|
||||
} else if (mark.type === MarkupMarkType.em) {
|
||||
builder.addTag('<em>')
|
||||
next?.()
|
||||
builder.addTag('</em>')
|
||||
} else if (mark.type === MarkupMarkType.link) {
|
||||
builder.addTag(`<a href=${attrs.href} target=${attrs.target}>`)
|
||||
next?.()
|
||||
builder.addTag('</a>')
|
||||
} else if (mark.type === MarkupMarkType.strike) {
|
||||
builder.addTag('<s>')
|
||||
next?.()
|
||||
builder.addTag('</s>')
|
||||
} else if (mark.type === MarkupMarkType.underline) {
|
||||
builder.addTag('<u>')
|
||||
next?.()
|
||||
builder.addTag('</u>')
|
||||
} else {
|
||||
builder.addTag(`unknown mark: "${mark.type as string}"`, false)
|
||||
next?.()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addMarks (builder: NodeBuilder, marks: MarkupMark[], next?: () => void): void {
|
||||
if (marks.length > 0) {
|
||||
const mark = marks[0]
|
||||
const others = marks.slice(1)
|
||||
|
||||
if (others.length > 0) {
|
||||
addMark(builder, mark, () => {
|
||||
addMarks(builder, others, next)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addNodeContent (builder: NodeBuilder, node?: MarkupNode): void {
|
||||
if (node == null) return
|
||||
|
||||
const attrs = node.attrs ?? {}
|
||||
const nodes = node.content ?? []
|
||||
|
||||
if (node.type === MarkupNodeType.doc) {
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
} else if (node.type === MarkupNodeType.text) {
|
||||
builder.addText(node.text ?? '')
|
||||
} else if (node.type === MarkupNodeType.paragraph) {
|
||||
builder.addTag('<p>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</p>')
|
||||
} else if (node.type === MarkupNodeType.blockquote) {
|
||||
builder.addTag('<blockquote>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</blockquote>')
|
||||
} else if (node.type === MarkupNodeType.horizontal_rule) {
|
||||
builder.addTag('<hr/>')
|
||||
} else if (node.type === MarkupNodeType.heading) {
|
||||
const level = toNumber(node.attrs?.level) ?? 1
|
||||
builder.addTag(`<h${level}>`)
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag(`</h${level}>`)
|
||||
} else if (node.type === MarkupNodeType.code_block) {
|
||||
builder.addTag('<pre><code>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</code></pre>')
|
||||
} else if (node.type === MarkupNodeType.image) {
|
||||
const src = toString(attrs.src)
|
||||
const alt = toString(attrs.alt)
|
||||
builder.addText(`<img src="${src}" alt="${alt}"/>`)
|
||||
} else if (node.type === MarkupNodeType.reference) {
|
||||
const label = toString(attrs.label)
|
||||
builder.addText(label !== undefined ? `@${label}` : '')
|
||||
} else if (node.type === MarkupNodeType.hard_break) {
|
||||
builder.addTag('<br/>')
|
||||
} else if (node.type === MarkupNodeType.ordered_list) {
|
||||
builder.addTag('<ol>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</ol>')
|
||||
} else if (node.type === MarkupNodeType.bullet_list) {
|
||||
builder.addTag('<ul>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</ul>')
|
||||
} else if (node.type === MarkupNodeType.list_item) {
|
||||
builder.addTag('<li>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</li>')
|
||||
} else if (node.type === MarkupNodeType.subLink) {
|
||||
builder.addTag('<sub>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</sub>')
|
||||
} else if (node.type === MarkupNodeType.table) {
|
||||
builder.addTag('<table><tbody>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</tbody></table>')
|
||||
} else if (node.type === MarkupNodeType.table_row) {
|
||||
builder.addTag('<tr>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</tr>')
|
||||
} else if (node.type === MarkupNodeType.table_cell) {
|
||||
builder.addTag('<td>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</td>')
|
||||
} else if (node.type === MarkupNodeType.table_header) {
|
||||
builder.addTag('<th>')
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
builder.addTag('</th>')
|
||||
} else {
|
||||
builder.addText(`unknown node: "${node.type}"`)
|
||||
nodes.forEach((childNode) => {
|
||||
addNode(builder, childNode)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function addNode (builder: NodeBuilder, node: MarkupNode): void {
|
||||
const marks = node.marks ?? []
|
||||
|
||||
if (marks.length > 0) {
|
||||
addMarks(builder, marks, () => {
|
||||
addNodeContent(builder, node)
|
||||
})
|
||||
} else {
|
||||
addNodeContent(builder, node)
|
||||
}
|
||||
}
|
||||
|
||||
function toString (value: AttrValue | undefined): string | undefined {
|
||||
return value !== undefined ? `${value}` : undefined
|
||||
}
|
||||
|
||||
function toNumber (value: AttrValue | undefined): number | undefined {
|
||||
if (typeof value === 'boolean') {
|
||||
return value ? 1 : 0
|
||||
}
|
||||
|
||||
return value !== undefined ? (typeof value === 'string' ? parseInt(value) : value) : undefined
|
||||
}
|
||||
|
||||
export function markupToHTML (markup: Markup): string {
|
||||
const jsonModel = markupToJSON(markup)
|
||||
const builder = new NodeBuilder(true)
|
||||
addNode(builder, jsonModel)
|
||||
return builder.toText()
|
||||
}
|
||||
|
||||
export function markupToText (markup: Markup): string {
|
||||
const jsonModel = markupToJSON(markup)
|
||||
const builder = new NodeBuilder(false)
|
||||
addNode(builder, jsonModel)
|
||||
return builder.toText()
|
||||
}
|
10
packages/text-core/tsconfig.json
Normal file
10
packages/text-core/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declarationDir": "./types",
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/core": "^0.6.32",
|
||||
"@hcengineering/text-core": "^0.6.0",
|
||||
"@tiptap/core": "^2.6.6",
|
||||
"@tiptap/html": "^2.6.6",
|
||||
"@tiptap/pm": "^2.6.6",
|
||||
|
@ -14,13 +14,9 @@
|
||||
//
|
||||
|
||||
export * from './extensions'
|
||||
export * from './markup/dsl'
|
||||
export * from './markup/model'
|
||||
export * from './markup/reference'
|
||||
export * from './markup/traverse'
|
||||
export * from './markup/utils'
|
||||
export * from '@hcengineering/text-core'
|
||||
export * from './nodes'
|
||||
// export * from './ydoc'
|
||||
export * from './markup/utils'
|
||||
export * from './marks/code'
|
||||
export * from './marks/colors'
|
||||
export * from './marks/noteBase'
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { MarkupNode, markupToJSON } from '@hcengineering/text-core'
|
||||
import { Extensions } from '@tiptap/core'
|
||||
import { defaultExtensions } from '../extensions'
|
||||
import { MarkdownParser } from './parser'
|
||||
import { MarkdownState, storeMarks, storeNodes } from './serializer'
|
||||
import { MarkupNode } from '../markup/model'
|
||||
import { markupToJSON } from '../markup/utils'
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { MarkupMark, MarkupMarkType, MarkupNode } from '../markup/model'
|
||||
import { MarkupMark, MarkupMarkType, MarkupNode } from '@hcengineering/text-core'
|
||||
|
||||
export function traverseMarks (node: MarkupNode, f: (el: MarkupMark) => void): void {
|
||||
node.marks?.forEach(f)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Attrs, MarkupNode } from '../markup/model'
|
||||
import { Attrs, MarkupNode } from '@hcengineering/text-core'
|
||||
|
||||
export function traverseMarkupNode (node: MarkupNode, f: (el: MarkupNode) => void): void {
|
||||
f(node)
|
||||
|
@ -3,10 +3,10 @@ import MarkdownIt, { type Token } from 'markdown-it'
|
||||
import type { RuleCore } from 'markdown-it/lib/parser_core'
|
||||
import type StateCore from 'markdown-it/lib/rules_core/state_core'
|
||||
|
||||
import { Attrs, AttrValue, MarkupMark, MarkupMarkType, MarkupNode, MarkupNodeType } from '@hcengineering/text-core'
|
||||
import { htmlToJSON } from '../markup/utils'
|
||||
import { addToSet, removeFromSet, sameSet } from './marks'
|
||||
import { messageContent } from './node'
|
||||
import { Attrs, AttrValue, MarkupMark, MarkupMarkType, MarkupNode, MarkupNodeType } from '../markup/model'
|
||||
import { htmlToJSON } from '../markup/utils'
|
||||
|
||||
interface ParsingBlockRule {
|
||||
block: MarkupNodeType
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { MarkupMark, MarkupNode, MarkupNodeType } from '@hcengineering/text-core'
|
||||
import { generateHTML } from '@tiptap/html'
|
||||
import { defaultExtensions } from '../extensions'
|
||||
import { isInSet, markEq } from './marks'
|
||||
import { messageContent, nodeAttrs } from './node'
|
||||
import { MarkupMark, MarkupNode, MarkupNodeType } from '../markup/model'
|
||||
import { defaultExtensions } from '../extensions'
|
||||
|
||||
type FirstDelim = (i: number, attrs?: Record<string, any>, parentAttrs?: Record<string, any>) => string
|
||||
interface IState {
|
||||
|
@ -1,5 +1,13 @@
|
||||
import { nodeDoc, nodeImage, nodeParagraph, nodeReference, nodeText, markLink, markUnderline } from '../dsl'
|
||||
import { MarkupNodeType } from '../model'
|
||||
import {
|
||||
markLink,
|
||||
markUnderline,
|
||||
MarkupNodeType,
|
||||
nodeDoc,
|
||||
nodeImage,
|
||||
nodeParagraph,
|
||||
nodeReference,
|
||||
nodeText
|
||||
} from '@hcengineering/text-core'
|
||||
import { jsonToHTML } from '../utils'
|
||||
|
||||
describe('dsl', () => {
|
||||
|
@ -17,28 +17,34 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Editor, getSchema } from '@tiptap/core'
|
||||
import { MarkupMarkType, MarkupNode, MarkupNodeType } from '../model'
|
||||
import {
|
||||
areEqualMarkups,
|
||||
isEmptyMarkup,
|
||||
isEmptyNode,
|
||||
jsonToMarkup,
|
||||
MarkupMarkType,
|
||||
MarkupNode,
|
||||
MarkupNodeType,
|
||||
markupToJSON,
|
||||
nodeDoc,
|
||||
nodeParagraph,
|
||||
nodeText,
|
||||
markupToHTML
|
||||
} from '@hcengineering/text-core'
|
||||
import { Editor, getSchema } from '@tiptap/core'
|
||||
import { ServerKit } from '../../kits/server-kit'
|
||||
import {
|
||||
getMarkup,
|
||||
htmlToJSON,
|
||||
htmlToMarkup,
|
||||
htmlToPmNode,
|
||||
isEmptyMarkup,
|
||||
isEmptyNode,
|
||||
jsonToHTML,
|
||||
jsonToMarkup,
|
||||
jsonToText,
|
||||
markupToHTML,
|
||||
markupToJSON,
|
||||
markupToPmNode,
|
||||
pmNodeToHTML,
|
||||
pmNodeToJSON,
|
||||
pmNodeToMarkup
|
||||
} from '../utils'
|
||||
import { ServerKit } from '../../kits/server-kit'
|
||||
import { nodeDoc, nodeParagraph, nodeText } from '../dsl'
|
||||
|
||||
// mock tiptap functions
|
||||
jest.mock('@tiptap/html', () => ({
|
||||
|
@ -18,13 +18,18 @@ import { Editor, Extensions, getSchema } from '@tiptap/core'
|
||||
import { generateHTML, generateJSON } from '@tiptap/html'
|
||||
import { Node as ProseMirrorNode, Schema } from '@tiptap/pm/model'
|
||||
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import {
|
||||
MarkupNode,
|
||||
emptyMarkupNode,
|
||||
jsonToMarkup,
|
||||
markupToJSON,
|
||||
nodeDoc,
|
||||
nodeParagraph,
|
||||
nodeText
|
||||
} from '@hcengineering/text-core'
|
||||
import { defaultExtensions } from '../extensions'
|
||||
import { nodeDoc, nodeParagraph, nodeText } from './dsl'
|
||||
import { MarkupMark, MarkupNode, MarkupNodeType, emptyMarkupNode } from './model'
|
||||
|
||||
/** @public */
|
||||
export const EmptyMarkup: Markup = jsonToMarkup(emptyMarkupNode())
|
||||
const defaultSchema = getSchema(defaultExtensions)
|
||||
|
||||
/** @public */
|
||||
@ -32,88 +37,6 @@ export function getMarkup (editor?: Editor): Markup {
|
||||
return jsonToMarkup(editor?.getJSON() as MarkupNode)
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function isEmptyMarkup (markup: Markup | undefined): boolean {
|
||||
if (markup === undefined || markup === null || markup === '') {
|
||||
return true
|
||||
}
|
||||
return isEmptyNode(markupToJSON(markup))
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function areEqualMarkups (markup1: Markup, markup2: Markup): boolean {
|
||||
if (markup1 === markup2) {
|
||||
return true
|
||||
}
|
||||
|
||||
const node1 = markupToJSON(markup1)
|
||||
const node2 = markupToJSON(markup2)
|
||||
|
||||
if (isEmptyNode(node1) && isEmptyNode(node2)) {
|
||||
return true
|
||||
}
|
||||
|
||||
return equalNodes(node1, node2)
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function areEqualJson (json1: MarkupNode, json2: MarkupNode): boolean {
|
||||
return equalNodes(json1, json2)
|
||||
}
|
||||
|
||||
function equalNodes (node1: MarkupNode, node2: MarkupNode): boolean {
|
||||
if (node1.type !== node2.type) return false
|
||||
|
||||
const text1 = node1.text ?? ''
|
||||
const text2 = node2.text ?? ''
|
||||
if (text1 !== text2) return false
|
||||
|
||||
if (!equalArrays(node1.content, node2.content, equalNodes)) return false
|
||||
if (!equalArrays(node1.marks, node2.marks, equalMarks)) return false
|
||||
if (!equalRecords(node1.attrs, node2.attrs)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function equalArrays<T> (a: T[] | undefined, b: T[] | undefined, equal: (a: T, b: T) => boolean): boolean {
|
||||
if (a === b) return true
|
||||
const arr1 = a ?? []
|
||||
const arr2 = b ?? []
|
||||
if (arr1.length !== arr2.length) return false
|
||||
return arr1.every((item1, i) => equal(item1, arr2[i]))
|
||||
}
|
||||
|
||||
function equalRecords (a: Record<string, any> | undefined, b: Record<string, any> | undefined): boolean {
|
||||
if (a === b) return true
|
||||
a = Object.fromEntries(Object.entries(a ?? {}).filter(([_, v]) => v != null))
|
||||
b = Object.fromEntries(Object.entries(b ?? {}).filter(([_, v]) => v != null))
|
||||
return deepEqual(a, b)
|
||||
}
|
||||
|
||||
function equalMarks (a: MarkupMark, b: MarkupMark): boolean {
|
||||
return a.type === b.type && equalRecords(a.attrs, b.attrs)
|
||||
}
|
||||
|
||||
const emptyNodes = [MarkupNodeType.hard_break]
|
||||
|
||||
const nonEmptyNodes = [
|
||||
MarkupNodeType.horizontal_rule,
|
||||
MarkupNodeType.image,
|
||||
MarkupNodeType.reference,
|
||||
MarkupNodeType.subLink,
|
||||
MarkupNodeType.table
|
||||
]
|
||||
|
||||
/** @public */
|
||||
export function isEmptyNode (node: MarkupNode): boolean {
|
||||
if (emptyNodes.includes(node.type)) return true
|
||||
if (nonEmptyNodes.includes(node.type)) return false
|
||||
if (node.text !== undefined && node.text?.trim().length > 0) return false
|
||||
|
||||
const content = node.content ?? []
|
||||
return content.every(isEmptyNode)
|
||||
}
|
||||
|
||||
// Markup
|
||||
|
||||
/** @public */
|
||||
@ -127,15 +50,8 @@ export function markupToPmNode (markup: Markup, schema?: Schema, extensions?: Ex
|
||||
return jsonToPmNode(json, schema, extensions)
|
||||
}
|
||||
|
||||
// JSON
|
||||
|
||||
/** @public */
|
||||
export function jsonToMarkup (json: MarkupNode): Markup {
|
||||
return JSON.stringify(json)
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function markupToJSON (markup: Markup): MarkupNode {
|
||||
export function markupHtmlToJSON (markup: Markup): MarkupNode {
|
||||
if (markup == null || markup === '') {
|
||||
return emptyMarkupNode()
|
||||
}
|
||||
@ -178,10 +94,10 @@ export function pmNodeToText (node: ProseMirrorNode): string {
|
||||
return jsonToText(node.toJSON())
|
||||
}
|
||||
|
||||
export function markupToText (markup: Markup, schema?: Schema, extensions?: Extensions): string {
|
||||
const pmNode = markupToPmNode(markup, schema, extensions)
|
||||
return pmNode.textBetween(0, pmNode.content.size, '\n', '')
|
||||
}
|
||||
// export function markupToText (markup: Markup, schema?: Schema, extensions?: Extensions): string {
|
||||
// const pmNode = markupToPmNode(markup, schema, extensions)
|
||||
// return pmNode.textBetween(0, pmNode.content.size, '\n', '')
|
||||
// }
|
||||
|
||||
// HTML
|
||||
|
||||
@ -191,11 +107,11 @@ export function htmlToMarkup (html: string, extensions?: Extensions): Markup {
|
||||
return jsonToMarkup(json)
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function markupToHTML (markup: Markup, extensions?: Extensions): string {
|
||||
const json = markupToJSON(markup)
|
||||
return jsonToHTML(json, extensions)
|
||||
}
|
||||
// /** @public */
|
||||
// export function markupToHTML (markup: Markup, extensions?: Extensions): string {
|
||||
// const json = markupToJSON(markup)
|
||||
// return jsonToHTML(json, extensions)
|
||||
// }
|
||||
|
||||
/** @public */
|
||||
export function htmlToJSON (html: string, extensions?: Extensions): MarkupNode {
|
||||
@ -221,55 +137,3 @@ export function pmNodeToHTML (node: ProseMirrorNode, extensions?: Extensions): s
|
||||
extensions ??= defaultExtensions
|
||||
return generateHTML(node.toJSON(), extensions)
|
||||
}
|
||||
|
||||
// UTILS
|
||||
|
||||
const ELLIPSIS_CHAR = '…'
|
||||
const WHITESPACE = ' '
|
||||
|
||||
/** @public */
|
||||
export function stripTags (markup: Markup, textLimit = 0, extensions: Extensions | undefined = undefined): string {
|
||||
const schema = extensions === undefined ? defaultSchema : getSchema(extensions)
|
||||
const parsed = markupToPmNode(markup, schema)
|
||||
|
||||
const textParts: string[] = []
|
||||
let charCount = 0
|
||||
let isHardStop = false
|
||||
|
||||
const pushText = (text: string): void => {
|
||||
if (textLimit > 0 && charCount + text.length > textLimit) {
|
||||
const toAddCount = textLimit - charCount
|
||||
const textPart = text.substring(0, toAddCount)
|
||||
textParts.push(textPart)
|
||||
textParts.push(ELLIPSIS_CHAR)
|
||||
isHardStop = true
|
||||
} else {
|
||||
textParts.push(text)
|
||||
charCount += text.length
|
||||
}
|
||||
}
|
||||
|
||||
parsed.descendants((node, _pos, parent): boolean => {
|
||||
if (isHardStop) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (node.type.isText) {
|
||||
const text = node.text ?? ''
|
||||
pushText(text)
|
||||
return false
|
||||
} else if (node.type.isBlock) {
|
||||
if (textParts.length > 0 && textParts[textParts.length - 1] !== WHITESPACE) {
|
||||
textParts.push(WHITESPACE)
|
||||
charCount++
|
||||
}
|
||||
} else if (node.type.name === 'reference') {
|
||||
const label = node.attrs.label ?? ''
|
||||
pushText(label.length > 0 ? `@${label}` : '')
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
const result = textParts.join('')
|
||||
return result
|
||||
}
|
||||
|
@ -35,7 +35,8 @@
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"@types/jest": "^29.5.5",
|
||||
"svelte-eslint-parser": "^0.33.1"
|
||||
"svelte-eslint-parser": "^0.33.1",
|
||||
"@types/crypto-js": "^4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/activity": "^0.6.0",
|
||||
@ -60,6 +61,7 @@
|
||||
"@hcengineering/view": "^0.6.13",
|
||||
"@hcengineering/view-resources": "^0.6.0",
|
||||
"@hcengineering/workbench": "^0.6.16",
|
||||
"svelte": "^4.2.19"
|
||||
"svelte": "^4.2.19",
|
||||
"crypto-js": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,9 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import { AvatarType, buildGravatarId, checkHasGravatar, type AvatarInfo } from '@hcengineering/contact'
|
||||
import MD5 from 'crypto-js/md5'
|
||||
|
||||
import { AvatarType, checkHasGravatar, type AvatarInfo } from '@hcengineering/contact'
|
||||
import type { Ref } from '@hcengineering/core'
|
||||
import { Blob as PlatformBlob } from '@hcengineering/core'
|
||||
import { Asset } from '@hcengineering/platform'
|
||||
@ -38,6 +40,10 @@
|
||||
import AvatarComponent from './Avatar.svelte'
|
||||
import EditAvatarPopup from './EditAvatarPopup.svelte'
|
||||
|
||||
function buildGravatarId (email: string): string {
|
||||
return MD5(email.trim().toLowerCase()).toString()
|
||||
}
|
||||
|
||||
export let selectedAvatarType: AvatarType
|
||||
export let selectedAvatar: AvatarInfo['avatar']
|
||||
export let selectedAvatarProps: AvatarInfo['avatarProps']
|
||||
|
@ -23,7 +23,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hcengineering/platform-rig": "^0.6.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
@ -42,8 +41,7 @@
|
||||
"@hcengineering/ui": "^0.6.15",
|
||||
"@hcengineering/core": "^0.6.32",
|
||||
"@hcengineering/templates": "^0.6.11",
|
||||
"@hcengineering/view": "^0.6.13",
|
||||
"crypto-js": "^4.1.1"
|
||||
"@hcengineering/view": "^0.6.13"
|
||||
},
|
||||
"repository": "https://github.com/hcengineering/platform",
|
||||
"publishConfig": {
|
||||
|
@ -16,7 +16,6 @@
|
||||
import { AttachedData, Class, Client, Doc, FindResult, Hierarchy, Ref } from '@hcengineering/core'
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import { ColorDefinition } from '@hcengineering/ui'
|
||||
import MD5 from 'crypto-js/md5'
|
||||
import { AvatarProvider, AvatarType, Channel, Contact, Person, contactPlugin } from '.'
|
||||
import { AVATAR_COLORS, GravatarPlaceholderType } from './types'
|
||||
|
||||
@ -48,13 +47,6 @@ export function getAvatarColorName (color: string): string {
|
||||
return AVATAR_COLORS.find((col) => col.color === color)?.name ?? AVATAR_COLORS[0].name
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function buildGravatarId (email: string): string {
|
||||
return MD5(email.trim().toLowerCase()).toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
@ -7,7 +7,6 @@ import { Analytics } from '@hcengineering/analytics'
|
||||
import { SplitLogger, configureAnalytics } from '@hcengineering/analytics-service'
|
||||
import contactPlugin from '@hcengineering/contact'
|
||||
import { MeasureMetricsContext, newMetrics, setOperationLogProfiling } from '@hcengineering/core'
|
||||
import notification from '@hcengineering/notification'
|
||||
import { setMetadata } from '@hcengineering/platform'
|
||||
import { serverConfigFromEnv } from '@hcengineering/server'
|
||||
import serverAiBot from '@hcengineering/server-ai-bot'
|
||||
@ -65,10 +64,7 @@ setMetadata(serverCore.metadata.FrontUrl, config.frontUrl)
|
||||
setMetadata(serverCore.metadata.FilesUrl, config.filesUrl)
|
||||
setMetadata(serverToken.metadata.Secret, config.serverSecret)
|
||||
setMetadata(serverNotification.metadata.SesUrl, config.sesUrl ?? '')
|
||||
setMetadata(notification.metadata.PushPublicKey, config.pushPublicKey)
|
||||
setMetadata(serverNotification.metadata.PushPrivateKey, config.pushPrivateKey)
|
||||
setMetadata(serverNotification.metadata.PushSubject, config.pushSubject)
|
||||
setMetadata(serverCore.metadata.ElasticIndexVersion, 'v1')
|
||||
setMetadata(serverNotification.metadata.SesAuthToken, config.sesAuthToken)
|
||||
setMetadata(serverTelegram.metadata.BotUrl, process.env.TELEGRAM_BOT_URL)
|
||||
setMetadata(serverAiBot.metadata.SupportWorkspaceId, process.env.SUPPORT_WORKSPACE)
|
||||
setMetadata(serverAiBot.metadata.EndpointURL, process.env.AI_BOT_URL)
|
||||
|
@ -475,6 +475,11 @@
|
||||
"projectFolder": "packages/theme",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@hcengineering/text-core",
|
||||
"projectFolder": "packages/text-core",
|
||||
"shouldPublish": true
|
||||
},
|
||||
{
|
||||
"packageName": "@hcengineering/text",
|
||||
"projectFolder": "packages/text",
|
||||
|
@ -44,7 +44,7 @@
|
||||
"@hcengineering/server-activity": "^0.6.0",
|
||||
"@hcengineering/server-core": "^0.6.1",
|
||||
"@hcengineering/server-notification-resources": "^0.6.0",
|
||||
"@hcengineering/text": "^0.6.5",
|
||||
"@hcengineering/text-core": "^0.6.0",
|
||||
"@hcengineering/contact": "^0.6.24"
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import { Class, Doc, Ref } from '@hcengineering/core'
|
||||
import { EmptyMarkup, MarkupNodeType, jsonToMarkup } from '@hcengineering/text'
|
||||
import { EmptyMarkup, MarkupNodeType, jsonToMarkup } from '@hcengineering/text-core'
|
||||
|
||||
import { getReferencesData } from '../references'
|
||||
|
||||
|
@ -51,7 +51,7 @@ import {
|
||||
toReceiverInfo,
|
||||
type NotificationProviderControl
|
||||
} from '@hcengineering/server-notification-resources'
|
||||
import { areEqualJson, extractReferences, jsonToMarkup, markupToJSON } from '@hcengineering/text'
|
||||
import { areEqualJson, extractReferences, jsonToMarkup, markupToJSON } from '@hcengineering/text-core'
|
||||
|
||||
export function isDocMentioned (doc: Ref<Doc>, content: string): boolean {
|
||||
const references = []
|
||||
|
@ -50,6 +50,6 @@
|
||||
"@hcengineering/server-notification": "^0.6.1",
|
||||
"@hcengineering/server-notification-resources": "^0.6.0",
|
||||
"@hcengineering/server": "^0.6.4",
|
||||
"@hcengineering/text": "^0.6.5"
|
||||
"@hcengineering/text-core": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ import {
|
||||
getDocCollaborators,
|
||||
getMixinTx
|
||||
} from '@hcengineering/server-notification-resources'
|
||||
import { markupToHTML, markupToText, stripTags } from '@hcengineering/text'
|
||||
import { markupToHTML, markupToText, stripTags } from '@hcengineering/text-core'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
|
||||
import { getPersonAccountById, NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
|
||||
|
@ -45,7 +45,6 @@
|
||||
"@hcengineering/server-token": "^0.6.11",
|
||||
"@hcengineering/chunter": "^0.6.20",
|
||||
"@hcengineering/server-chunter-resources": "^0.6.0",
|
||||
"@hcengineering/text": "^0.6.5",
|
||||
"@hcengineering/request": "^0.6.14",
|
||||
"@hcengineering/controlled-documents": "^0.1.0",
|
||||
"@hcengineering/training": "^0.1.0"
|
||||
|
@ -45,7 +45,6 @@
|
||||
"@hcengineering/platform": "^0.6.11",
|
||||
"@hcengineering/server-core": "^0.6.1",
|
||||
"@hcengineering/server-notification": "^0.6.1",
|
||||
"@hcengineering/server-notification-resources": "^0.6.0",
|
||||
"@hcengineering/text": "^0.6.5"
|
||||
"@hcengineering/server-notification-resources": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -115,10 +115,12 @@ export async function sendEmailNotification (
|
||||
ctx.error('Please provide email service url to enable email notifications.')
|
||||
return
|
||||
}
|
||||
const sesAuth: string | undefined = getMetadata(serverNotification.metadata.SesAuthToken)
|
||||
await fetch(concatLink(sesURL, '/send'), {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': 'application/json',
|
||||
...(sesAuth != null ? { Authorization: `Bearer ${sesAuth}` } : {})
|
||||
},
|
||||
body: JSON.stringify({
|
||||
text,
|
||||
|
@ -34,8 +34,7 @@
|
||||
"typescript": "^5.3.3",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@types/web-push": "~3.6.3"
|
||||
"@types/jest": "^29.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/activity": "^0.6.0",
|
||||
@ -48,9 +47,8 @@
|
||||
"@hcengineering/workbench": "^0.6.16",
|
||||
"@hcengineering/chunter": "^0.6.20",
|
||||
"@hcengineering/view": "^0.6.13",
|
||||
"@hcengineering/text": "^0.6.5",
|
||||
"@hcengineering/text-core": "^0.6.0",
|
||||
"@hcengineering/contact": "^0.6.24",
|
||||
"@hcengineering/server-view": "^0.6.0",
|
||||
"web-push": "~3.6.7"
|
||||
"@hcengineering/server-view": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -79,10 +79,9 @@ import serverNotification, {
|
||||
SenderInfo
|
||||
} from '@hcengineering/server-notification'
|
||||
import serverView from '@hcengineering/server-view'
|
||||
import { markupToText, stripTags } from '@hcengineering/text'
|
||||
import { markupToText, stripTags } from '@hcengineering/text-core'
|
||||
import { encodeObjectURI } from '@hcengineering/view'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
import webpush, { WebPushError } from 'web-push'
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
|
||||
import { Content, ContextsCache, ContextsCacheKey, NotifyParams, NotifyResult } from './types'
|
||||
@ -574,10 +573,9 @@ export async function createPushNotification (
|
||||
senderAvatar?: Data<AvatarInfo>,
|
||||
path?: string[]
|
||||
): Promise<void> {
|
||||
const publicKey = getMetadata(notification.metadata.PushPublicKey)
|
||||
const privateKey = getMetadata(serverNotification.metadata.PushPrivateKey)
|
||||
const subject = getMetadata(serverNotification.metadata.PushSubject) ?? 'mailto:hey@huly.io'
|
||||
if (privateKey === undefined || publicKey === undefined) return
|
||||
const sesURL: string | undefined = getMetadata(serverNotification.metadata.SesUrl)
|
||||
const sesAuth: string | undefined = getMetadata(serverNotification.metadata.SesAuthToken)
|
||||
if (sesURL === undefined || sesURL === '') return
|
||||
const userSubscriptions = subscriptions.filter((it) => it.user === target)
|
||||
const data: PushData = {
|
||||
title,
|
||||
@ -604,34 +602,45 @@ export async function createPushNotification (
|
||||
}
|
||||
}
|
||||
|
||||
webpush.setVapidDetails(subject, publicKey, privateKey)
|
||||
const limiter = new RateLimiter(5)
|
||||
|
||||
for (const subscription of userSubscriptions) {
|
||||
await limiter.add(async () => {
|
||||
await sendPushToSubscription(control, target, subscription, data)
|
||||
await sendPushToSubscription(sesURL, sesAuth, control, target, subscription, data)
|
||||
})
|
||||
}
|
||||
await limiter.waitProcessing()
|
||||
}
|
||||
|
||||
const errorMessages = ['expired', 'Unregistered', 'No such subscription']
|
||||
|
||||
async function sendPushToSubscription (
|
||||
sesURL: string,
|
||||
sesAuth: string | undefined,
|
||||
control: TriggerControl,
|
||||
targetUser: Ref<Account>,
|
||||
subscription: PushSubscription,
|
||||
data: PushData
|
||||
): Promise<void> {
|
||||
try {
|
||||
await webpush.sendNotification(subscription, JSON.stringify(data))
|
||||
const result: 'ok' | 'clear-push' = (
|
||||
await (
|
||||
await fetch(concatLink(sesURL, '/web-push'), {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(sesAuth != null ? { Authorization: `Bearer ${sesAuth}` } : {})
|
||||
},
|
||||
body: JSON.stringify({
|
||||
subscription,
|
||||
data
|
||||
})
|
||||
})
|
||||
).json()
|
||||
).result
|
||||
if (result === 'clear-push') {
|
||||
const tx = control.txFactory.createTxRemoveDoc(subscription._class, subscription.space, subscription._id)
|
||||
await control.apply(control.ctx, [tx])
|
||||
}
|
||||
} catch (err) {
|
||||
control.ctx.info('Cannot send push notification to', { user: targetUser, err })
|
||||
if (err instanceof WebPushError) {
|
||||
if (errorMessages.some((p) => JSON.stringify((err as WebPushError).body).includes(p))) {
|
||||
const tx = control.txFactory.createTxRemoveDoc(subscription._class, subscription.space, subscription._id)
|
||||
await control.apply(control.ctx, [tx])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,8 +151,7 @@ export const PUSH_NOTIFICATION_TITLE_SIZE = 80
|
||||
export default plugin(serverNotificationId, {
|
||||
metadata: {
|
||||
SesUrl: '' as Metadata<string>,
|
||||
PushPrivateKey: '' as Metadata<string>,
|
||||
PushSubject: '' as Metadata<string>,
|
||||
SesAuthToken: '' as Metadata<string>,
|
||||
InboxOnlyNotifications: '' as Metadata<boolean>
|
||||
},
|
||||
class: {
|
||||
|
@ -50,6 +50,6 @@
|
||||
"@hcengineering/server-token": "^0.6.11",
|
||||
"@hcengineering/setting": "^0.6.17",
|
||||
"@hcengineering/telegram": "^0.6.21",
|
||||
"@hcengineering/text": "^0.6.5"
|
||||
"@hcengineering/text-core": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ import serverTelegram from '@hcengineering/server-telegram'
|
||||
import { generateToken } from '@hcengineering/server-token'
|
||||
import setting, { Integration } from '@hcengineering/setting'
|
||||
import telegram, { TelegramMessage, TelegramNotificationRequest } from '@hcengineering/telegram'
|
||||
import { markupToHTML } from '@hcengineering/text'
|
||||
import { markupToHTML } from '@hcengineering/text-core'
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
@ -47,7 +47,7 @@
|
||||
"@hcengineering/task": "^0.6.20",
|
||||
"@hcengineering/tracker": "^0.6.24",
|
||||
"@hcengineering/server-time": "^0.6.0",
|
||||
"@hcengineering/text": "^0.6.5",
|
||||
"@hcengineering/text-core": "^0.6.0",
|
||||
"@hcengineering/time": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ import {
|
||||
} from '@hcengineering/server-notification-resources'
|
||||
import serverTime, { OnToDo, ToDoFactory } from '@hcengineering/server-time'
|
||||
import task, { makeRank } from '@hcengineering/task'
|
||||
import { jsonToMarkup, nodeDoc, nodeParagraph, nodeText } from '@hcengineering/text'
|
||||
import { jsonToMarkup, nodeDoc, nodeParagraph, nodeText } from '@hcengineering/text-core'
|
||||
import time, { ProjectToDo, ToDo, ToDoPriority, TodoAutomationHelper, WorkSlot } from '@hcengineering/time'
|
||||
import tracker, { Issue, IssueStatus, Project, TimeSpendReport } from '@hcengineering/tracker'
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
"@hcengineering/server-notification": "^0.6.1",
|
||||
"@hcengineering/server-task-resources": "^0.6.0",
|
||||
"@hcengineering/task": "^0.6.20",
|
||||
"@hcengineering/text": "^0.6.5",
|
||||
"@hcengineering/text-core": "^0.6.0",
|
||||
"@hcengineering/tracker": "^0.6.24",
|
||||
"@hcengineering/view": "^0.6.13",
|
||||
"@hcengineering/workbench": "^0.6.16"
|
||||
|
@ -35,7 +35,7 @@ import { NotificationContent } from '@hcengineering/notification'
|
||||
import { getMetadata, IntlString } from '@hcengineering/platform'
|
||||
import serverCore, { TriggerControl } from '@hcengineering/server-core'
|
||||
import { NOTIFICATION_BODY_SIZE } from '@hcengineering/server-notification'
|
||||
import { stripTags } from '@hcengineering/text'
|
||||
import { stripTags } from '@hcengineering/text-core'
|
||||
import tracker, { Component, Issue, IssueParentInfo, TimeSpendReport, trackerId } from '@hcengineering/tracker'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@types/otp-generator": "^4.0.2"
|
||||
"@types/otp-generator": "^4.0.2",
|
||||
"@types/crypto-js": "^4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/mongo": "^0.6.1",
|
||||
@ -55,6 +56,7 @@
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/server-storage": "^0.6.0",
|
||||
"@hcengineering/server-core": "^0.6.1",
|
||||
"@hcengineering/server-pipeline": "^0.6.0"
|
||||
"@hcengineering/server-pipeline": "^0.6.0",
|
||||
"crypto-js": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import contact, {
|
||||
AvatarType,
|
||||
buildGravatarId,
|
||||
checkHasGravatar,
|
||||
combineName,
|
||||
Employee,
|
||||
@ -95,6 +94,10 @@ import {
|
||||
} from './utils'
|
||||
import { getWorkspaceDestroyAdapter } from '@hcengineering/server-pipeline'
|
||||
|
||||
import MD5 from 'crypto-js/md5'
|
||||
function buildGravatarId (email: string): string {
|
||||
return MD5(email.trim().toLowerCase()).toString()
|
||||
}
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
@ -6,12 +6,10 @@ export interface ServerEnv {
|
||||
frontUrl: string
|
||||
filesUrl: string | undefined
|
||||
sesUrl: string | undefined
|
||||
sesAuthToken: string | undefined
|
||||
accountsUrl: string
|
||||
serverPort: number
|
||||
enableCompression: boolean
|
||||
pushPublicKey: string | undefined
|
||||
pushPrivateKey: string | undefined
|
||||
pushSubject: string | undefined
|
||||
brandingPath: string | undefined
|
||||
}
|
||||
|
||||
@ -47,6 +45,7 @@ export function serverConfigFromEnv (): ServerEnv {
|
||||
|
||||
const filesUrl = process.env.FILES_URL
|
||||
const sesUrl = process.env.SES_URL
|
||||
const sesAuthToken = process.env.SES_AUTH_TOKEN
|
||||
|
||||
const accountsUrl = process.env.ACCOUNTS_URL
|
||||
if (accountsUrl === undefined) {
|
||||
@ -54,9 +53,6 @@ export function serverConfigFromEnv (): ServerEnv {
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const pushPublicKey = process.env.PUSH_PUBLIC_KEY
|
||||
const pushPrivateKey = process.env.PUSH_PRIVATE_KEY
|
||||
const pushSubject = process.env.PUSH_SUBJECT
|
||||
const brandingPath = process.env.BRANDING_PATH
|
||||
|
||||
return {
|
||||
@ -67,12 +63,10 @@ export function serverConfigFromEnv (): ServerEnv {
|
||||
frontUrl,
|
||||
filesUrl,
|
||||
sesUrl,
|
||||
sesAuthToken,
|
||||
accountsUrl,
|
||||
serverPort,
|
||||
enableCompression,
|
||||
pushPublicKey,
|
||||
pushPrivateKey,
|
||||
pushSubject,
|
||||
brandingPath
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,8 @@
|
||||
"@tsconfig/node16": "^1.0.4",
|
||||
"@types/cors": "^2.8.12",
|
||||
"@types/express": "^4.17.13",
|
||||
"eslint-plugin-node": "^11.1.0"
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"@types/web-push": "^3.6.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/client": "^0.6.18",
|
||||
@ -62,6 +63,7 @@
|
||||
"aws-sdk": "^2.1423.0",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "~16.0.0",
|
||||
"express": "^4.21.2"
|
||||
"express": "^4.21.2",
|
||||
"web-push": "^3.6.7"
|
||||
}
|
||||
}
|
||||
|
@ -19,14 +19,22 @@ interface Config {
|
||||
AccessKey: string
|
||||
SecretKey: string
|
||||
Region: string
|
||||
AuthToken?: string
|
||||
PushSubject?: string
|
||||
PushPublicKey?: string
|
||||
PushPrivateKey?: string
|
||||
}
|
||||
|
||||
const envMap: { [key in keyof Config]: string } = {
|
||||
const envMap: { [key in keyof Required<Config>]: string } = {
|
||||
Port: 'PORT',
|
||||
Source: 'SOURCE',
|
||||
AccessKey: 'ACCESS_KEY',
|
||||
SecretKey: 'SECRET_KEY',
|
||||
Region: 'REGION'
|
||||
Region: 'REGION',
|
||||
AuthToken: 'AUTH_TOKEN',
|
||||
PushPublicKey: 'PUSH_PUBLIC_KEY',
|
||||
PushPrivateKey: 'PUSH_PRIVATE_KEY',
|
||||
PushSubject: 'PUSH_SUBJECT'
|
||||
}
|
||||
|
||||
const parseNumber = (str: string | undefined): number | undefined => (str !== undefined ? Number(str) : undefined)
|
||||
@ -37,7 +45,11 @@ const config: Config = (() => {
|
||||
Source: process.env[envMap.Source],
|
||||
AccessKey: process.env[envMap.AccessKey],
|
||||
SecretKey: process.env[envMap.SecretKey],
|
||||
Region: process.env[envMap.Region] ?? 'us-east-1'
|
||||
Region: process.env[envMap.Region] ?? 'us-east-1',
|
||||
AuthToken: process.env[envMap.AuthToken],
|
||||
PushPublicKey: process.env[envMap.PushPublicKey],
|
||||
PushPrivateKey: process.env[envMap.PushPrivateKey],
|
||||
PushSubject: process.env[envMap.PushSubject]
|
||||
}
|
||||
|
||||
const required: Array<keyof Config> = ['Port', 'Source', 'AccessKey', 'SecretKey', 'Region']
|
||||
|
@ -13,20 +13,57 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { PushSubscription, type PushData } from '@hcengineering/notification'
|
||||
import type { Request, Response } from 'express'
|
||||
import webpush, { WebPushError } from 'web-push'
|
||||
import config from './config'
|
||||
import { createServer, listen } from './server'
|
||||
import { SES } from './ses'
|
||||
import { Endpoint } from './types'
|
||||
|
||||
const errorMessages = ['expired', 'Unregistered', 'No such subscription']
|
||||
async function sendPushToSubscription (subscription: PushSubscription, data: PushData): Promise<'ok' | 'clear-push'> {
|
||||
try {
|
||||
await webpush.sendNotification(subscription, JSON.stringify(data))
|
||||
} catch (err: any) {
|
||||
if (err instanceof WebPushError) {
|
||||
if (errorMessages.some((p) => JSON.stringify((err as WebPushError).body).includes(p))) {
|
||||
return 'clear-push'
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'ok'
|
||||
}
|
||||
|
||||
export const main = async (): Promise<void> => {
|
||||
const ses = new SES()
|
||||
console.log('SES service has been started')
|
||||
|
||||
if (config.PushPublicKey !== undefined && config.PushPrivateKey !== undefined) {
|
||||
webpush.setVapidDetails(config.PushSubject ?? 'mailto:hey@huly.io', config.PushPublicKey, config.PushPublicKey)
|
||||
}
|
||||
|
||||
const checkAuth = (req: Request<any>, res: Response<any>): boolean => {
|
||||
if (config.AuthToken !== undefined) {
|
||||
// We need to verify authorization
|
||||
const authorization = req.headers.authorization ?? ''
|
||||
const token = authorization.replace('Bearer ', '')
|
||||
if (token !== config.AuthToken) {
|
||||
res.status(401).send({ err: 'Invalid auth token' })
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const endpoints: Endpoint[] = [
|
||||
{
|
||||
endpoint: '/send',
|
||||
type: 'post',
|
||||
handler: async (req, res) => {
|
||||
if (!checkAuth(req, res)) {
|
||||
return
|
||||
}
|
||||
const text = req.body?.text
|
||||
if (text === undefined) {
|
||||
res.status(400).send({ err: "'text' is missing" })
|
||||
@ -54,6 +91,28 @@ export const main = async (): Promise<void> => {
|
||||
|
||||
res.send()
|
||||
}
|
||||
},
|
||||
{
|
||||
endpoint: '/web-push',
|
||||
type: 'post',
|
||||
handler: async (req, res) => {
|
||||
if (!checkAuth(req, res)) {
|
||||
return
|
||||
}
|
||||
const data: PushData | undefined = req.body?.data
|
||||
if (data === undefined) {
|
||||
res.status(400).send({ err: "'data' is missing" })
|
||||
return
|
||||
}
|
||||
const subscription: PushSubscription | undefined = req.body?.subscription
|
||||
if (subscription === undefined) {
|
||||
res.status(400).send({ err: "'subscription' is missing" })
|
||||
return
|
||||
}
|
||||
|
||||
const result = await sendPushToSubscription(subscription, data)
|
||||
res.json({ result })
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -17,5 +17,7 @@ done <<< "$files"
|
||||
|
||||
# Sort the array by size (numerically, in descending order) and print
|
||||
printf '%s\n' "${file_info[@]}" | sort -t: -k1,1nr | while IFS=: read -r size path; do
|
||||
echo "Size: $(($size/1024)) KB - $path"
|
||||
if [ $(($size/1024)) -ne 0 ]; then
|
||||
echo "Size: $(($size/1024)) KB - $path"
|
||||
fi
|
||||
done
|
@ -54,7 +54,12 @@
|
||||
"@hcengineering/server-client": "^0.6.0",
|
||||
"@hcengineering/server-pipeline": "^0.6.0",
|
||||
"@hcengineering/server-token": "^0.6.11",
|
||||
"@hcengineering/contact": "^0.6.24",
|
||||
"@hcengineering/storage": "^0.6.0",
|
||||
"@hcengineering/server-notification": "^0.6.1",
|
||||
"@hcengineering/notification": "^0.6.23",
|
||||
"@hcengineering/server-ai-bot": "^0.6.0",
|
||||
"@hcengineering/server-telegram": "^0.6.0",
|
||||
"itty-router": "^5.0.18",
|
||||
"snappyjs": "^0.7.0"
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import { setMetadata } from '@hcengineering/platform'
|
||||
import { RPCHandler } from '@hcengineering/rpc'
|
||||
import { ClientSession, createSessionManager, doSessionOp, type WebsocketData } from '@hcengineering/server'
|
||||
import serverClient from '@hcengineering/server-client'
|
||||
import {
|
||||
import serverCore, {
|
||||
createDummyStorageAdapter,
|
||||
initStatisticsContext,
|
||||
loadBrandingMap,
|
||||
@ -52,6 +52,12 @@ import {
|
||||
} from '@hcengineering/server-pipeline'
|
||||
import { CloudFlareLogger } from './logger'
|
||||
import model from './model.json'
|
||||
// import { configureAnalytics } from '@hcengineering/analytics-service'
|
||||
// import { Analytics } from '@hcengineering/analytics'
|
||||
import serverAiBot from '@hcengineering/server-ai-bot'
|
||||
import serverNotification from '@hcengineering/server-notification'
|
||||
import serverTelegram from '@hcengineering/server-telegram'
|
||||
import contactPlugin from '@hcengineering/contact'
|
||||
|
||||
export const PREFERRED_SAVE_SIZE = 500
|
||||
export const PREFERRED_SAVE_INTERVAL = 30 * 1000
|
||||
@ -82,6 +88,20 @@ export class Transactor extends DurableObject<Env> {
|
||||
setExtraOptions({
|
||||
useCF: true
|
||||
})
|
||||
|
||||
// configureAnalytics(env.SENTRY_DSN, {})
|
||||
// Analytics.setTag('application', 'transactor')
|
||||
|
||||
const lastNameFirst = process.env.LAST_NAME_FIRST === 'true'
|
||||
setMetadata(contactPlugin.metadata.LastNameFirst, lastNameFirst)
|
||||
setMetadata(serverCore.metadata.FrontUrl, env.FRONT_URL)
|
||||
setMetadata(serverCore.metadata.FilesUrl, env.FILES_URL)
|
||||
setMetadata(serverNotification.metadata.SesUrl, env.SES_URL ?? '')
|
||||
setMetadata(serverNotification.metadata.SesAuthToken, env.SES_AUTH_TOKEN)
|
||||
setMetadata(serverTelegram.metadata.BotUrl, process.env.TELEGRAM_BOT_URL)
|
||||
setMetadata(serverAiBot.metadata.SupportWorkspaceId, process.env.SUPPORT_WORKSPACE)
|
||||
setMetadata(serverAiBot.metadata.EndpointURL, process.env.AI_BOT_URL)
|
||||
|
||||
registerTxAdapterFactory('postgresql', createPostgresTxAdapter, true)
|
||||
registerAdapterFactory('postgresql', createPostgresAdapter, true)
|
||||
registerDestroyFactory('postgresql', createPostgreeDestroyAdapter, true)
|
||||
|
12
workers/transactor/worker-configuration.d.ts
vendored
12
workers/transactor/worker-configuration.d.ts
vendored
@ -18,4 +18,16 @@ interface Env {
|
||||
FULLTEXT_URL: string | undefined
|
||||
|
||||
DB_MODE: 'hyperdrive' | 'direct' | undefined
|
||||
|
||||
FRONT_URL: string
|
||||
|
||||
FILES_URL?: string
|
||||
|
||||
SES_URL?: string
|
||||
SES_AUTH_TOKEN?: string
|
||||
SUPPORT_WORKSPACE?: string
|
||||
TELEGRAM_BOT_URL: string
|
||||
AI_BOT_URL?: string
|
||||
LAST_NAME_FIRST?: string
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,18 @@ mode = "smart"
|
||||
# ACCOUNTS_URL = "http://127.0.0.1:3000"
|
||||
# SERVER_SECRET = "secret"
|
||||
DB_MODE='hyperdrive'
|
||||
# FRONT_URL
|
||||
ENABLE_COMPRESSION=true
|
||||
# ACCOUNTS_URL
|
||||
# FULLTEXT_URL
|
||||
# STATS_URL
|
||||
# PUSH_PUBLIC_KEY
|
||||
# PUSH_PRIVATE_KEY
|
||||
# SENTRY_DSN
|
||||
# SUPPORT_WORKSPACE
|
||||
# TELEGRAM_BOT_URL
|
||||
# AI_BOT_URL
|
||||
# LAST_NAME_FIRST
|
||||
|
||||
# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network
|
||||
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai
|
||||
|
Loading…
Reference in New Issue
Block a user