@harperfast/harper 5.3.0-beta.4 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/bin/backup.ts +6 -1
  2. package/components/Application.ts +486 -115
  3. package/components/DESIGN.md +109 -21
  4. package/components/deploymentProvenance.ts +28 -0
  5. package/components/operations.js +14 -7
  6. package/components/packageComponent.ts +5 -1
  7. package/config-root.schema.json +1 -1
  8. package/dataLayer/DESIGN.md +35 -7
  9. package/dataLayer/blobBackup.ts +71 -30
  10. package/dataLayer/harperBridge/ResourceBridge.ts +16 -2
  11. package/dataLayer/rocksdbBackup.ts +88 -34
  12. package/dataLayer/schemaDescribe.ts +45 -1
  13. package/dist/bin/backup.js +1 -1
  14. package/dist/bin/backup.js.map +1 -1
  15. package/dist/components/Application.d.ts +11 -21
  16. package/dist/components/Application.js +436 -105
  17. package/dist/components/Application.js.map +1 -1
  18. package/dist/components/deploymentProvenance.d.ts +4 -0
  19. package/dist/components/deploymentProvenance.js +32 -0
  20. package/dist/components/deploymentProvenance.js.map +1 -0
  21. package/dist/components/operations.js +14 -7
  22. package/dist/components/operations.js.map +1 -1
  23. package/dist/components/packageComponent.js +6 -1
  24. package/dist/components/packageComponent.js.map +1 -1
  25. package/dist/dataLayer/blobBackup.d.ts +30 -3
  26. package/dist/dataLayer/blobBackup.js +73 -36
  27. package/dist/dataLayer/blobBackup.js.map +1 -1
  28. package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +1 -0
  29. package/dist/dataLayer/harperBridge/ResourceBridge.js +15 -3
  30. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  31. package/dist/dataLayer/rocksdbBackup.d.ts +4 -1
  32. package/dist/dataLayer/rocksdbBackup.js +74 -36
  33. package/dist/dataLayer/rocksdbBackup.js.map +1 -1
  34. package/dist/dataLayer/schemaDescribe.js +45 -1
  35. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  36. package/dist/resources/DatabaseTransaction.d.ts +1 -0
  37. package/dist/resources/DatabaseTransaction.js +33 -8
  38. package/dist/resources/DatabaseTransaction.js.map +1 -1
  39. package/dist/resources/ResourceInterface.d.ts +7 -3
  40. package/dist/resources/ResourceInterface.js +2 -0
  41. package/dist/resources/ResourceInterface.js.map +1 -1
  42. package/dist/resources/Table.d.ts +151 -445
  43. package/dist/resources/Table.js +209 -8
  44. package/dist/resources/Table.js.map +1 -1
  45. package/dist/resources/analytics/write.d.ts +11 -0
  46. package/dist/resources/analytics/write.js +3 -0
  47. package/dist/resources/analytics/write.js.map +1 -1
  48. package/dist/resources/blob.d.ts +30 -0
  49. package/dist/resources/blob.js +189 -1
  50. package/dist/resources/blob.js.map +1 -1
  51. package/dist/resources/databases.d.ts +1 -0
  52. package/dist/resources/databases.js +80 -15
  53. package/dist/resources/databases.js.map +1 -1
  54. package/dist/resources/derivedIndexRuntime.d.ts +13 -0
  55. package/dist/resources/derivedIndexRuntime.js +57 -5
  56. package/dist/resources/derivedIndexRuntime.js.map +1 -1
  57. package/dist/resources/derivedIndexes.d.ts +1 -0
  58. package/dist/resources/derivedIndexes.js +116 -15
  59. package/dist/resources/derivedIndexes.js.map +1 -1
  60. package/dist/resources/fullTextSchema.d.ts +5 -3
  61. package/dist/resources/fullTextSchema.js +48 -5
  62. package/dist/resources/fullTextSchema.js.map +1 -1
  63. package/dist/resources/fullTextSchemaLifecycle.d.ts +2 -0
  64. package/dist/resources/fullTextSchemaLifecycle.js +33 -0
  65. package/dist/resources/fullTextSchemaLifecycle.js.map +1 -1
  66. package/dist/resources/graphql.js +30 -12
  67. package/dist/resources/graphql.js.map +1 -1
  68. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +21 -1
  69. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +114 -5
  70. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  71. package/dist/resources/indexes/fullTextDerivedIndex.d.ts +11 -2
  72. package/dist/resources/indexes/fullTextDerivedIndex.js +187 -24
  73. package/dist/resources/indexes/fullTextDerivedIndex.js.map +1 -1
  74. package/dist/resources/indexes/fullTextNativeBinding.d.ts +99 -1
  75. package/dist/resources/indexes/fullTextNativeBinding.js +35 -1
  76. package/dist/resources/indexes/fullTextNativeBinding.js.map +1 -1
  77. package/dist/resources/indexes/fullTextQueryIndex.d.ts +58 -0
  78. package/dist/resources/indexes/fullTextQueryIndex.js +943 -0
  79. package/dist/resources/indexes/fullTextQueryIndex.js.map +1 -0
  80. package/dist/resources/indexes/fullTextQueryProtocol.d.ts +6 -0
  81. package/dist/resources/indexes/fullTextQueryProtocol.js +32 -0
  82. package/dist/resources/indexes/fullTextQueryProtocol.js.map +1 -0
  83. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.d.ts +4 -1
  84. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js +30 -7
  85. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js.map +1 -1
  86. package/dist/resources/search.d.ts +41 -0
  87. package/dist/resources/search.js +468 -26
  88. package/dist/resources/search.js.map +1 -1
  89. package/dist/resources/transactionBroadcast.js +101 -50
  90. package/dist/resources/transactionBroadcast.js.map +1 -1
  91. package/dist/resources/typeParity.d.ts +9 -0
  92. package/dist/resources/typeParity.js +3 -0
  93. package/dist/resources/typeParity.js.map +1 -0
  94. package/dist/server/REST.js.map +1 -1
  95. package/dist/server/itc/serverHandlers.js +48 -8
  96. package/dist/server/itc/serverHandlers.js.map +1 -1
  97. package/dist/server/serverHelpers/contentTypes.d.ts +7 -0
  98. package/dist/server/serverHelpers/contentTypes.js +36 -23
  99. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  100. package/dist/server/serverHelpers/uwsServer.js +28 -5
  101. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  102. package/dist/server/threads/itc.js +19 -0
  103. package/dist/server/threads/itc.js.map +1 -1
  104. package/dist/server/threads/manageThreads.d.ts +3 -0
  105. package/dist/server/threads/manageThreads.js +90 -23
  106. package/dist/server/threads/manageThreads.js.map +1 -1
  107. package/dist/utility/operation_authorization.js +25 -7
  108. package/dist/utility/operation_authorization.js.map +1 -1
  109. package/dist/utility/signalling.js +3 -0
  110. package/dist/utility/signalling.js.map +1 -1
  111. package/dist/validation/searchValidator.js +22 -2
  112. package/dist/validation/searchValidator.js.map +1 -1
  113. package/npm-shrinkwrap.json +22 -22
  114. package/package.json +2 -4
  115. package/resources/DESIGN.md +19 -2
  116. package/resources/DatabaseTransaction.ts +40 -10
  117. package/resources/FULL_TEXT.md +97 -0
  118. package/resources/ResourceInterface.ts +8 -2
  119. package/resources/Table.ts +767 -17
  120. package/resources/analytics/write.ts +3 -3
  121. package/resources/blob.ts +183 -1
  122. package/resources/databases.ts +126 -14
  123. package/resources/derivedIndexRuntime.ts +79 -6
  124. package/resources/derivedIndexes.ts +142 -18
  125. package/resources/fullTextSchema.ts +55 -9
  126. package/resources/fullTextSchemaLifecycle.ts +45 -0
  127. package/resources/graphql.ts +33 -12
  128. package/resources/indexes/DESIGN.md +167 -15
  129. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +125 -5
  130. package/resources/indexes/fullTextDerivedIndex.ts +216 -32
  131. package/resources/indexes/fullTextNativeBinding.ts +133 -3
  132. package/resources/indexes/fullTextQueryIndex.ts +1120 -0
  133. package/resources/indexes/fullTextQueryProtocol.ts +35 -0
  134. package/resources/indexes/nativeFullTextDerivedIndexLifecycle.ts +28 -8
  135. package/resources/search.ts +513 -26
  136. package/resources/transactionBroadcast.ts +86 -47
  137. package/resources/typeParity.ts +20 -0
  138. package/schema.graphql +18 -5
  139. package/server/DESIGN.md +18 -0
  140. package/server/REST.ts +1 -1
  141. package/server/itc/serverHandlers.js +61 -8
  142. package/server/serverHelpers/contentTypes.ts +31 -26
  143. package/server/serverHelpers/uwsServer.ts +35 -7
  144. package/server/threads/itc.js +21 -0
  145. package/server/threads/manageThreads.js +95 -21
  146. package/studio/web/assets/{Chat-Bq60AO-g.js → Chat-CNEKMllJ.js} +13 -13
  147. package/studio/web/assets/FloatingChat-CEnWhHeR.js +23 -0
  148. package/studio/web/assets/SearchDialog-CwhJdEdY.js +1 -0
  149. package/studio/web/assets/{abnfDiagram-O67JEVCF-DpPZWMOf.js → abnfDiagram-O67JEVCF-raXE027J.js} +1 -1
  150. package/studio/web/assets/alertDialog-BbWD9Xxa.js +1 -0
  151. package/studio/web/assets/apiToken-DC5vsaaO.js +1 -0
  152. package/studio/web/assets/applications-DQZxDy0x.js +296 -0
  153. package/studio/web/assets/architecture-7GRP2DOG-DDmz3hpI.js +1 -0
  154. package/studio/web/assets/{architectureDiagram-NJMV4G6O-OmgLraID.js → architectureDiagram-NJMV4G6O-C8_Eet7w.js} +1 -1
  155. package/studio/web/assets/arrow-up-D2g_57vT.js +1 -0
  156. package/studio/web/assets/authStore-CJCaADw9.js +3 -0
  157. package/studio/web/assets/{blockDiagram-BEXU5L5S-Cv7CD3Ai.js → blockDiagram-BEXU5L5S-DR6S5-1D.js} +1 -1
  158. package/studio/web/assets/{button-MFP9n8Ck.js → button-DWwfgGWI.js} +2 -2
  159. package/studio/web/assets/{c4Diagram-YGBWAQC7-Ds1vKYnN.js → c4Diagram-YGBWAQC7-BAfZ1G01.js} +1 -1
  160. package/studio/web/assets/channel-D0AkPjJ8.js +1 -0
  161. package/studio/web/assets/{chevron-up-CFe8x5Bp.js → chevron-up-CFxbMGv2.js} +1 -1
  162. package/studio/web/assets/{chunk-3FUC2YCW-DpnBPH8B.js → chunk-3FUC2YCW-DuRp-j19.js} +1 -1
  163. package/studio/web/assets/{chunk-5DYCD2WN-LLLCQSzg.js → chunk-5DYCD2WN-BceBfIHT.js} +1 -1
  164. package/studio/web/assets/{chunk-742MDFTN-BL8J_pIO.js → chunk-742MDFTN-CIkt8ijt.js} +1 -1
  165. package/studio/web/assets/{chunk-7INBJB4K-C-hJHiiK.js → chunk-7INBJB4K-BpeAXyOi.js} +1 -1
  166. package/studio/web/assets/{chunk-7M6MHVWA-C6ZqkFbA.js → chunk-7M6MHVWA-h6WlaTzO.js} +1 -1
  167. package/studio/web/assets/{chunk-7PRAP22T-CUXM8BG6.js → chunk-7PRAP22T-KyqX6x3f.js} +1 -1
  168. package/studio/web/assets/{chunk-GTNCS2PH-DJ2BFvS1.js → chunk-GTNCS2PH-DGHLXyow.js} +1 -1
  169. package/studio/web/assets/{chunk-GWA4HPMP-C42bSqLL.js → chunk-GWA4HPMP-DsejB6gA.js} +1 -1
  170. package/studio/web/assets/{chunk-MBY4JIJT-C-5jz6Lo.js → chunk-MBY4JIJT-BwSGweQP.js} +1 -1
  171. package/studio/web/assets/{chunk-NETBCI7D-D-bzlN4r.js → chunk-NETBCI7D-C8UnOw_f.js} +1 -1
  172. package/studio/web/assets/{chunk-O7XYJQB3-ep14zA23.js → chunk-O7XYJQB3-CBS3nZYV.js} +1 -1
  173. package/studio/web/assets/{chunk-UA2S7LBM-BMRWRHED.js → chunk-UA2S7LBM-BHpEdH8D.js} +1 -1
  174. package/studio/web/assets/{chunk-WEXAMYUT-DdLYVdX1.js → chunk-WEXAMYUT-BAIhTwyh.js} +1 -1
  175. package/studio/web/assets/{chunk-Z7XXMR3K-BmKEDjcP.js → chunk-Z7XXMR3K-DSHbImdf.js} +1 -1
  176. package/studio/web/assets/{chunk-ZIGJFQKS-DLZgdNxA.js → chunk-ZIGJFQKS-Cs8fUn7y.js} +1 -1
  177. package/studio/web/assets/{classDiagram-v2-NBCMYWYE-DOI5vgKT.js → classDiagram-v2-NBCMYWYE-DmDPkt2u.js} +1 -1
  178. package/studio/web/assets/cn-6T8VranJ.js +1 -0
  179. package/studio/web/assets/{codicon-Brq4_Ui5.ttf → codicon-DF1abBS2.ttf} +0 -0
  180. package/studio/web/assets/{createLucideIcon-bziYxJli.js → createLucideIcon-fO5dL7D5.js} +1 -1
  181. package/studio/web/assets/{css.worker-l1psR_wG.js → css.worker-DoT-OOzx.js} +36 -36
  182. package/studio/web/assets/{cssMode-DJyc9mHj.js → cssMode-Dz2DxF4e.js} +1 -1
  183. package/studio/web/assets/{cynefin-OW5HDTMX-BSW-DB7S.js → cynefin-OW5HDTMX-DIvbXLSj.js} +1 -1
  184. package/studio/web/assets/{cynefinDiagram-VND7K2PF-CbAHEwxt.js → cynefinDiagram-VND7K2PF-BdtaXiCE.js} +1 -1
  185. package/studio/web/assets/{dagre-6A5THRUB-Csxewgs4.js → dagre-6A5THRUB-C7RUWHyz.js} +1 -1
  186. package/studio/web/assets/{diagram-22UHCM2B-a0rt8tY4.js → diagram-22UHCM2B-DJCvcaWP.js} +1 -1
  187. package/studio/web/assets/{diagram-3UASUU5V-lEj2SVNh.js → diagram-3UASUU5V-Du6VKWln.js} +1 -1
  188. package/studio/web/assets/{diagram-ATOU4E4O-HcrAeB-q.js → diagram-ATOU4E4O-dxRfeG4B.js} +1 -1
  189. package/studio/web/assets/{diagram-CDSNMT55-CYxiuyEx.js → diagram-CDSNMT55-l5Ga0u-W.js} +1 -1
  190. package/studio/web/assets/{diagram-MLGK6HIB-ChbCJTgJ.js → diagram-MLGK6HIB-CNQY47LA.js} +1 -1
  191. package/studio/web/assets/{diagram-MPIPVDR6-DaX9Y-N3.js → diagram-MPIPVDR6-7prveD1B.js} +1 -1
  192. package/studio/web/assets/{dist-Cz2Y6-6G.js → dist-BrRuMUzt.js} +1 -1
  193. package/studio/web/assets/{download-CtostjYn.js → download-Cn6tPG4L.js} +1 -1
  194. package/studio/web/assets/{ebnfDiagram-ZINNZB2B-CwAsENB1.js → ebnfDiagram-ZINNZB2B-5OnkTpfi.js} +1 -1
  195. package/studio/web/assets/{editor-DDIsQfj6.js → editor-B3mjd3tz.js} +1 -1
  196. package/studio/web/assets/editor.worker-Yd1NR0QT.js +33 -0
  197. package/studio/web/assets/{elk-276RUBZZ-Hexg9E4D.js → elk-276RUBZZ-DxDQPjQT.js} +1 -1
  198. package/studio/web/assets/{erDiagram-OPXOYQCR-CeC-wwO1.js → erDiagram-OPXOYQCR-CQlCX84D.js} +1 -1
  199. package/studio/web/assets/eventmodeling-NTZA5JFV-DONQf5aG.js +1 -0
  200. package/studio/web/assets/flowDiagram-KWPJA3E3-BoZ8_QR1.js +1 -0
  201. package/studio/web/assets/{ganttDiagram-FUAMR5RP-C2_Hhl1-.js → ganttDiagram-FUAMR5RP-bloX3Voy.js} +1 -1
  202. package/studio/web/assets/{getAnalytics-CjthMQqF.js → getAnalytics-C0FHjtdQ.js} +1 -1
  203. package/studio/web/assets/{gitGraph-4MIJSDKK-xIk5Vuew.js → gitGraph-4MIJSDKK-BrXWmJt2.js} +1 -1
  204. package/studio/web/assets/{gitGraphDiagram-X574FWY7-CMxJ34up.js → gitGraphDiagram-X574FWY7-C2KnnZeY.js} +1 -1
  205. package/studio/web/assets/{html-g1BJHxLy.js → html-BsRGM7tp.js} +1 -1
  206. package/studio/web/assets/{html.worker-DdwM4IrA.js → html.worker-B1dwY0Ay.js} +27 -27
  207. package/studio/web/assets/{htmlMode-Vh5IglCQ.js → htmlMode-tUKJaA3o.js} +1 -1
  208. package/studio/web/assets/index-72cEH474.css +1 -0
  209. package/studio/web/assets/index-BuqFjN5K.js +828 -0
  210. package/studio/web/assets/index.lazy-CcpfQFY_.js +2 -0
  211. package/studio/web/assets/{info-A6RAGUB7-o49TEbj-.js → info-A6RAGUB7-BhzBHe4U.js} +1 -1
  212. package/studio/web/assets/{infoDiagram-VRGFBTTK-Cjhh7yzZ.js → infoDiagram-VRGFBTTK-B0J1132p.js} +1 -1
  213. package/studio/web/assets/{ishikawaDiagram-OU5B5YK6-C63aXRmh.js → ishikawaDiagram-OU5B5YK6-BNk0tuQx.js} +1 -1
  214. package/studio/web/assets/{javascript-5VIolqf7.js → javascript-BZ_uRGHl.js} +1 -1
  215. package/studio/web/assets/{journeyDiagram-ZHPQQLJL-D_o0P5Mu.js → journeyDiagram-ZHPQQLJL-Be79RMQM.js} +1 -1
  216. package/studio/web/assets/json.worker-BQqXGI3X.js +65 -0
  217. package/studio/web/assets/{jsonMode-DG4zQraI.js → jsonMode-DgB-aFMj.js} +1 -1
  218. package/studio/web/assets/{kanban-definition-PNTS6WVX-CTI9SSxY.js → kanban-definition-PNTS6WVX-4uuoQP9W.js} +1 -1
  219. package/studio/web/assets/{languageServices-t5FBpX-i.js → languageServices-BleuBw17.js} +1 -1
  220. package/studio/web/assets/localStorageKeys-etzFY_xV.js +1 -0
  221. package/studio/web/assets/{lspLanguageFeatures-DgVnNPh-.js → lspLanguageFeatures-ByVYLSsQ.js} +1 -1
  222. package/studio/web/assets/{mermaid-parser.core-C2lcH_jP.js → mermaid-parser.core-V1UYMeXV.js} +3 -3
  223. package/studio/web/assets/{mermaid.core-BG5bjfIG.js → mermaid.core-1PX6R49U.js} +4 -4
  224. package/studio/web/assets/{mindmap-definition-NLK3R4M7-BK7ho6JD.js → mindmap-definition-NLK3R4M7-C70Ctm0J.js} +1 -1
  225. package/studio/web/assets/notifications-D1Nf-Edn.js +1 -0
  226. package/studio/web/assets/notifications-TuzN0IMi.js +1 -0
  227. package/studio/web/assets/{packet-AYTQ26CC-BHPy6KBV.js → packet-AYTQ26CC-DWbXHx5g.js} +1 -1
  228. package/studio/web/assets/{pegDiagram-GJSIUBJH-DzjwG3jO.js → pegDiagram-GJSIUBJH-d6z1cc7W.js} +1 -1
  229. package/studio/web/assets/{pie-WAS4IAKB-D0cP-DTU.js → pie-WAS4IAKB-DjoTm3yr.js} +1 -1
  230. package/studio/web/assets/{pieDiagram-5QR66LMP-C_hOP9Lv.js → pieDiagram-5QR66LMP-Dz3RHpDA.js} +1 -1
  231. package/studio/web/assets/profile-D7C7Lupz.js +1 -0
  232. package/studio/web/assets/{quadrantDiagram-O4NWA36T-CZW8PbV1.js → quadrantDiagram-O4NWA36T-CIF5Qkou.js} +1 -1
  233. package/studio/web/assets/{radar-RG4KPBEZ-C8fk0U81.js → radar-RG4KPBEZ-CVBgjCOj.js} +1 -1
  234. package/studio/web/assets/{railroad-74A4TZTK-B60FWm17.js → railroad-74A4TZTK-BdhXw10Q.js} +1 -1
  235. package/studio/web/assets/railroad-abnf-HS5TGJTU-BcoQPN39.js +1 -0
  236. package/studio/web/assets/railroad-ebnf-LZEXJU2U-B1Lke2JN.js +1 -0
  237. package/studio/web/assets/railroad-peg-WCYAUIDC-D-oJFkiV.js +1 -0
  238. package/studio/web/assets/{railroadDiagram-XR7U4H2S-DyyNmgbU.js → railroadDiagram-XR7U4H2S-y3Jv2U6N.js} +1 -1
  239. package/studio/web/assets/regions-nGQCm-v8.js +1 -0
  240. package/studio/web/assets/register-C3x9Ze6P.js +909 -0
  241. package/studio/web/assets/register-DjpsE8to.css +1 -0
  242. package/studio/web/assets/{requirementDiagram-PLB6GJNP-C4H-mLKu.js → requirementDiagram-PLB6GJNP-ChINZEmu.js} +1 -1
  243. package/studio/web/assets/restartGate-nHAFLDh-.js +1 -0
  244. package/studio/web/assets/{sankeyDiagram-IPEJSGJF-DHDyga4c.js → sankeyDiagram-IPEJSGJF-D9AyLce2.js} +1 -1
  245. package/studio/web/assets/{sequenceDiagram-PO4LG4MO-CdNcHXRI.js → sequenceDiagram-PO4LG4MO-hfk4aIEm.js} +1 -1
  246. package/studio/web/assets/{setComponentFile-z4-qJCbA.js → setComponentFile-DpjrRqeG.js} +1 -1
  247. package/studio/web/assets/{setup-CS50uJ4x.js → setup-CGiKLZ9e.js} +2 -2
  248. package/studio/web/assets/{stateDiagram-v2-GCMORJYK-CpKuXq15.js → stateDiagram-v2-GCMORJYK-Bs8RIb9K.js} +1 -1
  249. package/studio/web/assets/status-CGJwrNPH.js +61 -0
  250. package/studio/web/assets/{swimlanes-2SLR337P-NRHa2D8I.js → swimlanes-2SLR337P-B52xrf6t.js} +1 -1
  251. package/studio/web/assets/swimlanesDiagram-TC7HE7FX-DfN7BAP5.js +8 -0
  252. package/studio/web/assets/tabs-BCTQzoQK.js +1 -0
  253. package/studio/web/assets/{timeline-definition-EJHVYXUP-D39Y-xpq.js → timeline-definition-EJHVYXUP-DJSITpQX.js} +1 -1
  254. package/studio/web/assets/toggleHighContrast-C-Ne6P7T.js +51 -0
  255. package/studio/web/assets/toggleHighContrast-n7clI0si.css +1 -0
  256. package/studio/web/assets/{treeView-Q6P3EWNA-CRWR9OqD.js → treeView-Q6P3EWNA-C-epdxRo.js} +1 -1
  257. package/studio/web/assets/{treemap-WGGIJYW6-ZfXyJgLO.js → treemap-WGGIJYW6-DOVyp_zw.js} +1 -1
  258. package/studio/web/assets/{ts.worker-DDMUrpqh.js → ts.worker-Clm12uY6.js} +131 -131
  259. package/studio/web/assets/{tsMode-D83Gg3cq.js → tsMode-CSreYTys.js} +1 -1
  260. package/studio/web/assets/{typescript-Dfp-GrNq.js → typescript-MnxBk89W.js} +1 -1
  261. package/studio/web/assets/{useEntityRestURL-BKetlINf.js → useEntityRestURL-TNrh77-s.js} +1 -1
  262. package/studio/web/assets/{usecaseDiagram-POWQR4AR-jf-zIDZ_.js → usecaseDiagram-POWQR4AR-B6252cbq.js} +1 -1
  263. package/studio/web/assets/{vendor-core-BdkdbUek.js → vendor-core-6LhfJlRC.js} +1 -1
  264. package/studio/web/assets/vendor-datadog-ozKf-pts.js +6 -0
  265. package/studio/web/assets/{vendor-react-izWchTRL.js → vendor-react-BOliS0BL.js} +1 -1
  266. package/studio/web/assets/vendor-tanstack-Bntfka-M.js +2 -0
  267. package/studio/web/assets/vendor-ui-9EYYDgoN.js +41 -0
  268. package/studio/web/assets/{vennDiagram-UO4OBE2U-BKYAZUh_.js → vennDiagram-UO4OBE2U-DZTsDA4k.js} +1 -1
  269. package/studio/web/assets/{wardley-WFR3VGLG-BO7f36ci.js → wardley-WFR3VGLG-Cfqoe6z4.js} +1 -1
  270. package/studio/web/assets/{wardleyDiagram-VNRHLVJA-Djb0JDQc.js → wardleyDiagram-VNRHLVJA-qu_f7Tvl.js} +1 -1
  271. package/studio/web/assets/{workers-CCvmDLH3.js → workers-BfZlUNVI.js} +3 -3
  272. package/studio/web/assets/{xml-06pZp00U.js → xml-BHd6qGH7.js} +1 -1
  273. package/studio/web/assets/{xychartDiagram-PMCCYNJV-BQh9ubvb.js → xychartDiagram-PMCCYNJV-UrOKRsmR.js} +1 -1
  274. package/studio/web/assets/{yaml-iSnWMVlV.js → yaml-C53R8OQq.js} +1 -1
  275. package/studio/web/assets/{yaml.worker-DAK2o_H1.js → yaml.worker-D9JekGdp.js} +183 -183
  276. package/studio/web/index.html +15 -15
  277. package/utility/operation_authorization.ts +27 -7
  278. package/utility/signalling.ts +3 -0
  279. package/validation/searchValidator.ts +22 -13
  280. package/studio/web/assets/FloatingChat-D4560T0p.js +0 -23
  281. package/studio/web/assets/alertDialog-UrbiMgQt.js +0 -1
  282. package/studio/web/assets/apiToken-BEvbFPMc.js +0 -1
  283. package/studio/web/assets/applications-CSUVTH4E.js +0 -296
  284. package/studio/web/assets/architecture-7GRP2DOG-11l4Ny1l.js +0 -1
  285. package/studio/web/assets/authStore-5jSS5pTW.js +0 -3
  286. package/studio/web/assets/channel-BDtouPd6.js +0 -1
  287. package/studio/web/assets/dialog-DTepachC.js +0 -1
  288. package/studio/web/assets/editor.worker-CkkvdXvO.js +0 -33
  289. package/studio/web/assets/eventmodeling-NTZA5JFV-CFb03e0o.js +0 -1
  290. package/studio/web/assets/flowDiagram-KWPJA3E3-Cidi00_Y.js +0 -1
  291. package/studio/web/assets/index-CPoDzQTe.css +0 -1
  292. package/studio/web/assets/index-DGRAzvO4.js +0 -824
  293. package/studio/web/assets/index.lazy-vgSic7et.js +0 -2
  294. package/studio/web/assets/json.worker-CSi2hF-a.js +0 -65
  295. package/studio/web/assets/notifications-BeWcX04m.js +0 -1
  296. package/studio/web/assets/notifications-DUGWrWoO.js +0 -1
  297. package/studio/web/assets/profile-BvUEDBzW.js +0 -1
  298. package/studio/web/assets/railroad-abnf-HS5TGJTU-CLMVZvH0.js +0 -1
  299. package/studio/web/assets/railroad-ebnf-LZEXJU2U--tlwFoVB.js +0 -1
  300. package/studio/web/assets/railroad-peg-WCYAUIDC-Dpuslblm.js +0 -1
  301. package/studio/web/assets/regions-CB-_2m7M.js +0 -1
  302. package/studio/web/assets/register-1w1Zr3b2.js +0 -848
  303. package/studio/web/assets/register-jjEx9u7D.css +0 -1
  304. package/studio/web/assets/setLocalStorage-D_kflv4U.js +0 -1
  305. package/studio/web/assets/status-CI0wOdOE.js +0 -61
  306. package/studio/web/assets/swimlanesDiagram-TC7HE7FX-BBk4t4hO.js +0 -8
  307. package/studio/web/assets/tabs-CnQ_zenf.js +0 -1
  308. package/studio/web/assets/toggleHighContrast--ixms01u.css +0 -1
  309. package/studio/web/assets/toggleHighContrast-BsAE4jPe.js +0 -49
  310. package/studio/web/assets/useLocalStorage-BYoZF60G.js +0 -1
  311. package/studio/web/assets/vendor-datadog-fCQhBHGk.js +0 -6
  312. package/studio/web/assets/vendor-tanstack-CQ1aRjVa.js +0 -2
  313. package/studio/web/assets/vendor-ui-aE1tHcW7.js +0 -41
  314. package/studio/web/assets/x-vYntCxm4.js +0 -1
