@happyvertical/smrt-core 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (631) hide show
  1. package/AGENTS.md +124 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +265 -0
  5. package/bin/smrt-prebuild.js +26 -0
  6. package/dist/__tests__/fixtures/advisor-test-classes.d.ts +28 -0
  7. package/dist/__tests__/fixtures/advisor-test-classes.d.ts.map +1 -0
  8. package/dist/__tests__/fixtures/collection-coverage-fixtures.d.ts +12 -0
  9. package/dist/__tests__/fixtures/collection-coverage-fixtures.d.ts.map +1 -0
  10. package/dist/__tests__/fixtures/inheritance-resolver-fixtures.d.ts +28 -0
  11. package/dist/__tests__/fixtures/inheritance-resolver-fixtures.d.ts.map +1 -0
  12. package/dist/__tests__/fixtures/inheritance-test-classes.d.ts +43 -0
  13. package/dist/__tests__/fixtures/inheritance-test-classes.d.ts.map +1 -0
  14. package/dist/__tests__/fixtures/mcp-integration-test-classes.d.ts +18 -0
  15. package/dist/__tests__/fixtures/mcp-integration-test-classes.d.ts.map +1 -0
  16. package/dist/__tests__/fixtures/object-ai-memory-fixtures.d.ts +15 -0
  17. package/dist/__tests__/fixtures/object-ai-memory-fixtures.d.ts.map +1 -0
  18. package/dist/__tests__/fixtures/object-spec-test-classes.d.ts +13 -0
  19. package/dist/__tests__/fixtures/object-spec-test-classes.d.ts.map +1 -0
  20. package/dist/__tests__/fixtures/registry-test-classes.d.ts +23 -0
  21. package/dist/__tests__/fixtures/registry-test-classes.d.ts.map +1 -0
  22. package/dist/adapters/ai-usage.d.ts +23 -0
  23. package/dist/adapters/ai-usage.d.ts.map +1 -0
  24. package/dist/adapters/ai-usage.js +105 -0
  25. package/dist/adapters/ai-usage.js.map +1 -0
  26. package/dist/adapters/cost-rates.d.ts +20 -0
  27. package/dist/adapters/cost-rates.d.ts.map +1 -0
  28. package/dist/adapters/cost-rates.js +40 -0
  29. package/dist/adapters/cost-rates.js.map +1 -0
  30. package/dist/adapters/index.d.ts +19 -0
  31. package/dist/adapters/index.d.ts.map +1 -0
  32. package/dist/adapters/metrics.d.ts +111 -0
  33. package/dist/adapters/metrics.d.ts.map +1 -0
  34. package/dist/adapters/metrics.js +169 -0
  35. package/dist/adapters/metrics.js.map +1 -0
  36. package/dist/adapters/pubsub.d.ts +124 -0
  37. package/dist/adapters/pubsub.d.ts.map +1 -0
  38. package/dist/adapters/pubsub.js +121 -0
  39. package/dist/adapters/pubsub.js.map +1 -0
  40. package/dist/browser.d.ts +32 -0
  41. package/dist/browser.d.ts.map +1 -0
  42. package/dist/browser.js +68 -0
  43. package/dist/browser.js.map +1 -0
  44. package/dist/child-accessors.d.ts +27 -0
  45. package/dist/child-accessors.d.ts.map +1 -0
  46. package/dist/child-accessors.js +35 -0
  47. package/dist/child-accessors.js.map +1 -0
  48. package/dist/class.d.ts +313 -0
  49. package/dist/class.d.ts.map +1 -0
  50. package/dist/class.js +896 -0
  51. package/dist/class.js.map +1 -0
  52. package/dist/collection-cache.d.ts +110 -0
  53. package/dist/collection-cache.d.ts.map +1 -0
  54. package/dist/collection-cache.js +187 -0
  55. package/dist/collection-cache.js.map +1 -0
  56. package/dist/collection.d.ts +894 -0
  57. package/dist/collection.d.ts.map +1 -0
  58. package/dist/collection.js +1987 -0
  59. package/dist/collection.js.map +1 -0
  60. package/dist/config/global-config.d.ts +3 -0
  61. package/dist/config/global-config.d.ts.map +1 -0
  62. package/dist/config/global-config.js +19 -0
  63. package/dist/config/global-config.js.map +1 -0
  64. package/dist/config.d.ts +145 -0
  65. package/dist/config.d.ts.map +1 -0
  66. package/dist/config.js +57 -0
  67. package/dist/config.js.map +1 -0
  68. package/dist/consumer-plugin/index.d.ts +22 -0
  69. package/dist/consumer-plugin/index.d.ts.map +1 -0
  70. package/dist/consumer-plugin/index.js +452 -0
  71. package/dist/consumer-plugin/index.js.map +1 -0
  72. package/dist/consumer-plugin.d.ts +8 -0
  73. package/dist/consumer-plugin.d.ts.map +1 -0
  74. package/dist/consumer-plugin.js +5 -0
  75. package/dist/consumer-plugin.js.map +1 -0
  76. package/dist/database.d.ts +95 -0
  77. package/dist/database.d.ts.map +1 -0
  78. package/dist/database.js +32 -0
  79. package/dist/database.js.map +1 -0
  80. package/dist/decorators/compatibility.d.ts +14 -0
  81. package/dist/decorators/compatibility.d.ts.map +1 -0
  82. package/dist/decorators/compatibility.js +111 -0
  83. package/dist/decorators/compatibility.js.map +1 -0
  84. package/dist/decorators/index.d.ts +381 -0
  85. package/dist/decorators/index.d.ts.map +1 -0
  86. package/dist/decorators/index.js +104 -0
  87. package/dist/decorators/index.js.map +1 -0
  88. package/dist/dispatch/bus.d.ts +306 -0
  89. package/dist/dispatch/bus.d.ts.map +1 -0
  90. package/dist/dispatch/bus.js +583 -0
  91. package/dist/dispatch/bus.js.map +1 -0
  92. package/dist/dispatch/collections/DispatchSubscriptions.d.ts +79 -0
  93. package/dist/dispatch/collections/DispatchSubscriptions.d.ts.map +1 -0
  94. package/dist/dispatch/collections/DispatchSubscriptions.js +243 -0
  95. package/dist/dispatch/collections/DispatchSubscriptions.js.map +1 -0
  96. package/dist/dispatch/collections/Dispatches.d.ts +98 -0
  97. package/dist/dispatch/collections/Dispatches.d.ts.map +1 -0
  98. package/dist/dispatch/collections/Dispatches.js +358 -0
  99. package/dist/dispatch/collections/Dispatches.js.map +1 -0
  100. package/dist/dispatch/index.d.ts +47 -0
  101. package/dist/dispatch/index.d.ts.map +1 -0
  102. package/dist/dispatch/models/Dispatch.d.ts +101 -0
  103. package/dist/dispatch/models/Dispatch.d.ts.map +1 -0
  104. package/dist/dispatch/models/Dispatch.js +162 -0
  105. package/dist/dispatch/models/Dispatch.js.map +1 -0
  106. package/dist/dispatch/models/DispatchSubscription.d.ts +83 -0
  107. package/dist/dispatch/models/DispatchSubscription.d.ts.map +1 -0
  108. package/dist/dispatch/models/DispatchSubscription.js +112 -0
  109. package/dist/dispatch/models/DispatchSubscription.js.map +1 -0
  110. package/dist/dispatch/tenant-resolver.d.ts +98 -0
  111. package/dist/dispatch/tenant-resolver.d.ts.map +1 -0
  112. package/dist/dispatch/tenant-resolver.js +32 -0
  113. package/dist/dispatch/tenant-resolver.js.map +1 -0
  114. package/dist/dispatch/types.d.ts +149 -0
  115. package/dist/dispatch/types.d.ts.map +1 -0
  116. package/dist/embeddings/hash.d.ts +33 -0
  117. package/dist/embeddings/hash.d.ts.map +1 -0
  118. package/dist/embeddings/hash.js +37 -0
  119. package/dist/embeddings/hash.js.map +1 -0
  120. package/dist/embeddings/index.d.ts +36 -0
  121. package/dist/embeddings/index.d.ts.map +1 -0
  122. package/dist/embeddings/provider.d.ts +75 -0
  123. package/dist/embeddings/provider.d.ts.map +1 -0
  124. package/dist/embeddings/provider.js +170 -0
  125. package/dist/embeddings/provider.js.map +1 -0
  126. package/dist/embeddings/similarity.d.ts +47 -0
  127. package/dist/embeddings/similarity.d.ts.map +1 -0
  128. package/dist/embeddings/similarity.js +64 -0
  129. package/dist/embeddings/similarity.js.map +1 -0
  130. package/dist/embeddings/storage.d.ts +125 -0
  131. package/dist/embeddings/storage.d.ts.map +1 -0
  132. package/dist/embeddings/storage.js +283 -0
  133. package/dist/embeddings/storage.js.map +1 -0
  134. package/dist/embeddings/types.d.ts +250 -0
  135. package/dist/embeddings/types.d.ts.map +1 -0
  136. package/dist/errors.d.ts +363 -0
  137. package/dist/errors.d.ts.map +1 -0
  138. package/dist/errors.js +669 -0
  139. package/dist/errors.js.map +1 -0
  140. package/dist/generators/cli.d.ts +162 -0
  141. package/dist/generators/cli.d.ts.map +1 -0
  142. package/dist/generators/cli.js +462 -0
  143. package/dist/generators/cli.js.map +1 -0
  144. package/dist/generators/index.d.ts +13 -0
  145. package/dist/generators/index.d.ts.map +1 -0
  146. package/dist/generators/mcp-runtime-template.d.ts +60 -0
  147. package/dist/generators/mcp-runtime-template.d.ts.map +1 -0
  148. package/dist/generators/mcp-runtime-template.js +509 -0
  149. package/dist/generators/mcp-runtime-template.js.map +1 -0
  150. package/dist/generators/mcp.d.ts +231 -0
  151. package/dist/generators/mcp.d.ts.map +1 -0
  152. package/dist/generators/mcp.js +1220 -0
  153. package/dist/generators/mcp.js.map +1 -0
  154. package/dist/generators/rest.d.ts +171 -0
  155. package/dist/generators/rest.d.ts.map +1 -0
  156. package/dist/generators/rest.js +591 -0
  157. package/dist/generators/rest.js.map +1 -0
  158. package/dist/generators/swagger.d.ts +21 -0
  159. package/dist/generators/swagger.d.ts.map +1 -0
  160. package/dist/generators/swagger.js +307 -0
  161. package/dist/generators/swagger.js.map +1 -0
  162. package/dist/generators/tenant-gate.d.ts +74 -0
  163. package/dist/generators/tenant-gate.d.ts.map +1 -0
  164. package/dist/generators/tenant-gate.js +15 -0
  165. package/dist/generators/tenant-gate.js.map +1 -0
  166. package/dist/generators.d.ts +8 -0
  167. package/dist/generators.d.ts.map +1 -0
  168. package/dist/generators.js +19 -0
  169. package/dist/generators.js.map +1 -0
  170. package/dist/hierarchical.d.ts +103 -0
  171. package/dist/hierarchical.d.ts.map +1 -0
  172. package/dist/hierarchical.js +184 -0
  173. package/dist/hierarchical.js.map +1 -0
  174. package/dist/index.d.ts +57 -0
  175. package/dist/index.d.ts.map +1 -0
  176. package/dist/index.js +202 -0
  177. package/dist/index.js.map +1 -0
  178. package/dist/interceptors.d.ts +251 -0
  179. package/dist/interceptors.d.ts.map +1 -0
  180. package/dist/interceptors.js +259 -0
  181. package/dist/interceptors.js.map +1 -0
  182. package/dist/junction.d.ts +99 -0
  183. package/dist/junction.d.ts.map +1 -0
  184. package/dist/junction.js +136 -0
  185. package/dist/junction.js.map +1 -0
  186. package/dist/knowledge.d.ts +11 -0
  187. package/dist/knowledge.d.ts.map +1 -0
  188. package/dist/knowledge.js +310 -0
  189. package/dist/knowledge.js.map +1 -0
  190. package/dist/lazy-config.d.ts +160 -0
  191. package/dist/lazy-config.d.ts.map +1 -0
  192. package/dist/lazy-config.js +146 -0
  193. package/dist/lazy-config.js.map +1 -0
  194. package/dist/manifest/discover-base-classes.d.ts +78 -0
  195. package/dist/manifest/discover-base-classes.d.ts.map +1 -0
  196. package/dist/manifest/discover-base-classes.js +85 -0
  197. package/dist/manifest/discover-base-classes.js.map +1 -0
  198. package/dist/manifest/discover-smrt-packages.d.ts +48 -0
  199. package/dist/manifest/discover-smrt-packages.d.ts.map +1 -0
  200. package/dist/manifest/discover-smrt-packages.js +361 -0
  201. package/dist/manifest/discover-smrt-packages.js.map +1 -0
  202. package/dist/manifest/generator.d.ts +93 -0
  203. package/dist/manifest/generator.d.ts.map +1 -0
  204. package/dist/manifest/generator.js +380 -0
  205. package/dist/manifest/generator.js.map +1 -0
  206. package/dist/manifest/index.d.ts +16 -0
  207. package/dist/manifest/index.d.ts.map +1 -0
  208. package/dist/manifest/index.js +51 -0
  209. package/dist/manifest/index.js.map +1 -0
  210. package/dist/manifest/manager.d.ts +51 -0
  211. package/dist/manifest/manager.d.ts.map +1 -0
  212. package/dist/manifest/manager.js +89 -0
  213. package/dist/manifest/manager.js.map +1 -0
  214. package/dist/manifest/manifest-loader.d.ts +187 -0
  215. package/dist/manifest/manifest-loader.d.ts.map +1 -0
  216. package/dist/manifest/manifest-loader.js +847 -0
  217. package/dist/manifest/manifest-loader.js.map +1 -0
  218. package/dist/manifest/sources/composite.d.ts +22 -0
  219. package/dist/manifest/sources/composite.d.ts.map +1 -0
  220. package/dist/manifest/sources/composite.js +60 -0
  221. package/dist/manifest/sources/composite.js.map +1 -0
  222. package/dist/manifest/sources/embedded.d.ts +7 -0
  223. package/dist/manifest/sources/embedded.d.ts.map +1 -0
  224. package/dist/manifest/sources/embedded.js +30 -0
  225. package/dist/manifest/sources/embedded.js.map +1 -0
  226. package/dist/manifest/sources/explicit-paths.d.ts +17 -0
  227. package/dist/manifest/sources/explicit-paths.d.ts.map +1 -0
  228. package/dist/manifest/sources/explicit-paths.js +35 -0
  229. package/dist/manifest/sources/explicit-paths.js.map +1 -0
  230. package/dist/manifest/sources/fallback.d.ts +25 -0
  231. package/dist/manifest/sources/fallback.d.ts.map +1 -0
  232. package/dist/manifest/sources/fallback.js +63 -0
  233. package/dist/manifest/sources/fallback.js.map +1 -0
  234. package/dist/manifest/sources/index.d.ts +17 -0
  235. package/dist/manifest/sources/index.d.ts.map +1 -0
  236. package/dist/manifest/sources/local-test.d.ts +7 -0
  237. package/dist/manifest/sources/local-test.d.ts.map +1 -0
  238. package/dist/manifest/sources/local-test.js +21 -0
  239. package/dist/manifest/sources/local-test.js.map +1 -0
  240. package/dist/manifest/sources/static.d.ts +7 -0
  241. package/dist/manifest/sources/static.d.ts.map +1 -0
  242. package/dist/manifest/sources/static.js +19 -0
  243. package/dist/manifest/sources/static.js.map +1 -0
  244. package/dist/manifest/sources/test.d.ts +7 -0
  245. package/dist/manifest/sources/test.d.ts.map +1 -0
  246. package/dist/manifest/sources/test.js +21 -0
  247. package/dist/manifest/sources/test.js.map +1 -0
  248. package/dist/manifest/sources/types.d.ts +79 -0
  249. package/dist/manifest/sources/types.d.ts.map +1 -0
  250. package/dist/manifest/sources/types.js +61 -0
  251. package/dist/manifest/sources/types.js.map +1 -0
  252. package/dist/manifest/static-manifest.d.ts +4 -0
  253. package/dist/manifest/static-manifest.d.ts.map +1 -0
  254. package/dist/manifest/static-manifest.js +1535 -0
  255. package/dist/manifest/static-manifest.js.map +1 -0
  256. package/dist/manifest/store.d.ts +111 -0
  257. package/dist/manifest/store.d.ts.map +1 -0
  258. package/dist/manifest/store.js +431 -0
  259. package/dist/manifest/store.js.map +1 -0
  260. package/dist/manifest/test-manifest-loader.d.ts +3 -0
  261. package/dist/manifest/test-manifest-loader.d.ts.map +1 -0
  262. package/dist/manifest/test-manifest-stub.d.ts +4 -0
  263. package/dist/manifest/test-manifest-stub.d.ts.map +1 -0
  264. package/dist/manifest/test-manifest-stub.js +80013 -0
  265. package/dist/manifest/test-manifest-stub.js.map +1 -0
  266. package/dist/manifest.d.ts +8 -0
  267. package/dist/manifest.d.ts.map +1 -0
  268. package/dist/manifest.js +20 -0
  269. package/dist/manifest.js.map +1 -0
  270. package/dist/manifest.json +1489 -0
  271. package/dist/mcp-advisor/index.d.ts +499 -0
  272. package/dist/mcp-advisor/index.d.ts.map +1 -0
  273. package/dist/mcp-advisor/tools/add-ai-methods.d.ts +6 -0
  274. package/dist/mcp-advisor/tools/add-ai-methods.d.ts.map +1 -0
  275. package/dist/mcp-advisor/tools/configure-decorators.d.ts +6 -0
  276. package/dist/mcp-advisor/tools/configure-decorators.d.ts.map +1 -0
  277. package/dist/mcp-advisor/tools/generate-collection.d.ts +6 -0
  278. package/dist/mcp-advisor/tools/generate-collection.d.ts.map +1 -0
  279. package/dist/mcp-advisor/tools/generate-field-definitions.d.ts +6 -0
  280. package/dist/mcp-advisor/tools/generate-field-definitions.d.ts.map +1 -0
  281. package/dist/mcp-advisor/tools/generate-smrt-class.d.ts +6 -0
  282. package/dist/mcp-advisor/tools/generate-smrt-class.d.ts.map +1 -0
  283. package/dist/mcp-advisor/tools/get-object-config.d.ts +6 -0
  284. package/dist/mcp-advisor/tools/get-object-config.d.ts.map +1 -0
  285. package/dist/mcp-advisor/tools/get-object-schema.d.ts +10 -0
  286. package/dist/mcp-advisor/tools/get-object-schema.d.ts.map +1 -0
  287. package/dist/mcp-advisor/tools/list-registered-objects.d.ts +9 -0
  288. package/dist/mcp-advisor/tools/list-registered-objects.d.ts.map +1 -0
  289. package/dist/mcp-advisor/tools/preview-api-endpoints.d.ts +9 -0
  290. package/dist/mcp-advisor/tools/preview-api-endpoints.d.ts.map +1 -0
  291. package/dist/mcp-advisor/tools/preview-mcp-tools.d.ts +9 -0
  292. package/dist/mcp-advisor/tools/preview-mcp-tools.d.ts.map +1 -0
  293. package/dist/mcp-advisor/tools/validate-smrt-object.d.ts +6 -0
  294. package/dist/mcp-advisor/tools/validate-smrt-object.d.ts.map +1 -0
  295. package/dist/mcp-advisor/types.d.ts +209 -0
  296. package/dist/mcp-advisor/types.d.ts.map +1 -0
  297. package/dist/migrations/backfill-tracker.d.ts +84 -0
  298. package/dist/migrations/backfill-tracker.d.ts.map +1 -0
  299. package/dist/migrations/backfill-tracker.js +118 -0
  300. package/dist/migrations/backfill-tracker.js.map +1 -0
  301. package/dist/migrations/checksum.d.ts +43 -0
  302. package/dist/migrations/checksum.d.ts.map +1 -0
  303. package/dist/migrations/checksum.js +32 -0
  304. package/dist/migrations/checksum.js.map +1 -0
  305. package/dist/migrations/differ.d.ts +186 -0
  306. package/dist/migrations/differ.d.ts.map +1 -0
  307. package/dist/migrations/differ.js +601 -0
  308. package/dist/migrations/differ.js.map +1 -0
  309. package/dist/migrations/generator.d.ts +133 -0
  310. package/dist/migrations/generator.d.ts.map +1 -0
  311. package/dist/migrations/generator.js +328 -0
  312. package/dist/migrations/generator.js.map +1 -0
  313. package/dist/migrations/index.d.ts +20 -0
  314. package/dist/migrations/index.d.ts.map +1 -0
  315. package/dist/migrations/orchestrate.d.ts +148 -0
  316. package/dist/migrations/orchestrate.d.ts.map +1 -0
  317. package/dist/migrations/orchestrate.js +118 -0
  318. package/dist/migrations/orchestrate.js.map +1 -0
  319. package/dist/migrations/tracker.d.ts +134 -0
  320. package/dist/migrations/tracker.d.ts.map +1 -0
  321. package/dist/migrations/tracker.js +624 -0
  322. package/dist/migrations/tracker.js.map +1 -0
  323. package/dist/migrations/types.d.ts +221 -0
  324. package/dist/migrations/types.d.ts.map +1 -0
  325. package/dist/migrations.d.ts +7 -0
  326. package/dist/migrations.d.ts.map +1 -0
  327. package/dist/migrations.js +26 -0
  328. package/dist/migrations.js.map +1 -0
  329. package/dist/node_modules/.pnpm/balanced-match@4.0.4/node_modules/balanced-match/dist/esm/index.js +56 -0
  330. package/dist/node_modules/.pnpm/balanced-match@4.0.4/node_modules/balanced-match/dist/esm/index.js.map +1 -0
  331. package/dist/node_modules/.pnpm/brace-expansion@5.0.5/node_modules/brace-expansion/dist/esm/index.js +163 -0
  332. package/dist/node_modules/.pnpm/brace-expansion@5.0.5/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
  333. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/assert-valid-pattern.js +13 -0
  334. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -0
  335. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/ast.js +654 -0
  336. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/ast.js.map +1 -0
  337. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/brace-expressions.js +111 -0
  338. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -0
  339. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/escape.js +10 -0
  340. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/escape.js.map +1 -0
  341. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/index.js +824 -0
  342. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/index.js.map +1 -0
  343. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/unescape.js +10 -0
  344. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/unescape.js.map +1 -0
  345. package/dist/object.d.ts +1202 -0
  346. package/dist/object.d.ts.map +1 -0
  347. package/dist/object.js +2731 -0
  348. package/dist/object.js.map +1 -0
  349. package/dist/polymorphic-association.d.ts +69 -0
  350. package/dist/polymorphic-association.d.ts.map +1 -0
  351. package/dist/polymorphic-association.js +96 -0
  352. package/dist/polymorphic-association.js.map +1 -0
  353. package/dist/prebuild/cli.d.ts +7 -0
  354. package/dist/prebuild/cli.d.ts.map +1 -0
  355. package/dist/prebuild/cli.js +29 -0
  356. package/dist/prebuild/cli.js.map +1 -0
  357. package/dist/prebuild/index.d.ts +22 -0
  358. package/dist/prebuild/index.d.ts.map +1 -0
  359. package/dist/prebuild/index.js +239 -0
  360. package/dist/prebuild/index.js.map +1 -0
  361. package/dist/prebuild.d.ts +8 -0
  362. package/dist/prebuild.d.ts.map +1 -0
  363. package/dist/prebuild.js +6 -0
  364. package/dist/prebuild.js.map +1 -0
  365. package/dist/registry/cache-config.d.ts +13 -0
  366. package/dist/registry/cache-config.d.ts.map +1 -0
  367. package/dist/registry/cache-config.js +17 -0
  368. package/dist/registry/cache-config.js.map +1 -0
  369. package/dist/registry/class-registration.d.ts +31 -0
  370. package/dist/registry/class-registration.d.ts.map +1 -0
  371. package/dist/registry/class-registration.js +1074 -0
  372. package/dist/registry/class-registration.js.map +1 -0
  373. package/dist/registry/collection-resolution.d.ts +45 -0
  374. package/dist/registry/collection-resolution.d.ts.map +1 -0
  375. package/dist/registry/collection-resolution.js +121 -0
  376. package/dist/registry/collection-resolution.js.map +1 -0
  377. package/dist/registry/collision-policy.d.ts +179 -0
  378. package/dist/registry/collision-policy.d.ts.map +1 -0
  379. package/dist/registry/collision-policy.js +153 -0
  380. package/dist/registry/collision-policy.js.map +1 -0
  381. package/dist/registry/diagnostics.d.ts +58 -0
  382. package/dist/registry/diagnostics.d.ts.map +1 -0
  383. package/dist/registry/diagnostics.js +54 -0
  384. package/dist/registry/diagnostics.js.map +1 -0
  385. package/dist/registry/embedding-manager.d.ts +23 -0
  386. package/dist/registry/embedding-manager.d.ts.map +1 -0
  387. package/dist/registry/embedding-manager.js +62 -0
  388. package/dist/registry/embedding-manager.js.map +1 -0
  389. package/dist/registry/index.d.ts +13 -0
  390. package/dist/registry/index.d.ts.map +1 -0
  391. package/dist/registry/inheritance-resolver.d.ts +13 -0
  392. package/dist/registry/inheritance-resolver.d.ts.map +1 -0
  393. package/dist/registry/inheritance-resolver.js +244 -0
  394. package/dist/registry/inheritance-resolver.js.map +1 -0
  395. package/dist/registry/manifest-field-merge.d.ts +4 -0
  396. package/dist/registry/manifest-field-merge.d.ts.map +1 -0
  397. package/dist/registry/manifest-field-merge.js +82 -0
  398. package/dist/registry/manifest-field-merge.js.map +1 -0
  399. package/dist/registry/name-resolver.d.ts +102 -0
  400. package/dist/registry/name-resolver.d.ts.map +1 -0
  401. package/dist/registry/name-resolver.js +241 -0
  402. package/dist/registry/name-resolver.js.map +1 -0
  403. package/dist/registry/relationship-graph.d.ts +16 -0
  404. package/dist/registry/relationship-graph.d.ts.map +1 -0
  405. package/dist/registry/relationship-graph.js +79 -0
  406. package/dist/registry/relationship-graph.js.map +1 -0
  407. package/dist/registry/schema-builder.d.ts +113 -0
  408. package/dist/registry/schema-builder.d.ts.map +1 -0
  409. package/dist/registry/schema-builder.js +474 -0
  410. package/dist/registry/schema-builder.js.map +1 -0
  411. package/dist/registry/shared-state.d.ts +62 -0
  412. package/dist/registry/shared-state.d.ts.map +1 -0
  413. package/dist/registry/shared-state.js +135 -0
  414. package/dist/registry/shared-state.js.map +1 -0
  415. package/dist/registry/types.d.ts +667 -0
  416. package/dist/registry/types.d.ts.map +1 -0
  417. package/dist/registry/validator.d.ts +13 -0
  418. package/dist/registry/validator.d.ts.map +1 -0
  419. package/dist/registry/validator.js +138 -0
  420. package/dist/registry/validator.js.map +1 -0
  421. package/dist/registry.d.ts +1358 -0
  422. package/dist/registry.d.ts.map +1 -0
  423. package/dist/registry.js +2301 -0
  424. package/dist/registry.js.map +1 -0
  425. package/dist/runtime/client.d.ts +34 -0
  426. package/dist/runtime/client.d.ts.map +1 -0
  427. package/dist/runtime/client.js +104 -0
  428. package/dist/runtime/client.js.map +1 -0
  429. package/dist/runtime/index.d.ts +10 -0
  430. package/dist/runtime/index.d.ts.map +1 -0
  431. package/dist/runtime/mcp.d.ts +47 -0
  432. package/dist/runtime/mcp.d.ts.map +1 -0
  433. package/dist/runtime/mcp.js +72 -0
  434. package/dist/runtime/mcp.js.map +1 -0
  435. package/dist/runtime/server.d.ts +92 -0
  436. package/dist/runtime/server.d.ts.map +1 -0
  437. package/dist/runtime/server.js +390 -0
  438. package/dist/runtime/server.js.map +1 -0
  439. package/dist/runtime/types.d.ts +58 -0
  440. package/dist/runtime/types.d.ts.map +1 -0
  441. package/dist/runtime.d.ts +8 -0
  442. package/dist/runtime.d.ts.map +1 -0
  443. package/dist/runtime.js +10 -0
  444. package/dist/runtime.js.map +1 -0
  445. package/dist/scanner/import-scanner.d.ts +7 -0
  446. package/dist/scanner/import-scanner.d.ts.map +1 -0
  447. package/dist/scanner/index.d.ts +12 -0
  448. package/dist/scanner/index.d.ts.map +1 -0
  449. package/dist/scanner/manifest-generator.d.ts +304 -0
  450. package/dist/scanner/manifest-generator.d.ts.map +1 -0
  451. package/dist/scanner/manifest-generator.js +1707 -0
  452. package/dist/scanner/manifest-generator.js.map +1 -0
  453. package/dist/scanner/test-file-patterns.d.ts +18 -0
  454. package/dist/scanner/test-file-patterns.d.ts.map +1 -0
  455. package/dist/scanner/test-file-patterns.js +16 -0
  456. package/dist/scanner/test-file-patterns.js.map +1 -0
  457. package/dist/scanner/types.d.ts +313 -0
  458. package/dist/scanner/types.d.ts.map +1 -0
  459. package/dist/scanner/types.js +2 -0
  460. package/dist/scanner/types.js.map +1 -0
  461. package/dist/scanner.d.ts +6 -0
  462. package/dist/scanner.d.ts.map +1 -0
  463. package/dist/scanner.js +6 -0
  464. package/dist/scanner.js.map +1 -0
  465. package/dist/schema/code-generator.d.ts +53 -0
  466. package/dist/schema/code-generator.d.ts.map +1 -0
  467. package/dist/schema/ddl/base-strategy.d.ts +80 -0
  468. package/dist/schema/ddl/base-strategy.d.ts.map +1 -0
  469. package/dist/schema/ddl/base-strategy.js +240 -0
  470. package/dist/schema/ddl/base-strategy.js.map +1 -0
  471. package/dist/schema/ddl/duckdb-strategy.d.ts +33 -0
  472. package/dist/schema/ddl/duckdb-strategy.d.ts.map +1 -0
  473. package/dist/schema/ddl/duckdb-strategy.js +74 -0
  474. package/dist/schema/ddl/duckdb-strategy.js.map +1 -0
  475. package/dist/schema/ddl/index.d.ts +53 -0
  476. package/dist/schema/ddl/index.d.ts.map +1 -0
  477. package/dist/schema/ddl/index.js +80 -0
  478. package/dist/schema/ddl/index.js.map +1 -0
  479. package/dist/schema/ddl/json-duckdb-strategy.d.ts +8 -0
  480. package/dist/schema/ddl/json-duckdb-strategy.d.ts.map +1 -0
  481. package/dist/schema/ddl/json-duckdb-strategy.js +14 -0
  482. package/dist/schema/ddl/json-duckdb-strategy.js.map +1 -0
  483. package/dist/schema/ddl/postgres-strategy.d.ts +29 -0
  484. package/dist/schema/ddl/postgres-strategy.d.ts.map +1 -0
  485. package/dist/schema/ddl/postgres-strategy.js +102 -0
  486. package/dist/schema/ddl/postgres-strategy.js.map +1 -0
  487. package/dist/schema/ddl/sqlite-strategy.d.ts +38 -0
  488. package/dist/schema/ddl/sqlite-strategy.d.ts.map +1 -0
  489. package/dist/schema/ddl/sqlite-strategy.js +74 -0
  490. package/dist/schema/ddl/sqlite-strategy.js.map +1 -0
  491. package/dist/schema/ddl/types.d.ts +114 -0
  492. package/dist/schema/ddl/types.d.ts.map +1 -0
  493. package/dist/schema/generator.d.ts +176 -0
  494. package/dist/schema/generator.d.ts.map +1 -0
  495. package/dist/schema/generator.js +1076 -0
  496. package/dist/schema/generator.js.map +1 -0
  497. package/dist/schema/index-utils.d.ts +19 -0
  498. package/dist/schema/index-utils.d.ts.map +1 -0
  499. package/dist/schema/index-utils.js +32 -0
  500. package/dist/schema/index-utils.js.map +1 -0
  501. package/dist/schema/index.d.ts +13 -0
  502. package/dist/schema/index.d.ts.map +1 -0
  503. package/dist/schema/override-system.d.ts +43 -0
  504. package/dist/schema/override-system.d.ts.map +1 -0
  505. package/dist/schema/schema-aggregator.d.ts +112 -0
  506. package/dist/schema/schema-aggregator.d.ts.map +1 -0
  507. package/dist/schema/schema-manager.d.ts +95 -0
  508. package/dist/schema/schema-manager.d.ts.map +1 -0
  509. package/dist/schema/schema-manager.js +283 -0
  510. package/dist/schema/schema-manager.js.map +1 -0
  511. package/dist/schema/sql-identifiers.d.ts +107 -0
  512. package/dist/schema/sql-identifiers.d.ts.map +1 -0
  513. package/dist/schema/sql-identifiers.js +190 -0
  514. package/dist/schema/sql-identifiers.js.map +1 -0
  515. package/dist/schema/table-verifier.d.ts +10 -0
  516. package/dist/schema/table-verifier.d.ts.map +1 -0
  517. package/dist/schema/table-verifier.js +37 -0
  518. package/dist/schema/table-verifier.js.map +1 -0
  519. package/dist/schema/types.d.ts +241 -0
  520. package/dist/schema/types.d.ts.map +1 -0
  521. package/dist/schema/utils.d.ts +32 -0
  522. package/dist/schema/utils.d.ts.map +1 -0
  523. package/dist/schema/utils.js +134 -0
  524. package/dist/schema/utils.js.map +1 -0
  525. package/dist/scripts/create-wrappers.js +89 -0
  526. package/dist/scripts/generate-manifest.js +155 -0
  527. package/dist/scripts/generate-test-manifest.js +77 -0
  528. package/dist/scripts/migrate-datetime-to-timestamp.ts +310 -0
  529. package/dist/scripts/prepack.js +49 -0
  530. package/dist/signals/bus.d.ts +64 -0
  531. package/dist/signals/bus.d.ts.map +1 -0
  532. package/dist/signals/bus.js +102 -0
  533. package/dist/signals/bus.js.map +1 -0
  534. package/dist/signals/index.d.ts +11 -0
  535. package/dist/signals/index.d.ts.map +1 -0
  536. package/dist/signals/sanitizer.d.ts +54 -0
  537. package/dist/signals/sanitizer.d.ts.map +1 -0
  538. package/dist/signals/sanitizer.js +111 -0
  539. package/dist/signals/sanitizer.js.map +1 -0
  540. package/dist/smrt-knowledge.json +335 -0
  541. package/dist/system/compatibility.d.ts +8 -0
  542. package/dist/system/compatibility.d.ts.map +1 -0
  543. package/dist/system/compatibility.js +409 -0
  544. package/dist/system/compatibility.js.map +1 -0
  545. package/dist/system/index.d.ts +9 -0
  546. package/dist/system/index.d.ts.map +1 -0
  547. package/dist/system/schema.d.ts +69 -0
  548. package/dist/system/schema.d.ts.map +1 -0
  549. package/dist/system/schema.js +271 -0
  550. package/dist/system/schema.js.map +1 -0
  551. package/dist/system/types.d.ts +135 -0
  552. package/dist/system/types.d.ts.map +1 -0
  553. package/dist/system-fields.d.ts +44 -0
  554. package/dist/system-fields.d.ts.map +1 -0
  555. package/dist/system-fields.js +55 -0
  556. package/dist/system-fields.js.map +1 -0
  557. package/dist/table-cache.d.ts +28 -0
  558. package/dist/table-cache.d.ts.map +1 -0
  559. package/dist/table-cache.js +21 -0
  560. package/dist/table-cache.js.map +1 -0
  561. package/dist/test-utils.d.ts +140 -0
  562. package/dist/test-utils.d.ts.map +1 -0
  563. package/dist/testing/database.d.ts +73 -0
  564. package/dist/testing/database.d.ts.map +1 -0
  565. package/dist/testing/database.js +204 -0
  566. package/dist/testing/database.js.map +1 -0
  567. package/dist/testing/index.d.ts +21 -0
  568. package/dist/testing/index.d.ts.map +1 -0
  569. package/dist/testing.d.ts +6 -0
  570. package/dist/testing.d.ts.map +1 -0
  571. package/dist/testing.js +5 -0
  572. package/dist/testing.js.map +1 -0
  573. package/dist/tools/index.d.ts +8 -0
  574. package/dist/tools/index.d.ts.map +1 -0
  575. package/dist/tools/tool-executor.d.ts +101 -0
  576. package/dist/tools/tool-executor.d.ts.map +1 -0
  577. package/dist/tools/tool-executor.js +142 -0
  578. package/dist/tools/tool-executor.js.map +1 -0
  579. package/dist/tools/tool-generator.d.ts +54 -0
  580. package/dist/tools/tool-generator.d.ts.map +1 -0
  581. package/dist/tools/tool-generator.js +121 -0
  582. package/dist/tools/tool-generator.js.map +1 -0
  583. package/dist/utils/chunk.d.ts +32 -0
  584. package/dist/utils/chunk.d.ts.map +1 -0
  585. package/dist/utils/chunk.js +14 -0
  586. package/dist/utils/chunk.js.map +1 -0
  587. package/dist/utils/import-workspace-module.d.ts +8 -0
  588. package/dist/utils/import-workspace-module.d.ts.map +1 -0
  589. package/dist/utils/import-workspace-module.js +81 -0
  590. package/dist/utils/import-workspace-module.js.map +1 -0
  591. package/dist/utils/json.d.ts +102 -0
  592. package/dist/utils/json.d.ts.map +1 -0
  593. package/dist/utils/json.js +43 -0
  594. package/dist/utils/json.js.map +1 -0
  595. package/dist/utils/lru-cache.d.ts +69 -0
  596. package/dist/utils/lru-cache.d.ts.map +1 -0
  597. package/dist/utils/lru-cache.js +100 -0
  598. package/dist/utils/lru-cache.js.map +1 -0
  599. package/dist/utils/naming.d.ts +16 -0
  600. package/dist/utils/naming.d.ts.map +1 -0
  601. package/dist/utils/naming.js +23 -0
  602. package/dist/utils/naming.js.map +1 -0
  603. package/dist/utils/qualified-names.d.ts +122 -0
  604. package/dist/utils/qualified-names.d.ts.map +1 -0
  605. package/dist/utils/qualified-names.js +82 -0
  606. package/dist/utils/qualified-names.js.map +1 -0
  607. package/dist/utils/scanner-module.d.ts +37 -0
  608. package/dist/utils/scanner-module.d.ts.map +1 -0
  609. package/dist/utils.d.ts +177 -0
  610. package/dist/utils.d.ts.map +1 -0
  611. package/dist/utils.js +185 -0
  612. package/dist/utils.js.map +1 -0
  613. package/dist/vite-plugin/import-build-aware.d.ts +68 -0
  614. package/dist/vite-plugin/import-build-aware.d.ts.map +1 -0
  615. package/dist/vite-plugin/import-build-aware.js +72 -0
  616. package/dist/vite-plugin/import-build-aware.js.map +1 -0
  617. package/dist/vite-plugin/index.d.ts +59 -0
  618. package/dist/vite-plugin/index.d.ts.map +1 -0
  619. package/dist/vite-plugin/index.js +1400 -0
  620. package/dist/vite-plugin/index.js.map +1 -0
  621. package/dist/vite-plugin/sveltekit-generator.d.ts +66 -0
  622. package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -0
  623. package/dist/vite-plugin/sveltekit-generator.js +1375 -0
  624. package/dist/vite-plugin/sveltekit-generator.js.map +1 -0
  625. package/dist/vite-plugin/templates/default-ui.ts +432 -0
  626. package/dist/vite-plugin/templates/default.html +206 -0
  627. package/dist/vite-plugin.d.ts +8 -0
  628. package/dist/vite-plugin.d.ts.map +1 -0
  629. package/dist/vite-plugin.js +11 -0
  630. package/dist/vite-plugin.js.map +1 -0
  631. package/package.json +208 -0
