dotdo 0.0.1 → 0.0.2

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 (727) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +446 -315
  3. package/dist/ai/index.js +19 -0
  4. package/dist/ai/index.js.map +1 -0
  5. package/dist/ai/template-literals.js +852 -0
  6. package/dist/ai/template-literals.js.map +1 -0
  7. package/dist/api/analytics/router.js +601 -0
  8. package/dist/api/analytics/router.js.map +1 -0
  9. package/dist/api/index.js +158 -0
  10. package/dist/api/index.js.map +1 -0
  11. package/dist/api/middleware/auth-federation.js +573 -0
  12. package/dist/api/middleware/auth-federation.js.map +1 -0
  13. package/dist/api/middleware/auth.js +544 -0
  14. package/dist/api/middleware/auth.js.map +1 -0
  15. package/dist/api/middleware/error-handling.js +176 -0
  16. package/dist/api/middleware/error-handling.js.map +1 -0
  17. package/dist/api/middleware/request-id.js +21 -0
  18. package/dist/api/middleware/request-id.js.map +1 -0
  19. package/dist/api/pages.js +1180 -0
  20. package/dist/api/pages.js.map +1 -0
  21. package/dist/api/routes/api.js +612 -0
  22. package/dist/api/routes/api.js.map +1 -0
  23. package/dist/api/routes/browsers.js +471 -0
  24. package/dist/api/routes/browsers.js.map +1 -0
  25. package/dist/api/routes/do.js +188 -0
  26. package/dist/api/routes/do.js.map +1 -0
  27. package/dist/api/routes/mcp.js +459 -0
  28. package/dist/api/routes/mcp.js.map +1 -0
  29. package/dist/api/routes/obs.js +445 -0
  30. package/dist/api/routes/obs.js.map +1 -0
  31. package/dist/api/routes/openapi.js +794 -0
  32. package/dist/api/routes/openapi.js.map +1 -0
  33. package/dist/api/routes/rpc.js +1103 -0
  34. package/dist/api/routes/rpc.js.map +1 -0
  35. package/dist/api/routes/sandboxes.js +389 -0
  36. package/dist/api/routes/sandboxes.js.map +1 -0
  37. package/dist/api/test-do.js +38 -0
  38. package/dist/api/test-do.js.map +1 -0
  39. package/dist/api/types.js +11 -0
  40. package/dist/api/types.js.map +1 -0
  41. package/dist/cli/bin.js +2 -0
  42. package/dist/cli/main.js +52342 -0
  43. package/dist/db/actions.js +212 -0
  44. package/dist/db/actions.js.map +1 -0
  45. package/dist/db/auth.js +506 -0
  46. package/dist/db/auth.js.map +1 -0
  47. package/dist/db/branches.js +65 -0
  48. package/dist/db/branches.js.map +1 -0
  49. package/dist/db/clickhouse.js +1074 -0
  50. package/dist/db/clickhouse.js.map +1 -0
  51. package/dist/db/dlq.js +39 -0
  52. package/dist/db/dlq.js.map +1 -0
  53. package/dist/db/events.js +28 -0
  54. package/dist/db/events.js.map +1 -0
  55. package/dist/db/exec.js +64 -0
  56. package/dist/db/exec.js.map +1 -0
  57. package/dist/db/files.js +85 -0
  58. package/dist/db/files.js.map +1 -0
  59. package/dist/db/flags.js +24 -0
  60. package/dist/db/flags.js.map +1 -0
  61. package/dist/db/git.js +116 -0
  62. package/dist/db/git.js.map +1 -0
  63. package/dist/db/iceberg/inverted-index.js +862 -0
  64. package/dist/db/iceberg/inverted-index.js.map +1 -0
  65. package/dist/db/iceberg/puffin.js +878 -0
  66. package/dist/db/iceberg/puffin.js.map +1 -0
  67. package/dist/db/iceberg/search-manifest.js +422 -0
  68. package/dist/db/iceberg/search-manifest.js.map +1 -0
  69. package/dist/db/iceberg/types.js +8 -0
  70. package/dist/db/iceberg/types.js.map +1 -0
  71. package/dist/db/index.js +121 -0
  72. package/dist/db/index.js.map +1 -0
  73. package/dist/db/integrations.js +368 -0
  74. package/dist/db/integrations.js.map +1 -0
  75. package/dist/db/json-indexes.js +332 -0
  76. package/dist/db/json-indexes.js.map +1 -0
  77. package/dist/db/linked-accounts.js +287 -0
  78. package/dist/db/linked-accounts.js.map +1 -0
  79. package/dist/db/nouns.js +183 -0
  80. package/dist/db/nouns.js.map +1 -0
  81. package/dist/db/objects.js +170 -0
  82. package/dist/db/objects.js.map +1 -0
  83. package/dist/db/primitives/dag-scheduler/index.js +869 -0
  84. package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
  85. package/dist/db/primitives/exactly-once-context.js +237 -0
  86. package/dist/db/primitives/exactly-once-context.js.map +1 -0
  87. package/dist/db/primitives/index.js +62 -0
  88. package/dist/db/primitives/index.js.map +1 -0
  89. package/dist/db/primitives/keyed-router.js +145 -0
  90. package/dist/db/primitives/keyed-router.js.map +1 -0
  91. package/dist/db/primitives/observability.js +162 -0
  92. package/dist/db/primitives/observability.js.map +1 -0
  93. package/dist/db/primitives/schema-evolution.js +643 -0
  94. package/dist/db/primitives/schema-evolution.js.map +1 -0
  95. package/dist/db/primitives/stateful-operator/index.js +770 -0
  96. package/dist/db/primitives/stateful-operator/index.js.map +1 -0
  97. package/dist/db/primitives/temporal-store.js +306 -0
  98. package/dist/db/primitives/temporal-store.js.map +1 -0
  99. package/dist/db/primitives/typed-column-store.js +1229 -0
  100. package/dist/db/primitives/typed-column-store.js.map +1 -0
  101. package/dist/db/primitives/utils/duration.js +162 -0
  102. package/dist/db/primitives/utils/duration.js.map +1 -0
  103. package/dist/db/primitives/utils/murmur3.js +118 -0
  104. package/dist/db/primitives/utils/murmur3.js.map +1 -0
  105. package/dist/db/primitives/watermark-service.js +136 -0
  106. package/dist/db/primitives/watermark-service.js.map +1 -0
  107. package/dist/db/primitives/window-manager.js +764 -0
  108. package/dist/db/primitives/window-manager.js.map +1 -0
  109. package/dist/db/relationships.js +66 -0
  110. package/dist/db/relationships.js.map +1 -0
  111. package/dist/db/schema-minimal.js +61 -0
  112. package/dist/db/schema-minimal.js.map +1 -0
  113. package/dist/db/search.js +28 -0
  114. package/dist/db/search.js.map +1 -0
  115. package/dist/db/stores.js +1665 -0
  116. package/dist/db/stores.js.map +1 -0
  117. package/dist/db/things.js +297 -0
  118. package/dist/db/things.js.map +1 -0
  119. package/dist/db/vault.js +171 -0
  120. package/dist/db/vault.js.map +1 -0
  121. package/dist/db/verbs.js +102 -0
  122. package/dist/db/verbs.js.map +1 -0
  123. package/dist/do/base.js +48 -0
  124. package/dist/do/base.js.map +1 -0
  125. package/dist/do/bash.js +35 -0
  126. package/dist/do/bash.js.map +1 -0
  127. package/dist/do/fs.js +25 -0
  128. package/dist/do/fs.js.map +1 -0
  129. package/dist/do/full.js +61 -0
  130. package/dist/do/full.js.map +1 -0
  131. package/dist/do/git.js +28 -0
  132. package/dist/do/git.js.map +1 -0
  133. package/dist/do/index.js +52 -0
  134. package/dist/do/index.js.map +1 -0
  135. package/dist/do/tiny.js +31 -0
  136. package/dist/do/tiny.js.map +1 -0
  137. package/dist/lib/DOAuth.js +261 -0
  138. package/dist/lib/DOAuth.js.map +1 -0
  139. package/dist/lib/DODispatcher.js +72 -0
  140. package/dist/lib/DODispatcher.js.map +1 -0
  141. package/dist/lib/Modifier.js +189 -0
  142. package/dist/lib/Modifier.js.map +1 -0
  143. package/dist/lib/StateStorage.js +403 -0
  144. package/dist/lib/StateStorage.js.map +1 -0
  145. package/dist/lib/TypeRegistry.js +122 -0
  146. package/dist/lib/TypeRegistry.js.map +1 -0
  147. package/dist/lib/agent/tools/bash.js +336 -0
  148. package/dist/lib/agent/tools/bash.js.map +1 -0
  149. package/dist/lib/agent/tools/edit.js +157 -0
  150. package/dist/lib/agent/tools/edit.js.map +1 -0
  151. package/dist/lib/agent/tools/glob.js +137 -0
  152. package/dist/lib/agent/tools/glob.js.map +1 -0
  153. package/dist/lib/agent/tools/grep.js +315 -0
  154. package/dist/lib/agent/tools/grep.js.map +1 -0
  155. package/dist/lib/agent/tools/index.js +71 -0
  156. package/dist/lib/agent/tools/index.js.map +1 -0
  157. package/dist/lib/agent/tools/read.js +212 -0
  158. package/dist/lib/agent/tools/read.js.map +1 -0
  159. package/dist/lib/agent/tools/types.js +197 -0
  160. package/dist/lib/agent/tools/types.js.map +1 -0
  161. package/dist/lib/agent/tools/write.js +159 -0
  162. package/dist/lib/agent/tools/write.js.map +1 -0
  163. package/dist/lib/ai/gateway.js +247 -0
  164. package/dist/lib/ai/gateway.js.map +1 -0
  165. package/dist/lib/ai/tool-loop-agent.js +591 -0
  166. package/dist/lib/ai/tool-loop-agent.js.map +1 -0
  167. package/dist/lib/auto-wiring.js +439 -0
  168. package/dist/lib/auto-wiring.js.map +1 -0
  169. package/dist/lib/browse/browserbase.js +163 -0
  170. package/dist/lib/browse/browserbase.js.map +1 -0
  171. package/dist/lib/browse/cloudflare.js +144 -0
  172. package/dist/lib/browse/cloudflare.js.map +1 -0
  173. package/dist/lib/browse/index.js +62 -0
  174. package/dist/lib/browse/index.js.map +1 -0
  175. package/dist/lib/browse/types.js +13 -0
  176. package/dist/lib/browse/types.js.map +1 -0
  177. package/dist/lib/cache/index.js +37 -0
  178. package/dist/lib/cache/index.js.map +1 -0
  179. package/dist/lib/cache/visibility.js +638 -0
  180. package/dist/lib/cache/visibility.js.map +1 -0
  181. package/dist/lib/capabilities.js +268 -0
  182. package/dist/lib/capabilities.js.map +1 -0
  183. package/dist/lib/channels/base.js +106 -0
  184. package/dist/lib/channels/base.js.map +1 -0
  185. package/dist/lib/channels/discord.js +94 -0
  186. package/dist/lib/channels/discord.js.map +1 -0
  187. package/dist/lib/channels/email.js +204 -0
  188. package/dist/lib/channels/email.js.map +1 -0
  189. package/dist/lib/channels/index.js +90 -0
  190. package/dist/lib/channels/index.js.map +1 -0
  191. package/dist/lib/channels/mdxui-chat.js +95 -0
  192. package/dist/lib/channels/mdxui-chat.js.map +1 -0
  193. package/dist/lib/channels/slack-blockkit.js +121 -0
  194. package/dist/lib/channels/slack-blockkit.js.map +1 -0
  195. package/dist/lib/channels/types.js +7 -0
  196. package/dist/lib/channels/types.js.map +1 -0
  197. package/dist/lib/cloudflare/ai.js +654 -0
  198. package/dist/lib/cloudflare/ai.js.map +1 -0
  199. package/dist/lib/cloudflare/index.js +88 -0
  200. package/dist/lib/cloudflare/index.js.map +1 -0
  201. package/dist/lib/cloudflare/kv.js +342 -0
  202. package/dist/lib/cloudflare/kv.js.map +1 -0
  203. package/dist/lib/cloudflare/queues.js +434 -0
  204. package/dist/lib/cloudflare/queues.js.map +1 -0
  205. package/dist/lib/cloudflare/r2.js +604 -0
  206. package/dist/lib/cloudflare/r2.js.map +1 -0
  207. package/dist/lib/cloudflare/vectorize.js +494 -0
  208. package/dist/lib/cloudflare/vectorize.js.map +1 -0
  209. package/dist/lib/cloudflare/workflows.js +569 -0
  210. package/dist/lib/cloudflare/workflows.js.map +1 -0
  211. package/dist/lib/colo/caching.js +196 -0
  212. package/dist/lib/colo/caching.js.map +1 -0
  213. package/dist/lib/colo/detection.js +194 -0
  214. package/dist/lib/colo/detection.js.map +1 -0
  215. package/dist/lib/colo/external-data.js +219 -0
  216. package/dist/lib/colo/external-data.js.map +1 -0
  217. package/dist/lib/colo/globe-data.js +179 -0
  218. package/dist/lib/colo/globe-data.js.map +1 -0
  219. package/dist/lib/colo/index.js +16 -0
  220. package/dist/lib/colo/index.js.map +1 -0
  221. package/dist/lib/decorators.js +37 -0
  222. package/dist/lib/decorators.js.map +1 -0
  223. package/dist/lib/discovery.js +81 -0
  224. package/dist/lib/discovery.js.map +1 -0
  225. package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
  226. package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
  227. package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
  228. package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
  229. package/dist/lib/executors/CascadeExecutor.js +418 -0
  230. package/dist/lib/executors/CascadeExecutor.js.map +1 -0
  231. package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
  232. package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
  233. package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
  234. package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
  235. package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
  236. package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
  237. package/dist/lib/executors/ParallelStepExecutor.js +308 -0
  238. package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
  239. package/dist/lib/executors/types.js +12 -0
  240. package/dist/lib/executors/types.js.map +1 -0
  241. package/dist/lib/experiments.js +89 -0
  242. package/dist/lib/experiments.js.map +1 -0
  243. package/dist/lib/flags/store.js +262 -0
  244. package/dist/lib/flags/store.js.map +1 -0
  245. package/dist/lib/functions/FunctionComposition.js +467 -0
  246. package/dist/lib/functions/FunctionComposition.js.map +1 -0
  247. package/dist/lib/functions/FunctionMiddleware.js +457 -0
  248. package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
  249. package/dist/lib/functions/FunctionRegistry.js +426 -0
  250. package/dist/lib/functions/FunctionRegistry.js.map +1 -0
  251. package/dist/lib/functions/createFunction.js +1048 -0
  252. package/dist/lib/functions/createFunction.js.map +1 -0
  253. package/dist/lib/humans/index.js +68 -0
  254. package/dist/lib/humans/index.js.map +1 -0
  255. package/dist/lib/humans/templates.js +117 -0
  256. package/dist/lib/humans/templates.js.map +1 -0
  257. package/dist/lib/identity.js +98 -0
  258. package/dist/lib/identity.js.map +1 -0
  259. package/dist/lib/index.js +9 -0
  260. package/dist/lib/index.js.map +1 -0
  261. package/dist/lib/logging/error-logger.js +163 -0
  262. package/dist/lib/logging/error-logger.js.map +1 -0
  263. package/dist/lib/logging/index.js +160 -0
  264. package/dist/lib/logging/index.js.map +1 -0
  265. package/dist/lib/mixins/bash.js +825 -0
  266. package/dist/lib/mixins/bash.js.map +1 -0
  267. package/dist/lib/mixins/fs.js +648 -0
  268. package/dist/lib/mixins/fs.js.map +1 -0
  269. package/dist/lib/mixins/git.js +1011 -0
  270. package/dist/lib/mixins/git.js.map +1 -0
  271. package/dist/lib/mixins/index.js +29 -0
  272. package/dist/lib/mixins/index.js.map +1 -0
  273. package/dist/lib/mixins/npm.js +662 -0
  274. package/dist/lib/mixins/npm.js.map +1 -0
  275. package/dist/lib/noun-id.js +278 -0
  276. package/dist/lib/noun-id.js.map +1 -0
  277. package/dist/lib/rate-limit/sliding-window.js +148 -0
  278. package/dist/lib/rate-limit/sliding-window.js.map +1 -0
  279. package/dist/lib/rate-limit.js +110 -0
  280. package/dist/lib/rate-limit.js.map +1 -0
  281. package/dist/lib/rpc/bindings.js +548 -0
  282. package/dist/lib/rpc/bindings.js.map +1 -0
  283. package/dist/lib/rpc/index.js +64 -0
  284. package/dist/lib/rpc/index.js.map +1 -0
  285. package/dist/lib/safe-stringify.js +223 -0
  286. package/dist/lib/safe-stringify.js.map +1 -0
  287. package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
  288. package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
  289. package/dist/lib/sqids.js +110 -0
  290. package/dist/lib/sqids.js.map +1 -0
  291. package/dist/lib/sql/adapters/index.js +10 -0
  292. package/dist/lib/sql/adapters/index.js.map +1 -0
  293. package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
  294. package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
  295. package/dist/lib/sql/adapters/pgsql-parser.js +1189 -0
  296. package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
  297. package/dist/lib/sql/index.js +277 -0
  298. package/dist/lib/sql/index.js.map +1 -0
  299. package/dist/lib/sql/types.js +56 -0
  300. package/dist/lib/sql/types.js.map +1 -0
  301. package/dist/lib/type-classifier.js +126 -0
  302. package/dist/lib/type-classifier.js.map +1 -0
  303. package/dist/lib/utils/html.js +47 -0
  304. package/dist/lib/utils/html.js.map +1 -0
  305. package/dist/lib/validation.js +48 -0
  306. package/dist/lib/validation.js.map +1 -0
  307. package/dist/lib/vault/store.js +411 -0
  308. package/dist/lib/vault/store.js.map +1 -0
  309. package/dist/metrics/hunch.js +739 -0
  310. package/dist/metrics/hunch.js.map +1 -0
  311. package/dist/objects/API.js +302 -0
  312. package/dist/objects/API.js.map +1 -0
  313. package/dist/objects/Agent.js +179 -0
  314. package/dist/objects/Agent.js.map +1 -0
  315. package/dist/objects/AgenticFunctionExecutor.js +8 -0
  316. package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
  317. package/dist/objects/App.js +83 -0
  318. package/dist/objects/App.js.map +1 -0
  319. package/dist/objects/Browser.js +884 -0
  320. package/dist/objects/Browser.js.map +1 -0
  321. package/dist/objects/Business.js +107 -0
  322. package/dist/objects/Business.js.map +1 -0
  323. package/dist/objects/CLI.js +221 -0
  324. package/dist/objects/CLI.js.map +1 -0
  325. package/dist/objects/CodeFunctionExecutor.js +8 -0
  326. package/dist/objects/CodeFunctionExecutor.js.map +1 -0
  327. package/dist/objects/Collection.js +161 -0
  328. package/dist/objects/Collection.js.map +1 -0
  329. package/dist/objects/DO.js +41 -0
  330. package/dist/objects/DO.js.map +1 -0
  331. package/dist/objects/DOBase.js +2309 -0
  332. package/dist/objects/DOBase.js.map +1 -0
  333. package/dist/objects/DOFull.js +1676 -0
  334. package/dist/objects/DOFull.js.map +1 -0
  335. package/dist/objects/DOTiny.js +207 -0
  336. package/dist/objects/DOTiny.js.map +1 -0
  337. package/dist/objects/Directory.js +199 -0
  338. package/dist/objects/Directory.js.map +1 -0
  339. package/dist/objects/Entity.js +413 -0
  340. package/dist/objects/Entity.js.map +1 -0
  341. package/dist/objects/Function.js +116 -0
  342. package/dist/objects/Function.js.map +1 -0
  343. package/dist/objects/Human.js +231 -0
  344. package/dist/objects/Human.js.map +1 -0
  345. package/dist/objects/HumanFunctionExecutor.js +8 -0
  346. package/dist/objects/HumanFunctionExecutor.js.map +1 -0
  347. package/dist/objects/IcebergMetadataDO.js +938 -0
  348. package/dist/objects/IcebergMetadataDO.js.map +1 -0
  349. package/dist/objects/IntegrationsDO.js +1174 -0
  350. package/dist/objects/IntegrationsDO.js.map +1 -0
  351. package/dist/objects/ObservabilityBroadcaster.js +149 -0
  352. package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
  353. package/dist/objects/Package.js +154 -0
  354. package/dist/objects/Package.js.map +1 -0
  355. package/dist/objects/Product.js +193 -0
  356. package/dist/objects/Product.js.map +1 -0
  357. package/dist/objects/SDK.js +152 -0
  358. package/dist/objects/SDK.js.map +1 -0
  359. package/dist/objects/SaaS.js +235 -0
  360. package/dist/objects/SaaS.js.map +1 -0
  361. package/dist/objects/SandboxDO.js +759 -0
  362. package/dist/objects/SandboxDO.js.map +1 -0
  363. package/dist/objects/Service.js +337 -0
  364. package/dist/objects/Service.js.map +1 -0
  365. package/dist/objects/Site.js +80 -0
  366. package/dist/objects/Site.js.map +1 -0
  367. package/dist/objects/Startup.js +479 -0
  368. package/dist/objects/Startup.js.map +1 -0
  369. package/dist/objects/ThingsDO.js +170 -0
  370. package/dist/objects/ThingsDO.js.map +1 -0
  371. package/dist/objects/VectorShardDO.js +648 -0
  372. package/dist/objects/VectorShardDO.js.map +1 -0
  373. package/dist/objects/Worker.js +144 -0
  374. package/dist/objects/Worker.js.map +1 -0
  375. package/dist/objects/Workflow.js +196 -0
  376. package/dist/objects/Workflow.js.map +1 -0
  377. package/dist/objects/WorkflowFactory.js +313 -0
  378. package/dist/objects/WorkflowFactory.js.map +1 -0
  379. package/dist/objects/WorkflowRuntime.js +863 -0
  380. package/dist/objects/WorkflowRuntime.js.map +1 -0
  381. package/dist/objects/circuit-breaker-bulkhead.js +178 -0
  382. package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
  383. package/dist/objects/createFunction.js +934 -0
  384. package/dist/objects/createFunction.js.map +1 -0
  385. package/dist/objects/index.js +80 -0
  386. package/dist/objects/index.js.map +1 -0
  387. package/dist/objects/lifecycle/Branch.js +275 -0
  388. package/dist/objects/lifecycle/Branch.js.map +1 -0
  389. package/dist/objects/lifecycle/Clone.js +1499 -0
  390. package/dist/objects/lifecycle/Clone.js.map +1 -0
  391. package/dist/objects/lifecycle/Compact.js +237 -0
  392. package/dist/objects/lifecycle/Compact.js.map +1 -0
  393. package/dist/objects/lifecycle/Promote.js +476 -0
  394. package/dist/objects/lifecycle/Promote.js.map +1 -0
  395. package/dist/objects/lifecycle/Shard.js +560 -0
  396. package/dist/objects/lifecycle/Shard.js.map +1 -0
  397. package/dist/objects/lifecycle/index.js +15 -0
  398. package/dist/objects/lifecycle/index.js.map +1 -0
  399. package/dist/objects/lifecycle/types.js +33 -0
  400. package/dist/objects/lifecycle/types.js.map +1 -0
  401. package/dist/objects/mixins/infrastructure.js +171 -0
  402. package/dist/objects/mixins/infrastructure.js.map +1 -0
  403. package/dist/objects/modules/StoresModule.js +153 -0
  404. package/dist/objects/modules/StoresModule.js.map +1 -0
  405. package/dist/objects/persistence/checkpoint-manager.js +606 -0
  406. package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
  407. package/dist/objects/persistence/index.js +72 -0
  408. package/dist/objects/persistence/index.js.map +1 -0
  409. package/dist/objects/persistence/migration-runner.js +562 -0
  410. package/dist/objects/persistence/migration-runner.js.map +1 -0
  411. package/dist/objects/persistence/replication-manager.js +501 -0
  412. package/dist/objects/persistence/replication-manager.js.map +1 -0
  413. package/dist/objects/persistence/tiered-storage-manager.js +595 -0
  414. package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
  415. package/dist/objects/persistence/types.js +14 -0
  416. package/dist/objects/persistence/types.js.map +1 -0
  417. package/dist/objects/persistence/wal-manager.js +653 -0
  418. package/dist/objects/persistence/wal-manager.js.map +1 -0
  419. package/dist/objects/presets/index.js +20 -0
  420. package/dist/objects/presets/index.js.map +1 -0
  421. package/dist/objects/presets/primitives.js +188 -0
  422. package/dist/objects/presets/primitives.js.map +1 -0
  423. package/dist/objects/primitives/alarm-adapter.js +141 -0
  424. package/dist/objects/primitives/alarm-adapter.js.map +1 -0
  425. package/dist/objects/primitives/index.js +337 -0
  426. package/dist/objects/primitives/index.js.map +1 -0
  427. package/dist/objects/primitives/storage-adapter.js +182 -0
  428. package/dist/objects/primitives/storage-adapter.js.map +1 -0
  429. package/dist/objects/primitives/with-primitives.js +102 -0
  430. package/dist/objects/primitives/with-primitives.js.map +1 -0
  431. package/dist/objects/services/StoreManager.js +227 -0
  432. package/dist/objects/services/StoreManager.js.map +1 -0
  433. package/dist/objects/services/index.js +13 -0
  434. package/dist/objects/services/index.js.map +1 -0
  435. package/dist/objects/transport/auth-layer.js +1451 -0
  436. package/dist/objects/transport/auth-layer.js.map +1 -0
  437. package/dist/objects/transport/capnweb-target.js +355 -0
  438. package/dist/objects/transport/capnweb-target.js.map +1 -0
  439. package/dist/objects/transport/chain.js +441 -0
  440. package/dist/objects/transport/chain.js.map +1 -0
  441. package/dist/objects/transport/handler.js +58 -0
  442. package/dist/objects/transport/handler.js.map +1 -0
  443. package/dist/objects/transport/index.js +53 -0
  444. package/dist/objects/transport/index.js.map +1 -0
  445. package/dist/objects/transport/mcp-server.js +690 -0
  446. package/dist/objects/transport/mcp-server.js.map +1 -0
  447. package/dist/objects/transport/rest-autowire.js +1507 -0
  448. package/dist/objects/transport/rest-autowire.js.map +1 -0
  449. package/dist/objects/transport/rest-router.js +440 -0
  450. package/dist/objects/transport/rest-router.js.map +1 -0
  451. package/dist/objects/transport/rpc-server.js +1536 -0
  452. package/dist/objects/transport/rpc-server.js.map +1 -0
  453. package/dist/objects/transport/shared.js +575 -0
  454. package/dist/objects/transport/shared.js.map +1 -0
  455. package/dist/objects/transport/sync-engine.js +291 -0
  456. package/dist/objects/transport/sync-engine.js.map +1 -0
  457. package/dist/objects/transport/types.js +8 -0
  458. package/dist/objects/transport/types.js.map +1 -0
  459. package/dist/primitives/bashx/src/ast/analyze.js +1472 -0
  460. package/dist/primitives/bashx/src/ast/analyze.js.map +1 -0
  461. package/dist/primitives/bashx/src/ast/parser.js +1488 -0
  462. package/dist/primitives/bashx/src/ast/parser.js.map +1 -0
  463. package/dist/primitives/bashx/src/do/commands/crypto.js +1954 -0
  464. package/dist/primitives/bashx/src/do/commands/crypto.js.map +1 -0
  465. package/dist/primitives/bashx/src/do/commands/data-processing.js +1812 -0
  466. package/dist/primitives/bashx/src/do/commands/data-processing.js.map +1 -0
  467. package/dist/primitives/bashx/src/do/commands/extended-utils.js +804 -0
  468. package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +1 -0
  469. package/dist/primitives/bashx/src/do/commands/math-control.js +1122 -0
  470. package/dist/primitives/bashx/src/do/commands/math-control.js.map +1 -0
  471. package/dist/primitives/bashx/src/do/commands/posix-utils.js +1015 -0
  472. package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +1 -0
  473. package/dist/primitives/bashx/src/do/commands/system-utils.js +687 -0
  474. package/dist/primitives/bashx/src/do/commands/system-utils.js.map +1 -0
  475. package/dist/primitives/bashx/src/do/commands/test-command.js +523 -0
  476. package/dist/primitives/bashx/src/do/commands/test-command.js.map +1 -0
  477. package/dist/primitives/bashx/src/do/commands/text-processing.js +1550 -0
  478. package/dist/primitives/bashx/src/do/commands/text-processing.js.map +1 -0
  479. package/dist/primitives/bashx/src/do/container-executor.js +429 -0
  480. package/dist/primitives/bashx/src/do/container-executor.js.map +1 -0
  481. package/dist/primitives/bashx/src/do/index.js +668 -0
  482. package/dist/primitives/bashx/src/do/index.js.map +1 -0
  483. package/dist/primitives/bashx/src/do/tiered-executor.js +2647 -0
  484. package/dist/primitives/bashx/src/do/tiered-executor.js.map +1 -0
  485. package/dist/primitives/bashx/src/do/worker.js +352 -0
  486. package/dist/primitives/bashx/src/do/worker.js.map +1 -0
  487. package/dist/primitives/bashx/src/types.js +10 -0
  488. package/dist/primitives/bashx/src/types.js.map +1 -0
  489. package/dist/primitives/fsx/core/backend.js +480 -0
  490. package/dist/primitives/fsx/core/backend.js.map +1 -0
  491. package/dist/primitives/fsx/core/constants.js +140 -0
  492. package/dist/primitives/fsx/core/constants.js.map +1 -0
  493. package/dist/primitives/fsx/core/fsx.js +1184 -0
  494. package/dist/primitives/fsx/core/fsx.js.map +1 -0
  495. package/dist/primitives/fsx/core/glob/glob.js +438 -0
  496. package/dist/primitives/fsx/core/glob/glob.js.map +1 -0
  497. package/dist/primitives/fsx/core/glob/index.js +8 -0
  498. package/dist/primitives/fsx/core/glob/index.js.map +1 -0
  499. package/dist/primitives/fsx/core/glob/match.js +392 -0
  500. package/dist/primitives/fsx/core/glob/match.js.map +1 -0
  501. package/dist/primitives/fsx/core/types.js +307 -0
  502. package/dist/primitives/fsx/core/types.js.map +1 -0
  503. package/dist/sandbox/index.js +258 -0
  504. package/dist/sandbox/index.js.map +1 -0
  505. package/dist/sdk/capnweb-compat.js +42 -0
  506. package/dist/sdk/capnweb-compat.js.map +1 -0
  507. package/dist/sdk/client.js +20 -0
  508. package/dist/sdk/client.js.map +1 -0
  509. package/dist/sdk/index.js +17 -0
  510. package/dist/sdk/index.js.map +1 -0
  511. package/dist/snippets/artifacts-config.js +241 -0
  512. package/dist/snippets/artifacts-config.js.map +1 -0
  513. package/dist/snippets/artifacts-ingest.js +832 -0
  514. package/dist/snippets/artifacts-ingest.js.map +1 -0
  515. package/dist/snippets/artifacts-serve.js +1035 -0
  516. package/dist/snippets/artifacts-serve.js.map +1 -0
  517. package/dist/snippets/artifacts-types.js +161 -0
  518. package/dist/snippets/artifacts-types.js.map +1 -0
  519. package/dist/snippets/cache-probe.js +376 -0
  520. package/dist/snippets/cache-probe.js.map +1 -0
  521. package/dist/snippets/cache.js +10 -0
  522. package/dist/snippets/cache.js.map +1 -0
  523. package/dist/snippets/events.js +469 -0
  524. package/dist/snippets/events.js.map +1 -0
  525. package/dist/snippets/index.js +7 -0
  526. package/dist/snippets/index.js.map +1 -0
  527. package/dist/snippets/proxy.js +495 -0
  528. package/dist/snippets/proxy.js.map +1 -0
  529. package/dist/snippets/search.js +1759 -0
  530. package/dist/snippets/search.js.map +1 -0
  531. package/dist/streams/index.js +30 -0
  532. package/dist/streams/index.js.map +1 -0
  533. package/dist/streams/observability.js +68 -0
  534. package/dist/streams/observability.js.map +1 -0
  535. package/dist/types/AI.js +92 -0
  536. package/dist/types/AI.js.map +1 -0
  537. package/dist/types/AIFunction.js +171 -0
  538. package/dist/types/AIFunction.js.map +1 -0
  539. package/dist/types/BrowseVerb.js +89 -0
  540. package/dist/types/BrowseVerb.js.map +1 -0
  541. package/dist/types/Browser.js +31 -0
  542. package/dist/types/Browser.js.map +1 -0
  543. package/dist/types/Chaos.js +15 -0
  544. package/dist/types/Chaos.js.map +1 -0
  545. package/dist/types/CloudflareBindings.js +109 -0
  546. package/dist/types/CloudflareBindings.js.map +1 -0
  547. package/dist/types/Collection.js +50 -0
  548. package/dist/types/Collection.js.map +1 -0
  549. package/dist/types/DO.js +2 -0
  550. package/dist/types/DO.js.map +1 -0
  551. package/dist/types/DOLocation.js +63 -0
  552. package/dist/types/DOLocation.js.map +1 -0
  553. package/dist/types/EventHandler.js +57 -0
  554. package/dist/types/EventHandler.js.map +1 -0
  555. package/dist/types/Experiment.js +33 -0
  556. package/dist/types/Experiment.js.map +1 -0
  557. package/dist/types/Flag.js +57 -0
  558. package/dist/types/Flag.js.map +1 -0
  559. package/dist/types/Lifecycle.js +13 -0
  560. package/dist/types/Lifecycle.js.map +1 -0
  561. package/dist/types/Location.js +169 -0
  562. package/dist/types/Location.js.map +1 -0
  563. package/dist/types/Noun.js +66 -0
  564. package/dist/types/Noun.js.map +1 -0
  565. package/dist/types/SessionEvent.js +194 -0
  566. package/dist/types/SessionEvent.js.map +1 -0
  567. package/dist/types/Thing.js +55 -0
  568. package/dist/types/Thing.js.map +1 -0
  569. package/dist/types/ThingDO.js +153 -0
  570. package/dist/types/ThingDO.js.map +1 -0
  571. package/dist/types/Things.js +2 -0
  572. package/dist/types/Things.js.map +1 -0
  573. package/dist/types/Verb.js +119 -0
  574. package/dist/types/Verb.js.map +1 -0
  575. package/dist/types/WorkflowContext.js +70 -0
  576. package/dist/types/WorkflowContext.js.map +1 -0
  577. package/dist/types/analytics-api.js +13 -0
  578. package/dist/types/analytics-api.js.map +1 -0
  579. package/dist/types/capabilities.js +135 -0
  580. package/dist/types/capabilities.js.map +1 -0
  581. package/dist/types/drizzle.js +12 -0
  582. package/dist/types/drizzle.js.map +1 -0
  583. package/dist/types/event.js +201 -0
  584. package/dist/types/event.js.map +1 -0
  585. package/dist/types/fn.js +12 -0
  586. package/dist/types/fn.js.map +1 -0
  587. package/dist/types/iceberg.js +48 -0
  588. package/dist/types/iceberg.js.map +1 -0
  589. package/dist/types/ids.js +170 -0
  590. package/dist/types/ids.js.map +1 -0
  591. package/dist/types/index.js +41 -0
  592. package/dist/types/index.js.map +1 -0
  593. package/dist/types/introspect.js +54 -0
  594. package/dist/types/introspect.js.map +1 -0
  595. package/dist/types/observability.js +124 -0
  596. package/dist/types/observability.js.map +1 -0
  597. package/dist/types/sync-protocol.js +175 -0
  598. package/dist/types/sync-protocol.js.map +1 -0
  599. package/dist/types/vector.js +13 -0
  600. package/dist/types/vector.js.map +1 -0
  601. package/dist/workflows/ScheduleManager.js +473 -0
  602. package/dist/workflows/ScheduleManager.js.map +1 -0
  603. package/dist/workflows/StepDOBridge.js +149 -0
  604. package/dist/workflows/StepDOBridge.js.map +1 -0
  605. package/dist/workflows/StepResultStorage.js +232 -0
  606. package/dist/workflows/StepResultStorage.js.map +1 -0
  607. package/dist/workflows/WaitForEventManager.js +461 -0
  608. package/dist/workflows/WaitForEventManager.js.map +1 -0
  609. package/dist/workflows/analyzer.js +332 -0
  610. package/dist/workflows/analyzer.js.map +1 -0
  611. package/dist/workflows/compat/activity-router.js +484 -0
  612. package/dist/workflows/compat/activity-router.js.map +1 -0
  613. package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
  614. package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
  615. package/dist/workflows/compat/backends/index.js +14 -0
  616. package/dist/workflows/compat/backends/index.js.map +1 -0
  617. package/dist/workflows/compat/errors/index.js +375 -0
  618. package/dist/workflows/compat/errors/index.js.map +1 -0
  619. package/dist/workflows/compat/index.js +79 -0
  620. package/dist/workflows/compat/index.js.map +1 -0
  621. package/dist/workflows/compat/inngest/index.js +989 -0
  622. package/dist/workflows/compat/inngest/index.js.map +1 -0
  623. package/dist/workflows/compat/qstash/index.js +1263 -0
  624. package/dist/workflows/compat/qstash/index.js.map +1 -0
  625. package/dist/workflows/compat/temporal/activities.js +739 -0
  626. package/dist/workflows/compat/temporal/activities.js.map +1 -0
  627. package/dist/workflows/compat/temporal/child-workflows.js +154 -0
  628. package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
  629. package/dist/workflows/compat/temporal/client.js +381 -0
  630. package/dist/workflows/compat/temporal/client.js.map +1 -0
  631. package/dist/workflows/compat/temporal/context.js +309 -0
  632. package/dist/workflows/compat/temporal/context.js.map +1 -0
  633. package/dist/workflows/compat/temporal/determinism.js +216 -0
  634. package/dist/workflows/compat/temporal/determinism.js.map +1 -0
  635. package/dist/workflows/compat/temporal/errors.js +128 -0
  636. package/dist/workflows/compat/temporal/errors.js.map +1 -0
  637. package/dist/workflows/compat/temporal/index.js +2464 -0
  638. package/dist/workflows/compat/temporal/index.js.map +1 -0
  639. package/dist/workflows/compat/temporal/saga.js +504 -0
  640. package/dist/workflows/compat/temporal/saga.js.map +1 -0
  641. package/dist/workflows/compat/temporal/signals.js +364 -0
  642. package/dist/workflows/compat/temporal/signals.js.map +1 -0
  643. package/dist/workflows/compat/temporal/storage.js +271 -0
  644. package/dist/workflows/compat/temporal/storage.js.map +1 -0
  645. package/dist/workflows/compat/temporal/timers.js +347 -0
  646. package/dist/workflows/compat/temporal/timers.js.map +1 -0
  647. package/dist/workflows/compat/temporal/types.js +7 -0
  648. package/dist/workflows/compat/temporal/types.js.map +1 -0
  649. package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
  650. package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
  651. package/dist/workflows/compat/trigger/index.js +468 -0
  652. package/dist/workflows/compat/trigger/index.js.map +1 -0
  653. package/dist/workflows/compat/utils/index.js +69 -0
  654. package/dist/workflows/compat/utils/index.js.map +1 -0
  655. package/dist/workflows/context/correlation-capability.js +266 -0
  656. package/dist/workflows/context/correlation-capability.js.map +1 -0
  657. package/dist/workflows/context/correlation.js +484 -0
  658. package/dist/workflows/context/correlation.js.map +1 -0
  659. package/dist/workflows/context/experiment.js +289 -0
  660. package/dist/workflows/context/experiment.js.map +1 -0
  661. package/dist/workflows/context/flag.js +244 -0
  662. package/dist/workflows/context/flag.js.map +1 -0
  663. package/dist/workflows/context/foundation.js +648 -0
  664. package/dist/workflows/context/foundation.js.map +1 -0
  665. package/dist/workflows/context/human-base.js +106 -0
  666. package/dist/workflows/context/human-base.js.map +1 -0
  667. package/dist/workflows/context/human.js +368 -0
  668. package/dist/workflows/context/human.js.map +1 -0
  669. package/dist/workflows/context/measure.js +354 -0
  670. package/dist/workflows/context/measure.js.map +1 -0
  671. package/dist/workflows/context/rate-limit.js +358 -0
  672. package/dist/workflows/context/rate-limit.js.map +1 -0
  673. package/dist/workflows/context/user.js +117 -0
  674. package/dist/workflows/context/user.js.map +1 -0
  675. package/dist/workflows/context/vault.js +360 -0
  676. package/dist/workflows/context/vault.js.map +1 -0
  677. package/dist/workflows/data/entity-events/entity-events.js +489 -0
  678. package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
  679. package/dist/workflows/data/experiment/index.js +599 -0
  680. package/dist/workflows/data/experiment/index.js.map +1 -0
  681. package/dist/workflows/data/goal/context.js +558 -0
  682. package/dist/workflows/data/goal/context.js.map +1 -0
  683. package/dist/workflows/data/goal/index.js +32 -0
  684. package/dist/workflows/data/goal/index.js.map +1 -0
  685. package/dist/workflows/data/measure/index.js +840 -0
  686. package/dist/workflows/data/measure/index.js.map +1 -0
  687. package/dist/workflows/data/stream/index.js +1215 -0
  688. package/dist/workflows/data/stream/index.js.map +1 -0
  689. package/dist/workflows/data/track/context.js +883 -0
  690. package/dist/workflows/data/track/context.js.map +1 -0
  691. package/dist/workflows/data/track/index.js +15 -0
  692. package/dist/workflows/data/track/index.js.map +1 -0
  693. package/dist/workflows/data/view/context.js +864 -0
  694. package/dist/workflows/data/view/context.js.map +1 -0
  695. package/dist/workflows/domain.js +93 -0
  696. package/dist/workflows/domain.js.map +1 -0
  697. package/dist/workflows/flag.js +176 -0
  698. package/dist/workflows/flag.js.map +1 -0
  699. package/dist/workflows/flags.js +217 -0
  700. package/dist/workflows/flags.js.map +1 -0
  701. package/dist/workflows/hash.js +209 -0
  702. package/dist/workflows/hash.js.map +1 -0
  703. package/dist/workflows/index.js +50 -0
  704. package/dist/workflows/index.js.map +1 -0
  705. package/dist/workflows/on.js +378 -0
  706. package/dist/workflows/on.js.map +1 -0
  707. package/dist/workflows/pipeline-promise.js +481 -0
  708. package/dist/workflows/pipeline-promise.js.map +1 -0
  709. package/dist/workflows/pipeline-types.js +20 -0
  710. package/dist/workflows/pipeline-types.js.map +1 -0
  711. package/dist/workflows/proxy.js +76 -0
  712. package/dist/workflows/proxy.js.map +1 -0
  713. package/dist/workflows/runtime.js +310 -0
  714. package/dist/workflows/runtime.js.map +1 -0
  715. package/dist/workflows/schedule-builder.js +327 -0
  716. package/dist/workflows/schedule-builder.js.map +1 -0
  717. package/dist/workflows/visibility/index.js +148 -0
  718. package/dist/workflows/visibility/index.js.map +1 -0
  719. package/dist/workflows/visibility/query-parser.js +150 -0
  720. package/dist/workflows/visibility/query-parser.js.map +1 -0
  721. package/dist/workflows/visibility/store.js +223 -0
  722. package/dist/workflows/visibility/store.js.map +1 -0
  723. package/dist/workflows/visibility/types.js +30 -0
  724. package/dist/workflows/visibility/types.js.map +1 -0
  725. package/dist/workflows/workflow.js +53 -0
  726. package/dist/workflows/workflow.js.map +1 -0
  727. package/package.json +279 -46
