@baseplate-dev/project-builder-server 0.3.3 → 0.3.5

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 (247) hide show
  1. package/dist/actions/diff/diff-project.action.d.ts +73 -0
  2. package/dist/actions/diff/diff-project.action.d.ts.map +1 -0
  3. package/dist/actions/diff/diff-project.action.js +103 -0
  4. package/dist/actions/diff/diff-project.action.js.map +1 -0
  5. package/dist/actions/diff/index.d.ts +2 -0
  6. package/dist/actions/diff/index.d.ts.map +1 -0
  7. package/dist/actions/diff/index.js +2 -0
  8. package/dist/actions/diff/index.js.map +1 -0
  9. package/dist/actions/index.d.ts +7 -0
  10. package/dist/actions/index.d.ts.map +1 -0
  11. package/dist/actions/index.js +7 -0
  12. package/dist/actions/index.js.map +1 -0
  13. package/dist/actions/registry.d.ts +270 -0
  14. package/dist/actions/registry.d.ts.map +1 -0
  15. package/dist/actions/registry.js +23 -0
  16. package/dist/actions/registry.js.map +1 -0
  17. package/dist/actions/snapshot/index.d.ts +5 -0
  18. package/dist/actions/snapshot/index.d.ts.map +1 -0
  19. package/dist/actions/snapshot/index.js +5 -0
  20. package/dist/actions/snapshot/index.js.map +1 -0
  21. package/dist/actions/snapshot/snapshot-add.action.d.ts +16 -0
  22. package/dist/actions/snapshot/snapshot-add.action.d.ts.map +1 -0
  23. package/dist/actions/snapshot/snapshot-add.action.js +80 -0
  24. package/dist/actions/snapshot/snapshot-add.action.js.map +1 -0
  25. package/dist/actions/snapshot/snapshot-remove.action.d.ts +15 -0
  26. package/dist/actions/snapshot/snapshot-remove.action.d.ts.map +1 -0
  27. package/dist/actions/snapshot/snapshot-remove.action.js +75 -0
  28. package/dist/actions/snapshot/snapshot-remove.action.js.map +1 -0
  29. package/dist/actions/snapshot/snapshot-save.action.d.ts +15 -0
  30. package/dist/actions/snapshot/snapshot-save.action.d.ts.map +1 -0
  31. package/dist/actions/snapshot/snapshot-save.action.js +82 -0
  32. package/dist/actions/snapshot/snapshot-save.action.js.map +1 -0
  33. package/dist/actions/snapshot/snapshot-show.action.d.ts +43 -0
  34. package/dist/actions/snapshot/snapshot-show.action.d.ts.map +1 -0
  35. package/dist/actions/snapshot/snapshot-show.action.js +136 -0
  36. package/dist/actions/snapshot/snapshot-show.action.js.map +1 -0
  37. package/dist/actions/sync/index.d.ts +2 -0
  38. package/dist/actions/sync/index.d.ts.map +1 -0
  39. package/dist/actions/sync/index.js +2 -0
  40. package/dist/actions/sync/index.js.map +1 -0
  41. package/dist/actions/sync/sync-project.action.d.ts +14 -0
  42. package/dist/actions/sync/sync-project.action.d.ts.map +1 -0
  43. package/dist/actions/sync/sync-project.action.js +94 -0
  44. package/dist/actions/sync/sync-project.action.js.map +1 -0
  45. package/dist/actions/template-extractor/discover-generators.action.d.ts +49 -0
  46. package/dist/actions/template-extractor/discover-generators.action.d.ts.map +1 -0
  47. package/dist/actions/template-extractor/discover-generators.action.js +57 -0
  48. package/dist/actions/template-extractor/discover-generators.action.js.map +1 -0
  49. package/dist/actions/template-extractor/extract-templates.action.d.ts +14 -0
  50. package/dist/actions/template-extractor/extract-templates.action.d.ts.map +1 -0
  51. package/dist/actions/template-extractor/extract-templates.action.js +60 -0
  52. package/dist/actions/template-extractor/extract-templates.action.js.map +1 -0
  53. package/dist/actions/template-extractor/generate-templates.action.d.ts +12 -0
  54. package/dist/actions/template-extractor/generate-templates.action.d.ts.map +1 -0
  55. package/dist/actions/template-extractor/generate-templates.action.js +58 -0
  56. package/dist/actions/template-extractor/generate-templates.action.js.map +1 -0
  57. package/dist/actions/template-extractor/index.d.ts +4 -0
  58. package/dist/actions/template-extractor/index.d.ts.map +1 -0
  59. package/dist/actions/template-extractor/index.js +4 -0
  60. package/dist/actions/template-extractor/index.js.map +1 -0
  61. package/dist/actions/templates/configure-raw-template.action.d.ts +16 -0
  62. package/dist/actions/templates/configure-raw-template.action.d.ts.map +1 -0
  63. package/dist/actions/templates/configure-raw-template.action.js +50 -0
  64. package/dist/actions/templates/configure-raw-template.action.js.map +1 -0
  65. package/dist/actions/templates/configure-text-template.action.d.ts +27 -0
  66. package/dist/actions/templates/configure-text-template.action.d.ts.map +1 -0
  67. package/dist/actions/templates/configure-text-template.action.js +64 -0
  68. package/dist/actions/templates/configure-text-template.action.js.map +1 -0
  69. package/dist/actions/templates/configure-ts-template.action.d.ts +18 -0
  70. package/dist/actions/templates/configure-ts-template.action.d.ts.map +1 -0
  71. package/dist/actions/templates/configure-ts-template.action.js +58 -0
  72. package/dist/actions/templates/configure-ts-template.action.js.map +1 -0
  73. package/dist/actions/templates/delete-template.action.d.ts +15 -0
  74. package/dist/actions/templates/delete-template.action.d.ts.map +1 -0
  75. package/dist/actions/templates/delete-template.action.js +49 -0
  76. package/dist/actions/templates/delete-template.action.js.map +1 -0
  77. package/dist/actions/templates/index.d.ts +7 -0
  78. package/dist/actions/templates/index.d.ts.map +1 -0
  79. package/dist/actions/templates/index.js +7 -0
  80. package/dist/actions/templates/index.js.map +1 -0
  81. package/dist/actions/templates/list-templates.action.d.ts +35 -0
  82. package/dist/actions/templates/list-templates.action.d.ts.map +1 -0
  83. package/dist/actions/templates/list-templates.action.js +63 -0
  84. package/dist/actions/templates/list-templates.action.js.map +1 -0
  85. package/dist/actions/templates/show-template-metadata.action.d.ts +17 -0
  86. package/dist/actions/templates/show-template-metadata.action.d.ts.map +1 -0
  87. package/dist/actions/templates/show-template-metadata.action.js +57 -0
  88. package/dist/actions/templates/show-template-metadata.action.js.map +1 -0
  89. package/dist/actions/types.d.ts +60 -0
  90. package/dist/actions/types.d.ts.map +1 -0
  91. package/dist/actions/types.js +9 -0
  92. package/dist/actions/types.js.map +1 -0
  93. package/dist/actions/utils/cli.d.ts +12 -0
  94. package/dist/actions/utils/cli.d.ts.map +1 -0
  95. package/dist/actions/utils/cli.js +14 -0
  96. package/dist/actions/utils/cli.js.map +1 -0
  97. package/dist/actions/utils/index.d.ts +6 -0
  98. package/dist/actions/utils/index.d.ts.map +1 -0
  99. package/dist/actions/utils/index.js +6 -0
  100. package/dist/actions/utils/index.js.map +1 -0
  101. package/dist/actions/utils/project-discovery.d.ts +22 -0
  102. package/dist/actions/utils/project-discovery.d.ts.map +1 -0
  103. package/dist/actions/utils/project-discovery.js +78 -0
  104. package/dist/actions/utils/project-discovery.js.map +1 -0
  105. package/dist/actions/utils/project-id.d.ts +7 -0
  106. package/dist/actions/utils/project-id.d.ts.map +1 -0
  107. package/dist/actions/utils/project-id.js +15 -0
  108. package/dist/actions/utils/project-id.js.map +1 -0
  109. package/dist/actions/utils/projects.d.ts +9 -0
  110. package/dist/actions/utils/projects.d.ts.map +1 -0
  111. package/dist/actions/utils/projects.js +16 -0
  112. package/dist/actions/utils/projects.js.map +1 -0
  113. package/dist/actions/utils/run-in-worker.d.ts +13 -0
  114. package/dist/actions/utils/run-in-worker.d.ts.map +1 -0
  115. package/dist/actions/utils/run-in-worker.js +78 -0
  116. package/dist/actions/utils/run-in-worker.js.map +1 -0
  117. package/dist/actions/utils/trpc.d.ts +16 -0
  118. package/dist/actions/utils/trpc.d.ts.map +1 -0
  119. package/dist/actions/utils/trpc.js +19 -0
  120. package/dist/actions/utils/trpc.js.map +1 -0
  121. package/dist/actions/utils/worker-script.d.ts +28 -0
  122. package/dist/actions/utils/worker-script.d.ts.map +1 -0
  123. package/dist/actions/utils/worker-script.js +55 -0
  124. package/dist/actions/utils/worker-script.js.map +1 -0
  125. package/dist/api/context.d.ts.map +1 -1
  126. package/dist/api/trpc.d.ts.map +1 -1
  127. package/dist/compiler/web/index.d.ts.map +1 -1
  128. package/dist/compiler/web/index.js +3 -2
  129. package/dist/compiler/web/index.js.map +1 -1
  130. package/dist/constants/server.d.ts +1 -1
  131. package/dist/constants/server.js +1 -1
  132. package/dist/dev-server/api/router.d.ts +325 -0
  133. package/dist/dev-server/api/router.d.ts.map +1 -0
  134. package/dist/dev-server/api/router.js +40 -0
  135. package/dist/dev-server/api/router.js.map +1 -0
  136. package/dist/dev-server/api/trpc.d.ts +20 -0
  137. package/dist/dev-server/api/trpc.d.ts.map +1 -0
  138. package/dist/dev-server/api/trpc.js +18 -0
  139. package/dist/dev-server/api/trpc.js.map +1 -0
  140. package/dist/dev-server/auth-plugin.d.ts +6 -0
  141. package/dist/dev-server/auth-plugin.d.ts.map +1 -0
  142. package/dist/dev-server/auth-plugin.js +43 -0
  143. package/dist/dev-server/auth-plugin.js.map +1 -0
  144. package/dist/dev-server/get-or-create-config.d.ts +18 -0
  145. package/dist/dev-server/get-or-create-config.d.ts.map +1 -0
  146. package/dist/dev-server/get-or-create-config.js +76 -0
  147. package/dist/dev-server/get-or-create-config.js.map +1 -0
  148. package/dist/dev-server/index.d.ts +4 -0
  149. package/dist/dev-server/index.d.ts.map +1 -0
  150. package/dist/dev-server/index.js +3 -0
  151. package/dist/dev-server/index.js.map +1 -0
  152. package/dist/dev-server/mcp/fastify.d.ts +8 -0
  153. package/dist/dev-server/mcp/fastify.d.ts.map +1 -0
  154. package/dist/dev-server/mcp/fastify.js +80 -0
  155. package/dist/dev-server/mcp/fastify.js.map +1 -0
  156. package/dist/dev-server/mcp/server.d.ts +15 -0
  157. package/dist/dev-server/mcp/server.d.ts.map +1 -0
  158. package/dist/dev-server/mcp/server.js +120 -0
  159. package/dist/dev-server/mcp/server.js.map +1 -0
  160. package/dist/dev-server/mcp/stdio.d.ts +4 -0
  161. package/dist/dev-server/mcp/stdio.d.ts.map +1 -0
  162. package/dist/dev-server/mcp/stdio.js +15 -0
  163. package/dist/dev-server/mcp/stdio.js.map +1 -0
  164. package/dist/dev-server/server.d.ts +18 -0
  165. package/dist/dev-server/server.d.ts.map +1 -0
  166. package/dist/dev-server/server.js +91 -0
  167. package/dist/dev-server/server.js.map +1 -0
  168. package/dist/diff/diff-project.d.ts +37 -20
  169. package/dist/diff/diff-project.d.ts.map +1 -1
  170. package/dist/diff/diff-project.js +89 -79
  171. package/dist/diff/diff-project.js.map +1 -1
  172. package/dist/fastify-plugins/graceful-shutdown.d.ts.map +1 -0
  173. package/dist/fastify-plugins/graceful-shutdown.js.map +1 -0
  174. package/dist/server/builder-service-manager.d.ts +9 -8
  175. package/dist/server/builder-service-manager.d.ts.map +1 -1
  176. package/dist/server/builder-service-manager.js +4 -10
  177. package/dist/server/builder-service-manager.js.map +1 -1
  178. package/dist/server/server.js +1 -1
  179. package/dist/server/server.js.map +1 -1
  180. package/dist/service/builder-service.d.ts +3 -4
  181. package/dist/service/builder-service.d.ts.map +1 -1
  182. package/dist/service/builder-service.js +7 -3
  183. package/dist/service/builder-service.js.map +1 -1
  184. package/dist/template-extractor/discover-generators.d.ts.map +1 -1
  185. package/dist/template-extractor/discover-generators.js +1 -1
  186. package/dist/template-extractor/discover-generators.js.map +1 -1
  187. package/dist/templates/configure/configure-raw-template.d.ts +13 -0
  188. package/dist/templates/configure/configure-raw-template.d.ts.map +1 -0
  189. package/dist/templates/configure/configure-raw-template.js +26 -0
  190. package/dist/templates/configure/configure-raw-template.js.map +1 -0
  191. package/dist/templates/configure/configure-text-template.d.ts +18 -0
  192. package/dist/templates/configure/configure-text-template.d.ts.map +1 -0
  193. package/dist/templates/configure/configure-text-template.js +48 -0
  194. package/dist/templates/configure/configure-text-template.js.map +1 -0
  195. package/dist/templates/configure/configure-ts-template.d.ts +15 -0
  196. package/dist/templates/configure/configure-ts-template.d.ts.map +1 -0
  197. package/dist/templates/configure/configure-ts-template.js +44 -0
  198. package/dist/templates/configure/configure-ts-template.js.map +1 -0
  199. package/dist/templates/configure/index.d.ts +5 -0
  200. package/dist/templates/configure/index.d.ts.map +1 -0
  201. package/dist/templates/configure/index.js +4 -0
  202. package/dist/templates/configure/index.js.map +1 -0
  203. package/dist/templates/configure/types.d.ts +7 -0
  204. package/dist/templates/configure/types.d.ts.map +1 -0
  205. package/dist/templates/configure/types.js +2 -0
  206. package/dist/templates/configure/types.js.map +1 -0
  207. package/dist/templates/delete/delete-template.d.ts +16 -0
  208. package/dist/templates/delete/delete-template.d.ts.map +1 -0
  209. package/dist/templates/delete/delete-template.js +45 -0
  210. package/dist/templates/delete/delete-template.js.map +1 -0
  211. package/dist/templates/list/list-templates.d.ts +22 -0
  212. package/dist/templates/list/list-templates.d.ts.map +1 -0
  213. package/dist/templates/list/list-templates.js +29 -0
  214. package/dist/templates/list/list-templates.js.map +1 -0
  215. package/dist/templates/show/show-template-metadata.d.ts +19 -0
  216. package/dist/templates/show/show-template-metadata.d.ts.map +1 -0
  217. package/dist/templates/show/show-template-metadata.js +37 -0
  218. package/dist/templates/show/show-template-metadata.js.map +1 -0
  219. package/dist/templates/utils/extractor-config.d.ts +18 -0
  220. package/dist/templates/utils/extractor-config.d.ts.map +1 -0
  221. package/dist/templates/utils/extractor-config.js +55 -0
  222. package/dist/templates/utils/extractor-config.js.map +1 -0
  223. package/dist/templates/utils/infer-exports-from-ts-file.d.ts +10 -0
  224. package/dist/templates/utils/infer-exports-from-ts-file.d.ts.map +1 -0
  225. package/dist/templates/utils/infer-exports-from-ts-file.js +87 -0
  226. package/dist/templates/utils/infer-exports-from-ts-file.js.map +1 -0
  227. package/dist/templates/utils/resolve-file-path.d.ts +15 -0
  228. package/dist/templates/utils/resolve-file-path.d.ts.map +1 -0
  229. package/dist/templates/utils/resolve-file-path.js +48 -0
  230. package/dist/templates/utils/resolve-file-path.js.map +1 -0
  231. package/dist/templates/utils/resolve-generator.d.ts +8 -0
  232. package/dist/templates/utils/resolve-generator.d.ts.map +1 -0
  233. package/dist/templates/utils/resolve-generator.js +26 -0
  234. package/dist/templates/utils/resolve-generator.js.map +1 -0
  235. package/dist/templates/utils/template-metadata.d.ts +14 -0
  236. package/dist/templates/utils/template-metadata.d.ts.map +1 -0
  237. package/dist/templates/utils/template-metadata.js +54 -0
  238. package/dist/templates/utils/template-metadata.js.map +1 -0
  239. package/dist/utils/case.d.ts +0 -1
  240. package/dist/utils/case.d.ts.map +1 -1
  241. package/dist/utils/case.js +1 -10
  242. package/dist/utils/case.js.map +1 -1
  243. package/package.json +17 -12
  244. package/dist/server/graceful-shutdown.d.ts.map +0 -1
  245. package/dist/server/graceful-shutdown.js.map +0 -1
  246. /package/dist/{server → fastify-plugins}/graceful-shutdown.d.ts +0 -0
  247. /package/dist/{server → fastify-plugins}/graceful-shutdown.js +0 -0
