@superblocksteam/vite-plugin-file-sync 2.0.151 → 2.0.152-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/dist/ai-service/agent/middleware.d.ts.map +1 -1
  2. package/dist/ai-service/agent/middleware.js +10 -1
  3. package/dist/ai-service/agent/middleware.js.map +1 -1
  4. package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts.map +1 -1
  5. package/dist/ai-service/agent/prompts/build-base-system-prompt.js +25 -6
  6. package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
  7. package/dist/ai-service/agent/prompts/build-security-scan-prompt.d.ts.map +1 -1
  8. package/dist/ai-service/agent/prompts/build-security-scan-prompt.js +7 -2
  9. package/dist/ai-service/agent/prompts/build-security-scan-prompt.js.map +1 -1
  10. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.d.ts +47 -1
  11. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.d.ts.map +1 -1
  12. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js +129 -15
  13. package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js.map +1 -1
  14. package/dist/ai-service/agent/tools/apis/test-api.d.ts.map +1 -1
  15. package/dist/ai-service/agent/tools/apis/test-api.js +1 -24
  16. package/dist/ai-service/agent/tools/apis/test-api.js.map +1 -1
  17. package/dist/ai-service/agent/tools/databases/dev-database-tasks.d.ts +53 -9
  18. package/dist/ai-service/agent/tools/databases/dev-database-tasks.d.ts.map +1 -1
  19. package/dist/ai-service/agent/tools/databases/dev-database-tasks.js +304 -67
  20. package/dist/ai-service/agent/tools/databases/dev-database-tasks.js.map +1 -1
  21. package/dist/ai-service/agent/tools/databases/dev-database-tools.d.ts +47 -1
  22. package/dist/ai-service/agent/tools/databases/dev-database-tools.d.ts.map +1 -1
  23. package/dist/ai-service/agent/tools/databases/dev-database-tools.js +38 -1
  24. package/dist/ai-service/agent/tools/databases/dev-database-tools.js.map +1 -1
  25. package/dist/ai-service/agent/tools/integrations/execute-request.d.ts +391 -0
  26. package/dist/ai-service/agent/tools/integrations/execute-request.d.ts.map +1 -1
  27. package/dist/ai-service/agent/tools/integrations/execute-request.js +257 -44
  28. package/dist/ai-service/agent/tools/integrations/execute-request.js.map +1 -1
  29. package/dist/ai-service/agent/tools/integrations/index.d.ts +1 -1
  30. package/dist/ai-service/agent/tools/integrations/index.d.ts.map +1 -1
  31. package/dist/ai-service/agent/tools/integrations/index.js +1 -1
  32. package/dist/ai-service/agent/tools/integrations/index.js.map +1 -1
  33. package/dist/ai-service/agent/tools/integrations/managed-app-database.d.ts +16 -0
  34. package/dist/ai-service/agent/tools/integrations/managed-app-database.d.ts.map +1 -0
  35. package/dist/ai-service/agent/tools/integrations/managed-app-database.js +31 -0
  36. package/dist/ai-service/agent/tools/integrations/managed-app-database.js.map +1 -0
  37. package/dist/ai-service/agent/tools/integrations/sql-classification.d.ts +44 -0
  38. package/dist/ai-service/agent/tools/integrations/sql-classification.d.ts.map +1 -0
  39. package/dist/ai-service/agent/tools/integrations/sql-classification.js +352 -0
  40. package/dist/ai-service/agent/tools/integrations/sql-classification.js.map +1 -0
  41. package/dist/ai-service/agent/tools/report-security-findings.d.ts +5 -5
  42. package/dist/ai-service/agent/tools.d.ts.map +1 -1
  43. package/dist/ai-service/agent/tools.js +5 -1
  44. package/dist/ai-service/agent/tools.js.map +1 -1
  45. package/dist/ai-service/agent/tools2/registry.d.ts.map +1 -1
  46. package/dist/ai-service/agent/tools2/registry.js +2 -0
  47. package/dist/ai-service/agent/tools2/registry.js.map +1 -1
  48. package/dist/ai-service/agent/tools2/tools/check-task.d.ts.map +1 -1
  49. package/dist/ai-service/agent/tools2/tools/check-task.js +4 -1
  50. package/dist/ai-service/agent/tools2/tools/check-task.js.map +1 -1
  51. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
  52. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +12 -1
  53. package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
  54. package/dist/ai-service/agent/tools2/tools/wait-for-task.d.ts.map +1 -1
  55. package/dist/ai-service/agent/tools2/tools/wait-for-task.js +5 -1
  56. package/dist/ai-service/agent/tools2/tools/wait-for-task.js.map +1 -1
  57. package/dist/ai-service/chat/chat-session-store.d.ts +10 -1
  58. package/dist/ai-service/chat/chat-session-store.d.ts.map +1 -1
  59. package/dist/ai-service/chat/chat-session-store.js +65 -15
  60. package/dist/ai-service/chat/chat-session-store.js.map +1 -1
  61. package/dist/ai-service/context-archive-paths.d.ts +7 -0
  62. package/dist/ai-service/context-archive-paths.d.ts.map +1 -1
  63. package/dist/ai-service/context-archive-paths.js +7 -0
  64. package/dist/ai-service/context-archive-paths.js.map +1 -1
  65. package/dist/ai-service/context-download.d.ts.map +1 -1
  66. package/dist/ai-service/context-download.js +8 -10
  67. package/dist/ai-service/context-download.js.map +1 -1
  68. package/dist/ai-service/context-flush.d.ts +36 -0
  69. package/dist/ai-service/context-flush.d.ts.map +1 -0
  70. package/dist/ai-service/context-flush.js +90 -0
  71. package/dist/ai-service/context-flush.js.map +1 -0
  72. package/dist/ai-service/context-restore.d.ts +64 -0
  73. package/dist/ai-service/context-restore.d.ts.map +1 -0
  74. package/dist/ai-service/context-restore.js +136 -0
  75. package/dist/ai-service/context-restore.js.map +1 -0
  76. package/dist/ai-service/context-upload.d.ts +13 -4
  77. package/dist/ai-service/context-upload.d.ts.map +1 -1
  78. package/dist/ai-service/context-upload.js +28 -18
  79. package/dist/ai-service/context-upload.js.map +1 -1
  80. package/dist/ai-service/dev-database-client.d.ts +51 -0
  81. package/dist/ai-service/dev-database-client.d.ts.map +1 -1
  82. package/dist/ai-service/dev-database-client.js +3 -0
  83. package/dist/ai-service/dev-database-client.js.map +1 -1
  84. package/dist/ai-service/index.d.ts +19 -0
  85. package/dist/ai-service/index.d.ts.map +1 -1
  86. package/dist/ai-service/index.js +449 -182
  87. package/dist/ai-service/index.js.map +1 -1
  88. package/dist/ai-service/llm/context-v2/adapter.d.ts.map +1 -1
  89. package/dist/ai-service/llm/context-v2/adapter.js +1 -0
  90. package/dist/ai-service/llm/context-v2/adapter.js.map +1 -1
  91. package/dist/ai-service/llm/context-v2/compaction/client-side.d.ts +30 -0
  92. package/dist/ai-service/llm/context-v2/compaction/client-side.d.ts.map +1 -1
  93. package/dist/ai-service/llm/context-v2/compaction/client-side.js +77 -4
  94. package/dist/ai-service/llm/context-v2/compaction/client-side.js.map +1 -1
  95. package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.d.ts +5 -0
  96. package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.d.ts.map +1 -1
  97. package/dist/ai-service/llm/context-v2/compaction/server-side.d.ts +1 -0
  98. package/dist/ai-service/llm/context-v2/compaction/server-side.d.ts.map +1 -1
  99. package/dist/ai-service/llm/context-v2/compaction/server-side.js +3 -0
  100. package/dist/ai-service/llm/context-v2/compaction/server-side.js.map +1 -1
  101. package/dist/ai-service/llm/context-v2/compactor.d.ts.map +1 -1
  102. package/dist/ai-service/llm/context-v2/compactor.js +57 -6
  103. package/dist/ai-service/llm/context-v2/compactor.js.map +1 -1
  104. package/dist/ai-service/llm/context-v2/config.d.ts +13 -1
  105. package/dist/ai-service/llm/context-v2/config.d.ts.map +1 -1
  106. package/dist/ai-service/llm/context-v2/config.js +39 -2
  107. package/dist/ai-service/llm/context-v2/config.js.map +1 -1
  108. package/dist/ai-service/llm/context-v2/context-metrics.d.ts +23 -0
  109. package/dist/ai-service/llm/context-v2/context-metrics.d.ts.map +1 -1
  110. package/dist/ai-service/llm/context-v2/context-metrics.js +52 -1
  111. package/dist/ai-service/llm/context-v2/context-metrics.js.map +1 -1
  112. package/dist/ai-service/llm/context-v2/context.d.ts +27 -3
  113. package/dist/ai-service/llm/context-v2/context.d.ts.map +1 -1
  114. package/dist/ai-service/llm/context-v2/context.js +107 -10
  115. package/dist/ai-service/llm/context-v2/context.js.map +1 -1
  116. package/dist/ai-service/llm/context-v2/manager.d.ts +66 -0
  117. package/dist/ai-service/llm/context-v2/manager.d.ts.map +1 -1
  118. package/dist/ai-service/llm/context-v2/manager.js +194 -2
  119. package/dist/ai-service/llm/context-v2/manager.js.map +1 -1
  120. package/dist/ai-service/llm/context-v2/storage/event-store.d.ts +31 -5
  121. package/dist/ai-service/llm/context-v2/storage/event-store.d.ts.map +1 -1
  122. package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts +30 -9
  123. package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts.map +1 -1
  124. package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js +96 -13
  125. package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js.map +1 -1
  126. package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.d.ts +46 -0
  127. package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.d.ts.map +1 -0
  128. package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.js +240 -0
  129. package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.js.map +1 -0
  130. package/dist/ai-service/llm/context-v2/storage/local.d.ts +1 -1
  131. package/dist/ai-service/llm/context-v2/storage/local.d.ts.map +1 -1
  132. package/dist/ai-service/llm/context-v2/storage/local.js +3 -2
  133. package/dist/ai-service/llm/context-v2/storage/local.js.map +1 -1
  134. package/dist/ai-service/llm/context-v2/types.d.ts +5 -1
  135. package/dist/ai-service/llm/context-v2/types.d.ts.map +1 -1
  136. package/dist/ai-service/llm/context-v2/types.js.map +1 -1
  137. package/dist/ai-service/llm/stream/config.d.ts +4 -3
  138. package/dist/ai-service/llm/stream/config.d.ts.map +1 -1
  139. package/dist/ai-service/llm/stream/config.js.map +1 -1
  140. package/dist/ai-service/llm/stream/idle-monitor.d.ts +37 -4
  141. package/dist/ai-service/llm/stream/idle-monitor.d.ts.map +1 -1
  142. package/dist/ai-service/llm/stream/idle-monitor.js +38 -3
  143. package/dist/ai-service/llm/stream/idle-monitor.js.map +1 -1
  144. package/dist/ai-service/policy-agent-metrics.d.ts +18 -0
  145. package/dist/ai-service/policy-agent-metrics.d.ts.map +1 -0
  146. package/dist/ai-service/policy-agent-metrics.js +99 -0
  147. package/dist/ai-service/policy-agent-metrics.js.map +1 -0
  148. package/dist/ai-service/state-machine/clark-fsm.d.ts +9 -0
  149. package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
  150. package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts +9 -0
  151. package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts.map +1 -1
  152. package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js +27 -0
  153. package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js.map +1 -1
  154. package/dist/ai-service/tasks/factory.d.ts +7 -0
  155. package/dist/ai-service/tasks/factory.d.ts.map +1 -1
  156. package/dist/ai-service/tasks/factory.js +5 -0
  157. package/dist/ai-service/tasks/factory.js.map +1 -1
  158. package/dist/ai-service/tasks/task-store.d.ts +11 -1
  159. package/dist/ai-service/tasks/task-store.d.ts.map +1 -1
  160. package/dist/ai-service/tasks/task-store.js +104 -29
  161. package/dist/ai-service/tasks/task-store.js.map +1 -1
  162. package/dist/ai-service/tasks/types.d.ts +9 -1
  163. package/dist/ai-service/tasks/types.d.ts.map +1 -1
  164. package/dist/extract-api-integrations.d.ts +76 -0
  165. package/dist/extract-api-integrations.d.ts.map +1 -1
  166. package/dist/extract-api-integrations.js +428 -109
  167. package/dist/extract-api-integrations.js.map +1 -1
  168. package/dist/file-sync-vite-plugin.d.ts +1 -1
  169. package/dist/file-sync-vite-plugin.d.ts.map +1 -1
  170. package/dist/file-sync-vite-plugin.js +42 -79
  171. package/dist/file-sync-vite-plugin.js.map +1 -1
  172. package/dist/file-system-helpers.d.ts +1 -1
  173. package/dist/file-system-helpers.d.ts.map +1 -1
  174. package/dist/file-system-helpers.js +1 -0
  175. package/dist/file-system-helpers.js.map +1 -1
  176. package/dist/git-auth-state.d.ts +4 -0
  177. package/dist/git-auth-state.d.ts.map +1 -0
  178. package/dist/git-auth-state.js +25 -0
  179. package/dist/git-auth-state.js.map +1 -0
  180. package/dist/git-service/checkpoint-commit-metrics.d.ts +2 -0
  181. package/dist/git-service/checkpoint-commit-metrics.d.ts.map +1 -0
  182. package/dist/git-service/checkpoint-commit-metrics.js +15 -0
  183. package/dist/git-service/checkpoint-commit-metrics.js.map +1 -0
  184. package/dist/git-service/checkpoint-committer.d.ts +22 -0
  185. package/dist/git-service/checkpoint-committer.d.ts.map +1 -0
  186. package/dist/git-service/checkpoint-committer.js +91 -0
  187. package/dist/git-service/checkpoint-committer.js.map +1 -0
  188. package/dist/git-service/commit-live-branch.d.ts +17 -0
  189. package/dist/git-service/commit-live-branch.d.ts.map +1 -0
  190. package/dist/git-service/commit-live-branch.js +28 -0
  191. package/dist/git-service/commit-live-branch.js.map +1 -0
  192. package/dist/git-service/provider-workflow-files.d.ts +12 -0
  193. package/dist/git-service/provider-workflow-files.d.ts.map +1 -0
  194. package/dist/git-service/provider-workflow-files.js +36 -0
  195. package/dist/git-service/provider-workflow-files.js.map +1 -0
  196. package/dist/plugin-options.d.ts +8 -0
  197. package/dist/plugin-options.d.ts.map +1 -1
  198. package/dist/plugin-options.js.map +1 -1
  199. package/dist/policy-gate-runner.d.ts.map +1 -1
  200. package/dist/policy-gate-runner.js +7 -9
  201. package/dist/policy-gate-runner.js.map +1 -1
  202. package/dist/server-rpc/client.d.ts.map +1 -1
  203. package/dist/server-rpc/client.js +2 -0
  204. package/dist/server-rpc/client.js.map +1 -1
  205. package/dist/server-rpc/index.d.ts +43 -1
  206. package/dist/server-rpc/index.d.ts.map +1 -1
  207. package/dist/server-rpc/index.js +143 -5
  208. package/dist/server-rpc/index.js.map +1 -1
  209. package/dist/server-rpc/request-abort-context.d.ts +3 -0
  210. package/dist/server-rpc/request-abort-context.d.ts.map +1 -0
  211. package/dist/server-rpc/request-abort-context.js +23 -0
  212. package/dist/server-rpc/request-abort-context.js.map +1 -0
  213. package/dist/server-rpc/rpc-invalidate-metrics.d.ts +20 -0
  214. package/dist/server-rpc/rpc-invalidate-metrics.d.ts.map +1 -0
  215. package/dist/server-rpc/rpc-invalidate-metrics.js +86 -0
  216. package/dist/server-rpc/rpc-invalidate-metrics.js.map +1 -0
  217. package/dist/socket-manager.d.ts.map +1 -1
  218. package/dist/socket-manager.js +21 -60
  219. package/dist/socket-manager.js.map +1 -1
  220. package/dist/sync-service/index.d.ts +26 -2
  221. package/dist/sync-service/index.d.ts.map +1 -1
  222. package/dist/sync-service/index.js +74 -37
  223. package/dist/sync-service/index.js.map +1 -1
  224. package/package.json +9 -8
