alpic 0.0.0-dev.gee3e167 → 0.0.0-dev.gee425da

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 (263) hide show
  1. package/README.md +18 -0
  2. package/bin/dev.js +0 -0
  3. package/bin/run.js +15 -1
  4. package/dist/__tests__/alpic-command.test.js +8 -4
  5. package/dist/__tests__/alpic-command.test.js.map +1 -1
  6. package/dist/__tests__/audit.e2e.test.js +17 -30
  7. package/dist/__tests__/audit.e2e.test.js.map +1 -1
  8. package/dist/__tests__/auth.e2e.test.js +9 -23
  9. package/dist/__tests__/auth.e2e.test.js.map +1 -1
  10. package/dist/__tests__/deploy-flags.e2e.test.js +6 -21
  11. package/dist/__tests__/deploy-flags.e2e.test.js.map +1 -1
  12. package/dist/__tests__/deploy.e2e.test.js +5 -21
  13. package/dist/__tests__/deploy.e2e.test.js.map +1 -1
  14. package/dist/__tests__/deployment-inspect.e2e.test.js +18 -31
  15. package/dist/__tests__/deployment-inspect.e2e.test.js.map +1 -1
  16. package/dist/__tests__/deployment-list.e2e.test.js +18 -31
  17. package/dist/__tests__/deployment-list.e2e.test.js.map +1 -1
  18. package/dist/__tests__/deployment-logs.e2e.test.js +15 -29
  19. package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -1
  20. package/dist/__tests__/environment-delete.e2e.test.d.ts +1 -0
  21. package/dist/__tests__/environment-delete.e2e.test.js +95 -0
  22. package/dist/__tests__/environment-delete.e2e.test.js.map +1 -0
  23. package/dist/__tests__/environment-list.e2e.test.js +6 -22
  24. package/dist/__tests__/environment-list.e2e.test.js.map +1 -1
  25. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js +19 -31
  26. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js.map +1 -1
  27. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js +19 -31
  28. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js.map +1 -1
  29. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js +18 -31
  30. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js.map +1 -1
  31. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js +18 -31
  32. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js.map +1 -1
  33. package/dist/__tests__/git-flags.e2e.test.js +6 -22
  34. package/dist/__tests__/git-flags.e2e.test.js.map +1 -1
  35. package/dist/__tests__/git.e2e.test.js +7 -22
  36. package/dist/__tests__/git.e2e.test.js.map +1 -1
  37. package/dist/__tests__/insights-category.e2e.test.d.ts +1 -0
  38. package/dist/__tests__/insights-category.e2e.test.js +247 -0
  39. package/dist/__tests__/insights-category.e2e.test.js.map +1 -0
  40. package/dist/__tests__/insights.e2e.test.d.ts +1 -0
  41. package/dist/__tests__/insights.e2e.test.js +193 -0
  42. package/dist/__tests__/insights.e2e.test.js.map +1 -0
  43. package/dist/__tests__/logs.e2e.test.js +21 -35
  44. package/dist/__tests__/logs.e2e.test.js.map +1 -1
  45. package/dist/__tests__/mock-api.d.ts +28 -1
  46. package/dist/__tests__/mock-api.js +385 -41
  47. package/dist/__tests__/mock-api.js.map +1 -1
  48. package/dist/__tests__/playground/playground-configure.e2e.test.js +18 -26
  49. package/dist/__tests__/playground/playground-configure.e2e.test.js.map +1 -1
  50. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js +18 -26
  51. package/dist/__tests__/playground/playground-enable-disable.e2e.test.js.map +1 -1
  52. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js +18 -26
  53. package/dist/__tests__/playground/playground-example-prompt.e2e.test.js.map +1 -1
  54. package/dist/__tests__/playground/playground-headers.e2e.test.js +18 -26
  55. package/dist/__tests__/playground/playground-headers.e2e.test.js.map +1 -1
  56. package/dist/__tests__/playground/playground-status.e2e.test.js +18 -26
  57. package/dist/__tests__/playground/playground-status.e2e.test.js.map +1 -1
  58. package/dist/__tests__/project-list.e2e.test.js +5 -21
  59. package/dist/__tests__/project-list.e2e.test.js.map +1 -1
  60. package/dist/__tests__/publish.e2e.test.js +6 -24
  61. package/dist/__tests__/publish.e2e.test.js.map +1 -1
  62. package/dist/__tests__/submission.e2e.test.d.ts +1 -0
  63. package/dist/__tests__/submission.e2e.test.js +173 -0
  64. package/dist/__tests__/submission.e2e.test.js.map +1 -0
  65. package/dist/__tests__/team-inspect.e2e.test.js +26 -1
  66. package/dist/__tests__/team-inspect.e2e.test.js.map +1 -1
  67. package/dist/__tests__/team-list.e2e.test.js +5 -21
  68. package/dist/__tests__/team-list.e2e.test.js.map +1 -1
  69. package/dist/__tests__/telemetry-destinations.e2e.test.d.ts +1 -0
  70. package/dist/__tests__/telemetry-destinations.e2e.test.js +105 -0
  71. package/dist/__tests__/telemetry-destinations.e2e.test.js.map +1 -0
  72. package/dist/__tests__/tunnel.e2e.test.js +114 -23
  73. package/dist/__tests__/tunnel.e2e.test.js.map +1 -1
  74. package/dist/__tests__/utils.d.ts +17 -6
  75. package/dist/__tests__/utils.js +49 -20
  76. package/dist/__tests__/utils.js.map +1 -1
  77. package/dist/api.d.ts +1 -1
  78. package/dist/api.js +2 -21
  79. package/dist/api.js.map +1 -1
  80. package/dist/commands/audit.js +3 -1
  81. package/dist/commands/audit.js.map +1 -1
  82. package/dist/commands/deploy.js +71 -54
  83. package/dist/commands/deploy.js.map +1 -1
  84. package/dist/commands/deployment/list.js +3 -3
  85. package/dist/commands/deployment/list.js.map +1 -1
  86. package/dist/commands/environment/delete.d.ts +13 -0
  87. package/dist/commands/environment/delete.js +45 -0
  88. package/dist/commands/environment/delete.js.map +1 -0
  89. package/dist/commands/environment/inspect.js +3 -3
  90. package/dist/commands/environment/inspect.js.map +1 -1
  91. package/dist/commands/environment/list.js +3 -3
  92. package/dist/commands/environment/list.js.map +1 -1
  93. package/dist/commands/git/connect.js +2 -2
  94. package/dist/commands/git/connect.js.map +1 -1
  95. package/dist/commands/git/disconnect.js +2 -2
  96. package/dist/commands/git/disconnect.js.map +1 -1
  97. package/dist/commands/insights/category/create.d.ts +17 -0
  98. package/dist/commands/insights/category/create.js +63 -0
  99. package/dist/commands/insights/category/create.js.map +1 -0
  100. package/dist/commands/insights/category/delete.d.ts +13 -0
  101. package/dist/commands/insights/category/delete.js +40 -0
  102. package/dist/commands/insights/category/delete.js.map +1 -0
  103. package/dist/commands/insights/category/link.d.ts +14 -0
  104. package/dist/commands/insights/category/link.js +36 -0
  105. package/dist/commands/insights/category/link.js.map +1 -0
  106. package/dist/commands/insights/category/list.d.ts +13 -0
  107. package/dist/commands/insights/category/list.js +46 -0
  108. package/dist/commands/insights/category/list.js.map +1 -0
  109. package/dist/commands/insights/category/unlink.d.ts +14 -0
  110. package/dist/commands/insights/category/unlink.js +36 -0
  111. package/dist/commands/insights/category/unlink.js.map +1 -0
  112. package/dist/commands/insights/category/update.d.ts +16 -0
  113. package/dist/commands/insights/category/update.js +45 -0
  114. package/dist/commands/insights/category/update.js.map +1 -0
  115. package/dist/commands/insights/feedback/list.d.ts +19 -0
  116. package/dist/commands/insights/feedback/list.js +73 -0
  117. package/dist/commands/insights/feedback/list.js.map +1 -0
  118. package/dist/commands/insights/intent/list.d.ts +22 -0
  119. package/dist/commands/insights/intent/list.js +89 -0
  120. package/dist/commands/insights/intent/list.js.map +1 -0
  121. package/dist/commands/link.js +4 -3
  122. package/dist/commands/link.js.map +1 -1
  123. package/dist/commands/login.js +7 -5
  124. package/dist/commands/login.js.map +1 -1
  125. package/dist/commands/logout.js +1 -1
  126. package/dist/commands/logout.js.map +1 -1
  127. package/dist/commands/logs.js +1 -9
  128. package/dist/commands/logs.js.map +1 -1
  129. package/dist/commands/project/inspect.js +3 -3
  130. package/dist/commands/project/inspect.js.map +1 -1
  131. package/dist/commands/project/list.js +3 -3
  132. package/dist/commands/project/list.js.map +1 -1
  133. package/dist/commands/submission/create.d.ts +15 -0
  134. package/dist/commands/submission/create.js +59 -0
  135. package/dist/commands/submission/create.js.map +1 -0
  136. package/dist/commands/submission/inspect.d.ts +10 -0
  137. package/dist/commands/submission/inspect.js +56 -0
  138. package/dist/commands/submission/inspect.js.map +1 -0
  139. package/dist/commands/submission/list.d.ts +13 -0
  140. package/dist/commands/submission/list.js +63 -0
  141. package/dist/commands/submission/list.js.map +1 -0
  142. package/dist/commands/submission/update.d.ts +12 -0
  143. package/dist/commands/submission/update.js +37 -0
  144. package/dist/commands/submission/update.js.map +1 -0
  145. package/dist/commands/team/inspect.js +25 -10
  146. package/dist/commands/team/inspect.js.map +1 -1
  147. package/dist/commands/team/list.js +3 -3
  148. package/dist/commands/team/list.js.map +1 -1
  149. package/dist/commands/telemetry/destinations/create.d.ts +19 -0
  150. package/dist/commands/telemetry/destinations/create.js +57 -0
  151. package/dist/commands/telemetry/destinations/create.js.map +1 -0
  152. package/dist/commands/telemetry/destinations/delete.d.ts +13 -0
  153. package/dist/commands/telemetry/destinations/delete.js +27 -0
  154. package/dist/commands/telemetry/destinations/delete.js.map +1 -0
  155. package/dist/commands/telemetry/destinations/list.d.ts +13 -0
  156. package/dist/commands/telemetry/destinations/list.js +48 -0
  157. package/dist/commands/telemetry/destinations/list.js.map +1 -0
  158. package/dist/commands/telemetry/destinations/update.d.ts +20 -0
  159. package/dist/commands/telemetry/destinations/update.js +62 -0
  160. package/dist/commands/telemetry/destinations/update.js.map +1 -0
  161. package/dist/commands/tunnel.js +30 -66
  162. package/dist/commands/tunnel.js.map +1 -1
  163. package/dist/commands/whoami.js +1 -1
  164. package/dist/commands/whoami.js.map +1 -1
  165. package/dist/lib/agent-mode.d.ts +8 -1
  166. package/dist/lib/agent-mode.js +25 -26
  167. package/dist/lib/agent-mode.js.map +1 -1
  168. package/dist/lib/alpic-command.d.ts +2 -1
  169. package/dist/lib/alpic-command.js +20 -8
  170. package/dist/lib/alpic-command.js.map +1 -1
  171. package/dist/lib/alpic-sdk.d.ts +2 -0
  172. package/dist/lib/alpic-sdk.js +8 -0
  173. package/dist/lib/alpic-sdk.js.map +1 -0
  174. package/dist/lib/audit.d.ts +1 -0
  175. package/dist/lib/audit.js +24 -15
  176. package/dist/lib/audit.js.map +1 -1
  177. package/dist/lib/base-workflow.d.ts +2 -1
  178. package/dist/lib/base-workflow.js +3 -3
  179. package/dist/lib/base-workflow.js.map +1 -1
  180. package/dist/lib/deployment.d.ts +0 -21
  181. package/dist/lib/deployment.js +20 -69
  182. package/dist/lib/deployment.js.map +1 -1
  183. package/dist/lib/environment-variable.js +14 -13
  184. package/dist/lib/environment-variable.js.map +1 -1
  185. package/dist/lib/insights.d.ts +19 -0
  186. package/dist/lib/insights.js +54 -0
  187. package/dist/lib/insights.js.map +1 -0
  188. package/dist/lib/link.d.ts +1 -2
  189. package/dist/lib/link.js +20 -75
  190. package/dist/lib/link.js.map +1 -1
  191. package/dist/lib/logs.js +4 -5
  192. package/dist/lib/logs.js.map +1 -1
  193. package/dist/lib/playground.js +25 -25
  194. package/dist/lib/playground.js.map +1 -1
  195. package/dist/lib/project-settings.d.ts +7 -0
  196. package/dist/lib/project-settings.js +140 -0
  197. package/dist/lib/project-settings.js.map +1 -0
  198. package/dist/lib/project-settings.test.d.ts +1 -0
  199. package/dist/lib/project-settings.test.js +56 -0
  200. package/dist/lib/project-settings.test.js.map +1 -0
  201. package/dist/lib/publish.js +3 -3
  202. package/dist/lib/publish.js.map +1 -1
  203. package/dist/lib/resolve.d.ts +7 -6
  204. package/dist/lib/resolve.js +27 -23
  205. package/dist/lib/resolve.js.map +1 -1
  206. package/dist/lib/submission.d.ts +13 -0
  207. package/dist/lib/submission.js +52 -0
  208. package/dist/lib/submission.js.map +1 -0
  209. package/dist/lib/telemetry-destinations.d.ts +9 -0
  210. package/dist/lib/telemetry-destinations.js +21 -0
  211. package/dist/lib/telemetry-destinations.js.map +1 -0
  212. package/dist/lib/telemetry-destinations.test.d.ts +1 -0
  213. package/dist/lib/telemetry-destinations.test.js +14 -0
  214. package/dist/lib/telemetry-destinations.test.js.map +1 -0
  215. package/dist/lib/telemetry.js +27 -17
  216. package/dist/lib/telemetry.js.map +1 -1
  217. package/dist/lib/utils.d.ts +9 -1
  218. package/dist/lib/utils.js +28 -2
  219. package/dist/lib/utils.js.map +1 -1
  220. package/dist/lib/utils.test.js +43 -5
  221. package/dist/lib/utils.test.js.map +1 -1
  222. package/dist/lib/whoami.js +17 -0
  223. package/dist/lib/whoami.js.map +1 -0
  224. package/dist/sentry.js +3 -6
  225. package/dist/sentry.js.map +1 -1
  226. package/package.json +29 -32
  227. package/dist/lib/archive.d.ts +0 -7
  228. package/dist/lib/archive.js +0 -57
  229. package/dist/lib/archive.js.map +0 -1
  230. package/dist/lib/auth/auth.d.ts +0 -5
  231. package/dist/lib/auth/auth.js +0 -50
  232. package/dist/lib/auth/auth.js.map +0 -1
  233. package/dist/lib/auth/oauth/client.d.ts +0 -28
  234. package/dist/lib/auth/oauth/client.js +0 -116
  235. package/dist/lib/auth/oauth/client.js.map +0 -1
  236. package/dist/lib/auth/oauth/constants.d.ts +0 -2
  237. package/dist/lib/auth/oauth/constants.js +0 -3
  238. package/dist/lib/auth/oauth/constants.js.map +0 -1
  239. package/dist/lib/auth/oauth/server/assets/alpic-mountain.png +0 -0
  240. package/dist/lib/auth/oauth/server/assets/authorize.html +0 -234
  241. package/dist/lib/auth/oauth/server/assets/callback.html +0 -88
  242. package/dist/lib/auth/oauth/server/index.d.ts +0 -9
  243. package/dist/lib/auth/oauth/server/index.js +0 -128
  244. package/dist/lib/auth/oauth/server/index.js.map +0 -1
  245. package/dist/lib/auth/whoami.js +0 -47
  246. package/dist/lib/auth/whoami.js.map +0 -1
  247. package/dist/lib/config.d.ts +0 -12
  248. package/dist/lib/config.js +0 -32
  249. package/dist/lib/config.js.map +0 -1
  250. package/dist/lib/global-store.d.ts +0 -28
  251. package/dist/lib/global-store.js +0 -76
  252. package/dist/lib/global-store.js.map +0 -1
  253. package/dist/lib/upload.d.ts +0 -1
  254. package/dist/lib/upload.js +0 -13
  255. package/dist/lib/upload.js.map +0 -1
  256. package/dist/lib/vendor/pipenet.d.ts +0 -1
  257. package/dist/lib/vendor/pipenet.js +0 -16877
  258. package/dist/lib/vendor/pipenet.js.LEGAL.txt +0 -17
  259. package/dist/lib/vendor/pipenet.js.map +0 -7
  260. package/dist/types.d.ts +0 -8
  261. package/dist/types.js +0 -2
  262. package/dist/types.js.map +0 -1
  263. /package/dist/lib/{auth/whoami.d.ts → whoami.d.ts} +0 -0
