@pwfabric/runtime 0.0.0-stage → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/LICENSE +90 -0
  2. package/README.md +43 -2
  3. package/dist/a11y/announcer.d.ts +65 -0
  4. package/dist/a11y/announcer.js +140 -0
  5. package/dist/a11y/announcer.js.map +1 -0
  6. package/dist/a11y/contrast.d.ts +54 -0
  7. package/dist/a11y/contrast.js +93 -0
  8. package/dist/a11y/contrast.js.map +1 -0
  9. package/dist/a11y/focus.d.ts +123 -0
  10. package/dist/a11y/focus.js +282 -0
  11. package/dist/a11y/focus.js.map +1 -0
  12. package/dist/a11y/index.d.ts +21 -0
  13. package/dist/a11y/index.js +18 -0
  14. package/dist/a11y/index.js.map +1 -0
  15. package/dist/a11y/keyboard.d.ts +144 -0
  16. package/dist/a11y/keyboard.js +317 -0
  17. package/dist/a11y/keyboard.js.map +1 -0
  18. package/dist/adapters/default-image.d.ts +25 -0
  19. package/dist/adapters/default-image.js +37 -0
  20. package/dist/adapters/default-image.js.map +1 -0
  21. package/dist/adapters/index.d.ts +27 -0
  22. package/dist/adapters/index.js +28 -0
  23. package/dist/adapters/index.js.map +1 -0
  24. package/dist/adapters/next-image.d.ts +38 -0
  25. package/dist/adapters/next-image.js +124 -0
  26. package/dist/adapters/next-image.js.map +1 -0
  27. package/dist/adapters/types.d.ts +61 -0
  28. package/dist/adapters/types.js +11 -0
  29. package/dist/adapters/types.js.map +1 -0
  30. package/dist/analytics/index.d.ts +14 -0
  31. package/dist/analytics/index.js +15 -0
  32. package/dist/analytics/index.js.map +1 -0
  33. package/dist/analytics/tracker.d.ts +65 -0
  34. package/dist/analytics/tracker.js +251 -0
  35. package/dist/analytics/tracker.js.map +1 -0
  36. package/dist/analytics/types.d.ts +130 -0
  37. package/dist/analytics/types.js +11 -0
  38. package/dist/analytics/types.js.map +1 -0
  39. package/dist/auth/index.d.ts +15 -0
  40. package/dist/auth/index.js +14 -0
  41. package/dist/auth/index.js.map +1 -0
  42. package/dist/auth/provider.d.ts +132 -0
  43. package/dist/auth/provider.js +473 -0
  44. package/dist/auth/provider.js.map +1 -0
  45. package/dist/auth/types.d.ts +117 -0
  46. package/dist/auth/types.js +9 -0
  47. package/dist/auth/types.js.map +1 -0
  48. package/dist/binding/collection.d.ts +190 -0
  49. package/dist/binding/collection.js +358 -0
  50. package/dist/binding/collection.js.map +1 -0
  51. package/dist/binding/datasource.d.ts +319 -0
  52. package/dist/binding/datasource.js +556 -0
  53. package/dist/binding/datasource.js.map +1 -0
  54. package/dist/binding/engine.d.ts +65 -0
  55. package/dist/binding/engine.js +268 -0
  56. package/dist/binding/engine.js.map +1 -0
  57. package/dist/binding/expression.d.ts +150 -0
  58. package/dist/binding/expression.js +787 -0
  59. package/dist/binding/expression.js.map +1 -0
  60. package/dist/binding/index.d.ts +19 -0
  61. package/dist/binding/index.js +14 -0
  62. package/dist/binding/index.js.map +1 -0
  63. package/dist/binding/two-way.d.ts +149 -0
  64. package/dist/binding/two-way.js +462 -0
  65. package/dist/binding/two-way.js.map +1 -0
  66. package/dist/binding/types.d.ts +119 -0
  67. package/dist/binding/types.js +9 -0
  68. package/dist/binding/types.js.map +1 -0
  69. package/dist/blocks/component-types.d.ts +81 -0
  70. package/dist/blocks/component-types.js +11 -0
  71. package/dist/blocks/component-types.js.map +1 -0
  72. package/dist/blocks/composition-rules.d.ts +168 -0
  73. package/dist/blocks/composition-rules.js +391 -0
  74. package/dist/blocks/composition-rules.js.map +1 -0
  75. package/dist/blocks/hooks.d.ts +31 -0
  76. package/dist/blocks/hooks.js +42 -0
  77. package/dist/blocks/hooks.js.map +1 -0
  78. package/dist/blocks/index.d.ts +14 -0
  79. package/dist/blocks/index.js +23 -0
  80. package/dist/blocks/index.js.map +1 -0
  81. package/dist/blocks/registry.d.ts +84 -0
  82. package/dist/blocks/registry.js +136 -0
  83. package/dist/blocks/registry.js.map +1 -0
  84. package/dist/blocks/rule-engine.d.ts +131 -0
  85. package/dist/blocks/rule-engine.js +321 -0
  86. package/dist/blocks/rule-engine.js.map +1 -0
  87. package/dist/blocks/surface-event-context.d.ts +13 -0
  88. package/dist/blocks/surface-event-context.js +14 -0
  89. package/dist/blocks/surface-event-context.js.map +1 -0
  90. package/dist/blocks/surface-id-context.d.ts +13 -0
  91. package/dist/blocks/surface-id-context.js +15 -0
  92. package/dist/blocks/surface-id-context.js.map +1 -0
  93. package/dist/bus.d.ts +41 -0
  94. package/dist/bus.js +158 -0
  95. package/dist/bus.js.map +1 -0
  96. package/dist/cache/index.d.ts +9 -0
  97. package/dist/cache/index.js +10 -0
  98. package/dist/cache/index.js.map +1 -0
  99. package/dist/cache/memory.d.ts +32 -0
  100. package/dist/cache/memory.js +138 -0
  101. package/dist/cache/memory.js.map +1 -0
  102. package/dist/cache/types.d.ts +62 -0
  103. package/dist/cache/types.js +9 -0
  104. package/dist/cache/types.js.map +1 -0
  105. package/dist/capability/index.d.ts +72 -0
  106. package/dist/capability/index.js +87 -0
  107. package/dist/capability/index.js.map +1 -0
  108. package/dist/capability/kernel-capabilities.d.ts +31 -0
  109. package/dist/capability/kernel-capabilities.js +36 -0
  110. package/dist/capability/kernel-capabilities.js.map +1 -0
  111. package/dist/capability/platform-capabilities.d.ts +71 -0
  112. package/dist/capability/platform-capabilities.js +267 -0
  113. package/dist/capability/platform-capabilities.js.map +1 -0
  114. package/dist/capability/type-mapping.d.ts +70 -0
  115. package/dist/capability/type-mapping.js +107 -0
  116. package/dist/capability/type-mapping.js.map +1 -0
  117. package/dist/capability/validation.d.ts +46 -0
  118. package/dist/capability/validation.js +54 -0
  119. package/dist/capability/validation.js.map +1 -0
  120. package/dist/connectors/declared-connector.d.ts +48 -0
  121. package/dist/connectors/declared-connector.js +333 -0
  122. package/dist/connectors/declared-connector.js.map +1 -0
  123. package/dist/connectors/engine-registry.d.ts +50 -0
  124. package/dist/connectors/engine-registry.js +135 -0
  125. package/dist/connectors/engine-registry.js.map +1 -0
  126. package/dist/connectors/index.d.ts +14 -0
  127. package/dist/connectors/index.js +14 -0
  128. package/dist/connectors/index.js.map +1 -0
  129. package/dist/connectors/module-loader.d.ts +70 -0
  130. package/dist/connectors/module-loader.js +143 -0
  131. package/dist/connectors/module-loader.js.map +1 -0
  132. package/dist/connectors/types.d.ts +174 -0
  133. package/dist/connectors/types.js +23 -0
  134. package/dist/connectors/types.js.map +1 -0
  135. package/dist/context.d.ts +27 -0
  136. package/dist/context.js +38 -0
  137. package/dist/context.js.map +1 -0
  138. package/dist/data/DataCapabilityProvider.d.ts +39 -0
  139. package/dist/data/DataCapabilityProvider.js +58 -0
  140. package/dist/data/DataCapabilityProvider.js.map +1 -0
  141. package/dist/data/index.d.ts +17 -0
  142. package/dist/data/index.js +18 -0
  143. package/dist/data/index.js.map +1 -0
  144. package/dist/data/manager.d.ts +40 -0
  145. package/dist/data/manager.js +442 -0
  146. package/dist/data/manager.js.map +1 -0
  147. package/dist/data/types.d.ts +218 -0
  148. package/dist/data/types.js +2 -0
  149. package/dist/data/types.js.map +1 -0
  150. package/dist/entity/aggregate.d.ts +8 -0
  151. package/dist/entity/aggregate.js +24 -0
  152. package/dist/entity/aggregate.js.map +1 -0
  153. package/dist/entity/apply-query.d.ts +58 -0
  154. package/dist/entity/apply-query.js +264 -0
  155. package/dist/entity/apply-query.js.map +1 -0
  156. package/dist/entity/behavior.d.ts +94 -0
  157. package/dist/entity/behavior.js +78 -0
  158. package/dist/entity/behavior.js.map +1 -0
  159. package/dist/entity/connector.d.ts +141 -0
  160. package/dist/entity/connector.js +89 -0
  161. package/dist/entity/connector.js.map +1 -0
  162. package/dist/entity/connectors/index.d.ts +12 -0
  163. package/dist/entity/connectors/index.js +11 -0
  164. package/dist/entity/connectors/index.js.map +1 -0
  165. package/dist/entity/connectors/static.d.ts +51 -0
  166. package/dist/entity/connectors/static.js +245 -0
  167. package/dist/entity/connectors/static.js.map +1 -0
  168. package/dist/entity/entity-datasource.d.ts +50 -0
  169. package/dist/entity/entity-datasource.js +33 -0
  170. package/dist/entity/entity-datasource.js.map +1 -0
  171. package/dist/entity/facade.d.ts +70 -0
  172. package/dist/entity/facade.js +70 -0
  173. package/dist/entity/facade.js.map +1 -0
  174. package/dist/entity/http-connector.d.ts +123 -0
  175. package/dist/entity/http-connector.js +295 -0
  176. package/dist/entity/http-connector.js.map +1 -0
  177. package/dist/entity/index.d.ts +38 -0
  178. package/dist/entity/index.js +31 -0
  179. package/dist/entity/index.js.map +1 -0
  180. package/dist/entity/postgres-connector.d.ts +64 -0
  181. package/dist/entity/postgres-connector.js +239 -0
  182. package/dist/entity/postgres-connector.js.map +1 -0
  183. package/dist/entity/registry.d.ts +59 -0
  184. package/dist/entity/registry.js +90 -0
  185. package/dist/entity/registry.js.map +1 -0
  186. package/dist/entity/store.d.ts +66 -0
  187. package/dist/entity/store.js +349 -0
  188. package/dist/entity/store.js.map +1 -0
  189. package/dist/entity/types.d.ts +180 -0
  190. package/dist/entity/types.js +10 -0
  191. package/dist/entity/types.js.map +1 -0
  192. package/dist/execution-context.d.ts +88 -0
  193. package/dist/execution-context.js +146 -0
  194. package/dist/execution-context.js.map +1 -0
  195. package/dist/executor.d.ts +27 -0
  196. package/dist/executor.js +33 -0
  197. package/dist/executor.js.map +1 -0
  198. package/dist/forms/form-entity-bridge.d.ts +94 -0
  199. package/dist/forms/form-entity-bridge.js +96 -0
  200. package/dist/forms/form-entity-bridge.js.map +1 -0
  201. package/dist/forms/form-write-target.d.ts +34 -0
  202. package/dist/forms/form-write-target.js +81 -0
  203. package/dist/forms/form-write-target.js.map +1 -0
  204. package/dist/forms/index.d.ts +22 -0
  205. package/dist/forms/index.js +25 -0
  206. package/dist/forms/index.js.map +1 -0
  207. package/dist/forms/named-control-values.d.ts +27 -0
  208. package/dist/forms/named-control-values.js +42 -0
  209. package/dist/forms/named-control-values.js.map +1 -0
  210. package/dist/forms/processor.d.ts +55 -0
  211. package/dist/forms/processor.js +154 -0
  212. package/dist/forms/processor.js.map +1 -0
  213. package/dist/forms/types.d.ts +174 -0
  214. package/dist/forms/types.js +33 -0
  215. package/dist/forms/types.js.map +1 -0
  216. package/dist/forms/validator.d.ts +61 -0
  217. package/dist/forms/validator.js +218 -0
  218. package/dist/forms/validator.js.map +1 -0
  219. package/dist/graph/index.d.ts +10 -0
  220. package/dist/graph/index.js +9 -0
  221. package/dist/graph/index.js.map +1 -0
  222. package/dist/graph/resolver.d.ts +66 -0
  223. package/dist/graph/resolver.js +243 -0
  224. package/dist/graph/resolver.js.map +1 -0
  225. package/dist/graph/types.d.ts +125 -0
  226. package/dist/graph/types.js +9 -0
  227. package/dist/graph/types.js.map +1 -0
  228. package/dist/hooks/useInstalledAtoms.d.ts +96 -0
  229. package/dist/hooks/useInstalledAtoms.js +92 -0
  230. package/dist/hooks/useInstalledAtoms.js.map +1 -0
  231. package/dist/i18n/index.d.ts +15 -0
  232. package/dist/i18n/index.js +14 -0
  233. package/dist/i18n/index.js.map +1 -0
  234. package/dist/i18n/translator.d.ts +76 -0
  235. package/dist/i18n/translator.js +357 -0
  236. package/dist/i18n/translator.js.map +1 -0
  237. package/dist/i18n/types.d.ts +93 -0
  238. package/dist/i18n/types.js +9 -0
  239. package/dist/i18n/types.js.map +1 -0
  240. package/dist/index.d.ts +64 -0
  241. package/dist/index.js +95 -0
  242. package/dist/index.js.map +1 -0
  243. package/dist/kernel.d.ts +47 -0
  244. package/dist/kernel.js +258 -0
  245. package/dist/kernel.js.map +1 -0
  246. package/dist/perf/budget.d.ts +92 -0
  247. package/dist/perf/budget.js +122 -0
  248. package/dist/perf/budget.js.map +1 -0
  249. package/dist/perf/index.d.ts +16 -0
  250. package/dist/perf/index.js +13 -0
  251. package/dist/perf/index.js.map +1 -0
  252. package/dist/perf/render-timer.d.ts +90 -0
  253. package/dist/perf/render-timer.js +136 -0
  254. package/dist/perf/render-timer.js.map +1 -0
  255. package/dist/perf/reporter.d.ts +126 -0
  256. package/dist/perf/reporter.js +241 -0
  257. package/dist/perf/reporter.js.map +1 -0
  258. package/dist/perf/web-vitals.d.ts +111 -0
  259. package/dist/perf/web-vitals.js +268 -0
  260. package/dist/perf/web-vitals.js.map +1 -0
  261. package/dist/registry.d.ts +63 -0
  262. package/dist/registry.js +126 -0
  263. package/dist/registry.js.map +1 -0
  264. package/dist/render/BehaviorSurfaceProvider.d.ts +65 -0
  265. package/dist/render/BehaviorSurfaceProvider.js +185 -0
  266. package/dist/render/BehaviorSurfaceProvider.js.map +1 -0
  267. package/dist/render/BlockErrorBoundary.d.ts +26 -0
  268. package/dist/render/BlockErrorBoundary.js +41 -0
  269. package/dist/render/BlockErrorBoundary.js.map +1 -0
  270. package/dist/render/DataBoundSurfaceRenderer.d.ts +78 -0
  271. package/dist/render/DataBoundSurfaceRenderer.js +998 -0
  272. package/dist/render/DataBoundSurfaceRenderer.js.map +1 -0
  273. package/dist/render/DynamicBlockWrapper.d.ts +23 -0
  274. package/dist/render/DynamicBlockWrapper.js +117 -0
  275. package/dist/render/DynamicBlockWrapper.js.map +1 -0
  276. package/dist/render/appearance-resolver.d.ts +50 -0
  277. package/dist/render/appearance-resolver.js +78 -0
  278. package/dist/render/appearance-resolver.js.map +1 -0
  279. package/dist/render/capability-gate.d.ts +69 -0
  280. package/dist/render/capability-gate.js +94 -0
  281. package/dist/render/capability-gate.js.map +1 -0
  282. package/dist/render/conditional-states-css.d.ts +41 -0
  283. package/dist/render/conditional-states-css.js +82 -0
  284. package/dist/render/conditional-states-css.js.map +1 -0
  285. package/dist/render/connections-context.d.ts +31 -0
  286. package/dist/render/connections-context.js +34 -0
  287. package/dist/render/connections-context.js.map +1 -0
  288. package/dist/render/dark-theme-css.d.ts +36 -0
  289. package/dist/render/dark-theme-css.js +67 -0
  290. package/dist/render/dark-theme-css.js.map +1 -0
  291. package/dist/render/data-binding-types.d.ts +191 -0
  292. package/dist/render/data-binding-types.js +11 -0
  293. package/dist/render/data-binding-types.js.map +1 -0
  294. package/dist/render/data-cache.d.ts +30 -0
  295. package/dist/render/data-cache.js +37 -0
  296. package/dist/render/data-cache.js.map +1 -0
  297. package/dist/render/derive-dark-theme.d.ts +17 -0
  298. package/dist/render/derive-dark-theme.js +18 -0
  299. package/dist/render/derive-dark-theme.js.map +1 -0
  300. package/dist/render/dynamic-artifact-context.d.ts +77 -0
  301. package/dist/render/dynamic-artifact-context.js +89 -0
  302. package/dist/render/dynamic-artifact-context.js.map +1 -0
  303. package/dist/render/dynamic-block-loader.d.ts +80 -0
  304. package/dist/render/dynamic-block-loader.js +197 -0
  305. package/dist/render/dynamic-block-loader.js.map +1 -0
  306. package/dist/render/endpoint.d.ts +18 -0
  307. package/dist/render/endpoint.js +109 -0
  308. package/dist/render/endpoint.js.map +1 -0
  309. package/dist/render/entity-facade-context.d.ts +34 -0
  310. package/dist/render/entity-facade-context.js +37 -0
  311. package/dist/render/entity-facade-context.js.map +1 -0
  312. package/dist/render/group-states-css.d.ts +41 -0
  313. package/dist/render/group-states-css.js +73 -0
  314. package/dist/render/group-states-css.js.map +1 -0
  315. package/dist/render/hooks/useSurfaceEvents.d.ts +8 -0
  316. package/dist/render/hooks/useSurfaceEvents.js +9 -0
  317. package/dist/render/hooks/useSurfaceEvents.js.map +1 -0
  318. package/dist/render/hooks/useSurfaceId.d.ts +8 -0
  319. package/dist/render/hooks/useSurfaceId.js +9 -0
  320. package/dist/render/hooks/useSurfaceId.js.map +1 -0
  321. package/dist/render/index.d.ts +48 -0
  322. package/dist/render/index.js +61 -0
  323. package/dist/render/index.js.map +1 -0
  324. package/dist/render/interaction-rule-engine.d.ts +12 -0
  325. package/dist/render/interaction-rule-engine.js +47 -0
  326. package/dist/render/interaction-rule-engine.js.map +1 -0
  327. package/dist/render/keyframes-css.d.ts +31 -0
  328. package/dist/render/keyframes-css.js +44 -0
  329. package/dist/render/keyframes-css.js.map +1 -0
  330. package/dist/render/query-state.d.ts +3 -0
  331. package/dist/render/query-state.js +70 -0
  332. package/dist/render/query-state.js.map +1 -0
  333. package/dist/render/renderer.d.ts +44 -0
  334. package/dist/render/renderer.js +937 -0
  335. package/dist/render/renderer.js.map +1 -0
  336. package/dist/render/resolve-expressions.d.ts +37 -0
  337. package/dist/render/resolve-expressions.js +309 -0
  338. package/dist/render/resolve-expressions.js.map +1 -0
  339. package/dist/render/responsive-style-css.d.ts +42 -0
  340. package/dist/render/responsive-style-css.js +123 -0
  341. package/dist/render/responsive-style-css.js.map +1 -0
  342. package/dist/render/responsive.d.ts +49 -0
  343. package/dist/render/responsive.js +99 -0
  344. package/dist/render/responsive.js.map +1 -0
  345. package/dist/render/scoped-css.d.ts +71 -0
  346. package/dist/render/scoped-css.js +102 -0
  347. package/dist/render/scoped-css.js.map +1 -0
  348. package/dist/render/shell-selection.d.ts +69 -0
  349. package/dist/render/shell-selection.js +117 -0
  350. package/dist/render/shell-selection.js.map +1 -0
  351. package/dist/render/states-css.d.ts +32 -0
  352. package/dist/render/states-css.js +63 -0
  353. package/dist/render/states-css.js.map +1 -0
  354. package/dist/render/surface-data-context.d.ts +18 -0
  355. package/dist/render/surface-data-context.js +21 -0
  356. package/dist/render/surface-data-context.js.map +1 -0
  357. package/dist/render/surface-event-bus.d.ts +19 -0
  358. package/dist/render/surface-event-bus.js +68 -0
  359. package/dist/render/surface-event-bus.js.map +1 -0
  360. package/dist/render/surface-event-context.d.ts +11 -0
  361. package/dist/render/surface-event-context.js +12 -0
  362. package/dist/render/surface-event-context.js.map +1 -0
  363. package/dist/render/surface-id-context.d.ts +8 -0
  364. package/dist/render/surface-id-context.js +9 -0
  365. package/dist/render/surface-id-context.js.map +1 -0
  366. package/dist/render/theme-utils.d.ts +14 -0
  367. package/dist/render/theme-utils.js +15 -0
  368. package/dist/render/theme-utils.js.map +1 -0
  369. package/dist/render/types.d.ts +282 -0
  370. package/dist/render/types.js +9 -0
  371. package/dist/render/types.js.map +1 -0
  372. package/dist/render/visibility-css.d.ts +42 -0
  373. package/dist/render/visibility-css.js +119 -0
  374. package/dist/render/visibility-css.js.map +1 -0
  375. package/dist/render/width-scope.d.ts +34 -0
  376. package/dist/render/width-scope.js +44 -0
  377. package/dist/render/width-scope.js.map +1 -0
  378. package/dist/render/write-only-sources.d.ts +33 -0
  379. package/dist/render/write-only-sources.js +99 -0
  380. package/dist/render/write-only-sources.js.map +1 -0
  381. package/dist/routing/index.d.ts +14 -0
  382. package/dist/routing/index.js +15 -0
  383. package/dist/routing/index.js.map +1 -0
  384. package/dist/routing/router.d.ts +42 -0
  385. package/dist/routing/router.js +218 -0
  386. package/dist/routing/router.js.map +1 -0
  387. package/dist/routing/types.d.ts +124 -0
  388. package/dist/routing/types.js +9 -0
  389. package/dist/routing/types.js.map +1 -0
  390. package/dist/seo/generator.d.ts +39 -0
  391. package/dist/seo/generator.js +236 -0
  392. package/dist/seo/generator.js.map +1 -0
  393. package/dist/seo/index.d.ts +14 -0
  394. package/dist/seo/index.js +15 -0
  395. package/dist/seo/index.js.map +1 -0
  396. package/dist/seo/types.d.ts +181 -0
  397. package/dist/seo/types.js +9 -0
  398. package/dist/seo/types.js.map +1 -0
  399. package/dist/state/index.d.ts +15 -0
  400. package/dist/state/index.js +16 -0
  401. package/dist/state/index.js.map +1 -0
  402. package/dist/state/manager.d.ts +33 -0
  403. package/dist/state/manager.js +81 -0
  404. package/dist/state/manager.js.map +1 -0
  405. package/dist/state/store.d.ts +40 -0
  406. package/dist/state/store.js +145 -0
  407. package/dist/state/store.js.map +1 -0
  408. package/dist/state/types.d.ts +107 -0
  409. package/dist/state/types.js +9 -0
  410. package/dist/state/types.js.map +1 -0
  411. package/dist/surface/expression.d.ts +65 -0
  412. package/dist/surface/expression.js +179 -0
  413. package/dist/surface/expression.js.map +1 -0
  414. package/dist/surface/index.d.ts +32 -0
  415. package/dist/surface/index.js +25 -0
  416. package/dist/surface/index.js.map +1 -0
  417. package/dist/surface/interpreter.d.ts +96 -0
  418. package/dist/surface/interpreter.js +231 -0
  419. package/dist/surface/interpreter.js.map +1 -0
  420. package/dist/surface/layout.d.ts +54 -0
  421. package/dist/surface/layout.js +288 -0
  422. package/dist/surface/layout.js.map +1 -0
  423. package/dist/surface/output.d.ts +90 -0
  424. package/dist/surface/output.js +104 -0
  425. package/dist/surface/output.js.map +1 -0
  426. package/dist/surface/primitives.d.ts +180 -0
  427. package/dist/surface/primitives.js +339 -0
  428. package/dist/surface/primitives.js.map +1 -0
  429. package/dist/surface/renderer.d.ts +96 -0
  430. package/dist/surface/renderer.js +190 -0
  431. package/dist/surface/renderer.js.map +1 -0
  432. package/dist/surface/schemas.d.ts +181 -0
  433. package/dist/surface/schemas.js +142 -0
  434. package/dist/surface/schemas.js.map +1 -0
  435. package/dist/surface/transforms.d.ts +144 -0
  436. package/dist/surface/transforms.js +120 -0
  437. package/dist/surface/transforms.js.map +1 -0
  438. package/dist/surface/types.d.ts +160 -0
  439. package/dist/surface/types.js +51 -0
  440. package/dist/surface/types.js.map +1 -0
  441. package/dist/surface/validation.d.ts +123 -0
  442. package/dist/surface/validation.js +147 -0
  443. package/dist/surface/validation.js.map +1 -0
  444. package/dist/validator.d.ts +55 -0
  445. package/dist/validator.js +100 -0
  446. package/dist/validator.js.map +1 -0
  447. package/package.json +106 -3
