@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.
- package/LICENSE +21 -0
- package/README.md +24 -15
- package/dist/api-client-plugin.d.ts +4 -0
- package/dist/api-client-plugin.d.ts.map +1 -0
- package/dist/api-client-plugin.js +20 -0
- package/dist/api-client-plugin.js.map +1 -0
- package/dist/api-client.impl.d.ts +23 -0
- package/dist/api-client.impl.d.ts.map +1 -0
- package/dist/api-client.impl.js +47 -0
- package/dist/api-client.impl.js.map +1 -0
- package/dist/client.consumer.plugin.d.ts +3 -0
- package/dist/client.consumer.plugin.d.ts.map +1 -0
- package/dist/client.consumer.plugin.js +10 -0
- package/dist/client.consumer.plugin.js.map +1 -0
- package/dist/cloud.plugin.d.ts +3 -0
- package/dist/cloud.plugin.d.ts.map +1 -0
- package/dist/cloud.plugin.js +10 -0
- package/dist/cloud.plugin.js.map +1 -0
- package/dist/config/client.config.descriptor.d.ts +4 -0
- package/dist/config/client.config.descriptor.d.ts.map +1 -0
- package/dist/config/client.config.descriptor.js +32 -0
- package/dist/config/client.config.descriptor.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/settings.d.ts +9 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +25 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/docs/client.api-request.docs.descriptor.d.ts +4 -0
- package/dist/docs/client.api-request.docs.descriptor.d.ts.map +1 -0
- package/dist/docs/client.api-request.docs.descriptor.js +71 -0
- package/dist/docs/client.api-request.docs.descriptor.js.map +1 -0
- package/dist/events/auth-rejected.event.d.ts +35 -0
- package/dist/events/auth-rejected.event.d.ts.map +1 -0
- package/dist/events/auth-rejected.event.js +36 -0
- package/dist/events/auth-rejected.event.js.map +1 -0
- package/dist/factory.d.ts +5 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +16 -17
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/kind-augment.d.ts +11 -0
- package/dist/kind-augment.d.ts.map +1 -0
- package/dist/kind-augment.js +2 -0
- package/dist/kind-augment.js.map +1 -0
- package/dist/lib/client/api-diagnostics.d.ts +79 -0
- package/dist/lib/client/api-diagnostics.d.ts.map +1 -0
- package/dist/lib/client/api-diagnostics.js +111 -0
- package/dist/lib/client/api-diagnostics.js.map +1 -0
- package/dist/lib/client/configured.d.ts +78 -0
- package/dist/lib/client/configured.d.ts.map +1 -0
- package/dist/lib/client/configured.js +261 -0
- package/dist/lib/client/configured.js.map +1 -0
- package/dist/lib/client/internal/auth-headers.d.ts +11 -0
- package/dist/lib/client/internal/auth-headers.d.ts.map +1 -0
- package/dist/lib/client/internal/auth-headers.js +35 -0
- package/dist/lib/client/internal/auth-headers.js.map +1 -0
- package/dist/lib/client/internal/base-client.d.ts +5 -2
- package/dist/lib/client/internal/base-client.d.ts.map +1 -1
- package/dist/lib/client/internal/base-client.js +42 -22
- package/dist/lib/client/internal/base-client.js.map +1 -1
- package/dist/lib/client/internal/base-helpers.d.ts.map +1 -1
- package/dist/lib/client/internal/base-helpers.js +20 -20
- package/dist/lib/client/internal/base-helpers.js.map +1 -1
- package/dist/lib/client/internal/base-types.d.ts +10 -5
- package/dist/lib/client/internal/base-types.d.ts.map +1 -1
- package/dist/lib/client/internal/base-types.js +5 -3
- package/dist/lib/client/internal/base-types.js.map +1 -1
- package/dist/lib/client/internal/client-values.d.ts +43 -0
- package/dist/lib/client/internal/client-values.d.ts.map +1 -0
- package/dist/lib/client/internal/client-values.js +76 -0
- package/dist/lib/client/internal/client-values.js.map +1 -0
- package/dist/lib/client/internal/endpoint.d.ts +6 -5
- package/dist/lib/client/internal/endpoint.d.ts.map +1 -1
- package/dist/lib/client/internal/endpoint.js +3 -0
- package/dist/lib/client/internal/endpoint.js.map +1 -1
- package/dist/lib/client/internal/generator.d.ts +98 -9
- package/dist/lib/client/internal/generator.d.ts.map +1 -1
- package/dist/lib/client/internal/generator.js +92 -140
- package/dist/lib/client/internal/generator.js.map +1 -1
- package/dist/lib/client/internal/request-builder.d.ts +5 -2
- package/dist/lib/client/internal/request-builder.d.ts.map +1 -1
- package/dist/lib/client/internal/request-builder.js +105 -65
- package/dist/lib/client/internal/request-builder.js.map +1 -1
- package/dist/lib/client/internal/sse-stream.d.ts +9 -5
- package/dist/lib/client/internal/sse-stream.d.ts.map +1 -1
- package/dist/lib/client/internal/sse-stream.js +96 -94
- package/dist/lib/client/internal/sse-stream.js.map +1 -1
- package/dist/lib/client/internal/timeout-signal.d.ts +8 -0
- package/dist/lib/client/internal/timeout-signal.d.ts.map +1 -0
- package/dist/lib/client/internal/timeout-signal.js +17 -0
- package/dist/lib/client/internal/timeout-signal.js.map +1 -0
- package/dist/lib/client/internal/transport/http2-fetch.d.ts +8 -0
- package/dist/lib/client/internal/transport/http2-fetch.d.ts.map +1 -0
- package/dist/lib/client/internal/transport/http2-fetch.js +17 -0
- package/dist/lib/client/internal/transport/http2-fetch.js.map +1 -0
- package/dist/lib/client/internal/vibes-client.d.ts +17 -8
- package/dist/lib/client/internal/vibes-client.d.ts.map +1 -1
- package/dist/lib/client/internal/vibes-client.js +127 -67
- package/dist/lib/client/internal/vibes-client.js.map +1 -1
- package/dist/lib/client/internal/wrap-fetch.d.ts +3 -2
- package/dist/lib/client/internal/wrap-fetch.d.ts.map +1 -1
- package/dist/lib/client/internal/wrap-fetch.js +14 -33
- package/dist/lib/client/internal/wrap-fetch.js.map +1 -1
- package/dist/lib/client/runtime-fetch.d.ts +14 -0
- package/dist/lib/client/runtime-fetch.d.ts.map +1 -0
- package/dist/lib/client/runtime-fetch.js +25 -0
- package/dist/lib/client/runtime-fetch.js.map +1 -0
- package/dist/lib/client/types.d.ts +18 -9
- package/dist/lib/client/types.d.ts.map +1 -1
- package/dist/lib/client/types.js +22 -3
- package/dist/lib/client/types.js.map +1 -1
- package/dist/plugin.d.ts +2 -18
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +7 -74
- package/dist/plugin.js.map +1 -1
- package/dist/runtime-client.d.ts +10 -0
- package/dist/runtime-client.d.ts.map +1 -0
- package/dist/runtime-client.js +14 -0
- package/dist/runtime-client.js.map +1 -0
- package/dist/schemas/auth-rejected.d.ts +12 -0
- package/dist/schemas/auth-rejected.d.ts.map +1 -0
- package/dist/schemas/auth-rejected.js +11 -0
- package/dist/schemas/auth-rejected.js.map +1 -0
- package/dist/schemas/sdk-languages.d.ts +47 -0
- package/dist/schemas/sdk-languages.d.ts.map +1 -0
- package/dist/schemas/sdk-languages.js +75 -0
- package/dist/schemas/sdk-languages.js.map +1 -0
- package/dist/schemas/settings.d.ts +14 -0
- package/dist/schemas/settings.d.ts.map +1 -0
- package/dist/schemas/settings.js +10 -0
- package/dist/schemas/settings.js.map +1 -0
- package/dist/schemas/validated-request.d.ts +19 -0
- package/dist/schemas/validated-request.d.ts.map +1 -0
- package/dist/schemas/validated-request.js +2 -0
- package/dist/schemas/validated-request.js.map +1 -0
- package/dist/schemas.d.ts +23 -8
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +8 -2
- package/dist/schemas.js.map +1 -1
- package/dist/sse-client.d.ts +17 -15
- package/dist/sse-client.d.ts.map +1 -1
- package/dist/sse-client.js +111 -91
- package/dist/sse-client.js.map +1 -1
- package/dist/svelte/client-svelte.plugin.d.ts +5 -0
- package/dist/svelte/client-svelte.plugin.d.ts.map +1 -0
- package/dist/svelte/client-svelte.plugin.js +46 -0
- package/dist/svelte/index.d.ts +3 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +2 -0
- package/dist/svelte/styles.css +8 -0
- package/dist/svelte/tool-widgets/ApiRequestToolCard.svelte +53 -0
- package/dist/svelte/tool-widgets/ApiRequestToolCard.svelte.d.ts +5 -0
- package/dist/svelte/tool-widgets/ApiRequestToolCard.svelte.d.ts.map +1 -0
- package/dist/svelte/tool-widgets/index.d.ts +2 -0
- package/dist/svelte/tool-widgets/index.d.ts.map +1 -0
- package/dist/svelte/tool-widgets/index.js +1 -0
- package/dist/tools/api-request/api-request.contract.d.ts +19 -0
- package/dist/tools/api-request/api-request.contract.d.ts.map +1 -0
- package/dist/tools/api-request/api-request.contract.js +110 -0
- package/dist/tools/api-request/api-request.contract.js.map +1 -0
- package/dist/tools/api-request/api-request.descriptor.d.ts +11 -4
- package/dist/tools/api-request/api-request.descriptor.d.ts.map +1 -1
- package/dist/tools/api-request/api-request.descriptor.js +8 -5
- package/dist/tools/api-request/api-request.descriptor.js.map +1 -1
- package/dist/tools/api-request/api-request.impl.cloud.d.ts +15 -0
- package/dist/tools/api-request/api-request.impl.cloud.d.ts.map +1 -0
- package/dist/tools/api-request/api-request.impl.cloud.js +75 -0
- package/dist/tools/api-request/api-request.impl.cloud.js.map +1 -0
- package/dist/tools/api-request/api-request.impl.consumer.d.ts +5 -3
- package/dist/tools/api-request/api-request.impl.consumer.d.ts.map +1 -1
- package/dist/tools/api-request/api-request.impl.consumer.js +27 -33
- package/dist/tools/api-request/api-request.impl.consumer.js.map +1 -1
- package/dist/tools/api-request/api-request.view.d.ts +29 -0
- package/dist/tools/api-request/api-request.view.d.ts.map +1 -0
- package/dist/tools/api-request/api-request.view.js +62 -0
- package/dist/tools/api-request/api-request.view.js.map +1 -0
- package/dist/tools/api-request/schemas/index.d.ts +12 -5
- package/dist/tools/api-request/schemas/index.d.ts.map +1 -1
- package/dist/tools/api-request/schemas/index.js +24 -6
- package/dist/tools/api-request/schemas/index.js.map +1 -1
- package/dist/tui/client-tui.plugin.d.ts +3 -0
- package/dist/tui/client-tui.plugin.d.ts.map +1 -0
- package/dist/tui/client-tui.plugin.js +32 -0
- package/dist/tui/client-tui.plugin.js.map +1 -0
- package/dist/tui/index.d.ts +2 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +2 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.d.ts +17 -0
- package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.d.ts.map +1 -0
- package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.js +28 -0
- package/dist/tui/tool-widgets/ApiRequestToolWidget.impl.tui.js.map +1 -0
- package/dist/validated-request.d.ts +27 -0
- package/dist/validated-request.d.ts.map +1 -0
- package/dist/validated-request.js +119 -0
- package/dist/validated-request.js.map +1 -0
- package/package.json +188 -41
- package/dist/lib/client/internal/node/http2-fetch.node.d.ts +0 -2
- package/dist/lib/client/internal/node/http2-fetch.node.d.ts.map +0 -1
- package/dist/lib/client/internal/node/http2-fetch.node.js +0 -131
- package/dist/lib/client/internal/node/http2-fetch.node.js.map +0 -1
- package/dist/lib/client/node.d.ts +0 -5
- package/dist/lib/client/node.d.ts.map +0 -1
- package/dist/lib/client/node.js +0 -33
- package/dist/lib/client/node.js.map +0 -1
- package/dist/tools/api-request/index.d.ts +0 -5
- package/dist/tools/api-request/index.d.ts.map +0 -1
- package/dist/tools/api-request/index.js +0 -4
- package/dist/tools/api-request/index.js.map +0 -1
- package/src/factory.ts +0 -114
- package/src/index.ts +0 -15
- package/src/lib/client/core.ts +0 -13
- package/src/lib/client/internal/base-client.ts +0 -107
- package/src/lib/client/internal/base-helpers.ts +0 -74
- package/src/lib/client/internal/base-types.ts +0 -42
- package/src/lib/client/internal/endpoint.ts +0 -51
- package/src/lib/client/internal/generator.ts +0 -181
- package/src/lib/client/internal/index.ts +0 -4
- package/src/lib/client/internal/node/http2-fetch.node.ts +0 -138
- package/src/lib/client/internal/request-builder.ts +0 -147
- package/src/lib/client/internal/sse-stream.ts +0 -130
- package/src/lib/client/internal/vibes-client.ts +0 -167
- package/src/lib/client/internal/wrap-fetch.ts +0 -59
- package/src/lib/client/node.ts +0 -36
- package/src/lib/client/types.ts +0 -156
- package/src/plugin.ts +0 -104
- package/src/schemas.ts +0 -91
- package/src/sse-client.ts +0 -155
- package/src/tools/api-request/api-request.descriptor.ts +0 -28
- package/src/tools/api-request/api-request.impl.consumer.ts +0 -66
- package/src/tools/api-request/index.ts +0 -4
- 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
|
|
8
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
-
|
|
32
|
+
const name = this.toCamelCase(parts[1]);
|
|
33
|
+
let resource = resources.get(name);
|
|
23
34
|
if (!resource) {
|
|
24
|
-
resource = {
|
|
25
|
-
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
60
|
-
return
|
|
61
|
-
|
|
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' && !
|
|
60
|
+
if (method === 'post' && !parameter)
|
|
78
61
|
return 'create';
|
|
79
|
-
if ((method === 'put' || method === 'patch') &&
|
|
62
|
+
if ((method === 'put' || method === 'patch') && parameter)
|
|
80
63
|
return 'update';
|
|
81
|
-
if (method === 'delete' &&
|
|
64
|
+
if (method === 'delete' && parameter)
|
|
82
65
|
return 'delete';
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
98
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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 (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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(
|
|
168
|
-
return
|
|
169
|
-
.replace(
|
|
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":"
|
|
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
|
-
|
|
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;
|
|
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
|
-
|
|
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:
|
|
41
|
+
signal: deadline.signal
|
|
22
42
|
};
|
|
23
|
-
|
|
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
|
-
|
|
32
|
-
url: url.toString(),
|
|
45
|
+
this.logger?.info('Client request', {
|
|
33
46
|
method: options.method,
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
headerNames: [...headers.keys()],
|
|
48
|
+
queryCount: [...url.searchParams].length,
|
|
49
|
+
hasBody: options.body !== undefined
|
|
36
50
|
});
|
|
37
51
|
}
|
|
38
52
|
try {
|
|
39
|
-
|
|
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
|
-
|
|
67
|
+
this.logger?.info('Client response', {
|
|
42
68
|
status: response.status,
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
59
|
-
url: url.toString(),
|
|
92
|
+
this.logger?.error('Client request failed', {
|
|
60
93
|
method: options.method,
|
|
61
|
-
|
|
62
|
-
|
|
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 (
|
|
66
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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
|
|
124
|
-
const
|
|
125
|
-
|
|
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
|
|
130
|
-
const
|
|
131
|
-
|
|
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
|
-
|
|
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
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
//
|
|
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(
|
|
195
|
+
return new ClientError(safeMessage(), response.status, response, request);
|
|
156
196
|
}
|
|
157
197
|
}
|
|
158
198
|
//# sourceMappingURL=request-builder.js.map
|