@vibesdotdev/client 0.1.1 → 1.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -15
  3. package/dist/api-client-plugin.d.ts +4 -0
  4. package/dist/api-client-plugin.d.ts.map +1 -0
  5. package/dist/api-client-plugin.js +20 -0
  6. package/dist/api-client-plugin.js.map +1 -0
  7. package/dist/api-client.impl.d.ts +23 -0
  8. package/dist/api-client.impl.d.ts.map +1 -0
  9. package/dist/api-client.impl.js +47 -0
  10. package/dist/api-client.impl.js.map +1 -0
  11. package/dist/client.consumer.plugin.d.ts +3 -0
  12. package/dist/client.consumer.plugin.d.ts.map +1 -0
  13. package/dist/client.consumer.plugin.js +10 -0
  14. package/dist/client.consumer.plugin.js.map +1 -0
  15. package/dist/cloud.plugin.d.ts +3 -0
  16. package/dist/cloud.plugin.d.ts.map +1 -0
  17. package/dist/cloud.plugin.js +10 -0
  18. package/dist/cloud.plugin.js.map +1 -0
  19. package/dist/config/client.config.descriptor.d.ts +4 -0
  20. package/dist/config/client.config.descriptor.d.ts.map +1 -0
  21. package/dist/config/client.config.descriptor.js +32 -0
  22. package/dist/config/client.config.descriptor.js.map +1 -0
  23. package/dist/config/index.d.ts +3 -0
  24. package/dist/config/index.d.ts.map +1 -0
  25. package/dist/config/index.js +3 -0
  26. package/dist/config/index.js.map +1 -0
  27. package/dist/config/settings.d.ts +9 -0
  28. package/dist/config/settings.d.ts.map +1 -0
  29. package/dist/config/settings.js +25 -0
  30. package/dist/config/settings.js.map +1 -0
  31. package/dist/docs/client.api-request.docs.descriptor.d.ts +4 -0
  32. package/dist/docs/client.api-request.docs.descriptor.d.ts.map +1 -0
  33. package/dist/docs/client.api-request.docs.descriptor.js +71 -0
  34. package/dist/docs/client.api-request.docs.descriptor.js.map +1 -0
  35. package/dist/events/auth-rejected.event.d.ts +35 -0
  36. package/dist/events/auth-rejected.event.d.ts.map +1 -0
  37. package/dist/events/auth-rejected.event.js +36 -0
  38. package/dist/events/auth-rejected.event.js.map +1 -0
  39. package/dist/factory.d.ts +5 -1
  40. package/dist/factory.d.ts.map +1 -1
  41. package/dist/factory.js +16 -17
  42. package/dist/factory.js.map +1 -1
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +2 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/kind-augment.d.ts +11 -0
  48. package/dist/kind-augment.d.ts.map +1 -0
  49. package/dist/kind-augment.js +2 -0
  50. package/dist/kind-augment.js.map +1 -0
  51. package/dist/lib/client/api-diagnostics.d.ts +79 -0
  52. package/dist/lib/client/api-diagnostics.d.ts.map +1 -0
  53. package/dist/lib/client/api-diagnostics.js +111 -0
  54. package/dist/lib/client/api-diagnostics.js.map +1 -0
  55. package/dist/lib/client/configured.d.ts +78 -0
  56. package/dist/lib/client/configured.d.ts.map +1 -0
  57. package/dist/lib/client/configured.js +261 -0
  58. package/dist/lib/client/configured.js.map +1 -0
  59. package/dist/lib/client/internal/auth-headers.d.ts +11 -0
  60. package/dist/lib/client/internal/auth-headers.d.ts.map +1 -0
  61. package/dist/lib/client/internal/auth-headers.js +35 -0
  62. package/dist/lib/client/internal/auth-headers.js.map +1 -0
  63. package/dist/lib/client/internal/base-client.d.ts +5 -2
  64. package/dist/lib/client/internal/base-client.d.ts.map +1 -1
  65. package/dist/lib/client/internal/base-client.js +42 -22
  66. package/dist/lib/client/internal/base-client.js.map +1 -1
  67. package/dist/lib/client/internal/base-helpers.d.ts.map +1 -1
  68. package/dist/lib/client/internal/base-helpers.js +20 -20
  69. package/dist/lib/client/internal/base-helpers.js.map +1 -1
  70. package/dist/lib/client/internal/base-types.d.ts +10 -5
  71. package/dist/lib/client/internal/base-types.d.ts.map +1 -1
  72. package/dist/lib/client/internal/base-types.js +5 -3
  73. package/dist/lib/client/internal/base-types.js.map +1 -1
  74. package/dist/lib/client/internal/client-values.d.ts +43 -0
  75. package/dist/lib/client/internal/client-values.d.ts.map +1 -0
  76. package/dist/lib/client/internal/client-values.js +76 -0
  77. package/dist/lib/client/internal/client-values.js.map +1 -0
  78. package/dist/lib/client/internal/endpoint.d.ts +6 -5
  79. package/dist/lib/client/internal/endpoint.d.ts.map +1 -1
  80. package/dist/lib/client/internal/endpoint.js +3 -0
  81. package/dist/lib/client/internal/endpoint.js.map +1 -1
  82. package/dist/lib/client/internal/generator.d.ts +98 -9
  83. package/dist/lib/client/internal/generator.d.ts.map +1 -1
  84. package/dist/lib/client/internal/generator.js +92 -140
  85. package/dist/lib/client/internal/generator.js.map +1 -1
  86. package/dist/lib/client/internal/request-builder.d.ts +5 -2
  87. package/dist/lib/client/internal/request-builder.d.ts.map +1 -1
  88. package/dist/lib/client/internal/request-builder.js +105 -65
  89. package/dist/lib/client/internal/request-builder.js.map +1 -1
  90. package/dist/lib/client/internal/sse-stream.d.ts +9 -5
  91. package/dist/lib/client/internal/sse-stream.d.ts.map +1 -1
  92. package/dist/lib/client/internal/sse-stream.js +96 -94
  93. package/dist/lib/client/internal/sse-stream.js.map +1 -1
  94. package/dist/lib/client/internal/timeout-signal.d.ts +8 -0
  95. package/dist/lib/client/internal/timeout-signal.d.ts.map +1 -0
  96. package/dist/lib/client/internal/timeout-signal.js +17 -0
  97. package/dist/lib/client/internal/timeout-signal.js.map +1 -0
  98. package/dist/lib/client/internal/transport/http2-fetch.d.ts +8 -0
  99. package/dist/lib/client/internal/transport/http2-fetch.d.ts.map +1 -0
  100. package/dist/lib/client/internal/transport/http2-fetch.js +17 -0
  101. package/dist/lib/client/internal/transport/http2-fetch.js.map +1 -0
  102. package/dist/lib/client/internal/vibes-client.d.ts +17 -8
  103. package/dist/lib/client/internal/vibes-client.d.ts.map +1 -1
  104. package/dist/lib/client/internal/vibes-client.js +127 -67
  105. package/dist/lib/client/internal/vibes-client.js.map +1 -1
  106. package/dist/lib/client/internal/wrap-fetch.d.ts +3 -2
  107. package/dist/lib/client/internal/wrap-fetch.d.ts.map +1 -1
  108. package/dist/lib/client/internal/wrap-fetch.js +14 -33
  109. package/dist/lib/client/internal/wrap-fetch.js.map +1 -1
  110. package/dist/lib/client/runtime-fetch.d.ts +14 -0
  111. package/dist/lib/client/runtime-fetch.d.ts.map +1 -0
  112. package/dist/lib/client/runtime-fetch.js +25 -0
  113. package/dist/lib/client/runtime-fetch.js.map +1 -0
  114. package/dist/lib/client/types.d.ts +18 -9
  115. package/dist/lib/client/types.d.ts.map +1 -1
  116. package/dist/lib/client/types.js +22 -3
  117. package/dist/lib/client/types.js.map +1 -1
  118. package/dist/plugin.d.ts +2 -18
  119. package/dist/plugin.d.ts.map +1 -1
  120. package/dist/plugin.js +7 -74
  121. package/dist/plugin.js.map +1 -1
  122. package/dist/runtime-client.d.ts +10 -0
  123. package/dist/runtime-client.d.ts.map +1 -0
  124. package/dist/runtime-client.js +14 -0
  125. package/dist/runtime-client.js.map +1 -0
  126. package/dist/schemas/auth-rejected.d.ts +12 -0
  127. package/dist/schemas/auth-rejected.d.ts.map +1 -0
  128. package/dist/schemas/auth-rejected.js +11 -0
  129. package/dist/schemas/auth-rejected.js.map +1 -0
  130. package/dist/schemas/sdk-languages.d.ts +47 -0
  131. package/dist/schemas/sdk-languages.d.ts.map +1 -0
  132. package/dist/schemas/sdk-languages.js +75 -0
  133. package/dist/schemas/sdk-languages.js.map +1 -0
  134. package/dist/schemas/settings.d.ts +14 -0
  135. package/dist/schemas/settings.d.ts.map +1 -0
  136. package/dist/schemas/settings.js +10 -0
  137. package/dist/schemas/settings.js.map +1 -0
  138. package/dist/schemas/validated-request.d.ts +19 -0
  139. package/dist/schemas/validated-request.d.ts.map +1 -0
  140. package/dist/schemas/validated-request.js +2 -0
  141. package/dist/schemas/validated-request.js.map +1 -0
  142. package/dist/schemas.d.ts +23 -8
  143. package/dist/schemas.d.ts.map +1 -1
  144. package/dist/schemas.js +8 -2
  145. package/dist/schemas.js.map +1 -1
  146. package/dist/sse-client.d.ts +17 -15
  147. package/dist/sse-client.d.ts.map +1 -1
  148. package/dist/sse-client.js +111 -91
  149. package/dist/sse-client.js.map +1 -1
  150. package/dist/svelte/client-svelte.plugin.d.ts +5 -0
  151. package/dist/svelte/client-svelte.plugin.d.ts.map +1 -0
  152. package/dist/svelte/client-svelte.plugin.js +46 -0
  153. package/dist/svelte/index.d.ts +3 -0
  154. package/dist/svelte/index.d.ts.map +1 -0
  155. package/dist/svelte/index.js +2 -0
  156. package/dist/svelte/styles.css +8 -0
  157. package/dist/svelte/tool-widgets/ApiRequestToolCard.svelte +53 -0
  158. package/dist/svelte/tool-widgets/ApiRequestToolCard.svelte.d.ts +5 -0
  159. package/dist/svelte/tool-widgets/ApiRequestToolCard.svelte.d.ts.map +1 -0
  160. package/dist/svelte/tool-widgets/index.d.ts +2 -0
  161. package/dist/svelte/tool-widgets/index.d.ts.map +1 -0
  162. package/dist/svelte/tool-widgets/index.js +1 -0
  163. package/dist/tools/api-request/api-request.contract.d.ts +19 -0
  164. package/dist/tools/api-request/api-request.contract.d.ts.map +1 -0
  165. package/dist/tools/api-request/api-request.contract.js +110 -0
  166. package/dist/tools/api-request/api-request.contract.js.map +1 -0
  167. package/dist/tools/api-request/api-request.descriptor.d.ts +11 -4
  168. package/dist/tools/api-request/api-request.descriptor.d.ts.map +1 -1
  169. package/dist/tools/api-request/api-request.descriptor.js +8 -5
  170. package/dist/tools/api-request/api-request.descriptor.js.map +1 -1
  171. package/dist/tools/api-request/api-request.impl.cloud.d.ts +15 -0
  172. package/dist/tools/api-request/api-request.impl.cloud.d.ts.map +1 -0
  173. package/dist/tools/api-request/api-request.impl.cloud.js +75 -0
  174. package/dist/tools/api-request/api-request.impl.cloud.js.map +1 -0
  175. package/dist/tools/api-request/api-request.impl.consumer.d.ts +5 -3
  176. package/dist/tools/api-request/api-request.impl.consumer.d.ts.map +1 -1
  177. package/dist/tools/api-request/api-request.impl.consumer.js +27 -33
  178. package/dist/tools/api-request/api-request.impl.consumer.js.map +1 -1
  179. package/dist/tools/api-request/api-request.view.d.ts +29 -0
  180. package/dist/tools/api-request/api-request.view.d.ts.map +1 -0
  181. package/dist/tools/api-request/api-request.view.js +62 -0
  182. package/dist/tools/api-request/api-request.view.js.map +1 -0
  183. package/dist/tools/api-request/schemas/index.d.ts +12 -5
  184. package/dist/tools/api-request/schemas/index.d.ts.map +1 -1
  185. package/dist/tools/api-request/schemas/index.js +24 -6
  186. package/dist/tools/api-request/schemas/index.js.map +1 -1
  187. package/dist/tui/client-tui.plugin.d.ts +3 -0
  188. package/dist/tui/client-tui.plugin.d.ts.map +1 -0
  189. package/dist/tui/client-tui.plugin.js +32 -0
  190. package/dist/tui/client-tui.plugin.js.map +1 -0
  191. package/dist/tui/index.d.ts +2 -0
  192. package/dist/tui/index.d.ts.map +1 -0
  193. package/dist/tui/index.js +2 -0
  194. package/dist/tui/index.js.map +1 -0
  195. package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.d.ts +17 -0
  196. package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.d.ts.map +1 -0
  197. package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.js +28 -0
  198. package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.js.map +1 -0
  199. package/dist/validated-request.d.ts +27 -0
  200. package/dist/validated-request.d.ts.map +1 -0
  201. package/dist/validated-request.js +119 -0
  202. package/dist/validated-request.js.map +1 -0
  203. package/package.json +188 -41
  204. package/dist/lib/client/internal/node/http2-fetch.node.d.ts +0 -2
  205. package/dist/lib/client/internal/node/http2-fetch.node.d.ts.map +0 -1
  206. package/dist/lib/client/internal/node/http2-fetch.node.js +0 -131
  207. package/dist/lib/client/internal/node/http2-fetch.node.js.map +0 -1
  208. package/dist/lib/client/node.d.ts +0 -5
  209. package/dist/lib/client/node.d.ts.map +0 -1
  210. package/dist/lib/client/node.js +0 -33
  211. package/dist/lib/client/node.js.map +0 -1
  212. package/dist/tools/api-request/index.d.ts +0 -5
  213. package/dist/tools/api-request/index.d.ts.map +0 -1
  214. package/dist/tools/api-request/index.js +0 -4
  215. package/dist/tools/api-request/index.js.map +0 -1
  216. package/src/factory.ts +0 -114
  217. package/src/index.ts +0 -15
  218. package/src/lib/client/core.ts +0 -13
  219. package/src/lib/client/internal/base-client.ts +0 -107
  220. package/src/lib/client/internal/base-helpers.ts +0 -74
  221. package/src/lib/client/internal/base-types.ts +0 -42
  222. package/src/lib/client/internal/endpoint.ts +0 -51
  223. package/src/lib/client/internal/generator.ts +0 -181
  224. package/src/lib/client/internal/index.ts +0 -4
  225. package/src/lib/client/internal/node/http2-fetch.node.ts +0 -138
  226. package/src/lib/client/internal/request-builder.ts +0 -147
  227. package/src/lib/client/internal/sse-stream.ts +0 -130
  228. package/src/lib/client/internal/vibes-client.ts +0 -167
  229. package/src/lib/client/internal/wrap-fetch.ts +0 -59
  230. package/src/lib/client/node.ts +0 -36
  231. package/src/lib/client/types.ts +0 -156
  232. package/src/plugin.ts +0 -104
  233. package/src/schemas.ts +0 -91
  234. package/src/sse-client.ts +0 -155
  235. package/src/tools/api-request/api-request.descriptor.ts +0 -28
  236. package/src/tools/api-request/api-request.impl.consumer.ts +0 -66
  237. package/src/tools/api-request/index.ts +0 -4
  238. package/src/tools/api-request/schemas/index.ts +0 -29
