@tier0/sdk-v2 0.0.0-stage → 0.2.1

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 (310) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +7 -0
  3. package/README.md +201 -2
  4. package/dist/cjs/app-identity-contract.generated.d.ts +22 -0
  5. package/dist/cjs/app-identity-contract.generated.js +51 -0
  6. package/dist/cjs/app-identity-contract.generated.js.map +1 -0
  7. package/dist/cjs/capabilities.d.ts +54 -0
  8. package/dist/cjs/capabilities.js +134 -0
  9. package/dist/cjs/capabilities.js.map +1 -0
  10. package/dist/cjs/client.d.ts +604 -0
  11. package/dist/cjs/client.js +35 -0
  12. package/dist/cjs/client.js.map +1 -0
  13. package/dist/cjs/cloud-server.d.ts +31 -0
  14. package/dist/cjs/cloud-server.js +114 -0
  15. package/dist/cjs/cloud-server.js.map +1 -0
  16. package/dist/cjs/cloud-transport.d.ts +67 -0
  17. package/dist/cjs/cloud-transport.js +272 -0
  18. package/dist/cjs/cloud-transport.js.map +1 -0
  19. package/dist/cjs/controls.d.ts +93 -0
  20. package/dist/cjs/controls.js +169 -0
  21. package/dist/cjs/controls.js.map +1 -0
  22. package/dist/cjs/data/bootstrap.d.ts +70 -0
  23. package/dist/cjs/data/bootstrap.js +291 -0
  24. package/dist/cjs/data/bootstrap.js.map +1 -0
  25. package/dist/cjs/data/call.d.ts +33 -0
  26. package/dist/cjs/data/call.js +216 -0
  27. package/dist/cjs/data/call.js.map +1 -0
  28. package/dist/cjs/data/client.d.ts +134 -0
  29. package/dist/cjs/data/client.js +185 -0
  30. package/dist/cjs/data/client.js.map +1 -0
  31. package/dist/cjs/data/collection.d.ts +335 -0
  32. package/dist/cjs/data/collection.js +601 -0
  33. package/dist/cjs/data/collection.js.map +1 -0
  34. package/dist/cjs/data/context.d.ts +12 -0
  35. package/dist/cjs/data/context.js +50 -0
  36. package/dist/cjs/data/context.js.map +1 -0
  37. package/dist/cjs/data/declarations.d.ts +11 -0
  38. package/dist/cjs/data/declarations.js +18 -0
  39. package/dist/cjs/data/declarations.js.map +1 -0
  40. package/dist/cjs/data/define.d.ts +77 -0
  41. package/dist/cjs/data/define.js +31 -0
  42. package/dist/cjs/data/define.js.map +1 -0
  43. package/dist/cjs/data/error.d.ts +78 -0
  44. package/dist/cjs/data/error.js +182 -0
  45. package/dist/cjs/data/error.js.map +1 -0
  46. package/dist/cjs/data/index.d.ts +24 -0
  47. package/dist/cjs/data/index.js +49 -0
  48. package/dist/cjs/data/index.js.map +1 -0
  49. package/dist/cjs/data/schema.d.ts +88 -0
  50. package/dist/cjs/data/schema.js +657 -0
  51. package/dist/cjs/data/schema.js.map +1 -0
  52. package/dist/cjs/data/sort.d.ts +8 -0
  53. package/dist/cjs/data/sort.js +21 -0
  54. package/dist/cjs/data/sort.js.map +1 -0
  55. package/dist/cjs/data/subscribe.d.ts +108 -0
  56. package/dist/cjs/data/subscribe.js +270 -0
  57. package/dist/cjs/data/subscribe.js.map +1 -0
  58. package/dist/cjs/files.d.ts +67 -0
  59. package/dist/cjs/files.js +119 -0
  60. package/dist/cjs/files.js.map +1 -0
  61. package/dist/cjs/framework-scope.d.ts +1 -0
  62. package/dist/cjs/framework-scope.js +14 -0
  63. package/dist/cjs/framework-scope.js.map +1 -0
  64. package/dist/cjs/index.d.ts +14 -0
  65. package/dist/cjs/index.js +33 -0
  66. package/dist/cjs/index.js.map +1 -0
  67. package/dist/cjs/mq/broker.d.ts +65 -0
  68. package/dist/cjs/mq/broker.js +115 -0
  69. package/dist/cjs/mq/broker.js.map +1 -0
  70. package/dist/cjs/mq/client.d.ts +37 -0
  71. package/dist/cjs/mq/client.js +321 -0
  72. package/dist/cjs/mq/client.js.map +1 -0
  73. package/dist/cjs/mq/index.d.ts +5 -0
  74. package/dist/cjs/mq/index.js +11 -0
  75. package/dist/cjs/mq/index.js.map +1 -0
  76. package/dist/cjs/mq/types.d.ts +48 -0
  77. package/dist/cjs/mq/types.js +3 -0
  78. package/dist/cjs/mq/types.js.map +1 -0
  79. package/dist/cjs/openapi/api.generated.d.ts +820 -0
  80. package/dist/cjs/openapi/api.generated.js +607 -0
  81. package/dist/cjs/openapi/api.generated.js.map +1 -0
  82. package/dist/cjs/openapi/client.d.ts +56 -0
  83. package/dist/cjs/openapi/client.js +219 -0
  84. package/dist/cjs/openapi/client.js.map +1 -0
  85. package/dist/cjs/openapi/codecs.generated.d.ts +2234 -0
  86. package/dist/cjs/openapi/codecs.generated.js +6 -0
  87. package/dist/cjs/openapi/codecs.generated.js.map +1 -0
  88. package/dist/cjs/openapi/index.d.ts +5 -0
  89. package/dist/cjs/openapi/index.js +12 -0
  90. package/dist/cjs/openapi/index.js.map +1 -0
  91. package/dist/cjs/openapi/types.generated.d.ts +3227 -0
  92. package/dist/cjs/openapi/types.generated.js +3 -0
  93. package/dist/cjs/openapi/types.generated.js.map +1 -0
  94. package/dist/cjs/package.json +1 -0
  95. package/dist/cjs/react.d.ts +9 -0
  96. package/dist/cjs/react.js +16 -0
  97. package/dist/cjs/react.js.map +1 -0
  98. package/dist/cjs/runtime-context.d.ts +9 -0
  99. package/dist/cjs/runtime-context.js +25 -0
  100. package/dist/cjs/runtime-context.js.map +1 -0
  101. package/dist/cjs/runtime-env.d.ts +1 -0
  102. package/dist/cjs/runtime-env.js +18 -0
  103. package/dist/cjs/runtime-env.js.map +1 -0
  104. package/dist/cjs/source.d.ts +39 -0
  105. package/dist/cjs/source.js +29 -0
  106. package/dist/cjs/source.js.map +1 -0
  107. package/dist/cjs/stream.d.ts +40 -0
  108. package/dist/cjs/stream.js +33 -0
  109. package/dist/cjs/stream.js.map +1 -0
  110. package/dist/cjs/uns-v2/client.d.ts +132 -0
  111. package/dist/cjs/uns-v2/client.js +352 -0
  112. package/dist/cjs/uns-v2/client.js.map +1 -0
  113. package/dist/cjs/uns-v2/codec.d.ts +11 -0
  114. package/dist/cjs/uns-v2/codec.js +290 -0
  115. package/dist/cjs/uns-v2/codec.js.map +1 -0
  116. package/dist/cjs/uns-v2/data-client.d.ts +10 -0
  117. package/dist/cjs/uns-v2/data-client.js +18 -0
  118. package/dist/cjs/uns-v2/data-client.js.map +1 -0
  119. package/dist/cjs/uns-v2/generated.d.ts +18178 -0
  120. package/dist/cjs/uns-v2/generated.js +144 -0
  121. package/dist/cjs/uns-v2/generated.js.map +1 -0
  122. package/dist/cjs/uns-v2/index.d.ts +5 -0
  123. package/dist/cjs/uns-v2/index.js +24 -0
  124. package/dist/cjs/uns-v2/index.js.map +1 -0
  125. package/dist/cjs/uns-v2/sse.d.ts +20 -0
  126. package/dist/cjs/uns-v2/sse.js +65 -0
  127. package/dist/cjs/uns-v2/sse.js.map +1 -0
  128. package/dist/cjs/vue.d.ts +9 -0
  129. package/dist/cjs/vue.js +39 -0
  130. package/dist/cjs/vue.js.map +1 -0
  131. package/dist/esm/app-identity-contract.generated.d.ts +22 -0
  132. package/dist/esm/app-identity-contract.generated.js +48 -0
  133. package/dist/esm/app-identity-contract.generated.js.map +1 -0
  134. package/dist/esm/capabilities.d.ts +54 -0
  135. package/dist/esm/capabilities.js +129 -0
  136. package/dist/esm/capabilities.js.map +1 -0
  137. package/dist/esm/client.d.ts +604 -0
  138. package/dist/esm/client.js +32 -0
  139. package/dist/esm/client.js.map +1 -0
  140. package/dist/esm/cloud-server.d.ts +31 -0
  141. package/dist/esm/cloud-server.js +109 -0
  142. package/dist/esm/cloud-server.js.map +1 -0
  143. package/dist/esm/cloud-transport.d.ts +67 -0
  144. package/dist/esm/cloud-transport.js +267 -0
  145. package/dist/esm/cloud-transport.js.map +1 -0
  146. package/dist/esm/controls.d.ts +93 -0
  147. package/dist/esm/controls.js +163 -0
  148. package/dist/esm/controls.js.map +1 -0
  149. package/dist/esm/data/bootstrap.d.ts +70 -0
  150. package/dist/esm/data/bootstrap.js +286 -0
  151. package/dist/esm/data/bootstrap.js.map +1 -0
  152. package/dist/esm/data/call.d.ts +33 -0
  153. package/dist/esm/data/call.js +211 -0
  154. package/dist/esm/data/call.js.map +1 -0
  155. package/dist/esm/data/client.d.ts +134 -0
  156. package/dist/esm/data/client.js +181 -0
  157. package/dist/esm/data/client.js.map +1 -0
  158. package/dist/esm/data/collection.d.ts +335 -0
  159. package/dist/esm/data/collection.js +594 -0
  160. package/dist/esm/data/collection.js.map +1 -0
  161. package/dist/esm/data/context.d.ts +12 -0
  162. package/dist/esm/data/context.js +44 -0
  163. package/dist/esm/data/context.js.map +1 -0
  164. package/dist/esm/data/declarations.d.ts +11 -0
  165. package/dist/esm/data/declarations.js +10 -0
  166. package/dist/esm/data/declarations.js.map +1 -0
  167. package/dist/esm/data/define.d.ts +77 -0
  168. package/dist/esm/data/define.js +27 -0
  169. package/dist/esm/data/define.js.map +1 -0
  170. package/dist/esm/data/error.d.ts +78 -0
  171. package/dist/esm/data/error.js +176 -0
  172. package/dist/esm/data/error.js.map +1 -0
  173. package/dist/esm/data/index.d.ts +24 -0
  174. package/dist/esm/data/index.js +20 -0
  175. package/dist/esm/data/index.js.map +1 -0
  176. package/dist/esm/data/schema.d.ts +88 -0
  177. package/dist/esm/data/schema.js +646 -0
  178. package/dist/esm/data/schema.js.map +1 -0
  179. package/dist/esm/data/sort.d.ts +8 -0
  180. package/dist/esm/data/sort.js +18 -0
  181. package/dist/esm/data/sort.js.map +1 -0
  182. package/dist/esm/data/subscribe.d.ts +108 -0
  183. package/dist/esm/data/subscribe.js +265 -0
  184. package/dist/esm/data/subscribe.js.map +1 -0
  185. package/dist/esm/files.d.ts +67 -0
  186. package/dist/esm/files.js +113 -0
  187. package/dist/esm/files.js.map +1 -0
  188. package/dist/esm/framework-scope.d.ts +1 -0
  189. package/dist/esm/framework-scope.js +11 -0
  190. package/dist/esm/framework-scope.js.map +1 -0
  191. package/dist/esm/index.d.ts +14 -0
  192. package/dist/esm/index.js +10 -0
  193. package/dist/esm/index.js.map +1 -0
  194. package/dist/esm/mq/broker.d.ts +65 -0
  195. package/dist/esm/mq/broker.js +109 -0
  196. package/dist/esm/mq/broker.js.map +1 -0
  197. package/dist/esm/mq/client.d.ts +37 -0
  198. package/dist/esm/mq/client.js +314 -0
  199. package/dist/esm/mq/client.js.map +1 -0
  200. package/dist/esm/mq/index.d.ts +5 -0
  201. package/dist/esm/mq/index.js +3 -0
  202. package/dist/esm/mq/index.js.map +1 -0
  203. package/dist/esm/mq/types.d.ts +48 -0
  204. package/dist/esm/mq/types.js +2 -0
  205. package/dist/esm/mq/types.js.map +1 -0
  206. package/dist/esm/openapi/api.generated.d.ts +820 -0
  207. package/dist/esm/openapi/api.generated.js +603 -0
  208. package/dist/esm/openapi/api.generated.js.map +1 -0
  209. package/dist/esm/openapi/client.d.ts +56 -0
  210. package/dist/esm/openapi/client.js +210 -0
  211. package/dist/esm/openapi/client.js.map +1 -0
  212. package/dist/esm/openapi/codecs.generated.d.ts +2234 -0
  213. package/dist/esm/openapi/codecs.generated.js +3 -0
  214. package/dist/esm/openapi/codecs.generated.js.map +1 -0
  215. package/dist/esm/openapi/index.d.ts +5 -0
  216. package/dist/esm/openapi/index.js +3 -0
  217. package/dist/esm/openapi/index.js.map +1 -0
  218. package/dist/esm/openapi/types.generated.d.ts +3227 -0
  219. package/dist/esm/openapi/types.generated.js +2 -0
  220. package/dist/esm/openapi/types.generated.js.map +1 -0
  221. package/dist/esm/package.json +1 -0
  222. package/dist/esm/react.d.ts +9 -0
  223. package/dist/esm/react.js +12 -0
  224. package/dist/esm/react.js.map +1 -0
  225. package/dist/esm/runtime-context.d.ts +9 -0
  226. package/dist/esm/runtime-context.js +22 -0
  227. package/dist/esm/runtime-context.js.map +1 -0
  228. package/dist/esm/runtime-env.d.ts +1 -0
  229. package/dist/esm/runtime-env.js +15 -0
  230. package/dist/esm/runtime-env.js.map +1 -0
  231. package/dist/esm/source.d.ts +39 -0
  232. package/dist/esm/source.js +25 -0
  233. package/dist/esm/source.js.map +1 -0
  234. package/dist/esm/stream.d.ts +40 -0
  235. package/dist/esm/stream.js +29 -0
  236. package/dist/esm/stream.js.map +1 -0
  237. package/dist/esm/uns-v2/client.d.ts +132 -0
  238. package/dist/esm/uns-v2/client.js +343 -0
  239. package/dist/esm/uns-v2/client.js.map +1 -0
  240. package/dist/esm/uns-v2/codec.d.ts +11 -0
  241. package/dist/esm/uns-v2/codec.js +284 -0
  242. package/dist/esm/uns-v2/codec.js.map +1 -0
  243. package/dist/esm/uns-v2/data-client.d.ts +10 -0
  244. package/dist/esm/uns-v2/data-client.js +14 -0
  245. package/dist/esm/uns-v2/data-client.js.map +1 -0
  246. package/dist/esm/uns-v2/generated.d.ts +18178 -0
  247. package/dist/esm/uns-v2/generated.js +141 -0
  248. package/dist/esm/uns-v2/generated.js.map +1 -0
  249. package/dist/esm/uns-v2/index.d.ts +5 -0
  250. package/dist/esm/uns-v2/index.js +5 -0
  251. package/dist/esm/uns-v2/index.js.map +1 -0
  252. package/dist/esm/uns-v2/sse.d.ts +20 -0
  253. package/dist/esm/uns-v2/sse.js +60 -0
  254. package/dist/esm/uns-v2/sse.js.map +1 -0
  255. package/dist/esm/vue.d.ts +9 -0
  256. package/dist/esm/vue.js +36 -0
  257. package/dist/esm/vue.js.map +1 -0
  258. package/docs/acceptance-2026-10-22.md +88 -0
  259. package/package.json +243 -4
  260. package/skills/tier0-sdk-v2/SKILL.md +66 -0
  261. package/skills/tier0-sdk-v2/references/integration.md +72 -0
  262. package/skills/tier0-sdk-v2/tier0-sdk-v2-agent/SKILL.md +73 -0
  263. package/skills/tier0-sdk-v2/tier0-sdk-v2-agent/references/results.md +45 -0
  264. package/skills/tier0-sdk-v2/tier0-sdk-v2-controls/SKILL.md +63 -0
  265. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +58 -0
  266. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +70 -0
  267. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +82 -0
  268. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/modeling.md +113 -0
  269. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +168 -0
  270. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/schema-evolution.md +36 -0
  271. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/SKILL.md +85 -0
  272. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/delete.md +22 -0
  273. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/download.md +49 -0
  274. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/multipart.md +42 -0
  275. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/upload.md +27 -0
  276. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/url.md +22 -0
  277. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/SKILL.md +56 -0
  278. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +41 -0
  279. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/platform-members.md +56 -0
  280. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +78 -0
  281. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +69 -0
  282. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/SKILL.md +42 -0
  283. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/get.md +34 -0
  284. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +72 -0
  285. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +38 -0
  286. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +40 -0
  287. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +63 -0
  288. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +47 -0
  289. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +36 -0
  290. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +34 -0
  291. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/state.md +37 -0
  292. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +62 -0
  293. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +43 -0
  294. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +56 -0
  295. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/delete.md +35 -0
  296. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +64 -0
  297. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/lifecycle.md +26 -0
  298. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +35 -0
  299. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/update.md +36 -0
  300. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/SKILL.md +64 -0
  301. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/info.md +23 -0
  302. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/whoami.md +21 -0
  303. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +55 -0
  304. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +56 -0
  305. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/data-workflows.md +69 -0
  306. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +53 -0
  307. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/namespace.md +38 -0
  308. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +34 -0
  309. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/restore.md +39 -0
  310. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/update.md +62 -0
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_BATCH_QUERIES = void 0;
4
+ exports.createDataClient = createDataClient;
5
+ const runtime_env_js_1 = require("../runtime-env.js");
6
+ const bootstrap_js_1 = require("./bootstrap.js");
7
+ const call_js_1 = require("./call.js");
8
+ const collection_js_1 = require("./collection.js");
9
+ const context_js_1 = require("./context.js");
10
+ const define_js_1 = require("./define.js");
11
+ const subscribe_js_1 = require("./subscribe.js");
12
+ const client_js_1 = require("../uns-v2/client.js");
13
+ const error_js_1 = require("./error.js");
14
+ const schema_js_1 = require("./schema.js");
15
+ const sort_js_1 = require("./sort.js");
16
+ /** Contract limit of `records:queryBatch`. */
17
+ exports.MAX_BATCH_QUERIES = 20;
18
+ const QUERY_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
19
+ function createDataClient(config) {
20
+ const { call, openStream } = (0, call_js_1.createDataTransport)(config);
21
+ const environment = config.environment ?? ((0, runtime_env_js_1.getEnvVar)('NODE_ENV') === 'production' ? 'deployed' : 'preview');
22
+ const declared = [...config.collections];
23
+ if (declared.length > define_js_1.MAX_COLLECTIONS) {
24
+ throw new Error(`An App declares at most ${define_js_1.MAX_COLLECTIONS} collections; got ${declared.length}.`);
25
+ }
26
+ const seen = new Set();
27
+ for (const definition of declared) {
28
+ const key = definition.alias.toLowerCase();
29
+ if (seen.has(key))
30
+ throw new Error(`Collection alias "${definition.alias}" is declared twice (aliases are case-insensitive).`);
31
+ seen.add(key);
32
+ }
33
+ const bootstrap = (0, bootstrap_js_1.createBootstrap)({ call, collections: declared, environment, logger: config.logger ?? console });
34
+ const runtime = {
35
+ call,
36
+ resolve: (target) => bootstrap.resolve(lookup(target)),
37
+ recover: bootstrap.recover,
38
+ subject: context_js_1.currentDataSubject,
39
+ signal: context_js_1.currentSignal,
40
+ };
41
+ const handles = new Map();
42
+ function lookup(target) {
43
+ if (typeof target === 'string') {
44
+ const found = declared.find((definition) => definition.alias.toLowerCase() === target.toLowerCase());
45
+ if (!found)
46
+ throw new Error(`Collection "${target}" is not declared in this data client's collections.`);
47
+ return found;
48
+ }
49
+ if (!declared.includes(target)) {
50
+ throw new Error(`Collection "${target.alias}" is declared but missing from the \`collections\` passed to createDataClient.`);
51
+ }
52
+ return target;
53
+ }
54
+ function collection(target) {
55
+ const definition = lookup(target);
56
+ let handle = handles.get(definition);
57
+ if (!handle) {
58
+ handle = new collection_js_1.Collection(definition, runtime);
59
+ handles.set(definition, handle);
60
+ }
61
+ return handle;
62
+ }
63
+ async function transact(steps, options = {}) {
64
+ (0, collection_js_1.assertAtomicBatch)('data.transact', steps.length);
65
+ // Steps resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.
66
+ const result = await bootstrap.recover(() => sendTransaction(steps, options));
67
+ const results = (result.results ?? []).map(({ document, ...item }) => ({
68
+ ...item,
69
+ ...(document ? { document: (0, collection_js_1.toDoc)(document) } : {}),
70
+ }));
71
+ const expected = options.dryRun ? 'validated' : 'committed';
72
+ if (result.status !== expected) {
73
+ const failed = results.filter((item) => item.error);
74
+ // A sync transaction should only fail whole; map the rest of the Outcome statuses anyway.
75
+ const execution = result.status === 'unknown' ? 'unknown' : result.status === 'partiallyCommitted' ? 'committed' : 'rolledBack';
76
+ throw new error_js_1.DataError({
77
+ message: `Transaction ${result.status}: ${failed.map((item) => `${item.opId} ${JSON.stringify(item.error)}`).join('; ') || 'no step committed'}`,
78
+ status: execution === 'unknown' ? 503 : 409,
79
+ code: 'TRANSACTION_FAILED',
80
+ execution,
81
+ attempts: 1,
82
+ details: { status: result.status, results },
83
+ });
84
+ }
85
+ return { status: result.status, results };
86
+ }
87
+ async function sendTransaction(steps, options) {
88
+ const items = await Promise.all(steps.map(async ({ collection: target, sort, query, ...step }) => {
89
+ const definition = lookup(target);
90
+ const item = { ...step, collectionId: await bootstrap.resolve(definition) };
91
+ if (sort)
92
+ item.sort = (0, sort_js_1.toSortPairs)(sort);
93
+ if (query)
94
+ item.query = { ...query, ...(query.sort ? { sort: (0, sort_js_1.toSortPairs)(query.sort) } : {}) };
95
+ if (step.data) {
96
+ // Fields bound to earlier results are filled by UNS at commit; everything literal validates now.
97
+ const bound = (step.bindings ?? []).flatMap((binding) => (binding.path.startsWith('data.') ? [binding.path.slice(5).split('.')[0]] : []));
98
+ item.data = (0, schema_js_1.validateStepData)(definition, step.data, bound);
99
+ }
100
+ if (step.update)
101
+ item.update = (0, schema_js_1.validateUpdate)(definition, step.update);
102
+ return item;
103
+ }));
104
+ return call('recordTransactionExecute', {
105
+ items,
106
+ mode: 'sync',
107
+ ...(options.dryRun ? { dryRun: true } : {}),
108
+ ...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),
109
+ }, { dataSubject: (0, context_js_1.currentDataSubject)(), signal: (0, context_js_1.currentSignal)() });
110
+ }
111
+ async function queryBatch(queries, options = {}) {
112
+ const names = Object.keys(queries);
113
+ if (names.length < 1 || names.length > exports.MAX_BATCH_QUERIES) {
114
+ throw new TypeError(`data.queryBatch takes 1–${exports.MAX_BATCH_QUERIES} queries; got ${names.length}.`);
115
+ }
116
+ const bad = names.find((name) => !QUERY_NAME.test(name));
117
+ if (bad !== undefined)
118
+ throw new TypeError(`data.queryBatch query name "${bad}" must match ${QUERY_NAME}.`);
119
+ for (const name of names)
120
+ lookup(queries[name].collection);
121
+ // Items resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.
122
+ const { results } = await bootstrap.recover(async () => {
123
+ const items = await Promise.all(names.map(async (name) => ({
124
+ id: name,
125
+ collectionId: await bootstrap.resolve(queries[name].collection),
126
+ ...(await queries[name].prepare()),
127
+ })));
128
+ return call('recordQueryBatch', { queries: items }, { dataSubject: (0, context_js_1.currentDataSubject)(), signal: (0, context_js_1.currentSignal)() });
129
+ });
130
+ const settled = Object.fromEntries(names.map((name) => {
131
+ const result = results[name];
132
+ if (result?.ok === true)
133
+ return [name, { ok: true, value: queries[name].parse(result.data) }];
134
+ return [name, { ok: false, error: itemError(name, result?.error) }];
135
+ }));
136
+ if (options.settle)
137
+ return settled;
138
+ const failed = names.find((name) => !settled[name].ok);
139
+ if (failed !== undefined)
140
+ throw settled[failed].error;
141
+ return Object.fromEntries(names.map((name) => [name, settled[name].value]));
142
+ }
143
+ const subscribe = (0, subscribe_js_1.createSubscribe)({
144
+ openStream,
145
+ ensure: bootstrap.ensure,
146
+ rebuild: bootstrap.rebuild,
147
+ lookup,
148
+ declared,
149
+ subject: context_js_1.currentDataSubject,
150
+ });
151
+ return {
152
+ collection: collection,
153
+ transact,
154
+ queryBatch: queryBatch,
155
+ subscribe,
156
+ ensure: bootstrap.ensure,
157
+ };
158
+ }
159
+ /** Item errors carry no HTTP status of their own; it follows from the code. */
160
+ const ITEM_STATUS = { FORBIDDEN: 403, NOT_FOUND: 404 };
161
+ /** A queryBatch item's error as a DataError; its `upstreamStatus` is the status its code stands for. */
162
+ function itemError(name, value) {
163
+ const fault = (0, client_js_1.parseUnsV2Fault)(value);
164
+ if (!fault) {
165
+ return new error_js_1.DataError({
166
+ message: `UNS answered query "${name}" of recordQueryBatch with an invalid result.`,
167
+ status: 502,
168
+ code: 'DATA_BAD_RESPONSE',
169
+ upstreamStatus: 200,
170
+ execution: 'rolledBack',
171
+ attempts: 1,
172
+ });
173
+ }
174
+ const error = new client_js_1.UnsV2Error(fault.reason ?? fault.code, {
175
+ ...fault,
176
+ // The items are reads: never an unknown outcome.
177
+ execution: fault.execution === 'unknown' ? 'rolledBack' : fault.execution,
178
+ queryId: fault.queryId ?? name,
179
+ status: ITEM_STATUS[fault.code] ?? 400,
180
+ operation: 'recordQueryBatch',
181
+ data: { queryId: fault.queryId ?? name, details: fault.details ?? [] },
182
+ });
183
+ return (0, error_js_1.toDataError)(error);
184
+ }
185
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/data/client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Data client factory: collection handles, cross-collection transactions and\n * the shared bootstrap. An App builds one client per process from its\n * collection declarations; tests build their own with a mock `fetch`.\n */\nimport type { z } from 'zod';\nimport type { ClientConfig } from '../openapi/client.js';\nimport { getEnvVar } from '../runtime-env.js';\nimport { createBootstrap, type DataEnvironment, type EnsureState, type Logger } from './bootstrap.js';\nimport { createDataTransport } from './call.js';\nimport { assertAtomicBatch, Collection, toDoc, type BatchQuery, type UnsRecord, type WithMeta } from './collection.js';\nimport { currentDataSubject, currentSignal } from './context.js';\nimport { MAX_COLLECTIONS, type CollectionDefinition } from './define.js';\nimport { createSubscribe, type SubscribeOptions, type SubscriptionEvent } from './subscribe.js';\nimport { parseUnsV2Fault, UnsV2Error } from '../uns-v2/client.js';\nimport { DataError, toDataError } from './error.js';\nimport { validateStepData, validateUpdate } from './schema.js';\nimport { toSortPairs, type Filter, type Sort } from './sort.js';\n\nexport type TransactAction =\n | 'record.create'\n | 'record.check'\n | 'record.read'\n | 'record.update'\n | 'record.modify'\n | 'record.replace'\n | 'record.delete'\n | 'record.query';\n\n/** One `recordTransactionExecute` item; `collection` is a declaration or alias instead of a collection ID. */\nexport interface TransactStep {\n opId: string;\n action: TransactAction;\n collection: CollectionDefinition | string;\n id?: string | { ref: string };\n filter?: Filter;\n data?: Record<string, unknown>;\n update?: Record<string, unknown>;\n upsert?: boolean;\n expectedRevision?: number;\n dependsOn?: string[];\n bindings?: { path: string; ref: string; resultPath: string }[];\n selection?: 'exactOne' | 'first';\n sort?: Sort;\n returnDocument?: 'before' | 'after';\n exists?: boolean;\n operations?: Record<string, unknown>[];\n conditions?: Filter[];\n /** `record.query`: rows to bind from; `expectCount` asserts the match count before `limit`. */\n query?: { filter?: Filter; sort?: Sort; limit?: number; expectCount?: { min?: number; max?: number } };\n arrayFilters?: Record<string, unknown>[];\n}\n\nexport interface TransactResultItem {\n opId: string;\n action: string;\n id: string;\n status: string;\n collectionId?: string;\n revision?: number;\n /** Before/after snapshot when requested, as a flat document. */\n document?: WithMeta<Record<string, unknown>>;\n data?: unknown;\n query?: unknown;\n error?: unknown;\n}\n\nexport interface TransactResult {\n status: string;\n results: TransactResultItem[];\n}\n\n/** Named reads for `data.queryBatch`: 1–20 entries, names matching `[A-Za-z0-9_.-]{1,64}`. */\nexport type BatchQueries = Record<string, BatchQuery<unknown>>;\nexport type BatchResults<Q extends BatchQueries> = { [K in keyof Q]: Q[K] extends BatchQuery<infer R> ? R : never };\nexport type SettledBatchResults<Q extends BatchQueries> = {\n [K in keyof Q]: Q[K] extends BatchQuery<infer R> ? { ok: true; value: R } | { ok: false; error: DataError } : never;\n};\n\n/** Contract limit of `records:queryBatch`. */\nexport const MAX_BATCH_QUERIES = 20;\nconst QUERY_NAME = /^[A-Za-z0-9_.-]{1,64}$/;\n\n/** Credentials as for `createClient`; `transportTimeoutMs` (per attempt) defaults to 25 s here, see DEFAULT_DATA_TIMEOUT_MS. */\nexport interface DataClientConfig extends ClientConfig {\n collections: readonly CollectionDefinition[];\n /** Defaults to \"deployed\" when NODE_ENV is production, otherwise \"preview\". */\n environment?: DataEnvironment;\n logger?: Logger;\n}\n\nexport interface DataClient {\n /** Typed handle for a declaration listed in `collections`. */\n collection<C extends CollectionDefinition>(definition: C): Collection<z.output<C['schema']>, z.input<C['schema']>>;\n /** Handle by alias, typed by the caller. */\n collection<T extends object = Record<string, unknown>>(alias: string): Collection<T>;\n /**\n * Atomic multi-record, multi-collection write (`recordTransactionExecute`, sync),\n * at most 200 steps. Steps can depend on each other (`dependsOn`) and bind\n * earlier results (`bindings`). This is not a Mongo session: everything is\n * sent at once.\n */\n transact(steps: readonly TransactStep[], options?: { dryRun?: boolean; idempotencyKey?: string }): Promise<TransactResult>;\n /**\n * Committed record changes of declared collections (all by default), as\n * one async iterable that reconnects and resumes by itself; see\n * `SubscribeOptions`. Events carry identities only; changes in collections\n * with employee data rules arrive as collection-level notices unless\n * `restricted: \"record\"` is asked for. Open it inside a request to watch as\n * that employee, or in `runAsApp` for one App-wide stream a server fans out.\n */\n subscribe(options?: SubscribeOptions): AsyncIterable<SubscriptionEvent>;\n /**\n * Up to 20 reads of declared collections in one request, answered from one\n * snapshot: what a page shows (a list page with its total, counters, a\n * lookup by ID) in one round trip. Build each read with\n * `collection.query.*`; results come back under the same names.\n *\n * A read UNS refuses on its own (invalid filter, no grant) rejects the\n * whole call with its DataError; with `{ settle: true }` every result is\n * `{ ok, value }` or `{ ok: false, error }` instead. A statement timeout or\n * a batch over 2000 rows / 8 MiB always fails the whole call.\n */\n queryBatch<Q extends BatchQueries>(queries: Q): Promise<BatchResults<Q>>;\n queryBatch<Q extends BatchQueries>(queries: Q, options: { settle: true }): Promise<SettledBatchResults<Q>>;\n /** Ensures every declaration now (normally lazy on first access). */\n ensure(): Promise<EnsureState>;\n}\n\nexport function createDataClient(config: DataClientConfig): DataClient {\n const { call, openStream } = createDataTransport(config);\n const environment = config.environment ?? (getEnvVar('NODE_ENV') === 'production' ? 'deployed' : 'preview');\n const declared = [...config.collections];\n if (declared.length > MAX_COLLECTIONS) {\n throw new Error(`An App declares at most ${MAX_COLLECTIONS} collections; got ${declared.length}.`);\n }\n const seen = new Set<string>();\n for (const definition of declared) {\n const key = definition.alias.toLowerCase();\n if (seen.has(key)) throw new Error(`Collection alias \"${definition.alias}\" is declared twice (aliases are case-insensitive).`);\n seen.add(key);\n }\n\n const bootstrap = createBootstrap({ call, collections: declared, environment, logger: config.logger ?? console });\n const runtime = {\n call,\n resolve: (target: CollectionDefinition | string) => bootstrap.resolve(lookup(target)),\n recover: bootstrap.recover,\n subject: currentDataSubject,\n signal: currentSignal,\n };\n const handles = new Map<CollectionDefinition, Collection<object>>();\n\n function lookup(target: CollectionDefinition | string): CollectionDefinition {\n if (typeof target === 'string') {\n const found = declared.find((definition) => definition.alias.toLowerCase() === target.toLowerCase());\n if (!found) throw new Error(`Collection \"${target}\" is not declared in this data client's collections.`);\n return found;\n }\n if (!declared.includes(target)) {\n throw new Error(`Collection \"${target.alias}\" is declared but missing from the \\`collections\\` passed to createDataClient.`);\n }\n return target;\n }\n\n function collection(target: CollectionDefinition | string) {\n const definition = lookup(target);\n let handle = handles.get(definition);\n if (!handle) {\n handle = new Collection<object>(definition, runtime);\n handles.set(definition, handle);\n }\n return handle;\n }\n\n async function transact(\n steps: readonly TransactStep[],\n options: { dryRun?: boolean; idempotencyKey?: string } = {},\n ): Promise<TransactResult> {\n assertAtomicBatch('data.transact', steps.length);\n // Steps resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.\n const result = await bootstrap.recover(() => sendTransaction(steps, options));\n const results = (result.results ?? []).map(({ document, ...item }) => ({\n ...item,\n ...(document ? { document: toDoc<Record<string, unknown>>(document) } : {}),\n }));\n const expected = options.dryRun ? 'validated' : 'committed';\n if (result.status !== expected) {\n const failed = results.filter((item) => item.error);\n // A sync transaction should only fail whole; map the rest of the Outcome statuses anyway.\n const execution = result.status === 'unknown' ? 'unknown' : result.status === 'partiallyCommitted' ? 'committed' : 'rolledBack';\n throw new DataError({\n message: `Transaction ${result.status}: ${failed.map((item) => `${item.opId} ${JSON.stringify(item.error)}`).join('; ') || 'no step committed'}`,\n status: execution === 'unknown' ? 503 : 409,\n code: 'TRANSACTION_FAILED',\n execution,\n attempts: 1,\n details: { status: result.status, results },\n });\n }\n return { status: result.status, results };\n }\n\n async function sendTransaction(steps: readonly TransactStep[], options: { dryRun?: boolean; idempotencyKey?: string }) {\n const items = await Promise.all(\n steps.map(async ({ collection: target, sort, query, ...step }) => {\n const definition = lookup(target);\n const item: Record<string, unknown> = { ...step, collectionId: await bootstrap.resolve(definition) };\n if (sort) item.sort = toSortPairs(sort);\n if (query) item.query = { ...query, ...(query.sort ? { sort: toSortPairs(query.sort) } : {}) };\n if (step.data) {\n // Fields bound to earlier results are filled by UNS at commit; everything literal validates now.\n const bound = (step.bindings ?? []).flatMap((binding) => (binding.path.startsWith('data.') ? [binding.path.slice(5).split('.')[0]] : []));\n item.data = validateStepData(definition, step.data, bound);\n }\n if (step.update) item.update = validateUpdate(definition, step.update);\n return item;\n }),\n );\n return call<{ status: string; results?: (Omit<TransactResultItem, 'document'> & { document?: UnsRecord })[] }>(\n 'recordTransactionExecute',\n {\n items,\n mode: 'sync',\n ...(options.dryRun ? { dryRun: true } : {}),\n ...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),\n },\n { dataSubject: currentDataSubject(), signal: currentSignal() },\n );\n }\n\n async function queryBatch<Q extends BatchQueries>(queries: Q, options: { settle?: boolean } = {}) {\n const names = Object.keys(queries);\n if (names.length < 1 || names.length > MAX_BATCH_QUERIES) {\n throw new TypeError(`data.queryBatch takes 1–${MAX_BATCH_QUERIES} queries; got ${names.length}.`);\n }\n const bad = names.find((name) => !QUERY_NAME.test(name));\n if (bad !== undefined) throw new TypeError(`data.queryBatch query name \"${bad}\" must match ${QUERY_NAME}.`);\n for (const name of names) lookup(queries[name].collection);\n // Items resolve their collection IDs inside the recovered call, so a retry uses fresh IDs.\n const { results } = await bootstrap.recover(async () => {\n const items = await Promise.all(names.map(async (name) => ({\n id: name,\n collectionId: await bootstrap.resolve(queries[name].collection),\n ...(await queries[name].prepare()),\n })));\n return call<{ results: Record<string, { ok: true; data: unknown } | { ok: false; error: unknown }> }>(\n 'recordQueryBatch', { queries: items }, { dataSubject: currentDataSubject(), signal: currentSignal() });\n });\n const settled = Object.fromEntries(names.map((name) => {\n const result = results[name];\n if (result?.ok === true) return [name, { ok: true, value: queries[name].parse(result.data) }];\n return [name, { ok: false, error: itemError(name, result?.error) }];\n })) as Record<string, { ok: true; value: unknown } | { ok: false; error: DataError }>;\n if (options.settle) return settled;\n const failed = names.find((name) => !settled[name].ok);\n if (failed !== undefined) throw (settled[failed] as { error: DataError }).error;\n return Object.fromEntries(names.map((name) => [name, (settled[name] as { value: unknown }).value]));\n }\n\n const subscribe = createSubscribe({\n openStream,\n ensure: bootstrap.ensure,\n rebuild: bootstrap.rebuild,\n lookup,\n declared,\n subject: currentDataSubject,\n });\n\n return {\n collection: collection as DataClient['collection'],\n transact,\n queryBatch: queryBatch as DataClient['queryBatch'],\n subscribe,\n ensure: bootstrap.ensure,\n };\n}\n\n/** Item errors carry no HTTP status of their own; it follows from the code. */\nconst ITEM_STATUS: Record<string, number> = { FORBIDDEN: 403, NOT_FOUND: 404 };\n\n/** A queryBatch item's error as a DataError; its `upstreamStatus` is the status its code stands for. */\nfunction itemError(name: string, value: unknown): DataError {\n const fault = parseUnsV2Fault(value);\n if (!fault) {\n return new DataError({\n message: `UNS answered query \"${name}\" of recordQueryBatch with an invalid result.`,\n status: 502,\n code: 'DATA_BAD_RESPONSE',\n upstreamStatus: 200,\n execution: 'rolledBack',\n attempts: 1,\n });\n }\n const error = new UnsV2Error(fault.reason ?? fault.code, {\n ...fault,\n // The items are reads: never an unknown outcome.\n execution: fault.execution === 'unknown' ? 'rolledBack' : fault.execution,\n queryId: fault.queryId ?? name,\n status: ITEM_STATUS[fault.code] ?? 400,\n operation: 'recordQueryBatch',\n data: { queryId: fault.queryId ?? name, details: fault.details ?? [] },\n });\n return toDataError(error);\n}\n\n"]}
@@ -0,0 +1,335 @@
1
+ import type { DataCall } from './call.js';
2
+ import type { CollectionDefinition, RecordMeta } from './define.js';
3
+ import { type Filter, type Sort, type SortPairs } from './sort.js';
4
+ /** UNS page limit for find / aggregate / distinct. */
5
+ export declare const MAX_PAGE_SIZE = 200;
6
+ /**
7
+ * UNS commits at most 200 items in one synchronous atomic batch
8
+ * (insertMany, bulkWrite, data.transact).
9
+ */
10
+ export declare const MAX_ATOMIC_ITEMS = 200;
11
+ export type WithMeta<T> = T & {
12
+ _id: string;
13
+ _meta: RecordMeta;
14
+ };
15
+ export type Projection = Record<string, 0 | 1 | boolean>;
16
+ export type Update = Record<string, unknown>;
17
+ export interface UnsRecord {
18
+ id: string;
19
+ data: Record<string, unknown>;
20
+ revision: number;
21
+ createdAt: number;
22
+ updatedAt: number;
23
+ }
24
+ /** Position of the next page: an opaque cursor or a 1-based offset page number. */
25
+ type PageToken = string | number;
26
+ interface Page<T> {
27
+ items: T[];
28
+ /** Token of the following page; null when this was the last one. */
29
+ next: PageToken | null;
30
+ }
31
+ /** Runtime services a collection handle needs from its client. */
32
+ export interface CollectionRuntime {
33
+ call: DataCall;
34
+ /** Collection ID of a declaration or declared alias, ensuring all declarations first. */
35
+ resolve(target: CollectionDefinition | string): Promise<string>;
36
+ /** Runs a call, re-ensuring and retrying once when its collection ID went stale (see bootstrap). */
37
+ recover<R>(fn: () => Promise<R>, options?: {
38
+ retry?: boolean;
39
+ }): Promise<R>;
40
+ /** Data subject of the request being served. */
41
+ subject(): string | undefined;
42
+ /** Abort signal of the request being served. */
43
+ signal(): AbortSignal | undefined;
44
+ }
45
+ /** Rejects batches UNS would refuse, before anything is sent. */
46
+ export declare function assertAtomicBatch(operation: string, count: number): void;
47
+ export declare function toDoc<T>(record: UnsRecord): WithMeta<T>;
48
+ /**
49
+ * Async-iterable result set. Pages hold at most 200 items; the page source
50
+ * decides whether the next page is reached by cursor or by offset page number.
51
+ */
52
+ export declare class Cursor<T> implements AsyncIterable<T> {
53
+ private readonly fetchPage;
54
+ private sortSpec?;
55
+ private limitCount?;
56
+ private projection?;
57
+ private started;
58
+ constructor(fetchPage: (state: {
59
+ token: PageToken | null;
60
+ size: number;
61
+ sort?: SortPairs;
62
+ projection?: Projection;
63
+ }) => Promise<Page<T>>, options?: {
64
+ sort?: Sort;
65
+ limit?: number;
66
+ projection?: Projection;
67
+ });
68
+ private assertNotStarted;
69
+ sort(sort: Sort): this;
70
+ /** Total number of documents to return (pages are fetched ≤200 at a time). */
71
+ limit(count: number): this;
72
+ project(projection: Projection): this;
73
+ [Symbol.asyncIterator](): AsyncIterator<T>;
74
+ toArray(): Promise<T[]>;
75
+ }
76
+ export interface FindOptions {
77
+ sort?: Sort;
78
+ limit?: number;
79
+ projection?: Projection;
80
+ }
81
+ export interface FindPageOptions {
82
+ sort?: Sort;
83
+ /** 1-based page number. */
84
+ page?: number;
85
+ /** At most 200. */
86
+ pageSize?: number;
87
+ projection?: Projection;
88
+ /** Count matches up to this many (1–100000); UNS defaults to 10000. */
89
+ maxCount?: number;
90
+ }
91
+ /** A match count UNS stopped at its limit: `capped` means "at least `count`". */
92
+ export interface CappedCount {
93
+ count: number;
94
+ capped: boolean;
95
+ }
96
+ /** UNS reads at most 100 records by ID per request. */
97
+ export declare const MAX_GET_IDS = 100;
98
+ export interface FoundPage<T> {
99
+ items: WithMeta<T>[];
100
+ total: CappedCount;
101
+ page: number;
102
+ pageSize: number;
103
+ }
104
+ export interface ValueCount {
105
+ value: unknown;
106
+ count: number;
107
+ }
108
+ /** One read of `data.queryBatch`, built by `collection.query.*`. */
109
+ export interface BatchQuery<R> {
110
+ readonly collection: CollectionDefinition;
111
+ /** The batch item without `id` and `collectionId`; resolves `$lookup` targets. */
112
+ prepare(): Promise<Record<string, unknown>>;
113
+ /** The item's result as the builder's caller sees it. */
114
+ parse(data: unknown): R;
115
+ }
116
+ export interface CollectionQueries<T> {
117
+ /** First page (≤200, default 20); `maxCount` adds the capped total of all matches. */
118
+ find(filter?: Filter, options?: {
119
+ sort?: Sort;
120
+ limit?: number;
121
+ projection?: Projection;
122
+ maxCount?: number;
123
+ }): BatchQuery<{
124
+ items: WithMeta<T>[];
125
+ hasMore: boolean;
126
+ total?: CappedCount;
127
+ }>;
128
+ /** Like `collection.findPage`. */
129
+ findPage(filter?: Filter, options?: FindPageOptions): BatchQuery<FoundPage<T>>;
130
+ count(filter?: Filter, options?: {
131
+ maxCount?: number;
132
+ }): BatchQuery<CappedCount>;
133
+ /** The 200 most frequent values. */
134
+ countBy(field: string, filter?: Filter): BatchQuery<ValueCount[]>;
135
+ /** The first 200 distinct values. */
136
+ distinct(field: string, filter?: Filter): BatchQuery<unknown[]>;
137
+ /** The first 200 output rows. */
138
+ aggregate<R = Record<string, unknown>>(pipeline: Record<string, unknown>[]): BatchQuery<R[]>;
139
+ /** 1–100 distinct records by ID, as `collection.get`. */
140
+ get(ids: readonly string[], options?: {
141
+ projection?: Projection;
142
+ }): BatchQuery<{
143
+ items: WithMeta<T>[];
144
+ missing: string[];
145
+ }>;
146
+ }
147
+ export interface UpdateOptions {
148
+ upsert?: boolean;
149
+ /** Reject the write with VERSION_CONFLICT unless the record is at this revision. */
150
+ expectedRevision?: number;
151
+ sort?: Sort;
152
+ arrayFilters?: Record<string, unknown>[];
153
+ idempotencyKey?: string;
154
+ }
155
+ export interface FindOneAndOptions extends UpdateOptions {
156
+ returnDocument?: 'before' | 'after';
157
+ projection?: Projection;
158
+ }
159
+ export type BulkOperation = {
160
+ insertOne: {
161
+ document: Record<string, unknown>;
162
+ };
163
+ } | {
164
+ updateOne: {
165
+ filter: Filter;
166
+ update: Update;
167
+ upsert?: boolean;
168
+ sort?: Sort;
169
+ };
170
+ } | {
171
+ replaceOne: {
172
+ filter: Filter;
173
+ replacement: Record<string, unknown>;
174
+ upsert?: boolean;
175
+ sort?: Sort;
176
+ };
177
+ } | {
178
+ deleteOne: {
179
+ filter: Filter;
180
+ sort?: Sort;
181
+ };
182
+ };
183
+ export declare class Collection<T extends object = Record<string, unknown>, TInput extends object = T> {
184
+ readonly definition: CollectionDefinition;
185
+ private readonly runtime;
186
+ constructor(definition: CollectionDefinition, runtime: CollectionRuntime);
187
+ get alias(): string;
188
+ /**
189
+ * One call with stale-ID recovery. A call continuing a cursor or
190
+ * resumeAfter token of the old collection is not retried: the token means
191
+ * nothing to a recreated collection.
192
+ */
193
+ private post;
194
+ private send;
195
+ find(filter?: Filter, options?: FindOptions): Cursor<WithMeta<T>>;
196
+ findOne(filter?: Filter, options?: Omit<FindOptions, 'limit'>): Promise<WithMeta<T> | null>;
197
+ /**
198
+ * Records by ID, in the order asked for (each ID once, at its first
199
+ * position); IDs that do not exist, are deleted or are hidden by employee
200
+ * data rules are listed in `missing` alike. More than 100 IDs are read in
201
+ * chunks of 100 (not one snapshot).
202
+ */
203
+ get(ids: readonly string[], options?: {
204
+ projection?: Projection;
205
+ }): Promise<{
206
+ items: WithMeta<T>[];
207
+ missing: string[];
208
+ }>;
209
+ /**
210
+ * One numbered page plus the total match count, for paged list screens:
211
+ * one `recordAggregatePipeline` offset page whose `count` runs in the same
212
+ * snapshot. Show a capped total as "10000+".
213
+ */
214
+ findPage(filter?: Filter, options?: FindPageOptions): Promise<FoundPage<T>>;
215
+ /**
216
+ * Counts matches up to `maxCount` (1–100000, UNS default 100000). A
217
+ * `capped` result means "at least `count`".
218
+ */
219
+ countDocuments(filter?: Filter, options?: {
220
+ maxCount?: number;
221
+ }): Promise<CappedCount>;
222
+ /**
223
+ * Match counts per value of `field`, largest first: one `$group` pipeline
224
+ * instead of a count per value. Records without the field count under
225
+ * `value: null`.
226
+ */
227
+ countBy(field: string, filter?: Filter): Promise<ValueCount[]>;
228
+ /**
229
+ * Builders for `data.queryBatch`: each describes one read of this
230
+ * collection, run together with the others in one request and one
231
+ * snapshot. Each returns one page (at most 200 rows), unlike the cursor
232
+ * methods; `get` takes at most 100 IDs.
233
+ */
234
+ get query(): CollectionQueries<T>;
235
+ /** Distinct values of a field (every page). */
236
+ distinct(field: string, filter?: Filter): Promise<unknown[]>;
237
+ /**
238
+ * Runs a pipeline (`$match`, `$sort`, `$group`, `$project`, `$set`,
239
+ * `$lookup`, `$unwind`, `$skip`, `$limit`, `$count`). `$sort` accepts
240
+ * `{ field: 1 | -1 }`; `$lookup` takes `from` (a declared collection or
241
+ * alias of this App) instead of a collection ID. Rows are whatever the
242
+ * pipeline outputs, not wrapped records.
243
+ *
244
+ * Pipelines of only `$match` / `$sort` page by cursor; any other stage pages
245
+ * by offset (UNS rejects cursors for transformed results). The `$exists`,
246
+ * `$distinct` and `$frequencies` stages are listed in the UNS schema but not
247
+ * executed by the record pipeline; use `countDocuments`, `distinct` or `$group`.
248
+ */
249
+ aggregate<R = Record<string, unknown>>(pipeline: Record<string, unknown>[]): Cursor<R>;
250
+ private aggregatePage;
251
+ /** Converts Mongo-style `$sort` objects and resolves `$lookup.from`, recursively. */
252
+ private prepareStages;
253
+ insertOne(document: TInput & {
254
+ _id?: string;
255
+ }, options?: {
256
+ idempotencyKey?: string;
257
+ }): Promise<{
258
+ insertedId: string;
259
+ }>;
260
+ /** Inserts up to 200 documents atomically (all or none). */
261
+ insertMany(documents: readonly (TInput & {
262
+ _id?: string;
263
+ })[], options?: {
264
+ idempotencyKey?: string;
265
+ }): Promise<{
266
+ insertedCount: number;
267
+ insertedIds: string[];
268
+ }>;
269
+ updateOne(filter: Filter, update: Update, options?: UpdateOptions): Promise<{
270
+ matchedCount: number;
271
+ modifiedCount: number;
272
+ upsertedId: string | null;
273
+ }>;
274
+ /**
275
+ * Updates every match like Mongo's updateMany: documents commit one by one
276
+ * (not atomically), following `resumeAfter` until every match is processed.
277
+ * A failure after some documents committed keeps its code but is
278
+ * `execution: "committed"`, with the cumulative counts and
279
+ * `details.resumeAfter`; pass that back as `resumeAfter` to continue
280
+ * instead of repeating the call. For all-or-nothing multi-document changes
281
+ * use `data.transact` (≤200 items).
282
+ */
283
+ updateMany(filter: Filter, update: Update, options?: Pick<UpdateOptions, 'arrayFilters'> & {
284
+ resumeAfter?: string;
285
+ }): Promise<{
286
+ matchedCount: number;
287
+ modifiedCount: number;
288
+ }>;
289
+ /** Runs a non-atomic many-write page by page; see updateMany for failures. */
290
+ private writeEach;
291
+ /**
292
+ * Replaces the whole body. Fields written by another App version and not in
293
+ * this declaration are lost — prefer `updateOne` with `$set`.
294
+ */
295
+ replaceOne(filter: Filter, replacement: TInput, options?: Omit<UpdateOptions, 'arrayFilters'>): Promise<{
296
+ matchedCount: number;
297
+ modifiedCount: number;
298
+ upsertedId: string | null;
299
+ }>;
300
+ /** Soft-deletes one record; requires `uns.delete` on the App key. */
301
+ deleteOne(filter: Filter, options?: Pick<UpdateOptions, 'expectedRevision' | 'sort' | 'idempotencyKey'>): Promise<{
302
+ deletedCount: number;
303
+ }>;
304
+ /**
305
+ * Soft-deletes every match, one document at a time like Mongo's deleteMany
306
+ * (not atomic), following `resumeAfter`; requires `uns.delete` on the App
307
+ * key. Failures after committed deletes report them as updateMany does.
308
+ */
309
+ deleteMany(filter: Filter, options?: {
310
+ resumeAfter?: string;
311
+ }): Promise<{
312
+ deletedCount: number;
313
+ }>;
314
+ /**
315
+ * Atomic read-modify-write. A state transition puts the expected state in
316
+ * the filter: `findOneAndUpdate({ _id, status: "DRAFT" }, { $set: { status: "SUBMITTED" } })`
317
+ * returns null when another request moved the record first.
318
+ */
319
+ findOneAndUpdate(filter: Filter, update: Update, options?: FindOneAndOptions): Promise<WithMeta<T> | null>;
320
+ findOneAndReplace(filter: Filter, replacement: TInput, options?: Omit<FindOneAndOptions, 'arrayFilters'>): Promise<WithMeta<T> | null>;
321
+ findOneAndDelete(filter: Filter, options?: Pick<FindOneAndOptions, 'expectedRevision' | 'sort' | 'projection' | 'idempotencyKey'>): Promise<WithMeta<T> | null>;
322
+ /** Up to 200 mixed single-record writes in one atomic call (insertOne / updateOne / replaceOne / deleteOne). */
323
+ bulkWrite(operations: readonly BulkOperation[], options?: {
324
+ idempotencyKey?: string;
325
+ }): Promise<{
326
+ insertedCount: number;
327
+ matchedCount: number;
328
+ modifiedCount: number;
329
+ deletedCount: number;
330
+ upsertedCount: number;
331
+ insertedIds: Record<number, string>;
332
+ upsertedIds: Record<number, string>;
333
+ }>;
334
+ }
335
+ export {};