@proseql/core 0.1.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 (342) hide show
  1. package/LICENSE +21 -0
  2. package/dist/errors/crud-errors.d.ts +98 -0
  3. package/dist/errors/crud-errors.d.ts.map +1 -0
  4. package/dist/errors/crud-errors.js +23 -0
  5. package/dist/errors/crud-errors.js.map +1 -0
  6. package/dist/errors/index.d.ts +16 -0
  7. package/dist/errors/index.d.ts.map +1 -0
  8. package/dist/errors/index.js +12 -0
  9. package/dist/errors/index.js.map +1 -0
  10. package/dist/errors/migration-errors.d.ts +22 -0
  11. package/dist/errors/migration-errors.d.ts.map +1 -0
  12. package/dist/errors/migration-errors.js +14 -0
  13. package/dist/errors/migration-errors.js.map +1 -0
  14. package/dist/errors/plugin-errors.d.ts +15 -0
  15. package/dist/errors/plugin-errors.d.ts.map +1 -0
  16. package/dist/errors/plugin-errors.js +11 -0
  17. package/dist/errors/plugin-errors.js.map +1 -0
  18. package/dist/errors/query-errors.d.ts +31 -0
  19. package/dist/errors/query-errors.d.ts.map +1 -0
  20. package/dist/errors/query-errors.js +11 -0
  21. package/dist/errors/query-errors.js.map +1 -0
  22. package/dist/errors/storage-errors.d.ts +30 -0
  23. package/dist/errors/storage-errors.d.ts.map +1 -0
  24. package/dist/errors/storage-errors.js +11 -0
  25. package/dist/errors/storage-errors.js.map +1 -0
  26. package/dist/factories/crud-factory-with-relationships.d.ts +28 -0
  27. package/dist/factories/crud-factory-with-relationships.d.ts.map +1 -0
  28. package/dist/factories/crud-factory-with-relationships.js +8 -0
  29. package/dist/factories/crud-factory-with-relationships.js.map +1 -0
  30. package/dist/factories/crud-factory.d.ts +25 -0
  31. package/dist/factories/crud-factory.d.ts.map +1 -0
  32. package/dist/factories/crud-factory.js +8 -0
  33. package/dist/factories/crud-factory.js.map +1 -0
  34. package/dist/factories/database-effect.d.ts +241 -0
  35. package/dist/factories/database-effect.d.ts.map +1 -0
  36. package/dist/factories/database-effect.js +859 -0
  37. package/dist/factories/database-effect.js.map +1 -0
  38. package/dist/hooks/hook-runner.d.ts +60 -0
  39. package/dist/hooks/hook-runner.d.ts.map +1 -0
  40. package/dist/hooks/hook-runner.js +107 -0
  41. package/dist/hooks/hook-runner.js.map +1 -0
  42. package/dist/index.d.ts +84 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +110 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/indexes/index-lookup.d.ts +33 -0
  47. package/dist/indexes/index-lookup.d.ts.map +1 -0
  48. package/dist/indexes/index-lookup.js +180 -0
  49. package/dist/indexes/index-lookup.js.map +1 -0
  50. package/dist/indexes/index-manager.d.ts +118 -0
  51. package/dist/indexes/index-manager.d.ts.map +1 -0
  52. package/dist/indexes/index-manager.js +345 -0
  53. package/dist/indexes/index-manager.js.map +1 -0
  54. package/dist/indexes/search-index.d.ts +179 -0
  55. package/dist/indexes/search-index.d.ts.map +1 -0
  56. package/dist/indexes/search-index.js +405 -0
  57. package/dist/indexes/search-index.js.map +1 -0
  58. package/dist/migrations/migration-runner.d.ts +70 -0
  59. package/dist/migrations/migration-runner.d.ts.map +1 -0
  60. package/dist/migrations/migration-runner.js +271 -0
  61. package/dist/migrations/migration-runner.js.map +1 -0
  62. package/dist/migrations/migration-types.d.ts +63 -0
  63. package/dist/migrations/migration-types.d.ts.map +1 -0
  64. package/dist/migrations/migration-types.js +5 -0
  65. package/dist/migrations/migration-types.js.map +1 -0
  66. package/dist/operations/crud/create-with-relationships.d.ts +44 -0
  67. package/dist/operations/crud/create-with-relationships.d.ts.map +1 -0
  68. package/dist/operations/crud/create-with-relationships.js +483 -0
  69. package/dist/operations/crud/create-with-relationships.js.map +1 -0
  70. package/dist/operations/crud/create.d.ts +48 -0
  71. package/dist/operations/crud/create.d.ts.map +1 -0
  72. package/dist/operations/crud/create.js +333 -0
  73. package/dist/operations/crud/create.js.map +1 -0
  74. package/dist/operations/crud/delete-with-relationships.d.ts +63 -0
  75. package/dist/operations/crud/delete-with-relationships.d.ts.map +1 -0
  76. package/dist/operations/crud/delete-with-relationships.js +395 -0
  77. package/dist/operations/crud/delete-with-relationships.js.map +1 -0
  78. package/dist/operations/crud/delete.d.ts +58 -0
  79. package/dist/operations/crud/delete.d.ts.map +1 -0
  80. package/dist/operations/crud/delete.js +267 -0
  81. package/dist/operations/crud/delete.js.map +1 -0
  82. package/dist/operations/crud/unique-check.d.ts +114 -0
  83. package/dist/operations/crud/unique-check.d.ts.map +1 -0
  84. package/dist/operations/crud/unique-check.js +383 -0
  85. package/dist/operations/crud/unique-check.js.map +1 -0
  86. package/dist/operations/crud/update-with-relationships.d.ts +45 -0
  87. package/dist/operations/crud/update-with-relationships.d.ts.map +1 -0
  88. package/dist/operations/crud/update-with-relationships.js +516 -0
  89. package/dist/operations/crud/update-with-relationships.js.map +1 -0
  90. package/dist/operations/crud/update.d.ts +91 -0
  91. package/dist/operations/crud/update.d.ts.map +1 -0
  92. package/dist/operations/crud/update.js +505 -0
  93. package/dist/operations/crud/update.js.map +1 -0
  94. package/dist/operations/crud/upsert.d.ts +52 -0
  95. package/dist/operations/crud/upsert.d.ts.map +1 -0
  96. package/dist/operations/crud/upsert.js +386 -0
  97. package/dist/operations/crud/upsert.js.map +1 -0
  98. package/dist/operations/query/aggregate.d.ts +30 -0
  99. package/dist/operations/query/aggregate.d.ts.map +1 -0
  100. package/dist/operations/query/aggregate.js +227 -0
  101. package/dist/operations/query/aggregate.js.map +1 -0
  102. package/dist/operations/query/cursor-stream.d.ts +18 -0
  103. package/dist/operations/query/cursor-stream.d.ts.map +1 -0
  104. package/dist/operations/query/cursor-stream.js +199 -0
  105. package/dist/operations/query/cursor-stream.js.map +1 -0
  106. package/dist/operations/query/filter-stream.d.ts +12 -0
  107. package/dist/operations/query/filter-stream.d.ts.map +1 -0
  108. package/dist/operations/query/filter-stream.js +167 -0
  109. package/dist/operations/query/filter-stream.js.map +1 -0
  110. package/dist/operations/query/filter.d.ts +13 -0
  111. package/dist/operations/query/filter.d.ts.map +1 -0
  112. package/dist/operations/query/filter.js +267 -0
  113. package/dist/operations/query/filter.js.map +1 -0
  114. package/dist/operations/query/paginate-stream.d.ts +11 -0
  115. package/dist/operations/query/paginate-stream.d.ts.map +1 -0
  116. package/dist/operations/query/paginate-stream.js +22 -0
  117. package/dist/operations/query/paginate-stream.js.map +1 -0
  118. package/dist/operations/query/query-helpers.d.ts +14 -0
  119. package/dist/operations/query/query-helpers.d.ts.map +1 -0
  120. package/dist/operations/query/query-helpers.js +22 -0
  121. package/dist/operations/query/query-helpers.js.map +1 -0
  122. package/dist/operations/query/resolve-computed.d.ts +142 -0
  123. package/dist/operations/query/resolve-computed.d.ts.map +1 -0
  124. package/dist/operations/query/resolve-computed.js +197 -0
  125. package/dist/operations/query/resolve-computed.js.map +1 -0
  126. package/dist/operations/query/search.d.ts +110 -0
  127. package/dist/operations/query/search.d.ts.map +1 -0
  128. package/dist/operations/query/search.js +188 -0
  129. package/dist/operations/query/search.js.map +1 -0
  130. package/dist/operations/query/select-stream.d.ts +27 -0
  131. package/dist/operations/query/select-stream.d.ts.map +1 -0
  132. package/dist/operations/query/select-stream.js +88 -0
  133. package/dist/operations/query/select-stream.js.map +1 -0
  134. package/dist/operations/query/select.d.ts +54 -0
  135. package/dist/operations/query/select.d.ts.map +1 -0
  136. package/dist/operations/query/select.js +159 -0
  137. package/dist/operations/query/select.js.map +1 -0
  138. package/dist/operations/query/sort-stream.d.ts +46 -0
  139. package/dist/operations/query/sort-stream.d.ts.map +1 -0
  140. package/dist/operations/query/sort-stream.js +158 -0
  141. package/dist/operations/query/sort-stream.js.map +1 -0
  142. package/dist/operations/query/sort.d.ts +9 -0
  143. package/dist/operations/query/sort.d.ts.map +1 -0
  144. package/dist/operations/query/sort.js +58 -0
  145. package/dist/operations/query/sort.js.map +1 -0
  146. package/dist/operations/relationships/populate-stream.d.ts +29 -0
  147. package/dist/operations/relationships/populate-stream.d.ts.map +1 -0
  148. package/dist/operations/relationships/populate-stream.js +159 -0
  149. package/dist/operations/relationships/populate-stream.js.map +1 -0
  150. package/dist/operations/relationships/populate.d.ts +15 -0
  151. package/dist/operations/relationships/populate.d.ts.map +1 -0
  152. package/dist/operations/relationships/populate.js +228 -0
  153. package/dist/operations/relationships/populate.js.map +1 -0
  154. package/dist/plugins/plugin-hooks.d.ts +25 -0
  155. package/dist/plugins/plugin-hooks.d.ts.map +1 -0
  156. package/dist/plugins/plugin-hooks.js +64 -0
  157. package/dist/plugins/plugin-hooks.js.map +1 -0
  158. package/dist/plugins/plugin-registry.d.ts +26 -0
  159. package/dist/plugins/plugin-registry.d.ts.map +1 -0
  160. package/dist/plugins/plugin-registry.js +150 -0
  161. package/dist/plugins/plugin-registry.js.map +1 -0
  162. package/dist/plugins/plugin-types.d.ts +95 -0
  163. package/dist/plugins/plugin-types.d.ts.map +1 -0
  164. package/dist/plugins/plugin-types.js +6 -0
  165. package/dist/plugins/plugin-types.js.map +1 -0
  166. package/dist/plugins/plugin-validation.d.ts +49 -0
  167. package/dist/plugins/plugin-validation.d.ts.map +1 -0
  168. package/dist/plugins/plugin-validation.js +295 -0
  169. package/dist/plugins/plugin-validation.js.map +1 -0
  170. package/dist/reactive/change-event.d.ts +44 -0
  171. package/dist/reactive/change-event.d.ts.map +1 -0
  172. package/dist/reactive/change-event.js +49 -0
  173. package/dist/reactive/change-event.js.map +1 -0
  174. package/dist/reactive/change-pubsub.d.ts +32 -0
  175. package/dist/reactive/change-pubsub.d.ts.map +1 -0
  176. package/dist/reactive/change-pubsub.js +31 -0
  177. package/dist/reactive/change-pubsub.js.map +1 -0
  178. package/dist/reactive/evaluate-query.d.ts +62 -0
  179. package/dist/reactive/evaluate-query.d.ts.map +1 -0
  180. package/dist/reactive/evaluate-query.js +57 -0
  181. package/dist/reactive/evaluate-query.js.map +1 -0
  182. package/dist/reactive/watch-by-id.d.ts +53 -0
  183. package/dist/reactive/watch-by-id.d.ts.map +1 -0
  184. package/dist/reactive/watch-by-id.js +55 -0
  185. package/dist/reactive/watch-by-id.js.map +1 -0
  186. package/dist/reactive/watch.d.ts +78 -0
  187. package/dist/reactive/watch.d.ts.map +1 -0
  188. package/dist/reactive/watch.js +133 -0
  189. package/dist/reactive/watch.js.map +1 -0
  190. package/dist/serializers/codecs/hjson.d.ts +33 -0
  191. package/dist/serializers/codecs/hjson.d.ts.map +1 -0
  192. package/dist/serializers/codecs/hjson.js +40 -0
  193. package/dist/serializers/codecs/hjson.js.map +1 -0
  194. package/dist/serializers/codecs/json.d.ts +22 -0
  195. package/dist/serializers/codecs/json.d.ts.map +1 -0
  196. package/dist/serializers/codecs/json.js +28 -0
  197. package/dist/serializers/codecs/json.js.map +1 -0
  198. package/dist/serializers/codecs/json5.d.ts +26 -0
  199. package/dist/serializers/codecs/json5.d.ts.map +1 -0
  200. package/dist/serializers/codecs/json5.js +33 -0
  201. package/dist/serializers/codecs/json5.js.map +1 -0
  202. package/dist/serializers/codecs/jsonc.d.ts +29 -0
  203. package/dist/serializers/codecs/jsonc.d.ts.map +1 -0
  204. package/dist/serializers/codecs/jsonc.js +38 -0
  205. package/dist/serializers/codecs/jsonc.js.map +1 -0
  206. package/dist/serializers/codecs/jsonl.d.ts +17 -0
  207. package/dist/serializers/codecs/jsonl.d.ts.map +1 -0
  208. package/dist/serializers/codecs/jsonl.js +31 -0
  209. package/dist/serializers/codecs/jsonl.js.map +1 -0
  210. package/dist/serializers/codecs/prose.d.ts +419 -0
  211. package/dist/serializers/codecs/prose.d.ts.map +1 -0
  212. package/dist/serializers/codecs/prose.js +1060 -0
  213. package/dist/serializers/codecs/prose.js.map +1 -0
  214. package/dist/serializers/codecs/toml.d.ts +23 -0
  215. package/dist/serializers/codecs/toml.d.ts.map +1 -0
  216. package/dist/serializers/codecs/toml.js +66 -0
  217. package/dist/serializers/codecs/toml.js.map +1 -0
  218. package/dist/serializers/codecs/toon.d.ts +20 -0
  219. package/dist/serializers/codecs/toon.d.ts.map +1 -0
  220. package/dist/serializers/codecs/toon.js +33 -0
  221. package/dist/serializers/codecs/toon.js.map +1 -0
  222. package/dist/serializers/codecs/yaml.d.ts +24 -0
  223. package/dist/serializers/codecs/yaml.d.ts.map +1 -0
  224. package/dist/serializers/codecs/yaml.js +31 -0
  225. package/dist/serializers/codecs/yaml.js.map +1 -0
  226. package/dist/serializers/format-codec.d.ts +53 -0
  227. package/dist/serializers/format-codec.d.ts.map +1 -0
  228. package/dist/serializers/format-codec.js +148 -0
  229. package/dist/serializers/format-codec.js.map +1 -0
  230. package/dist/serializers/presets.d.ts +48 -0
  231. package/dist/serializers/presets.d.ts.map +1 -0
  232. package/dist/serializers/presets.js +72 -0
  233. package/dist/serializers/presets.js.map +1 -0
  234. package/dist/serializers/serializer-service.d.ts +11 -0
  235. package/dist/serializers/serializer-service.d.ts.map +1 -0
  236. package/dist/serializers/serializer-service.js +4 -0
  237. package/dist/serializers/serializer-service.js.map +1 -0
  238. package/dist/state/collection-state.d.ts +19 -0
  239. package/dist/state/collection-state.d.ts.map +1 -0
  240. package/dist/state/collection-state.js +15 -0
  241. package/dist/state/collection-state.js.map +1 -0
  242. package/dist/state/state-operations.d.ts +38 -0
  243. package/dist/state/state-operations.d.ts.map +1 -0
  244. package/dist/state/state-operations.js +65 -0
  245. package/dist/state/state-operations.js.map +1 -0
  246. package/dist/storage/in-memory-adapter-layer.d.ts +16 -0
  247. package/dist/storage/in-memory-adapter-layer.d.ts.map +1 -0
  248. package/dist/storage/in-memory-adapter-layer.js +81 -0
  249. package/dist/storage/in-memory-adapter-layer.js.map +1 -0
  250. package/dist/storage/persistence-effect.d.ts +244 -0
  251. package/dist/storage/persistence-effect.d.ts.map +1 -0
  252. package/dist/storage/persistence-effect.js +551 -0
  253. package/dist/storage/persistence-effect.js.map +1 -0
  254. package/dist/storage/storage-service.d.ts +22 -0
  255. package/dist/storage/storage-service.d.ts.map +1 -0
  256. package/dist/storage/storage-service.js +4 -0
  257. package/dist/storage/storage-service.js.map +1 -0
  258. package/dist/storage/transforms.d.ts +183 -0
  259. package/dist/storage/transforms.d.ts.map +1 -0
  260. package/dist/storage/transforms.js +263 -0
  261. package/dist/storage/transforms.js.map +1 -0
  262. package/dist/transactions/transaction.d.ts +87 -0
  263. package/dist/transactions/transaction.d.ts.map +1 -0
  264. package/dist/transactions/transaction.js +240 -0
  265. package/dist/transactions/transaction.js.map +1 -0
  266. package/dist/types/aggregate-types.d.ts +73 -0
  267. package/dist/types/aggregate-types.d.ts.map +1 -0
  268. package/dist/types/aggregate-types.js +14 -0
  269. package/dist/types/aggregate-types.js.map +1 -0
  270. package/dist/types/computed-types.d.ts +71 -0
  271. package/dist/types/computed-types.d.ts.map +1 -0
  272. package/dist/types/computed-types.js +8 -0
  273. package/dist/types/computed-types.js.map +1 -0
  274. package/dist/types/crud-relationship-types.d.ts +180 -0
  275. package/dist/types/crud-relationship-types.d.ts.map +1 -0
  276. package/dist/types/crud-relationship-types.js +17 -0
  277. package/dist/types/crud-relationship-types.js.map +1 -0
  278. package/dist/types/crud-types.d.ts +343 -0
  279. package/dist/types/crud-types.d.ts.map +1 -0
  280. package/dist/types/crud-types.js +43 -0
  281. package/dist/types/crud-types.js.map +1 -0
  282. package/dist/types/cursor-types.d.ts +52 -0
  283. package/dist/types/cursor-types.d.ts.map +1 -0
  284. package/dist/types/cursor-types.js +2 -0
  285. package/dist/types/cursor-types.js.map +1 -0
  286. package/dist/types/database-config-types.d.ts +196 -0
  287. package/dist/types/database-config-types.d.ts.map +1 -0
  288. package/dist/types/database-config-types.js +11 -0
  289. package/dist/types/database-config-types.js.map +1 -0
  290. package/dist/types/hook-types.d.ts +158 -0
  291. package/dist/types/hook-types.d.ts.map +1 -0
  292. package/dist/types/hook-types.js +6 -0
  293. package/dist/types/hook-types.js.map +1 -0
  294. package/dist/types/index-types.d.ts +42 -0
  295. package/dist/types/index-types.d.ts.map +1 -0
  296. package/dist/types/index-types.js +8 -0
  297. package/dist/types/index-types.js.map +1 -0
  298. package/dist/types/operators.d.ts +5 -0
  299. package/dist/types/operators.d.ts.map +1 -0
  300. package/dist/types/operators.js +297 -0
  301. package/dist/types/operators.js.map +1 -0
  302. package/dist/types/query-overloads.d.ts +54 -0
  303. package/dist/types/query-overloads.d.ts.map +1 -0
  304. package/dist/types/query-overloads.js +3 -0
  305. package/dist/types/query-overloads.js.map +1 -0
  306. package/dist/types/reactive-types.d.ts +75 -0
  307. package/dist/types/reactive-types.d.ts.map +1 -0
  308. package/dist/types/reactive-types.js +7 -0
  309. package/dist/types/reactive-types.js.map +1 -0
  310. package/dist/types/schema-types.d.ts +56 -0
  311. package/dist/types/schema-types.d.ts.map +1 -0
  312. package/dist/types/schema-types.js +8 -0
  313. package/dist/types/schema-types.js.map +1 -0
  314. package/dist/types/search-types.d.ts +82 -0
  315. package/dist/types/search-types.d.ts.map +1 -0
  316. package/dist/types/search-types.js +110 -0
  317. package/dist/types/search-types.js.map +1 -0
  318. package/dist/types/types.d.ts +286 -0
  319. package/dist/types/types.d.ts.map +1 -0
  320. package/dist/types/types.js +2 -0
  321. package/dist/types/types.js.map +1 -0
  322. package/dist/utils/id-generator.d.ts +97 -0
  323. package/dist/utils/id-generator.d.ts.map +1 -0
  324. package/dist/utils/id-generator.js +247 -0
  325. package/dist/utils/id-generator.js.map +1 -0
  326. package/dist/utils/nested-path.d.ts +56 -0
  327. package/dist/utils/nested-path.d.ts.map +1 -0
  328. package/dist/utils/nested-path.js +119 -0
  329. package/dist/utils/nested-path.js.map +1 -0
  330. package/dist/utils/path.d.ts +16 -0
  331. package/dist/utils/path.d.ts.map +1 -0
  332. package/dist/utils/path.js +24 -0
  333. package/dist/utils/path.js.map +1 -0
  334. package/dist/validators/foreign-key.d.ts +49 -0
  335. package/dist/validators/foreign-key.d.ts.map +1 -0
  336. package/dist/validators/foreign-key.js +153 -0
  337. package/dist/validators/foreign-key.js.map +1 -0
  338. package/dist/validators/schema-validator.d.ts +19 -0
  339. package/dist/validators/schema-validator.d.ts.map +1 -0
  340. package/dist/validators/schema-validator.js +34 -0
  341. package/dist/validators/schema-validator.js.map +1 -0
  342. package/package.json +57 -0
