@entifix/core 0.1.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/dist/base-entities/configuration-client/configuration-client-singleton.d.ts +39 -0
  4. package/dist/base-entities/configuration-client/configuration-client-singleton.d.ts.map +1 -0
  5. package/dist/base-entities/configuration-client/configuration-client-singleton.js +164 -0
  6. package/dist/base-entities/configuration-client/configuration-client-singleton.js.map +1 -0
  7. package/dist/base-entities/configuration-client/index.d.ts +4 -0
  8. package/dist/base-entities/configuration-client/index.d.ts.map +1 -0
  9. package/dist/base-entities/configuration-client/index.js +5 -0
  10. package/dist/base-entities/configuration-client/index.js.map +1 -0
  11. package/dist/base-entities/configuration-client/read-configuration-from-process.d.ts +11 -0
  12. package/dist/base-entities/configuration-client/read-configuration-from-process.d.ts.map +1 -0
  13. package/dist/base-entities/configuration-client/read-configuration-from-process.js +26 -0
  14. package/dist/base-entities/configuration-client/read-configuration-from-process.js.map +1 -0
  15. package/dist/base-entities/configuration-client/types.d.ts +38 -0
  16. package/dist/base-entities/configuration-client/types.d.ts.map +1 -0
  17. package/dist/base-entities/configuration-client/types.js +3 -0
  18. package/dist/base-entities/configuration-client/types.js.map +1 -0
  19. package/dist/base-entities/entifix-error/entifix-error.d.ts +31 -0
  20. package/dist/base-entities/entifix-error/entifix-error.d.ts.map +1 -0
  21. package/dist/base-entities/entifix-error/entifix-error.js +56 -0
  22. package/dist/base-entities/entifix-error/entifix-error.js.map +1 -0
  23. package/dist/base-entities/entifix-error/index.d.ts +2 -0
  24. package/dist/base-entities/entifix-error/index.d.ts.map +1 -0
  25. package/dist/base-entities/entifix-error/index.js +3 -0
  26. package/dist/base-entities/entifix-error/index.js.map +1 -0
  27. package/dist/command-palette/command-matching.d.ts +79 -0
  28. package/dist/command-palette/command-matching.d.ts.map +1 -0
  29. package/dist/command-palette/command-matching.js +116 -0
  30. package/dist/command-palette/command-matching.js.map +1 -0
  31. package/dist/command-palette/command-source.d.ts +109 -0
  32. package/dist/command-palette/command-source.d.ts.map +1 -0
  33. package/dist/command-palette/command-source.js +11 -0
  34. package/dist/command-palette/command-source.js.map +1 -0
  35. package/dist/command-palette/index.d.ts +3 -0
  36. package/dist/command-palette/index.d.ts.map +1 -0
  37. package/dist/command-palette/index.js +4 -0
  38. package/dist/command-palette/index.js.map +1 -0
  39. package/dist/entity-definition/decorators/accessor/accessor.d.ts +3 -0
  40. package/dist/entity-definition/decorators/accessor/accessor.d.ts.map +1 -0
  41. package/dist/entity-definition/decorators/accessor/accessor.js +11 -0
  42. package/dist/entity-definition/decorators/accessor/accessor.js.map +1 -0
  43. package/dist/entity-definition/decorators/accessor/index.d.ts +2 -0
  44. package/dist/entity-definition/decorators/accessor/index.d.ts.map +1 -0
  45. package/dist/entity-definition/decorators/accessor/index.js +3 -0
  46. package/dist/entity-definition/decorators/accessor/index.js.map +1 -0
  47. package/dist/entity-definition/decorators/entity/entity.d.ts +4 -0
  48. package/dist/entity-definition/decorators/entity/entity.d.ts.map +1 -0
  49. package/dist/entity-definition/decorators/entity/entity.js +9 -0
  50. package/dist/entity-definition/decorators/entity/entity.js.map +1 -0
  51. package/dist/entity-definition/decorators/entity/index.d.ts +2 -0
  52. package/dist/entity-definition/decorators/entity/index.d.ts.map +1 -0
  53. package/dist/entity-definition/decorators/entity/index.js +3 -0
  54. package/dist/entity-definition/decorators/entity/index.js.map +1 -0
  55. package/dist/entity-definition/decorators/method/index.d.ts +2 -0
  56. package/dist/entity-definition/decorators/method/index.d.ts.map +1 -0
  57. package/dist/entity-definition/decorators/method/index.js +3 -0
  58. package/dist/entity-definition/decorators/method/index.js.map +1 -0
  59. package/dist/entity-definition/decorators/method/method.d.ts +3 -0
  60. package/dist/entity-definition/decorators/method/method.d.ts.map +1 -0
  61. package/dist/entity-definition/decorators/method/method.js +10 -0
  62. package/dist/entity-definition/decorators/method/method.js.map +1 -0
  63. package/dist/entity-definition/decorators/use-case/index.d.ts +2 -0
  64. package/dist/entity-definition/decorators/use-case/index.d.ts.map +1 -0
  65. package/dist/entity-definition/decorators/use-case/index.js +3 -0
  66. package/dist/entity-definition/decorators/use-case/index.js.map +1 -0
  67. package/dist/entity-definition/decorators/use-case/use-case.d.ts +18 -0
  68. package/dist/entity-definition/decorators/use-case/use-case.d.ts.map +1 -0
  69. package/dist/entity-definition/decorators/use-case/use-case.js +26 -0
  70. package/dist/entity-definition/decorators/use-case/use-case.js.map +1 -0
  71. package/dist/entity-definition/describe/describe-child-columns.d.ts +33 -0
  72. package/dist/entity-definition/describe/describe-child-columns.d.ts.map +1 -0
  73. package/dist/entity-definition/describe/describe-child-columns.js +44 -0
  74. package/dist/entity-definition/describe/describe-child-columns.js.map +1 -0
  75. package/dist/entity-definition/describe/describe-entity-columns.d.ts +83 -0
  76. package/dist/entity-definition/describe/describe-entity-columns.d.ts.map +1 -0
  77. package/dist/entity-definition/describe/describe-entity-columns.js +112 -0
  78. package/dist/entity-definition/describe/describe-entity-columns.js.map +1 -0
  79. package/dist/entity-definition/describe/describe-entity-use-cases.d.ts +34 -0
  80. package/dist/entity-definition/describe/describe-entity-use-cases.d.ts.map +1 -0
  81. package/dist/entity-definition/describe/describe-entity-use-cases.js +24 -0
  82. package/dist/entity-definition/describe/describe-entity-use-cases.js.map +1 -0
  83. package/dist/entity-definition/describe/index.d.ts +4 -0
  84. package/dist/entity-definition/describe/index.d.ts.map +1 -0
  85. package/dist/entity-definition/describe/index.js +5 -0
  86. package/dist/entity-definition/describe/index.js.map +1 -0
  87. package/dist/entity-definition/field-path.d.ts +49 -0
  88. package/dist/entity-definition/field-path.d.ts.map +1 -0
  89. package/dist/entity-definition/field-path.js +58 -0
  90. package/dist/entity-definition/field-path.js.map +1 -0
  91. package/dist/entity-definition/helpers/entity-definition-helpers.d.ts +59 -0
  92. package/dist/entity-definition/helpers/entity-definition-helpers.d.ts.map +1 -0
  93. package/dist/entity-definition/helpers/entity-definition-helpers.js +115 -0
  94. package/dist/entity-definition/helpers/entity-definition-helpers.js.map +1 -0
  95. package/dist/entity-definition/helpers/index.d.ts +2 -0
  96. package/dist/entity-definition/helpers/index.d.ts.map +1 -0
  97. package/dist/entity-definition/helpers/index.js +3 -0
  98. package/dist/entity-definition/helpers/index.js.map +1 -0
  99. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.d.ts +48 -0
  100. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.d.ts.map +1 -0
  101. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.js +88 -0
  102. package/dist/entity-definition/links/apply-entity-links/apply-entity-links.js.map +1 -0
  103. package/dist/entity-definition/links/apply-entity-links/index.d.ts +2 -0
  104. package/dist/entity-definition/links/apply-entity-links/index.d.ts.map +1 -0
  105. package/dist/entity-definition/links/apply-entity-links/index.js +3 -0
  106. package/dist/entity-definition/links/apply-entity-links/index.js.map +1 -0
  107. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.d.ts +29 -0
  108. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.d.ts.map +1 -0
  109. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.js +61 -0
  110. package/dist/entity-definition/links/entity-collection-link/entity-collection-link.js.map +1 -0
  111. package/dist/entity-definition/links/entity-collection-link/index.d.ts +2 -0
  112. package/dist/entity-definition/links/entity-collection-link/index.d.ts.map +1 -0
  113. package/dist/entity-definition/links/entity-collection-link/index.js +3 -0
  114. package/dist/entity-definition/links/entity-collection-link/index.js.map +1 -0
  115. package/dist/entity-definition/links/entity-link/entity-link.d.ts +58 -0
  116. package/dist/entity-definition/links/entity-link/entity-link.d.ts.map +1 -0
  117. package/dist/entity-definition/links/entity-link/entity-link.js +79 -0
  118. package/dist/entity-definition/links/entity-link/entity-link.js.map +1 -0
  119. package/dist/entity-definition/links/entity-link/index.d.ts +2 -0
  120. package/dist/entity-definition/links/entity-link/index.d.ts.map +1 -0
  121. package/dist/entity-definition/links/entity-link/index.js +3 -0
  122. package/dist/entity-definition/links/entity-link/index.js.map +1 -0
  123. package/dist/entity-definition/links/entity-link-source/entity-link-source.d.ts +74 -0
  124. package/dist/entity-definition/links/entity-link-source/entity-link-source.d.ts.map +1 -0
  125. package/dist/entity-definition/links/entity-link-source/entity-link-source.js +11 -0
  126. package/dist/entity-definition/links/entity-link-source/entity-link-source.js.map +1 -0
  127. package/dist/entity-definition/links/entity-link-source/index.d.ts +2 -0
  128. package/dist/entity-definition/links/entity-link-source/index.d.ts.map +1 -0
  129. package/dist/entity-definition/links/entity-link-source/index.js +3 -0
  130. package/dist/entity-definition/links/entity-link-source/index.js.map +1 -0
  131. package/dist/entity-definition/meta-entities/meta-accessor/index.d.ts +2 -0
  132. package/dist/entity-definition/meta-entities/meta-accessor/index.d.ts.map +1 -0
  133. package/dist/entity-definition/meta-entities/meta-accessor/index.js +3 -0
  134. package/dist/entity-definition/meta-entities/meta-accessor/index.js.map +1 -0
  135. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.d.ts +137 -0
  136. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.d.ts.map +1 -0
  137. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.js +52 -0
  138. package/dist/entity-definition/meta-entities/meta-accessor/meta-accessor.js.map +1 -0
  139. package/dist/entity-definition/meta-entities/meta-entity/index.d.ts +2 -0
  140. package/dist/entity-definition/meta-entities/meta-entity/index.d.ts.map +1 -0
  141. package/dist/entity-definition/meta-entities/meta-entity/index.js +3 -0
  142. package/dist/entity-definition/meta-entities/meta-entity/index.js.map +1 -0
  143. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.d.ts +17 -0
  144. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.d.ts.map +1 -0
  145. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.js +13 -0
  146. package/dist/entity-definition/meta-entities/meta-entity/meta-entity.js.map +1 -0
  147. package/dist/entity-definition/meta-entities/meta-method/index.d.ts +2 -0
  148. package/dist/entity-definition/meta-entities/meta-method/index.d.ts.map +1 -0
  149. package/dist/entity-definition/meta-entities/meta-method/index.js +3 -0
  150. package/dist/entity-definition/meta-entities/meta-method/index.js.map +1 -0
  151. package/dist/entity-definition/meta-entities/meta-method/meta-method.d.ts +16 -0
  152. package/dist/entity-definition/meta-entities/meta-method/meta-method.d.ts.map +1 -0
  153. package/dist/entity-definition/meta-entities/meta-method/meta-method.js +11 -0
  154. package/dist/entity-definition/meta-entities/meta-method/meta-method.js.map +1 -0
  155. package/dist/entity-definition/meta-entities/meta-use-case/index.d.ts +2 -0
  156. package/dist/entity-definition/meta-entities/meta-use-case/index.d.ts.map +1 -0
  157. package/dist/entity-definition/meta-entities/meta-use-case/index.js +3 -0
  158. package/dist/entity-definition/meta-entities/meta-use-case/index.js.map +1 -0
  159. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.d.ts +94 -0
  160. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.d.ts.map +1 -0
  161. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.js +17 -0
  162. package/dist/entity-definition/meta-entities/meta-use-case/meta-use-case.js.map +1 -0
  163. package/dist/entity-definition/metadata/entity-metadata-document.d.ts +23 -0
  164. package/dist/entity-definition/metadata/entity-metadata-document.d.ts.map +1 -0
  165. package/dist/entity-definition/metadata/entity-metadata-document.js +16 -0
  166. package/dist/entity-definition/metadata/entity-metadata-document.js.map +1 -0
  167. package/dist/entity-definition/metadata/entity-metadata-source.d.ts +19 -0
  168. package/dist/entity-definition/metadata/entity-metadata-source.d.ts.map +1 -0
  169. package/dist/entity-definition/metadata/entity-metadata-source.js +15 -0
  170. package/dist/entity-definition/metadata/entity-metadata-source.js.map +1 -0
  171. package/dist/entity-definition/metadata/index.d.ts +3 -0
  172. package/dist/entity-definition/metadata/index.d.ts.map +1 -0
  173. package/dist/entity-definition/metadata/index.js +4 -0
  174. package/dist/entity-definition/metadata/index.js.map +1 -0
  175. package/dist/entity-definition/reconstruct/clone-entity-draft.d.ts +34 -0
  176. package/dist/entity-definition/reconstruct/clone-entity-draft.d.ts.map +1 -0
  177. package/dist/entity-definition/reconstruct/clone-entity-draft.js +75 -0
  178. package/dist/entity-definition/reconstruct/clone-entity-draft.js.map +1 -0
  179. package/dist/entity-definition/reconstruct/coerce-field-value.d.ts +34 -0
  180. package/dist/entity-definition/reconstruct/coerce-field-value.d.ts.map +1 -0
  181. package/dist/entity-definition/reconstruct/coerce-field-value.js +42 -0
  182. package/dist/entity-definition/reconstruct/coerce-field-value.js.map +1 -0
  183. package/dist/entity-definition/reconstruct/index.d.ts +5 -0
  184. package/dist/entity-definition/reconstruct/index.d.ts.map +1 -0
  185. package/dist/entity-definition/reconstruct/index.js +6 -0
  186. package/dist/entity-definition/reconstruct/index.js.map +1 -0
  187. package/dist/entity-definition/reconstruct/reconstruct-child.d.ts +35 -0
  188. package/dist/entity-definition/reconstruct/reconstruct-child.d.ts.map +1 -0
  189. package/dist/entity-definition/reconstruct/reconstruct-child.js +47 -0
  190. package/dist/entity-definition/reconstruct/reconstruct-child.js.map +1 -0
  191. package/dist/entity-definition/reconstruct/reconstruct-entity.d.ts +49 -0
  192. package/dist/entity-definition/reconstruct/reconstruct-entity.d.ts.map +1 -0
  193. package/dist/entity-definition/reconstruct/reconstruct-entity.js +116 -0
  194. package/dist/entity-definition/reconstruct/reconstruct-entity.js.map +1 -0
  195. package/dist/entity-definition/serializer/deserialize.d.ts +13 -0
  196. package/dist/entity-definition/serializer/deserialize.d.ts.map +1 -0
  197. package/dist/entity-definition/serializer/deserialize.js +145 -0
  198. package/dist/entity-definition/serializer/deserialize.js.map +1 -0
  199. package/dist/entity-definition/serializer/index.d.ts +3 -0
  200. package/dist/entity-definition/serializer/index.d.ts.map +1 -0
  201. package/dist/entity-definition/serializer/index.js +4 -0
  202. package/dist/entity-definition/serializer/index.js.map +1 -0
  203. package/dist/entity-definition/serializer/serialize.d.ts +26 -0
  204. package/dist/entity-definition/serializer/serialize.d.ts.map +1 -0
  205. package/dist/entity-definition/serializer/serialize.js +64 -0
  206. package/dist/entity-definition/serializer/serialize.js.map +1 -0
  207. package/dist/envelope/event-pattern.d.ts +14 -0
  208. package/dist/envelope/event-pattern.d.ts.map +1 -0
  209. package/dist/envelope/event-pattern.js +30 -0
  210. package/dist/envelope/event-pattern.js.map +1 -0
  211. package/dist/envelope/index.d.ts +5 -0
  212. package/dist/envelope/index.d.ts.map +1 -0
  213. package/dist/envelope/index.js +6 -0
  214. package/dist/envelope/index.js.map +1 -0
  215. package/dist/envelope/make-envelope.d.ts +45 -0
  216. package/dist/envelope/make-envelope.d.ts.map +1 -0
  217. package/dist/envelope/make-envelope.js +111 -0
  218. package/dist/envelope/make-envelope.js.map +1 -0
  219. package/dist/envelope/read-envelope.d.ts +48 -0
  220. package/dist/envelope/read-envelope.d.ts.map +1 -0
  221. package/dist/envelope/read-envelope.js +138 -0
  222. package/dist/envelope/read-envelope.js.map +1 -0
  223. package/dist/envelope/types.d.ts +173 -0
  224. package/dist/envelope/types.d.ts.map +1 -0
  225. package/dist/envelope/types.js +6 -0
  226. package/dist/envelope/types.js.map +1 -0
  227. package/dist/http/session-cookies.d.ts +25 -0
  228. package/dist/http/session-cookies.d.ts.map +1 -0
  229. package/dist/http/session-cookies.js +22 -0
  230. package/dist/http/session-cookies.js.map +1 -0
  231. package/dist/i18n/format.d.ts +22 -0
  232. package/dist/i18n/format.d.ts.map +1 -0
  233. package/dist/i18n/format.js +49 -0
  234. package/dist/i18n/format.js.map +1 -0
  235. package/dist/i18n/index.d.ts +4 -0
  236. package/dist/i18n/index.d.ts.map +1 -0
  237. package/dist/i18n/index.js +5 -0
  238. package/dist/i18n/index.js.map +1 -0
  239. package/dist/i18n/locales.d.ts +23 -0
  240. package/dist/i18n/locales.d.ts.map +1 -0
  241. package/dist/i18n/locales.js +25 -0
  242. package/dist/i18n/locales.js.map +1 -0
  243. package/dist/i18n/negotiate.d.ts +39 -0
  244. package/dist/i18n/negotiate.d.ts.map +1 -0
  245. package/dist/i18n/negotiate.js +63 -0
  246. package/dist/i18n/negotiate.js.map +1 -0
  247. package/dist/index.d.ts +42 -0
  248. package/dist/index.d.ts.map +1 -0
  249. package/dist/index.js +43 -0
  250. package/dist/index.js.map +1 -0
  251. package/dist/rsql/coerce-rsql.d.ts +27 -0
  252. package/dist/rsql/coerce-rsql.d.ts.map +1 -0
  253. package/dist/rsql/coerce-rsql.js +121 -0
  254. package/dist/rsql/coerce-rsql.js.map +1 -0
  255. package/dist/rsql/index.d.ts +8 -0
  256. package/dist/rsql/index.d.ts.map +1 -0
  257. package/dist/rsql/index.js +9 -0
  258. package/dist/rsql/index.js.map +1 -0
  259. package/dist/rsql/load-request-url.d.ts +30 -0
  260. package/dist/rsql/load-request-url.d.ts.map +1 -0
  261. package/dist/rsql/load-request-url.js +67 -0
  262. package/dist/rsql/load-request-url.js.map +1 -0
  263. package/dist/rsql/parse-rsql.d.ts +35 -0
  264. package/dist/rsql/parse-rsql.d.ts.map +1 -0
  265. package/dist/rsql/parse-rsql.js +235 -0
  266. package/dist/rsql/parse-rsql.js.map +1 -0
  267. package/dist/rsql/rsql-operators.d.ts +36 -0
  268. package/dist/rsql/rsql-operators.d.ts.map +1 -0
  269. package/dist/rsql/rsql-operators.js +65 -0
  270. package/dist/rsql/rsql-operators.js.map +1 -0
  271. package/dist/rsql/rsql-values.d.ts +11 -0
  272. package/dist/rsql/rsql-values.d.ts.map +1 -0
  273. package/dist/rsql/rsql-values.js +26 -0
  274. package/dist/rsql/rsql-values.js.map +1 -0
  275. package/dist/rsql/serialize-rsql.d.ts +19 -0
  276. package/dist/rsql/serialize-rsql.d.ts.map +1 -0
  277. package/dist/rsql/serialize-rsql.js +71 -0
  278. package/dist/rsql/serialize-rsql.js.map +1 -0
  279. package/dist/rsql/sort-param.d.ts +20 -0
  280. package/dist/rsql/sort-param.d.ts.map +1 -0
  281. package/dist/rsql/sort-param.js +66 -0
  282. package/dist/rsql/sort-param.js.map +1 -0
  283. package/dist/types/BulkOutcome.d.ts +27 -0
  284. package/dist/types/BulkOutcome.d.ts.map +1 -0
  285. package/dist/types/BulkOutcome.js +8 -0
  286. package/dist/types/BulkOutcome.js.map +1 -0
  287. package/dist/types/Entity.d.ts +6 -0
  288. package/dist/types/Entity.d.ts.map +1 -0
  289. package/dist/types/Entity.js +3 -0
  290. package/dist/types/Entity.js.map +1 -0
  291. package/dist/types/EntityAction.d.ts +15 -0
  292. package/dist/types/EntityAction.d.ts.map +1 -0
  293. package/dist/types/EntityAction.js +18 -0
  294. package/dist/types/EntityAction.js.map +1 -0
  295. package/dist/types/EntityDraft.d.ts +47 -0
  296. package/dist/types/EntityDraft.d.ts.map +1 -0
  297. package/dist/types/EntityDraft.js +14 -0
  298. package/dist/types/EntityDraft.js.map +1 -0
  299. package/dist/types/EntityFiltering.d.ts +45 -0
  300. package/dist/types/EntityFiltering.d.ts.map +1 -0
  301. package/dist/types/EntityFiltering.js +30 -0
  302. package/dist/types/EntityFiltering.js.map +1 -0
  303. package/dist/types/EntityLoadRequest.d.ts +10 -0
  304. package/dist/types/EntityLoadRequest.d.ts.map +1 -0
  305. package/dist/types/EntityLoadRequest.js +3 -0
  306. package/dist/types/EntityLoadRequest.js.map +1 -0
  307. package/dist/types/EntityPage.d.ts +8 -0
  308. package/dist/types/EntityPage.d.ts.map +1 -0
  309. package/dist/types/EntityPage.js +3 -0
  310. package/dist/types/EntityPage.js.map +1 -0
  311. package/dist/types/EntityRowDraft.d.ts +79 -0
  312. package/dist/types/EntityRowDraft.d.ts.map +1 -0
  313. package/dist/types/EntityRowDraft.js +65 -0
  314. package/dist/types/EntityRowDraft.js.map +1 -0
  315. package/dist/types/EntitySelection.d.ts +117 -0
  316. package/dist/types/EntitySelection.d.ts.map +1 -0
  317. package/dist/types/EntitySelection.js +107 -0
  318. package/dist/types/EntitySelection.js.map +1 -0
  319. package/dist/types/EntitySorting.d.ts +7 -0
  320. package/dist/types/EntitySorting.d.ts.map +1 -0
  321. package/dist/types/EntitySorting.js +3 -0
  322. package/dist/types/EntitySorting.js.map +1 -0
  323. package/dist/types/Json.d.ts +37 -0
  324. package/dist/types/Json.d.ts.map +1 -0
  325. package/dist/types/Json.js +43 -0
  326. package/dist/types/Json.js.map +1 -0
  327. package/dist/types/StandardSchema.d.ts +45 -0
  328. package/dist/types/StandardSchema.d.ts.map +1 -0
  329. package/dist/types/StandardSchema.js +15 -0
  330. package/dist/types/StandardSchema.js.map +1 -0
  331. package/dist/types/UseCase.d.ts +10 -0
  332. package/dist/types/UseCase.d.ts.map +1 -0
  333. package/dist/types/UseCase.js +10 -0
  334. package/dist/types/UseCase.js.map +1 -0
  335. package/dist/wizard/index.d.ts +4 -0
  336. package/dist/wizard/index.d.ts.map +1 -0
  337. package/dist/wizard/index.js +5 -0
  338. package/dist/wizard/index.js.map +1 -0
  339. package/dist/wizard/wizard-definition.d.ts +108 -0
  340. package/dist/wizard/wizard-definition.d.ts.map +1 -0
  341. package/dist/wizard/wizard-definition.js +125 -0
  342. package/dist/wizard/wizard-definition.js.map +1 -0
  343. package/dist/wizard/wizard-navigation.d.ts +81 -0
  344. package/dist/wizard/wizard-navigation.d.ts.map +1 -0
  345. package/dist/wizard/wizard-navigation.js +139 -0
  346. package/dist/wizard/wizard-navigation.js.map +1 -0
  347. package/dist/wizard/wizard-state.d.ts +89 -0
  348. package/dist/wizard/wizard-state.d.ts.map +1 -0
  349. package/dist/wizard/wizard-state.js +103 -0
  350. package/dist/wizard/wizard-state.js.map +1 -0
  351. package/package.json +64 -0