@@ -8,6 +8,32 @@ import { OpenAPIHandler } from "@orpc/openapi/node";
8
8
  import { implement, ORPCError } from "@orpc/server";
9
9
  import express, {} from "express";
10
10
  import { inc as semverInc } from "semver";
11
+ function createEmptyMockData() {
12
+ return {
13
+ tunnelTicket: null,
14
+ teams: null,
15
+ projects: new Map(),
16
+ environments: new Map(),
17
+ deployments: new Map(),
18
+ environmentVariables: new Map(),
19
+ runtimeLogs: new Map(),
20
+ runtimeLogPages: new Map(),
21
+ deploymentLogPages: new Map(),
22
+ deploymentLogCallCounts: new Map(),
23
+ publishedServers: new Map(),
24
+ beaconGetResponses: [],
25
+ beaconGetCallCount: 0,
26
+ playgrounds: new Map(),
27
+ teamUsages: new Map(),
28
+ intents: new Map(),
29
+ feedbacks: new Map(),
30
+ intentCategories: new Map(),
31
+ intentCategoryCounter: 0,
32
+ submissions: new Map(),
33
+ submissionPrefills: new Map(),
34
+ telemetryDestinations: new Map(),
35
+ };
36
+ }
11
37
  const __testDirname = dirname(fileURLToPath(import.meta.url));