@@ -1,3 +1,4 @@
1
+ import { posix as posixPath } from "node:path";
1
2
  import { parse } from "@babel/parser";
2
3
  function isNode(value) {
3
4
  return !!value && typeof value === "object";
@@ -15,18 +16,19 @@ function getPropertyName(node) {
15
16
  return undefined;
16
17
  }
17
18
  function getLiteralString(node) {
18
- if (!isNode(node)) {
19
+ const resolved = unwrapExpression(node);
20
+ if (!resolved) {
19
21
  return undefined;
20
22
  }
21
- if (node.type === "StringLiteral" && typeof node.value === "string") {
22
- return node.value;
23
+ if (resolved.type === "StringLiteral" && typeof resolved.value === "string") {
24
+ return resolved.value;
23
25
  }
24
- if (node.type === "TemplateLiteral" &&
25
- Array.isArray(node.expressions) &&
26
- node.expressions.length === 0 &&
27
- Array.isArray(node.quasis) &&
28
- node.quasis.length === 1) {
29
- const quasi = node.quasis[0];
26
+ if (resolved.type === "TemplateLiteral" &&
27
+ Array.isArray(resolved.expressions) &&
28
+ resolved.expressions.length === 0 &&
29
+ Array.isArray(resolved.quasis) &&
30
+ resolved.quasis.length === 1) {
31
+ const quasi = resolved.quasis[0];
30
32
  if (isNode(quasi) &&
31
33
  isNode(quasi.value) &&
32
34
  typeof quasi.value.cooked === "string") {
@@ -58,27 +60,44 @@ function unwrapExpression(node) {
58
60
  }
59
61
  return node;
60
62
  }
61
- function buildVariableInitializerMap(programBody) {
62
- const initializers = new Map();
63
+ /**
64
+ * Walks top-level variable declarations in a program body, calling `visitor`
65
+ * for each individual declarator. Unwraps `export const x = ...`
66
+ * (`ExportNamedDeclaration` whose `.declaration` is a `VariableDeclaration`)
67
+ * to its inner `VariableDeclaration` so exported declarations are visited
68
+ * the same as bare ones.
69
+ */
70
+ function visitVariableDeclarations(programBody, visitor) {
63
71
  for (const statement of programBody) {
64
- if (!isNode(statement) ||
65
- statement.type !== "VariableDeclaration" ||
66
- !Array.isArray(statement.declarations)) {
72
+ if (!isNode(statement)) {
67
73
  continue;
68
74
  }
69
- for (const declaration of statement.declarations) {
70
- if (!isNode(declaration)) {
71
- continue;
72
- }
73
- const identifier = declaration.id;
74
- if (!isNode(identifier) ||
75
- identifier.type !== "Identifier" ||
76
- typeof identifier.name !== "string") {
77
- continue;
75
+ const declarationNode = statement.type === "ExportNamedDeclaration" &&
76
+ isNode(statement.declaration)
77
+ ? statement.declaration
78
+ : statement;
79
+ if (declarationNode.type !== "VariableDeclaration" ||
80
+ !Array.isArray(declarationNode.declarations)) {
81
+ continue;
82
+ }
83
+ for (const declaration of declarationNode.declarations) {
84
+ if (isNode(declaration)) {
85
+ visitor(declaration);
78
86
  }
79
- initializers.set(identifier.name, declaration.init);
80
87
  }
81
88
  }
89
+ }
90
+ function buildVariableInitializerMap(programBody) {
91
+ const initializers = new Map();
92
+ visitVariableDeclarations(programBody, (declaration) => {
93
+ const identifier = declaration.id;
94
+ if (!isNode(identifier) ||
95
+ identifier.type !== "Identifier" ||
96
+ typeof identifier.name !== "string") {
97
+ return;
98
+ }
99
+ initializers.set(identifier.name, declaration.init);
100
+ });
82
101
  return initializers;
83
102
  }
84
103
  function resolveApiConfigObject(expression, variableInitializers) {
@@ -126,62 +145,42 @@ function findExportedApiConfigObject(programBody) {
126
145
  }
127
146
  function buildVariableReferenceMap(programBody, stringLiterals) {
128
147
  const refs = new Map();
129
- for (const statement of programBody) {
130
- if (!isNode(statement) ||
131
- statement.type !== "VariableDeclaration" ||
132
- !Array.isArray(statement.declarations)) {
133
- continue;
148
+ visitVariableDeclarations(programBody, (declaration) => {
149
+ const identifier = declaration.id;
150
+ const init = declaration.init;
151
+ if (!isNode(identifier) ||
152
+ identifier.type !== "Identifier" ||
153
+ typeof identifier.name !== "string") {
154
+ return;
134
155
  }
135
- for (const declaration of statement.declarations) {
136
- if (!isNode(declaration)) {
137
- continue;
138
- }
139
- const identifier = declaration.id;
140
- const init = declaration.init;
141
- if (!isNode(identifier) ||
142
- identifier.type !== "Identifier" ||
143
- typeof identifier.name !== "string") {
144
- continue;
145
- }
146
- if (!isNode(init) ||
147
- init.type !== "CallExpression" ||
148
- !Array.isArray(init.arguments)) {
149
- continue;
150
- }
151
- const pluginId = getCalleeName(init.callee);
152
- const id = resolveStringArgument(init.arguments[0], stringLiterals);
153
- if (!pluginId || !id) {
154
- continue;
155
- }
156
- refs.set(identifier.name, { pluginId, id });
156
+ if (!isNode(init) ||
157
+ init.type !== "CallExpression" ||
158
+ !Array.isArray(init.arguments)) {
159
+ return;
157
160
  }
158
- }
161
+ const pluginId = getCalleeName(init.callee);
162
+ const id = resolveStringArgument(init.arguments[0], stringLiterals);
163
+ if (!pluginId || !id) {
164
+ return;
165
+ }
166
+ refs.set(identifier.name, { pluginId, id });
167
+ });
159
168
  return refs;
160
169
  }
161
170
  function buildStringLiteralMap(programBody) {
162
171
  const literals = new Map();
163
- for (const statement of programBody) {
164
- if (!isNode(statement) ||
165
- statement.type !== "VariableDeclaration" ||
166
- !Array.isArray(statement.declarations)) {
167
- continue;
172
+ visitVariableDeclarations(programBody, (declaration) => {
173
+ const identifier = declaration.id;
174
+ if (!isNode(identifier) ||
175
+ identifier.type !== "Identifier" ||
176
+ typeof identifier.name !== "string") {
177
+ return;
168
178
  }
169
- for (const declaration of statement.declarations) {
170
- if (!isNode(declaration)) {
171
- continue;
172
- }
173
- const identifier = declaration.id;
174
- if (!isNode(identifier) ||
175
- identifier.type !== "Identifier" ||
176
- typeof identifier.name !== "string") {
177
- continue;
178
- }
179
- const value = getLiteralString(declaration.init);
180
- if (value !== undefined) {
181
- literals.set(identifier.name, value);
182
- }
179
+ const value = getLiteralString(declaration.init);
180
+ if (value !== undefined) {
181
+ literals.set(identifier.name, value);
183
182
  }
184
- }
183
+ });
185
184
  return literals;
186
185
  }
187
186
  function resolveStringArgument(node, stringLiterals) {
@@ -196,68 +195,82 @@ function resolveStringArgument(node, stringLiterals) {
196
195
  }
197
196
  return undefined;
198
197
  }
199
- /**
200
- * Extract integration declarations from an SDK API source file.
201
- *
202
- * Anchors on the exported `api({ ... })` config object and extracts
203
- * integrations from its `integrations` property.
204
- *
205
- * Supports inline declarations:
206
- * `integrations: { db: postgres("uuid") }`
207
- *
208
- * Top-level variable references:
209
- * `const DB = postgres("uuid"); integrations: { db: DB }`
210
- *
211
- * And string variable indirection:
212
- * `const ID = "uuid"; integrations: { db: postgres(ID) }`
213
- */
214
- export function extractIntegrationsFromSource(source) {
215
- let ast;
216
- try {
217
- ast = parse(source, {
218
- sourceType: "module",
219
- plugins: ["typescript"],
220
- });
221
- }
222
- catch {
223
- return [];
198
+ function extractFromProgram(programBody, importedRefs) {
199
+ const stringLiterals = buildStringLiteralMap(programBody);
200
+ // Seed with imported id constants (e.g. `import { SHEETS_ID } from
201
+ // "../lib/constants.js"`) so a same-file declaration like
202
+ // `const sheets = restApiIntegration(SHEETS_ID)` can resolve them. Only
203
+ // fill in names the same-file scan didn't already find, so a same-file
204
+ // literal always wins over an imported one of the same name. In practice
205
+ // this `!stringLiterals.has(name)` check is defensive and unreachable for
206
+ // valid input: a same-file `const X` and an `import { X }` of the same
207
+ // name is a duplicate lexical binding, which is a parse/type error in
208
+ // real TS/ESM and can't occur in a file that actually compiles.
209
+ for (const [name, ref] of importedRefs) {
210
+ if (ref.kind === "id" && !stringLiterals.has(name)) {
211
+ stringLiterals.set(name, ref.id);
212
+ }
224
213
  }
225
- const stringLiterals = buildStringLiteralMap(ast.program.body);
226
- const variableRefs = buildVariableReferenceMap(ast.program.body, stringLiterals);
227
- const apiConfig = findExportedApiConfigObject(ast.program.body);
214
+ const variableRefs = buildVariableReferenceMap(programBody, stringLiterals);
215
+ const apiConfig = findExportedApiConfigObject(programBody);
228
216
  if (!apiConfig) {
229
- return [];
217
+ return { integrations: [], unresolvedKeys: [] };
230
218
  }
231
- const results = [];
219
+ const integrations = [];
220
+ const unresolvedKeys = [];
232
221
  const apiConfigProperties = Array.isArray(apiConfig.properties)
233
222
  ? apiConfig.properties
234
223
  : [];
235
224
  const integrationsProperty = apiConfigProperties.find((property) => isNode(property) &&
236
225
  property.type === "ObjectProperty" &&
237
226
  getPropertyName(property.key) === "integrations");
238
- if (!isNode(integrationsProperty) ||
239
- !isNode(integrationsProperty.value) ||
227
+ if (!isNode(integrationsProperty)) {
228
+ return { integrations: [], unresolvedKeys: [] };
229
+ }
230
+ if (!isNode(integrationsProperty.value) ||
240
231
  integrationsProperty.value.type !== "ObjectExpression") {
241
- return [];
232
+ // The `integrations` property exists but its value isn't a statically
233
+ // analyzable object literal (e.g. `api({ integrations })` shorthand, or
234
+ // `api({ integrations: sharedObject })`). "*" is a sentinel meaning the
235
+ // whole integrations object could not be resolved, as opposed to one
236
+ // specific key.
237
+ return { integrations: [], unresolvedKeys: ["*"] };
242
238
  }
243
239
  const properties = Array.isArray(integrationsProperty.value.properties)
244
240
  ? integrationsProperty.value.properties
245
241
  : [];
246
242
  for (const property of properties) {
247
243
  if (!isNode(property) || property.type !== "ObjectProperty") {
244
+ // Not a key/value property at all (e.g. a spread element or a method),
245
+ // so there is no key to report as unresolved.
246
+ unresolvedKeys.push("(dynamic)");
248
247
  continue;
249
248
  }
250
249
  const key = getPropertyName(property.key);
251
250
  if (!key) {
251
+ unresolvedKeys.push("(unknown)");
252
252
  continue;
253
253
  }
254
254
  if (isNode(property.value) &&
255
255
  property.value.type === "CallExpression" &&
256
256
  Array.isArray(property.value.arguments)) {
257
257
  const pluginId = getCalleeName(property.value.callee);
258
- const id = resolveStringArgument(property.value.arguments[0], stringLiterals);
258
+ const arg = property.value.arguments[0];
259
+ let id = resolveStringArgument(arg, stringLiterals);
260
+ if (!id &&
261
+ isNode(arg) &&
262
+ arg.type === "Identifier" &&
263
+ typeof arg.name === "string") {
264
+ const imported = importedRefs.get(arg.name);
265
+ if (imported?.kind === "id") {
266
+ id = imported.id;
267
+ }
268
+ }
259
269
  if (pluginId && id) {
260
- results.push({ key, pluginId, id });
270
+ integrations.push({ key, pluginId, id });
271
+ }
272
+ else {
273
+ unresolvedKeys.push(key);
261
274
  }
262
275
  continue;
263
276
  }
@@ -266,13 +279,319 @@ export function extractIntegrationsFromSource(source) {
266
279
  typeof property.value.name === "string") {
267
280
  const resolved = variableRefs.get(property.value.name);
268
281
  if (resolved) {
269
- results.push({ key, ...resolved });
282
+ integrations.push({ key, ...resolved });
283
+ continue;
270
284
  }
285
+ const imported = importedRefs.get(property.value.name);
286
+ if (imported?.kind === "declaration") {
287
+ integrations.push({
288
+ key,
289
+ pluginId: imported.pluginId,
290
+ id: imported.id,
291
+ });
292
+ continue;
293
+ }
294
+ unresolvedKeys.push(key);
295
+ continue;
271
296
  }
297
+ unresolvedKeys.push(key);
298
+ }
299
+ return { integrations, unresolvedKeys };
300
+ }
301
+ /**
302
+ * Extract integration declarations from an SDK API source file.
303
+ *
304
+ * Anchors on the exported `api({ ... })` config object and extracts
305
+ * integrations from its `integrations` property.
306
+ *
307
+ * Supports inline declarations:
308
+ * `integrations: { db: postgres("uuid") }`
309
+ *
310
+ * Top-level variable references:
311
+ * `const DB = postgres("uuid"); integrations: { db: DB }`
312
+ *
313
+ * And string variable indirection:
314
+ * `const ID = "uuid"; integrations: { db: postgres(ID) }`
315
+ *
316
+ * Also resolves top-level `export const` declarations and `as const`
317
+ * literals in the same file (e.g. `export const ID = "uuid" as const;`) —
318
+ * a deliberate, additive improvement over the previous bare-declaration-only
319
+ * behavior. This is still single-file scope: only same-file declarations
320
+ * (exported or not) are considered, imports are never followed.
321
+ *
322
+ * Single-file only: does not follow imports, so an integration declared via
323
+ * an imported constant or an imported `integrations` object cannot be
324
+ * resolved here — it is silently dropped (its key is simply absent from the
325
+ * returned array, with no signal that it was seen but unresolved). Callers
326
+ * that need imported declarations resolved, or that need to know about
327
+ * unresolved keys instead of silently losing them, must use
328
+ * {@link extractApiIntegrations} instead.
329
+ */
330
+ export function extractIntegrationsFromSource(source) {
331
+ let ast;
332
+ try {
333
+ ast = parse(source, {
334
+ sourceType: "module",
335
+ plugins: ["typescript"],
336
+ });
337
+ }
338
+ catch {
339
+ return [];
272
340
  }
273
- return results;
341
+ return extractFromProgram(ast.program.body, new Map()).integrations;
274
342
  }
343
+ /**
344
+ * Single-file only: does not follow imports, so an integration declared via
345
+ * an imported constant or an imported `integrations` object cannot be
346
+ * resolved here — it is silently dropped (its `id` is simply absent from the
347
+ * returned array, with no signal that it was seen but unresolved). Callers
348
+ * that need imported declarations resolved, or that need to know about
349
+ * unresolved keys instead of silently losing them, must use
350
+ * {@link extractApiIntegrations} instead.
351
+ */
275
352
  export function extractIntegrationIdsFromSource(source) {
276
353
  return extractIntegrationsFromSource(source).map((integration) => integration.id);
277
354
  }
355
+ /**
356
+ * Async variant of {@link extractIntegrationsFromSource} that also resolves
357
+ * integrations declared via imports from other files, and reports which
358
+ * `integrations` object keys could not be resolved to a complete
359
+ * `{ key, pluginId, id }` triple.
360
+ *
361
+ * Import resolution supports one-hop relative imports (e.g., `../lib/integrations.js`).
362
+ * For each imported name, resolves it in the imported module via:
363
+ * 1. Imported string-literal constants: `export const SHEETS_ID = "sheets-uuid"`
364
+ * (including `as const`/type-assertion wrapping and re-exports via
365
+ * `export { name }` specifiers).
366
+ * 2. Imported integration declarations: `export const jira = restApiIntegration("jira-uuid")`
367
+ * including string-literal indirection within the imported module, and
368
+ * the same `export { name }` specifier form.
369
+ *
370
+ * Non-relative imports (package imports) are not followed.
371
+ *
372
+ * `params.entryPoint` MUST be an app-root-relative posix path (e.g.
373
+ * `server/apis/get-rows.ts`), never an absolute path or one containing a
374
+ * backslash — an entry point that violates this contract skips import
375
+ * resolution entirely (see the guard at the top of
376
+ * `buildImportedIntegrationRefs`). Within that contract, resolved relative
377
+ * import candidates that would escape the app root (e.g. `../../../secrets.ts`)
378
+ * are skipped without reading them, but that `..`-prefix skip is only a
379
+ * best-effort guard against traversal *relative to entryPoint's own
380
+ * directory* — it is not a substitute for real containment enforcement.
381
+ * Authoritative containment against the actual filesystem root lives in the
382
+ * caller's `readSource` implementation (see `resolveContainedPath` in
383
+ * `collect-sdk-apis.mts`), which re-resolves every candidate against the app
384
+ * root before touching disk.
385
+ *
386
+ * `unresolvedKeys` entries are one of:
387
+ * - a specific `integrations` object key that could not be resolved
388
+ * - `"(unknown)"` for an `ObjectProperty` whose key itself couldn't be read
389
+ * (e.g. a computed key)
390
+ * - `"(dynamic)"` for a non-`ObjectProperty` member of the integrations
391
+ * object (spread elements, methods)
392
+ * - `"*"` as a sentinel meaning the whole `integrations` value could not be
393
+ * statically resolved at all (e.g. `api({ integrations })` shorthand, or
394
+ * `api({ integrations: sharedObject })` referencing a non-literal value,
395
+ * or the entry file itself failing to parse) — in this case `integrations`
396
+ * is always `[]`.
397
+ */
398
+ export async function extractApiIntegrations(params) {
399
+ let ast;
400
+ try {
401
+ ast = parse(params.source, {
402
+ sourceType: "module",
403
+ plugins: ["typescript"],
404
+ });
405
+ }
406
+ catch {
407
+ // The entry file itself failed to parse (e.g. parser-config drift: a
408
+ // real build compiles syntax our @babel/parser config rejects, such as
409
+ // decorators or import attributes). Report the "*" sentinel instead of
410
+ // silently returning an empty result — this is maximal uncertainty
411
+ // about the whole integrations surface, exactly what "*" means below.
412
+ return { integrations: [], unresolvedKeys: ["*"] };
413
+ }
414
+ const importedRefs = await buildImportedIntegrationRefs(ast.program.body, params.entryPoint, params.readSource);
415
+ return extractFromProgram(ast.program.body, importedRefs);
416
+ }
417
+ const TS_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts"];
418
+ const JS_TO_TS_EXTENSIONS = {
419
+ ".js": [".ts", ".tsx"],
420
+ ".jsx": [".tsx"],
421
+ ".mjs": [".mts", ".ts"],
422
+ ".cjs": [".cts", ".ts"],
423
+ };
424
+ export function resolveRelativeImportPath(fromPath, importPath) {
425
+ const resolved = posixPath.join(posixPath.dirname(fromPath), importPath);
426
+ const currentExt = posixPath.extname(resolved);
427
+ if (TS_EXTENSIONS.includes(currentExt)) {
428
+ return [resolved];
429
+ }
430
+ const tsReplacements = JS_TO_TS_EXTENSIONS[currentExt];
431
+ if (tsReplacements) {
432
+ const stem = resolved.slice(0, -currentExt.length);
433
+ return tsReplacements.map((ext) => stem + ext);
434
+ }
435
+ return TS_EXTENSIONS.map((ext) => resolved + ext);
436
+ }
437
+ async function readAndParseFirstExisting(candidatePaths, readSource, cache) {
438
+ for (const candidate of candidatePaths) {
439
+ if (!cache.has(candidate)) {
440
+ let body;
441
+ try {
442
+ const source = await readSource(candidate);
443
+ if (source !== undefined) {
444
+ body = parse(source, {
445
+ sourceType: "module",
446
+ plugins: ["typescript"],
447
+ }).program.body;
448
+ }
449
+ }
450
+ catch {
451
+ body = undefined;
452
+ }
453
+ cache.set(candidate, body);
454
+ }
455
+ const cached = cache.get(candidate);
456
+ if (cached) {
457
+ return cached;
458
+ }
459
+ }
460
+ return undefined;
461
+ }
462
+ function buildExportedIntegrationRefMap(programBody) {
463
+ const refs = new Map();
464
+ const stringLiterals = buildStringLiteralMap(programBody);
465
+ // Resolves specifier-based exports (`const jira = ...; export { jira };`)
466
+ // against the module's bare top-level variable declarations.
467
+ const variableRefs = buildVariableReferenceMap(programBody, stringLiterals);
468
+ // Resolve `export const x = ...` declarations directly. Filtering to only
469
+ // `ExportNamedDeclaration` statements before delegating to the shared
470
+ // walker means bare (non-exported) top-level consts are correctly excluded
471
+ // here, even though they're visible for same-file indirection above.
472
+ const exportedDeclarationStatements = programBody.filter((statement) => isNode(statement) && statement.type === "ExportNamedDeclaration");
473
+ visitVariableDeclarations(exportedDeclarationStatements, (declaration) => {
474
+ const identifier = declaration.id;
475
+ if (!isNode(identifier) ||
476
+ identifier.type !== "Identifier" ||
477
+ typeof identifier.name !== "string") {
478
+ return;
479
+ }
480
+ const literal = getLiteralString(declaration.init);
481
+ if (literal !== undefined) {
482
+ refs.set(identifier.name, { kind: "id", id: literal });
483
+ return;
484
+ }
485
+ const init = declaration.init;
486
+ if (isNode(init) &&
487
+ init.type === "CallExpression" &&
488
+ Array.isArray(init.arguments)) {
489
+ const pluginId = getCalleeName(init.callee);
490
+ const id = resolveStringArgument(init.arguments[0], stringLiterals);
491
+ if (pluginId && id) {
492
+ refs.set(identifier.name, { kind: "declaration", pluginId, id });
493
+ }
494
+ }
495
+ });
496
+ for (const statement of programBody) {
497
+ if (!isNode(statement) || statement.type !== "ExportNamedDeclaration") {
498
+ continue;
499
+ }
500
+ if (!Array.isArray(statement.specifiers)) {
501
+ continue;
502
+ }
503
+ for (const specifier of statement.specifiers) {
504
+ if (!isNode(specifier) || specifier.type !== "ExportSpecifier") {
505
+ continue;
506
+ }
507
+ const localName = getPropertyName(specifier.local);
508
+ const exportedName = getPropertyName(specifier.exported);
509
+ if (!localName || !exportedName) {
510
+ continue;
511
+ }
512
+ const literal = stringLiterals.get(localName);
513
+ if (literal !== undefined) {
514
+ refs.set(exportedName, { kind: "id", id: literal });
515
+ continue;
516
+ }
517
+ const varRef = variableRefs.get(localName);
518
+ if (varRef) {
519
+ refs.set(exportedName, {
520
+ kind: "declaration",
521
+ pluginId: varRef.pluginId,
522
+ id: varRef.id,
523
+ });
524
+ }
525
+ }
526
+ }
527
+ return refs;
528
+ }
529
+ async function buildImportedIntegrationRefs(programBody, entryPoint, readSource) {
530
+ const refs = new Map();
531
+ // entryPoint is contractually an app-root-relative posix path (see the
532
+ // JSDoc on extractApiIntegrations). An absolute path or one containing a
533
+ // backslash is out-of-contract input: resolveRelativeImportPath's
534
+ // `..`-prefix skip only guards against traversal relative to entryPoint's
535
+ // own directory, so a malformed entryPoint (e.g. an absolute path) could
536
+ // still let a resolved candidate land outside the app root even though it
537
+ // doesn't start with "..". Refuse to resolve any imports at all for such
538
+ // input rather than rely on that guard holding — callers that violate the
539
+ // contract get unresolved keys instead of a potential traversal.
540
+ if (entryPoint.startsWith("/") || entryPoint.includes("\\")) {
541
+ return refs;
542
+ }
543
+ // Deliberately scoped to this call (one per entry point), not shared/module
544
+ // -level: each call to extractApiIntegrations gets its own cache, so
545
+ // repeated imports of the same relative path within a single entry point's
546
+ // import graph are only read and parsed once, without leaking parsed
547
+ // bodies across unrelated entry points or app roots.
548
+ const parsedImportCache = new Map();
549
+ for (const statement of programBody) {
550
+ if (!isNode(statement) || statement.type !== "ImportDeclaration") {
551
+ continue;
552
+ }
553
+ const importSource = statement.source;
554
+ const importPath = isNode(importSource) ? importSource.value : undefined;
555
+ if (typeof importPath !== "string" ||
556
+ !importPath.startsWith(".") ||
557
+ !Array.isArray(statement.specifiers)) {
558
+ continue;
559
+ }
560
+ // Real ESM/TS import specifiers always use forward slashes, and no
561
+ // bundler resolves a backslash as a path separator either — a backslash
562
+ // here only ever comes from hostile or broken input (e.g.
563
+ // `..\\..\\..\\secret.js`). `posixPath.join` treats `\` as an ordinary
564
+ // filename character rather than a separator, so the `..`-prefix guard
565
+ // below cannot catch a traversal spelled with backslashes. Treat the
566
+ // specifier as unresolvable, the same as a bare package import, and
567
+ // never attempt to read it.
568
+ if (importPath.includes("\\")) {
569
+ continue;
570
+ }
571
+ // Skip candidates that resolve outside the app root (e.g.
572
+ // `../../../secrets.ts` escaping above the entry point's directory) —
573
+ // never read files outside the app being built.
574
+ const candidatePaths = resolveRelativeImportPath(entryPoint, importPath).filter((candidate) => !candidate.startsWith(".."));
575
+ if (candidatePaths.length === 0) {
576
+ continue;
577
+ }
578
+ const importedBody = await readAndParseFirstExisting(candidatePaths, readSource, parsedImportCache);
579
+ if (!importedBody) {
580
+ continue;
581
+ }
582
+ const exportedRefs = buildExportedIntegrationRefMap(importedBody);
583
+ for (const specifier of statement.specifiers) {
584
+ if (!isNode(specifier) || specifier.type !== "ImportSpecifier") {
585
+ continue;
586
+ }
587
+ const importedName = getPropertyName(specifier.imported);
588
+ const localName = getPropertyName(specifier.local);
589
+ const ref = importedName ? exportedRefs.get(importedName) : undefined;
590
+ if (localName && ref) {
591
+ refs.set(localName, ref);
592
+ }
593
+ }
594
+ }
595
+ return refs;
596
+ }
278
597
  //# sourceMappingURL=extract-api-integrations.js.map