@@ -0,0 +1,295 @@
1
+ /**
2
+ * HTTP Entity Connector
3
+ *
4
+ * REST API connector for entity data persistence and retrieval.
5
+ * Implements the EntityConnector interface using fetch for HTTP communication.
6
+ *
7
+ * @module @pwfabric/runtime/entity/http-connector
8
+ */
9
+ import { z } from 'zod';
10
+ // ============================================================
11
+ // DEFAULTS
12
+ // ============================================================
13
+ const queryResponseSchema = z
14
+ .object({
15
+ items: z.array(z.unknown()).optional(),
16
+ total: z.number().optional(),
17
+ offset: z.number().optional(),
18
+ limit: z.number().optional(),
19
+ })
20
+ .passthrough();
21
+ /**
22
+ * `{ data: { fn, field?, value, count, numericCount? }, meta }` is how the
23
+ * platform answers (`routes/app-records.ts`); a bare `{ value, count }` body
24
+ * is accepted too. `value` is null when a numeric fn had nothing to reduce.
25
+ */
26
+ const aggregateBodySchema = z
27
+ .object({
28
+ fn: z.enum(['count', 'sum', 'avg']).optional(),
29
+ field: z.string().optional(),
30
+ value: z.number().nullable().optional(),
31
+ count: z.number().optional(),
32
+ })
33
+ .passthrough();
34
+ const DEFAULT_TIMEOUT = 30_000;
35
+ const DEFAULT_RETRY = {
36
+ maxRetries: 3,
37
+ baseDelay: 1000,
38
+ maxDelay: 10_000,
39
+ retryableStatuses: [408, 429, 500, 502, 503, 504],
40
+ };
41
+ // ============================================================
42
+ // HTTP ENTITY CONNECTOR
43
+ // ============================================================
44
+ /**
45
+ * HTTP/REST connector for entity data operations.
46
+ * Maps entity CRUD operations to standard REST API endpoints.
47
+ */
48
+ export class HttpEntityConnector {
49
+ name;
50
+ type = 'http';
51
+ config;
52
+ constructor(name, config) {
53
+ this.name = name;
54
+ this.config = {
55
+ ...config,
56
+ timeout: config.timeout ?? DEFAULT_TIMEOUT,
57
+ };
58
+ }
59
+ async create(entityType, data) {
60
+ const url = this.buildUrl(entityType);
61
+ return this.request('POST', url, data);
62
+ }
63
+ async read(entityType, instanceId) {
64
+ const url = `${this.buildUrl(entityType)}/${instanceId}`;
65
+ return this.request('GET', url);
66
+ }
67
+ async update(entityType, instanceId, data) {
68
+ const url = `${this.buildUrl(entityType)}/${instanceId}`;
69
+ return this.request('PATCH', url, data);
70
+ }
71
+ async delete(entityType, instanceId) {
72
+ const url = `${this.buildUrl(entityType)}/${instanceId}`;
73
+ return this.request('DELETE', url);
74
+ }
75
+ async query(entityType, query) {
76
+ const url = this.buildUrl(entityType);
77
+ const params = this.buildQueryParams(query);
78
+ const fullUrl = params ? `${url}?${params}` : url;
79
+ const result = await this.request('GET', fullUrl);
80
+ if (!result.success) {
81
+ return { success: false, error: result.error };
82
+ }
83
+ // A vendor shape is mapped BEFORE the built-in schema runs — the mapper
84
+ // exists precisely for bodies this schema would reject, so validating first
85
+ // would refuse the very responses it was added to accept.
86
+ if (this.config.responseMapper) {
87
+ const mapped = this.config.responseMapper(result.data);
88
+ const items = mapped.items;
89
+ const total = mapped.total ?? items.length;
90
+ const offset = query.pagination?.offset ?? 0;
91
+ return {
92
+ success: true,
93
+ result: {
94
+ items,
95
+ total,
96
+ offset,
97
+ limit: query.pagination?.limit ?? items.length,
98
+ hasMore: total > offset + items.length,
99
+ },
100
+ };
101
+ }
102
+ const parsed = queryResponseSchema.safeParse(result.data);
103
+ if (!parsed.success) {
104
+ return { success: false, error: 'Invalid query response shape' };
105
+ }
106
+ const data = parsed.data;
107
+ // Accept both the connector contract ({items,total}) and the platform
108
+ // entity-records envelope ({data:[...], meta:{total}}).
109
+ const rawItems = (data.items ??
110
+ data.data ??
111
+ []);
112
+ // Entity records store user fields under `.data` — flatten them to the top
113
+ // level so expression/column bindings ({{id}}, column key 'name') resolve
114
+ // against the fields, while keeping id/metadata available.
115
+ const items = rawItems.map((r) => r && typeof r === 'object' && r.data && typeof r.data === 'object'
116
+ ? { ...r, ...r.data }
117
+ : r);
118
+ const meta = data.meta;
119
+ const total = data.total ?? meta?.total ?? items.length;
120
+ return {
121
+ success: true,
122
+ result: {
123
+ items,
124
+ total,
125
+ offset: data.offset ?? query.pagination?.offset ?? 0,
126
+ limit: data.limit ?? query.pagination?.limit ?? 50,
127
+ hasMore: total > (data.offset ?? 0) + items.length,
128
+ },
129
+ };
130
+ }
131
+ /**
132
+ * One number over the collection, computed by the server.
133
+ *
134
+ * `GET <base>/<type>/count[?filter=]` for a plain count and
135
+ * `GET <base>/<type>/aggregate?fn=&field=&filter=` for the rest — the two
136
+ * routes a host registers ahead of the read-one route.
137
+ * Constants (`defaultQueryParams`) and `entityPathMapper` apply as on
138
+ * every other read.
139
+ */
140
+ async aggregate(entityType, aggregate) {
141
+ const plainCount = aggregate.fn === 'count' && !aggregate.field;
142
+ const params = new URLSearchParams();
143
+ for (const [k, v] of Object.entries(this.config.defaultQueryParams ?? {}))
144
+ params.set(k, v);
145
+ if (!plainCount) {
146
+ params.set('fn', aggregate.fn);
147
+ if (aggregate.field)
148
+ params.set('field', aggregate.field);
149
+ }
150
+ if (aggregate.filter)
151
+ params.set('filter', JSON.stringify(aggregate.filter));
152
+ const url = `${this.buildUrl(entityType)}/${plainCount ? 'count' : 'aggregate'}`;
153
+ const qs = params.toString();
154
+ const result = await this.request('GET', qs ? `${url}?${qs}` : url);
155
+ if (!result.success)
156
+ return { success: false, error: result.error };
157
+ const envelope = result.data;
158
+ const body = envelope.data && typeof envelope.data === 'object' ? envelope.data : envelope;
159
+ const parsed = aggregateBodySchema.safeParse(body);
160
+ if (!parsed.success)
161
+ return { success: false, error: 'Invalid aggregate response shape' };
162
+ const d = parsed.data;
163
+ const field = d.field ?? aggregate.field;
164
+ const out = {
165
+ fn: d.fn ?? aggregate.fn,
166
+ ...(field ? { field } : {}),
167
+ value: d.value ?? null,
168
+ count: d.count ?? 0,
169
+ };
170
+ return { success: true, result: out };
171
+ }
172
+ // ============================================================
173
+ // PRIVATE HELPERS
174
+ // ============================================================
175
+ buildUrl(entityType) {
176
+ const path = this.config.entityPathMapper
177
+ ? this.config.entityPathMapper(entityType)
178
+ : `/${entityType}`;
179
+ return `${this.config.baseUrl}${path}`;
180
+ }
181
+ buildQueryParams(query) {
182
+ const params = new URLSearchParams();
183
+ // Constants first so a caller's own query can still override one.
184
+ for (const [k, v] of Object.entries(this.config.defaultQueryParams ?? {})) {
185
+ params.set(k, v);
186
+ }
187
+ if (query.pagination) {
188
+ params.set('offset', String(query.pagination.offset));
189
+ params.set('limit', String(query.pagination.limit));
190
+ }
191
+ if (query.sort && query.sort.length > 0) {
192
+ params.set('sort', query.sort.map((s) => `${s.field}:${s.direction}`).join(','));
193
+ }
194
+ if (query.filter) {
195
+ params.set('filter', JSON.stringify(query.filter));
196
+ }
197
+ if (query.include && query.include.length > 0) {
198
+ params.set('include', query.include.join(','));
199
+ }
200
+ return params.toString();
201
+ }
202
+ async buildHeaders() {
203
+ const headers = {
204
+ 'Content-Type': 'application/json',
205
+ Accept: 'application/json',
206
+ ...this.config.headers,
207
+ };
208
+ if (this.config.auth) {
209
+ const authHeader = await this.resolveAuthHeader(this.config.auth);
210
+ if (authHeader) {
211
+ Object.assign(headers, authHeader);
212
+ }
213
+ }
214
+ return headers;
215
+ }
216
+ async resolveAuthHeader(auth) {
217
+ switch (auth.type) {
218
+ case 'bearer': {
219
+ // Resolved per request, never cached — a session-length token is the
220
+ // reason this accepts a function at all. A resolver that answers null
221
+ // yields NO header: the server's own 401 is a truer error than a
222
+ // client-side guess, and the panel's errorWhen already renders it.
223
+ const token = typeof auth.token === 'function' ? await auth.token() : auth.token;
224
+ return token ? { Authorization: `Bearer ${token}` } : null;
225
+ }
226
+ case 'api-key':
227
+ return auth.apiKey ? { [auth.headerName ?? 'X-API-Key']: auth.apiKey } : null;
228
+ case 'basic':
229
+ if (auth.username && auth.password) {
230
+ const encoded = btoa(`${auth.username}:${auth.password}`);
231
+ return { Authorization: `Basic ${encoded}` };
232
+ }
233
+ return null;
234
+ default:
235
+ return null;
236
+ }
237
+ }
238
+ async request(method, url, body) {
239
+ const retryConfig = this.config.retry ?? DEFAULT_RETRY;
240
+ let lastError = '';
241
+ for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
242
+ try {
243
+ const controller = new AbortController();
244
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
245
+ const response = await fetch(url, {
246
+ method,
247
+ headers: await this.buildHeaders(),
248
+ body: body ? JSON.stringify(body) : null,
249
+ signal: controller.signal,
250
+ ...(this.config.credentials ? { credentials: this.config.credentials } : {}),
251
+ });
252
+ clearTimeout(timeoutId);
253
+ if (!response.ok) {
254
+ if (attempt < retryConfig.maxRetries &&
255
+ retryConfig.retryableStatuses.includes(response.status)) {
256
+ const delay = Math.min(retryConfig.baseDelay * Math.pow(2, attempt), retryConfig.maxDelay);
257
+ await this.sleep(delay);
258
+ continue;
259
+ }
260
+ const errorBody = await response.text().catch(() => '');
261
+ lastError = `HTTP ${response.status}: ${errorBody || response.statusText}`;
262
+ return { success: false, error: lastError };
263
+ }
264
+ if (method === 'DELETE' && response.status === 204) {
265
+ return { success: true, data: {} };
266
+ }
267
+ const jsonData = await response.json();
268
+ const data = z.record(z.unknown()).parse(jsonData);
269
+ return { success: true, data };
270
+ }
271
+ catch (err) {
272
+ lastError = err instanceof Error ? err.message : String(err);
273
+ if (attempt < retryConfig.maxRetries) {
274
+ const delay = Math.min(retryConfig.baseDelay * Math.pow(2, attempt), retryConfig.maxDelay);
275
+ await this.sleep(delay);
276
+ continue;
277
+ }
278
+ }
279
+ }
280
+ return { success: false, error: lastError };
281
+ }
282
+ sleep(ms) {
283
+ return new Promise((resolve) => setTimeout(resolve, ms));
284
+ }
285
+ }
286
+ // ============================================================
287
+ // FACTORY
288
+ // ============================================================
289
+ /**
290
+ * Create an HTTP entity connector
291
+ */
292
+ export function createHttpConnector(name, config) {
293
+ return new HttpEntityConnector(name, config);
294
+ }
295
+ //# sourceMappingURL=http-connector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-connector.js","sourceRoot":"","sources":["../../src/entity/http-connector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAkGvB,+DAA+D;AAC/D,WAAW;AACX,+DAA+D;AAE/D,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC;KACD,WAAW,EAAE,CAAA;AAEhB;;;;GAIG;AACH,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC9C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC;KACD,WAAW,EAAE,CAAA;AAEhB,MAAM,eAAe,GAAG,MAAM,CAAA;AAE9B,MAAM,aAAa,GAAoB;IACrC,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,MAAM;IAChB,iBAAiB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CAClD,CAAA;AAED,+DAA+D;AAC/D,wBAAwB;AACxB,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACrB,IAAI,CAAQ;IACZ,IAAI,GAAwB,MAAM,CAAA;IAE1B,MAAM,CACF;IAErB,YAAY,IAAY,EAAE,MAA2B;QACnD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,MAAM;YACT,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,eAAe;SAC3C,CAAA;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAwB,EAAE,IAA6B;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;QACrC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACxC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAwB,EAAE,UAA4B;QAC/D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,EAAE,CAAA;QACxD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,MAAM,CACV,UAAwB,EACxB,UAA4B,EAC5B,IAA6B;QAE7B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,EAAE,CAAA;QACxD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAwB,EAAE,UAA4B;QACjE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,EAAE,CAAA;QACxD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAwB,EAAE,KAAkB;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;QAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QACjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAA;QAChD,CAAC;QAED,wEAAwE;QACxE,4EAA4E;QAC5E,0DAA0D;QAC1D,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YACtD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAkC,CAAA;YACvD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAA;YAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,CAAA;YAC5C,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE;oBACN,KAAK;oBACL,KAAK;oBACL,MAAM;oBACN,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM;oBAC9C,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM;iBACvC;aACF,CAAA;QACH,CAAC;QAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAA;QAClE,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAA+B,CAAA;QAEnD,sEAAsE;QACtE,wDAAwD;QACxD,MAAM,QAAQ,GAAG,CAAE,IAAI,CAAC,KAAmB;YACxC,IAAI,CAAC,IAAkB;YACxB,EAAE,CAA8B,CAAA;QAClC,2EAA2E;QAC3E,0EAA0E;QAC1E,2DAA2D;QAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/B,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;YAChE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAI,CAAC,CAAC,IAAgC,EAAE;YAClD,CAAC,CAAC,CAAC,CACN,CAAA;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAA2C,CAAA;QAC7D,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAK,IAAI,EAAE,KAAgB,IAAI,KAAK,CAAC,MAAM,CAAA;QAE/E,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE;gBACN,KAAK;gBACL,KAAK;gBACL,MAAM,EAAG,IAAI,CAAC,MAAiB,IAAI,KAAK,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;gBAChE,KAAK,EAAG,IAAI,CAAC,KAAgB,IAAI,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;gBAC9D,OAAO,EAAE,KAAK,GAAG,CAAE,IAAI,CAAC,MAAiB,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM;aAC/D;SACF,CAAA;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,SAAS,CAAC,UAAwB,EAAE,SAA0B;QAClE,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QAC/D,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;QACpC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC3F,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAA;YAC9B,IAAI,SAAS,CAAC,KAAK;gBAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,SAAS,CAAC,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;QAC5E,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAChF,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QAE5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACnE,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAA;QAEnE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAA;QAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC1F,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAClD,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAA;QACzF,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAA;QACrB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,CAAA;QACxC,MAAM,GAAG,GAA0B;YACjC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,SAAS,CAAC,EAAE;YACxB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3B,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI;YACtB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SACpB,CAAA;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;IACvC,CAAC;IAED,+DAA+D;IAC/D,kBAAkB;IAClB,+DAA+D;IAEvD,QAAQ,CAAC,UAAwB;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB;YACvC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC;YAC1C,CAAC,CAAC,IAAI,UAAU,EAAE,CAAA;QACpB,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,EAAE,CAAA;IACxC,CAAC;IAEO,gBAAgB,CAAC,KAAkB;QACzC,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;QAEpC,kEAAkE;QAClE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1E,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAClB,CAAC;QAED,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;YACrD,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;QACrD,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAClF,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;QACpD,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAChD,CAAC;QAED,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAA;IAC1B,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;YAC1B,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO;SACvB,CAAA;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YACjE,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,IAAoB;QAClD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,qEAAqE;gBACrE,sEAAsE;gBACtE,iEAAiE;gBACjE,mEAAmE;gBACnE,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAA;gBAChF,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;YAC5D,CAAC;YACD,KAAK,SAAS;gBACZ,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,WAAW,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;YAC/E,KAAK,OAAO;gBACV,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACnC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;oBACzD,OAAO,EAAE,aAAa,EAAE,SAAS,OAAO,EAAE,EAAE,CAAA;gBAC9C,CAAC;gBACD,OAAO,IAAI,CAAA;YACb;gBACE,OAAO,IAAI,CAAA;QACf,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,MAAc,EACd,GAAW,EACX,IAA8B;QAE9B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,aAAa,CAAA;QACtD,IAAI,SAAS,GAAG,EAAE,CAAA;QAElB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACnE,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;gBACxC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;gBAE3E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBAChC,MAAM;oBACN,OAAO,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE;oBAClC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;oBACxC,MAAM,EAAE,UAAU,CAAC,MAAM;oBACzB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC7E,CAAC,CAAA;gBAEF,YAAY,CAAC,SAAS,CAAC,CAAA;gBAEvB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,IACE,OAAO,GAAG,WAAW,CAAC,UAAU;wBAChC,WAAW,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EACvD,CAAC;wBACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAC5C,WAAW,CAAC,QAAQ,CACrB,CAAA;wBACD,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;wBACvB,SAAQ;oBACV,CAAC;oBAED,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;oBACvD,SAAS,GAAG,QAAQ,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAA;oBAC1E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;gBAC7C,CAAC;gBAED,IAAI,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;gBACpC,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;gBACtC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;YAChC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAE5D,IAAI,OAAO,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC;oBACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;oBAC1F,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;oBACvB,SAAQ;gBACV,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;IAC7C,CAAC;IAEO,KAAK,CAAC,EAAU;QACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IAC1D,CAAC;CACF;AAED,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,MAA2B;IAE3B,OAAO,IAAI,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AAC9C,CAAC","sourcesContent":["/**\n * HTTP Entity Connector\n *\n * REST API connector for entity data persistence and retrieval.\n * Implements the EntityConnector interface using fetch for HTTP communication.\n *\n * @module @pwfabric/runtime/entity/http-connector\n */\n\nimport { z } from 'zod'\nimport type {\n EntityTypeId,\n EntityInstanceId,\n EntityQuery,\n EntityAggregate,\n EntityAggregateResult,\n} from './types.js'\nimport type {\n EntityConnector,\n EntityConnectorType,\n ConnectorResult,\n ConnectorQueryResult,\n ConnectorAggregateResult,\n} from './connector.js'\n\n// ============================================================\n// CONFIGURATION\n// ============================================================\n\n/**\n * HTTP connector authentication configuration\n */\nexport interface HttpAuthConfig {\n readonly type: 'bearer' | 'api-key' | 'basic'\n /**\n * A fixed value, or a RESOLVER re-invoked on every request.\n *\n * A string or a resolver. A delegated PKCE token expires within about an\n * hour, so a fixed string cannot serve a session; an engine that needs a\n * live token passes a resolver instead of reimplementing the transport\n * (and losing retry, timeout and the result envelope on the way).\n *\n * A string is used as is; a resolver is awaited per request and its answer\n * is never cached here, which is the whole point.\n */\n readonly token?: string | (() => Promise<string | null>)\n readonly apiKey?: string\n readonly headerName?: string\n readonly username?: string\n readonly password?: string\n}\n\n/**\n * HTTP connector retry configuration\n */\nexport interface HttpRetryConfig {\n readonly maxRetries: number\n readonly baseDelay: number\n readonly maxDelay: number\n readonly retryableStatuses: readonly number[]\n}\n\n/**\n * HTTP connector configuration\n */\nexport interface HttpConnectorConfig {\n readonly baseUrl: string\n readonly headers?: Record<string, string>\n readonly timeout?: number\n readonly auth?: HttpAuthConfig\n /**\n * Fetch credentials mode. Set 'include' so cookie-authoritative APIs\n * receive the session cookie on cross-origin entity requests\n * the visitor facade has no bearer token to send.\n */\n readonly credentials?: RequestCredentials\n readonly retry?: HttpRetryConfig\n /**\n * Query parameters this API requires on every read.\n *\n * GENERIC, and the distinction matters because three vendor-shaped widenings\n * were proposed and reverted the same day. Azure wants `api-version`, plenty\n * of APIs want `format=json`, Graph wants `expand=fields`: \"this endpoint\n * takes constant parameters\" is a REST fact, not one provider's dance, and no\n * provider name appears here.\n *\n * It exists because the alternative is worse. A caller that put its constants\n * in `entityPathMapper` would produce `...?expand=fields?limit=50` the moment\n * a query carried pagination, and `...?expand=fields/1` on a delete — the URL\n * is assembled as `params ? url + '?' + params : url`.\n */\n readonly defaultQueryParams?: Readonly<Record<string, string>>\n readonly entityPathMapper?: (entityType: EntityTypeId) => string\n /**\n * Maps a vendor response body to the connector's query result shape\n * `entityPathMapper`'s response-side twin.\n *\n * `entityPathMapper` has always let a caller say how an entity type becomes a\n * URL path; nothing let it say how the answer comes back. So a vendor whose\n * body is its own shape — Graph replies `{ value: [{ id, fields }] }`, not\n * `{ items }` — could not use this class at all, and that was the other half\n * of why every Graph engine forked. Absent, the built-in shapes below apply\n * unchanged.\n */\n readonly responseMapper?: (raw: unknown) => { items: unknown[]; total?: number }\n}\n\n// ============================================================\n// DEFAULTS\n// ============================================================\n\nconst queryResponseSchema = z\n .object({\n items: z.array(z.unknown()).optional(),\n total: z.number().optional(),\n offset: z.number().optional(),\n limit: z.number().optional(),\n })\n .passthrough()\n\n/**\n * `{ data: { fn, field?, value, count, numericCount? }, meta }` is how the\n * platform answers (`routes/app-records.ts`); a bare `{ value, count }` body\n * is accepted too. `value` is null when a numeric fn had nothing to reduce.\n */\nconst aggregateBodySchema = z\n .object({\n fn: z.enum(['count', 'sum', 'avg']).optional(),\n field: z.string().optional(),\n value: z.number().nullable().optional(),\n count: z.number().optional(),\n })\n .passthrough()\n\nconst DEFAULT_TIMEOUT = 30_000\n\nconst DEFAULT_RETRY: HttpRetryConfig = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 10_000,\n retryableStatuses: [408, 429, 500, 502, 503, 504],\n}\n\n// ============================================================\n// HTTP ENTITY CONNECTOR\n// ============================================================\n\n/**\n * HTTP/REST connector for entity data operations.\n * Maps entity CRUD operations to standard REST API endpoints.\n */\nexport class HttpEntityConnector implements EntityConnector {\n readonly name: string\n readonly type: EntityConnectorType = 'http'\n\n private readonly config: Required<Pick<HttpConnectorConfig, 'baseUrl' | 'timeout'>> &\n HttpConnectorConfig\n\n constructor(name: string, config: HttpConnectorConfig) {\n this.name = name\n this.config = {\n ...config,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n }\n }\n\n async create(entityType: EntityTypeId, data: Record<string, unknown>): Promise<ConnectorResult> {\n const url = this.buildUrl(entityType)\n return this.request('POST', url, data)\n }\n\n async read(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult> {\n const url = `${this.buildUrl(entityType)}/${instanceId}`\n return this.request('GET', url)\n }\n\n async update(\n entityType: EntityTypeId,\n instanceId: EntityInstanceId,\n data: Record<string, unknown>\n ): Promise<ConnectorResult> {\n const url = `${this.buildUrl(entityType)}/${instanceId}`\n return this.request('PATCH', url, data)\n }\n\n async delete(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult> {\n const url = `${this.buildUrl(entityType)}/${instanceId}`\n return this.request('DELETE', url)\n }\n\n async query(entityType: EntityTypeId, query: EntityQuery): Promise<ConnectorQueryResult> {\n const url = this.buildUrl(entityType)\n const params = this.buildQueryParams(query)\n const fullUrl = params ? `${url}?${params}` : url\n\n const result = await this.request('GET', fullUrl)\n if (!result.success) {\n return { success: false, error: result.error }\n }\n\n // A vendor shape is mapped BEFORE the built-in schema runs — the mapper\n // exists precisely for bodies this schema would reject, so validating first\n // would refuse the very responses it was added to accept.\n if (this.config.responseMapper) {\n const mapped = this.config.responseMapper(result.data)\n const items = mapped.items as Record<string, unknown>[]\n const total = mapped.total ?? items.length\n const offset = query.pagination?.offset ?? 0\n return {\n success: true,\n result: {\n items,\n total,\n offset,\n limit: query.pagination?.limit ?? items.length,\n hasMore: total > offset + items.length,\n },\n }\n }\n\n const parsed = queryResponseSchema.safeParse(result.data)\n if (!parsed.success) {\n return { success: false, error: 'Invalid query response shape' }\n }\n const data = parsed.data as Record<string, unknown>\n\n // Accept both the connector contract ({items,total}) and the platform\n // entity-records envelope ({data:[...], meta:{total}}).\n const rawItems = ((data.items as unknown[]) ??\n (data.data as unknown[]) ??\n []) as Record<string, unknown>[]\n // Entity records store user fields under `.data` — flatten them to the top\n // level so expression/column bindings ({{id}}, column key 'name') resolve\n // against the fields, while keeping id/metadata available.\n const items = rawItems.map((r) =>\n r && typeof r === 'object' && r.data && typeof r.data === 'object'\n ? { ...r, ...(r.data as Record<string, unknown>) }\n : r\n )\n const meta = data.meta as Record<string, unknown> | undefined\n const total = (data.total as number) ?? (meta?.total as number) ?? items.length\n\n return {\n success: true,\n result: {\n items,\n total,\n offset: (data.offset as number) ?? query.pagination?.offset ?? 0,\n limit: (data.limit as number) ?? query.pagination?.limit ?? 50,\n hasMore: total > ((data.offset as number) ?? 0) + items.length,\n },\n }\n }\n\n /**\n * One number over the collection, computed by the server.\n *\n * `GET <base>/<type>/count[?filter=]` for a plain count and\n * `GET <base>/<type>/aggregate?fn=&field=&filter=` for the rest — the two\n * routes a host registers ahead of the read-one route.\n * Constants (`defaultQueryParams`) and `entityPathMapper` apply as on\n * every other read.\n */\n async aggregate(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<ConnectorAggregateResult> {\n const plainCount = aggregate.fn === 'count' && !aggregate.field\n const params = new URLSearchParams()\n for (const [k, v] of Object.entries(this.config.defaultQueryParams ?? {})) params.set(k, v)\n if (!plainCount) {\n params.set('fn', aggregate.fn)\n if (aggregate.field) params.set('field', aggregate.field)\n }\n if (aggregate.filter) params.set('filter', JSON.stringify(aggregate.filter))\n const url = `${this.buildUrl(entityType)}/${plainCount ? 'count' : 'aggregate'}`\n const qs = params.toString()\n\n const result = await this.request('GET', qs ? `${url}?${qs}` : url)\n if (!result.success) return { success: false, error: result.error }\n\n const envelope = result.data\n const body = envelope.data && typeof envelope.data === 'object' ? envelope.data : envelope\n const parsed = aggregateBodySchema.safeParse(body)\n if (!parsed.success) return { success: false, error: 'Invalid aggregate response shape' }\n const d = parsed.data\n const field = d.field ?? aggregate.field\n const out: EntityAggregateResult = {\n fn: d.fn ?? aggregate.fn,\n ...(field ? { field } : {}),\n value: d.value ?? null,\n count: d.count ?? 0,\n }\n return { success: true, result: out }\n }\n\n // ============================================================\n // PRIVATE HELPERS\n // ============================================================\n\n private buildUrl(entityType: EntityTypeId): string {\n const path = this.config.entityPathMapper\n ? this.config.entityPathMapper(entityType)\n : `/${entityType}`\n return `${this.config.baseUrl}${path}`\n }\n\n private buildQueryParams(query: EntityQuery): string {\n const params = new URLSearchParams()\n\n // Constants first so a caller's own query can still override one.\n for (const [k, v] of Object.entries(this.config.defaultQueryParams ?? {})) {\n params.set(k, v)\n }\n\n if (query.pagination) {\n params.set('offset', String(query.pagination.offset))\n params.set('limit', String(query.pagination.limit))\n }\n\n if (query.sort && query.sort.length > 0) {\n params.set('sort', query.sort.map((s) => `${s.field}:${s.direction}`).join(','))\n }\n\n if (query.filter) {\n params.set('filter', JSON.stringify(query.filter))\n }\n\n if (query.include && query.include.length > 0) {\n params.set('include', query.include.join(','))\n }\n\n return params.toString()\n }\n\n private async buildHeaders(): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...this.config.headers,\n }\n\n if (this.config.auth) {\n const authHeader = await this.resolveAuthHeader(this.config.auth)\n if (authHeader) {\n Object.assign(headers, authHeader)\n }\n }\n\n return headers\n }\n\n private async resolveAuthHeader(auth: HttpAuthConfig): Promise<Record<string, string> | null> {\n switch (auth.type) {\n case 'bearer': {\n // Resolved per request, never cached — a session-length token is the\n // reason this accepts a function at all. A resolver that answers null\n // yields NO header: the server's own 401 is a truer error than a\n // client-side guess, and the panel's errorWhen already renders it.\n const token = typeof auth.token === 'function' ? await auth.token() : auth.token\n return token ? { Authorization: `Bearer ${token}` } : null\n }\n case 'api-key':\n return auth.apiKey ? { [auth.headerName ?? 'X-API-Key']: auth.apiKey } : null\n case 'basic':\n if (auth.username && auth.password) {\n const encoded = btoa(`${auth.username}:${auth.password}`)\n return { Authorization: `Basic ${encoded}` }\n }\n return null\n default:\n return null\n }\n }\n\n private async request(\n method: string,\n url: string,\n body?: Record<string, unknown>\n ): Promise<ConnectorResult> {\n const retryConfig = this.config.retry ?? DEFAULT_RETRY\n let lastError = ''\n\n for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {\n try {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout)\n\n const response = await fetch(url, {\n method,\n headers: await this.buildHeaders(),\n body: body ? JSON.stringify(body) : null,\n signal: controller.signal,\n ...(this.config.credentials ? { credentials: this.config.credentials } : {}),\n })\n\n clearTimeout(timeoutId)\n\n if (!response.ok) {\n if (\n attempt < retryConfig.maxRetries &&\n retryConfig.retryableStatuses.includes(response.status)\n ) {\n const delay = Math.min(\n retryConfig.baseDelay * Math.pow(2, attempt),\n retryConfig.maxDelay\n )\n await this.sleep(delay)\n continue\n }\n\n const errorBody = await response.text().catch(() => '')\n lastError = `HTTP ${response.status}: ${errorBody || response.statusText}`\n return { success: false, error: lastError }\n }\n\n if (method === 'DELETE' && response.status === 204) {\n return { success: true, data: {} }\n }\n\n const jsonData = await response.json()\n const data = z.record(z.unknown()).parse(jsonData)\n return { success: true, data }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err)\n\n if (attempt < retryConfig.maxRetries) {\n const delay = Math.min(retryConfig.baseDelay * Math.pow(2, attempt), retryConfig.maxDelay)\n await this.sleep(delay)\n continue\n }\n }\n }\n\n return { success: false, error: lastError }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n }\n}\n\n// ============================================================\n// FACTORY\n// ============================================================\n\n/**\n * Create an HTTP entity connector\n */\nexport function createHttpConnector(\n name: string,\n config: HttpConnectorConfig\n): HttpEntityConnector {\n return new HttpEntityConnector(name, config)\n}\n"]}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Entity System Module
3
+ *
4
+ * Entity system for schema-based entity types, CRUD operations,
5
+ * connectors, behaviors, and surface integration.
6
+ *
7
+ * Exports:
8
+ * - Types: EntityTypeId, EntityInstanceId, EntityDefinition, EntityQuery, etc.
9
+ * - Registry: EntityRegistry, InMemoryEntityRegistry, createEntityRegistry
10
+ * - Store: EntityStore, DefaultEntityStore, createEntityStore
11
+ * - Connectors: EntityConnector, ConnectorRegistry, StaticConnector
12
+ * - Lifecycle: EntityLifecycleEngine, EntityLifecycleHook, createEntityLifecycleEngine
13
+ * - Facade: EntityFacade, createEntityFacade
14
+ *
15
+ * @module @pwfabric/runtime/entity
16
+ */
17
+ export type { EntityTypeId, EntityInstanceId, EntityFieldType, EntityFieldDefinition, EntityRelationType, EntityRelationDefinition, EntityDefinition, EntityQuery, EntityFilter, EntitySortField, EntityPagination, EntityQueryResult, EntityAggregateFn, EntityAggregate, EntityAggregateResult, EntityMutationResult, EntityReadResult, EntityOperationError, EntityValidationResult, EntityValidationError, } from './types.js';
18
+ export type { EntityRegistry } from './registry.js';
19
+ export { InMemoryEntityRegistry, createEntityRegistry } from './registry.js';
20
+ export type { EntityStore } from './store.js';
21
+ export { DefaultEntityStore, createEntityStore } from './store.js';
22
+ export type { EntityConnectorType, ConnectorResult, ConnectorQueryResult, ConnectorAggregateResult, EntityConnector, ConnectorRegistry, } from './connector.js';
23
+ export { InMemoryConnectorRegistry, createConnectorRegistry } from './connector.js';
24
+ export { StaticConnector, createStaticConnector } from './connectors/index.js';
25
+ export type { HttpAuthConfig, HttpRetryConfig, HttpConnectorConfig } from './http-connector.js';
26
+ export { HttpEntityConnector, createHttpConnector } from './http-connector.js';
27
+ export type { PostgresConnectorConfig, DatabaseAdapter, DatabaseResult, } from './postgres-connector.js';
28
+ export { PostgresEntityConnector, createPostgresConnector } from './postgres-connector.js';
29
+ export type { EntityLifecycleEngine, EntityLifecycleTransition, EntityLifecycleHook, } from './behavior.js';
30
+ export { DefaultEntityLifecycleEngine, createEntityLifecycleEngine } from './behavior.js';
31
+ export type { EntityLifecycleEvent, EntityBehaviorContext, EntityGuard, EntityAction, } from './behavior.js';
32
+ export type { EntityFacade } from './facade.js';
33
+ export { DefaultEntityFacade, createEntityFacade } from './facade.js';
34
+ export type { EntityDataSourceConfig, EntityDataSource } from './entity-datasource.js';
35
+ export { createEntityDataSource } from './entity-datasource.js';
36
+ export { aggregateEntities, applyEntityQuery, matchesEntityFilter, normalizeEntitySort, sortEntities, } from './apply-query.js';
37
+ export type { AggregateSource } from './aggregate.js';
38
+ export { aggregateThrough } from './aggregate.js';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Entity System Module
3
+ *
4
+ * Entity system for schema-based entity types, CRUD operations,
5
+ * connectors, behaviors, and surface integration.
6
+ *
7
+ * Exports:
8
+ * - Types: EntityTypeId, EntityInstanceId, EntityDefinition, EntityQuery, etc.
9
+ * - Registry: EntityRegistry, InMemoryEntityRegistry, createEntityRegistry
10
+ * - Store: EntityStore, DefaultEntityStore, createEntityStore
11
+ * - Connectors: EntityConnector, ConnectorRegistry, StaticConnector
12
+ * - Lifecycle: EntityLifecycleEngine, EntityLifecycleHook, createEntityLifecycleEngine
13
+ * - Facade: EntityFacade, createEntityFacade
14
+ *
15
+ * @module @pwfabric/runtime/entity
16
+ */
17
+ export { InMemoryEntityRegistry, createEntityRegistry } from './registry.js';
18
+ export { DefaultEntityStore, createEntityStore } from './store.js';
19
+ export { InMemoryConnectorRegistry, createConnectorRegistry } from './connector.js';
20
+ // Connector implementations
21
+ export { StaticConnector, createStaticConnector } from './connectors/index.js';
22
+ export { HttpEntityConnector, createHttpConnector } from './http-connector.js';
23
+ export { PostgresEntityConnector, createPostgresConnector } from './postgres-connector.js';
24
+ export { DefaultEntityLifecycleEngine, createEntityLifecycleEngine } from './behavior.js';
25
+ export { DefaultEntityFacade, createEntityFacade } from './facade.js';
26
+ export { createEntityDataSource } from './entity-datasource.js';
27
+ // applyEntityQuery — the single in-memory applier for EntityQuery
28
+ // (filter → sort → pagination). Connectors call it on their result envelope.
29
+ export { aggregateEntities, applyEntityQuery, matchesEntityFilter, normalizeEntitySort, sortEntities, } from './apply-query.js';
30
+ export { aggregateThrough } from './aggregate.js';
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/entity/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA4BH,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAI5E,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAWlE,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAEnF,4BAA4B;AAC5B,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAI9E,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAQ9E,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAQ1F,OAAO,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAWzF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAIrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAE/D,kEAAkE;AAClE,6EAA6E;AAC7E,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAA;AAKzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA","sourcesContent":["/**\n * Entity System Module\n *\n * Entity system for schema-based entity types, CRUD operations,\n * connectors, behaviors, and surface integration.\n *\n * Exports:\n * - Types: EntityTypeId, EntityInstanceId, EntityDefinition, EntityQuery, etc.\n * - Registry: EntityRegistry, InMemoryEntityRegistry, createEntityRegistry\n * - Store: EntityStore, DefaultEntityStore, createEntityStore\n * - Connectors: EntityConnector, ConnectorRegistry, StaticConnector\n * - Lifecycle: EntityLifecycleEngine, EntityLifecycleHook, createEntityLifecycleEngine\n * - Facade: EntityFacade, createEntityFacade\n *\n * @module @pwfabric/runtime/entity\n */\n\n// Types\nexport type {\n EntityTypeId,\n EntityInstanceId,\n EntityFieldType,\n EntityFieldDefinition,\n EntityRelationType,\n EntityRelationDefinition,\n EntityDefinition,\n EntityQuery,\n EntityFilter,\n EntitySortField,\n EntityPagination,\n EntityQueryResult,\n EntityAggregateFn,\n EntityAggregate,\n EntityAggregateResult,\n EntityMutationResult,\n EntityReadResult,\n EntityOperationError,\n EntityValidationResult,\n EntityValidationError,\n} from './types.js'\n\n// Registry\nexport type { EntityRegistry } from './registry.js'\nexport { InMemoryEntityRegistry, createEntityRegistry } from './registry.js'\n\n// Store\nexport type { EntityStore } from './store.js'\nexport { DefaultEntityStore, createEntityStore } from './store.js'\n\n// Connectors\nexport type {\n EntityConnectorType,\n ConnectorResult,\n ConnectorQueryResult,\n ConnectorAggregateResult,\n EntityConnector,\n ConnectorRegistry,\n} from './connector.js'\nexport { InMemoryConnectorRegistry, createConnectorRegistry } from './connector.js'\n\n// Connector implementations\nexport { StaticConnector, createStaticConnector } from './connectors/index.js'\n\n// HTTP Connector (REST API connector)\nexport type { HttpAuthConfig, HttpRetryConfig, HttpConnectorConfig } from './http-connector.js'\nexport { HttpEntityConnector, createHttpConnector } from './http-connector.js'\n\n// PostgreSQL Connector (Database connector)\nexport type {\n PostgresConnectorConfig,\n DatabaseAdapter,\n DatabaseResult,\n} from './postgres-connector.js'\nexport { PostgresEntityConnector, createPostgresConnector } from './postgres-connector.js'\n\n// Lifecycle\nexport type {\n EntityLifecycleEngine,\n EntityLifecycleTransition,\n EntityLifecycleHook,\n} from './behavior.js'\nexport { DefaultEntityLifecycleEngine, createEntityLifecycleEngine } from './behavior.js'\n\nexport type {\n EntityLifecycleEvent,\n EntityBehaviorContext,\n EntityGuard,\n EntityAction,\n} from './behavior.js'\n\n// Facade\nexport type { EntityFacade } from './facade.js'\nexport { DefaultEntityFacade, createEntityFacade } from './facade.js'\n\n// EntityDataSource adapter for surface expression binding\nexport type { EntityDataSourceConfig, EntityDataSource } from './entity-datasource.js'\nexport { createEntityDataSource } from './entity-datasource.js'\n\n// applyEntityQuery — the single in-memory applier for EntityQuery\n// (filter → sort → pagination). Connectors call it on their result envelope.\nexport {\n aggregateEntities,\n applyEntityQuery,\n matchesEntityFilter,\n normalizeEntitySort,\n sortEntities,\n} from './apply-query.js'\n\n// aggregateThrough — one number from a connector/engine/facade: server-side\n// when it has `aggregate`, its listed rows reduced in memory when it has not.\nexport type { AggregateSource } from './aggregate.js'\nexport { aggregateThrough } from './aggregate.js'\n"]}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * PostgreSQL Entity Connector
3
+ *
4
+ * Database connector for entity data persistence using Drizzle ORM.
5
+ * Implements the EntityConnector interface with PostgreSQL-specific query building.
6
+ *
7
+ * @module @pwfabric/runtime/entity/postgres-connector
8
+ */
9
+ import type { EntityTypeId, EntityInstanceId, EntityQuery } from './types.js';
10
+ import type { EntityConnector, EntityConnectorType, ConnectorResult, ConnectorQueryResult } from './connector.js';
11
+ /**
12
+ * PostgreSQL connector configuration
13
+ */
14
+ export interface PostgresConnectorConfig {
15
+ /**
16
+ * Database connection — either a connection string or a Drizzle db instance.
17
+ * When a string, the connector will create its own connection.
18
+ * When an object, it must implement the DatabaseAdapter interface.
19
+ */
20
+ readonly connection: string | DatabaseAdapter;
21
+ /** Optional table name prefix for multi-tenant isolation */
22
+ readonly tablePrefix?: string;
23
+ /** Default page size for queries */
24
+ readonly defaultPageSize?: number;
25
+ /** Maximum page size to prevent excessive queries */
26
+ readonly maxPageSize?: number;
27
+ }
28
+ /**
29
+ * Minimal database adapter interface.
30
+ * This abstracts over Drizzle ORM or any SQL-capable client.
31
+ */
32
+ export interface DatabaseAdapter {
33
+ execute(sql: string, params?: unknown[]): Promise<DatabaseResult>;
34
+ }
35
+ /**
36
+ * Result of a database query execution
37
+ */
38
+ export interface DatabaseResult {
39
+ readonly rows: Record<string, unknown>[];
40
+ readonly rowCount: number;
41
+ }
42
+ /**
43
+ * PostgreSQL connector for entity data operations.
44
+ * Maps entity CRUD operations to SQL queries via a DatabaseAdapter.
45
+ */
46
+ export declare class PostgresEntityConnector implements EntityConnector {
47
+ readonly name: string;
48
+ readonly type: EntityConnectorType;
49
+ private readonly db;
50
+ private readonly tablePrefix;
51
+ private readonly defaultPageSize;
52
+ private readonly maxPageSize;
53
+ constructor(name: string, config: PostgresConnectorConfig);
54
+ private tableName;
55
+ create(entityType: EntityTypeId, data: Record<string, unknown>): Promise<ConnectorResult>;
56
+ read(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult>;
57
+ update(entityType: EntityTypeId, instanceId: EntityInstanceId, data: Record<string, unknown>): Promise<ConnectorResult>;
58
+ delete(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult>;
59
+ query(entityType: EntityTypeId, query: EntityQuery): Promise<ConnectorQueryResult>;
60
+ }
61
+ /**
62
+ * Create a PostgreSQL entity connector
63
+ */
64
+ export declare function createPostgresConnector(name: string, config: PostgresConnectorConfig): PostgresEntityConnector;