@@ -379,6 +379,7 @@ const MAX_OUT_OF_ORDER_AUDIT_DEPTH = 1000;
379
379
  const MAX_PREVIOUS_COUNT_SCAN = 10_000;
380
380
  const AUTHORIZATION_SELECT = Symbol.for('harper.authorizationSelect');
381
381
  const SEARCH_AUTHORIZATION_TRANSFORMS = Symbol.for('harper.searchAuthorizationTransforms');
382
+ const FULL_TEXT_READ_PERMISSION = Symbol('fullTextReadPermission');
382
383
  const AUTHORIZATION_TRANSFORM_METHODS = ['map', 'filter', 'concat', 'flatMap', 'slice', 'mapError'];
383
384
  function propagateSearchAuthorization(iterable, authorization, source) {
384
385
  if (!iterable || typeof iterable !== 'object')
@@ -439,6 +440,30 @@ function cloneConditions(conditions) {
439
440
  return copy;
440
441
  });
441
442
  }
443
+ function selectRequestsProperty(select, propertyName) {
444
+ if (!select)
445
+ return false;
446
+ const selected = Array.isArray(select) ? select : [select];
447
+ return selected.some((property) => (typeof property === 'string' ? property : property?.name) === propertyName);
448
+ }
449
+ function appendSelectProperty(select, propertyName) {
450
+ if (!Array.isArray(select))
451
+ return [select, propertyName];
452
+ return Object.assign([...select, propertyName], select);
453
+ }
454
+ function conditionsContainFullText(entries, definitions) {
455
+ for (const entry of entries) {
456
+ if (entry.conditions) {
457
+ if (conditionsContainFullText(entry.conditions, definitions))
458
+ return true;
459
+ }
460
+ else if ((0, search_ts_1.fullTextComparatorMode)(entry.comparator) &&
461
+ typeof (entry[0] ?? entry.attribute) === 'string' &&
462
+ definitions.some(({ name }) => name === (entry[0] ?? entry.attribute)))
463
+ return true;
464
+ }
465
+ return false;
466
+ }
442
467
  // Ambient, path-scoped cycle guard for the enumerable-struct `toJSON` serialization path. A record on