12
38
  const FIXTURE_CERT_PATH = join(__testDirname, "fixtures", "certs", "localhost-cert.pem");
13
39
  const FIXTURE_KEY_PATH = join(__testDirname, "fixtures", "certs", "localhost-key.pem");
@@ -26,21 +52,7 @@ export class MockApiServer {
26
52
  callHistory = [];
27
53
  constructor() {
28
54
  this.app = express();
29
- this.mockData = {
30
- teams: null,
31
- projects: new Map(),
32
- environments: new Map(),
33
- deployments: new Map(),
34
- environmentVariables: new Map(),
35
- runtimeLogs: new Map(),
36
- runtimeLogPages: new Map(),
37
- deploymentLogPages: new Map(),
38
- deploymentLogCallCounts: new Map(),
39
- publishedServers: new Map(),
40
- beaconGetResponses: [],
41
- beaconGetCallCount: 0,
42
- playgrounds: new Map(),
43
- };
55
+ this.mockData = createEmptyMockData();
44
56
  }
45
57
  async start() {
46
58
  if (this.server) {
@@ -115,11 +127,11 @@ export class MockApiServer {
115
127
  tunnels: {
116
128
  getTicket: {
117
129
  v1: implement(contract.tunnels.getTicket.v1).handler(async () => {
118
- return {
130
+ return (this.mockData.tunnelTicket ?? {
119
131
  subdomain: "cool-mongoose-123",
120
132
  ticket: "mock-ticket",
121
133
  tunnelHost: "tunnel.alpic.dev",
122
- };
134
+ });
123
135
  }),
124
136
  },
125
137
  },
@@ -139,6 +151,15 @@ export class MockApiServer {
139
151
  ];
140
152
  }),
141
153
  },
154
+ getUsage: {
155
+ v1: implement(contract.teams.getUsage.v1).handler(async ({ input }) => {
156
+ const usage = this.mockData.teamUsages.get(input.teamId);
157
+ if (!usage) {
158
+ throw new ORPCError("NOT_FOUND", { message: "Team usage not found" });
159
+ }
160
+ return usage;
161
+ }),
162
+ },
142
163
  },