@@ -1,173 +1,125 @@
1
+ import * as z from 'zod/v4';
2
+ import { CapabilityError, CaughtFailureSchema } from '@vibesdotdev/kernel';
3
+ import { ClientError } from "../types.js";
4
+ import { readClientValue, JsonValueSchema, QuerySchema } from "./client-values.js";
5
+ const ParameterSchema = z.object({ name: z.string().min(1), in: z.string().min(1) });
6
+ const OperationSchema = z.object({
7
+ operationId: z.string().optional(), parameters: z.array(ParameterSchema).optional(),
8
+ requestBody: z.record(z.string(), JsonValueSchema).optional(), responses: z.record(z.string(), JsonValueSchema),
9
+ tags: z.array(z.string()).optional(), summary: z.string().optional(), description: z.string().optional()
10
+ });
11
+ const PathItemSchema = z.object({
12
+ parameters: z.array(ParameterSchema).optional(), get: OperationSchema.optional(), post: OperationSchema.optional(),
13
+ put: OperationSchema.optional(), patch: OperationSchema.optional(), delete: OperationSchema.optional(),
14
+ head: OperationSchema.optional(), options: OperationSchema.optional()
15
+ });
16
+ export const OpenAPISpecSchema = z.object({ paths: z.record(z.string(), PathItemSchema).optional() });
1
17
  export class APIGenerator {
2
18
  requestBuilder;
3
19
  constructor(requestBuilder) {
4
20
  this.requestBuilder = requestBuilder;
5
21
  }
6
22
  generateAPIs(spec) {
7
- const resources = this.groupPathsByResource(spec);
8
- const apis = {};
9
- for (const resource of resources.values()) {
10
- apis[resource.name] = this.createResourceAPI(resource);
11
- }
12
- return apis;
23
+ const parsed = readClientValue(OpenAPISpecSchema, spec, 'client-openapi-invalid');
24
+ return Object.fromEntries([...this.groupPathsByResource(parsed)].map(([name, resource]) => [name, this.createResourceAPI(resource)]));
13
25
  }
14
26
  groupPathsByResource(spec) {
15
27
  const resources = new Map();
16
- for (const [path, pathItem] of Object.entries(spec.paths || {})) {
17
- if (!pathItem || typeof pathItem !== 'object')
18
- continue;
19
- const resourceName = this.extractResourceName(path);
20
- if (!resourceName)
28
+ for (const [path, pathItem] of Object.entries(spec.paths ?? {})) {
29
+ const parts = path.split('/').filter(Boolean);
30
+ if (parts[0] !== 'api' || parts.length < 2)
21
31
  continue;
22
- let resource = resources.get(resourceName);
32
+ const name = this.toCamelCase(parts[1]);
33
+ let resource = resources.get(name);
23
34
  if (!resource) {
24
- resource = {
25
- name: resourceName,
26
- basePath: this.extractBasePath(path, resourceName),
27
- operations: new Map()
28
- };
29
- resources.set(resourceName, resource);
35
+ resource = { name, basePath: `/api/${parts[1]}`, operations: new Map() };
36
+ resources.set(name, resource);
30
37
  }
31
- const methods = ['get', 'post', 'put', 'patch', 'delete'];
32
- for (const method of methods) {
33
- const operation = pathItem[method];
34
- if (operation && typeof operation === 'object' && 'responses' in operation) {
35
- const op = operation;
36
- const pi = pathItem;
37
- const opParams = (op.parameters || []);
38
- const piParams = (pi.parameters || []);
39
- const pathInfo = {
40
- path,
41
- method: method.toUpperCase(),
42
- operationId: op.operationId,
43
- parameters: [...piParams, ...opParams],
44
- requestBody: op.requestBody,
45
- responses: op.responses,
46
- tags: op.tags,
47
- summary: op.summary,
48
- description: op.description
49
- };
50
- const operationName = this.getOperationName(pathInfo);
51
- resource.operations.set(operationName, pathInfo);
52
- }
38
+ for (const method of ['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) {
39
+ const op = pathItem[method];
40
+ if (!op)
41
+ continue;
42
+ const parameters = new Map([...(pathItem.parameters ?? []), ...(op.parameters ?? [])].map(p => [`${p.in}:${p.name}`, p]));
43
+ const info = { ...op, path, method: method.toUpperCase(), parameters: [...parameters.values()] };
44
+ let operationName = this.getOperationName(info);
45
+ if (resource.operations.has(operationName))
46
+ operationName = op.operationId ?? this.toCamelCase(`${method}-${parts.slice(2).join('-').replace(/[{}]/g, '')}`);
47
+ if (resource.operations.has(operationName))
48
+ throw new CapabilityError('OpenAPI operations have conflicting names.', 'INVALID_INPUT', { reason: 'client-operation-name-conflict' });
49
+ resource.operations.set(operationName, info);
53
50
  }
54
51
  }
55
52
  return resources;
56
53
  }
57
- extractResourceName(path) {
58
- const segments = path.split('/').filter(Boolean);
59
- if (segments[0] !== 'api' || segments.length < 2)
60
- return null;
61
- return this.toCamelCase(segments[1]);
62
- }
63
- extractBasePath(path, resourceName) {
64
- const match = path.match(/^(\/api\/[^/]+)/);
65
- return match ? match[1] : `/api/${resourceName}`;
66
- }
67
- getOperationName(pathInfo) {
68
- const pathParts = pathInfo.path.split('/').filter(Boolean);
69
- const method = pathInfo.method.toLowerCase();
70
- const hasPathParam = pathInfo.path.includes('{');
71
- const resourceName = pathParts[1];
72
- if (method === 'get' && !hasPathParam) {
73
- return pathInfo.operationId?.toLowerCase().includes('list') ? 'list' : 'list';
74
- }
75
- if (method === 'get' && hasPathParam)
54
+ getOperationName(info) {
55
+ const parts = info.path.split('/').filter(Boolean), method = info.method.toLowerCase(), parameter = info.path.includes('{');
56
+ if (method === 'get' && !parameter)
57
+ return 'list';
58
+ if (method === 'get' && parameter)
76
59
  return 'get';
77
- if (method === 'post' && !hasPathParam)
60
+ if (method === 'post' && !parameter)
78
61
  return 'create';
79
- if ((method === 'put' || method === 'patch') && hasPathParam)
62
+ if ((method === 'put' || method === 'patch') && parameter)
80
63
  return 'update';
81
- if (method === 'delete' && hasPathParam)
64
+ if (method === 'delete' && parameter)
82
65
  return 'delete';
83
- if (pathInfo.operationId) {
84
- let opName = pathInfo.operationId;
85
- if (resourceName && opName.toLowerCase().startsWith(resourceName.slice(0, -1))) {
86
- opName = opName.slice(resourceName.length - 1);
87
- }
88
- return this.toCamelCase(opName);
89
- }
90
- const lastPart = pathParts[pathParts.length - 1];
91
- if (!lastPart.startsWith('{'))
92
- return this.toCamelCase(lastPart);
93
- return method;
66
+ if (info.operationId)
67
+ return this.toCamelCase(info.operationId);
68
+ const last = parts.at(-1) ?? method;
69
+ return last.startsWith('{') ? method : this.toCamelCase(last);
94
70
  }
95
71
  createResourceAPI(resource) {
96
- const api = {};
97
- for (const [name, pathInfo] of resource.operations) {
98
- api[name] = this.createOperation(pathInfo);
72
+ const api = Object.fromEntries([...resource.operations].map(([name, info]) => [name, (...args) => this.requestBuilder.request(this.buildRequestOptions(info, args))]));
73
+ if (Object.hasOwn(api, 'list') && !Object.hasOwn(api, 'search')) {
74
+ const list = api.list;
75
+ api.search = (search, params) => list({ ...readClientValue(QuerySchema, params ?? {}, 'client-query-invalid'),
76
+ search: readClientValue(z.string(), search, 'client-search-invalid') });
99
77
  }
100
- this.addConvenienceMethods(api, resource);
101
- return api;
102
- }
103
- createOperation(pathInfo) {
104
- return (...args) => {
105
- const options = this.buildRequestOptions(pathInfo, args);
106
- return this.requestBuilder.request(options);
107
- };
108
- }
109
- buildRequestOptions(pathInfo, args) {
110
- const options = { method: pathInfo.method, path: pathInfo.path };
111
- const params = {};
112
- const query = {};
113
- let body;
114
- let argIndex = 0;
115
- if (pathInfo.parameters) {
116
- for (const param of pathInfo.parameters) {
117
- if (param.in === 'path' && argIndex < args.length) {
118
- params[param.name] = args[argIndex++];
119
- }
120
- }
121
- }
122
- if (argIndex < args.length) {
123
- const nextArg = args[argIndex];
124
- if (typeof nextArg === 'object' && nextArg !== null) {
125
- if (pathInfo.method === 'GET' || pathInfo.method === 'DELETE') {
126
- Object.assign(query, nextArg);
78
+ if (Object.hasOwn(api, 'get') && Object.hasOwn(api, 'create') && !Object.hasOwn(api, 'getOrCreate')) {
79
+ const get = api.get, create = api.create;
80
+ const path = resource.operations.get('get')?.path ?? '';
81
+ api.getOrCreate = async (id, data) => {
82
+ const key = readClientValue(z.union([z.string(), z.number(), z.boolean()]), id, 'client-path-parameter-invalid');
83
+ try {
84
+ return await get(key);
127
85
  }
128
- else {
129
- body = nextArg;
130
- argIndex++;
131
- if (argIndex < args.length && typeof args[argIndex] === 'object') {
132
- Object.assign(query, args[argIndex]);
133
- }
86
+ catch (error) {
87
+ const failure = CaughtFailureSchema.parse(error);
88
+ if (!(failure instanceof ClientError && CapabilityError.isAbsenceOf(failure, 'api/resource', path)))
89
+ throw failure;
90
+ return create({ ...readClientValue(z.record(z.string(), JsonValueSchema), data, 'client-create-invalid'), id: key });
134
91
  }
135
- }
92
+ };
136
93
  }
137
- if (Object.keys(params).length > 0)
138
- options.params = params;
139
- if (Object.keys(query).length > 0)
140
- options.query = query;
141
- if (body !== undefined)
142
- options.body = body;
143
- return options;
94
+ return api;
144
95
  }
145
- addConvenienceMethods(api, _resource) {
146
- if (api.list && !api.search) {
147
- api.search = ((query, params) => {
148
- return api.list({ ...params, search: query });
149
- });
96
+ buildRequestOptions(info, args) {
97
+ const options = { method: info.method, path: info.path };
98
+ let index = 0;
99
+ const params = new Map();
100
+ for (const parameter of info.parameters ?? []) {
101
+ if (parameter.in === 'path')
102
+ params.set(parameter.name, readClientValue(z.union([z.string(), z.number().finite(), z.boolean()]), args[index++], 'client-path-parameter-invalid'));
150
103
  }
151
- if (api.get && api.create && !api.getOrCreate) {
152
- api.getOrCreate = (async (id, data) => {
153
- try {
154
- return await api.get(id);
155
- }
156
- catch (error) {
157
- const status = error.status;
158
- if (status === 404) {
159
- const record = data;
160
- return await api.create(Object.assign({}, record, { id }));
161
- }
162
- throw error;
163
- }
164
- });
104
+ if (params.size)
105
+ options.params = Object.fromEntries(params);
106
+ if (info.method === 'GET' || info.method === 'DELETE' || info.method === 'HEAD') {
107
+ if (index < args.length)
108
+ options.query = readClientValue(QuerySchema, args[index++], 'client-query-invalid');
109
+ }
110
+ else {
111
+ if (index < args.length)
112
+ options.body = readClientValue(JsonValueSchema, args[index++], 'client-body-invalid');
113
+ if (index < args.length)
114
+ options.query = readClientValue(QuerySchema, args[index++], 'client-query-invalid');
165
115
  }
116
+ if (index < args.length)
117
+ throw new CapabilityError('Too many generated operation arguments.', 'INVALID_INPUT', { reason: 'client-operation-arguments-invalid' });
118
+ return options;
166
119
  }
167
- toCamelCase(str) {
168
- return str
169
- .replace(/[-_](.)/g, (_, char) => char.toUpperCase())
170
- .replace(/^(.)/, (_, char) => char.toLowerCase());
120
+ toCamelCase(text) {
121
+ return text.split(/[-_]/).map((part, index) => index ? part.charAt(0).toUpperCase() + part.slice(1) : part).join('')
122
+ .replace(/^./, character => character.toLowerCase());
171
123
  }
172
124
  }
173
125
  //# sourceMappingURL=generator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/lib/client/internal/generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/lib/client/internal/generator.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,18 @@
1
+ import { type RuntimeRef } from '@vibesdotdev/kernel';
1
2
  import { type AuthConfig, type RequestOptions } from '../types.ts';
3
+ import { type ClientFetch } from './client-values.ts';
2
4
  export declare class RequestBuilder {
3
5
  private baseUrl;
4
6
  private auth;
5
7
  private fetchImpl;
6
8
  private timeout;
7
9
  private debug;
8
- constructor(baseUrl: string, auth: AuthConfig, fetchImpl: typeof fetch, timeout?: number, debug?: boolean);
10
+ private runtime?;
11
+ private readonly logger;
12
+ constructor(baseUrl: string, auth: AuthConfig, fetchImpl: ClientFetch, timeout?: number, debug?: boolean, runtime?: RuntimeRef | undefined);
9
13
  request<T = unknown>(options: RequestOptions): Promise<T>;
10
14
  private buildUrl;
11
15
  private buildHeaders;
12
- private createAbortSignal;
13
16
  private createError;
14
17
  }
15
18
  //# sourceMappingURL=request-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-builder.d.ts","sourceRoot":"","sources":["../../../../src/lib/client/internal/request-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhF,qBAAa,cAAc;IAEzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK;gBAJL,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,OAAO,KAAK,EACvB,OAAO,GAAE,MAAc,EACvB,KAAK,GAAE,OAAe;IAGzB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAqD/D,OAAO,CAAC,QAAQ;YAkBF,YAAY;IAsB1B,OAAO,CAAC,iBAAiB;YAMX,WAAW;CAoCzB"}
1
+ {"version":3,"file":"request-builder.d.ts","sourceRoot":"","sources":["../../../../src/lib/client/internal/request-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAO3E,OAAO,EAAe,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAgI,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQpL,qBAAa,cAAc;IAGzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO,CAAC;IAPjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;gBAEzD,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,GAAE,MAAc,EACvB,KAAK,GAAE,OAAe,EACtB,OAAO,CAAC,EAAE,UAAU,YAAA;IAMvB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IA8E/D,OAAO,CAAC,QAAQ;YAkBF,YAAY;YAWZ,WAAW;CAiDzB"}
@@ -1,78 +1,119 @@
1
+ import { CaughtFailureSchema } from '@vibesdotdev/kernel';
2
+ import { emitClientAuthRejected } from "../../../events/auth-rejected.event.js";
3
+ import { redactedExcerpt, urlRedactions } from '@vibesdotdev/shared/utils';
4
+ import { getLogger } from '@vibesdotdev/logging';
5
+ import * as z from 'zod/v4';
6
+ import { createTimeoutSignal } from "./timeout-signal.js";
7
+ import { buildAuthHeaders } from "./auth-headers.js";
1
8
  import { ClientError } from "../types.js";
9
+ import { readClientValue, readClientFields, encodeClientBody, NativeBodySchema, JsonValueSchema, RequestInputSchema, HttpOriginSchema } from "./client-values.js";
10
+ /**
11
+ * Error payloads arrive as untyped JSON; fields are decoded per use below
12
+ * instead of asserted, so a malformed body degrades to the status text.
13
+ */
14
+ const ErrorRecordSchema = z.record(z.string(), JsonValueSchema);
2
15
  export class RequestBuilder {
3
16
  baseUrl;
4
17
  auth;
5
18
  fetchImpl;
6
19
  timeout;
7
20
  debug;
8
- constructor(baseUrl, auth, fetchImpl, timeout = 30000, debug = false) {
21
+ runtime;
22
+ logger;
23
+ constructor(baseUrl, auth, fetchImpl, timeout = 30000, debug = false, runtime) {
9
24
  this.baseUrl = baseUrl;
10
25
  this.auth = auth;
11
26
  this.fetchImpl = fetchImpl;
12
27
  this.timeout = timeout;
13
28
  this.debug = debug;
29
+ this.runtime = runtime;
30
+ readClientValue(HttpOriginSchema, baseUrl, 'client-origin-invalid');
31
+ this.logger = runtime ? getLogger('client', runtime) : undefined;
14
32
  }
15
33
  async request(options) {
34
+ options = readClientValue(RequestInputSchema, options, 'client-request-invalid');
16
35
  const url = this.buildUrl(options);
17
36
  const headers = await this.buildHeaders(options);
37
+ const deadline = createTimeoutSignal(this.runtime, options.timeout ?? this.timeout);
18
38
  const init = {
19
39
  method: options.method,
20
40
  headers,
21
- signal: this.createAbortSignal(options.timeout || this.timeout)
41
+ signal: deadline.signal
22
42
  };
23
- if (options.body !== undefined) {
24
- if (headers.get('Content-Type')?.includes('application/json'))
25
- init.body = JSON.stringify(options.body);
26
- else
27
- init.body = options.body;
28
- }
29
- const shouldLog = this.debug || url.pathname.includes('/auth/');
43
+ const shouldLog = this.debug;
30
44
  if (shouldLog) {
31
- console.info('[Client] Request:', {
32
- url: url.toString(),
45
+ this.logger?.info('Client request', {
33
46
  method: options.method,
34
- headers: Object.fromEntries(headers.entries()),
35
- body: options.body
47
+ headerNames: [...headers.keys()],
48
+ queryCount: [...url.searchParams].length,
49
+ hasBody: options.body !== undefined
36
50
  });
37
51
  }
38
52
  try {
39
- const response = await this.fetchImpl(url.toString(), init);
53
+ if (options.body !== undefined)
54
+ init.body = encodeClientBody(options.body, headers.get('Content-Type'));
55
+ let response = await this.fetchImpl(url.toString(), init);
56
+ const refresh = readClientFields(() => this.auth.refreshHandler, 'client-auth-unreadable');
57
+ if (response.status === 401 && refresh && !(options.body instanceof ReadableStream)) {
58
+ await response.body?.cancel();
59
+ const refreshed = await refresh();
60
+ if (refreshed) {
61
+ this.auth = { ...readClientFields(() => ({ ...refreshed }), 'client-auth-unreadable'), refreshHandler: refresh };
62
+ init.headers = await this.buildHeaders(options);
63
+ response = await this.fetchImpl(url.toString(), init);
64
+ }
65
+ }
40
66
  if (shouldLog) {
41
- console.info('[Client] Response:', {
67
+ this.logger?.info('Client response', {
42
68
  status: response.status,
43
- statusText: response.statusText,
44
- headers: Object.fromEntries(response.headers.entries())
69
+ headerNames: [...response.headers.keys()]
45
70
  });
46
71
  }
72
+ if ((response.status === 401 || response.status === 403) && this.runtime) {
73
+ // The origin and status only: a credential's owner drops what it cached for it.
74
+ await emitClientAuthRejected(this.runtime, { origin: url.origin, status: response.status });
75
+ }
47
76
  if (!response.ok)
48
- throw await this.createError(response, options);
77
+ throw await this.createError(response, options, new Headers(init.headers));
49
78
  if (response.status === 204 || response.headers.get('Content-Length') === '0')
79
+ // SAFETY: Empty responses carry no payload; the caller decodes `undefined` as its own absent value.
50
80
  return undefined;
51
81
  const contentType = response.headers.get('Content-Type');
52
- if (contentType?.includes('application/json'))
53
- return (await response.json());
82
+ if (contentType?.includes('application/json')) {
83
+ // SAFETY: The caller owns the decoded JSON shape; the generic binds it at the call site.
84
+ return readClientValue(JsonValueSchema, await response.json(), 'client-response-invalid');
85
+ }
86
+ // SAFETY: Non-JSON responses decode as text; the caller binds `T` to the string form.
54
87
  return (await response.text());
55
88
  }
56
89
  catch (error) {
90
+ const failure = CaughtFailureSchema.parse(error);
57
91
  if (this.debug) {
58
- console.error('[Client] Request failed:', {
59
- url: url.toString(),
92
+ this.logger?.error('Client request failed', {
60
93
  method: options.method,
61
- error: error instanceof Error ? error.message : String(error),
62
- errorName: error instanceof Error ? error.name : undefined
94
+ queryCount: [...url.searchParams].length,
95
+ failureType: failure instanceof ClientError ? 'client-error' : 'transport-error',
96
+ status: failure instanceof ClientError ? failure.status : undefined,
97
+ code: failure instanceof ClientError ? failure.code : undefined
63
98
  });
64
99
  }
65
- if (error instanceof Error && error.name === 'AbortError') {
66
- throw new ClientError('Request timeout', 408, undefined, options);
100
+ if (failure instanceof Error &&
101
+ (failure.name === 'AbortError' || failure.name === 'TimeoutError')) {
102
+ throw new ClientError('Request timeout', 408, undefined, options, { cause: failure });
67
103
  }
68
- throw error;
104
+ if (failure instanceof ClientError)
105
+ throw failure;
106
+ throw new ClientError('The client transport failed.', 0, undefined, options, { cause: failure });
107
+ }
108
+ finally {
109
+ deadline.dispose();
69
110
  }
70
111
  }
71
112
  buildUrl(options) {
72
113
  let path = options.path;
73
114
  if (options.params) {
74
115
  for (const [key, value] of Object.entries(options.params)) {
75
- path = path.replace(`{${key}}`, encodeURIComponent(String(value)));
116
+ path = path.replaceAll(`{${key}}`, encodeURIComponent(String(value))).replaceAll(`:${key}`, encodeURIComponent(String(value)));
76
117
  }
77
118
  }
78
119
  const url = new URL(path, this.baseUrl);
@@ -90,57 +131,50 @@ export class RequestBuilder {
90
131
  }
91
132
  async buildHeaders(options) {
92
133
  const headers = new Headers(options.headers);
93
- if (!headers.has('Content-Type') && options.body !== undefined)
134
+ if (!headers.has('Content-Type') && options.body !== undefined && !NativeBodySchema.safeParse(options.body).success)
94
135
  headers.set('Content-Type', 'application/json');
95
136
  if (!headers.has('Accept'))
96
137
  headers.set('Accept', 'application/json');
97
- if (this.auth.type !== 'none') {
98
- const token = this.auth.credentials || (await this.auth.tokenProvider?.());
99
- if (token) {
100
- switch (this.auth.type) {
101
- case 'apiKey':
102
- case 'bearer':
103
- headers.set('Authorization', `Bearer ${token}`);
104
- break;
105
- case 'session':
106
- headers.set('Cookie', `session=${token}`);
107
- break;
108
- }
109
- }
110
- }
138
+ // Auth headers come from the canonical mapping shared with the stream transport.
139
+ const authHeaders = await buildAuthHeaders(this.auth);
140
+ for (const [name, value] of Object.entries(authHeaders))
141
+ headers.set(name, value);
111
142
  return headers;
112
143
  }
113
- createAbortSignal(timeout) {
114
- const controller = new AbortController();
115
- setTimeout(() => controller.abort(), timeout);
116
- return controller.signal;
117
- }
118
- async createError(response, request) {
144
+ async createError(response, request, headers) {
119
145
  let message = `${response.status} ${response.statusText}`;
146
+ const secrets = [...urlRedactions(this.buildUrl(request).href), this.auth.credentials ?? '', ...[...headers.values()].flatMap(value => [value, value.replace(/^Bearer /, '')])];
147
+ const safeMessage = () => redactedExcerpt(message, { maxChars: 2000, secrets });
120
148
  try {
121
149
  const contentType = response.headers.get('Content-Type');
122
150
  if (contentType?.includes('application/json')) {
123
- const error = await response.json();
124
- const validationErrors = error.issues ??
125
- error.errors;
151
+ const parsed = ErrorRecordSchema.safeParse(await response.json());
152
+ const body = parsed.success ? parsed.data : {};
153
+ const validationErrors = body.issues ?? body.errors;
126
154
  if (Array.isArray(validationErrors) && validationErrors.length > 0) {
127
155
  const fieldErrors = validationErrors
128
156
  .map((issue) => {
129
- const rec = issue;
130
- const path = Array.isArray(rec.path) && rec.path.length > 0
131
- ? rec.path.map(String).join('.')
157
+ const entry = ErrorRecordSchema.safeParse(issue);
158
+ const record = entry.success ? entry.data : {};
159
+ const pathParts = z.array(z.union([z.string(), z.number()])).safeParse(record.path);
160
+ const path = pathParts.success && pathParts.data.length > 0
161
+ ? pathParts.data.map(String).join('.')
132
162
  : 'unknown';
133
- return ` - ${path}: ${typeof rec.message === 'string' ? rec.message : 'Invalid'}`;
163
+ const text = z.string().safeParse(record.message);
164
+ return ` - ${path}: ${text.success ? text.data : 'Invalid'}`;
134
165
  })
135
166
  .join('\n');
136
167
  message = `Validation failed:\n${fieldErrors}`;
137
168
  }
138
- else if (typeof error.message === 'string') {
139
- message = error.message;
140
- }
141
- else if (error.error !== undefined) {
142
- const e = error.error;
143
- message = typeof e === 'string' ? e : JSON.stringify(e);
169
+ else {
170
+ const messageText = z.string().safeParse(body.message);
171
+ if (messageText.success) {
172
+ message = messageText.data;
173
+ }
174
+ else if (body.error !== undefined) {
175
+ const errorText = z.string().safeParse(body.error);
176
+ message = errorText.success ? errorText.data : JSON.stringify(body.error);
177
+ }
144
178
  }
145
179
  }
146
180
  else {
@@ -149,10 +183,16 @@ export class RequestBuilder {
149
183
  message = text;
150
184
  }
151
185
  }
152
- catch {
153
- // ignore parsing errors
186
+ catch (error) {
187
+ // Preserve the HTTP failure when its body cannot be consumed.
188
+ const failure = CaughtFailureSchema.parse(error);
189
+ this.logger?.warn('Could not parse error response body', {
190
+ status: response.status,
191
+ bodyReadFailed: true
192
+ });
193
+ return new ClientError(safeMessage(), response.status, response, request, { cause: failure });
154
194
  }
155
- return new ClientError(message, response.status, response, request);
195
+ return new ClientError(safeMessage(), response.status, response, request);
156
196
  }
157
197
  }
158
198
  //# sourceMappingURL=request-builder.js.map