@@ -0,0 +1,591 @@
1
+ import http from "node:http";
2
+ import { ObjectRegistry } from "../registry.js";
3
+ class APIGenerator {
4
+ config;
5
+ collections = /* @__PURE__ */ new Map();
6
+ context;
7
+ constructor(config = {}, context = {}) {
8
+ this.config = {
9
+ basePath: "/api/v1",
10
+ // Security defaults (#1540): bind to loopback and keep CORS off unless an
11
+ // explicit origin allowlist is supplied. No `Access-Control-Allow-Origin: *`.
12
+ enableCors: false,
13
+ port: 3e3,
14
+ hostname: "127.0.0.1",
15
+ ...config
16
+ };
17
+ this.context = context;
18
+ }
19
+ /**
20
+ * Register a pre-configured collection instance for API exposure
21
+ *
22
+ * @param name - URL path segment for the collection (e.g., 'products' for /api/products)
23
+ * @param collection - Pre-initialized SmrtCollection instance
24
+ */
25
+ registerCollection(name, collection) {
26
+ this.collections.set(name, collection);
27
+ }
28
+ /**
29
+ * Create Node.js HTTP server with all routes
30
+ */
31
+ createServer() {
32
+ const server = http.createServer(async (req, res) => {
33
+ try {
34
+ const request = await this.nodeRequestToWebRequest(req);
35
+ const response = await this.handleRequest(request);
36
+ await this.webResponseToNodeResponse(response, res);
37
+ } catch (_error) {
38
+ res.statusCode = 500;
39
+ res.end("Internal Server Error");
40
+ }
41
+ });
42
+ server.listen(this.config.port, this.config.hostname);
43
+ return {
44
+ server,
45
+ url: `http://${this.config.hostname}:${this.config.port}`
46
+ };
47
+ }
48
+ /**
49
+ * Convert stream to string
50
+ */
51
+ async streamToString(stream) {
52
+ const chunks = [];
53
+ for await (const chunk of stream) {
54
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
55
+ }
56
+ return Buffer.concat(chunks).toString("utf-8");
57
+ }
58
+ /**
59
+ * Convert Node.js IncomingMessage to Web Request
60
+ */
61
+ async nodeRequestToWebRequest(req) {
62
+ const url = `http://${this.config.hostname}:${this.config.port}${req.url}`;
63
+ const method = req.method || "GET";
64
+ const headers = new Headers();
65
+ for (const [key, value] of Object.entries(req.headers)) {
66
+ if (value) {
67
+ headers.set(key, Array.isArray(value) ? value[0] : value);
68
+ }
69
+ }
70
+ let body;
71
+ if (method !== "GET" && method !== "HEAD") {
72
+ body = await this.streamToString(req);
73
+ }
74
+ return new Request(url, {
75
+ method,
76
+ headers,
77
+ body
78
+ });
79
+ }
80
+ /**
81
+ * Convert Web Response to Node.js ServerResponse
82
+ */
83
+ async webResponseToNodeResponse(webResponse, res) {
84
+ res.statusCode = webResponse.status;
85
+ webResponse.headers.forEach((value, key) => {
86
+ res.setHeader(key, value);
87
+ });
88
+ if (webResponse.body) {
89
+ const reader = webResponse.body.getReader();
90
+ while (true) {
91
+ const { done, value } = await reader.read();
92
+ if (done) break;
93
+ res.write(value);
94
+ }
95
+ }
96
+ res.end();
97
+ }
98
+ /**
99
+ * Generate fetch handler function (for serverless environments)
100
+ */
101
+ generateHandler() {
102
+ return (req) => this.handleRequest(req);
103
+ }
104
+ /**
105
+ * Main request handler using native Bun APIs
106
+ */
107
+ async handleRequest(req) {
108
+ const url = new URL(req.url);
109
+ if (req.method === "OPTIONS" && this.config.enableCors) {
110
+ return this.createCorsResponse(req);
111
+ }
112
+ if (this.config.customRoutes) {
113
+ for (const [path, handler] of Object.entries(this.config.customRoutes)) {
114
+ if (url.pathname === `${this.config.basePath}${path}`) {
115
+ const response = await handler(req);
116
+ return this.addCorsHeaders(response, req);
117
+ }
118
+ }
119
+ }
120
+ if (url.pathname.startsWith(this.config.basePath || "")) {
121
+ const response = await this.handleObjectRoute(req, url);
122
+ return this.addCorsHeaders(response, req);
123
+ }
124
+ return this.createErrorResponse(404, "Not found");
125
+ }
126
+ /**
127
+ * Handle CRUD routes for SMRT objects
128
+ */
129
+ async handleObjectRoute(req, url) {
130
+ const pathParts = url.pathname.replace(this.config.basePath || "", "").split("/").filter(Boolean);
131
+ if (pathParts.length === 0) {
132
+ return this.createErrorResponse(400, "Object type required");
133
+ }
134
+ const objectType = pathParts[0];
135
+ const objectId = pathParts[1];
136
+ if (this.collections.has(objectType)) {
137
+ const collection2 = this.collections.get(objectType);
138
+ if (!collection2) throw new Error(`Collection ${objectType} not found`);
139
+ const objectName = this.getCollectionObjectName(collection2) || objectType;
140
+ if (this.config.authMiddleware) {
141
+ const authCheck = this.config.authMiddleware(
142
+ objectName,
143
+ req.method.toLowerCase()
144
+ );
145
+ const authResult = await authCheck(req);
146
+ if (authResult instanceof Response) {
147
+ return authResult;
148
+ }
149
+ req = authResult;
150
+ } else if (!this.isRoutePublic(objectName, req.method)) {
151
+ return this.createErrorResponse(401, "Authentication required");
152
+ }
153
+ return await this.executeCrudOperation(
154
+ req,
155
+ collection2,
156
+ objectId,
157
+ url,
158
+ objectName
159
+ );
160
+ }
161
+ const registeredClasses = ObjectRegistry.getAllClasses();
162
+ const pluralName = this.pluralize(objectType);
163
+ let classInfo = null;
164
+ for (const [_key, info] of registeredClasses) {
165
+ if (this.pluralize((info.name || _key).toLowerCase()) === pluralName) {
166
+ classInfo = info;
167
+ break;
168
+ }
169
+ }
170
+ if (!classInfo) {
171
+ return this.createErrorResponse(
172
+ 404,
173
+ `Object type '${objectType}' not found`
174
+ );
175
+ }
176
+ if (this.config.authMiddleware) {
177
+ const authCheck = this.config.authMiddleware(
178
+ classInfo.name,
179
+ req.method.toLowerCase()
180
+ );
181
+ const authResult = await authCheck(req);
182
+ if (authResult instanceof Response) {
183
+ return authResult;
184
+ }
185
+ req = authResult;
186
+ } else if (!this.isRoutePublic(classInfo.name, req.method)) {
187
+ return this.createErrorResponse(401, "Authentication required");
188
+ }
189
+ const collection = this.getCollection(classInfo);
190
+ return await this.executeCrudOperation(
191
+ req,
192
+ collection,
193
+ objectId,
194
+ url,
195
+ classInfo.name
196
+ );
197
+ }
198
+ /**
199
+ * Execute CRUD operation on a collection
200
+ */
201
+ async executeCrudOperation(req, collection, objectId, url, objectName) {
202
+ try {
203
+ const action = this.getCrudAction(req.method, objectId);
204
+ if (action && !this.isApiActionEnabled(objectName, action)) {
205
+ return this.createErrorResponse(405, "Method not allowed");
206
+ }
207
+ if (objectId === "count" && req.method === "GET") {
208
+ return await this.handleCount(collection, url.searchParams);
209
+ }
210
+ switch (req.method) {
211
+ case "GET":
212
+ return objectId ? await this.handleGet(collection, objectId) : await this.handleList(collection, url.searchParams);
213
+ case "POST":
214
+ return await this.handleCreate(collection, req, objectName);
215
+ case "PUT":
216
+ case "PATCH":
217
+ if (!objectId) {
218
+ return this.createErrorResponse(
219
+ 400,
220
+ "Object ID required for update"
221
+ );
222
+ }
223
+ return await this.handleUpdate(collection, objectId, req, objectName);
224
+ case "DELETE":
225
+ if (!objectId) {
226
+ return this.createErrorResponse(
227
+ 400,
228
+ "Object ID required for delete"
229
+ );
230
+ }
231
+ return await this.handleDelete(collection, objectId);
232
+ default:
233
+ return this.createErrorResponse(405, "Method not allowed");
234
+ }
235
+ } catch (error) {
236
+ console.error("API Error:", error);
237
+ return this.createErrorResponse(500, "Internal server error");
238
+ }
239
+ }
240
+ getCrudAction(method, objectId) {
241
+ switch (method) {
242
+ case "GET":
243
+ return objectId && objectId !== "count" ? "get" : "list";
244
+ case "POST":
245
+ return "create";
246
+ case "PUT":
247
+ case "PATCH":
248
+ return "update";
249
+ case "DELETE":
250
+ return "delete";
251
+ default:
252
+ return null;
253
+ }
254
+ }
255
+ /**
256
+ * Fail-closed authorization posture (#1540). Returns true only when the
257
+ * object opts out of auth via `@smrt({ api: { public } })`:
258
+ * - `public: true` → all methods are public.
259
+ * - `public: 'read'` → only safe (GET) methods are public.
260
+ * Everything else requires an `authMiddleware` to be configured.
261
+ */
262
+ isRoutePublic(objectName, method) {
263
+ if (!objectName) return false;
264
+ const apiConfig = ObjectRegistry.getConfig(objectName)?.api;
265
+ if (!apiConfig || typeof apiConfig !== "object") return false;
266
+ const publicAccess = apiConfig.public;
267
+ if (publicAccess === true) return true;
268
+ if (publicAccess === "read") return method.toUpperCase() === "GET";
269
+ return false;
270
+ }
271
+ isApiActionEnabled(objectName, action) {
272
+ if (!objectName) {
273
+ return true;
274
+ }
275
+ const config = ObjectRegistry.getConfig(objectName);
276
+ const apiConfig = config.api;
277
+ if (apiConfig === false) {
278
+ return false;
279
+ }
280
+ if (apiConfig && typeof apiConfig === "object") {
281
+ if (apiConfig.include && !apiConfig.include.includes(action)) {
282
+ return false;
283
+ }
284
+ if (apiConfig.exclude?.includes(action)) {
285
+ return false;
286
+ }
287
+ }
288
+ return true;
289
+ }
290
+ getCollectionObjectName(collection) {
291
+ const itemClass = collection._itemClass || collection.constructor?._itemClass;
292
+ if (!itemClass) {
293
+ return void 0;
294
+ }
295
+ const registered = ObjectRegistry.getClassByConstructor(itemClass);
296
+ return registered?.qualifiedName || registered?.name || itemClass.name;
297
+ }
298
+ /**
299
+ * Handle GET /objects/:id
300
+ */
301
+ async handleGet(collection, id) {
302
+ const object = await collection.get(id);
303
+ if (!object) {
304
+ return this.createErrorResponse(404, "Object not found");
305
+ }
306
+ return this.createJsonResponse(this.toPublicData(object));
307
+ }
308
+ /**
309
+ * Handle GET /objects (list with query params)
310
+ */
311
+ async handleList(collection, params) {
312
+ const limit = Number.parseInt(params.get("limit") || "50", 10);
313
+ const offset = Number.parseInt(params.get("offset") || "0", 10);
314
+ const orderBy = params.get("orderBy") || "created_at DESC";
315
+ const where = {};
316
+ for (const [key, value] of params.entries()) {
317
+ if (!["limit", "offset", "orderBy"].includes(key)) {
318
+ const match = key.match(/^(.+)\[(.+)\]$/);
319
+ if (match) {
320
+ const field = match[1];
321
+ const operator = match[2];
322
+ const operatorMap = {
323
+ gt: ">",
324
+ gte: ">=",
325
+ lt: "<",
326
+ lte: "<=",
327
+ ne: "!=",
328
+ in: "in",
329
+ like: "like"
330
+ };
331
+ const sqlOperator = operatorMap[operator] || operator;
332
+ const sqlKey = `${field} ${sqlOperator}`;
333
+ where[sqlKey] = operator === "in" ? value.split(",") : value;
334
+ } else {
335
+ where[key] = value;
336
+ }
337
+ }
338
+ }
339
+ const objects = await collection.list({
340
+ where: Object.keys(where).length > 0 ? where : void 0,
341
+ limit,
342
+ offset,
343
+ orderBy
344
+ });
345
+ return this.createJsonResponse(
346
+ objects.map((object) => this.toPublicData(object))
347
+ );
348
+ }
349
+ /**
350
+ * Handle GET /objects/count
351
+ */
352
+ async handleCount(collection, params) {
353
+ const where = {};
354
+ for (const [key, value] of params.entries()) {
355
+ const match = key.match(/^(.+)\[(.+)\]$/);
356
+ if (match) {
357
+ const field = match[1];
358
+ const operator = match[2];
359
+ const operatorMap = {
360
+ gt: ">",
361
+ gte: ">=",
362
+ lt: "<",
363
+ lte: "<=",
364
+ ne: "!=",
365
+ in: "in",
366
+ like: "like"
367
+ };
368
+ const sqlOperator = operatorMap[operator] || operator;
369
+ const sqlKey = `${field} ${sqlOperator}`;
370
+ where[sqlKey] = operator === "in" ? value.split(",") : value;
371
+ } else {
372
+ where[key] = value;
373
+ }
374
+ }
375
+ const count = await collection.count({
376
+ where: Object.keys(where).length > 0 ? where : void 0
377
+ });
378
+ return this.createJsonResponse({ count });
379
+ }
380
+ /**
381
+ * Handle POST /objects
382
+ */
383
+ async handleCreate(collection, req, objectName) {
384
+ const data = this.applyWritablePolicy(objectName, await req.json());
385
+ const object = await collection.create({ ...data, _skipLoad: true });
386
+ await object.save();
387
+ return this.createJsonResponse(this.toPublicData(object), 201);
388
+ }
389
+ /**
390
+ * Handle PUT/PATCH /objects/:id
391
+ */
392
+ async handleUpdate(collection, id, req, objectName) {
393
+ const data = this.applyWritablePolicy(objectName, await req.json());
394
+ const object = await collection.get(id);
395
+ if (!object) {
396
+ return this.createErrorResponse(404, "Object not found");
397
+ }
398
+ Object.assign(object, data);
399
+ await object.save();
400
+ return this.createJsonResponse(this.toPublicData(object));
401
+ }
402
+ /**
403
+ * Handle DELETE /objects/:id
404
+ */
405
+ async handleDelete(collection, id) {
406
+ const object = await collection.get(id);
407
+ if (!object) {
408
+ return this.createErrorResponse(404, "Object not found");
409
+ }
410
+ await object.delete();
411
+ return new Response(null, { status: 204 });
412
+ }
413
+ /**
414
+ * Get or create collection instance
415
+ */
416
+ getCollection(classInfo) {
417
+ if (!this.collections.has(classInfo.name)) {
418
+ const collection2 = new classInfo.collectionConstructor({
419
+ ai: this.context.ai,
420
+ db: this.context.db
421
+ });
422
+ this.collections.set(classInfo.name, collection2);
423
+ }
424
+ const collection = this.collections.get(classInfo.name);
425
+ if (!collection) throw new Error(`Collection ${classInfo.name} not found`);
426
+ return collection;
427
+ }
428
+ /**
429
+ * Mass-assignment guard (#1540): strip framework/server-managed and
430
+ * `@field({ readonly: true })` fields from a create/update body, and — when an
431
+ * `@smrt({ api: { writable: [...] } })` allowlist is set — intersect with it.
432
+ */
433
+ applyWritablePolicy(objectName, data) {
434
+ if (!data || typeof data !== "object") {
435
+ return {};
436
+ }
437
+ const serverManaged = /* @__PURE__ */ new Set([
438
+ "id",
439
+ "tenantId",
440
+ "tenant_id",
441
+ "createdAt",
442
+ "created_at",
443
+ "updatedAt",
444
+ "updated_at"
445
+ ]);
446
+ const readonly = /* @__PURE__ */ new Set();
447
+ let writable = null;
448
+ if (objectName) {
449
+ const apiConfig = ObjectRegistry.getConfig(objectName)?.api;
450
+ if (apiConfig && typeof apiConfig === "object" && Array.isArray(apiConfig.writable)) {
451
+ writable = apiConfig.writable;
452
+ }
453
+ for (const [name, def] of ObjectRegistry.getFields(objectName)) {
454
+ if (def && (def.readonly === true || def._meta?.readonly === true)) {
455
+ readonly.add(name);
456
+ }
457
+ }
458
+ }
459
+ const result = {};
460
+ for (const [key, value] of Object.entries(data)) {
461
+ if (key.startsWith("_")) continue;
462
+ if (serverManaged.has(key)) continue;
463
+ if (readonly.has(key)) continue;
464
+ if (writable && !writable.includes(key)) continue;
465
+ result[key] = value;
466
+ }
467
+ return result;
468
+ }
469
+ /**
470
+ * Serialize a SmrtObject for a network response, excluding sensitive fields
471
+ * (#1540). Falls back to the value unchanged for non-SmrtObject payloads.
472
+ */
473
+ toPublicData(object) {
474
+ return typeof object?.toPublicJSON === "function" ? object.toPublicJSON() : object;
475
+ }
476
+ /**
477
+ * Create JSON response with proper headers
478
+ */
479
+ createJsonResponse(data, status = 200) {
480
+ return new Response(JSON.stringify(data), {
481
+ status,
482
+ headers: {
483
+ "Content-Type": "application/json"
484
+ }
485
+ });
486
+ }
487
+ /**
488
+ * Create error response
489
+ */
490
+ createErrorResponse(status, message) {
491
+ return new Response(JSON.stringify({ error: message }), {
492
+ status,
493
+ headers: {
494
+ "Content-Type": "application/json"
495
+ }
496
+ });
497
+ }
498
+ /**
499
+ * Resolve the allowed `Access-Control-Allow-Origin` for a request (#1540).
500
+ * Returns the request's `Origin` only when it is in the configured allowlist;
501
+ * never `*`. Returns null when CORS should not be applied.
502
+ */
503
+ resolveAllowedOrigin(req) {
504
+ if (!this.config.enableCors) return null;
505
+ const allowed = this.config.allowedOrigins;
506
+ if (!allowed || allowed.length === 0) return null;
507
+ const origin = req.headers.get("origin");
508
+ return origin && allowed.includes(origin) ? origin : null;
509
+ }
510
+ /**
511
+ * Create CORS preflight response
512
+ */
513
+ createCorsResponse(req) {
514
+ const headers = {
515
+ "Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,OPTIONS",
516
+ "Access-Control-Allow-Headers": "Content-Type,Authorization",
517
+ "Access-Control-Max-Age": "86400"
518
+ };
519
+ const origin = this.resolveAllowedOrigin(req);
520
+ if (origin) {
521
+ headers["Access-Control-Allow-Origin"] = origin;
522
+ headers.Vary = "Origin";
523
+ }
524
+ return new Response(null, { status: 200, headers });
525
+ }
526
+ /**
527
+ * Add CORS headers to response
528
+ */
529
+ addCorsHeaders(response, req) {
530
+ const origin = this.resolveAllowedOrigin(req);
531
+ if (!origin) return response;
532
+ const headers = new Headers(response.headers);
533
+ headers.set("Access-Control-Allow-Origin", origin);
534
+ headers.set("Vary", "Origin");
535
+ headers.set(
536
+ "Access-Control-Allow-Methods",
537
+ "GET,POST,PUT,PATCH,DELETE,OPTIONS"
538
+ );
539
+ headers.set("Access-Control-Allow-Headers", "Content-Type,Authorization");
540
+ return new Response(response.body, {
541
+ status: response.status,
542
+ statusText: response.statusText,
543
+ headers
544
+ });
545
+ }
546
+ /**
547
+ * Simple pluralization (basic implementation)
548
+ */
549
+ pluralize(word) {
550
+ if (word.endsWith("y")) {
551
+ return `${word.slice(0, -1)}ies`;
552
+ }
553
+ if (word.endsWith("s") || word.endsWith("sh") || word.endsWith("ch")) {
554
+ return `${word}es`;
555
+ }
556
+ return `${word}s`;
557
+ }
558
+ }
559
+ function createRestServer(objects, context = {}, config = {}) {
560
+ objects.forEach((obj) => {
561
+ if (!ObjectRegistry.hasClass(obj.name)) {
562
+ console.warn(`Object ${obj.name} not registered with @smrt decorator`);
563
+ }
564
+ });
565
+ const generator = new APIGenerator(config, context);
566
+ const { server, url } = generator.createServer();
567
+ console.log(`🚀 smrt REST API server running at ${url}`);
568
+ return { server, url };
569
+ }
570
+ function startRestServer(objects, context = {}, config = {}) {
571
+ return new Promise((resolve) => {
572
+ const { server, url } = createRestServer(objects, context, config);
573
+ const shutdown = () => {
574
+ return new Promise((shutdownResolve) => {
575
+ console.log("🛑 Shutting down server gracefully...");
576
+ server.stop();
577
+ console.log("✅ Server shut down complete");
578
+ shutdownResolve();
579
+ });
580
+ };
581
+ process.on("SIGTERM", shutdown);
582
+ process.on("SIGINT", shutdown);
583
+ resolve(shutdown);
584
+ });
585
+ }
586
+ export {
587
+ APIGenerator,
588
+ createRestServer,
589
+ startRestServer
590
+ };
591
+ //# sourceMappingURL=rest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.js","sources":["../../src/generators/rest.ts"],"sourcesContent":["/**\n * High-performance REST API generator for smrt objects using Node.js HTTP server\n *\n * Designed for minimal bundle size and maximum performance\n */\n\nimport http from 'node:http';\nimport type { SmrtCollection } from '../collection';\nimport type { SmrtObject } from '../object';\nimport { ObjectRegistry } from '../registry';\n\nexport interface APIConfig {\n basePath?: string;\n enableCors?: boolean;\n /**\n * Explicit CORS origin allowlist (#1540). Required when `enableCors` is true —\n * the generator never emits `Access-Control-Allow-Origin: *`. A request's\n * `Origin` is echoed only when it appears here.\n */\n allowedOrigins?: string[];\n customRoutes?: Record<string, (req: Request) => Promise<Response>>;\n authMiddleware?: (\n objectName: string,\n action: string,\n ) => (req: Request) => Promise<Request | Response>;\n port?: number;\n hostname?: string;\n}\n\nexport interface APIContext {\n db?: any;\n ai?: any;\n user?: {\n id: string;\n username?: string;\n roles?: string[];\n };\n}\n\n/**\n * High-performance API generator using native Bun\n */\nexport class APIGenerator {\n private config: APIConfig;\n private collections = new Map<string, SmrtCollection<any>>();\n private context: APIContext;\n\n constructor(config: APIConfig = {}, context: APIContext = {}) {\n this.config = {\n basePath: '/api/v1',\n // Security defaults (#1540): bind to loopback and keep CORS off unless an\n // explicit origin allowlist is supplied. No `Access-Control-Allow-Origin: *`.\n enableCors: false,\n port: 3000,\n hostname: '127.0.0.1',\n ...config,\n };\n this.context = context;\n }\n\n /**\n * Register a pre-configured collection instance for API exposure\n *\n * @param name - URL path segment for the collection (e.g., 'products' for /api/products)\n * @param collection - Pre-initialized SmrtCollection instance\n */\n registerCollection(name: string, collection: SmrtCollection<any>): void {\n this.collections.set(name, collection);\n }\n\n /**\n * Create Node.js HTTP server with all routes\n */\n createServer(): { server: any; url: string } {\n const server = http.createServer(async (req, res) => {\n try {\n const request = await this.nodeRequestToWebRequest(req);\n const response = await this.handleRequest(request);\n await this.webResponseToNodeResponse(response, res);\n } catch (_error) {\n res.statusCode = 500;\n res.end('Internal Server Error');\n }\n });\n\n server.listen(this.config.port, this.config.hostname);\n\n return {\n server,\n url: `http://${this.config.hostname}:${this.config.port}`,\n };\n }\n\n /**\n * Convert stream to string\n */\n private async streamToString(stream: http.IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString('utf-8');\n }\n\n /**\n * Convert Node.js IncomingMessage to Web Request\n */\n private async nodeRequestToWebRequest(\n req: http.IncomingMessage,\n ): Promise<Request> {\n const url = `http://${this.config.hostname}:${this.config.port}${req.url}`;\n const method = req.method || 'GET';\n const headers = new Headers();\n\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value[0] : value);\n }\n }\n\n let body: string | undefined;\n if (method !== 'GET' && method !== 'HEAD') {\n body = await this.streamToString(req);\n }\n\n return new Request(url, {\n method,\n headers,\n body,\n });\n }\n\n /**\n * Convert Web Response to Node.js ServerResponse\n */\n private async webResponseToNodeResponse(\n webResponse: Response,\n res: http.ServerResponse,\n ): Promise<void> {\n res.statusCode = webResponse.status;\n\n // Set headers\n webResponse.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n\n // Send body\n if (webResponse.body) {\n const reader = webResponse.body.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n }\n\n res.end();\n }\n\n /**\n * Generate fetch handler function (for serverless environments)\n */\n generateHandler(): (req: Request) => Promise<Response> {\n return (req) => this.handleRequest(req);\n }\n\n /**\n * Main request handler using native Bun APIs\n */\n private async handleRequest(req: Request): Promise<Response> {\n const url = new URL(req.url);\n\n // Handle CORS preflight\n if (req.method === 'OPTIONS' && this.config.enableCors) {\n return this.createCorsResponse(req);\n }\n\n // Handle custom routes first\n if (this.config.customRoutes) {\n for (const [path, handler] of Object.entries(this.config.customRoutes)) {\n if (url.pathname === `${this.config.basePath}${path}`) {\n const response = await handler(req);\n return this.addCorsHeaders(response, req);\n }\n }\n }\n\n // Handle object routes\n if (url.pathname.startsWith(this.config.basePath || '')) {\n const response = await this.handleObjectRoute(req, url);\n return this.addCorsHeaders(response, req);\n }\n\n // Not found\n return this.createErrorResponse(404, 'Not found');\n }\n\n /**\n * Handle CRUD routes for SMRT objects\n */\n private async handleObjectRoute(req: Request, url: URL): Promise<Response> {\n const pathParts = url.pathname\n .replace(this.config.basePath || '', '')\n .split('/')\n .filter(Boolean);\n\n if (pathParts.length === 0) {\n return this.createErrorResponse(400, 'Object type required');\n }\n\n const objectType = pathParts[0];\n const objectId = pathParts[1];\n\n // Check for explicitly registered collection first\n if (this.collections.has(objectType)) {\n const collection = this.collections.get(objectType);\n if (!collection) throw new Error(`Collection ${objectType} not found`);\n\n const objectName = this.getCollectionObjectName(collection) || objectType;\n\n // Apply auth middleware if configured\n if (this.config.authMiddleware) {\n const authCheck = this.config.authMiddleware(\n objectName,\n req.method.toLowerCase(),\n );\n const authResult = await authCheck(req);\n if (authResult instanceof Response) {\n return authResult; // Auth failed\n }\n // Auth passed, use the potentially modified request\n req = authResult;\n } else if (!this.isRoutePublic(objectName, req.method)) {\n // Fail-closed (#1540): no auth middleware wired and the object isn't\n // marked `@smrt({ api: { public } })` → refuse rather than serve open.\n return this.createErrorResponse(401, 'Authentication required');\n }\n\n // Use registered collection directly\n return await this.executeCrudOperation(\n req,\n collection,\n objectId,\n url,\n objectName,\n );\n }\n\n // Fall back to auto-discovery via ObjectRegistry\n const registeredClasses = ObjectRegistry.getAllClasses();\n const pluralName = this.pluralize(objectType);\n\n let classInfo: any = null;\n for (const [_key, info] of registeredClasses) {\n // Issue #951: Use simple name (info.name) for URL matching, not the map key\n // which may be a qualified name like '@happyvertical/smrt-events:Event'\n if (this.pluralize((info.name || _key).toLowerCase()) === pluralName) {\n classInfo = info;\n break;\n }\n }\n\n if (!classInfo) {\n return this.createErrorResponse(\n 404,\n `Object type '${objectType}' not found`,\n );\n }\n\n // Apply auth middleware if configured\n if (this.config.authMiddleware) {\n const authCheck = this.config.authMiddleware(\n classInfo.name,\n req.method.toLowerCase(),\n );\n const authResult = await authCheck(req);\n if (authResult instanceof Response) {\n return authResult; // Auth failed\n }\n // Auth passed, use the potentially modified request\n req = authResult;\n } else if (!this.isRoutePublic(classInfo.name, req.method)) {\n // Fail-closed (#1540): see registered-collection branch above.\n return this.createErrorResponse(401, 'Authentication required');\n }\n\n // Get or create collection\n const collection = this.getCollection(classInfo);\n\n return await this.executeCrudOperation(\n req,\n collection,\n objectId,\n url,\n classInfo.name,\n );\n }\n\n /**\n * Execute CRUD operation on a collection\n */\n private async executeCrudOperation(\n req: Request,\n collection: SmrtCollection<any>,\n objectId: string | undefined,\n url: URL,\n objectName?: string,\n ): Promise<Response> {\n try {\n const action = this.getCrudAction(req.method, objectId);\n if (action && !this.isApiActionEnabled(objectName, action)) {\n return this.createErrorResponse(405, 'Method not allowed');\n }\n\n // Handle special /count endpoint\n if (objectId === 'count' && req.method === 'GET') {\n return await this.handleCount(collection, url.searchParams);\n }\n\n // Route to appropriate CRUD operation\n switch (req.method) {\n case 'GET':\n return objectId\n ? await this.handleGet(collection, objectId)\n : await this.handleList(collection, url.searchParams);\n\n case 'POST':\n return await this.handleCreate(collection, req, objectName);\n\n case 'PUT':\n case 'PATCH':\n if (!objectId) {\n return this.createErrorResponse(\n 400,\n 'Object ID required for update',\n );\n }\n return await this.handleUpdate(collection, objectId, req, objectName);\n\n case 'DELETE':\n if (!objectId) {\n return this.createErrorResponse(\n 400,\n 'Object ID required for delete',\n );\n }\n return await this.handleDelete(collection, objectId);\n\n default:\n return this.createErrorResponse(405, 'Method not allowed');\n }\n } catch (error) {\n console.error('API Error:', error);\n return this.createErrorResponse(500, 'Internal server error');\n }\n }\n\n private getCrudAction(\n method: string,\n objectId: string | undefined,\n ): 'list' | 'get' | 'create' | 'update' | 'delete' | null {\n switch (method) {\n case 'GET':\n return objectId && objectId !== 'count' ? 'get' : 'list';\n case 'POST':\n return 'create';\n case 'PUT':\n case 'PATCH':\n return 'update';\n case 'DELETE':\n return 'delete';\n default:\n return null;\n }\n }\n\n /**\n * Fail-closed authorization posture (#1540). Returns true only when the\n * object opts out of auth via `@smrt({ api: { public } })`:\n * - `public: true` → all methods are public.\n * - `public: 'read'` → only safe (GET) methods are public.\n * Everything else requires an `authMiddleware` to be configured.\n */\n private isRoutePublic(\n objectName: string | undefined,\n method: string,\n ): boolean {\n if (!objectName) return false;\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') return false;\n const publicAccess = (apiConfig as { public?: boolean | 'read' }).public;\n if (publicAccess === true) return true;\n if (publicAccess === 'read') return method.toUpperCase() === 'GET';\n return false;\n }\n\n private isApiActionEnabled(\n objectName: string | undefined,\n action: 'list' | 'get' | 'create' | 'update' | 'delete',\n ): boolean {\n if (!objectName) {\n return true;\n }\n\n const config = ObjectRegistry.getConfig(objectName);\n const apiConfig = config.api;\n\n if (apiConfig === false) {\n return false;\n }\n\n if (apiConfig && typeof apiConfig === 'object') {\n if (apiConfig.include && !apiConfig.include.includes(action)) {\n return false;\n }\n\n if (apiConfig.exclude?.includes(action)) {\n return false;\n }\n }\n\n return true;\n }\n\n private getCollectionObjectName(\n collection: SmrtCollection<any>,\n ): string | undefined {\n const itemClass =\n (collection as any)._itemClass ||\n (collection.constructor as any)?._itemClass;\n\n if (!itemClass) {\n return undefined;\n }\n\n const registered = ObjectRegistry.getClassByConstructor(itemClass);\n return registered?.qualifiedName || registered?.name || itemClass.name;\n }\n\n /**\n * Handle GET /objects/:id\n */\n private async handleGet(\n collection: SmrtCollection<any>,\n id: string,\n ): Promise<Response> {\n const object = await collection.get(id);\n if (!object) {\n return this.createErrorResponse(404, 'Object not found');\n }\n return this.createJsonResponse(this.toPublicData(object));\n }\n\n /**\n * Handle GET /objects (list with query params)\n */\n private async handleList(\n collection: SmrtCollection<any>,\n params: URLSearchParams,\n ): Promise<Response> {\n const limit = Number.parseInt(params.get('limit') || '50', 10);\n const offset = Number.parseInt(params.get('offset') || '0', 10);\n const orderBy = params.get('orderBy') || 'created_at DESC';\n\n // Build where clause from query params\n // Convert REST-style operators (price[gt]) to SQL-style (price >)\n const where: any = {};\n for (const [key, value] of params.entries()) {\n if (!['limit', 'offset', 'orderBy'].includes(key)) {\n // Parse REST operator format: field[operator]\n const match = key.match(/^(.+)\\[(.+)\\]$/);\n if (match) {\n const field = match[1];\n const operator = match[2];\n // Map REST operators to SQL operators\n const operatorMap: Record<string, string> = {\n gt: '>',\n gte: '>=',\n lt: '<',\n lte: '<=',\n ne: '!=',\n in: 'in',\n like: 'like',\n };\n const sqlOperator = operatorMap[operator] || operator;\n const sqlKey = `${field} ${sqlOperator}`;\n // Handle 'in' operator - convert comma-separated string to array\n where[sqlKey] = operator === 'in' ? value.split(',') : value;\n } else {\n where[key] = value;\n }\n }\n }\n\n const objects = await collection.list({\n where: Object.keys(where).length > 0 ? where : undefined,\n limit,\n offset,\n orderBy,\n });\n\n return this.createJsonResponse(\n objects.map((object: any) => this.toPublicData(object)),\n );\n }\n\n /**\n * Handle GET /objects/count\n */\n private async handleCount(\n collection: SmrtCollection<any>,\n params: URLSearchParams,\n ): Promise<Response> {\n // Build where clause from query params (same logic as handleList)\n const where: any = {};\n for (const [key, value] of params.entries()) {\n // Parse REST operator format: field[operator]\n const match = key.match(/^(.+)\\[(.+)\\]$/);\n if (match) {\n const field = match[1];\n const operator = match[2];\n // Map REST operators to SQL operators\n const operatorMap: Record<string, string> = {\n gt: '>',\n gte: '>=',\n lt: '<',\n lte: '<=',\n ne: '!=',\n in: 'in',\n like: 'like',\n };\n const sqlOperator = operatorMap[operator] || operator;\n const sqlKey = `${field} ${sqlOperator}`;\n // Handle 'in' operator - convert comma-separated string to array\n where[sqlKey] = operator === 'in' ? value.split(',') : value;\n } else {\n where[key] = value;\n }\n }\n\n const count = await collection.count({\n where: Object.keys(where).length > 0 ? where : undefined,\n });\n\n return this.createJsonResponse({ count });\n }\n\n /**\n * Handle POST /objects\n */\n private async handleCreate(\n collection: SmrtCollection<any>,\n req: Request,\n objectName?: string,\n ): Promise<Response> {\n const data = this.applyWritablePolicy(objectName, await req.json());\n const object = await collection.create({ ...data, _skipLoad: true });\n await object.save();\n return this.createJsonResponse(this.toPublicData(object), 201);\n }\n\n /**\n * Handle PUT/PATCH /objects/:id\n */\n private async handleUpdate(\n collection: SmrtCollection<any>,\n id: string,\n req: Request,\n objectName?: string,\n ): Promise<Response> {\n const data = this.applyWritablePolicy(objectName, await req.json());\n const object = await collection.get(id);\n\n if (!object) {\n return this.createErrorResponse(404, 'Object not found');\n }\n\n // Update object properties\n Object.assign(object, data);\n await object.save();\n\n return this.createJsonResponse(this.toPublicData(object));\n }\n\n /**\n * Handle DELETE /objects/:id\n */\n private async handleDelete(\n collection: SmrtCollection<any>,\n id: string,\n ): Promise<Response> {\n const object = await collection.get(id);\n\n if (!object) {\n return this.createErrorResponse(404, 'Object not found');\n }\n\n await object.delete();\n return new Response(null, { status: 204 });\n }\n\n /**\n * Get or create collection instance\n */\n private getCollection(classInfo: any): SmrtCollection<any> {\n if (!this.collections.has(classInfo.name)) {\n const collection = new classInfo.collectionConstructor({\n ai: this.context.ai,\n db: this.context.db,\n });\n this.collections.set(classInfo.name, collection);\n }\n const collection = this.collections.get(classInfo.name);\n if (!collection) throw new Error(`Collection ${classInfo.name} not found`);\n return collection;\n }\n\n /**\n * Mass-assignment guard (#1540): strip framework/server-managed and\n * `@field({ readonly: true })` fields from a create/update body, and — when an\n * `@smrt({ api: { writable: [...] } })` allowlist is set — intersect with it.\n */\n private applyWritablePolicy(\n objectName: string | undefined,\n data: any,\n ): Record<string, any> {\n if (!data || typeof data !== 'object') {\n return {};\n }\n\n const serverManaged = new Set([\n 'id',\n 'tenantId',\n 'tenant_id',\n 'createdAt',\n 'created_at',\n 'updatedAt',\n 'updated_at',\n ]);\n\n const readonly = new Set<string>();\n let writable: string[] | null = null;\n\n if (objectName) {\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (\n apiConfig &&\n typeof apiConfig === 'object' &&\n Array.isArray((apiConfig as { writable?: unknown }).writable)\n ) {\n writable = (apiConfig as { writable: string[] }).writable;\n }\n\n for (const [name, def] of ObjectRegistry.getFields(objectName)) {\n if (def && (def.readonly === true || def._meta?.readonly === true)) {\n readonly.add(name);\n }\n }\n }\n\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(data)) {\n if (key.startsWith('_')) continue;\n if (serverManaged.has(key)) continue;\n if (readonly.has(key)) continue;\n if (writable && !writable.includes(key)) continue;\n result[key] = value;\n }\n return result;\n }\n\n /**\n * Serialize a SmrtObject for a network response, excluding sensitive fields\n * (#1540). Falls back to the value unchanged for non-SmrtObject payloads.\n */\n private toPublicData(object: any): any {\n return typeof object?.toPublicJSON === 'function'\n ? object.toPublicJSON()\n : object;\n }\n\n /**\n * Create JSON response with proper headers\n */\n private createJsonResponse(data: any, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n }\n\n /**\n * Create error response\n */\n private createErrorResponse(status: number, message: string): Response {\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n }\n\n /**\n * Resolve the allowed `Access-Control-Allow-Origin` for a request (#1540).\n * Returns the request's `Origin` only when it is in the configured allowlist;\n * never `*`. Returns null when CORS should not be applied.\n */\n private resolveAllowedOrigin(req: Request): string | null {\n if (!this.config.enableCors) return null;\n const allowed = this.config.allowedOrigins;\n if (!allowed || allowed.length === 0) return null;\n const origin = req.headers.get('origin');\n return origin && allowed.includes(origin) ? origin : null;\n }\n\n /**\n * Create CORS preflight response\n */\n private createCorsResponse(req: Request): Response {\n const headers: Record<string, string> = {\n 'Access-Control-Allow-Methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type,Authorization',\n 'Access-Control-Max-Age': '86400',\n };\n const origin = this.resolveAllowedOrigin(req);\n if (origin) {\n headers['Access-Control-Allow-Origin'] = origin;\n headers.Vary = 'Origin';\n }\n return new Response(null, { status: 200, headers });\n }\n\n /**\n * Add CORS headers to response\n */\n private addCorsHeaders(response: Response, req: Request): Response {\n const origin = this.resolveAllowedOrigin(req);\n if (!origin) return response;\n\n const headers = new Headers(response.headers);\n headers.set('Access-Control-Allow-Origin', origin);\n headers.set('Vary', 'Origin');\n headers.set(\n 'Access-Control-Allow-Methods',\n 'GET,POST,PUT,PATCH,DELETE,OPTIONS',\n );\n headers.set('Access-Control-Allow-Headers', 'Content-Type,Authorization');\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n /**\n * Simple pluralization (basic implementation)\n */\n private pluralize(word: string): string {\n if (word.endsWith('y')) {\n return `${word.slice(0, -1)}ies`;\n }\n if (word.endsWith('s') || word.endsWith('sh') || word.endsWith('ch')) {\n return `${word}es`;\n }\n return `${word}s`;\n }\n}\n\n// REST Server Utilities\n\nexport interface RestServerConfig extends APIConfig {\n healthCheck?: {\n enabled?: boolean;\n path?: string;\n customChecks?: (() => Promise<boolean>)[];\n };\n}\n\n/**\n * Create REST server with health checks using Bun\n */\nexport function createRestServer(\n objects: (typeof SmrtObject)[],\n context: APIContext = {},\n config: RestServerConfig = {},\n): { server: any; url: string } {\n // Register objects if not already registered\n objects.forEach((obj) => {\n if (!ObjectRegistry.hasClass(obj.name)) {\n console.warn(`Object ${obj.name} not registered with @smrt decorator`);\n }\n });\n\n const generator = new APIGenerator(config, context);\n const { server, url } = generator.createServer();\n\n console.log(`🚀 smrt REST API server running at ${url}`);\n\n return { server, url };\n}\n\n/**\n * Start server with graceful shutdown\n */\nexport function startRestServer(\n objects: (typeof SmrtObject)[],\n context: APIContext = {},\n config: RestServerConfig = {},\n): Promise<() => Promise<void>> {\n return new Promise((resolve) => {\n const { server, url } = createRestServer(objects, context, config);\n\n // Graceful shutdown function\n const shutdown = (): Promise<void> => {\n return new Promise((shutdownResolve) => {\n console.log('🛑 Shutting down server gracefully...');\n server.stop();\n console.log('✅ Server shut down complete');\n shutdownResolve();\n });\n };\n\n // Handle shutdown signals\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n\n resolve(shutdown);\n });\n}\n"],"names":["collection"],"mappings":"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"}