@@ -0,0 +1,235 @@
1
+ import { EntifixBuildError } from '../base-entities/entifix-error/index.js';
2
+ import { RSQL_AND, RSQL_COMPARISON_TOKENS, RSQL_NULL_TOKEN, RSQL_OPERATORS, RSQL_OR, rsqlArity } from './rsql-operators.js';
3
+ /**
4
+ * Bounds on what an inbound expression may cost us. The URL comes from a
5
+ * client, so an unbounded parser is a denial-of-service surface: deep nesting
6
+ * would exhaust the stack and a huge disjunction would become an equally huge
7
+ * Mongo query.
8
+ */ const MAX_DEPTH = 16;
9
+ const MAX_NODES = 128;
10
+ const fail = (message, expression)=>new EntifixBuildError(`Invalid RSQL: ${message}`, undefined, {
11
+ expression
12
+ });
13
+ /** A property name — the RSQL selector. Kept conservative on purpose. */ const SELECTOR = /^[A-Za-z_][A-Za-z0-9_.-]*/;
14
+ const atEnd = (cursor)=>cursor.index >= cursor.text.length;
15
+ const peek = (cursor)=>cursor.text[cursor.index];
16
+ function skipWhitespace(cursor) {
17
+ while(!atEnd(cursor) && /\s/.test(cursor.text[cursor.index]))cursor.index++;
18
+ }
19
+ function countNode(cursor) {
20
+ if (++cursor.nodes > MAX_NODES) {
21
+ throw fail(`expression exceeds ${MAX_NODES} nodes`, cursor.text);
22
+ }
23
+ }
24
+ /**
25
+ * Reads one argument: a quoted string (either quote style, with `\` escapes) or
26
+ * a bare run of characters up to the next grammar character. The result is
27
+ * always a string — typing happens later, from metadata.
28
+ */ function readValue(cursor) {
29
+ skipWhitespace(cursor);
30
+ const quoteChar = peek(cursor);
31
+ if (quoteChar === "'" || quoteChar === '"') {
32
+ cursor.index++;
33
+ let value = '';
34
+ while(!atEnd(cursor)){
35
+ const char = cursor.text[cursor.index];
36
+ if (char === '\\') {
37
+ const escaped = cursor.text[cursor.index + 1];
38
+ if (escaped === undefined) {
39
+ throw fail('expression ends in an escape', cursor.text);
40
+ }
41
+ value += escaped;
42
+ cursor.index += 2;
43
+ continue;
44
+ }
45
+ if (char === quoteChar) {
46
+ cursor.index++;
47
+ return value;
48
+ }
49
+ value += char;
50
+ cursor.index++;
51
+ }
52
+ throw fail('unterminated quoted value', cursor.text);
53
+ }
54
+ const start = cursor.index;
55
+ while(!atEnd(cursor) && !/[;,()\s]/.test(cursor.text[cursor.index])){
56
+ cursor.index++;
57
+ }
58
+ if (cursor.index === start) {
59
+ throw fail('missing value', cursor.text);
60
+ }
61
+ return cursor.text.slice(start, cursor.index);
62
+ }
63
+ /** Reads `(a,b,…)` — the argument list of `=in=`/`=out=`/`=btn=`/`=nbtn=`. */ function readValueList(cursor) {
64
+ skipWhitespace(cursor);
65
+ if (peek(cursor) !== '(') {
66
+ throw fail('expected a parenthesized value list', cursor.text);
67
+ }
68
+ cursor.index++;
69
+ const values = [];
70
+ for(;;){
71
+ values.push(readValue(cursor));
72
+ skipWhitespace(cursor);
73
+ const char = peek(cursor);
74
+ if (char === ',') {
75
+ cursor.index++;
76
+ continue;
77
+ }
78
+ if (char === ')') {
79
+ cursor.index++;
80
+ return values;
81
+ }
82
+ throw fail('unterminated value list', cursor.text);
83
+ }
84
+ }
85
+ /** Matches the longest comparison token at the cursor, or `undefined`. */ function readToken(cursor) {
86
+ for (const token of RSQL_COMPARISON_TOKENS){
87
+ if (cursor.text.startsWith(token, cursor.index)) {
88
+ cursor.index += token.length;
89
+ return token;
90
+ }
91
+ }
92
+ return undefined;
93
+ }
94
+ function parseComparison(cursor) {
95
+ countNode(cursor);
96
+ skipWhitespace(cursor);
97
+ const selector = SELECTOR.exec(cursor.text.slice(cursor.index));
98
+ if (!selector) {
99
+ throw fail(`expected a property name at position ${cursor.index}`, cursor.text);
100
+ }
101
+ const property = selector[0];
102
+ cursor.index += property.length;
103
+ skipWhitespace(cursor);
104
+ const token = readToken(cursor);
105
+ if (!token) {
106
+ throw fail(`expected an operator after "${property}"`, cursor.text);
107
+ }
108
+ if (token === RSQL_NULL_TOKEN) {
109
+ const argument = readValue(cursor);
110
+ if (argument !== 'true' && argument !== 'false') {
111
+ throw fail(`"${RSQL_NULL_TOKEN}" takes true or false`, cursor.text);
112
+ }
113
+ return {
114
+ property,
115
+ operator: argument === 'true' ? 'isNull' : 'isNotNull'
116
+ };
117
+ }
118
+ const operator = RSQL_OPERATORS[token];
119
+ switch(rsqlArity(operator)){
120
+ case 'list':
121
+ return {
122
+ property,
123
+ operator,
124
+ values: readValueList(cursor)
125
+ };
126
+ case 'range':
127
+ {
128
+ const bounds = readValueList(cursor);
129
+ if (bounds.length !== 2) {
130
+ throw fail(`"${token}" takes exactly two bounds`, cursor.text);
131
+ }
132
+ return {
133
+ property,
134
+ operator,
135
+ start: bounds[0],
136
+ end: bounds[1]
137
+ };
138
+ }
139
+ default:
140
+ return {
141
+ property,
142
+ operator,
143
+ value: readValue(cursor)
144
+ };
145
+ }
146
+ }
147
+ /** A comparison, or a parenthesized sub-expression. */ function parsePrimary(cursor, depth) {
148
+ skipWhitespace(cursor);
149
+ if (peek(cursor) === '(') {
150
+ if (depth >= MAX_DEPTH) {
151
+ throw fail(`nesting deeper than ${MAX_DEPTH} levels`, cursor.text);
152
+ }
153
+ cursor.index++;
154
+ const group = parseOr(cursor, depth + 1);
155
+ skipWhitespace(cursor);
156
+ if (peek(cursor) !== ')') {
157
+ throw fail('unbalanced parenthesis', cursor.text);
158
+ }
159
+ cursor.index++;
160
+ return group;
161
+ }
162
+ return parseComparison(cursor);
163
+ }
164
+ /**
165
+ * Collapses a single-child group into that child, so `a==1` parses to one
166
+ * comparison rather than three nested wrappers. Keeps the parsed tree
167
+ * comparable with the one that was serialized.
168
+ */ function group(operator, values) {
169
+ return values.length === 1 ? values[0] : {
170
+ operator,
171
+ values
172
+ };
173
+ }
174
+ function parseAnd(cursor, depth) {
175
+ const values = [
176
+ parsePrimary(cursor, depth)
177
+ ];
178
+ for(;;){
179
+ skipWhitespace(cursor);
180
+ if (peek(cursor) !== RSQL_AND) return group('and', values);
181
+ cursor.index++;
182
+ values.push(parsePrimary(cursor, depth));
183
+ }
184
+ }
185
+ function parseOr(cursor, depth) {
186
+ const values = [
187
+ parseAnd(cursor, depth)
188
+ ];
189
+ for(;;){
190
+ skipWhitespace(cursor);
191
+ if (peek(cursor) !== RSQL_OR) return group('or', values);
192
+ cursor.index++;
193
+ values.push(parseAnd(cursor, depth));
194
+ }
195
+ }
196
+ /**
197
+ * Parses an RSQL expression into a raw (still untyped) filter tree.
198
+ *
199
+ * Precedence follows RSQL: `,` (or) binds looser than `;` (and), and
200
+ * parentheses override both. Values stay strings — {@link coerceFiltering} is
201
+ * what turns them into the entity's own types, and it is also what checks the
202
+ * properties against the metadata allowlist. Parsing alone never trusts the
203
+ * input enough to build a query from it.
204
+ *
205
+ * Throws {@link EntifixBuildError} on malformed input, which services surface
206
+ * as a `400`.
207
+ */ export function parseRsql(expression) {
208
+ const trimmed = expression.trim();
209
+ if (trimmed === '') return {
210
+ operator: 'and',
211
+ values: []
212
+ };
213
+ const cursor = {
214
+ text: trimmed,
215
+ index: 0,
216
+ nodes: 0
217
+ };
218
+ const parsed = parseOr(cursor, 0);
219
+ skipWhitespace(cursor);
220
+ if (!atEnd(cursor)) {
221
+ throw fail(`unexpected "${peek(cursor)}" at position ${cursor.index}`, trimmed);
222
+ }
223
+ // The result is always a group, so callers get one shape to walk.
224
+ return 'property' in parsed ? {
225
+ operator: 'and',
226
+ values: [
227
+ parsed
228
+ ]
229
+ } : parsed;
230
+ }
231
+ /** Narrows a raw node to a comparison. */ export function isRawFilter(node) {
232
+ return 'property' in node;
233
+ }
234
+
235
+ //# sourceMappingURL=parse-rsql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/rsql/parse-rsql.ts"],"sourcesContent":["import { EntifixBuildError } from '../base-entities/entifix-error/index.js';\nimport {\n RSQL_AND,\n RSQL_COMPARISON_TOKENS,\n RSQL_NULL_TOKEN,\n RSQL_OPERATORS,\n RSQL_OR,\n rsqlArity,\n type RsqlOperator,\n} from './rsql-operators.js';\n\n/**\n * A parsed filter before coercion: identical to an {@link EntityFilter} except\n * every argument is still the raw string the URL carried. Re-typing needs the\n * entity's metadata, which this parser deliberately does not have — see\n * `coerce-rsql`.\n */\nexport type RawFilter = {\n property: string;\n operator: RsqlOperator;\n value?: string;\n values?: string[];\n start?: string;\n end?: string;\n};\n\nexport type RawFilterGroup = {\n operator: 'and' | 'or';\n values: Array<RawFilter | RawFilterGroup>;\n};\n\n/**\n * Bounds on what an inbound expression may cost us. The URL comes from a\n * client, so an unbounded parser is a denial-of-service surface: deep nesting\n * would exhaust the stack and a huge disjunction would become an equally huge\n * Mongo query.\n */\nconst MAX_DEPTH = 16;\nconst MAX_NODES = 128;\n\nconst fail = (message: string, expression: string) =>\n new EntifixBuildError(`Invalid RSQL: ${message}`, undefined, { expression });\n\n/** A property name — the RSQL selector. Kept conservative on purpose. */\nconst SELECTOR = /^[A-Za-z_][A-Za-z0-9_.-]*/;\n\ninterface Cursor {\n readonly text: string;\n index: number;\n nodes: number;\n}\n\nconst atEnd = (cursor: Cursor) => cursor.index >= cursor.text.length;\n\nconst peek = (cursor: Cursor) => cursor.text[cursor.index];\n\nfunction skipWhitespace(cursor: Cursor): void {\n while (!atEnd(cursor) && /\\s/.test(cursor.text[cursor.index])) cursor.index++;\n}\n\nfunction countNode(cursor: Cursor): void {\n if (++cursor.nodes > MAX_NODES) {\n throw fail(`expression exceeds ${MAX_NODES} nodes`, cursor.text);\n }\n}\n\n/**\n * Reads one argument: a quoted string (either quote style, with `\\` escapes) or\n * a bare run of characters up to the next grammar character. The result is\n * always a string — typing happens later, from metadata.\n */\nfunction readValue(cursor: Cursor): string {\n skipWhitespace(cursor);\n const quoteChar = peek(cursor);\n\n if (quoteChar === \"'\" || quoteChar === '\"') {\n cursor.index++;\n let value = '';\n while (!atEnd(cursor)) {\n const char = cursor.text[cursor.index];\n if (char === '\\\\') {\n const escaped = cursor.text[cursor.index + 1];\n if (escaped === undefined) {\n throw fail('expression ends in an escape', cursor.text);\n }\n value += escaped;\n cursor.index += 2;\n continue;\n }\n if (char === quoteChar) {\n cursor.index++;\n return value;\n }\n value += char;\n cursor.index++;\n }\n throw fail('unterminated quoted value', cursor.text);\n }\n\n const start = cursor.index;\n while (!atEnd(cursor) && !/[;,()\\s]/.test(cursor.text[cursor.index])) {\n cursor.index++;\n }\n if (cursor.index === start) {\n throw fail('missing value', cursor.text);\n }\n return cursor.text.slice(start, cursor.index);\n}\n\n/** Reads `(a,b,…)` — the argument list of `=in=`/`=out=`/`=btn=`/`=nbtn=`. */\nfunction readValueList(cursor: Cursor): string[] {\n skipWhitespace(cursor);\n if (peek(cursor) !== '(') {\n throw fail('expected a parenthesized value list', cursor.text);\n }\n cursor.index++;\n\n const values: string[] = [];\n for (;;) {\n values.push(readValue(cursor));\n skipWhitespace(cursor);\n const char = peek(cursor);\n if (char === ',') {\n cursor.index++;\n continue;\n }\n if (char === ')') {\n cursor.index++;\n return values;\n }\n throw fail('unterminated value list', cursor.text);\n }\n}\n\n/** Matches the longest comparison token at the cursor, or `undefined`. */\nfunction readToken(cursor: Cursor): string | undefined {\n for (const token of RSQL_COMPARISON_TOKENS) {\n if (cursor.text.startsWith(token, cursor.index)) {\n cursor.index += token.length;\n return token;\n }\n }\n return undefined;\n}\n\nfunction parseComparison(cursor: Cursor): RawFilter {\n countNode(cursor);\n skipWhitespace(cursor);\n\n const selector = SELECTOR.exec(cursor.text.slice(cursor.index));\n if (!selector) {\n throw fail(\n `expected a property name at position ${cursor.index}`,\n cursor.text,\n );\n }\n const property = selector[0];\n cursor.index += property.length;\n\n skipWhitespace(cursor);\n const token = readToken(cursor);\n if (!token) {\n throw fail(`expected an operator after \"${property}\"`, cursor.text);\n }\n\n if (token === RSQL_NULL_TOKEN) {\n const argument = readValue(cursor);\n if (argument !== 'true' && argument !== 'false') {\n throw fail(`\"${RSQL_NULL_TOKEN}\" takes true or false`, cursor.text);\n }\n return {\n property,\n operator: argument === 'true' ? 'isNull' : 'isNotNull',\n };\n }\n\n const operator = RSQL_OPERATORS[token];\n\n switch (rsqlArity(operator)) {\n case 'list':\n return { property, operator, values: readValueList(cursor) };\n case 'range': {\n const bounds = readValueList(cursor);\n if (bounds.length !== 2) {\n throw fail(`\"${token}\" takes exactly two bounds`, cursor.text);\n }\n return { property, operator, start: bounds[0], end: bounds[1] };\n }\n default:\n return { property, operator, value: readValue(cursor) };\n }\n}\n\n/** A comparison, or a parenthesized sub-expression. */\nfunction parsePrimary(\n cursor: Cursor,\n depth: number,\n): RawFilter | RawFilterGroup {\n skipWhitespace(cursor);\n\n if (peek(cursor) === '(') {\n if (depth >= MAX_DEPTH) {\n throw fail(`nesting deeper than ${MAX_DEPTH} levels`, cursor.text);\n }\n cursor.index++;\n const group = parseOr(cursor, depth + 1);\n skipWhitespace(cursor);\n if (peek(cursor) !== ')') {\n throw fail('unbalanced parenthesis', cursor.text);\n }\n cursor.index++;\n return group;\n }\n\n return parseComparison(cursor);\n}\n\n/**\n * Collapses a single-child group into that child, so `a==1` parses to one\n * comparison rather than three nested wrappers. Keeps the parsed tree\n * comparable with the one that was serialized.\n */\nfunction group(\n operator: 'and' | 'or',\n values: Array<RawFilter | RawFilterGroup>,\n): RawFilter | RawFilterGroup {\n return values.length === 1 ? values[0] : { operator, values };\n}\n\nfunction parseAnd(cursor: Cursor, depth: number): RawFilter | RawFilterGroup {\n const values = [parsePrimary(cursor, depth)];\n for (;;) {\n skipWhitespace(cursor);\n if (peek(cursor) !== RSQL_AND) return group('and', values);\n cursor.index++;\n values.push(parsePrimary(cursor, depth));\n }\n}\n\nfunction parseOr(cursor: Cursor, depth: number): RawFilter | RawFilterGroup {\n const values = [parseAnd(cursor, depth)];\n for (;;) {\n skipWhitespace(cursor);\n if (peek(cursor) !== RSQL_OR) return group('or', values);\n cursor.index++;\n values.push(parseAnd(cursor, depth));\n }\n}\n\n/**\n * Parses an RSQL expression into a raw (still untyped) filter tree.\n *\n * Precedence follows RSQL: `,` (or) binds looser than `;` (and), and\n * parentheses override both. Values stay strings — {@link coerceFiltering} is\n * what turns them into the entity's own types, and it is also what checks the\n * properties against the metadata allowlist. Parsing alone never trusts the\n * input enough to build a query from it.\n *\n * Throws {@link EntifixBuildError} on malformed input, which services surface\n * as a `400`.\n */\nexport function parseRsql(expression: string): RawFilterGroup {\n const trimmed = expression.trim();\n if (trimmed === '') return { operator: 'and', values: [] };\n\n const cursor: Cursor = { text: trimmed, index: 0, nodes: 0 };\n const parsed = parseOr(cursor, 0);\n\n skipWhitespace(cursor);\n if (!atEnd(cursor)) {\n throw fail(\n `unexpected \"${peek(cursor)}\" at position ${cursor.index}`,\n trimmed,\n );\n }\n\n // The result is always a group, so callers get one shape to walk.\n return 'property' in parsed ? { operator: 'and', values: [parsed] } : parsed;\n}\n\n/** Narrows a raw node to a comparison. */\nexport function isRawFilter(\n node: RawFilter | RawFilterGroup,\n): node is RawFilter {\n return 'property' in node;\n}\n"],"names":["EntifixBuildError","RSQL_AND","RSQL_COMPARISON_TOKENS","RSQL_NULL_TOKEN","RSQL_OPERATORS","RSQL_OR","rsqlArity","MAX_DEPTH","MAX_NODES","fail","message","expression","undefined","SELECTOR","atEnd","cursor","index","text","length","peek","skipWhitespace","test","countNode","nodes","readValue","quoteChar","value","char","escaped","start","slice","readValueList","values","push","readToken","token","startsWith","parseComparison","selector","exec","property","argument","operator","bounds","end","parsePrimary","depth","group","parseOr","parseAnd","parseRsql","trimmed","trim","parsed","isRawFilter","node"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { EntityFilterArrayOperators, EntityFilterNullOperators, EntityFilterRangeOperators, EntityFilterStringOperators } from '../types/EntityFiltering.js';
2
+ /** Every operator an `EntityFilter` can carry, flattened across its variants. */
3
+ export type RsqlOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | (typeof EntityFilterArrayOperators)[number] | (typeof EntityFilterRangeOperators)[number] | (typeof EntityFilterStringOperators)[number] | (typeof EntityFilterNullOperators)[number];
4
+ /**
5
+ * The RSQL token each operator is written as. `==`/`!=`/`=gt=`/`=ge=`/`=lt=`/
6
+ * `=le=`/`=in=`/`=out=` are standard RSQL; the rest are entifix extensions,
7
+ * named in the same `=word=` shape so a generic RSQL tokenizer still splits
8
+ * them correctly.
9
+ *
10
+ * `isNull`/`isNotNull` share the `=isnull=` token and are told apart by their
11
+ * boolean argument, because RSQL has no unary comparison.
12
+ */
13
+ export declare const RSQL_TOKENS: Record<RsqlOperator, string>;
14
+ /**
15
+ * Token → operator. `=isnull=` is absent on purpose: it maps to two operators,
16
+ * so the parser resolves it from the argument instead.
17
+ */
18
+ export declare const RSQL_OPERATORS: Record<string, RsqlOperator>;
19
+ /** The token shared by `isNull`/`isNotNull`. */
20
+ export declare const RSQL_NULL_TOKEN = "=isnull=";
21
+ /**
22
+ * Comparison tokens ordered longest-first. The tokenizer matches greedily, so
23
+ * `=nbtn=` must be tried before any shorter token it starts with; scanning this
24
+ * list in order is what makes that safe as tokens are added.
25
+ */
26
+ export declare const RSQL_COMPARISON_TOKENS: readonly string[];
27
+ /**
28
+ * How many arguments an operator's RSQL form carries: `none` still writes a
29
+ * boolean argument (see `=isnull=`), `list` and `range` write a parenthesized
30
+ * group, `single` a bare value.
31
+ */
32
+ export declare function rsqlArity(operator: RsqlOperator): 'none' | 'single' | 'list' | 'range';
33
+ /** Logic operator → its RSQL separator. */
34
+ export declare const RSQL_AND = ";";
35
+ export declare const RSQL_OR = ",";
36
+ //# sourceMappingURL=rsql-operators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rsql-operators.d.ts","sourceRoot":"","sources":["../../src/rsql/rsql-operators.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,6BAA6B,CAAC;AAErC,iFAAiF;AACjF,MAAM,MAAM,YAAY,GACpB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,GAC3C,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,GAC3C,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,GAC5C,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAepD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAavD,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAGD,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,YAAY,GACrB,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAQtC;AAED,2CAA2C;AAC3C,eAAO,MAAM,QAAQ,MAAM,CAAC;AAC5B,eAAO,MAAM,OAAO,MAAM,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { EntityFilterArrayOperators, EntityFilterNullOperators, EntityFilterRangeOperators } from '../types/EntityFiltering.js';
2
+ /**
3
+ * The RSQL token each operator is written as. `==`/`!=`/`=gt=`/`=ge=`/`=lt=`/
4
+ * `=le=`/`=in=`/`=out=` are standard RSQL; the rest are entifix extensions,
5
+ * named in the same `=word=` shape so a generic RSQL tokenizer still splits
6
+ * them correctly.
7
+ *
8
+ * `isNull`/`isNotNull` share the `=isnull=` token and are told apart by their
9
+ * boolean argument, because RSQL has no unary comparison.
10
+ */ export const RSQL_TOKENS = {
11
+ eq: '==',
12
+ ne: '!=',
13
+ gt: '=gt=',
14
+ gte: '=ge=',
15
+ lt: '=lt=',
16
+ lte: '=le=',
17
+ in: '=in=',
18
+ nin: '=out=',
19
+ between: '=btn=',
20
+ nbetween: '=nbtn=',
21
+ like: '=like=',
22
+ nlike: '=nlike=',
23
+ isNull: '=isnull=',
24
+ isNotNull: '=isnull='
25
+ };
26
+ /**
27
+ * Token → operator. `=isnull=` is absent on purpose: it maps to two operators,
28
+ * so the parser resolves it from the argument instead.
29
+ */ export const RSQL_OPERATORS = {
30
+ '==': 'eq',
31
+ '!=': 'ne',
32
+ '=gt=': 'gt',
33
+ '=ge=': 'gte',
34
+ '=lt=': 'lt',
35
+ '=le=': 'lte',
36
+ '=in=': 'in',
37
+ '=out=': 'nin',
38
+ '=btn=': 'between',
39
+ '=nbtn=': 'nbetween',
40
+ '=like=': 'like',
41
+ '=nlike=': 'nlike'
42
+ };
43
+ /** The token shared by `isNull`/`isNotNull`. */ export const RSQL_NULL_TOKEN = '=isnull=';
44
+ /**
45
+ * Comparison tokens ordered longest-first. The tokenizer matches greedily, so
46
+ * `=nbtn=` must be tried before any shorter token it starts with; scanning this
47
+ * list in order is what makes that safe as tokens are added.
48
+ */ export const RSQL_COMPARISON_TOKENS = [
49
+ ...Object.keys(RSQL_OPERATORS),
50
+ RSQL_NULL_TOKEN
51
+ ].sort((left, right)=>right.length - left.length);
52
+ /**
53
+ * How many arguments an operator's RSQL form carries: `none` still writes a
54
+ * boolean argument (see `=isnull=`), `list` and `range` write a parenthesized
55
+ * group, `single` a bare value.
56
+ */ export function rsqlArity(operator) {
57
+ if (EntityFilterNullOperators.includes(operator)) return 'none';
58
+ if (EntityFilterRangeOperators.includes(operator)) return 'range';
59
+ if (EntityFilterArrayOperators.includes(operator)) return 'list';
60
+ return 'single';
61
+ }
62
+ /** Logic operator → its RSQL separator. */ export const RSQL_AND = ';';
63
+ export const RSQL_OR = ',';
64
+
65
+ //# sourceMappingURL=rsql-operators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/rsql/rsql-operators.ts"],"sourcesContent":["import {\n EntityFilterArrayOperators,\n EntityFilterNullOperators,\n EntityFilterRangeOperators,\n EntityFilterStringOperators,\n} from '../types/EntityFiltering.js';\n\n/** Every operator an `EntityFilter` can carry, flattened across its variants. */\nexport type RsqlOperator =\n | 'eq'\n | 'ne'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | (typeof EntityFilterArrayOperators)[number]\n | (typeof EntityFilterRangeOperators)[number]\n | (typeof EntityFilterStringOperators)[number]\n | (typeof EntityFilterNullOperators)[number];\n\n/**\n * The RSQL token each operator is written as. `==`/`!=`/`=gt=`/`=ge=`/`=lt=`/\n * `=le=`/`=in=`/`=out=` are standard RSQL; the rest are entifix extensions,\n * named in the same `=word=` shape so a generic RSQL tokenizer still splits\n * them correctly.\n *\n * `isNull`/`isNotNull` share the `=isnull=` token and are told apart by their\n * boolean argument, because RSQL has no unary comparison.\n */\nexport const RSQL_TOKENS: Record<RsqlOperator, string> = {\n eq: '==',\n ne: '!=',\n gt: '=gt=',\n gte: '=ge=',\n lt: '=lt=',\n lte: '=le=',\n in: '=in=',\n nin: '=out=',\n between: '=btn=',\n nbetween: '=nbtn=',\n like: '=like=',\n nlike: '=nlike=',\n isNull: '=isnull=',\n isNotNull: '=isnull=',\n};\n\n/**\n * Token → operator. `=isnull=` is absent on purpose: it maps to two operators,\n * so the parser resolves it from the argument instead.\n */\nexport const RSQL_OPERATORS: Record<string, RsqlOperator> = {\n '==': 'eq',\n '!=': 'ne',\n '=gt=': 'gt',\n '=ge=': 'gte',\n '=lt=': 'lt',\n '=le=': 'lte',\n '=in=': 'in',\n '=out=': 'nin',\n '=btn=': 'between',\n '=nbtn=': 'nbetween',\n '=like=': 'like',\n '=nlike=': 'nlike',\n};\n\n/** The token shared by `isNull`/`isNotNull`. */\nexport const RSQL_NULL_TOKEN = '=isnull=';\n\n/**\n * Comparison tokens ordered longest-first. The tokenizer matches greedily, so\n * `=nbtn=` must be tried before any shorter token it starts with; scanning this\n * list in order is what makes that safe as tokens are added.\n */\nexport const RSQL_COMPARISON_TOKENS: readonly string[] = [\n ...Object.keys(RSQL_OPERATORS),\n RSQL_NULL_TOKEN,\n].sort((left, right) => right.length - left.length);\n\n/**\n * How many arguments an operator's RSQL form carries: `none` still writes a\n * boolean argument (see `=isnull=`), `list` and `range` write a parenthesized\n * group, `single` a bare value.\n */\nexport function rsqlArity(\n operator: RsqlOperator,\n): 'none' | 'single' | 'list' | 'range' {\n if ((EntityFilterNullOperators as readonly string[]).includes(operator))\n return 'none';\n if ((EntityFilterRangeOperators as readonly string[]).includes(operator))\n return 'range';\n if ((EntityFilterArrayOperators as readonly string[]).includes(operator))\n return 'list';\n return 'single';\n}\n\n/** Logic operator → its RSQL separator. */\nexport const RSQL_AND = ';';\nexport const RSQL_OR = ',';\n"],"names":["EntityFilterArrayOperators","EntityFilterNullOperators","EntityFilterRangeOperators","RSQL_TOKENS","eq","ne","gt","gte","lt","lte","in","nin","between","nbetween","like","nlike","isNull","isNotNull","RSQL_OPERATORS","RSQL_NULL_TOKEN","RSQL_COMPARISON_TOKENS","Object","keys","sort","left","right","length","rsqlArity","operator","includes","RSQL_AND","RSQL_OR"],"mappings":"AAAA,SACEA,0BAA0B,EAC1BC,yBAAyB,EACzBC,0BAA0B,QAErB,8BAA8B;AAerC;;;;;;;;CAQC,GACD,OAAO,MAAMC,cAA4C;IACvDC,IAAI;IACJC,IAAI;IACJC,IAAI;IACJC,KAAK;IACLC,IAAI;IACJC,KAAK;IACLC,IAAI;IACJC,KAAK;IACLC,SAAS;IACTC,UAAU;IACVC,MAAM;IACNC,OAAO;IACPC,QAAQ;IACRC,WAAW;AACb,EAAE;AAEF;;;CAGC,GACD,OAAO,MAAMC,iBAA+C;IAC1D,MAAM;IACN,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,SAAS;IACT,UAAU;IACV,UAAU;IACV,WAAW;AACb,EAAE;AAEF,8CAA8C,GAC9C,OAAO,MAAMC,kBAAkB,WAAW;AAE1C;;;;CAIC,GACD,OAAO,MAAMC,yBAA4C;OACpDC,OAAOC,IAAI,CAACJ;IACfC;CACD,CAACI,IAAI,CAAC,CAACC,MAAMC,QAAUA,MAAMC,MAAM,GAAGF,KAAKE,MAAM,EAAE;AAEpD;;;;CAIC,GACD,OAAO,SAASC,UACdC,QAAsB;IAEtB,IAAI,AAAC3B,0BAAgD4B,QAAQ,CAACD,WAC5D,OAAO;IACT,IAAI,AAAC1B,2BAAiD2B,QAAQ,CAACD,WAC7D,OAAO;IACT,IAAI,AAAC5B,2BAAiD6B,QAAQ,CAACD,WAC7D,OAAO;IACT,OAAO;AACT;AAEA,yCAAyC,GACzC,OAAO,MAAME,WAAW,IAAI;AAC5B,OAAO,MAAMC,UAAU,IAAI"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Writes a value as an RSQL argument. Numbers and booleans go out bare (that is
3
+ * how RSQL is normally read by a human or another implementation); everything
4
+ * else is single-quoted, which is also the only way a value containing a
5
+ * separator can survive the round trip.
6
+ *
7
+ * Dates are written as ISO-8601 — the one lossless textual form, and the one
8
+ * the coercion step parses back.
9
+ */
10
+ export declare function encodeRsqlValue(value: unknown): string;
11
+ //# sourceMappingURL=rsql-values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rsql-values.d.ts","sourceRoot":"","sources":["../../src/rsql/rsql-values.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAStD"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Characters that would otherwise be read as grammar. A value containing any of
3
+ * them has to be quoted, or the tokenizer would split the expression inside it.
4
+ */ const RESERVED = /[\s;,()'"=!<>\\]/;
5
+ /**
6
+ * Writes a value as an RSQL argument. Numbers and booleans go out bare (that is
7
+ * how RSQL is normally read by a human or another implementation); everything
8
+ * else is single-quoted, which is also the only way a value containing a
9
+ * separator can survive the round trip.
10
+ *
11
+ * Dates are written as ISO-8601 — the one lossless textual form, and the one
12
+ * the coercion step parses back.
13
+ */ export function encodeRsqlValue(value) {
14
+ if (value === null || value === undefined) return "''";
15
+ if (typeof value === 'number' || typeof value === 'boolean') {
16
+ return String(value);
17
+ }
18
+ if (value instanceof Date) return quote(value.toISOString());
19
+ const text = String(value);
20
+ return text === '' || RESERVED.test(text) ? quote(text) : text;
21
+ }
22
+ /** Single-quotes a value, escaping the quote and the escape character itself. */ function quote(text) {
23
+ return `'${text.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
24
+ }
25
+
26
+ //# sourceMappingURL=rsql-values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/rsql/rsql-values.ts"],"sourcesContent":["/**\n * Characters that would otherwise be read as grammar. A value containing any of\n * them has to be quoted, or the tokenizer would split the expression inside it.\n */\nconst RESERVED = /[\\s;,()'\"=!<>\\\\]/;\n\n/**\n * Writes a value as an RSQL argument. Numbers and booleans go out bare (that is\n * how RSQL is normally read by a human or another implementation); everything\n * else is single-quoted, which is also the only way a value containing a\n * separator can survive the round trip.\n *\n * Dates are written as ISO-8601 — the one lossless textual form, and the one\n * the coercion step parses back.\n */\nexport function encodeRsqlValue(value: unknown): string {\n if (value === null || value === undefined) return \"''\";\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n if (value instanceof Date) return quote(value.toISOString());\n\n const text = String(value);\n return text === '' || RESERVED.test(text) ? quote(text) : text;\n}\n\n/** Single-quotes a value, escaping the quote and the escape character itself. */\nfunction quote(text: string): string {\n return `'${text.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`;\n}\n"],"names":["RESERVED","encodeRsqlValue","value","undefined","String","Date","quote","toISOString","text","test","replace"],"mappings":"AAAA;;;CAGC,GACD,MAAMA,WAAW;AAEjB;;;;;;;;CAQC,GACD,OAAO,SAASC,gBAAgBC,KAAc;IAC5C,IAAIA,UAAU,QAAQA,UAAUC,WAAW,OAAO;IAClD,IAAI,OAAOD,UAAU,YAAY,OAAOA,UAAU,WAAW;QAC3D,OAAOE,OAAOF;IAChB;IACA,IAAIA,iBAAiBG,MAAM,OAAOC,MAAMJ,MAAMK,WAAW;IAEzD,MAAMC,OAAOJ,OAAOF;IACpB,OAAOM,SAAS,MAAMR,SAASS,IAAI,CAACD,QAAQF,MAAME,QAAQA;AAC5D;AAEA,+EAA+E,GAC/E,SAASF,MAAME,IAAY;IACzB,OAAO,CAAC,CAAC,EAAEA,KAAKE,OAAO,CAAC,OAAO,QAAQA,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC;AAChE"}
@@ -0,0 +1,19 @@
1
+ import type { Entity } from '../types/Entity.js';
2
+ import type { EntityFilter, EntityFiltering, FilterGroup } from '../types/EntityFiltering.js';
3
+ /**
4
+ * A group carries `values` + a logic operator and, unlike the array filter, has
5
+ * no `property`. Same discriminator the Mongo `filter-translator` uses — the
6
+ * two must agree on what counts as a group or a filter would translate one way
7
+ * and serialize another.
8
+ */
9
+ export declare function isFilterGroup<TEntity extends Entity>(node: EntityFilter<TEntity> | FilterGroup<TEntity>): node is FilterGroup<TEntity>;
10
+ /**
11
+ * Serializes an {@link EntityLoadRequest}'s `filtering` into an RSQL
12
+ * expression. Every top-level entry is joined with `;` (and), mirroring how
13
+ * `translateFiltering` combines them with `$and` on the Mongo side.
14
+ *
15
+ * An absent, empty, or wholly-empty filtering yields `''`, which callers omit
16
+ * from the URL entirely rather than sending an empty parameter.
17
+ */
18
+ export declare function serializeRsql<TEntity extends Entity>(filtering?: EntityFiltering<TEntity>[]): string;
19
+ //# sourceMappingURL=serialize-rsql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize-rsql.d.ts","sourceRoot":"","sources":["../../src/rsql/serialize-rsql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,WAAW,EAEZ,MAAM,6BAA6B,CAAC;AAUrC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAS,MAAM,EAClD,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,GACjD,IAAI,IAAI,WAAW,CAAC,OAAO,CAAC,CAI9B;AA0DD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAS,MAAM,EAClD,SAAS,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,GACrC,MAAM,CAaR"}
@@ -0,0 +1,71 @@
1
+ import { RSQL_AND, RSQL_OR, RSQL_TOKENS, rsqlArity } from './rsql-operators.js';
2
+ import { encodeRsqlValue } from './rsql-values.js';
3
+ /**
4
+ * A group carries `values` + a logic operator and, unlike the array filter, has
5
+ * no `property`. Same discriminator the Mongo `filter-translator` uses — the
6
+ * two must agree on what counts as a group or a filter would translate one way
7
+ * and serialize another.
8
+ */ export function isFilterGroup(node) {
9
+ return !('property' in node) && (node.operator === 'and' || node.operator === 'or');
10
+ }
11
+ const separatorFor = (operator)=>operator === 'or' ? RSQL_OR : RSQL_AND;
12
+ /** `isNull`/`isNotNull` share one token, told apart by their boolean argument. */ const nullArgument = (operator)=>operator === 'isNull' ? 'true' : 'false';
13
+ function serializeComparison(filter) {
14
+ const operator = filter.operator;
15
+ const property = String(filter.property);
16
+ const token = RSQL_TOKENS[operator];
17
+ switch(rsqlArity(operator)){
18
+ case 'none':
19
+ return `${property}${token}${nullArgument(operator)}`;
20
+ case 'list':
21
+ {
22
+ const { values } = filter;
23
+ return `${property}${token}(${values.map(encodeRsqlValue).join(',')})`;
24
+ }
25
+ case 'range':
26
+ {
27
+ const { start, end } = filter;
28
+ return `${property}${token}(${encodeRsqlValue(start)},${encodeRsqlValue(end)})`;
29
+ }
30
+ default:
31
+ {
32
+ const { value } = filter;
33
+ return `${property}${token}${encodeRsqlValue(value)}`;
34
+ }
35
+ }
36
+ }
37
+ /**
38
+ * Serializes one node. `parent` is the logic operator this node's text will sit
39
+ * inside: a group only needs parentheses when its own operator differs, since
40
+ * `;` and `,` already read left-to-right within one operator.
41
+ */ function serializeNode(node, parent) {
42
+ if (!isFilterGroup(node)) return serializeComparison(node);
43
+ const parts = node.values.map((child)=>serializeNode(child, node.operator)).filter((part)=>part !== '');
44
+ if (parts.length === 0) return '';
45
+ const text = parts.join(separatorFor(node.operator));
46
+ const needsParentheses = parts.length > 1 && parent !== undefined && parent !== node.operator;
47
+ return needsParentheses ? `(${text})` : text;
48
+ }
49
+ /**
50
+ * Serializes an {@link EntityLoadRequest}'s `filtering` into an RSQL
51
+ * expression. Every top-level entry is joined with `;` (and), mirroring how
52
+ * `translateFiltering` combines them with `$and` on the Mongo side.
53
+ *
54
+ * An absent, empty, or wholly-empty filtering yields `''`, which callers omit
55
+ * from the URL entirely rather than sending an empty parameter.
56
+ */ export function serializeRsql(filtering) {
57
+ if (!filtering || filtering.length === 0) return '';
58
+ const parts = [];
59
+ for (const entry of filtering){
60
+ const nodes = Array.isArray(entry) ? entry : [
61
+ entry
62
+ ];
63
+ for (const node of nodes){
64
+ const text = serializeNode(node, 'and');
65
+ if (text !== '') parts.push(text);
66
+ }
67
+ }
68
+ return parts.join(RSQL_AND);
69
+ }
70
+
71
+ //# sourceMappingURL=serialize-rsql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/rsql/serialize-rsql.ts"],"sourcesContent":["import type { Entity } from '../types/Entity.js';\nimport type {\n EntityFilter,\n EntityFiltering,\n FilterGroup,\n LogicOperator,\n} from '../types/EntityFiltering.js';\nimport {\n RSQL_AND,\n RSQL_OR,\n RSQL_TOKENS,\n rsqlArity,\n type RsqlOperator,\n} from './rsql-operators.js';\nimport { encodeRsqlValue } from './rsql-values.js';\n\n/**\n * A group carries `values` + a logic operator and, unlike the array filter, has\n * no `property`. Same discriminator the Mongo `filter-translator` uses — the\n * two must agree on what counts as a group or a filter would translate one way\n * and serialize another.\n */\nexport function isFilterGroup<TEntity extends Entity>(\n node: EntityFilter<TEntity> | FilterGroup<TEntity>,\n): node is FilterGroup<TEntity> {\n return (\n !('property' in node) && (node.operator === 'and' || node.operator === 'or')\n );\n}\n\nconst separatorFor = (operator: LogicOperator) =>\n operator === 'or' ? RSQL_OR : RSQL_AND;\n\n/** `isNull`/`isNotNull` share one token, told apart by their boolean argument. */\nconst nullArgument = (operator: RsqlOperator) =>\n operator === 'isNull' ? 'true' : 'false';\n\nfunction serializeComparison<TEntity extends Entity>(\n filter: EntityFilter<TEntity>,\n): string {\n const operator = filter.operator as RsqlOperator;\n const property = String(filter.property);\n const token = RSQL_TOKENS[operator];\n\n switch (rsqlArity(operator)) {\n case 'none':\n return `${property}${token}${nullArgument(operator)}`;\n case 'list': {\n const { values } = filter as { values: unknown[] };\n return `${property}${token}(${values.map(encodeRsqlValue).join(',')})`;\n }\n case 'range': {\n const { start, end } = filter as { start: unknown; end: unknown };\n return `${property}${token}(${encodeRsqlValue(start)},${encodeRsqlValue(end)})`;\n }\n default: {\n const { value } = filter as { value: unknown };\n return `${property}${token}${encodeRsqlValue(value)}`;\n }\n }\n}\n\n/**\n * Serializes one node. `parent` is the logic operator this node's text will sit\n * inside: a group only needs parentheses when its own operator differs, since\n * `;` and `,` already read left-to-right within one operator.\n */\nfunction serializeNode<TEntity extends Entity>(\n node: EntityFilter<TEntity> | FilterGroup<TEntity>,\n parent?: LogicOperator,\n): string {\n if (!isFilterGroup(node)) return serializeComparison(node);\n\n const parts = node.values\n .map(child => serializeNode(child, node.operator))\n .filter(part => part !== '');\n\n if (parts.length === 0) return '';\n\n const text = parts.join(separatorFor(node.operator));\n const needsParentheses =\n parts.length > 1 && parent !== undefined && parent !== node.operator;\n\n return needsParentheses ? `(${text})` : text;\n}\n\n/**\n * Serializes an {@link EntityLoadRequest}'s `filtering` into an RSQL\n * expression. Every top-level entry is joined with `;` (and), mirroring how\n * `translateFiltering` combines them with `$and` on the Mongo side.\n *\n * An absent, empty, or wholly-empty filtering yields `''`, which callers omit\n * from the URL entirely rather than sending an empty parameter.\n */\nexport function serializeRsql<TEntity extends Entity>(\n filtering?: EntityFiltering<TEntity>[],\n): string {\n if (!filtering || filtering.length === 0) return '';\n\n const parts: string[] = [];\n for (const entry of filtering) {\n const nodes = Array.isArray(entry) ? entry : [entry];\n for (const node of nodes) {\n const text = serializeNode(node, 'and');\n if (text !== '') parts.push(text);\n }\n }\n\n return parts.join(RSQL_AND);\n}\n"],"names":["RSQL_AND","RSQL_OR","RSQL_TOKENS","rsqlArity","encodeRsqlValue","isFilterGroup","node","operator","separatorFor","nullArgument","serializeComparison","filter","property","String","token","values","map","join","start","end","value","serializeNode","parent","parts","child","part","length","text","needsParentheses","undefined","serializeRsql","filtering","entry","nodes","Array","isArray","push"],"mappings":"AAOA,SACEA,QAAQ,EACRC,OAAO,EACPC,WAAW,EACXC,SAAS,QAEJ,sBAAsB;AAC7B,SAASC,eAAe,QAAQ,mBAAmB;AAEnD;;;;;CAKC,GACD,OAAO,SAASC,cACdC,IAAkD;IAElD,OACE,CAAE,CAAA,cAAcA,IAAG,KAAOA,CAAAA,KAAKC,QAAQ,KAAK,SAASD,KAAKC,QAAQ,KAAK,IAAG;AAE9E;AAEA,MAAMC,eAAe,CAACD,WACpBA,aAAa,OAAON,UAAUD;AAEhC,gFAAgF,GAChF,MAAMS,eAAe,CAACF,WACpBA,aAAa,WAAW,SAAS;AAEnC,SAASG,oBACPC,MAA6B;IAE7B,MAAMJ,WAAWI,OAAOJ,QAAQ;IAChC,MAAMK,WAAWC,OAAOF,OAAOC,QAAQ;IACvC,MAAME,QAAQZ,WAAW,CAACK,SAAS;IAEnC,OAAQJ,UAAUI;QAChB,KAAK;YACH,OAAO,GAAGK,WAAWE,QAAQL,aAAaF,WAAW;QACvD,KAAK;YAAQ;gBACX,MAAM,EAAEQ,MAAM,EAAE,GAAGJ;gBACnB,OAAO,GAAGC,WAAWE,MAAM,CAAC,EAAEC,OAAOC,GAAG,CAACZ,iBAAiBa,IAAI,CAAC,KAAK,CAAC,CAAC;YACxE;QACA,KAAK;YAAS;gBACZ,MAAM,EAAEC,KAAK,EAAEC,GAAG,EAAE,GAAGR;gBACvB,OAAO,GAAGC,WAAWE,MAAM,CAAC,EAAEV,gBAAgBc,OAAO,CAAC,EAAEd,gBAAgBe,KAAK,CAAC,CAAC;YACjF;QACA;YAAS;gBACP,MAAM,EAAEC,KAAK,EAAE,GAAGT;gBAClB,OAAO,GAAGC,WAAWE,QAAQV,gBAAgBgB,QAAQ;YACvD;IACF;AACF;AAEA;;;;CAIC,GACD,SAASC,cACPf,IAAkD,EAClDgB,MAAsB;IAEtB,IAAI,CAACjB,cAAcC,OAAO,OAAOI,oBAAoBJ;IAErD,MAAMiB,QAAQjB,KAAKS,MAAM,CACtBC,GAAG,CAACQ,CAAAA,QAASH,cAAcG,OAAOlB,KAAKC,QAAQ,GAC/CI,MAAM,CAACc,CAAAA,OAAQA,SAAS;IAE3B,IAAIF,MAAMG,MAAM,KAAK,GAAG,OAAO;IAE/B,MAAMC,OAAOJ,MAAMN,IAAI,CAACT,aAAaF,KAAKC,QAAQ;IAClD,MAAMqB,mBACJL,MAAMG,MAAM,GAAG,KAAKJ,WAAWO,aAAaP,WAAWhB,KAAKC,QAAQ;IAEtE,OAAOqB,mBAAmB,CAAC,CAAC,EAAED,KAAK,CAAC,CAAC,GAAGA;AAC1C;AAEA;;;;;;;CAOC,GACD,OAAO,SAASG,cACdC,SAAsC;IAEtC,IAAI,CAACA,aAAaA,UAAUL,MAAM,KAAK,GAAG,OAAO;IAEjD,MAAMH,QAAkB,EAAE;IAC1B,KAAK,MAAMS,SAASD,UAAW;QAC7B,MAAME,QAAQC,MAAMC,OAAO,CAACH,SAASA,QAAQ;YAACA;SAAM;QACpD,KAAK,MAAM1B,QAAQ2B,MAAO;YACxB,MAAMN,OAAON,cAAcf,MAAM;YACjC,IAAIqB,SAAS,IAAIJ,MAAMa,IAAI,CAACT;QAC9B;IACF;IAEA,OAAOJ,MAAMN,IAAI,CAACjB;AACpB"}
@@ -0,0 +1,20 @@
1
+ import type { Entity, EntityConstructor } from '../types/Entity.js';
2
+ import type { EntitySorting } from '../types/EntitySorting.js';
3
+ /**
4
+ * Serializes an {@link EntityLoadRequest}'s `sorting` into the `sort`
5
+ * parameter's value. Absent or empty sorting yields `''`, which callers omit
6
+ * from the URL rather than sending empty.
7
+ */
8
+ export declare function serializeSort<TEntity extends Entity>(sorting?: EntitySorting<TEntity>[]): string;
9
+ /**
10
+ * Parses the `sort` parameter into the request's `sorting`, allowlisting every
11
+ * member against the entity's `sortable` metadata for the same reason
12
+ * {@link coerceFiltering} does: an unchecked property name would let a client
13
+ * sort by a member the entity never meant to expose, and an unindexed one is a
14
+ * collection scan.
15
+ *
16
+ * Returns a single-record array — one record whose numeric keys carry the
17
+ * precedence — or `undefined` when there is nothing to sort by.
18
+ */
19
+ export declare function parseSort<TEntity extends Entity>(entityConstructor: EntityConstructor<TEntity>, parameter: string | null | undefined): EntitySorting<TEntity>[] | undefined;
20
+ //# sourceMappingURL=sort-param.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort-param.d.ts","sourceRoot":"","sources":["../../src/rsql/sort-param.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,2BAA2B,CAAC;AA6B/E;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAS,MAAM,EAClD,OAAO,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,GACjC,MAAM,CAMR;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,SAAS,MAAM,EAC9C,iBAAiB,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,SAAS,CAgCtC"}
@@ -0,0 +1,66 @@
1
+ import { EntifixBuildError } from '../base-entities/entifix-error/index.js';
2
+ import { allowedDescriptors } from './coerce-rsql.js';
3
+ /**
4
+ * RSQL standardizes filtering only, so sorting travels in its own `sort`
5
+ * parameter: `+name,-code`. The sign is the direction (`-` descending, `+` or
6
+ * none ascending) and the list position is the precedence — which is exactly
7
+ * what `EntitySorting`'s numeric keys mean, so the two forms map one to one.
8
+ */ const SEPARATOR = ',';
9
+ /** Flattens the sorting records into `[property, direction]` in priority order. */ function orderedEntries(sorting) {
10
+ const entries = [];
11
+ for (const record of sorting){
12
+ for (const priority of Object.keys(record).map(Number).sort((left, right)=>left - right)){
13
+ const entry = record[priority];
14
+ if (entry) entries.push([
15
+ String(entry.property),
16
+ entry.type
17
+ ]);
18
+ }
19
+ }
20
+ return entries;
21
+ }
22
+ /**
23
+ * Serializes an {@link EntityLoadRequest}'s `sorting` into the `sort`
24
+ * parameter's value. Absent or empty sorting yields `''`, which callers omit
25
+ * from the URL rather than sending empty.
26
+ */ export function serializeSort(sorting) {
27
+ if (!sorting || sorting.length === 0) return '';
28
+ return orderedEntries(sorting).map(([property, type])=>`${type === 'desc' ? '-' : '+'}${property}`).join(SEPARATOR);
29
+ }
30
+ /**
31
+ * Parses the `sort` parameter into the request's `sorting`, allowlisting every
32
+ * member against the entity's `sortable` metadata for the same reason
33
+ * {@link coerceFiltering} does: an unchecked property name would let a client
34
+ * sort by a member the entity never meant to expose, and an unindexed one is a
35
+ * collection scan.
36
+ *
37
+ * Returns a single-record array — one record whose numeric keys carry the
38
+ * precedence — or `undefined` when there is nothing to sort by.
39
+ */ export function parseSort(entityConstructor, parameter) {
40
+ const text = parameter == null ? void 0 : parameter.trim();
41
+ if (!text) return undefined;
42
+ const allowed = allowedDescriptors(entityConstructor, (descriptor)=>descriptor.sortable);
43
+ const record = {};
44
+ let priority = 0;
45
+ for (const rawTerm of text.split(SEPARATOR)){
46
+ const term = rawTerm.trim();
47
+ if (term === '') continue;
48
+ const type = term.startsWith('-') ? 'desc' : 'asc';
49
+ const name = term.replace(/^[+-]/, '');
50
+ const descriptor = allowed.get(name);
51
+ if (!descriptor) {
52
+ throw new EntifixBuildError(`"${name}" is not a sortable member`, undefined, {
53
+ property: name
54
+ });
55
+ }
56
+ record[priority++] = {
57
+ property: descriptor.key,
58
+ type
59
+ };
60
+ }
61
+ return priority === 0 ? undefined : [
62
+ record
63
+ ];
64
+ }
65
+
66
+ //# sourceMappingURL=sort-param.js.map