143
164
  analytics: {
144
165
  get: {
@@ -171,6 +192,129 @@ export class MockApiServer {
171
192
  }),
172
193
  },
173
194
  },
195
+ intents: {
196
+ list: {
197
+ v1: implement(contract.intents.list.v1).handler(async ({ input }) => {
198
+ if (!this.mockData.environments.has(input.environmentId)) {
199
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
200
+ }
201
+ let intents = this.mockData.intents.get(input.environmentId) ?? [];
202
+ if (input.search) {
203
+ const search = input.search.toLowerCase();
204
+ intents = intents.filter((intent) => intent.message.toLowerCase().includes(search) ||
205
+ intent.toolName.toLowerCase().includes(search) ||
206
+ intent.categories.some(({ name }) => name.toLowerCase().includes(search)));
207
+ }
208
+ if (input.tools) {
209
+ intents = intents.filter(({ toolName }) => input.tools?.includes(toolName));
210
+ }
211
+ if (input.clientIds) {
212
+ intents = intents.filter(({ clientId }) => clientId !== null && input.clientIds?.includes(clientId));
213
+ }
214
+ if (input.categoryIds) {
215
+ intents = intents.filter(({ categories }) => categories.some(({ id }) => input.categoryIds?.includes(id)));
216
+ }
217
+ intents = [...intents].sort((left, right) => input.sortDir === "asc"
218
+ ? left.createdAt.getTime() - right.createdAt.getTime()
219
+ : right.createdAt.getTime() - left.createdAt.getTime());
220
+ return {
221
+ intents: intents.slice(input.offset, input.offset + input.limit),
222
+ totalCount: intents.length,
223
+ };
224
+ }),
225
+ },
226
+ },
227
+ intentCategories: {
228
+ list: {
229
+ v1: implement(contract.intentCategories.list.v1).handler(async ({ input }) => {
230
+ const categories = this.requireMockEnvironmentCategories(input.environmentId);
231
+ return categories.map(({ linkedIntentIds, ...category }) => ({
232
+ ...category,
233
+ intentCount: linkedIntentIds.size,
234
+ }));
235
+ }),
236
+ },
237
+ create: {
238
+ v1: implement(contract.intentCategories.create.v1).handler(async ({ input }) => {
239
+ const categories = this.requireMockEnvironmentCategories(input.environmentId);
240
+ this.requireMockIntents(input.environmentId, input.intentIds ?? [], "BAD_REQUEST");
241
+ const { linkedIntentIds, ...category } = {
242
+ id: `cat-mock-${++this.mockData.intentCategoryCounter}`,
243
+ createdAt: new Date("2026-08-13T00:00:00.000Z"),
244
+ environmentId: input.environmentId,
245
+ name: input.name,
246
+ color: input.color ?? "gray",
247
+ linkedIntentIds: new Set(input.intentIds ?? []),
248
+ };
249
+ categories.push({ ...category, linkedIntentIds });
250
+ return category;
251
+ }),
252
+ },
253
+ update: {
254
+ v1: implement(contract.intentCategories.update.v1).handler(async ({ input }) => {
255
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
256
+ category.name = input.name ?? category.name;
257
+ category.color = input.color ?? category.color;
258
+ const { linkedIntentIds, ...updated } = category;
259
+ return updated;
260
+ }),
261
+ },
262
+ delete: {
263
+ v1: implement(contract.intentCategories.delete.v1).handler(async ({ input }) => {
264
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
265
+ this.mockData.intentCategories.set(input.environmentId, (this.mockData.intentCategories.get(input.environmentId) ?? []).filter(({ id }) => id !== category.id));
266
+ this.removeCategoryFromIntents(input.environmentId, category.id, null);
267
+ return { success: true };
268
+ }),
269
+ },
270
+ link: {
271
+ v1: implement(contract.intentCategories.link.v1).handler(async ({ input }) => {
272
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
273
+ this.requireMockIntents(input.environmentId, input.intentIds, "NOT_FOUND");
274
+ for (const intentId of input.intentIds) {
275
+ category.linkedIntentIds.add(intentId);
276
+ }
277
+ for (const intent of this.mockData.intents.get(input.environmentId) ?? []) {
278
+ const isLinked = intent.intentIds.some((intentId) => category.linkedIntentIds.has(intentId));
279
+ if (isLinked && !intent.categories.some(({ id }) => id === category.id)) {
280
+ intent.categories.push({ id: category.id, name: category.name, color: category.color });
281
+ }
282
+ }
283
+ return { success: true };
284
+ }),
285
+ },
286
+ unlink: {
287
+ v1: implement(contract.intentCategories.unlink.v1).handler(async ({ input }) => {
288
+ const category = this.requireMockIntentCategory(input.environmentId, input.categoryId);
289
+ for (const intentId of input.intentIds) {
290
+ category.linkedIntentIds.delete(intentId);
291
+ }
292
+ this.removeCategoryFromIntents(input.environmentId, category.id, category.linkedIntentIds);
293
+ return { success: true };
294
+ }),
295
+ },
296
+ },
297
+ feedbacks: {
298
+ list: {
299
+ v1: implement(contract.feedbacks.list.v1).handler(async ({ input }) => {
300
+ if (!this.mockData.environments.has(input.environmentId)) {
301
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
302
+ }
303
+ let feedbacks = this.mockData.feedbacks.get(input.environmentId) ?? [];
304
+ if (input.search) {
305
+ const search = input.search.toLowerCase();
306
+ feedbacks = feedbacks.filter((feedback) => feedback.content.toLowerCase().includes(search) || feedback.source.toLowerCase().includes(search));
307
+ }
308
+ if (input.clientIds) {
309
+ feedbacks = feedbacks.filter(({ clientId }) => clientId !== null && input.clientIds?.includes(clientId));
310
+ }
311
+ return {
312
+ feedbacks: feedbacks.slice(input.offset, input.offset + input.limit),
313
+ totalCount: feedbacks.length,
314
+ };
315
+ }),
316
+ },
317
+ },
174
318
  projects: {
175
319
  list: {
176
320
  v1: implement(contract.projects.list.v1).handler(async ({ input }) => {
@@ -354,6 +498,30 @@ export class MockApiServer {
354
498
  return environment;
355
499
  }),
356
500
  },
501
+ delete: {
502
+ v1: implement(contract.environments.delete.v1).handler(async ({ input }) => {
503
+ const environment = this.mockData.environments.get(input.environmentId);
504
+ if (!environment) {
505
+ throw new ORPCError("NOT_FOUND", {
506
+ message: "Environment not found",
507
+ });
508
+ }
509
+ const project = this.mockData.projects.get(environment.projectId);
510
+ if (project?.productionEnvironment?.id === input.environmentId) {
511
+ throw new ORPCError("BAD_REQUEST", {
512
+ message: "Cannot delete the production environment of the project",
513
+ });
514
+ }
515
+ this.mockData.environments.delete(input.environmentId);
516
+ if (project) {
517
+ this.mockData.projects.set(environment.projectId, {
518
+ ...project,
519
+ environments: project.environments.filter((env) => env.id !== input.environmentId),
520
+ });
521
+ }
522
+ return { success: true };
523
+ }),
524
+ },
357
525
  getLogs: {
358
526
  v1: implement(contract.environments.getLogs.v1).handler(async ({ input }) => {
359
527
  const environment = this.mockData.environments.get(input.environmentId);
@@ -421,6 +589,80 @@ export class MockApiServer {
421
589
  }),
422
590
  },
423
591
  },
592
+ telemetryDestinations: {
593
+ list: {
594
+ v1: implement(contract.telemetryDestinations.list.v1).handler(async ({ input }) => {
595
+ if (!this.mockData.environments.has(input.environmentId)) {
596
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
597
+ }
598
+ return this.mockData.telemetryDestinations.get(input.environmentId) ?? [];
599
+ }),
600
+ },
601
+ create: {
602
+ v1: implement(contract.telemetryDestinations.create.v1).handler(async ({ input }) => {
603
+ if (!this.mockData.environments.has(input.environmentId)) {
604
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
605
+ }
606
+ const destination = {
607
+ id: randomUUID(),
608
+ signal: input.signal,
609
+ endpoint: input.endpoint,
610
+ protocol: input.protocol,
611
+ status: "active",
612
+ lastFailureReason: null,
613
+ isScopedToIntentionalRequestsOnly: input.signal === "traces" && input.isScopedToIntentionalRequestsOnly,
614
+ headers: input.headers.map((header) => header.isSecret
615
+ ? { id: randomUUID(), name: header.name, value: null, isSecret: true }
616
+ : { id: randomUUID(), name: header.name, value: header.value, isSecret: false }),
617
+ };
618
+ this.mockData.telemetryDestinations.set(input.environmentId, [
619
+ ...(this.mockData.telemetryDestinations.get(input.environmentId) ?? []),
620
+ destination,
621
+ ]);
622
+ return destination;
623
+ }),
624
+ },
625
+ update: {
626
+ v1: implement(contract.telemetryDestinations.update.v1).handler(async ({ input }) => {
627
+ const destinations = this.mockData.telemetryDestinations.get(input.environmentId) ?? [];
628
+ const current = destinations.find(({ id }) => id === input.destinationId);
629
+ if (current === undefined) {
630
+ throw new ORPCError("NOT_FOUND", { message: "Telemetry destination not found" });
631
+ }
632
+ const updated = {
633
+ ...current,
634
+ endpoint: input.endpoint ?? current.endpoint,
635
+ protocol: input.protocol ?? current.protocol,
636
+ isScopedToIntentionalRequestsOnly: current.signal === "traces"
637
+ ? (input.isScopedToIntentionalRequestsOnly ?? current.isScopedToIntentionalRequestsOnly)
638
+ : false,
639
+ headers: input.headers?.map((header) => {
640
+ const previous = header.id === undefined ? undefined : current.headers.find(({ id }) => id === header.id);
641
+ const id = header.id ?? randomUUID();
642
+ if (header.isSecret) {
643
+ return { id, name: header.name, value: null, isSecret: true };
644
+ }
645
+ const value = header.value ?? previous?.value;
646
+ if (value === undefined || value === null) {
647
+ throw new ORPCError("BAD_REQUEST", { message: `Enter a value for the ${header.name} header` });
648
+ }
649
+ return { id, name: header.name, value, isSecret: false };
650
+ }) ?? current.headers,
651
+ };
652
+ this.mockData.telemetryDestinations.set(input.environmentId, destinations.map((destination) => (destination.id === updated.id ? updated : destination)));
653
+ return updated;
654
+ }),
655
+ },
656
+ delete: {
657
+ v1: implement(contract.telemetryDestinations.delete.v1).handler(async ({ input }) => {
658
+ if (!this.mockData.environments.has(input.environmentId)) {
659
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
660
+ }
661
+ this.mockData.telemetryDestinations.set(input.environmentId, (this.mockData.telemetryDestinations.get(input.environmentId) ?? []).filter(({ id }) => id !== input.destinationId));
662
+ return { success: true };
663
+ }),
664
+ },
665
+ },
424
666
  environmentVariables: {
425
667
  list: {
426
668
  v1: implement(contract.environmentVariables.list.v1).handler(async ({ input }) => {
@@ -639,6 +881,73 @@ export class MockApiServer {
639
881
  }),
640
882
  },
641
883
  },
884
+ submissions: {
885
+ create: {
886
+ v1: implement(contract.submissions.create.v1).handler(async ({ input }) => {
887
+ const environment = this.mockData.environments.get(input.environmentId);
888
+ if (!environment) {
889
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
890
+ }
891
+ const formData = this.mockData.submissionPrefills.get(input.platform) ?? {};
892
+ const now = new Date();
893
+ const submission = {
894
+ id: `sub-${randomUUID()}`,
895
+ environmentId: input.environmentId,
896
+ platform: input.platform,
897
+ formData,
898
+ prefillSnapshot: formData,
899
+ auditId: "audit-1",
900
+ urlVerification: null,
901
+ createdAt: now,
902
+ updatedAt: now,
903
+ };
904
+ this.mockData.submissions.set(submission.id, submission);
905
+ return submission;
906
+ }),
907
+ },
908
+ list: {
909
+ v1: implement(contract.submissions.list.v1).handler(async ({ input }) => {
910
+ const project = this.mockData.projects.get(input.projectId);
911
+ if (!project) {
912
+ throw new ORPCError("NOT_FOUND", { message: "Project not found" });
913
+ }
914
+ const environmentIds = new Set(project.environments.map((environment) => environment.id));
915
+ let submissions = [...this.mockData.submissions.values()].filter((submission) => environmentIds.has(submission.environmentId));
916
+ if (input.environmentId) {
917
+ submissions = submissions.filter((submission) => submission.environmentId === input.environmentId);
918
+ }
919
+ if (input.platform) {
920
+ submissions = submissions.filter((submission) => submission.platform === input.platform);
921
+ }
922
+ return submissions;
923
+ }),
924
+ },
925
+ get: {
926
+ v1: implement(contract.submissions.get.v1).handler(async ({ input }) => {
927
+ const submission = this.mockData.submissions.get(input.submissionId);
928
+ if (!submission) {
929
+ throw new ORPCError("NOT_FOUND", { message: "Submission not found" });
930
+ }
931
+ return submission;
932
+ }),
933
+ },
934
+ update: {
935
+ v1: implement(contract.submissions.update.v1).handler(async ({ input }) => {
936
+ const submission = this.mockData.submissions.get(input.submissionId);
937
+ if (!submission) {
938
+ throw new ORPCError("NOT_FOUND", { message: "Submission not found" });
939
+ }
940
+ if (submission.platform !== input.platform) {
941
+ throw new ORPCError("BAD_REQUEST", {
942
+ message: `Platform mismatch: submission ${submission.id} is ${submission.platform}, payload claims ${input.platform}`,
943
+ });
944
+ }
945
+ const updated = { ...submission, formData: input.formData, updatedAt: new Date() };
946
+ this.mockData.submissions.set(submission.id, updated);
947
+ return updated;
948
+ }),
949
+ },
950
+ },
642
951
  deployments: {
643
952
  list: {
644
953
  v1: implement(contract.deployments.list.v1).handler(async ({ input }) => {
@@ -747,21 +1056,7 @@ export class MockApiServer {
747
1056
  }
748
1057
  reset() {
749
1058
  this.callHistory = [];
750
- this.mockData = {
751
- teams: null,
752
- projects: new Map(),
753
- environments: new Map(),
754
- deployments: new Map(),
755
- environmentVariables: new Map(),
756
- runtimeLogs: new Map(),
757
- runtimeLogPages: new Map(),
758
- deploymentLogPages: new Map(),
759
- deploymentLogCallCounts: new Map(),
760
- publishedServers: new Map(),
761
- beaconGetResponses: [],
762
- beaconGetCallCount: 0,
763
- playgrounds: new Map(),
764
- };
1059
+ this.mockData = createEmptyMockData();
765
1060
  }
766
1061
  async stop() {
767
1062
  return new Promise((resolve, reject) => {
@@ -792,10 +1087,8 @@ export class MockApiServer {
792
1087
  return false;
793
1088
  }
794
1089
  }
795
- else {
796
- if (!pathPattern.test(call.path)) {
797
- return false;
798
- }
1090
+ else if (!pathPattern.test(call.path)) {
1091
+ return false;
799
1092
  }
800
1093
  }
801
1094
  return true;
@@ -816,23 +1109,27 @@ export class MockApiServer {
816
1109
  continue;
817
1110
  }
818
1111
  }
819
- else {
820
- if (!pathPattern.test(call.path)) {
821
- continue;
822
- }
1112
+ else if (!pathPattern.test(call.path)) {
1113
+ continue;
823
1114
  }
824
1115
  }
825
1116
  return call;
826
1117
  }
827
1118
  return undefined;
828
1119
  }
1120
+ setTunnelTicket(ticket) {
1121
+ this.mockData.tunnelTicket = ticket;
1122
+ }
829
1123
  setTeams(teams) {
830
1124
  this.mockData.teams = teams.map((team) => ({
831
1125
  ...team,
832
- createdAt: new Date("2024-01-01T00:00:00.000Z"),
1126
+ createdAt: new Date(Date.now() - 2 * 365 * 24 * 60 * 60 * 1000),
833
1127
  hasStripeAccount: false,
834
1128
  }));
835
1129
  }
1130
+ setTeamUsage(usage) {
1131
+ this.mockData.teamUsages.set(usage.teamId, usage);
1132
+ }
836
1133
  addEnvironmentVariables(environmentId, variables) {
837
1134
  this.mockData.environmentVariables.set(environmentId, variables);
838
1135
  }
@@ -866,6 +1163,53 @@ export class MockApiServer {
866
1163
  setPlayground(environmentId, playground) {
867
1164
  this.mockData.playgrounds.set(environmentId, playground);
868
1165
  }
1166
+ setIntents(environmentId, intents) {
1167
+ this.mockData.intents.set(environmentId, intents);
1168
+ }
1169
+ setIntentCategories(environmentId, categories) {
1170
+ this.mockData.intentCategories.set(environmentId, categories.map((category) => ({ ...category, linkedIntentIds: new Set(category.linkedIntentIds ?? []) })));
1171
+ }
1172
+ setTelemetryDestinations(environmentId, destinations) {
1173
+ this.mockData.telemetryDestinations.set(environmentId, destinations);
1174
+ }
1175
+ requireMockEnvironmentCategories(environmentId) {
1176
+ if (!this.mockData.environments.has(environmentId)) {
1177
+ throw new ORPCError("NOT_FOUND", { message: "Environment not found" });
1178
+ }
1179
+ const categories = this.mockData.intentCategories.get(environmentId) ?? [];
1180
+ this.mockData.intentCategories.set(environmentId, categories);
1181
+ return categories;
1182
+ }
1183
+ requireMockIntentCategory(environmentId, categoryId) {
1184
+ const category = this.requireMockEnvironmentCategories(environmentId).find(({ id }) => id === categoryId);
1185
+ if (!category) {
1186
+ throw new ORPCError("NOT_FOUND", { message: "Intent category not found" });
1187
+ }
1188
+ return category;
1189
+ }
1190
+ requireMockIntents(environmentId, intentIds, errorCode) {
1191
+ const knownIntentIds = new Set((this.mockData.intents.get(environmentId) ?? []).flatMap((intent) => intent.intentIds));
1192
+ if (intentIds.some((intentId) => !knownIntentIds.has(intentId))) {
1193
+ throw new ORPCError(errorCode, { message: "One or more intents not found" });
1194
+ }
1195
+ }
1196
+ removeCategoryFromIntents(environmentId, categoryId, remainingIntentIds) {
1197
+ for (const intent of this.mockData.intents.get(environmentId) ?? []) {
1198
+ const stillLinked = remainingIntentIds !== null && intent.intentIds.some((intentId) => remainingIntentIds.has(intentId));
1199
+ if (!stillLinked) {
1200
+ intent.categories = intent.categories.filter(({ id }) => id !== categoryId);
1201
+ }
1202
+ }
1203
+ }
1204
+ setFeedbacks(environmentId, feedbacks) {
1205
+ this.mockData.feedbacks.set(environmentId, feedbacks);
1206
+ }
1207
+ addSubmission(submission) {
1208
+ this.mockData.submissions.set(submission.id, submission);
1209
+ }
1210
+ setSubmissionPrefill(platform, formData) {
1211
+ this.mockData.submissionPrefills.set(platform, formData);
1212
+ }
869
1213
  addProject(project) {
870
1214
  this.mockData.projects.set(project.id, project);
871
1215
  if (project.productionEnvironment) {