443
468
  // a cyclically-enumerable table can (transitively) reference itself, which would recurse forever through
444
469
  // JSON.stringify. The struct getters resolve related records by id — and without a shared cache each
@@ -554,7 +579,9 @@ function isPlainOptions(value) {
554
579
  });
555
580
  function makeTable(options) {
556
581
  var _a;
557
- const { primaryKey, indices, tableId, tableName, primaryStore, databasePath, databaseName, auditStore, schemaDefined, dbisDB: dbisDb, sealed, splitSegments, replicate, description, hidden, cacheControl, isBranch, fullTextIndexes = [], fullTextIndexGenerations = Object.create(null), fullTextIndexRetirements = [], } = options;
582
+ const { primaryKey, indices, tableId, tableName, primaryStore, databasePath, databaseName, auditStore, schemaDefined, dbisDB: dbisDb, sealed, splitSegments, replicate, description, hidden, cacheControl, isBranch, fullTextIndexes = [], fullTextFields = [], fullTextIndexGenerations = Object.create(null), fullTextIndexRetirements = [], } = options;
583
+ let declaredFullTextFields = Object.freeze([...fullTextFields]);
584
+ let fullTextFieldNames = fullTextFields.length > 0 ? new Set(fullTextFields) : undefined;
558
585
  const tableRootStore = primaryStore.rootStore;
559
586
  const tableRootPath = tableRootStore.path;
560
587
  let { expirationMS: expirationMs, evictionMS: evictionMs, audit, trackDeletes } = options;
@@ -890,6 +917,26 @@ function makeTable(options) {
890
917
  static derivedIndexRuntime;
891
918
  static audit = audit;
892
919
  static fullTextIndexes = fullTextIndexes;
920
+ static get fullTextFields() {
921
+ return declaredFullTextFields;
922
+ }
923
+ static set fullTextFields(names) {
924
+ declaredFullTextFields = Object.freeze([...names]);
925
+ fullTextFieldNames = names.length > 0 ? new Set(names) : undefined;
926
+ }
927
+ static assertFullTextSelection(select, sort) {
928
+ assertFullTextSelection(select);
929
+ for (let order = sort; order; order = order.next)
930
+ assertRecordField(order.attribute);
931
+ }
932
+ static assertFullTextRecordField(name) {
933
+ assertFullTextRecordField(name);
934
+ }
935
+ static isFullTextSearchEntryCurrent(entry) {
936
+ return !(entry.metadataFlags & (exports.INVALIDATED | exports.EVICTED | RecordEncoder_ts_1.VERSION_REUSED));
937
+ }
938
+ static fullTextQueryIndexes = Object.create(null);
939
+ static hasFullTextQueryIndexes = false;
893
940
  static fullTextIndexGenerations = fullTextIndexGenerations;
894
941
  static fullTextIndexRetirements = fullTextIndexRetirements;
895
942
  static hasCurrentFullTextIndexRetirements(names) {
@@ -1446,13 +1493,14 @@ function makeTable(options) {
1446
1493
  hasChanges = true;
1447
1494
  }
1448
1495
  }
1449
- if (hasChanges || event.fullTextIndexes !== undefined) {
1496
+ if (hasChanges || event.fullTextIndexes !== undefined || event.fullTextFields !== undefined) {
1450
1497
  const schemaVersion = this.schemaVersion;
1451
1498
  const definedTable = (0, databases_ts_1.table)({
1452
1499
  table: tableName,
1453
1500
  database: databaseName,
1454
1501
  attributes: updatedAttributes,
1455
1502
  fullTextIndexes: event.fullTextIndexes,
1503
+ fullTextFields: event.fullTextFields,
1456
1504
  origin: 'cluster',
1457
1505
  });
1458
1506
  if (definedTable.schemaVersion !== schemaVersion)
@@ -2263,6 +2311,11 @@ function makeTable(options) {
2263
2311
  */
2264
2312
  get(target) {
2265
2313
  const constructor = this.constructor;
2314
+ if (fullTextFieldNames || hasRelationships)
2315
+ assertFullTextSelection(target?.select);
2316
+ if (fullTextFieldNames) {
2317
+ assertRecordField(target?.property ?? (typeof target === 'string' && constructor.loadAsInstance !== false ? target : undefined));
2318
+ }
2266
2319
  if (typeof target === 'string' && constructor.loadAsInstance !== false)
2267
2320
  return this.getProperty(target);
2268
2321
  if (isSearchTarget(target)) {
@@ -2371,6 +2424,9 @@ function makeTable(options) {
2371
2424
  */
2372
2425
  allowRead(user, target, context) {
2373
2426
  const tablePermission = getTablePermissions(user, target);
2427
+ // Resource.search consumes checkPermission before full-text source-field authorization runs.
2428
+ if (_a.fullTextIndexes.length > 0 && target?.checkPermission && tablePermission)
2429
+ target[FULL_TEXT_READ_PERMISSION] = tablePermission;
2374
2430
  if (tablePermission?.read) {
2375
2431
  if (tablePermission.isSuperUser)
2376
2432
  return true;
@@ -2388,7 +2444,11 @@ function makeTable(options) {
2388
2444
  target.select = selectArray
2389
2445
  .map((property) => {
2390
2446
  const propertyName = property.name || property;
2391
- if (!attrsForType || attrsForType[propertyName]) {
2447
+ if (!attrsForType ||
2448
+ attrsForType[propertyName] ||
2449
+ fullTextFieldNames?.has(propertyName) ||
2450
+ propertyName === '$score' ||
2451
+ propertyName === '$highlights') {
2392
2452
  const relatedTable = propertyResolvers[propertyName]?.definition?.tableClass;
2393
2453
  if (relatedTable) {
2394
2454
  // if there is a related table, we need to ensure the user has permission to read from that table and that attributes are properly restricted
@@ -2411,7 +2471,9 @@ function makeTable(options) {
2411
2471
  }
2412
2472
  else {
2413
2473
  target.select = attribute_permissions
2414
- .filter((attribute) => attribute.read && !propertyResolvers[attribute.attribute_name])
2474
+ .filter((attribute) => attribute.read &&
2475
+ !fullTextFieldNames?.has(attribute.attribute_name) &&
2476
+ !propertyResolvers[attribute.attribute_name])
2415
2477
  .map((attribute) => attribute.attribute_name);
2416
2478
  }
2417
2479
  target[AUTHORIZATION_SELECT] = true;
@@ -2443,7 +2505,7 @@ function makeTable(options) {
2443
2505
  // that the user doesn't have permission to remove
2444
2506
  for (const permission of attribute_permissions) {
2445
2507
  const key = permission.attribute_name;
2446
- if (!permission.update && !(key in updatedData)) {
2508
+ if (!permission.update && !fullTextFieldNames?.has(key) && !(key in updatedData)) {
2447
2509
  updatedData[key] = this.getProperty(key);
2448
2510
  }
2449
2511
  }
@@ -3522,6 +3584,8 @@ function makeTable(options) {
3522
3584
  captureChanges,
3523
3585
  validate: (txnTime, committedBy = transaction) => {
3524
3586
  write.captureChanges?.();
3587
+ if (context?.source && !committedBy.isReplay)
3588
+ assertFullTextWrite(recordUpdate, true);
3525
3589
  if (fullUpdate || (recordUpdate && (0, tracked_ts_1.hasChanges)(this.#changes === recordUpdate ? this : recordUpdate))) {
3526
3590
  if (!context?.source) {
3527
3591
  committedBy.checkOverloaded();
@@ -4393,6 +4457,8 @@ function makeTable(options) {
4393
4457
  throw new Error('No query provided');
4394
4458
  if (target.parseError)
4395
4459
  throw target.parseError; // if there was a parse error, we can throw it now
4460
+ if (fullTextFieldNames || hasRelationships)
4461
+ assertFullTextSelection(target.select);
4396
4462
  const getColumns = () => {
4397
4463
  const select = target.select;
4398
4464
  if (select) {
@@ -4536,6 +4602,7 @@ function makeTable(options) {
4536
4602
  conditions = cloneConditions(conditions);
4537
4603
  let orderAlignedCondition;
4538
4604
  let syntheticOrderCondition;
4605
+ let includeFullTextHighlights = false;
4539
4606
  const filtered = {};
4540
4607
  function prepareConditions(conditions, operator) {
4541
4608
  // some validation:
@@ -4568,6 +4635,50 @@ function makeTable(options) {
4568
4635
  }
4569
4636
  }
4570
4637
  const attribute_name = condition[0] ?? condition.attribute;
4638
+ const fullTextMode = _a.fullTextIndexes.length > 0 ||
4639
+ Array.isArray(attribute_name) ||
4640
+ (typeof attribute_name === 'string' && fullTextFieldNames?.has(attribute_name))
4641
+ ? (0, search_ts_1.fullTextComparatorMode)(condition.comparator)
4642
+ : undefined;
4643
+ if (!fullTextMode && (fullTextFieldNames || hasRelationships))
4644
+ assertFullTextRecordField(attribute_name);
4645
+ const fullTextDefinition = fullTextMode && typeof attribute_name === 'string'
4646
+ ? _a.fullTextIndexes.find((definition) => definition.name === attribute_name)
4647
+ : undefined;
4648
+ if (fullTextMode && Array.isArray(attribute_name))
4649
+ throw new hdbError_ts_1.ClientError('Full-text predicates must directly name an index on the queried table', 400);
4650
+ if (fullTextMode && !fullTextDefinition)
4651
+ throwUnknownFullTextIndex(context, target, attribute_name);
4652
+ if (fullTextDefinition) {
4653
+ const fields = condition.fields;
4654
+ if (fields !== undefined) {
4655
+ if (!Array.isArray(fields) || fields.length === 0 || fields.some((field) => typeof field !== 'string'))
4656
+ throw new hdbError_ts_1.ClientError(`Full-text index '${attribute_name}' requires a non-empty fields list`, 400);
4657
+ assertFullTextReadAccess(context, target, fullTextDefinition, fields);
4658
+ }
4659
+ else
4660
+ assertFullTextReadAccess(context, target, fullTextDefinition);
4661
+ const value = condition[1] ?? condition.value;
4662
+ if (typeof value !== 'string' || value.length === 0)
4663
+ throw new hdbError_ts_1.ClientError(`Full-text index '${attribute_name}' requires a full-text comparator and non-empty string value`, 400);
4664
+ if (fullTextMode === 'phrase' && !fullTextDefinition.positions)
4665
+ throw new hdbError_ts_1.ClientError(`Full-text index '${attribute_name}' does not store phrase positions`, 400);
4666
+ if ((fullTextMode === 'prefix' || fullTextMode === 'fuzzy-prefix') && !fullTextDefinition.surfaceTerms)
4667
+ throw new hdbError_ts_1.ClientError(`Full-text index '${attribute_name}' does not store surface terms`, 400);
4668
+ if (fields !== undefined) {
4669
+ const sourceNames = new Set(fullTextDefinition.fields.map(({ name }) => name));
4670
+ if (new Set(fields).size !== fields.length || fields.some((field) => !sourceNames.has(field)))
4671
+ throw new hdbError_ts_1.ClientError(`Full-text index '${attribute_name}' contains an unknown or duplicate field`, 400);
4672
+ }
4673
+ condition.includeHighlights =
4674
+ condition.includeHighlights === true || selectRequestsProperty(target.select, '$highlights');
4675
+ if (condition.includeHighlights && !fullTextDefinition.highlighting)
4676
+ throw new hdbError_ts_1.ClientError(`Full-text index '${attribute_name}' does not enable highlighting`, 400);
4677
+ if (!_a.fullTextQueryIndexes[attribute_name]?.customIndex)
4678
+ throw new hdbError_ts_1.IndexRebuildingError(`Full-text index '${attribute_name}' is not ready`);
4679
+ includeFullTextHighlights ||= condition.includeHighlights;
4680
+ continue;
4681
+ }
4571
4682
  let attribute = attribute_name == null ? primaryKeyAttribute : (0, search_ts_1.findAttribute)(attributes, attribute_name);
4572
4683
  if (!attribute && Array.isArray(attribute_name) && attribute_name.length > 1) {
4573
4684
  // Plain JSON nested path: the leaf may not be declared in the
@@ -4647,8 +4758,18 @@ function makeTable(options) {
4647
4758
  const operator = target.operator;
4648
4759
  if (conditions.length > 0 || operator)
4649
4760
  conditions = prepareConditions(conditions, operator);
4650
- const sort = typeof target.sort === 'object' && target.sort;
4761
+ let sort = typeof target.sort === 'object' && target.sort;
4762
+ if (_a.fullTextIndexes.length > 0 &&
4763
+ conditionsContainFullText(conditions, _a.fullTextIndexes)) {
4764
+ if (target.reverse)
4765
+ throw new hdbError_ts_1.ClientError('Full-text results can only use descending $score order', 400);
4766
+ if (sort && (sort.attribute !== '$score' || sort.next || sort.descending !== true))
4767
+ throw new hdbError_ts_1.ClientError('Full-text results can only use descending $score order', 400);
4768
+ sort = undefined;
4769
+ }
4651
4770
  for (let order = sort; order; order = order.next) {
4771
+ if (fullTextFieldNames)
4772
+ assertRecordField(order.attribute);
4652
4773
  if (typeof order.attribute !== 'string')
4653
4774
  continue;
4654
4775
  const customIndex = indices[order.attribute]?.customIndex;
@@ -4715,7 +4836,13 @@ function makeTable(options) {
4715
4836
  postOrdering = sort;
4716
4837
  }
4717
4838
  }
4718
- const select = target.select;
4839
+ const select = includeFullTextHighlights
4840
+ ? target.select === undefined
4841
+ ? ['*', '$highlights']
4842
+ : selectRequestsProperty(target.select, '$highlights')
4843
+ ? target.select
4844
+ : appendSelectProperty(target.select, '$highlights')
4845
+ : target.select;
4719
4846
  // Whether the caller supplied real filter conditions — read from the raw request, NOT the
4720
4847
  // planner-augmented `conditions` (which by now may carry a synthetic `sort` pseudo-condition and
4721
4848
  // injected full-scan condition). Used to pick the count-estimate source below.
@@ -4816,7 +4943,11 @@ function makeTable(options) {
4816
4943
  if (c.conditions)
4817
4944
  return touchesCustomIndex(c.conditions);
4818
4945
  const attr = Array.isArray(c.attribute) ? c.attribute[0] : (c.attribute ?? c[0]);
4819
- return typeof attr === 'string' && Boolean(indices[attr]?.customIndex);
4946
+ if (typeof attr !== 'string')
4947
+ return false;
4948
+ return (0, search_ts_1.fullTextComparatorMode)(c.comparator)
4949
+ ? Boolean(_a.fullTextQueryIndexes?.[attr]?.customIndex)
4950
+ : Boolean(indices[attr]?.customIndex);
4820
4951
  });
4821
4952
  const approximateResultSet = typeof target.vectorFilter === 'function' || touchesCustomIndex(conditions);
4822
4953
  return (async () => {
@@ -6092,6 +6223,8 @@ function makeTable(options) {
6092
6223
  }
6093
6224
  // #section: validation
6094
6225
  validate(record, patch) {
6226
+ if (fullTextFieldNames)
6227
+ assertFullTextWrite(record);
6095
6228
  // Accumulate structured per-field issues so the 400 carries `{ path, code,
6096
6229
  // message }[]` matching the emitted OpenAPI, instead of a single joined string. The joined
6097
6230
  // message is still built for the HTTP title, preserving back-compat for callers that read it.
@@ -6523,6 +6656,8 @@ function makeTable(options) {
6523
6656
  $updatedTime: (object, context, entry) => entry.version,
6524
6657
  $expiresAt: (object, context, entry) => entry.expiresAt,
6525
6658
  $record: (object, context, entry) => (entry ? { value: object } : object),
6659
+ $score: (object, context, entry) => entry?.$score,
6660
+ $highlights: (object, context, entry) => entry?.$highlights,
6526
6661
  $distance: (object, context, entry, returnEntry, sort) => {
6527
6662
  if (!entry)
6528
6663
  return;
@@ -6545,6 +6680,7 @@ function makeTable(options) {
6545
6680
  return customIndex.propertyResolver(vector, context, entry, distanceSort);
6546
6681
  },
6547
6682
  };
6683
+ propertyResolvers.$highlights.directReturn = true;
6548
6684
  for (const attribute of this.attributes) {
6549
6685
  if (attribute.isPrimaryKey)
6550
6686
  primaryKeyAttribute = attribute;
@@ -7380,6 +7516,67 @@ function makeTable(options) {
7380
7516
  return table;
7381
7517
  }
7382
7518
  }
7519
+ function assertRecordField(name) {
7520
+ const field = Array.isArray(name) ? name[0] : name;
7521
+ if (typeof field === 'string' && fullTextFieldNames?.has(field))
7522
+ throw new hdbError_ts_1.ClientError(`Full-text field "${field}" is query-only; use a full-text comparator and select $score or $highlights`, 400);
7523
+ }
7524
+ function assertFullTextRecordField(name) {
7525
+ if (!Array.isArray(name))
7526
+ return assertRecordField(name);
7527
+ const [first, ...remaining] = name;
7528
+ assertRecordField(first);
7529
+ if (remaining.length === 0)
7530
+ return;
7531
+ propertyResolvers[first]?.definition?.tableClass?.assertFullTextRecordField?.(remaining.length === 1 ? remaining[0] : remaining);
7532
+ }
7533
+ function assertFullTextSelection(select) {
7534
+ if (!fullTextFieldNames && !hasRelationships)
7535
+ return;
7536
+ if (typeof select === 'string')
7537
+ assertRecordField(select);
7538
+ else if (Array.isArray(select)) {
7539
+ for (const property of select) {
7540
+ const name = typeof property === 'object' ? property?.name : property;
7541
+ assertRecordField(name);
7542
+ if (property && typeof property === 'object')
7543
+ propertyResolvers[name]?.definition?.tableClass?.assertFullTextSelection?.(property.select || (Array.isArray(property) ? property : undefined), property.sort);
7544
+ }
7545
+ }
7546
+ }
7547
+ function assertFullTextWrite(record, sourceFill = false) {
7548
+ if (!fullTextFieldNames || !record || typeof record !== 'object')
7549
+ return;
7550
+ for (const name in record) {
7551
+ if (fullTextFieldNames.has(name)) {
7552
+ if (sourceFill)
7553
+ throw new hdbError_ts_1.ServerError(`Source for ${tableName} returned query-only full-text field "${name}"`, 502);
7554
+ throw new hdbError_ts_1.ClientError(`Full-text field "${name}" is query-only and cannot be written`, 400);
7555
+ }
7556
+ }
7557
+ }
7558
+ function assertFullTextReadAccess(context, target, definition, requestedFields) {
7559
+ const user = context?.user;
7560
+ const permission = target[FULL_TEXT_READ_PERMISSION] ?? getTablePermissions(user, target);
7561
+ // Calls without a principal or explicit permission are trusted internal calls, matching allowRead.
7562
+ if (!permission && !user)
7563
+ return;
7564
+ if (permission?.isSuperUser || !permission?.attribute_permissions?.length)
7565
+ return;
7566
+ const readable = attributesAsObject(permission.attribute_permissions, 'read');
7567
+ const searched = requestedFields ?? definition.fields.map(({ name }) => name);
7568
+ if (searched.some((name) => !readable[name]))
7569
+ throw new hdbError_ts_1.AccessViolation(user);
7570
+ }
7571
+ function throwUnknownFullTextIndex(context, target, attributeName) {
7572
+ const user = context?.user;
7573
+ const permission = target[FULL_TEXT_READ_PERMISSION] ?? getTablePermissions(user, target);
7574
+ if (permission?.attribute_permissions?.length)
7575
+ throw new hdbError_ts_1.AccessViolation(user);
7576
+ if (typeof attributeName === 'string' && fullTextFieldNames?.has(attributeName))
7577
+ throw new hdbError_ts_1.IndexRebuildingError(`Full-text index '${attributeName}' is unavailable`);
7578
+ throw new hdbError_ts_1.ClientError('Full-text comparator requires a declared @fullText index', 400);
7579
+ }
7383
7580
  function setLoadedFromSource(target, loadedFromSource) {
7384
7581
  // cache disposition is a per-get result, recorded on the RequestTarget of the get (#1576)
7385
7582
  // target may be a primitive id on instance-API calls, which can't hold the flag
@@ -7745,6 +7942,7 @@ function makeTable(options) {
7745
7942
  const commitPromise = (0, transaction_ts_1.transaction)(sourceContext, async (_txn) => {
7746
7943
  const start = node_perf_hooks_1.performance.now();
7747
7944
  let updatedRecord, assignCreatedTime, sourceVersion;
7945
+ let reusedCachedRecord = false;
7748
7946
  let hasChanges, invalidated;
7749
7947
  try {
7750
7948
  updatedRecord = await throttledCallToSource(source, id, sourceContext, existingEntry);
@@ -7787,6 +7985,7 @@ function makeTable(options) {
7787
7985
  if (status === 304) {
7788
7986
  // revalidation of our current cached record
7789
7987
  updatedRecord = existingRecord;
7988
+ reusedCachedRecord = true;
7790
7989
  sourceVersion = existingVersion;
7791
7990
  }
7792
7991
  else if (!CACHEABLE_STATUS_CODES.has(status)) {
@@ -7862,6 +8061,8 @@ function makeTable(options) {
7862
8061
  }
7863
8062
  }
7864
8063
  updatedRecord = (0, RecordEncoder_ts_1.storedFieldsOnly)(primaryStore.encoder, updatedRecord);
8064
+ if (!reusedCachedRecord)
8065
+ assertFullTextWrite(updatedRecord, true);
7865
8066
  if (primaryKey && updatedRecord[primaryKey] !== id)
7866
8067
  updatedRecord[primaryKey] = id;
7867
8068
  }