@@ -0,0 +1,247 @@
1
+ /**
2
+ * ID generation utility with uniqueness guarantees
3
+ * Provides various ID generation strategies for database entities
4
+ */
5
+ // ============================================================================
6
+ // ID Generation Strategies
7
+ // ============================================================================
8
+ /**
9
+ * Counter for sequential IDs within a process
10
+ * Reset on process restart
11
+ */
12
+ let sequentialCounter = 0;
13
+ /**
14
+ * Generate a timestamp-based ID with microsecond precision
15
+ * Format: timestamp-random-counter
16
+ * Example: "1704067200000-a3f2-0001"
17
+ */
18
+ export function generateTimestampId() {
19
+ const timestamp = Date.now();
20
+ const random = Math.random().toString(36).substring(2, 6);
21
+ const counter = (++sequentialCounter).toString().padStart(4, "0");
22
+ return `${timestamp}-${random}-${counter}`;
23
+ }
24
+ /**
25
+ * Generate a nano ID - URL-safe, short, unique identifier
26
+ * Uses a larger alphabet for better uniqueness in shorter strings
27
+ */
28
+ export function generateNanoId(length = 21) {
29
+ const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
30
+ let id = "";
31
+ // Use crypto for better randomness if available
32
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
33
+ const bytes = new Uint8Array(length);
34
+ crypto.getRandomValues(bytes);
35
+ for (let i = 0; i < length; i++) {
36
+ id += alphabet[bytes[i] % alphabet.length];
37
+ }
38
+ }
39
+ else {
40
+ // Fallback to Math.random
41
+ for (let i = 0; i < length; i++) {
42
+ id += alphabet[Math.floor(Math.random() * alphabet.length)];
43
+ }
44
+ }
45
+ return id;
46
+ }
47
+ /**
48
+ * Generate a UUID v4 compliant identifier
49
+ * Standard format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
50
+ */
51
+ export function generateUUID() {
52
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
53
+ return crypto.randomUUID();
54
+ }
55
+ // Fallback implementation
56
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
57
+ const r = (Math.random() * 16) | 0;
58
+ const v = c === "x" ? r : (r & 0x3) | 0x8;
59
+ return v.toString(16);
60
+ });
61
+ }
62
+ /**
63
+ * Generate a prefixed ID for better organization
64
+ * Format: prefix_id
65
+ * Example: "user_1704067200000-a3f2-0001"
66
+ */
67
+ export function generatePrefixedId(prefix) {
68
+ const id = generateTimestampId();
69
+ return `${prefix}_${id}`;
70
+ }
71
+ /**
72
+ * Generate a ULID (Universally Unique Lexicographically Sortable Identifier)
73
+ * Sortable by creation time, case-insensitive
74
+ */
75
+ export function generateULID() {
76
+ const timestamp = Date.now();
77
+ const timestampChars = encodeTime(timestamp, 10);
78
+ const randomChars = encodeRandom(16);
79
+ return timestampChars + randomChars;
80
+ }
81
+ // ULID helper functions
82
+ const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; // Crockford's Base32
83
+ function encodeTime(timestamp, length) {
84
+ let str = "";
85
+ for (let i = length - 1; i >= 0; i--) {
86
+ const mod = timestamp % ENCODING.length;
87
+ str = ENCODING[mod] + str;
88
+ timestamp = Math.floor(timestamp / ENCODING.length);
89
+ }
90
+ return str;
91
+ }
92
+ function encodeRandom(length) {
93
+ let str = "";
94
+ for (let i = 0; i < length; i++) {
95
+ str += ENCODING[Math.floor(Math.random() * ENCODING.length)];
96
+ }
97
+ return str;
98
+ }
99
+ /**
100
+ * Generate a sortable ID that includes type information
101
+ * Format: type:timestamp:random
102
+ * Example: "user:1704067200000:a3f2"
103
+ */
104
+ export function generateTypedId(type) {
105
+ const timestamp = Date.now();
106
+ const random = generateNanoId(4);
107
+ return `${type}:${timestamp}:${random}`;
108
+ }
109
+ // ============================================================================
110
+ // ID Validation
111
+ // ============================================================================
112
+ /**
113
+ * Check if a string is a valid ID format
114
+ */
115
+ export function isValidId(id) {
116
+ return typeof id === "string" && id.length > 0 && !id.includes("\0");
117
+ }
118
+ /**
119
+ * Check if ID matches expected format
120
+ */
121
+ export function isValidIdFormat(id, format) {
122
+ switch (format) {
123
+ case "uuid":
124
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(id);
125
+ case "ulid":
126
+ return /^[0-9A-Z]{26}$/i.test(id);
127
+ case "timestamp":
128
+ return /^\d{13}-[a-z0-9]{4}-\d{4}$/.test(id);
129
+ case "nano":
130
+ return /^[0-9A-Za-z_-]+$/.test(id);
131
+ default:
132
+ return false;
133
+ }
134
+ }
135
+ /**
136
+ * Default ID generator configuration
137
+ */
138
+ export const defaultIdConfig = {
139
+ strategy: "nano",
140
+ length: 21,
141
+ };
142
+ /**
143
+ * Create an ID generator with specific configuration
144
+ */
145
+ export function createIdGenerator(config = defaultIdConfig) {
146
+ switch (config.strategy) {
147
+ case "timestamp":
148
+ return generateTimestampId;
149
+ case "nano":
150
+ return () => generateNanoId(config.length);
151
+ case "uuid":
152
+ return generateUUID;
153
+ case "ulid":
154
+ return generateULID;
155
+ case "prefixed": {
156
+ if (!config.prefix) {
157
+ throw new Error("Prefix required for prefixed ID strategy");
158
+ }
159
+ const prefix = config.prefix;
160
+ return () => generatePrefixedId(prefix);
161
+ }
162
+ case "typed": {
163
+ if (!config.type) {
164
+ throw new Error("Type required for typed ID strategy");
165
+ }
166
+ const type = config.type;
167
+ return () => generateTypedId(type);
168
+ }
169
+ default:
170
+ throw new Error(`Unknown ID strategy: ${config.strategy}`);
171
+ }
172
+ }
173
+ // ============================================================================
174
+ // Default Export
175
+ // ============================================================================
176
+ /**
177
+ * Default ID generator using nano ID strategy
178
+ */
179
+ export const generateId = createIdGenerator(defaultIdConfig);
180
+ /**
181
+ * Collection-specific ID generators
182
+ * Allows different ID strategies per collection
183
+ */
184
+ export class CollectionIdGenerators {
185
+ generators = new Map();
186
+ defaultGenerator;
187
+ constructor(defaultConfig = defaultIdConfig) {
188
+ this.defaultGenerator = createIdGenerator(defaultConfig);
189
+ }
190
+ /**
191
+ * Register a custom ID generator for a collection
192
+ */
193
+ register(collection, config) {
194
+ this.generators.set(collection, createIdGenerator(config));
195
+ }
196
+ /**
197
+ * Get ID generator for a collection
198
+ */
199
+ getGenerator(collection) {
200
+ return this.generators.get(collection) || this.defaultGenerator;
201
+ }
202
+ /**
203
+ * Generate ID for a collection
204
+ */
205
+ generateFor(collection) {
206
+ return this.getGenerator(collection)();
207
+ }
208
+ }
209
+ // ============================================================================
210
+ // ID Utilities
211
+ // ============================================================================
212
+ /**
213
+ * Extract timestamp from timestamp-based IDs
214
+ */
215
+ export function extractTimestamp(id) {
216
+ // Handle timestamp format
217
+ const timestampMatch = id.match(/^(\d{13})-/);
218
+ if (timestampMatch) {
219
+ return parseInt(timestampMatch[1], 10);
220
+ }
221
+ // Handle typed format
222
+ const typedMatch = id.match(/:(\d{13}):/);
223
+ if (typedMatch) {
224
+ return parseInt(typedMatch[1], 10);
225
+ }
226
+ return null;
227
+ }
228
+ /**
229
+ * Extract type from typed IDs
230
+ */
231
+ export function extractType(id) {
232
+ const match = id.match(/^([^:]+):/);
233
+ return match ? match[1] : null;
234
+ }
235
+ /**
236
+ * Compare IDs for sorting (works with timestamp-based IDs)
237
+ */
238
+ export function compareIds(a, b) {
239
+ const timestampA = extractTimestamp(a);
240
+ const timestampB = extractTimestamp(b);
241
+ if (timestampA !== null && timestampB !== null) {
242
+ return timestampA - timestampB;
243
+ }
244
+ // Fallback to string comparison
245
+ return a.localeCompare(b);
246
+ }
247
+ //# sourceMappingURL=id-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id-generator.js","sourceRoot":"","sources":["../../src/utils/id-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Utilities for resolving and mutating nested object paths using dot notation.
3
+ */
4
+ /**
5
+ * Check if a string is a dot-notation path (contains at least one ".").
6
+ *
7
+ * @param key - The string to check
8
+ * @returns true if the key contains a dot
9
+ */
10
+ export declare function isDotPath(key: string): boolean;
11
+ /**
12
+ * Get a nested value from an object using dot notation.
13
+ * Handles single-segment paths (no ".") as direct property access with no overhead.
14
+ *
15
+ * @param obj - The object to get the value from
16
+ * @param path - The dot-separated path to the value (e.g., "metadata.views")
17
+ * @returns The value at the path, or undefined if not found
18
+ *
19
+ * @example
20
+ * getNestedValue({ a: { b: 1 } }, "a.b") // returns 1
21
+ * getNestedValue({ a: { b: 1 } }, "a") // returns { b: 1 }
22
+ * getNestedValue({ a: { b: 1 } }, "a.c") // returns undefined
23
+ * getNestedValue({ name: "foo" }, "name") // returns "foo" (single-segment, direct access)
24
+ */
25
+ export declare function getNestedValue(obj: Record<string, unknown>, path: string): unknown;
26
+ /**
27
+ * Recursively collect all paths in an object that have string values.
28
+ * Used for auto-discovering searchable fields when no explicit fields are specified.
29
+ *
30
+ * @param obj - The object to traverse
31
+ * @param prefix - The current path prefix (used during recursion)
32
+ * @returns An array of dot-notation paths pointing to string values
33
+ *
34
+ * @example
35
+ * collectStringPaths({ name: "foo", metadata: { description: "bar", count: 5 } })
36
+ * // returns ["name", "metadata.description"]
37
+ */
38
+ export declare function collectStringPaths(obj: Record<string, unknown>, prefix?: string): ReadonlyArray<string>;
39
+ /**
40
+ * Set a nested value on an object using dot notation, returning a new object (immutable).
41
+ * Creates intermediate objects along the path if they don't exist.
42
+ * Handles single-segment paths (no ".") as direct property set with no overhead.
43
+ *
44
+ * @param obj - The source object
45
+ * @param path - The dot-separated path where to set the value (e.g., "metadata.views")
46
+ * @param value - The value to set
47
+ * @returns A new object with the value set at the path
48
+ *
49
+ * @example
50
+ * setNestedValue({ a: { b: 1 } }, "a.b", 2) // returns { a: { b: 2 } }
51
+ * setNestedValue({ a: { b: 1 } }, "a.c", 3) // returns { a: { b: 1, c: 3 } }
52
+ * setNestedValue({}, "a.b.c", 1) // returns { a: { b: { c: 1 } } }
53
+ * setNestedValue({ name: "foo" }, "name", "bar") // returns { name: "bar" } (single-segment)
54
+ */
55
+ export declare function setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>;
56
+ //# sourceMappingURL=nested-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-path.d.ts","sourceRoot":"","sources":["../../src/utils/nested-path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,GACV,OAAO,CAuBT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,MAAM,SAAK,GACT,aAAa,CAAC,MAAM,CAAC,CAmBvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+BzB"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Utilities for resolving and mutating nested object paths using dot notation.
3
+ */
4
+ /**
5
+ * Check if a string is a dot-notation path (contains at least one ".").
6
+ *
7
+ * @param key - The string to check
8
+ * @returns true if the key contains a dot
9
+ */
10
+ export function isDotPath(key) {
11
+ return key.includes(".");
12
+ }
13
+ /**
14
+ * Get a nested value from an object using dot notation.
15
+ * Handles single-segment paths (no ".") as direct property access with no overhead.
16
+ *
17
+ * @param obj - The object to get the value from
18
+ * @param path - The dot-separated path to the value (e.g., "metadata.views")
19
+ * @returns The value at the path, or undefined if not found
20
+ *
21
+ * @example
22
+ * getNestedValue({ a: { b: 1 } }, "a.b") // returns 1
23
+ * getNestedValue({ a: { b: 1 } }, "a") // returns { b: 1 }
24
+ * getNestedValue({ a: { b: 1 } }, "a.c") // returns undefined
25
+ * getNestedValue({ name: "foo" }, "name") // returns "foo" (single-segment, direct access)
26
+ */
27
+ export function getNestedValue(obj, path) {
28
+ // Fast path: single-segment path (no dot) - direct property access
29
+ if (!isDotPath(path)) {
30
+ return obj[path];
31
+ }
32
+ // Multi-segment path: traverse the object
33
+ const parts = path.split(".");
34
+ let current = obj;
35
+ for (const part of parts) {
36
+ if (current === null || current === undefined) {
37
+ return undefined;
38
+ }
39
+ if (typeof current === "object") {
40
+ current = current[part];
41
+ }
42
+ else {
43
+ return undefined;
44
+ }
45
+ }
46
+ return current;
47
+ }
48
+ /**
49
+ * Recursively collect all paths in an object that have string values.
50
+ * Used for auto-discovering searchable fields when no explicit fields are specified.
51
+ *
52
+ * @param obj - The object to traverse
53
+ * @param prefix - The current path prefix (used during recursion)
54
+ * @returns An array of dot-notation paths pointing to string values
55
+ *
56
+ * @example
57
+ * collectStringPaths({ name: "foo", metadata: { description: "bar", count: 5 } })
58
+ * // returns ["name", "metadata.description"]
59
+ */
60
+ export function collectStringPaths(obj, prefix = "") {
61
+ const paths = [];
62
+ for (const [key, value] of Object.entries(obj)) {
63
+ const path = prefix ? `${prefix}.${key}` : key;
64
+ if (typeof value === "string") {
65
+ paths.push(path);
66
+ }
67
+ else if (value !== null &&
68
+ typeof value === "object" &&
69
+ !Array.isArray(value)) {
70
+ // Recurse into nested objects (but not arrays)
71
+ paths.push(...collectStringPaths(value, path));
72
+ }
73
+ }
74
+ return paths;
75
+ }
76
+ /**
77
+ * Set a nested value on an object using dot notation, returning a new object (immutable).
78
+ * Creates intermediate objects along the path if they don't exist.
79
+ * Handles single-segment paths (no ".") as direct property set with no overhead.
80
+ *
81
+ * @param obj - The source object
82
+ * @param path - The dot-separated path where to set the value (e.g., "metadata.views")
83
+ * @param value - The value to set
84
+ * @returns A new object with the value set at the path
85
+ *
86
+ * @example
87
+ * setNestedValue({ a: { b: 1 } }, "a.b", 2) // returns { a: { b: 2 } }
88
+ * setNestedValue({ a: { b: 1 } }, "a.c", 3) // returns { a: { b: 1, c: 3 } }
89
+ * setNestedValue({}, "a.b.c", 1) // returns { a: { b: { c: 1 } } }
90
+ * setNestedValue({ name: "foo" }, "name", "bar") // returns { name: "bar" } (single-segment)
91
+ */
92
+ export function setNestedValue(obj, path, value) {
93
+ // Fast path: single-segment path (no dot) - direct property set
94
+ if (!isDotPath(path)) {
95
+ return { ...obj, [path]: value };
96
+ }
97
+ // Multi-segment path: build the nested structure
98
+ const parts = path.split(".");
99
+ const result = { ...obj };
100
+ let current = result;
101
+ // Navigate/create to the parent of the leaf
102
+ for (let i = 0; i < parts.length - 1; i++) {
103
+ const part = parts[i];
104
+ const existing = current[part];
105
+ // Copy or create the intermediate object
106
+ if (existing !== null && typeof existing === "object") {
107
+ current[part] = { ...existing };
108
+ }
109
+ else {
110
+ current[part] = {};
111
+ }
112
+ current = current[part];
113
+ }
114
+ // Set the leaf value
115
+ const leafKey = parts[parts.length - 1];
116
+ current[leafKey] = value;
117
+ return result;
118
+ }
119
+ //# sourceMappingURL=nested-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-path.js","sourceRoot":"","sources":["../../src/utils/nested-path.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Path utilities for file operations.
3
+ */
4
+ /**
5
+ * Extract the file extension from a file path without the leading dot.
6
+ *
7
+ * @param filePath - The file path to extract extension from
8
+ * @returns The file extension without the dot, or empty string if no extension
9
+ *
10
+ * @example
11
+ * getFileExtension('/path/to/file.json') // returns 'json'
12
+ * getFileExtension('/path/to/file.data.yaml') // returns 'yaml'
13
+ * getFileExtension('/path/to/file') // returns ''
14
+ */
15
+ export declare function getFileExtension(filePath: string): string;
16
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAazD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Path utilities for file operations.
3
+ */
4
+ /**
5
+ * Extract the file extension from a file path without the leading dot.
6
+ *
7
+ * @param filePath - The file path to extract extension from
8
+ * @returns The file extension without the dot, or empty string if no extension
9
+ *
10
+ * @example
11
+ * getFileExtension('/path/to/file.json') // returns 'json'
12
+ * getFileExtension('/path/to/file.data.yaml') // returns 'yaml'
13
+ * getFileExtension('/path/to/file') // returns ''
14
+ */
15
+ export function getFileExtension(filePath) {
16
+ const lastDotIndex = filePath.lastIndexOf(".");
17
+ const lastSlashIndex = Math.max(filePath.lastIndexOf("/"), filePath.lastIndexOf("\\"));
18
+ // If there's no dot, or the dot is before the last slash/backslash (part of directory name)
19
+ if (lastDotIndex === -1 || lastDotIndex <= lastSlashIndex) {
20
+ return "";
21
+ }
22
+ return filePath.slice(lastDotIndex + 1).toLowerCase();
23
+ }
24
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAChD,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAC9B,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,EACzB,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAC1B,CAAC;IAEF,4FAA4F;IAC5F,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,YAAY,IAAI,cAAc,EAAE,CAAC;QAC3D,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Foreign key validation system.
3
+ *
4
+ * Effect-based validators use Ref<ReadonlyMap> for O(1) lookups.
5
+ */
6
+ import { Effect, Ref } from "effect";
7
+ import { ForeignKeyError } from "../errors/crud-errors.js";
8
+ import type { ForeignKeyValidation } from "../types/crud-types.js";
9
+ import type { RelationshipDef } from "../types/types.js";
10
+ type HasId = {
11
+ readonly id: string;
12
+ };
13
+ type RelationshipConfig = {
14
+ readonly type: "ref" | "inverse";
15
+ readonly target?: string;
16
+ readonly foreignKey?: string;
17
+ };
18
+ /**
19
+ * Extract foreign key configurations from relationships
20
+ */
21
+ export declare function extractForeignKeyConfigs(relationships: Record<string, RelationshipDef<unknown, "ref" | "inverse", string>>): ForeignKeyValidation[];
22
+ /**
23
+ * Validate foreign keys for an entity using Ref-based state.
24
+ * Returns Effect that fails with ForeignKeyError if a violation is found.
25
+ *
26
+ * Uses ReadonlyMap for O(1) lookups instead of legacy array scanning.
27
+ */
28
+ export declare const validateForeignKeysEffect: <T extends HasId>(entity: T, collectionName: string, relationships: Record<string, RelationshipConfig>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>) => Effect.Effect<void, ForeignKeyError>;
29
+ /**
30
+ * Check if deleting an entity would violate foreign key constraints.
31
+ * Scans all collections for "ref" relationships targeting this collection
32
+ * whose foreign key field references the entity being deleted.
33
+ *
34
+ * Returns Effect that fails with ForeignKeyError if violations exist.
35
+ */
36
+ export declare const checkDeleteConstraintsEffect: (entityId: string, collectionName: string, allRelationships: Record<string, Record<string, RelationshipConfig>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>) => Effect.Effect<void, ForeignKeyError>;
37
+ /**
38
+ * Check referential integrity for an entire database using Ref-based state.
39
+ * Returns Effect with a list of violations.
40
+ */
41
+ export declare const checkReferentialIntegrityEffect: (allRelationships: Record<string, Record<string, RelationshipConfig>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>) => Effect.Effect<ReadonlyArray<{
42
+ readonly collection: string;
43
+ readonly entityId: string;
44
+ readonly field: string;
45
+ readonly invalidReference: unknown;
46
+ readonly targetCollection: string;
47
+ }>>;
48
+ export {};
49
+ //# sourceMappingURL=foreign-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foreign-key.d.ts","sourceRoot":"","sources":["../../src/validators/foreign-key.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMzD,KAAK,KAAK,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,KAAK,kBAAkB,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAMF;;GAEG;AACH,wBAAgB,wBAAwB,CACvC,aAAa,EAAE,MAAM,CACpB,MAAM,EACN,eAAe,CAAC,OAAO,EAAE,KAAK,GAAG,SAAS,EAAE,MAAM,CAAC,CACnD,GACC,oBAAoB,EAAE,CAoBxB;AAMD;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,KAAK,EACxD,QAAQ,CAAC,EACT,gBAAgB,MAAM,EACtB,eAAe,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACjD,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAC5D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAoDrC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,UAAU,MAAM,EAChB,gBAAgB,MAAM,EACtB,kBAAkB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EACpE,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAC5D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAkCnC,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,+BAA+B,GAC3C,kBAAkB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EACpE,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAC5D,MAAM,CAAC,MAAM,CACf,aAAa,CAAC;IACb,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CAClC,CAAC,CAyDA,CAAC"}