@useatlas/create 0.0.1 → 0.0.3

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 (298) hide show
  1. package/README.md +4 -18
  2. package/index.ts +191 -31
  3. package/package.json +1 -1
  4. package/templates/docker/.env.example +3 -3
  5. package/templates/docker/Dockerfile.sidecar +28 -0
  6. package/templates/docker/bin/__tests__/plugin-cli.test.ts +11 -11
  7. package/templates/docker/bin/atlas.ts +120 -56
  8. package/templates/docker/data/demo-semantic/catalog.yml +51 -27
  9. package/templates/docker/data/demo-semantic/entities/accounts.yml +95 -103
  10. package/templates/docker/data/demo-semantic/entities/companies.yml +88 -152
  11. package/templates/docker/data/demo-semantic/entities/people.yml +82 -95
  12. package/templates/docker/data/demo-semantic/glossary.yml +104 -8
  13. package/templates/docker/data/demo-semantic/metrics/accounts.yml +62 -23
  14. package/templates/docker/data/demo-semantic/metrics/companies.yml +52 -78
  15. package/templates/docker/docker-compose.yml +1 -1
  16. package/templates/docker/docs/deploy.md +4 -41
  17. package/templates/docker/package.json +17 -1
  18. package/templates/docker/semantic/catalog.yml +62 -3
  19. package/templates/docker/semantic/entities/accounts.yml +162 -0
  20. package/templates/docker/semantic/entities/companies.yml +143 -0
  21. package/templates/docker/semantic/entities/people.yml +132 -0
  22. package/templates/docker/semantic/glossary.yml +116 -4
  23. package/templates/docker/semantic/metrics/accounts.yml +77 -0
  24. package/templates/docker/semantic/metrics/companies.yml +63 -0
  25. package/templates/docker/sidecar/Dockerfile +5 -6
  26. package/templates/docker/sidecar/railway.json +1 -2
  27. package/templates/docker/src/api/__tests__/admin.test.ts +7 -7
  28. package/templates/docker/src/api/__tests__/health-plugin.test.ts +7 -0
  29. package/templates/docker/src/api/__tests__/health.test.ts +30 -8
  30. package/templates/docker/src/api/routes/admin.ts +549 -8
  31. package/templates/docker/src/api/routes/chat.ts +5 -20
  32. package/templates/docker/src/api/routes/health.ts +39 -27
  33. package/templates/docker/src/api/routes/openapi.ts +1329 -74
  34. package/templates/docker/src/api/routes/query.ts +2 -1
  35. package/templates/docker/src/api/server.ts +27 -0
  36. package/templates/docker/src/app/api/[...route]/route.ts +2 -2
  37. package/templates/docker/src/app/globals.css +13 -12
  38. package/templates/docker/src/app/layout.tsx +9 -2
  39. package/templates/docker/src/components/ui/alert-dialog.tsx +196 -0
  40. package/templates/docker/src/components/ui/badge.tsx +48 -0
  41. package/templates/docker/src/components/ui/button.tsx +64 -0
  42. package/templates/docker/src/components/ui/card.tsx +92 -0
  43. package/templates/docker/src/components/ui/collapsible.tsx +33 -0
  44. package/templates/docker/src/components/ui/command.tsx +184 -0
  45. package/templates/docker/src/components/ui/dialog.tsx +158 -0
  46. package/templates/docker/src/components/ui/dropdown-menu.tsx +257 -0
  47. package/templates/docker/src/components/ui/input.tsx +21 -0
  48. package/templates/docker/src/components/ui/scroll-area.tsx +58 -0
  49. package/templates/docker/src/components/ui/select.tsx +190 -0
  50. package/templates/docker/src/components/ui/separator.tsx +28 -0
  51. package/templates/docker/src/components/ui/sheet.tsx +143 -0
  52. package/templates/docker/src/components/ui/sidebar.tsx +726 -0
  53. package/templates/docker/src/components/ui/skeleton.tsx +13 -0
  54. package/templates/docker/src/components/ui/table.tsx +116 -0
  55. package/templates/docker/src/components/ui/tabs.tsx +91 -0
  56. package/templates/docker/src/components/ui/toggle-group.tsx +83 -0
  57. package/templates/docker/src/components/ui/toggle.tsx +47 -0
  58. package/templates/docker/src/components/ui/tooltip.tsx +57 -0
  59. package/templates/docker/src/hooks/use-mobile.ts +19 -0
  60. package/templates/docker/src/lib/__tests__/agent-cache.test.ts +2 -0
  61. package/templates/docker/src/lib/__tests__/agent-dialect.test.ts +17 -0
  62. package/templates/docker/src/lib/__tests__/agent-health-annotations.test.ts +2 -0
  63. package/templates/docker/src/lib/__tests__/agent-integration.test.ts +2 -0
  64. package/templates/docker/src/lib/__tests__/config.test.ts +69 -19
  65. package/templates/docker/src/lib/__tests__/plugin-aware-validation.test.ts +321 -0
  66. package/templates/docker/src/lib/__tests__/providers.test.ts +32 -1
  67. package/templates/docker/src/lib/__tests__/startup-actions.test.ts +9 -0
  68. package/templates/docker/src/lib/__tests__/startup-first-run.test.ts +429 -0
  69. package/templates/docker/src/lib/__tests__/startup.test.ts +5 -0
  70. package/templates/docker/src/lib/agent-query.ts +5 -23
  71. package/templates/docker/src/lib/agent.ts +32 -112
  72. package/templates/docker/src/lib/auth/__tests__/migrate.test.ts +5 -3
  73. package/templates/docker/src/lib/auth/middleware.ts +30 -4
  74. package/templates/docker/src/lib/auth/migrate.ts +97 -0
  75. package/templates/docker/src/lib/auth/server.ts +12 -1
  76. package/templates/docker/src/lib/config.ts +38 -40
  77. package/templates/docker/src/lib/db/__tests__/connection.test.ts +89 -14
  78. package/templates/docker/src/lib/db/__tests__/registry-health.test.ts +1 -18
  79. package/templates/docker/src/lib/db/__tests__/registry-pool-limits.test.ts +0 -19
  80. package/templates/docker/src/lib/db/__tests__/registry.test.ts +11 -208
  81. package/templates/docker/src/lib/db/connection.ts +87 -265
  82. package/templates/docker/src/lib/db/internal.ts +6 -1
  83. package/templates/docker/src/lib/plugins/__tests__/hooks-integration.test.ts +3 -1
  84. package/templates/docker/src/lib/plugins/__tests__/hooks.test.ts +2 -2
  85. package/templates/docker/src/lib/plugins/__tests__/migrate.test.ts +355 -1
  86. package/templates/docker/src/lib/plugins/__tests__/registry.test.ts +32 -5
  87. package/templates/docker/src/lib/plugins/__tests__/wiring.test.ts +228 -14
  88. package/templates/docker/src/lib/plugins/index.ts +4 -1
  89. package/templates/docker/src/lib/plugins/migrate.ts +104 -1
  90. package/templates/docker/src/lib/plugins/registry.ts +14 -8
  91. package/templates/docker/src/lib/plugins/wiring.ts +113 -4
  92. package/templates/docker/src/lib/providers.ts +6 -1
  93. package/templates/docker/src/lib/security.ts +24 -0
  94. package/templates/docker/src/lib/semantic.ts +2 -0
  95. package/templates/docker/src/lib/sidecar-types.ts +12 -1
  96. package/templates/docker/src/lib/startup.ts +71 -101
  97. package/templates/docker/src/lib/tools/__tests__/custom-validation.test.ts +2 -0
  98. package/templates/docker/src/lib/tools/__tests__/explore-nsjail.test.ts +32 -18
  99. package/templates/docker/src/lib/tools/__tests__/explore-plugin.test.ts +14 -14
  100. package/templates/docker/src/lib/tools/__tests__/explore-sdk-compat.test.ts +1 -1
  101. package/templates/docker/src/lib/tools/__tests__/explore-sidecar.test.ts +5 -3
  102. package/templates/docker/src/lib/tools/__tests__/python-nsjail.test.ts +515 -0
  103. package/templates/docker/src/lib/tools/__tests__/python-sandbox.test.ts +397 -0
  104. package/templates/docker/src/lib/tools/__tests__/python-sidecar.test.ts +365 -0
  105. package/templates/docker/src/lib/tools/__tests__/python.test.ts +331 -0
  106. package/templates/docker/src/lib/tools/__tests__/registry-actions.test.ts +1 -13
  107. package/templates/docker/src/lib/tools/__tests__/registry.test.ts +38 -31
  108. package/templates/docker/src/lib/tools/__tests__/sql-audit.test.ts +2 -0
  109. package/templates/docker/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +2 -0
  110. package/templates/docker/src/lib/tools/__tests__/sql-ratelimit.test.ts +2 -0
  111. package/templates/docker/src/lib/tools/__tests__/sql.test.ts +5 -308
  112. package/templates/docker/src/lib/tools/explore-nsjail.ts +17 -12
  113. package/templates/docker/src/lib/tools/explore-sidecar.ts +25 -0
  114. package/templates/docker/src/lib/tools/explore.ts +28 -32
  115. package/templates/docker/src/lib/tools/python-nsjail.ts +396 -0
  116. package/templates/docker/src/lib/tools/python-sandbox.ts +476 -0
  117. package/templates/docker/src/lib/tools/python-sidecar.ts +150 -0
  118. package/templates/docker/src/lib/tools/python.ts +367 -0
  119. package/templates/docker/src/lib/tools/registry.ts +49 -22
  120. package/templates/docker/src/lib/tools/sql.ts +88 -88
  121. package/templates/docker/src/types/vercel-sandbox.d.ts +7 -0
  122. package/templates/docker/src/ui/components/admin/admin-layout.tsx +77 -8
  123. package/templates/docker/src/ui/components/admin/admin-sidebar.tsx +25 -17
  124. package/templates/docker/src/ui/components/admin/change-password-dialog.tsx +128 -0
  125. package/templates/docker/src/ui/components/admin/entity-detail.tsx +3 -3
  126. package/templates/docker/src/ui/components/admin/semantic-file-tree.tsx +159 -0
  127. package/templates/docker/src/ui/components/atlas-chat.tsx +64 -12
  128. package/templates/docker/src/ui/components/chart/result-chart.tsx +25 -15
  129. package/templates/docker/src/ui/components/chat/markdown.tsx +88 -42
  130. package/templates/docker/src/ui/components/chat/python-result-card.tsx +244 -0
  131. package/templates/docker/src/ui/components/chat/sql-block.tsx +39 -15
  132. package/templates/docker/src/ui/components/chat/sql-result-card.tsx +6 -1
  133. package/templates/docker/src/ui/components/chat/tool-part.tsx +12 -3
  134. package/templates/docker/src/ui/components/chat/typing-indicator.tsx +5 -2
  135. package/templates/docker/src/ui/components/conversations/conversation-item.tsx +25 -20
  136. package/templates/docker/src/ui/context.tsx +1 -1
  137. package/templates/docker/src/ui/hooks/use-conversations.ts +3 -3
  138. package/templates/docker/src/ui/hooks/use-dark-mode.ts +17 -10
  139. package/templates/docker/tsconfig.json +2 -2
  140. package/templates/nextjs-standalone/.env.example +1 -1
  141. package/templates/nextjs-standalone/bin/__tests__/plugin-cli.test.ts +11 -11
  142. package/templates/nextjs-standalone/bin/atlas.ts +120 -56
  143. package/templates/nextjs-standalone/data/demo-semantic/catalog.yml +51 -27
  144. package/templates/nextjs-standalone/data/demo-semantic/entities/accounts.yml +95 -103
  145. package/templates/nextjs-standalone/data/demo-semantic/entities/companies.yml +88 -152
  146. package/templates/nextjs-standalone/data/demo-semantic/entities/people.yml +82 -95
  147. package/templates/nextjs-standalone/data/demo-semantic/glossary.yml +104 -8
  148. package/templates/nextjs-standalone/data/demo-semantic/metrics/accounts.yml +62 -23
  149. package/templates/nextjs-standalone/data/demo-semantic/metrics/companies.yml +52 -78
  150. package/templates/nextjs-standalone/docs/deploy.md +4 -41
  151. package/templates/nextjs-standalone/package.json +11 -2
  152. package/templates/nextjs-standalone/scripts/migrate-auth.ts +25 -0
  153. package/templates/nextjs-standalone/scripts/seed-demo.ts +94 -0
  154. package/templates/nextjs-standalone/semantic/catalog.yml +62 -3
  155. package/templates/nextjs-standalone/semantic/entities/accounts.yml +162 -0
  156. package/templates/nextjs-standalone/semantic/entities/companies.yml +143 -0
  157. package/templates/nextjs-standalone/semantic/entities/people.yml +132 -0
  158. package/templates/nextjs-standalone/semantic/glossary.yml +116 -4
  159. package/templates/nextjs-standalone/semantic/metrics/accounts.yml +77 -0
  160. package/templates/nextjs-standalone/semantic/metrics/companies.yml +63 -0
  161. package/templates/nextjs-standalone/src/api/__tests__/admin.test.ts +7 -7
  162. package/templates/nextjs-standalone/src/api/__tests__/health-plugin.test.ts +7 -0
  163. package/templates/nextjs-standalone/src/api/__tests__/health.test.ts +30 -8
  164. package/templates/nextjs-standalone/src/api/routes/admin.ts +549 -8
  165. package/templates/nextjs-standalone/src/api/routes/chat.ts +5 -20
  166. package/templates/nextjs-standalone/src/api/routes/health.ts +39 -27
  167. package/templates/nextjs-standalone/src/api/routes/openapi.ts +1329 -74
  168. package/templates/nextjs-standalone/src/api/routes/query.ts +2 -1
  169. package/templates/nextjs-standalone/src/api/server.ts +27 -0
  170. package/templates/nextjs-standalone/src/app/api/[...route]/route.ts +2 -2
  171. package/templates/nextjs-standalone/src/app/globals.css +13 -12
  172. package/templates/nextjs-standalone/src/app/layout.tsx +9 -2
  173. package/templates/nextjs-standalone/src/components/ui/alert-dialog.tsx +196 -0
  174. package/templates/nextjs-standalone/src/components/ui/badge.tsx +48 -0
  175. package/templates/nextjs-standalone/src/components/ui/button.tsx +64 -0
  176. package/templates/nextjs-standalone/src/components/ui/card.tsx +92 -0
  177. package/templates/nextjs-standalone/src/components/ui/collapsible.tsx +33 -0
  178. package/templates/nextjs-standalone/src/components/ui/command.tsx +184 -0
  179. package/templates/nextjs-standalone/src/components/ui/dialog.tsx +158 -0
  180. package/templates/nextjs-standalone/src/components/ui/dropdown-menu.tsx +257 -0
  181. package/templates/nextjs-standalone/src/components/ui/input.tsx +21 -0
  182. package/templates/nextjs-standalone/src/components/ui/scroll-area.tsx +58 -0
  183. package/templates/nextjs-standalone/src/components/ui/select.tsx +190 -0
  184. package/templates/nextjs-standalone/src/components/ui/separator.tsx +28 -0
  185. package/templates/nextjs-standalone/src/components/ui/sheet.tsx +143 -0
  186. package/templates/nextjs-standalone/src/components/ui/sidebar.tsx +726 -0
  187. package/templates/nextjs-standalone/src/components/ui/skeleton.tsx +13 -0
  188. package/templates/nextjs-standalone/src/components/ui/table.tsx +116 -0
  189. package/templates/nextjs-standalone/src/components/ui/tabs.tsx +91 -0
  190. package/templates/nextjs-standalone/src/components/ui/toggle-group.tsx +83 -0
  191. package/templates/nextjs-standalone/src/components/ui/toggle.tsx +47 -0
  192. package/templates/nextjs-standalone/src/components/ui/tooltip.tsx +57 -0
  193. package/templates/nextjs-standalone/src/hooks/use-mobile.ts +19 -0
  194. package/templates/nextjs-standalone/src/lib/__tests__/agent-cache.test.ts +2 -0
  195. package/templates/nextjs-standalone/src/lib/__tests__/agent-dialect.test.ts +17 -0
  196. package/templates/nextjs-standalone/src/lib/__tests__/agent-health-annotations.test.ts +2 -0
  197. package/templates/nextjs-standalone/src/lib/__tests__/agent-integration.test.ts +2 -0
  198. package/templates/nextjs-standalone/src/lib/__tests__/config.test.ts +69 -19
  199. package/templates/nextjs-standalone/src/lib/__tests__/plugin-aware-validation.test.ts +321 -0
  200. package/templates/nextjs-standalone/src/lib/__tests__/providers.test.ts +32 -1
  201. package/templates/nextjs-standalone/src/lib/__tests__/startup-actions.test.ts +9 -0
  202. package/templates/nextjs-standalone/src/lib/__tests__/startup-first-run.test.ts +429 -0
  203. package/templates/nextjs-standalone/src/lib/__tests__/startup.test.ts +5 -0
  204. package/templates/nextjs-standalone/src/lib/agent-query.ts +5 -23
  205. package/templates/nextjs-standalone/src/lib/agent.ts +32 -112
  206. package/templates/nextjs-standalone/src/lib/auth/__tests__/migrate.test.ts +5 -3
  207. package/templates/nextjs-standalone/src/lib/auth/middleware.ts +30 -4
  208. package/templates/nextjs-standalone/src/lib/auth/migrate.ts +97 -0
  209. package/templates/nextjs-standalone/src/lib/auth/server.ts +12 -1
  210. package/templates/nextjs-standalone/src/lib/config.ts +38 -40
  211. package/templates/nextjs-standalone/src/lib/db/__tests__/connection.test.ts +89 -14
  212. package/templates/nextjs-standalone/src/lib/db/__tests__/registry-health.test.ts +1 -18
  213. package/templates/nextjs-standalone/src/lib/db/__tests__/registry-pool-limits.test.ts +0 -19
  214. package/templates/nextjs-standalone/src/lib/db/__tests__/registry.test.ts +11 -208
  215. package/templates/nextjs-standalone/src/lib/db/connection.ts +87 -265
  216. package/templates/nextjs-standalone/src/lib/db/internal.ts +6 -1
  217. package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks-integration.test.ts +3 -1
  218. package/templates/nextjs-standalone/src/lib/plugins/__tests__/hooks.test.ts +2 -2
  219. package/templates/nextjs-standalone/src/lib/plugins/__tests__/migrate.test.ts +355 -1
  220. package/templates/nextjs-standalone/src/lib/plugins/__tests__/registry.test.ts +32 -5
  221. package/templates/nextjs-standalone/src/lib/plugins/__tests__/wiring.test.ts +228 -14
  222. package/templates/nextjs-standalone/src/lib/plugins/index.ts +4 -1
  223. package/templates/nextjs-standalone/src/lib/plugins/migrate.ts +104 -1
  224. package/templates/nextjs-standalone/src/lib/plugins/registry.ts +14 -8
  225. package/templates/nextjs-standalone/src/lib/plugins/wiring.ts +113 -4
  226. package/templates/nextjs-standalone/src/lib/providers.ts +6 -1
  227. package/templates/nextjs-standalone/src/lib/security.ts +24 -0
  228. package/templates/nextjs-standalone/src/lib/semantic.ts +2 -0
  229. package/templates/nextjs-standalone/src/lib/sidecar-types.ts +12 -1
  230. package/templates/nextjs-standalone/src/lib/startup.ts +71 -101
  231. package/templates/nextjs-standalone/src/lib/tools/__tests__/custom-validation.test.ts +2 -0
  232. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-nsjail.test.ts +32 -18
  233. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-plugin.test.ts +14 -14
  234. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-sdk-compat.test.ts +1 -1
  235. package/templates/nextjs-standalone/src/lib/tools/__tests__/explore-sidecar.test.ts +5 -3
  236. package/templates/nextjs-standalone/src/lib/tools/__tests__/python-nsjail.test.ts +515 -0
  237. package/templates/nextjs-standalone/src/lib/tools/__tests__/python-sandbox.test.ts +397 -0
  238. package/templates/nextjs-standalone/src/lib/tools/__tests__/python-sidecar.test.ts +365 -0
  239. package/templates/nextjs-standalone/src/lib/tools/__tests__/python.test.ts +331 -0
  240. package/templates/nextjs-standalone/src/lib/tools/__tests__/registry-actions.test.ts +1 -13
  241. package/templates/nextjs-standalone/src/lib/tools/__tests__/registry.test.ts +38 -31
  242. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-audit.test.ts +2 -0
  243. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-connection-whitelist.test.ts +2 -0
  244. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-ratelimit.test.ts +2 -0
  245. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql.test.ts +5 -308
  246. package/templates/nextjs-standalone/src/lib/tools/explore-nsjail.ts +17 -12
  247. package/templates/nextjs-standalone/src/lib/tools/explore-sidecar.ts +25 -0
  248. package/templates/nextjs-standalone/src/lib/tools/explore.ts +28 -32
  249. package/templates/nextjs-standalone/src/lib/tools/python-nsjail.ts +396 -0
  250. package/templates/nextjs-standalone/src/lib/tools/python-sandbox.ts +476 -0
  251. package/templates/nextjs-standalone/src/lib/tools/python-sidecar.ts +150 -0
  252. package/templates/nextjs-standalone/src/lib/tools/python.ts +367 -0
  253. package/templates/nextjs-standalone/src/lib/tools/registry.ts +49 -22
  254. package/templates/nextjs-standalone/src/lib/tools/sql.ts +88 -88
  255. package/templates/nextjs-standalone/src/ui/components/admin/admin-layout.tsx +77 -8
  256. package/templates/nextjs-standalone/src/ui/components/admin/admin-sidebar.tsx +25 -17
  257. package/templates/nextjs-standalone/src/ui/components/admin/change-password-dialog.tsx +128 -0
  258. package/templates/nextjs-standalone/src/ui/components/admin/entity-detail.tsx +3 -3
  259. package/templates/nextjs-standalone/src/ui/components/admin/semantic-file-tree.tsx +159 -0
  260. package/templates/nextjs-standalone/src/ui/components/atlas-chat.tsx +64 -12
  261. package/templates/nextjs-standalone/src/ui/components/chart/result-chart.tsx +25 -15
  262. package/templates/nextjs-standalone/src/ui/components/chat/markdown.tsx +88 -42
  263. package/templates/nextjs-standalone/src/ui/components/chat/python-result-card.tsx +244 -0
  264. package/templates/nextjs-standalone/src/ui/components/chat/sql-block.tsx +39 -15
  265. package/templates/nextjs-standalone/src/ui/components/chat/sql-result-card.tsx +6 -1
  266. package/templates/nextjs-standalone/src/ui/components/chat/tool-part.tsx +12 -3
  267. package/templates/nextjs-standalone/src/ui/components/chat/typing-indicator.tsx +5 -2
  268. package/templates/nextjs-standalone/src/ui/components/conversations/conversation-item.tsx +25 -20
  269. package/templates/nextjs-standalone/src/ui/context.tsx +1 -1
  270. package/templates/nextjs-standalone/src/ui/hooks/use-conversations.ts +3 -3
  271. package/templates/nextjs-standalone/src/ui/hooks/use-dark-mode.ts +17 -10
  272. package/templates/nextjs-standalone/tsconfig.json +0 -1
  273. package/templates/nextjs-standalone/vercel.json +4 -1
  274. package/templates/docker/render.yaml +0 -34
  275. package/templates/docker/semantic/entities/.gitkeep +0 -0
  276. package/templates/docker/semantic/metrics/.gitkeep +0 -0
  277. package/templates/docker/src/lib/db/__tests__/duckdb.test.ts +0 -141
  278. package/templates/docker/src/lib/db/__tests__/salesforce.test.ts +0 -339
  279. package/templates/docker/src/lib/db/__tests__/snowflake.test.ts +0 -217
  280. package/templates/docker/src/lib/db/duckdb.ts +0 -122
  281. package/templates/docker/src/lib/db/salesforce.ts +0 -342
  282. package/templates/docker/src/lib/tools/__tests__/salesforce-tool.test.ts +0 -154
  283. package/templates/docker/src/lib/tools/__tests__/soql-validation.test.ts +0 -303
  284. package/templates/docker/src/lib/tools/__tests__/sql-duckdb.test.ts +0 -233
  285. package/templates/docker/src/lib/tools/salesforce.ts +0 -138
  286. package/templates/docker/src/lib/tools/soql-validation.ts +0 -172
  287. package/templates/nextjs-standalone/semantic/entities/.gitkeep +0 -0
  288. package/templates/nextjs-standalone/semantic/metrics/.gitkeep +0 -0
  289. package/templates/nextjs-standalone/src/lib/db/__tests__/duckdb.test.ts +0 -141
  290. package/templates/nextjs-standalone/src/lib/db/__tests__/salesforce.test.ts +0 -339
  291. package/templates/nextjs-standalone/src/lib/db/__tests__/snowflake.test.ts +0 -217
  292. package/templates/nextjs-standalone/src/lib/db/duckdb.ts +0 -122
  293. package/templates/nextjs-standalone/src/lib/db/salesforce.ts +0 -342
  294. package/templates/nextjs-standalone/src/lib/tools/__tests__/salesforce-tool.test.ts +0 -154
  295. package/templates/nextjs-standalone/src/lib/tools/__tests__/soql-validation.test.ts +0 -303
  296. package/templates/nextjs-standalone/src/lib/tools/__tests__/sql-duckdb.test.ts +0 -233
  297. package/templates/nextjs-standalone/src/lib/tools/salesforce.ts +0 -138
  298. package/templates/nextjs-standalone/src/lib/tools/soql-validation.ts +0 -172
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Tests for plugin-aware SQL validation (#15).
3
+ *
4
+ * Verifies:
5
+ * - ConnectionRegistry stores and returns plugin metadata
6
+ * - parserDatabase() consults plugin metadata before hardcoded switch
7
+ * - getExtraPatterns() (via validateSQL) consults plugin metadata before hardcoded switch
8
+ * - Custom validate() completely bypasses the standard pipeline
9
+ * - wireDatasourcePlugins passes parserDialect + forbiddenPatterns through
10
+ */
11
+ import { describe, test, expect, beforeEach } from "bun:test";
12
+ import { ConnectionRegistry } from "@atlas/api/lib/db/connection";
13
+ import type { DBConnection, ConnectionPluginMeta } from "@atlas/api/lib/db/connection";
14
+ import { PluginRegistry } from "@atlas/api/lib/plugins/registry";
15
+ import type { PluginLike, PluginContextLike } from "@atlas/api/lib/plugins/registry";
16
+ import { wireDatasourcePlugins } from "@atlas/api/lib/plugins/wiring";
17
+
18
+ // --- Helpers ---
19
+
20
+ function mockConn(): DBConnection {
21
+ return {
22
+ async query() { return { columns: [], rows: [] }; },
23
+ async close() {},
24
+ };
25
+ }
26
+
27
+ const minimalCtx: PluginContextLike = {
28
+ db: null,
29
+ connections: { get: () => ({}), list: () => [] },
30
+ tools: { register: () => {} },
31
+ logger: {},
32
+ config: {},
33
+ };
34
+
35
+ // --- ConnectionRegistry plugin metadata ---
36
+
37
+ describe("ConnectionRegistry plugin metadata", () => {
38
+ let registry: ConnectionRegistry;
39
+
40
+ beforeEach(() => {
41
+ registry = new ConnectionRegistry();
42
+ });
43
+
44
+ test("registerDirect stores and retrieves parserDialect", () => {
45
+ registry.registerDirect("bq", mockConn(), "postgres", "BigQuery", undefined, {
46
+ parserDialect: "BigQuery",
47
+ });
48
+
49
+ expect(registry.getParserDialect("bq")).toBe("BigQuery");
50
+ });
51
+
52
+ test("registerDirect stores and retrieves forbiddenPatterns", () => {
53
+ const patterns = [/\bMERGE\b/i, /\bEXPORT\b/i];
54
+ registry.registerDirect("custom", mockConn(), "postgres", "Custom DB", undefined, {
55
+ forbiddenPatterns: patterns,
56
+ });
57
+
58
+ expect(registry.getForbiddenPatterns("custom")).toEqual(patterns);
59
+ });
60
+
61
+ test("getParserDialect returns undefined when no meta", () => {
62
+ registry.registerDirect("plain", mockConn(), "postgres");
63
+ expect(registry.getParserDialect("plain")).toBeUndefined();
64
+ });
65
+
66
+ test("getForbiddenPatterns returns empty array when no meta", () => {
67
+ registry.registerDirect("plain", mockConn(), "postgres");
68
+ expect(registry.getForbiddenPatterns("plain")).toEqual([]);
69
+ });
70
+
71
+ test("getParserDialect returns undefined for unregistered connection", () => {
72
+ expect(registry.getParserDialect("nonexistent")).toBeUndefined();
73
+ });
74
+
75
+ test("getForbiddenPatterns returns empty array for unregistered connection", () => {
76
+ expect(registry.getForbiddenPatterns("nonexistent")).toEqual([]);
77
+ });
78
+
79
+ test("registerDirect with both meta fields", () => {
80
+ const meta: ConnectionPluginMeta = {
81
+ parserDialect: "TransactSQL",
82
+ forbiddenPatterns: [/\bEXEC\b/i],
83
+ };
84
+ registry.registerDirect("mssql", mockConn(), "postgres", "SQL Server", undefined, meta);
85
+
86
+ expect(registry.getParserDialect("mssql")).toBe("TransactSQL");
87
+ expect(registry.getForbiddenPatterns("mssql")).toEqual([/\bEXEC\b/i]);
88
+ });
89
+
90
+ test("re-registration replaces meta", () => {
91
+ registry.registerDirect("ds", mockConn(), "postgres", undefined, undefined, {
92
+ parserDialect: "MySQL",
93
+ });
94
+ expect(registry.getParserDialect("ds")).toBe("MySQL");
95
+
96
+ registry.registerDirect("ds", mockConn(), "postgres", undefined, undefined, {
97
+ parserDialect: "BigQuery",
98
+ });
99
+ expect(registry.getParserDialect("ds")).toBe("BigQuery");
100
+ });
101
+ });
102
+
103
+ // --- parserDatabase with plugin metadata ---
104
+
105
+ describe("parserDatabase with plugin metadata", () => {
106
+ // We need to import parserDatabase which uses the global `connections` singleton.
107
+ // To test with our own registry, we'll use validateSQL indirectly via the
108
+ // parserDatabase export. But parserDatabase uses the global connections import.
109
+ // Instead, let's test through validateSQL which is the public API.
110
+
111
+ // Actually, parserDatabase is exported. We need to test that it consults
112
+ // the global connections registry. Let's use the global one.
113
+
114
+ beforeEach(async () => {
115
+ const { connections } = await import("@atlas/api/lib/db/connection");
116
+ connections._reset();
117
+ });
118
+
119
+ test("parserDatabase uses plugin dialect over hardcoded", async () => {
120
+ const { connections } = await import("@atlas/api/lib/db/connection");
121
+ const { parserDatabase } = await import("@atlas/api/lib/tools/sql");
122
+
123
+ connections.registerDirect("bq-conn", mockConn(), "postgres", "BigQuery", undefined, {
124
+ parserDialect: "BigQuery",
125
+ });
126
+
127
+ // With connectionId — should use plugin dialect
128
+ expect(parserDatabase("postgres", "bq-conn")).toBe("BigQuery");
129
+
130
+ // Without connectionId — should use hardcoded
131
+ expect(parserDatabase("postgres")).toBe("PostgresQL");
132
+ });
133
+
134
+ test("parserDatabase falls back to hardcoded when no plugin dialect", async () => {
135
+ const { connections } = await import("@atlas/api/lib/db/connection");
136
+ const { parserDatabase } = await import("@atlas/api/lib/tools/sql");
137
+
138
+ connections.registerDirect("plain-pg", mockConn(), "postgres");
139
+
140
+ expect(parserDatabase("postgres", "plain-pg")).toBe("PostgresQL");
141
+ expect(parserDatabase("mysql", "plain-pg")).toBe("MySQL");
142
+ });
143
+
144
+ test("parserDatabase defaults to PostgresQL for unknown dbType", async () => {
145
+ const { parserDatabase } = await import("@atlas/api/lib/tools/sql");
146
+
147
+ // Unknown dbType with no connectionId
148
+ expect(parserDatabase("custom-db" as never)).toBe("PostgresQL");
149
+ });
150
+ });
151
+
152
+ // --- validateSQL with plugin-provided forbidden patterns ---
153
+
154
+ describe("validateSQL with plugin forbidden patterns", () => {
155
+ beforeEach(async () => {
156
+ const { connections } = await import("@atlas/api/lib/db/connection");
157
+ connections._reset();
158
+ });
159
+
160
+ test("plugin-provided forbidden patterns block matching queries", async () => {
161
+ const { connections } = await import("@atlas/api/lib/db/connection");
162
+ const { validateSQL } = await import("@atlas/api/lib/tools/sql");
163
+
164
+ connections.registerDirect("strict-ds", mockConn(), "postgres", "Strict DB", undefined, {
165
+ forbiddenPatterns: [/\bUNION\b/i],
166
+ });
167
+
168
+ // UNION is not forbidden for regular postgres, but our plugin says it is
169
+ const result = validateSQL("SELECT 1 UNION SELECT 2", "strict-ds");
170
+ expect(result.valid).toBe(false);
171
+ expect(result.error).toContain("UNION");
172
+ });
173
+
174
+ test("plugin patterns do not affect connections without them", async () => {
175
+ const { connections } = await import("@atlas/api/lib/db/connection");
176
+ const { validateSQL } = await import("@atlas/api/lib/tools/sql");
177
+
178
+ // Register one with patterns, one without
179
+ connections.registerDirect("strict", mockConn(), "postgres", undefined, undefined, {
180
+ forbiddenPatterns: [/\bUNION\b/i],
181
+ });
182
+ connections.registerDirect("plain", mockConn(), "postgres");
183
+
184
+ // Blocked on strict
185
+ expect(validateSQL("SELECT 1 UNION SELECT 2", "strict").valid).toBe(false);
186
+
187
+ // Allowed on plain (postgres has no UNION restriction)
188
+ // Note: this requires the semantic layer whitelist to be off
189
+ process.env.ATLAS_TABLE_WHITELIST = "false";
190
+ expect(validateSQL("SELECT 1 UNION SELECT 2", "plain").valid).toBe(true);
191
+ delete process.env.ATLAS_TABLE_WHITELIST;
192
+ });
193
+ });
194
+
195
+ // --- wireDatasourcePlugins passes metadata through ---
196
+
197
+ describe("wireDatasourcePlugins metadata passthrough", () => {
198
+ function makeMockConnectionRegistry() {
199
+ return {
200
+ registered: [] as { id: string; conn: unknown; dbType: string; description?: string; validate?: unknown; meta?: unknown }[],
201
+ async registerDirect(id: string, conn: unknown, dbType: string, description?: string, validate?: unknown, meta?: unknown) {
202
+ this.registered.push({ id, conn, dbType, description, validate, meta });
203
+ },
204
+ };
205
+ }
206
+
207
+ test("passes parserDialect and forbiddenPatterns from plugin", async () => {
208
+ const registry = new PluginRegistry();
209
+ const connRegistry = makeMockConnectionRegistry();
210
+ const patterns = [/\bCUSTOM_OP\b/i];
211
+
212
+ const plugin: PluginLike = {
213
+ id: "dialect-ds",
214
+ types: ["datasource"],
215
+ version: "1.0.0",
216
+ connection: {
217
+ create: () => ({ query: async () => ({ columns: [], rows: [] }), close: async () => {} }),
218
+ dbType: "postgres",
219
+ parserDialect: "BigQuery",
220
+ forbiddenPatterns: patterns,
221
+ },
222
+ };
223
+ registry.register(plugin);
224
+ await registry.initializeAll(minimalCtx);
225
+
226
+ await wireDatasourcePlugins(
227
+ registry,
228
+ connRegistry as unknown as import("@atlas/api/lib/db/connection").ConnectionRegistry,
229
+ );
230
+
231
+ expect(connRegistry.registered).toHaveLength(1);
232
+ expect(connRegistry.registered[0].meta).toEqual({
233
+ parserDialect: "BigQuery",
234
+ forbiddenPatterns: patterns,
235
+ });
236
+ });
237
+
238
+ test("passes undefined meta when plugin has no dialect or patterns", async () => {
239
+ const registry = new PluginRegistry();
240
+ const connRegistry = makeMockConnectionRegistry();
241
+
242
+ const plugin: PluginLike = {
243
+ id: "plain-ds",
244
+ types: ["datasource"],
245
+ version: "1.0.0",
246
+ connection: {
247
+ create: () => ({ query: async () => ({ columns: [], rows: [] }), close: async () => {} }),
248
+ dbType: "postgres",
249
+ },
250
+ };
251
+ registry.register(plugin);
252
+ await registry.initializeAll(minimalCtx);
253
+
254
+ await wireDatasourcePlugins(
255
+ registry,
256
+ connRegistry as unknown as import("@atlas/api/lib/db/connection").ConnectionRegistry,
257
+ );
258
+
259
+ expect(connRegistry.registered).toHaveLength(1);
260
+ expect(connRegistry.registered[0].meta).toBeUndefined();
261
+ });
262
+
263
+ test("passes meta with only parserDialect", async () => {
264
+ const registry = new PluginRegistry();
265
+ const connRegistry = makeMockConnectionRegistry();
266
+
267
+ const plugin: PluginLike = {
268
+ id: "dialect-only",
269
+ types: ["datasource"],
270
+ version: "1.0.0",
271
+ connection: {
272
+ create: () => ({ query: async () => ({ columns: [], rows: [] }), close: async () => {} }),
273
+ dbType: "postgres",
274
+ parserDialect: "Redshift",
275
+ },
276
+ };
277
+ registry.register(plugin);
278
+ await registry.initializeAll(minimalCtx);
279
+
280
+ await wireDatasourcePlugins(
281
+ registry,
282
+ connRegistry as unknown as import("@atlas/api/lib/db/connection").ConnectionRegistry,
283
+ );
284
+
285
+ expect(connRegistry.registered).toHaveLength(1);
286
+ expect(connRegistry.registered[0].meta).toEqual({
287
+ parserDialect: "Redshift",
288
+ forbiddenPatterns: undefined,
289
+ });
290
+ });
291
+
292
+ test("passes meta with only forbiddenPatterns", async () => {
293
+ const registry = new PluginRegistry();
294
+ const connRegistry = makeMockConnectionRegistry();
295
+ const patterns = [/\bDELETE\b/i];
296
+
297
+ const plugin: PluginLike = {
298
+ id: "patterns-only",
299
+ types: ["datasource"],
300
+ version: "1.0.0",
301
+ connection: {
302
+ create: () => ({ query: async () => ({ columns: [], rows: [] }), close: async () => {} }),
303
+ dbType: "postgres",
304
+ forbiddenPatterns: patterns,
305
+ },
306
+ };
307
+ registry.register(plugin);
308
+ await registry.initializeAll(minimalCtx);
309
+
310
+ await wireDatasourcePlugins(
311
+ registry,
312
+ connRegistry as unknown as import("@atlas/api/lib/db/connection").ConnectionRegistry,
313
+ );
314
+
315
+ expect(connRegistry.registered).toHaveLength(1);
316
+ expect(connRegistry.registered[0].meta).toEqual({
317
+ parserDialect: undefined,
318
+ forbiddenPatterns: patterns,
319
+ });
320
+ });
321
+ });
@@ -2,7 +2,7 @@ import { describe, expect, test, afterEach } from "bun:test";
2
2
 
3
3
  // Import after mocks — getProviderType reads process.env at call time, so no
4
4
  // module-level mocking is needed.
5
- const { getProviderType } = await import("@atlas/api/lib/providers");
5
+ const { getProviderType, getDefaultProvider } = await import("@atlas/api/lib/providers");
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  // Env snapshot — capture/restore only the vars this test touches
@@ -10,6 +10,7 @@ const { getProviderType } = await import("@atlas/api/lib/providers");
10
10
 
11
11
  const origProvider = process.env.ATLAS_PROVIDER;
12
12
  const origModel = process.env.ATLAS_MODEL;
13
+ const origVercel = process.env.VERCEL;
13
14
 
14
15
  afterEach(() => {
15
16
  if (origProvider !== undefined) process.env.ATLAS_PROVIDER = origProvider;
@@ -17,6 +18,9 @@ afterEach(() => {
17
18
 
18
19
  if (origModel !== undefined) process.env.ATLAS_MODEL = origModel;
19
20
  else delete process.env.ATLAS_MODEL;
21
+
22
+ if (origVercel !== undefined) process.env.VERCEL = origVercel;
23
+ else delete process.env.VERCEL;
20
24
  });
21
25
 
22
26
  // ---------------------------------------------------------------------------
@@ -90,6 +94,21 @@ describe("getProviderType", () => {
90
94
  expect(getProviderType()).toBe("bedrock");
91
95
  });
92
96
 
97
+ // --- Vercel auto-detection ------------------------------------------------
98
+
99
+ test("defaults to 'gateway' when VERCEL env var is set and no ATLAS_PROVIDER", () => {
100
+ delete process.env.ATLAS_PROVIDER;
101
+ delete process.env.ATLAS_MODEL;
102
+ process.env.VERCEL = "1";
103
+ expect(getProviderType()).toBe("gateway");
104
+ });
105
+
106
+ test("explicit ATLAS_PROVIDER overrides Vercel default", () => {
107
+ process.env.ATLAS_PROVIDER = "anthropic";
108
+ process.env.VERCEL = "1";
109
+ expect(getProviderType()).toBe("anthropic");
110
+ });
111
+
93
112
  // --- Invalid provider ----------------------------------------------------
94
113
 
95
114
  test("throws for an invalid provider string", () => {
@@ -97,3 +116,15 @@ describe("getProviderType", () => {
97
116
  expect(() => getProviderType()).toThrow(Error);
98
117
  });
99
118
  });
119
+
120
+ describe("getDefaultProvider", () => {
121
+ test("returns 'anthropic' when VERCEL is not set", () => {
122
+ delete process.env.VERCEL;
123
+ expect(getDefaultProvider()).toBe("anthropic");
124
+ });
125
+
126
+ test("returns 'gateway' when VERCEL is set", () => {
127
+ process.env.VERCEL = "1";
128
+ expect(getDefaultProvider()).toBe("gateway");
129
+ });
130
+ });
@@ -13,6 +13,11 @@ mock.module("fs", () => ({
13
13
 
14
14
  mock.module("@atlas/api/lib/db/connection", () => ({
15
15
  detectDBType: () => "postgres",
16
+ resolveDatasourceUrl: () => process.env.ATLAS_DATASOURCE_URL || null,
17
+ }));
18
+
19
+ mock.module("@atlas/api/lib/providers", () => ({
20
+ getDefaultProvider: () => "anthropic",
16
21
  }));
17
22
 
18
23
  mock.module("@atlas/api/lib/tools/explore-nsjail", () => ({
@@ -50,6 +55,10 @@ let mockConfig: Record<string, unknown> | null = null;
50
55
 
51
56
  mock.module("@atlas/api/lib/config", () => ({
52
57
  getConfig: () => mockConfig,
58
+ loadConfig: async () => {
59
+ mockConfig = { source: "env" };
60
+ return mockConfig;
61
+ },
53
62
  }));
54
63
 
55
64
  const { validateEnvironment, getStartupWarnings, resetStartupCache } =