@@ -0,0 +1,1812 @@
1
+ /**
2
+ * Data Processing Commands
3
+ *
4
+ * Native implementations of data processing commands:
5
+ * - jq: JSON processor
6
+ * - yq: YAML processor
7
+ * - base64: Encoding/decoding
8
+ * - envsubst: Environment variable substitution
9
+ *
10
+ * These run as Tier 1 native commands in the Worker.
11
+ *
12
+ * @module bashx/do/commands/data-processing
13
+ */
14
+ /**
15
+ * Sentinel value indicating expression was not a builtin function
16
+ */
17
+ const NOT_A_BUILTIN = Symbol('NOT_A_BUILTIN');
18
+ /**
19
+ * Custom error for jq parsing/execution errors
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * throw new JqError('parse error: Invalid JSON input', 5)
24
+ * ```
25
+ */
26
+ export class JqError extends Error {
27
+ exitCode;
28
+ /**
29
+ * Creates a new JqError
30
+ *
31
+ * @param message - Error message describing the problem
32
+ * @param exitCode - Exit code to return (default: 1, parse errors: 5)
33
+ */
34
+ constructor(message, exitCode = 1) {
35
+ super(message);
36
+ this.exitCode = exitCode;
37
+ this.name = 'JqError';
38
+ }
39
+ }
40
+ /**
41
+ * JqEngine - Reusable JSON query processor
42
+ *
43
+ * Provides a jq-compatible query language for filtering and transforming JSON data.
44
+ * Supports:
45
+ * - Key access (.key, .key.nested)
46
+ * - Array operations (.[n], .[], map, select, sort_by)
47
+ * - Object construction ({key, newKey: .expr})
48
+ * - Built-in functions (length, keys, values, type, etc.)
49
+ * - Conditionals (if-then-else, alternative operator //)
50
+ * - Variables (--arg, --argjson)
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const engine = new JqEngine()
55
+ * const result = engine.execute('.name', '{"name": "test"}')
56
+ * // result = '"test"\n'
57
+ *
58
+ * const filtered = engine.execute(
59
+ * '.[] | select(.age > 18)',
60
+ * '[{"name": "alice", "age": 25}]'
61
+ * )
62
+ * ```
63
+ */
64
+ export class JqEngine {
65
+ /** Cached parsed JSON to avoid re-parsing */
66
+ cachedInput = null;
67
+ cachedData = null;
68
+ /**
69
+ * Execute a jq query on JSON input
70
+ *
71
+ * @param query - The jq query expression (e.g., '.name', '.[] | select(.age > 18)')
72
+ * @param input - JSON input string
73
+ * @param options - Execution options (raw output, compact, slurp, variables)
74
+ * @returns Query result as formatted string
75
+ * @throws {JqError} On invalid JSON or query syntax errors
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const engine = new JqEngine()
80
+ *
81
+ * // Simple key access
82
+ * engine.execute('.name', '{"name": "test"}')
83
+ * // => '"test"\n'
84
+ *
85
+ * // With raw output (no quotes)
86
+ * engine.execute('.name', '{"name": "test"}', { raw: true })
87
+ * // => 'test\n'
88
+ *
89
+ * // With variables
90
+ * engine.execute(
91
+ * '.[] | select(.age > $minAge)',
92
+ * '[{"age": 25}, {"age": 17}]',
93
+ * { argjson: { minAge: 18 } }
94
+ * )
95
+ * ```
96
+ */
97
+ execute(query, input, options = {}) {
98
+ const data = this.parseInput(input, options);
99
+ const context = this.createContext(options);
100
+ const result = this.evaluateWithMeta(query, data, context);
101
+ return this.formatOutput(result.value, options, result.isIterator);
102
+ }
103
+ /**
104
+ * Evaluate a jq expression and return the raw value (not formatted)
105
+ *
106
+ * @param query - The jq query expression
107
+ * @param data - Parsed JSON data
108
+ * @param context - Execution context with variables
109
+ * @returns Raw evaluated value
110
+ */
111
+ evaluate(query, data, context) {
112
+ const trimmedQuery = query.trim();
113
+ if (trimmedQuery === '.' || trimmedQuery === '') {
114
+ return data;
115
+ }
116
+ const tokens = this.tokenize(trimmedQuery);
117
+ return this.executeTokens(tokens, data, context).value;
118
+ }
119
+ /**
120
+ * Parse JSON input, handling slurp mode for multiple documents
121
+ *
122
+ * @param input - JSON input string
123
+ * @param options - Options containing slurp mode setting
124
+ * @returns Parsed JSON data
125
+ * @throws {JqError} On invalid JSON
126
+ */
127
+ parseInput(input, options) {
128
+ // Check cache for non-slurp mode
129
+ if (!options.slurp && input === this.cachedInput) {
130
+ return this.cachedData;
131
+ }
132
+ let data;
133
+ if (options.slurp) {
134
+ data = this.parseSlurpMode(input);
135
+ }
136
+ else {
137
+ try {
138
+ data = JSON.parse(input);
139
+ // Cache the parsed result
140
+ this.cachedInput = input;
141
+ this.cachedData = data;
142
+ }
143
+ catch {
144
+ throw new JqError('parse error: Invalid JSON input', 5);
145
+ }
146
+ }
147
+ return data;
148
+ }
149
+ /**
150
+ * Parse multiple JSON documents in slurp mode
151
+ *
152
+ * @param input - Input containing multiple JSON documents (newline-separated)
153
+ * @returns Array of parsed documents
154
+ */
155
+ parseSlurpMode(input) {
156
+ const docs = [];
157
+ const lines = input.trim().split('\n');
158
+ let currentDoc = '';
159
+ let braceCount = 0;
160
+ let bracketCount = 0;
161
+ for (const line of lines) {
162
+ currentDoc += line;
163
+ for (const char of line) {
164
+ if (char === '{')
165
+ braceCount++;
166
+ else if (char === '}')
167
+ braceCount--;
168
+ else if (char === '[')
169
+ bracketCount++;
170
+ else if (char === ']')
171
+ bracketCount--;
172
+ }
173
+ if (braceCount === 0 && bracketCount === 0 && currentDoc.trim()) {
174
+ try {
175
+ docs.push(JSON.parse(currentDoc.trim()));
176
+ currentDoc = '';
177
+ }
178
+ catch {
179
+ // Continue accumulating
180
+ }
181
+ }
182
+ }
183
+ // Try to parse any remaining content
184
+ if (currentDoc.trim()) {
185
+ try {
186
+ docs.push(JSON.parse(currentDoc.trim()));
187
+ }
188
+ catch {
189
+ // Ignore
190
+ }
191
+ }
192
+ return docs;
193
+ }
194
+ /**
195
+ * Create execution context from options
196
+ *
197
+ * @param options - Options containing variable bindings
198
+ * @returns JqContext with variables
199
+ */
200
+ createContext(options) {
201
+ return {
202
+ vars: { ...options.args },
203
+ argjson: { ...options.argjson },
204
+ };
205
+ }
206
+ /**
207
+ * Evaluate a jq expression with iterator metadata
208
+ *
209
+ * @param query - The jq query expression
210
+ * @param data - Parsed JSON data
211
+ * @param context - Execution context
212
+ * @returns Result with value and iterator flag
213
+ */
214
+ evaluateWithMeta(query, data, context) {
215
+ const trimmedQuery = query.trim();
216
+ if (trimmedQuery === '.' || trimmedQuery === '') {
217
+ return { value: data, isIterator: false };
218
+ }
219
+ const tokens = this.tokenize(trimmedQuery);
220
+ return this.executeTokens(tokens, data, context);
221
+ }
222
+ /**
223
+ * Tokenize a jq query into pipe-separated components
224
+ *
225
+ * Handles nested structures (parentheses, brackets, braces) and strings
226
+ * to correctly split on pipe operators.
227
+ *
228
+ * @param query - The jq query to tokenize
229
+ * @returns Array of token strings
230
+ */
231
+ tokenize(query) {
232
+ const tokens = [];
233
+ let current = '';
234
+ let parenDepth = 0;
235
+ let bracketDepth = 0;
236
+ let braceDepth = 0;
237
+ let inString = false;
238
+ let stringChar = '';
239
+ for (let i = 0; i < query.length; i++) {
240
+ const char = query[i];
241
+ const prevChar = i > 0 ? query[i - 1] : '';
242
+ // Handle strings
243
+ if ((char === '"' || char === "'") && prevChar !== '\\') {
244
+ if (!inString) {
245
+ inString = true;
246
+ stringChar = char;
247
+ }
248
+ else if (char === stringChar) {
249
+ inString = false;
250
+ }
251
+ current += char;
252
+ continue;
253
+ }
254
+ if (inString) {
255
+ current += char;
256
+ continue;
257
+ }
258
+ // Track nesting
259
+ if (char === '(')
260
+ parenDepth++;
261
+ else if (char === ')')
262
+ parenDepth--;
263
+ else if (char === '[')
264
+ bracketDepth++;
265
+ else if (char === ']')
266
+ bracketDepth--;
267
+ else if (char === '{')
268
+ braceDepth++;
269
+ else if (char === '}')
270
+ braceDepth--;
271
+ // Pipe separator at top level
272
+ if (char === '|' && parenDepth === 0 && bracketDepth === 0 && braceDepth === 0) {
273
+ if (current.trim()) {
274
+ tokens.push(current.trim());
275
+ }
276
+ current = '';
277
+ continue;
278
+ }
279
+ current += char;
280
+ }
281
+ if (current.trim()) {
282
+ tokens.push(current.trim());
283
+ }
284
+ return tokens;
285
+ }
286
+ /**
287
+ * Execute tokenized jq query
288
+ *
289
+ * Handles iterator semantics: when a filter produces multiple outputs,
290
+ * subsequent filters are applied to each output independently.
291
+ *
292
+ * @param tokens - Array of query tokens (pipe-separated components)
293
+ * @param data - Input data
294
+ * @param context - Execution context
295
+ * @returns Result with value and iterator flag
296
+ */
297
+ executeTokens(tokens, data, context) {
298
+ let result = data;
299
+ let isIterator = false;
300
+ for (const token of tokens) {
301
+ if (isIterator && Array.isArray(result)) {
302
+ // Apply filter to each element
303
+ const filtered = [];
304
+ for (const item of result) {
305
+ const itemResult = this.executeExpression(token, item, context);
306
+ if (itemResult !== undefined) {
307
+ filtered.push(itemResult);
308
+ }
309
+ }
310
+ result = filtered;
311
+ isIterator = true;
312
+ }
313
+ else {
314
+ result = this.executeExpression(token, result, context);
315
+ isIterator = token === '.[]' || /^\.[a-zA-Z_]\w*\[\]$/.test(token);
316
+ }
317
+ }
318
+ return { value: result, isIterator };
319
+ }
320
+ /**
321
+ * Execute a single jq expression
322
+ *
323
+ * @param expr - Expression to execute
324
+ * @param data - Current data
325
+ * @param context - Execution context
326
+ * @returns Expression result
327
+ * @throws {JqError} On invalid expression
328
+ */
329
+ executeExpression(expr, data, context) {
330
+ const trimmed = expr.trim();
331
+ // Identity
332
+ if (trimmed === '.') {
333
+ return data;
334
+ }
335
+ // Iterator: .[]
336
+ if (trimmed === '.[]') {
337
+ return this.handleIterator(data);
338
+ }
339
+ // Key access with iterator: .key[]
340
+ const keyIterMatch = trimmed.match(/^\.([a-zA-Z_][a-zA-Z0-9_]*)\[\]$/);
341
+ if (keyIterMatch) {
342
+ return this.handleKeyIterator(data, keyIterMatch[1]);
343
+ }
344
+ // Path with iterator: .items[].name
345
+ const pathIterMatch = trimmed.match(/^\.([\w.]+)\[\]\.(\w+)$/);
346
+ if (pathIterMatch) {
347
+ return this.handlePathIterator(data, pathIterMatch[1], pathIterMatch[2]);
348
+ }
349
+ // Simple key access: .key or .key.nested
350
+ if (trimmed.startsWith('.') && /^\.[\w.]+$/.test(trimmed)) {
351
+ return this.getPath(data, trimmed.slice(1));
352
+ }
353
+ // Array index: .[n] or .[n:m]
354
+ const indexMatch = trimmed.match(/^\.\[(-?\d+)(?::(-?\d+))?\]$/);
355
+ if (indexMatch) {
356
+ return this.handleArrayIndex(data, indexMatch);
357
+ }
358
+ // Key with array index: .key[n] or .key[n:m]
359
+ const keyIndexMatch = trimmed.match(/^\.(\w+)\[(-?\d+)(?::(-?\d+))?\]$/);
360
+ if (keyIndexMatch) {
361
+ return this.handleKeyIndex(data, keyIndexMatch);
362
+ }
363
+ // Nested path with array index: .items[0].name
364
+ const nestedIndexMatch = trimmed.match(/^\.(\w+)\[(-?\d+)\]\.(\w+)$/);
365
+ if (nestedIndexMatch) {
366
+ return this.handleNestedIndex(data, nestedIndexMatch);
367
+ }
368
+ // Variable access: $var
369
+ if (trimmed.startsWith('$')) {
370
+ return this.handleVariable(trimmed, context);
371
+ }
372
+ // Dynamic key access with variable: .[$key]
373
+ const dynKeyMatch = trimmed.match(/^\.\[\$(\w+)\]$/);
374
+ if (dynKeyMatch) {
375
+ return this.handleDynamicKey(data, dynKeyMatch[1], context);
376
+ }
377
+ // Built-in functions
378
+ const builtinResult = this.handleBuiltinFunction(trimmed, data, context);
379
+ if (builtinResult !== NOT_A_BUILTIN) {
380
+ return builtinResult;
381
+ }
382
+ // Object construction
383
+ if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
384
+ return this.constructObject(trimmed, data, context);
385
+ }
386
+ // Object addition
387
+ const addMatch = trimmed.match(/^\.\s*\+\s*(\{.+\})$/);
388
+ if (addMatch) {
389
+ const newObj = this.constructObject(addMatch[1], data, context);
390
+ return { ...data, ...newObj };
391
+ }
392
+ // Alternative operator: expr // default
393
+ if (trimmed.includes(' // ')) {
394
+ return this.handleAlternative(trimmed, data, context);
395
+ }
396
+ // if-then-else
397
+ const ifMatch = trimmed.match(/^if\s+(.+)\s+then\s+(.+)\s+else\s+(.+)\s+end$/);
398
+ if (ifMatch) {
399
+ return this.handleConditional(ifMatch, data, context);
400
+ }
401
+ // try-catch
402
+ const tryMatch = trimmed.match(/^try\s+(.+)\s+catch\s+(.+)$/);
403
+ if (tryMatch) {
404
+ return this.handleTryCatch(tryMatch, data, context);
405
+ }
406
+ // Literals
407
+ const literalResult = this.handleLiteral(trimmed);
408
+ if (literalResult !== NOT_A_BUILTIN) {
409
+ return literalResult;
410
+ }
411
+ throw new JqError(`Unknown expression: ${trimmed}`);
412
+ }
413
+ /**
414
+ * Handle iterator expression (.[] )
415
+ */
416
+ handleIterator(data) {
417
+ if (Array.isArray(data)) {
418
+ return data;
419
+ }
420
+ if (data && typeof data === 'object') {
421
+ return Object.values(data);
422
+ }
423
+ throw new JqError(`Cannot iterate over ${typeof data}`);
424
+ }
425
+ /**
426
+ * Handle key iterator (.key[])
427
+ */
428
+ handleKeyIterator(data, key) {
429
+ const obj = data;
430
+ const value = obj?.[key];
431
+ if (Array.isArray(value)) {
432
+ return value;
433
+ }
434
+ if (value && typeof value === 'object') {
435
+ return Object.values(value);
436
+ }
437
+ throw new JqError(`Cannot iterate over ${typeof value}`);
438
+ }
439
+ /**
440
+ * Handle path iterator (.items[].name)
441
+ */
442
+ handlePathIterator(data, basePath, finalKey) {
443
+ let current = data;
444
+ for (const key of basePath.split('.')) {
445
+ if (current && typeof current === 'object') {
446
+ current = current[key];
447
+ }
448
+ else {
449
+ return [null];
450
+ }
451
+ }
452
+ if (Array.isArray(current)) {
453
+ return current.map((item) => item?.[finalKey]);
454
+ }
455
+ throw new JqError(`Cannot iterate: not an array`);
456
+ }
457
+ /**
458
+ * Handle array index (.[n] or .[n:m])
459
+ */
460
+ handleArrayIndex(data, match) {
461
+ if (!Array.isArray(data)) {
462
+ throw new JqError('Cannot index non-array');
463
+ }
464
+ const start = parseInt(match[1], 10);
465
+ if (match[2] !== undefined) {
466
+ const end = parseInt(match[2], 10);
467
+ return data.slice(start < 0 ? data.length + start : start, end < 0 ? data.length + end : end);
468
+ }
469
+ const idx = start < 0 ? data.length + start : start;
470
+ return data[idx];
471
+ }
472
+ /**
473
+ * Handle key with array index (.key[n])
474
+ */
475
+ handleKeyIndex(data, match) {
476
+ const key = match[1];
477
+ const arr = data?.[key];
478
+ if (!Array.isArray(arr)) {
479
+ throw new JqError(`Cannot index: .${key} is not an array`);
480
+ }
481
+ const start = parseInt(match[2], 10);
482
+ if (match[3] !== undefined) {
483
+ const end = parseInt(match[3], 10);
484
+ return arr.slice(start < 0 ? arr.length + start : start, end < 0 ? arr.length + end : end);
485
+ }
486
+ const idx = start < 0 ? arr.length + start : start;
487
+ return arr[idx];
488
+ }
489
+ /**
490
+ * Handle nested path with array index (.items[0].name)
491
+ */
492
+ handleNestedIndex(data, match) {
493
+ const key = match[1];
494
+ const idx = parseInt(match[2], 10);
495
+ const finalKey = match[3];
496
+ const arr = data?.[key];
497
+ if (!Array.isArray(arr)) {
498
+ throw new JqError(`Cannot index: .${key} is not an array`);
499
+ }
500
+ const realIdx = idx < 0 ? arr.length + idx : idx;
501
+ const item = arr[realIdx];
502
+ if (item === undefined || item === null) {
503
+ throw new JqError(`Cannot get .${finalKey} of null`);
504
+ }
505
+ return item?.[finalKey];
506
+ }
507
+ /**
508
+ * Handle variable access ($var)
509
+ */
510
+ handleVariable(varExpr, context) {
511
+ const varName = varExpr.slice(1);
512
+ if (varName in context.argjson) {
513
+ return context.argjson[varName];
514
+ }
515
+ if (varName in context.vars) {
516
+ return context.vars[varName];
517
+ }
518
+ throw new JqError(`Variable ${varExpr} is not defined`);
519
+ }
520
+ /**
521
+ * Handle dynamic key access (.[$key])
522
+ */
523
+ handleDynamicKey(data, varName, context) {
524
+ let key;
525
+ if (varName in context.argjson) {
526
+ key = String(context.argjson[varName]);
527
+ }
528
+ else if (varName in context.vars) {
529
+ key = context.vars[varName];
530
+ }
531
+ else {
532
+ throw new JqError(`Variable $${varName} is not defined`);
533
+ }
534
+ return data?.[key];
535
+ }
536
+ /**
537
+ * Handle built-in functions (length, keys, sort, etc.)
538
+ *
539
+ * @returns Result value, undefined for select filter-out, or NOT_A_BUILTIN if not a builtin
540
+ */
541
+ handleBuiltinFunction(expr, data, context) {
542
+ // Simple builtins
543
+ switch (expr) {
544
+ case 'length':
545
+ if (Array.isArray(data))
546
+ return data.length;
547
+ if (typeof data === 'string')
548
+ return data.length;
549
+ if (data && typeof data === 'object')
550
+ return Object.keys(data).length;
551
+ return 0;
552
+ case 'keys':
553
+ if (data && typeof data === 'object' && !Array.isArray(data)) {
554
+ return Object.keys(data).sort();
555
+ }
556
+ if (Array.isArray(data)) {
557
+ return data.map((_, i) => i);
558
+ }
559
+ throw new JqError('keys requires an object or array');
560
+ case 'values':
561
+ if (data === null || data === undefined) {
562
+ return undefined;
563
+ }
564
+ if (data && typeof data === 'object' && !Array.isArray(data)) {
565
+ return Object.values(data);
566
+ }
567
+ return data;
568
+ case 'type':
569
+ if (data === null)
570
+ return 'null';
571
+ if (Array.isArray(data))
572
+ return 'array';
573
+ return typeof data;
574
+ case 'tonumber': {
575
+ const num = Number(data);
576
+ if (isNaN(num))
577
+ throw new JqError('Cannot convert to number');
578
+ return num;
579
+ }
580
+ case 'tostring':
581
+ if (typeof data === 'string')
582
+ return data;
583
+ return JSON.stringify(data);
584
+ case 'sort':
585
+ if (!Array.isArray(data))
586
+ throw new JqError('sort requires an array');
587
+ return [...data].sort((a, b) => {
588
+ if (typeof a === 'string' && typeof b === 'string')
589
+ return a.localeCompare(b);
590
+ if (typeof a === 'number' && typeof b === 'number')
591
+ return a - b;
592
+ return String(a).localeCompare(String(b));
593
+ });
594
+ case 'reverse':
595
+ if (!Array.isArray(data))
596
+ throw new JqError('reverse requires an array');
597
+ return [...data].reverse();
598
+ case 'unique':
599
+ if (!Array.isArray(data))
600
+ throw new JqError('unique requires an array');
601
+ return this.uniqueArray(data);
602
+ case 'flatten':
603
+ if (!Array.isArray(data))
604
+ throw new JqError('flatten requires an array');
605
+ return data.flat(Infinity);
606
+ case 'add':
607
+ if (!Array.isArray(data))
608
+ throw new JqError('add requires an array');
609
+ return this.addArray(data);
610
+ case 'ascii_upcase':
611
+ if (typeof data !== 'string')
612
+ throw new JqError('ascii_upcase requires a string');
613
+ return data.toUpperCase();
614
+ case 'ascii_downcase':
615
+ if (typeof data !== 'string')
616
+ throw new JqError('ascii_downcase requires a string');
617
+ return data.toLowerCase();
618
+ }
619
+ // Parameterized builtins
620
+ return this.handleParameterizedBuiltin(expr, data, context);
621
+ }
622
+ /**
623
+ * Handle parameterized built-in functions (sort_by, map, select, etc.)
624
+ */
625
+ handleParameterizedBuiltin(expr, data, context) {
626
+ // sort_by(.key)
627
+ const sortByMatch = expr.match(/^sort_by\(\.(\w+)\)$/);
628
+ if (sortByMatch) {
629
+ if (!Array.isArray(data))
630
+ throw new JqError('sort_by requires an array');
631
+ const key = sortByMatch[1];
632
+ return [...data].sort((a, b) => {
633
+ const aVal = a?.[key];
634
+ const bVal = b?.[key];
635
+ if (typeof aVal === 'number' && typeof bVal === 'number')
636
+ return aVal - bVal;
637
+ return String(aVal ?? '').localeCompare(String(bVal ?? ''));
638
+ });
639
+ }
640
+ // map(expr)
641
+ const mapMatch = expr.match(/^map\((.+)\)$/);
642
+ if (mapMatch) {
643
+ if (!Array.isArray(data))
644
+ throw new JqError('map requires an array');
645
+ const innerExpr = mapMatch[1];
646
+ // Handle select inside map - filter out undefined results
647
+ const results = [];
648
+ for (const item of data) {
649
+ const result = this.evaluate(innerExpr, item, context);
650
+ if (result !== undefined) {
651
+ results.push(result);
652
+ }
653
+ }
654
+ return results;
655
+ }
656
+ // select(condition)
657
+ const selectMatch = expr.match(/^select\((.+)\)$/);
658
+ if (selectMatch) {
659
+ if (this.evaluateCondition(selectMatch[1], data, context)) {
660
+ return data;
661
+ }
662
+ return undefined;
663
+ }
664
+ // has("key")
665
+ const hasMatch = expr.match(/^has\("([^"]+)"\)$/) || expr.match(/^has\(\\"([^"]+)\\"\)$/);
666
+ if (hasMatch) {
667
+ if (data && typeof data === 'object') {
668
+ return hasMatch[1] in data;
669
+ }
670
+ return false;
671
+ }
672
+ // split("delimiter")
673
+ const splitMatch = expr.match(/^split\("([^"]*)"\)$/) || expr.match(/^split\(\\"([^"]*)\\"\)$/);
674
+ if (splitMatch) {
675
+ if (typeof data !== 'string')
676
+ throw new JqError('split requires a string');
677
+ return data.split(splitMatch[1]);
678
+ }
679
+ // join("delimiter")
680
+ const joinMatch = expr.match(/^join\("([^"]*)"\)$/) || expr.match(/^join\(\\"([^"]*)\\"\)$/);
681
+ if (joinMatch) {
682
+ if (!Array.isArray(data))
683
+ throw new JqError('join requires an array');
684
+ return data.join(joinMatch[1]);
685
+ }
686
+ // test("pattern")
687
+ const testMatch = expr.match(/^test\("([^"]+)"\)$/) || expr.match(/^test\(\\"([^"]+)\\"\)$/);
688
+ if (testMatch) {
689
+ if (typeof data !== 'string')
690
+ throw new JqError('test requires a string');
691
+ return new RegExp(testMatch[1]).test(data);
692
+ }
693
+ return NOT_A_BUILTIN;
694
+ }
695
+ /**
696
+ * Get unique values from array
697
+ */
698
+ uniqueArray(data) {
699
+ const seen = new Set();
700
+ return data.filter((item) => {
701
+ const key = JSON.stringify(item);
702
+ if (seen.has(key))
703
+ return false;
704
+ seen.add(key);
705
+ return true;
706
+ });
707
+ }
708
+ /**
709
+ * Add array elements (numbers, strings, arrays, or objects)
710
+ */
711
+ addArray(data) {
712
+ if (data.length === 0)
713
+ return null;
714
+ if (typeof data[0] === 'number') {
715
+ return data.reduce((a, b) => a + b, 0);
716
+ }
717
+ if (typeof data[0] === 'string') {
718
+ return data.join('');
719
+ }
720
+ if (Array.isArray(data[0])) {
721
+ return data.flat(1);
722
+ }
723
+ return data.reduce((a, b) => ({ ...a, ...b }), {});
724
+ }
725
+ /**
726
+ * Handle alternative operator (expr // default)
727
+ */
728
+ handleAlternative(expr, data, context) {
729
+ const [primary, fallback] = expr.split(' // ');
730
+ try {
731
+ const result = this.evaluate(primary.trim(), data, context);
732
+ if (result === null || result === undefined) {
733
+ return this.evaluate(fallback.trim(), data, context);
734
+ }
735
+ return result;
736
+ }
737
+ catch {
738
+ return this.evaluate(fallback.trim(), data, context);
739
+ }
740
+ }
741
+ /**
742
+ * Handle if-then-else conditional
743
+ */
744
+ handleConditional(match, data, context) {
745
+ const condition = match[1];
746
+ const thenExpr = match[2];
747
+ const elseExpr = match[3];
748
+ if (this.evaluateCondition(condition, data, context)) {
749
+ return this.evaluate(thenExpr, data, context);
750
+ }
751
+ return this.evaluate(elseExpr, data, context);
752
+ }
753
+ /**
754
+ * Handle try-catch expression
755
+ */
756
+ handleTryCatch(match, data, context) {
757
+ try {
758
+ return this.evaluate(match[1], data, context);
759
+ }
760
+ catch {
761
+ const catchExpr = match[2].trim();
762
+ if (catchExpr.startsWith('"') && catchExpr.endsWith('"')) {
763
+ return catchExpr.slice(1, -1);
764
+ }
765
+ if (catchExpr.startsWith('\\"') && catchExpr.endsWith('\\"')) {
766
+ return catchExpr.slice(2, -2);
767
+ }
768
+ return this.evaluate(catchExpr, data, context);
769
+ }
770
+ }
771
+ /**
772
+ * Handle literal values (strings, numbers, booleans, null)
773
+ */
774
+ handleLiteral(expr) {
775
+ // String literal
776
+ if ((expr.startsWith('"') && expr.endsWith('"')) || (expr.startsWith('\\"') && expr.endsWith('\\"'))) {
777
+ return expr.startsWith('\\"') ? expr.slice(2, -2) : expr.slice(1, -1);
778
+ }
779
+ // Number literal
780
+ if (/^-?\d+(\.\d+)?$/.test(expr)) {
781
+ return parseFloat(expr);
782
+ }
783
+ // Boolean and null literals
784
+ if (expr === 'true')
785
+ return true;
786
+ if (expr === 'false')
787
+ return false;
788
+ if (expr === 'null')
789
+ return null;
790
+ return NOT_A_BUILTIN;
791
+ }
792
+ /**
793
+ * Evaluate a condition expression for select/if-then-else
794
+ */
795
+ evaluateCondition(condition, data, context) {
796
+ const trimmed = condition.trim();
797
+ // Handle compound conditions (and/or)
798
+ if (trimmed.includes(' and ')) {
799
+ const parts = trimmed.split(' and ');
800
+ return parts.every((part) => this.evaluateCondition(part.trim(), data, context));
801
+ }
802
+ if (trimmed.includes(' or ')) {
803
+ const parts = trimmed.split(' or ');
804
+ return parts.some((part) => this.evaluateCondition(part.trim(), data, context));
805
+ }
806
+ // Comparison operators
807
+ const compMatch = trimmed.match(/^(.+?)\s*(>=|<=|>|<|==|!=)\s*(.+)$/);
808
+ if (compMatch) {
809
+ return this.evaluateComparison(compMatch, data, context);
810
+ }
811
+ // Truthy check for path expressions
812
+ if (trimmed.startsWith('.')) {
813
+ const value = this.evaluate(trimmed, data, context);
814
+ return Boolean(value);
815
+ }
816
+ // has("key") condition
817
+ const hasCondMatch = trimmed.match(/^has\("([^"]+)"\)$/) || trimmed.match(/^has\(\\"([^"]+)\\"\)$/);
818
+ if (hasCondMatch) {
819
+ const hasKey = data && typeof data === 'object' && hasCondMatch[1] in data;
820
+ return hasKey;
821
+ }
822
+ return false;
823
+ }
824
+ /**
825
+ * Evaluate comparison expression
826
+ */
827
+ evaluateComparison(match, data, context) {
828
+ const left = this.evaluate(match[1].trim(), data, context);
829
+ const op = match[2];
830
+ let right = match[3].trim();
831
+ // Parse right side
832
+ if (/^-?\d+(\.\d+)?$/.test(right)) {
833
+ right = parseFloat(right);
834
+ }
835
+ else if (right.startsWith('$')) {
836
+ const varName = right.slice(1);
837
+ right = context.argjson[varName] ?? context.vars[varName];
838
+ }
839
+ else if (right.startsWith('.')) {
840
+ right = this.evaluate(right, data, context);
841
+ }
842
+ else if (right.startsWith('"') && right.endsWith('"')) {
843
+ right = right.slice(1, -1);
844
+ }
845
+ switch (op) {
846
+ case '>':
847
+ return left > right;
848
+ case '<':
849
+ return left < right;
850
+ case '>=':
851
+ return left >= right;
852
+ case '<=':
853
+ return left <= right;
854
+ case '==':
855
+ return left === right;
856
+ case '!=':
857
+ return left !== right;
858
+ default:
859
+ return false;
860
+ }
861
+ }
862
+ /**
863
+ * Construct an object from jq object syntax ({key, newKey: .expr})
864
+ */
865
+ constructObject(expr, data, context) {
866
+ const inner = expr.slice(1, -1).trim();
867
+ const result = {};
868
+ const pairs = this.parseObjectPairs(inner);
869
+ for (const pair of pairs) {
870
+ // Shorthand: key (same as key: .key)
871
+ if (/^\w+$/.test(pair)) {
872
+ result[pair] = data?.[pair];
873
+ continue;
874
+ }
875
+ // Full syntax: newKey: .expr or newKey: "value"
876
+ const colonIdx = pair.indexOf(':');
877
+ if (colonIdx > 0) {
878
+ const key = pair.slice(0, colonIdx).trim();
879
+ const valueExpr = pair.slice(colonIdx + 1).trim();
880
+ if (valueExpr.startsWith('\\"') && valueExpr.endsWith('\\"')) {
881
+ result[key] = valueExpr.slice(2, -2);
882
+ }
883
+ else if (valueExpr.startsWith('"') && valueExpr.endsWith('"')) {
884
+ result[key] = valueExpr.slice(1, -1);
885
+ }
886
+ else {
887
+ result[key] = this.evaluate(valueExpr, data, context);
888
+ }
889
+ }
890
+ }
891
+ return result;
892
+ }
893
+ /**
894
+ * Parse object key-value pairs, handling nested structures
895
+ */
896
+ parseObjectPairs(inner) {
897
+ const pairs = [];
898
+ let current = '';
899
+ let depth = 0;
900
+ let inString = false;
901
+ for (let i = 0; i < inner.length; i++) {
902
+ const char = inner[i];
903
+ if (char === '"' && inner[i - 1] !== '\\') {
904
+ inString = !inString;
905
+ }
906
+ if (!inString) {
907
+ if (char === '{' || char === '[')
908
+ depth++;
909
+ else if (char === '}' || char === ']')
910
+ depth--;
911
+ else if (char === ',' && depth === 0) {
912
+ pairs.push(current.trim());
913
+ current = '';
914
+ continue;
915
+ }
916
+ }
917
+ current += char;
918
+ }
919
+ if (current.trim()) {
920
+ pairs.push(current.trim());
921
+ }
922
+ return pairs;
923
+ }
924
+ /**
925
+ * Get value at a dot-separated path
926
+ */
927
+ getPath(data, path) {
928
+ const parts = path.split('.');
929
+ let current = data;
930
+ for (const part of parts) {
931
+ if (current === null || current === undefined) {
932
+ return null;
933
+ }
934
+ if (typeof current !== 'object') {
935
+ return null;
936
+ }
937
+ current = current[part];
938
+ }
939
+ return current === undefined ? null : current;
940
+ }
941
+ /**
942
+ * Format jq output based on options
943
+ */
944
+ formatOutput(result, options, isIteratorResult = false) {
945
+ // Filter out undefined values
946
+ if (Array.isArray(result) && result.some((r) => r === undefined)) {
947
+ result = result.filter((r) => r !== undefined);
948
+ }
949
+ // Handle undefined
950
+ if (result === undefined) {
951
+ return '';
952
+ }
953
+ // Handle empty iterator result
954
+ if (isIteratorResult && Array.isArray(result) && result.length === 0) {
955
+ return '';
956
+ }
957
+ // Iterator output - each result on its own line
958
+ if (isIteratorResult && Array.isArray(result)) {
959
+ if (options.tab) {
960
+ return result
961
+ .map((item) => {
962
+ if (typeof item === 'string')
963
+ return options.raw ? item : JSON.stringify(item);
964
+ return JSON.stringify(item);
965
+ })
966
+ .join('\n') + '\n';
967
+ }
968
+ return result
969
+ .map((item) => {
970
+ if (options.raw && typeof item === 'string')
971
+ return item;
972
+ return options.compact ? JSON.stringify(item) : JSON.stringify(item, null, 2);
973
+ })
974
+ .join('\n') + '\n';
975
+ }
976
+ // Raw output for strings
977
+ if (options.raw && typeof result === 'string') {
978
+ return result + '\n';
979
+ }
980
+ // Normal JSON output
981
+ const formatted = options.compact ? JSON.stringify(result) : JSON.stringify(result, null, 2);
982
+ return formatted + '\n';
983
+ }
984
+ /**
985
+ * Clear the parsed JSON cache
986
+ */
987
+ clearCache() {
988
+ this.cachedInput = null;
989
+ this.cachedData = null;
990
+ }
991
+ }
992
+ // Global JqEngine instance for simple usage
993
+ const defaultJqEngine = new JqEngine();
994
+ /**
995
+ * Execute a jq query on JSON input
996
+ *
997
+ * This is the main entry point for jq functionality. For repeated queries
998
+ * on the same input, consider using JqEngine directly for better caching.
999
+ *
1000
+ * @param query - The jq query expression
1001
+ * @param input - JSON input string
1002
+ * @param options - Execution options
1003
+ * @returns Query result as string
1004
+ * @throws {JqError} On invalid JSON or query syntax errors
1005
+ *
1006
+ * @example
1007
+ * ```typescript
1008
+ * // Simple key extraction
1009
+ * executeJq('.name', '{"name": "test"}')
1010
+ * // => '"test"\n'
1011
+ *
1012
+ * // Filter array
1013
+ * executeJq('.[] | select(.age > 18)', '[{"age": 25}, {"age": 17}]')
1014
+ * ```
1015
+ */
1016
+ export function executeJq(query, input, options = {}) {
1017
+ return defaultJqEngine.execute(query, input, options);
1018
+ }
1019
+ /**
1020
+ * Parse a YAML string into a JavaScript value
1021
+ *
1022
+ * Supports a subset of YAML including:
1023
+ * - Key-value pairs
1024
+ * - Nested objects
1025
+ * - Arrays (both block and inline)
1026
+ * - Anchors and aliases
1027
+ * - Multi-document files
1028
+ * - Basic scalar types (strings, numbers, booleans, null)
1029
+ *
1030
+ * @param input - YAML input string
1031
+ * @returns Parsed JavaScript value
1032
+ * @throws {Error} On invalid YAML syntax
1033
+ *
1034
+ * @example
1035
+ * ```typescript
1036
+ * parseYaml('name: bashx\nversion: 1.0.0')
1037
+ * // => { name: 'bashx', version: '1.0.0' }
1038
+ * ```
1039
+ */
1040
+ export function parseYaml(input) {
1041
+ const lines = input.split('\n');
1042
+ const docs = [];
1043
+ let currentDocLines = [];
1044
+ for (const line of lines) {
1045
+ if (line === '---') {
1046
+ if (currentDocLines.length > 0) {
1047
+ docs.push(parseYamlDocument(currentDocLines));
1048
+ currentDocLines = [];
1049
+ }
1050
+ }
1051
+ else {
1052
+ currentDocLines.push(line);
1053
+ }
1054
+ }
1055
+ if (currentDocLines.length > 0 || docs.length === 0) {
1056
+ docs.push(parseYamlDocument(currentDocLines));
1057
+ }
1058
+ return docs.length === 1 ? docs[0] : docs;
1059
+ }
1060
+ /**
1061
+ * Parse a single YAML document
1062
+ */
1063
+ function parseYamlDocument(lines) {
1064
+ const anchors = {};
1065
+ return parseYamlLines(lines, 0, anchors).value;
1066
+ }
1067
+ /**
1068
+ * Parse YAML lines at a given indentation level
1069
+ */
1070
+ function parseYamlLines(lines, startIndent, anchors) {
1071
+ const result = {};
1072
+ let i = 0;
1073
+ while (i < lines.length) {
1074
+ const line = lines[i];
1075
+ // Skip empty lines and comments
1076
+ if (!line.trim() || line.trim().startsWith('#')) {
1077
+ i++;
1078
+ continue;
1079
+ }
1080
+ const indent = line.search(/\S/);
1081
+ if (indent < startIndent) {
1082
+ break;
1083
+ }
1084
+ const content = line.trim();
1085
+ // Handle list item
1086
+ if (content.startsWith('- ')) {
1087
+ const arr = [];
1088
+ while (i < lines.length) {
1089
+ const listLine = lines[i];
1090
+ if (!listLine.trim() || listLine.trim().startsWith('#')) {
1091
+ i++;
1092
+ continue;
1093
+ }
1094
+ const listIndent = listLine.search(/\S/);
1095
+ if (listIndent < startIndent || !listLine.trim().startsWith('-')) {
1096
+ break;
1097
+ }
1098
+ const itemContent = listLine.trim().slice(2).trim();
1099
+ arr.push(parseYamlValue(itemContent, anchors));
1100
+ i++;
1101
+ }
1102
+ return { value: arr, consumed: i };
1103
+ }
1104
+ // Handle key: value
1105
+ const colonIdx = content.indexOf(':');
1106
+ if (colonIdx > 0) {
1107
+ const key = content.slice(0, colonIdx).trim();
1108
+ let valueStr = content.slice(colonIdx + 1).trim();
1109
+ // Handle anchor definition: &anchorName
1110
+ let anchorName = null;
1111
+ const anchorMatch = valueStr.match(/^&(\w+)\s*/);
1112
+ if (anchorMatch) {
1113
+ anchorName = anchorMatch[1];
1114
+ valueStr = valueStr.slice(anchorMatch[0].length);
1115
+ }
1116
+ // Handle merge: <<: *anchorName
1117
+ if (key === '<<') {
1118
+ const mergeAliasMatch = valueStr.match(/^\*(\w+)$/);
1119
+ if (mergeAliasMatch) {
1120
+ const merged = anchors[mergeAliasMatch[1]];
1121
+ if (merged && typeof merged === 'object') {
1122
+ Object.assign(result, merged);
1123
+ }
1124
+ }
1125
+ i++;
1126
+ continue;
1127
+ }
1128
+ // Handle alias: *anchorName
1129
+ const aliasMatch = valueStr.match(/^\*(\w+)$/);
1130
+ if (aliasMatch) {
1131
+ result[key] = anchors[aliasMatch[1]];
1132
+ i++;
1133
+ continue;
1134
+ }
1135
+ if (valueStr) {
1136
+ // Inline value
1137
+ const value = parseYamlValue(valueStr, anchors);
1138
+ if (anchorName) {
1139
+ anchors[anchorName] = value;
1140
+ }
1141
+ result[key] = value;
1142
+ i++;
1143
+ }
1144
+ else {
1145
+ // Nested structure
1146
+ i++;
1147
+ const nextIndent = i < lines.length ? lines[i].search(/\S/) : 0;
1148
+ if (nextIndent > indent) {
1149
+ const nested = parseYamlLines(lines.slice(i), nextIndent, anchors);
1150
+ if (anchorName) {
1151
+ anchors[anchorName] = nested.value;
1152
+ }
1153
+ result[key] = nested.value;
1154
+ i += nested.consumed;
1155
+ }
1156
+ else {
1157
+ result[key] = null;
1158
+ }
1159
+ }
1160
+ }
1161
+ else {
1162
+ i++;
1163
+ }
1164
+ }
1165
+ return { value: result, consumed: i };
1166
+ }
1167
+ /**
1168
+ * Parse a single YAML value
1169
+ */
1170
+ function parseYamlValue(str, anchors) {
1171
+ const trimmed = str.trim();
1172
+ // Handle anchor reference
1173
+ if (trimmed.startsWith('*')) {
1174
+ return anchors[trimmed.slice(1)];
1175
+ }
1176
+ // Handle quoted strings
1177
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
1178
+ return trimmed.slice(1, -1);
1179
+ }
1180
+ // Detect unclosed quotes - invalid YAML
1181
+ if ((trimmed.startsWith('"') && !trimmed.endsWith('"')) ||
1182
+ (trimmed.startsWith("'") && !trimmed.endsWith("'"))) {
1183
+ throw new Error(`Unclosed quote in YAML value: ${trimmed}`);
1184
+ }
1185
+ // Handle inline array
1186
+ if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
1187
+ const inner = trimmed.slice(1, -1);
1188
+ if (!inner.trim())
1189
+ return [];
1190
+ return inner.split(',').map((s) => parseYamlValue(s.trim(), anchors));
1191
+ }
1192
+ // Detect unclosed bracket - invalid YAML
1193
+ if (trimmed.startsWith('[') && !trimmed.endsWith(']')) {
1194
+ throw new Error(`Unclosed bracket in YAML value: ${trimmed}`);
1195
+ }
1196
+ // Handle inline object
1197
+ if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
1198
+ const inner = trimmed.slice(1, -1);
1199
+ if (!inner.trim())
1200
+ return {};
1201
+ const obj = {};
1202
+ const pairs = inner.split(',');
1203
+ for (const pair of pairs) {
1204
+ const [k, v] = pair.split(':').map((s) => s.trim());
1205
+ if (k && v !== undefined) {
1206
+ obj[k] = parseYamlValue(v, anchors);
1207
+ }
1208
+ }
1209
+ return obj;
1210
+ }
1211
+ // Detect unclosed brace - invalid YAML
1212
+ if (trimmed.startsWith('{') && !trimmed.endsWith('}')) {
1213
+ throw new Error(`Unclosed brace in YAML value: ${trimmed}`);
1214
+ }
1215
+ // Handle numbers
1216
+ if (/^-?\d+$/.test(trimmed)) {
1217
+ return parseInt(trimmed, 10);
1218
+ }
1219
+ if (/^-?\d+\.\d+$/.test(trimmed)) {
1220
+ return parseFloat(trimmed);
1221
+ }
1222
+ // Handle booleans
1223
+ if (trimmed === 'true' || trimmed === 'yes' || trimmed === 'on') {
1224
+ return true;
1225
+ }
1226
+ if (trimmed === 'false' || trimmed === 'no' || trimmed === 'off') {
1227
+ return false;
1228
+ }
1229
+ // Handle null
1230
+ if (trimmed === 'null' || trimmed === '~' || trimmed === '') {
1231
+ return null;
1232
+ }
1233
+ // Plain string
1234
+ return trimmed;
1235
+ }
1236
+ /**
1237
+ * Convert a JavaScript value to YAML format
1238
+ *
1239
+ * @param data - Value to stringify
1240
+ * @param indent - Current indentation level
1241
+ * @returns YAML string representation
1242
+ *
1243
+ * @example
1244
+ * ```typescript
1245
+ * stringifyYaml({ name: 'bashx', version: '1.0.0' })
1246
+ * // => 'name: bashx\nversion: 1.0.0'
1247
+ * ```
1248
+ */
1249
+ export function stringifyYaml(data, indent = 0) {
1250
+ const prefix = ' '.repeat(indent);
1251
+ if (data === null || data === undefined) {
1252
+ return 'null';
1253
+ }
1254
+ if (typeof data === 'string') {
1255
+ // Quote if contains special characters
1256
+ if (/[:\[\]{}"'#|>&*!?]/.test(data) || /^\s|\s$/.test(data)) {
1257
+ return JSON.stringify(data);
1258
+ }
1259
+ return data;
1260
+ }
1261
+ if (typeof data === 'number' || typeof data === 'boolean') {
1262
+ return String(data);
1263
+ }
1264
+ if (Array.isArray(data)) {
1265
+ if (data.length === 0)
1266
+ return '[]';
1267
+ return data.map((item) => `${prefix}- ${stringifyYaml(item, indent + 1).trimStart()}`).join('\n');
1268
+ }
1269
+ if (typeof data === 'object') {
1270
+ const entries = Object.entries(data);
1271
+ if (entries.length === 0)
1272
+ return '{}';
1273
+ return entries
1274
+ .map(([key, value]) => {
1275
+ if (value && typeof value === 'object') {
1276
+ return `${prefix}${key}:\n${stringifyYaml(value, indent + 1)}`;
1277
+ }
1278
+ return `${prefix}${key}: ${stringifyYaml(value, indent)}`;
1279
+ })
1280
+ .join('\n');
1281
+ }
1282
+ return String(data);
1283
+ }
1284
+ /**
1285
+ * Execute yq command on YAML input
1286
+ *
1287
+ * @param query - The yq query expression
1288
+ * @param input - YAML input string
1289
+ * @param options - Execution options
1290
+ * @returns Query result as formatted string
1291
+ * @throws {Error} On invalid YAML or query errors
1292
+ *
1293
+ * @example
1294
+ * ```typescript
1295
+ * executeYq('.name', 'name: bashx\nversion: 1.0.0')
1296
+ * // => 'bashx\n'
1297
+ *
1298
+ * executeYq('.', 'name: bashx', { output: 'json' })
1299
+ * // => '{"name":"bashx"}\n'
1300
+ * ```
1301
+ */
1302
+ export function executeYq(query, input, options = {}) {
1303
+ // Parse YAML
1304
+ let data;
1305
+ try {
1306
+ data = parseYaml(input);
1307
+ }
1308
+ catch (e) {
1309
+ throw new Error(`YAML parse error: ${e instanceof Error ? e.message : String(e)}`);
1310
+ }
1311
+ // Handle multi-document queries
1312
+ const docs = Array.isArray(data) && input.includes('---') ? data : [data];
1313
+ // Process query
1314
+ let result;
1315
+ // Handle eval-all
1316
+ if (query.startsWith('eval-all ')) {
1317
+ query = query.slice(9).trim();
1318
+ }
1319
+ // Handle document_index selection
1320
+ const docIndexMatch = query.match(/select\(document_index\s*==\s*(\d+)\)/);
1321
+ if (docIndexMatch) {
1322
+ result = docs[parseInt(docIndexMatch[1], 10)];
1323
+ }
1324
+ else if (query === '.') {
1325
+ result = docs.length === 1 ? docs[0] : docs;
1326
+ }
1327
+ else if (query.startsWith('.') && query.includes(' = ')) {
1328
+ // Assignment
1329
+ const [path, valueExpr] = query.split(' = ');
1330
+ const pathParts = path.slice(1).split('.');
1331
+ const value = parseYamlValue(valueExpr.replace(/^\\?"/, '').replace(/\\?"$/, ''), {});
1332
+ result = setPath(docs[0], pathParts, value);
1333
+ }
1334
+ else if (query.startsWith('del(')) {
1335
+ // Deletion
1336
+ const pathMatch = query.match(/del\(\.(\w+)\)/);
1337
+ if (pathMatch) {
1338
+ const obj = { ...docs[0] };
1339
+ delete obj[pathMatch[1]];
1340
+ result = obj;
1341
+ }
1342
+ else {
1343
+ result = docs[0];
1344
+ }
1345
+ }
1346
+ else if (query.startsWith('explode(')) {
1347
+ // Explode anchors (already expanded during parse)
1348
+ result = docs[0];
1349
+ }
1350
+ else if (query.includes(' += ')) {
1351
+ // Append to array
1352
+ const [path, valueExpr] = query.split(' += ');
1353
+ const pathParts = path.slice(1).split('.');
1354
+ const arr = getPath(docs[0], path.slice(1));
1355
+ const newItems = JSON.parse(valueExpr.replace(/\\"/g, '"'));
1356
+ result = setPath(docs[0], pathParts, [...arr, ...newItems]);
1357
+ }
1358
+ else {
1359
+ // Use jq-style evaluation
1360
+ result = defaultJqEngine.evaluate(query, docs[0], { vars: {}, argjson: {} });
1361
+ }
1362
+ // Format output
1363
+ if (options.output === 'json') {
1364
+ return options.compact ? JSON.stringify(result) + '\n' : JSON.stringify(result, null, 2) + '\n';
1365
+ }
1366
+ if (options.output === 'props') {
1367
+ return formatAsProps(result);
1368
+ }
1369
+ if (options.output === 'csv') {
1370
+ return formatAsCsv(result);
1371
+ }
1372
+ // Default YAML output
1373
+ if (typeof result === 'string' || typeof result === 'number' || typeof result === 'boolean') {
1374
+ return String(result) + '\n';
1375
+ }
1376
+ return stringifyYaml(result) + '\n';
1377
+ }
1378
+ /**
1379
+ * Get value at a dot-separated path (for yq)
1380
+ */
1381
+ function getPath(data, path) {
1382
+ const parts = path.split('.');
1383
+ let current = data;
1384
+ for (const part of parts) {
1385
+ if (current === null || current === undefined) {
1386
+ return null;
1387
+ }
1388
+ if (typeof current !== 'object') {
1389
+ return null;
1390
+ }
1391
+ current = current[part];
1392
+ }
1393
+ return current === undefined ? null : current;
1394
+ }
1395
+ /**
1396
+ * Set value at path in object (for yq mutations)
1397
+ */
1398
+ function setPath(obj, path, value) {
1399
+ if (path.length === 0)
1400
+ return value;
1401
+ const result = { ...obj };
1402
+ const [head, ...rest] = path;
1403
+ if (rest.length === 0) {
1404
+ result[head] = value;
1405
+ }
1406
+ else {
1407
+ result[head] = setPath(result[head], rest, value);
1408
+ }
1409
+ return result;
1410
+ }
1411
+ /**
1412
+ * Format data as properties file format
1413
+ */
1414
+ function formatAsProps(data, prefix = '') {
1415
+ const lines = [];
1416
+ if (data && typeof data === 'object' && !Array.isArray(data)) {
1417
+ for (const [key, value] of Object.entries(data)) {
1418
+ const path = prefix ? `${prefix}.${key}` : key;
1419
+ if (value && typeof value === 'object') {
1420
+ lines.push(formatAsProps(value, path));
1421
+ }
1422
+ else {
1423
+ lines.push(`${path} = ${value}`);
1424
+ }
1425
+ }
1426
+ }
1427
+ return lines.join('\n') + '\n';
1428
+ }
1429
+ /**
1430
+ * Format data as CSV
1431
+ */
1432
+ function formatAsCsv(data) {
1433
+ if (Array.isArray(data)) {
1434
+ return data.map((item) => (Array.isArray(item) ? item.join(',') : String(item))).join('\n') + '\n';
1435
+ }
1436
+ if (data && typeof data === 'object') {
1437
+ const obj = data;
1438
+ const keys = Object.keys(obj);
1439
+ const values = Object.values(obj);
1440
+ return keys.join(',') + '\n' + values.join(',') + '\n';
1441
+ }
1442
+ return String(data) + '\n';
1443
+ }
1444
+ /**
1445
+ * Custom error for base64 encoding/decoding errors
1446
+ */
1447
+ export class Base64Error extends Error {
1448
+ constructor(message) {
1449
+ super(message);
1450
+ this.name = 'Base64Error';
1451
+ }
1452
+ }
1453
+ /**
1454
+ * Execute base64 encoding or decoding
1455
+ *
1456
+ * @param input - Input string to encode/decode
1457
+ * @param options - Encoding/decoding options
1458
+ * @returns Encoded or decoded string
1459
+ * @throws {Base64Error} On invalid base64 input during decoding
1460
+ *
1461
+ * @example
1462
+ * ```typescript
1463
+ * // Encode
1464
+ * executeBase64('Hello, World!')
1465
+ * // => 'SGVsbG8sIFdvcmxkIQ==\n'
1466
+ *
1467
+ * // Decode
1468
+ * executeBase64('SGVsbG8sIFdvcmxkIQ==', { decode: true })
1469
+ * // => 'Hello, World!'
1470
+ * ```
1471
+ */
1472
+ export function executeBase64(input, options = {}) {
1473
+ if (options.decode) {
1474
+ return decodeBase64(input, options);
1475
+ }
1476
+ return encodeBase64(input, options);
1477
+ }
1478
+ /**
1479
+ * Encode string to base64
1480
+ */
1481
+ function encodeBase64(input, options) {
1482
+ let encoded;
1483
+ if (options.urlSafe) {
1484
+ // URL-safe base64
1485
+ encoded = btoa(input).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
1486
+ }
1487
+ else {
1488
+ encoded = btoa(input);
1489
+ }
1490
+ // Apply line wrapping
1491
+ const wrap = options.wrap ?? 76;
1492
+ if (wrap > 0 && encoded.length > wrap) {
1493
+ const lines = [];
1494
+ for (let i = 0; i < encoded.length; i += wrap) {
1495
+ lines.push(encoded.slice(i, i + wrap));
1496
+ }
1497
+ return lines.join('\n') + '\n';
1498
+ }
1499
+ return encoded + '\n';
1500
+ }
1501
+ /**
1502
+ * Decode base64 string
1503
+ */
1504
+ function decodeBase64(input, options) {
1505
+ let cleaned = input.replace(/\s/g, '');
1506
+ if (options.ignoreGarbage) {
1507
+ if (options.urlSafe) {
1508
+ cleaned = cleaned.replace(/[^A-Za-z0-9\-_=]/g, '');
1509
+ }
1510
+ else {
1511
+ cleaned = cleaned.replace(/[^A-Za-z0-9+/=]/g, '');
1512
+ }
1513
+ // For standard base64, truncate at padding
1514
+ if (!options.urlSafe) {
1515
+ const paddingMatch = cleaned.match(/^[A-Za-z0-9+/]*(={0,2})/);
1516
+ if (paddingMatch) {
1517
+ cleaned = paddingMatch[0];
1518
+ }
1519
+ }
1520
+ }
1521
+ if (options.urlSafe) {
1522
+ cleaned = cleaned.replace(/-/g, '+').replace(/_/g, '/');
1523
+ while (cleaned.length % 4 !== 0) {
1524
+ cleaned += '=';
1525
+ }
1526
+ }
1527
+ // Validate base64
1528
+ if (!options.ignoreGarbage && !options.urlSafe && !/^[A-Za-z0-9+/]*={0,2}$/.test(cleaned)) {
1529
+ throw new Base64Error('invalid base64 input');
1530
+ }
1531
+ try {
1532
+ return atob(cleaned);
1533
+ }
1534
+ catch {
1535
+ if (options.urlSafe) {
1536
+ return '';
1537
+ }
1538
+ throw new Base64Error('invalid base64 input');
1539
+ }
1540
+ }
1541
+ /**
1542
+ * Custom error for envsubst errors (e.g., required variable missing)
1543
+ */
1544
+ export class EnvsubstError extends Error {
1545
+ constructor(message) {
1546
+ super(message);
1547
+ this.name = 'EnvsubstError';
1548
+ }
1549
+ }
1550
+ /**
1551
+ * Execute environment variable substitution
1552
+ *
1553
+ * Supports:
1554
+ * - $VAR and ${VAR} syntax
1555
+ * - ${VAR:-default} - use default if unset/empty
1556
+ * - ${VAR:+alternate} - use alternate if set and non-empty
1557
+ * - ${VAR:?error} - error if unset/empty
1558
+ * - ${VAR:=default} - use default if unset/empty (assignment)
1559
+ * - $$ escape sequence for literal $
1560
+ *
1561
+ * @param template - Template string with variable references
1562
+ * @param options - Substitution options including env vars
1563
+ * @returns Substituted string
1564
+ * @throws {EnvsubstError} On ${VAR:?error} with missing variable
1565
+ *
1566
+ * @example
1567
+ * ```typescript
1568
+ * executeEnvsubst('Hello, $NAME!', { env: { NAME: 'World' } })
1569
+ * // => 'Hello, World!'
1570
+ *
1571
+ * executeEnvsubst('${VAR:-default}', { env: {} })
1572
+ * // => 'default'
1573
+ * ```
1574
+ */
1575
+ export function executeEnvsubst(template, options) {
1576
+ const { env, variables, listVariables } = options;
1577
+ if (listVariables) {
1578
+ const vars = extractVariables(template);
1579
+ return vars.join('\n') + '\n';
1580
+ }
1581
+ return substituteVariables(template, env, variables);
1582
+ }
1583
+ /**
1584
+ * Extract variable names from template
1585
+ */
1586
+ function extractVariables(template) {
1587
+ const vars = new Set();
1588
+ const bracedPattern = /\$\{([A-Z_][A-Z0-9_]*)(:[^}]+)?\}/gi;
1589
+ const simplePattern = /\$([A-Z_][A-Z0-9_]*)/gi;
1590
+ let match;
1591
+ while ((match = bracedPattern.exec(template)) !== null) {
1592
+ vars.add(match[1]);
1593
+ }
1594
+ while ((match = simplePattern.exec(template)) !== null) {
1595
+ vars.add(match[1]);
1596
+ }
1597
+ return Array.from(vars);
1598
+ }
1599
+ /**
1600
+ * Substitute variables in template
1601
+ */
1602
+ function substituteVariables(template, env, onlyVars) {
1603
+ let result = template;
1604
+ // Handle escaped dollar signs: $$ -> $
1605
+ result = result.replace(/\$\$/g, '\x00ESCAPED_DOLLAR\x00');
1606
+ // Handle ${VAR:modifier} patterns
1607
+ result = result.replace(/\$\{([A-Z_][A-Z0-9_]*)(:[^}]+)?\}/gi, (match, varName, modifier) => {
1608
+ if (onlyVars && !onlyVars.includes(varName)) {
1609
+ return match;
1610
+ }
1611
+ const value = env[varName];
1612
+ const isEmpty = value === undefined || value === '';
1613
+ if (modifier) {
1614
+ const modType = modifier.slice(1, 2);
1615
+ const modValue = modifier.slice(2);
1616
+ switch (modType) {
1617
+ case '-':
1618
+ return isEmpty ? modValue : value;
1619
+ case '+':
1620
+ return isEmpty ? '' : modValue;
1621
+ case '?':
1622
+ if (isEmpty) {
1623
+ throw new EnvsubstError(`${varName}: ${modValue}`);
1624
+ }
1625
+ return value;
1626
+ case '=':
1627
+ return isEmpty ? modValue : value;
1628
+ default:
1629
+ return value ?? '';
1630
+ }
1631
+ }
1632
+ return value ?? '';
1633
+ });
1634
+ // Handle simple $VAR patterns
1635
+ result = result.replace(/\$([A-Z_][A-Z0-9_]*)/gi, (match, varName) => {
1636
+ if (onlyVars && !onlyVars.includes(varName)) {
1637
+ return match;
1638
+ }
1639
+ return env[varName] ?? '';
1640
+ });
1641
+ // Restore escaped dollar signs
1642
+ result = result.replace(/\x00ESCAPED_DOLLAR\x00/g, '$');
1643
+ return result;
1644
+ }
1645
+ // ============================================================================
1646
+ // COMMAND PARSING HELPERS
1647
+ // ============================================================================
1648
+ /**
1649
+ * Parse jq command line arguments
1650
+ *
1651
+ * @param args - Array of command line arguments
1652
+ * @returns Parsed query, file path, and options
1653
+ *
1654
+ * @example
1655
+ * ```typescript
1656
+ * parseJqArgs(['-r', '.name', 'file.json'])
1657
+ * // => { query: '.name', file: 'file.json', options: { raw: true } }
1658
+ * ```
1659
+ */
1660
+ export function parseJqArgs(args) {
1661
+ const options = {
1662
+ args: {},
1663
+ argjson: {},
1664
+ };
1665
+ let query = '';
1666
+ let file;
1667
+ let i = 0;
1668
+ while (i < args.length) {
1669
+ const arg = args[i];
1670
+ if (arg === '-r' || arg === '--raw-output') {
1671
+ options.raw = true;
1672
+ }
1673
+ else if (arg === '-c' || arg === '--compact-output') {
1674
+ options.compact = true;
1675
+ }
1676
+ else if (arg === '-s' || arg === '--slurp') {
1677
+ options.slurp = true;
1678
+ }
1679
+ else if (arg === '-t' || arg === '--tab') {
1680
+ options.tab = true;
1681
+ }
1682
+ else if (arg === '--arg' && i + 2 < args.length) {
1683
+ const name = args[++i];
1684
+ const value = args[++i];
1685
+ options.args[name] = value;
1686
+ }
1687
+ else if (arg === '--argjson' && i + 2 < args.length) {
1688
+ const name = args[++i];
1689
+ const value = args[++i];
1690
+ options.argjson[name] = JSON.parse(value);
1691
+ }
1692
+ else if (!arg.startsWith('-') && !query) {
1693
+ query = arg;
1694
+ }
1695
+ else if (!arg.startsWith('-')) {
1696
+ file = arg;
1697
+ }
1698
+ i++;
1699
+ }
1700
+ return { query, file, options };
1701
+ }
1702
+ /**
1703
+ * Parse yq command line arguments
1704
+ *
1705
+ * @param args - Array of command line arguments
1706
+ * @returns Parsed query, file path, and options
1707
+ */
1708
+ export function parseYqArgs(args) {
1709
+ const options = {};
1710
+ let query = '';
1711
+ let file;
1712
+ let i = 0;
1713
+ while (i < args.length) {
1714
+ const arg = args[i];
1715
+ if (arg === '-o' && i + 1 < args.length) {
1716
+ const format = args[++i];
1717
+ if (format === 'json' || format === 'yaml' || format === 'props' || format === 'csv') {
1718
+ options.output = format;
1719
+ }
1720
+ }
1721
+ else if (arg === '-c' || arg === '--compact-output') {
1722
+ options.compact = true;
1723
+ }
1724
+ else if (arg === '-i' || arg === '--inplace') {
1725
+ options.inPlace = true;
1726
+ }
1727
+ else if (arg === 'eval-all') {
1728
+ query = 'eval-all ' + (args[i + 1] || '.');
1729
+ i++;
1730
+ }
1731
+ else if (!arg.startsWith('-') && !query) {
1732
+ query = arg;
1733
+ }
1734
+ else if (!arg.startsWith('-')) {
1735
+ file = arg;
1736
+ }
1737
+ i++;
1738
+ }
1739
+ return { query: query || '.', file, options };
1740
+ }
1741
+ /**
1742
+ * Parse base64 command line arguments
1743
+ *
1744
+ * @param args - Array of command line arguments
1745
+ * @returns Parsed file path and options
1746
+ */
1747
+ export function parseBase64Args(args) {
1748
+ const options = {};
1749
+ let file;
1750
+ let i = 0;
1751
+ while (i < args.length) {
1752
+ const arg = args[i];
1753
+ if (arg === '-d' || arg === '--decode' || arg === '-D') {
1754
+ options.decode = true;
1755
+ }
1756
+ else if (arg === '-w' && i + 1 < args.length) {
1757
+ options.wrap = parseInt(args[++i], 10);
1758
+ }
1759
+ else if (arg.startsWith('-w')) {
1760
+ options.wrap = parseInt(arg.slice(2), 10);
1761
+ }
1762
+ else if (arg === '-i' || arg === '--ignore-garbage') {
1763
+ options.ignoreGarbage = true;
1764
+ }
1765
+ else if (arg === '--url') {
1766
+ options.urlSafe = true;
1767
+ }
1768
+ else if (!arg.startsWith('-')) {
1769
+ file = arg;
1770
+ }
1771
+ i++;
1772
+ }
1773
+ return { file, options };
1774
+ }
1775
+ /**
1776
+ * Parse envsubst command line arguments
1777
+ *
1778
+ * @param args - Array of command line arguments
1779
+ * @param env - Environment variables
1780
+ * @returns Parsed options and input redirect path
1781
+ */
1782
+ export function parseEnvsubstArgs(args, env) {
1783
+ const options = { env };
1784
+ let inputRedirect;
1785
+ let i = 0;
1786
+ while (i < args.length) {
1787
+ const arg = args[i];
1788
+ if (arg === '--variables' || arg === '-v') {
1789
+ options.listVariables = true;
1790
+ }
1791
+ else if (arg === '<' && i + 1 < args.length) {
1792
+ inputRedirect = args[++i];
1793
+ }
1794
+ else if (arg.startsWith('$')) {
1795
+ options.variables = arg
1796
+ .split(/\s+/)
1797
+ .filter((v) => v.startsWith('$'))
1798
+ .map((v) => v.slice(1));
1799
+ }
1800
+ else if (!arg.startsWith('-')) {
1801
+ if (arg.includes('$')) {
1802
+ options.variables = arg
1803
+ .split(/\s+/)
1804
+ .filter((v) => v.startsWith('$'))
1805
+ .map((v) => v.slice(1));
1806
+ }
1807
+ }
1808
+ i++;
1809
+ }
1810
+ return { options, inputRedirect };
1811
+ }
1812
+ //# sourceMappingURL=data-processing.js.map