@@ -0,0 +1,43 @@
1
+ import fastifyPlugin from 'fastify-plugin';
2
+ const devServerAuthPluginCallback = function (fastify, { port, token }, done) {
3
+ // Add authentication hook for all routes
4
+ fastify.addHook('onRequest', async (request, reply) => {
5
+ // Check origin for DNS rebinding protection
6
+ const { origin } = request.headers;
7
+ const { host } = request.headers;
8
+ const allowedHosts = [
9
+ `localhost:${port}`,
10
+ `127.0.0.1:${port}`,
11
+ `[::1]:${port}`,
12
+ ];
13
+ const allowedOrigins = new Set(allowedHosts.map((host) => `http://${host}`));
14
+ // For non-GET requests, check origin header
15
+ if (request.method !== 'GET' && origin && !allowedOrigins.has(origin)) {
16
+ reply.code(403).send({ error: `Blocked: invalid origin ${origin}` });
17
+ return;
18
+ }
19
+ // For all requests, check host header
20
+ if (!allowedHosts.includes(host ?? '')) {
21
+ reply
22
+ .code(403)
23
+ .send({ error: `Blocked: invalid host ${host ?? 'unknown'}` });
24
+ return;
25
+ }
26
+ // Check authentication token
27
+ const authHeader = request.headers.authorization;
28
+ if (!authHeader) {
29
+ reply.code(401).send({ error: 'Authorization header required' });
30
+ return;
31
+ }
32
+ const requestToken = authHeader.replace('Bearer ', '');
33
+ if (requestToken !== token) {
34
+ reply.code(401).send({ error: 'Invalid token' });
35
+ return;
36
+ }
37
+ });
38
+ done();
39
+ };
40
+ export const devServerAuthPlugin = fastifyPlugin(devServerAuthPluginCallback, {
41
+ name: 'dev-server-auth',
42
+ });
43
+ //# sourceMappingURL=auth-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-plugin.js","sourceRoot":"","sources":["../../src/dev-server/auth-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAI3C,MAAM,2BAA2B,GAC/B,UAAU,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI;IACtC,yCAAyC;IACzC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACpD,4CAA4C;QAC5C,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAEjC,MAAM,YAAY,GAAG;YACnB,aAAa,IAAI,EAAE;YACnB,aAAa,IAAI,EAAE;YACnB,SAAS,IAAI,EAAE;SAChB,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,GAAG,CAC5B,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,CAC7C,CAAC;QAEF,4CAA4C;QAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACtE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,MAAM,EAAE,EAAE,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;YACvC,KAAK;iBACF,IAAI,CAAC,GAAG,CAAC;iBACT,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,IAAI,IAAI,SAAS,EAAE,EAAE,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,6BAA6B;QAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC,2BAA2B,EAAE;IAC5E,IAAI,EAAE,iBAAiB;CACxB,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ declare const devServerConfigSchema: z.ZodObject<{
3
+ port: z.ZodNumber;
4
+ token: z.ZodString;
5
+ }, "strip", z.ZodTypeAny, {
6
+ port: number;
7
+ token: string;
8
+ }, {
9
+ port: number;
10
+ token: string;
11
+ }>;
12
+ export type DevServerConfig = z.infer<typeof devServerConfigSchema>;
13
+ /**
14
+ * Gets or creates a dev server configuration
15
+ */
16
+ export declare function getOrCreateDevServerConfig(directory: string): Promise<DevServerConfig>;
17
+ export {};
18
+ //# sourceMappingURL=get-or-create-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-or-create-config.d.ts","sourceRoot":"","sources":["../../src/dev-server/get-or-create-config.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,qBAAqB;;;;;;;;;EAGzB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAqDpE;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAuC1B"}
@@ -0,0 +1,76 @@
1
+ import { fileExists, findNearestPackageJson, handleFileNotFoundError, readJsonWithSchema, writeStablePrettyJson, } from '@baseplate-dev/utils/node';
2
+ import crypto from 'node:crypto';
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { z } from 'zod';
6
+ const devServerConfigSchema = z.object({
7
+ port: z.number(),
8
+ token: z.string().min(1),
9
+ });
10
+ const DEFAULT_DEV_SERVER_PORT = 4500;
11
+ const ROOT_PACKAGE_NAME = '@baseplate-dev/root';
12
+ async function isRootPackage(packageJsonPath) {
13
+ const content = await readJsonWithSchema(packageJsonPath, z.object({ name: z.string() }));
14
+ return content.name === ROOT_PACKAGE_NAME;
15
+ }
16
+ /**
17
+ * Detects the appropriate root directory based on project type
18
+ */
19
+ async function detectProjectRoot(startDir) {
20
+ // Check if we're in the Baseplate monorepo
21
+ const packageJsonPath = await findNearestPackageJson({ cwd: startDir });
22
+ if (packageJsonPath) {
23
+ // Check current package.json
24
+ if (await isRootPackage(packageJsonPath)) {
25
+ return path.dirname(packageJsonPath);
26
+ }
27
+ // Check parent directory for monorepo root
28
+ const parentDir = path.dirname(path.dirname(packageJsonPath));
29
+ const parentPkgPath = await findNearestPackageJson({ cwd: parentDir });
30
+ if (parentPkgPath && (await isRootPackage(parentPkgPath))) {
31
+ return path.dirname(parentPkgPath);
32
+ }
33
+ }
34
+ // Check if we're in a generated Baseplate project
35
+ let currentDir = path.resolve(startDir);
36
+ while (currentDir !== path.dirname(currentDir)) {
37
+ const projectDefPath = path.join(currentDir, 'baseplate', 'project-definition.json');
38
+ if (await fileExists(projectDefPath)) {
39
+ return currentDir;
40
+ }
41
+ currentDir = path.dirname(currentDir);
42
+ }
43
+ throw new Error(`Project root not found. Please run this command from the root of a Baseplate project or the Baseplate monorepo.`);
44
+ }
45
+ /**
46
+ * Gets or creates a dev server configuration
47
+ */
48
+ export async function getOrCreateDevServerConfig(directory) {
49
+ // Detect project root
50
+ const rootDirectory = await detectProjectRoot(directory);
51
+ // Config path is always in .baseplate/dev-server.json
52
+ const configPath = path.join(rootDirectory, '.baseplate', 'dev-server.json');
53
+ // Try to load existing config
54
+ const existingConfig = await readJsonWithSchema(configPath, devServerConfigSchema).catch(handleFileNotFoundError);
55
+ if (existingConfig) {
56
+ return existingConfig;
57
+ }
58
+ // Simple port calculation: 4500 + PORT_OFFSET
59
+ const portOffset = process.env.PORT_OFFSET
60
+ ? Number.parseInt(process.env.PORT_OFFSET, 10)
61
+ : 0;
62
+ const port = DEFAULT_DEV_SERVER_PORT + portOffset;
63
+ // Generate secure token
64
+ const token = crypto.randomBytes(32).toString('hex');
65
+ const config = {
66
+ port,
67
+ token,
68
+ };
69
+ // Ensure .baseplate directory exists
70
+ const baseplateDir = path.dirname(configPath);
71
+ await fs.mkdir(baseplateDir, { recursive: true });
72
+ // Save config
73
+ await writeStablePrettyJson(configPath, config);
74
+ return config;
75
+ }
76
+ //# sourceMappingURL=get-or-create-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-or-create-config.js","sourceRoot":"","sources":["../../src/dev-server/get-or-create-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type { DevServerRouter } from './api/router.js';
2
+ export * from './mcp/stdio.js';
3
+ export * from './server.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dev-server/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './mcp/stdio.js';
2
+ export * from './server.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dev-server/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { FastifyPluginCallbackZod } from 'fastify-type-provider-zod';
3
+ interface McpPluginOptions {
4
+ mcpServer: McpServer;
5
+ }
6
+ export declare const mcpPlugin: FastifyPluginCallbackZod<McpPluginOptions>;
7
+ export {};
8
+ //# sourceMappingURL=fastify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../../src/dev-server/mcp/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAO1E,UAAU,gBAAgB;IACxB,SAAS,EAAE,SAAS,CAAC;CACtB;AA+FD,eAAO,MAAM,SAAS,4CAAmC,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
2
+ import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
3
+ import fastifyPlugin from 'fastify-plugin';
4
+ import { randomUUID } from 'node:crypto';
5
+ const mcpPluginCallback = function (fastify, { mcpServer }, done) {
6
+ // Map to store transports by session ID
7
+ const transports = {};
8
+ // Handle POST requests for client-to-server communication
9
+ fastify.post('/dev/mcp', async (req, reply) => {
10
+ // Check for existing session ID
11
+ const sessionId = req.headers['mcp-session-id'];
12
+ let transport;
13
+ if (sessionId && transports[sessionId]) {
14
+ // Reuse existing transport
15
+ transport = transports[sessionId];
16
+ }
17
+ else if (!sessionId && isInitializeRequest(req.body)) {
18
+ // New initialization request
19
+ transport = new StreamableHTTPServerTransport({
20
+ sessionIdGenerator: () => randomUUID(),
21
+ onsessioninitialized: (newSessionId) => {
22
+ // Store the transport by session ID
23
+ transports[newSessionId] = transport;
24
+ fastify.log.info('MCP session initialized', {
25
+ sessionId: newSessionId,
26
+ });
27
+ },
28
+ // DNS rebinding protection
29
+ enableDnsRebindingProtection: true,
30
+ });
31
+ // Clean up transport when closed
32
+ // eslint-disable-next-line unicorn/prefer-add-event-listener -- MCP server requires this signature
33
+ transport.onclose = () => {
34
+ if (transport.sessionId) {
35
+ transports[transport.sessionId] = undefined;
36
+ fastify.log.info('MCP session closed', {
37
+ sessionId: transport.sessionId,
38
+ });
39
+ }
40
+ };
41
+ await mcpServer.connect(transport);
42
+ }
43
+ else {
44
+ // Invalid request
45
+ reply.status(400);
46
+ return {
47
+ jsonrpc: '2.0',
48
+ error: {
49
+ code: -32_000,
50
+ message: 'Bad Request: No valid session ID provided or not an initialize request',
51
+ },
52
+ id: null,
53
+ };
54
+ }
55
+ // Handle the request
56
+ await transport.handleRequest(req.raw, reply.raw, req.body);
57
+ });
58
+ // Reusable handler for GET and DELETE requests
59
+ const handleSessionRequest = async (req, reply) => {
60
+ const sessionId = req.headers['mcp-session-id'];
61
+ if (!sessionId || !transports[sessionId]) {
62
+ reply.status(400).send({
63
+ error: 'Invalid or missing session ID',
64
+ });
65
+ return;
66
+ }
67
+ const transport = transports[sessionId];
68
+ await transport.handleRequest(req.raw, reply.raw, req.body);
69
+ };
70
+ // Handle GET requests for server-to-client notifications via SSE
71
+ fastify.get('/dev/mcp', handleSessionRequest);
72
+ // Handle DELETE requests for session termination
73
+ fastify.delete('/dev/mcp', handleSessionRequest);
74
+ fastify.log.info('MCP plugin registered', {
75
+ endpoint: '/dev/mcp',
76
+ });
77
+ done();
78
+ };
79
+ export const mcpPlugin = fastifyPlugin(mcpPluginCallback);
80
+ //# sourceMappingURL=fastify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../../src/dev-server/mcp/fastify.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzC,MAAM,iBAAiB,GAA+C,UACpE,OAAwB,EACxB,EAAE,SAAS,EAAE,EACb,IAAI;IAEJ,wCAAwC;IACxC,MAAM,UAAU,GACd,EAAE,CAAC;IAEL,0DAA0D;IAC1D,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,GAAmB,EAAE,KAAmB,EAAE,EAAE;QAC1E,gCAAgC;QAChC,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;QACtE,IAAI,SAAwC,CAAC;QAE7C,IAAI,SAAS,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,2BAA2B;YAC3B,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,CAAC,SAAS,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,6BAA6B;YAC7B,SAAS,GAAG,IAAI,6BAA6B,CAAC;gBAC5C,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;gBACtC,oBAAoB,EAAE,CAAC,YAAY,EAAE,EAAE;oBACrC,oCAAoC;oBACpC,UAAU,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;oBACrC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAyB,EAAE;wBAC1C,SAAS,EAAE,YAAY;qBACxB,CAAC,CAAC;gBACL,CAAC;gBACD,2BAA2B;gBAC3B,4BAA4B,EAAE,IAAI;aACnC,CAAC,CAAC;YAEH,iCAAiC;YACjC,mGAAmG;YACnG,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;gBACvB,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;oBACxB,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;oBAC5C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE;wBACrC,SAAS,EAAE,SAAS,CAAC,SAAS;qBAC/B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,kBAAkB;YAClB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,MAAM;oBACb,OAAO,EACL,wEAAwE;iBAC3E;gBACD,EAAE,EAAE,IAAI;aACT,CAAC;QACJ,CAAC;QAED,qBAAqB;QACrB,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,+CAA+C;IAC/C,MAAM,oBAAoB,GAAG,KAAK,EAChC,GAAmB,EACnB,KAAmB,EACJ,EAAE;QACjB,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;QACtE,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACrB,KAAK,EAAE,+BAA+B;aACvC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC,CAAC;IAEF,iEAAiE;IACjE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAE9C,iDAAiD;IACjD,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAEjD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE;QACxC,QAAQ,EAAE,UAAU;KACrB,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { AnyServiceAction, ServiceActionContext } from '#src/actions/types.js';
3
+ interface CreateMcpServerOptions {
4
+ context: ServiceActionContext;
5
+ actions: AnyServiceAction[];
6
+ /**
7
+ * Whether to forward all logs to the console. (errors are always forwarded)
8
+ *
9
+ * This is important to leave disable in the context of STDIO mode since we can't have the console logs clobbering the output.
10
+ */
11
+ forwardAllLogsToConsole?: boolean;
12
+ }
13
+ export declare function createMcpServer({ actions, context, forwardAllLogsToConsole, }: CreateMcpServerOptions): McpServer;
14
+ export {};
15
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/dev-server/mcp/server.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,SAAS,EAEV,MAAM,yCAAyC,CAAC;AAGjD,OAAO,KAAK,EACV,gBAAgB,EAEhB,oBAAoB,EACrB,MAAM,uBAAuB,CAAC;AAkB/B,UAAU,sBAAsB;IAC9B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,OAAO,EACP,uBAAuB,GACxB,EAAE,sBAAsB,GAAG,SAAS,CAoIpC"}
@@ -0,0 +1,120 @@
1
+ import { createEventedLogger } from '@baseplate-dev/sync';
2
+ import { enhanceErrorWithContext } from '@baseplate-dev/utils';
3
+ import { McpServer, ResourceTemplate, } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ import { SetLevelRequestSchema } from '@modelcontextprotocol/sdk/types.js';
5
+ import { runActionInWorker } from '#src/actions/utils/run-in-worker.js';
6
+ // List of MCP log levels ordered from most to least verbose
7
+ const LOG_LEVEL_LIST = [
8
+ 'debug',
9
+ 'info',
10
+ 'notice',
11
+ 'warning',
12
+ 'error',
13
+ 'critical',
14
+ 'alert',
15
+ 'emergency',
16
+ ];
17
+ export function createMcpServer({ actions, context, forwardAllLogsToConsole, }) {
18
+ const { projects, logger } = context;
19
+ const server = new McpServer({
20
+ name: 'baseplate-dev-server',
21
+ version: '1.0.0',
22
+ }, {
23
+ capabilities: {
24
+ logging: {},
25
+ },
26
+ });
27
+ server.registerResource('projects', new ResourceTemplate('baseplate://projects/{projectId}', {
28
+ list: () => ({
29
+ resources: projects.map((p) => ({
30
+ uri: `baseplate://projects/${p.id}`,
31
+ name: p.name,
32
+ })),
33
+ }),
34
+ }), {
35
+ title: 'Projects',
36
+ description: 'A list of projects tracked by the dev server',
37
+ }, (uri, { projectId }) => {
38
+ const project = projects.find((p) => p.id === projectId);
39
+ if (!project) {
40
+ return { contents: [] };
41
+ }
42
+ return {
43
+ contents: [
44
+ {
45
+ uri: uri.href,
46
+ text: JSON.stringify({
47
+ id: project.id,
48
+ directory: project.directory,
49
+ name: project.name,
50
+ }),
51
+ mimeType: 'application/json',
52
+ },
53
+ ],
54
+ };
55
+ });
56
+ let logLevel = 'info';
57
+ server.server.setRequestHandler(SetLevelRequestSchema, (request) => {
58
+ logLevel = request.params.level;
59
+ return {};
60
+ });
61
+ const mcpLogger = createEventedLogger();
62
+ mcpLogger.onMessage((message) => {
63
+ const mcpLevel = message.level === 'warn' ? 'warning' : message.level;
64
+ if (LOG_LEVEL_LIST.indexOf(logLevel) > LOG_LEVEL_LIST.indexOf(mcpLevel)) {
65
+ return;
66
+ }
67
+ if (message.level === 'error' || forwardAllLogsToConsole) {
68
+ logger[message.level](message.metadata ?? {}, message.message);
69
+ }
70
+ server.server
71
+ .sendLoggingMessage({
72
+ // match MCP specification for warn => warning
73
+ level: mcpLevel,
74
+ data: {
75
+ message: message.message,
76
+ metadata: message.metadata,
77
+ },
78
+ })
79
+ .catch((err) => {
80
+ logger.error(enhanceErrorWithContext(err, 'Failed to send logging message'));
81
+ });
82
+ });
83
+ const mcpServiceContext = {
84
+ ...context,
85
+ logger: mcpLogger,
86
+ };
87
+ let isActionRunning = false;
88
+ for (const action of actions) {
89
+ const typedAction = action;
90
+ server.registerTool(action.name, {
91
+ title: action.title,
92
+ description: action.description,
93
+ inputSchema: typedAction.inputSchema,
94
+ outputSchema: typedAction.outputSchema,
95
+ }, async (input) => {
96
+ if (isActionRunning) {
97
+ throw new Error('An action is already running');
98
+ }
99
+ try {
100
+ isActionRunning = true;
101
+ const result = await runActionInWorker(typedAction, input, mcpServiceContext);
102
+ return {
103
+ content: [
104
+ {
105
+ type: 'text',
106
+ text: JSON.stringify(result),
107
+ mimeType: 'application/json',
108
+ },
109
+ ],
110
+ structuredContent: result,
111
+ };
112
+ }
113
+ finally {
114
+ isActionRunning = false;
115
+ }
116
+ });
117
+ }
118
+ return server;
119
+ }
120
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/dev-server/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ServiceActionContext } from '#src/actions/types.js';
3
+ export declare function startMcpStdioServer(context: ServiceActionContext): Promise<McpServer>;
4
+ //# sourceMappingURL=stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../../src/dev-server/mcp/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAMlE,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,SAAS,CAAC,CAYpB"}
@@ -0,0 +1,15 @@
1
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
2
+ import { ALL_SERVICE_ACTIONS } from '#src/actions/registry.js';
3
+ import { createMcpServer } from './server.js';
4
+ export async function startMcpStdioServer(context) {
5
+ const server = createMcpServer({
6
+ actions: ALL_SERVICE_ACTIONS,
7
+ context,
8
+ });
9
+ const transport = new StdioServerTransport();
10
+ await server.connect(transport).catch((error) => {
11
+ context.logger.error(error);
12
+ });
13
+ return server;
14
+ }
15
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../src/dev-server/mcp/stdio.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAIjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAA6B;IAE7B,MAAM,MAAM,GAAG,eAAe,CAAC;QAC7B,OAAO,EAAE,mBAAmB;QAC5B,OAAO;KACR,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ServiceActionContext } from '#src/actions/types.js';
2
+ export interface DevServerOptions {
3
+ cwd: string;
4
+ context: ServiceActionContext;
5
+ }
6
+ export declare class DevServer {
7
+ private server;
8
+ private context;
9
+ private cwd;
10
+ constructor(options: DevServerOptions);
11
+ start(): Promise<{
12
+ port: number;
13
+ token: string;
14
+ }>;
15
+ stop(): Promise<void>;
16
+ isRunning(): boolean;
17
+ }
18
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAalE,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,oBAAoB,CAAC;CAC/B;AA4CD,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,GAAG,CAAS;gBAER,OAAO,EAAE,gBAAgB;IAK/B,KAAK,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAqCjD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,SAAS,IAAI,OAAO;CAGrB"}
@@ -0,0 +1,91 @@
1
+ import { enhanceErrorWithContext } from '@baseplate-dev/utils';
2
+ import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
3
+ import { fastify } from 'fastify';
4
+ import { serializerCompiler, validatorCompiler, } from 'fastify-type-provider-zod';
5
+ import { ALL_SERVICE_ACTIONS } from '#src/actions/registry.js';
6
+ import { devServerRouter } from './api/router.js';
7
+ import { devServerAuthPlugin } from './auth-plugin.js';
8
+ import { getOrCreateDevServerConfig } from './get-or-create-config.js';
9
+ import { mcpPlugin } from './mcp/fastify.js';
10
+ import { createMcpServer } from './mcp/server.js';
11
+ async function createServer(config, context) {
12
+ // Create Fastify server
13
+ const server = fastify({
14
+ loggerInstance: context.logger,
15
+ forceCloseConnections: 'idle',
16
+ maxParamLength: 10_000,
17
+ });
18
+ server.setValidatorCompiler(validatorCompiler);
19
+ server.setSerializerCompiler(serializerCompiler);
20
+ // Add authentication hook for all dev routes
21
+ await server.register(devServerAuthPlugin, config);
22
+ // Register TRPC router
23
+ await server.register(fastifyTRPCPlugin, {
24
+ prefix: '/dev/trpc',
25
+ trpcOptions: {
26
+ router: devServerRouter,
27
+ createContext: () => context,
28
+ onError: ({ error }) => {
29
+ server.log.error(error);
30
+ },
31
+ },
32
+ });
33
+ // Register MCP server
34
+ const mcpServer = createMcpServer({
35
+ actions: ALL_SERVICE_ACTIONS,
36
+ context,
37
+ forwardAllLogsToConsole: true,
38
+ });
39
+ await server.register(mcpPlugin, {
40
+ mcpServer,
41
+ });
42
+ return server;
43
+ }
44
+ export class DevServer {
45
+ server = null;
46
+ context;
47
+ cwd;
48
+ constructor(options) {
49
+ this.context = options.context;
50
+ this.cwd = options.cwd;
51
+ }
52
+ async start() {
53
+ if (this.server) {
54
+ throw new Error('Server is already running');
55
+ }
56
+ // Get or create server configuration
57
+ const configResult = await getOrCreateDevServerConfig(this.cwd);
58
+ const server = await createServer(configResult, this.context);
59
+ this.server = server;
60
+ // Start server
61
+ try {
62
+ await server.listen({
63
+ port: configResult.port,
64
+ host: '127.0.0.1',
65
+ });
66
+ server.log.info(`Baseplate dev server started for projects: ${this.context.projects.map((p) => p.name).join(', ')}`, {
67
+ port: configResult.port,
68
+ token: configResult.token,
69
+ projects: this.context.projects.map((p) => p.name),
70
+ });
71
+ return {
72
+ port: configResult.port,
73
+ token: configResult.token,
74
+ };
75
+ }
76
+ catch (error) {
77
+ this.server = null;
78
+ throw enhanceErrorWithContext(error, 'Failed to start dev server');
79
+ }
80
+ }
81
+ async stop() {
82
+ if (this.server) {
83
+ await this.server.close();
84
+ this.server = null;
85
+ }
86
+ }
87
+ isRunning() {
88
+ return this.server !== null;
89
+ }
90
+ }
91
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAK/D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAOlD,KAAK,UAAU,YAAY,CACzB,MAAuB,EACvB,OAA6B;IAE7B,wBAAwB;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC;QACrB,cAAc,EAAE,OAAO,CAAC,MAA2B;QACnD,qBAAqB,EAAE,MAAM;QAC7B,cAAc,EAAE,MAAM;KACvB,CAAC,CAAC;IAEH,MAAM,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAC/C,MAAM,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;IAEjD,6CAA6C;IAC7C,MAAM,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAEnD,uBAAuB;IACvB,MAAM,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE;QACvC,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE;YACX,MAAM,EAAE,eAAe;YACvB,aAAa,EAAE,GAAG,EAAE,CAAC,OAAO;YAC5B,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;gBACrB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;SACF;KACkD,CAAC,CAAC;IAEvD,sBAAsB;IACtB,MAAM,SAAS,GAAG,eAAe,CAAC;QAChC,OAAO,EAAE,mBAAmB;QAC5B,OAAO;QACP,uBAAuB,EAAE,IAAI;KAC9B,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE;QAC/B,SAAS;KACV,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,OAAO,SAAS;IACZ,MAAM,GAA2B,IAAI,CAAC;IACtC,OAAO,CAAuB;IAC9B,GAAG,CAAS;IAEpB,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,qCAAqC;QACrC,MAAM,YAAY,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,eAAe;QACf,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,MAAM,CAAC;gBAClB,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;YAEH,MAAM,CAAC,GAAG,CAAC,IAAI,CACb,8CAA8C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACnG;gBACE,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aACnD,CACF,CAAC;YAEF,OAAO;gBACL,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,KAAK,EAAE,YAAY,CAAC,KAAK;aAC1B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,MAAM,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IAC9B,CAAC;CACF"}