toolcraft-openapi 0.0.67 → 0.0.69
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/dist/generate.js +4 -17
- package/dist/http.d.ts +2 -3
- package/dist/http.js +33 -28
- package/dist/runtime.js +5 -5
- package/package.json +2 -2
package/dist/generate.js
CHANGED
|
@@ -20,19 +20,6 @@ const NULL_HELPER_SUPPORT = {
|
|
|
20
20
|
// keeps null-helper flags body-only until a real query-null convention lands.
|
|
21
21
|
query: { array: false, scalar: false }
|
|
22
22
|
};
|
|
23
|
-
const TRANSPORT_PARAMS = [
|
|
24
|
-
{
|
|
25
|
-
paramName: "verbose",
|
|
26
|
-
sourceName: "verbose",
|
|
27
|
-
location: "transport",
|
|
28
|
-
description: "Log the request line to stderr.",
|
|
29
|
-
shortFlag: "v",
|
|
30
|
-
scope: ["cli", "sdk"],
|
|
31
|
-
global: true,
|
|
32
|
-
optional: true,
|
|
33
|
-
definition: { kind: "boolean" }
|
|
34
|
-
}
|
|
35
|
-
];
|
|
36
23
|
const BINARY_OUTPUT_PARAM = {
|
|
37
24
|
paramName: "output",
|
|
38
25
|
sourceName: "output",
|
|
@@ -347,7 +334,7 @@ function resolveOperationBaseUrl(operation, operationId) {
|
|
|
347
334
|
}
|
|
348
335
|
}
|
|
349
336
|
function collectParams(document, entry, operation, operationId, auth, responseMode) {
|
|
350
|
-
const transportParams = responseMode === "binary" ? [
|
|
337
|
+
const transportParams = responseMode === "binary" ? [BINARY_OUTPUT_PARAM] : [];
|
|
351
338
|
const operationParams = collectOperationParameters(document, entry.path, entry.pathItem.parameters ?? [], operation.parameters ?? [], operationId, auth);
|
|
352
339
|
const requestBodyParams = collectRequestBodyParams(document, operation, operationId, entry.method);
|
|
353
340
|
const qualifiedRequestBodyParams = qualifyBodyParamCollisions(requestBodyParams, new Set([...operationParams.params, ...transportParams].map((param) => param.paramName)));
|
|
@@ -1550,8 +1537,8 @@ function createCommandFile(options) {
|
|
|
1550
1537
|
? " }, { additionalProperties: false }),"
|
|
1551
1538
|
: " }),");
|
|
1552
1539
|
lines.push(usesRequestShapeVariable
|
|
1553
|
-
? " handler: async ({ params, baseUrl, tokenSource, fetch, fs, env }) => {"
|
|
1554
|
-
: " handler: async ({ params, baseUrl, tokenSource, fetch }) => {");
|
|
1540
|
+
? " handler: async ({ params, baseUrl, tokenSource, fetch, fs, env, diagnostics }) => {"
|
|
1541
|
+
: " handler: async ({ params, baseUrl, tokenSource, fetch, diagnostics }) => {");
|
|
1555
1542
|
lines.push(...options.preflightBlocks.flatMap((block) => renderPreflightBlock(block)));
|
|
1556
1543
|
if (usesRequestShapeVariable) {
|
|
1557
1544
|
lines.push(" const requestShape = {");
|
|
@@ -1605,7 +1592,7 @@ function createCommandFile(options) {
|
|
|
1605
1592
|
}
|
|
1606
1593
|
lines.push(" tokenSource,");
|
|
1607
1594
|
lines.push(" fetch,");
|
|
1608
|
-
lines.push("
|
|
1595
|
+
lines.push(" diagnostics,");
|
|
1609
1596
|
if (options.rawResponse === true) {
|
|
1610
1597
|
lines.push(" rawResponse: params.rawResponse,");
|
|
1611
1598
|
}
|
package/dist/http.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpError, type HandlerEnv, type HandlerFs, type HttpErrorRequest, type HttpErrorResponse } from "toolcraft";
|
|
1
|
+
import { HttpError, type HandlerEnv, type HandlerFs, type HttpErrorRequest, type HttpErrorResponse, type RuntimeLogger } from "toolcraft";
|
|
2
2
|
import type { TokenSource } from "./auth/types.js";
|
|
3
3
|
export { HttpError };
|
|
4
4
|
export type { HttpErrorRequest, HttpErrorResponse };
|
|
@@ -24,7 +24,7 @@ export interface HttpRequestOptions {
|
|
|
24
24
|
multipartBinaryFields?: readonly string[];
|
|
25
25
|
responseMode?: "json" | "text" | "binary";
|
|
26
26
|
accept?: string;
|
|
27
|
-
|
|
27
|
+
diagnostics?: RuntimeLogger;
|
|
28
28
|
signal?: AbortSignal;
|
|
29
29
|
rawResponse?: boolean;
|
|
30
30
|
retries?: {
|
|
@@ -40,7 +40,6 @@ export interface HttpRequestOptions {
|
|
|
40
40
|
key?: string;
|
|
41
41
|
createKey?: () => string;
|
|
42
42
|
};
|
|
43
|
-
writeStderr?: (chunk: string) => void;
|
|
44
43
|
}
|
|
45
44
|
export interface BinaryHttpResponse {
|
|
46
45
|
contentType: string;
|
package/dist/http.js
CHANGED
|
@@ -28,10 +28,8 @@ export async function requestJson(options) {
|
|
|
28
28
|
}
|
|
29
29
|
: {};
|
|
30
30
|
const headers = createHeaders(token, hasBody, { ...options.headers, ...idempotencyHeader }, options.accept, options.bodyMode, options.contentType);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
writeStderr(formatTranscriptLines(formatVerboseRequestTranscript(method, url, headers, options.body)));
|
|
34
|
-
}
|
|
31
|
+
emitHttpDebug(options, `${method} ${url}`, { method, url });
|
|
32
|
+
emitHttpTrace(options, "HTTP request transcript", formatVerboseRequestTranscript(method, url, headers, options.body));
|
|
35
33
|
const response = await fetchWithRetries(options, url, {
|
|
36
34
|
method,
|
|
37
35
|
headers,
|
|
@@ -44,9 +42,7 @@ export async function requestJson(options) {
|
|
|
44
42
|
if (response.ok && options.responseMode === "binary") {
|
|
45
43
|
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
46
44
|
if (bytes.byteLength === 0) {
|
|
47
|
-
|
|
48
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders)));
|
|
49
|
-
}
|
|
45
|
+
emitHttpTrace(options, "HTTP response transcript", formatVerboseResponseTranscript(response, responseHeaders));
|
|
50
46
|
return formatRawResponseResult(undefined, response, options.rawResponse);
|
|
51
47
|
}
|
|
52
48
|
const body = {
|
|
@@ -55,29 +51,20 @@ export async function requestJson(options) {
|
|
|
55
51
|
byteLength: bytes.byteLength,
|
|
56
52
|
data: Buffer.from(bytes).toString("base64")
|
|
57
53
|
};
|
|
58
|
-
|
|
59
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders, body)));
|
|
60
|
-
}
|
|
54
|
+
emitHttpTrace(options, "HTTP response transcript", formatVerboseResponseTranscript(response, responseHeaders, body));
|
|
61
55
|
return formatRawResponseResult(body, response, options.rawResponse);
|
|
62
56
|
}
|
|
63
57
|
const text = await response.text();
|
|
64
58
|
if (response.ok) {
|
|
65
59
|
if (text.length === 0) {
|
|
66
|
-
|
|
67
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders)));
|
|
68
|
-
}
|
|
60
|
+
emitHttpTrace(options, "HTTP response transcript", formatVerboseResponseTranscript(response, responseHeaders));
|
|
69
61
|
return formatRawResponseResult(undefined, response, options.rawResponse);
|
|
70
62
|
}
|
|
71
63
|
if (options.responseMode === "text") {
|
|
72
|
-
|
|
73
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders, text)));
|
|
74
|
-
}
|
|
64
|
+
emitHttpTrace(options, "HTTP response transcript", formatVerboseResponseTranscript(response, responseHeaders, text));
|
|
75
65
|
return formatRawResponseResult(text, response, options.rawResponse);
|
|
76
66
|
}
|
|
77
67
|
if (!isJsonContentType(contentType)) {
|
|
78
|
-
if (options.verbose) {
|
|
79
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders, text)));
|
|
80
|
-
}
|
|
81
68
|
throw createHttpError({
|
|
82
69
|
request,
|
|
83
70
|
response: {
|
|
@@ -94,9 +81,6 @@ export async function requestJson(options) {
|
|
|
94
81
|
body = JSON.parse(text);
|
|
95
82
|
}
|
|
96
83
|
catch {
|
|
97
|
-
if (options.verbose) {
|
|
98
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders, text)));
|
|
99
|
-
}
|
|
100
84
|
throw createHttpError({
|
|
101
85
|
request,
|
|
102
86
|
response: {
|
|
@@ -108,18 +92,13 @@ export async function requestJson(options) {
|
|
|
108
92
|
message: "Expected a valid JSON response body but received malformed JSON."
|
|
109
93
|
});
|
|
110
94
|
}
|
|
111
|
-
|
|
112
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders, body)));
|
|
113
|
-
}
|
|
95
|
+
emitHttpTrace(options, "HTTP response transcript", formatVerboseResponseTranscript(response, responseHeaders, body));
|
|
114
96
|
return formatRawResponseResult(body, response, options.rawResponse);
|
|
115
97
|
}
|
|
116
98
|
if (response.status === 401 && options.auth === "required") {
|
|
117
99
|
await options.tokenSource.invalidate?.(token).catch(() => undefined);
|
|
118
100
|
}
|
|
119
101
|
const body = parseResponseBody(text, contentType);
|
|
120
|
-
if (options.verbose) {
|
|
121
|
-
writeStderr(formatTranscriptLines(formatVerboseResponseTranscript(response, responseHeaders, body)));
|
|
122
|
-
}
|
|
123
102
|
throw createHttpError({
|
|
124
103
|
request,
|
|
125
104
|
response: {
|
|
@@ -145,6 +124,10 @@ async function fetchWithRetries(options, url, init) {
|
|
|
145
124
|
!shouldRetryStatus(response.status, retries.retryOn)) {
|
|
146
125
|
return response;
|
|
147
126
|
}
|
|
127
|
+
emitHttpDebug(options, `Retrying ${String(init.method ?? "GET")} ${url}`, {
|
|
128
|
+
attempt: attempt + 1,
|
|
129
|
+
status: response.status
|
|
130
|
+
});
|
|
148
131
|
await sleepBeforeRetry(response, retries, attempt);
|
|
149
132
|
attempt += 1;
|
|
150
133
|
}
|
|
@@ -153,11 +136,33 @@ async function fetchWithRetries(options, url, init) {
|
|
|
153
136
|
if (attempt >= maxRetries || retries === undefined) {
|
|
154
137
|
throw classified;
|
|
155
138
|
}
|
|
139
|
+
emitHttpDebug(options, `Retrying ${String(init.method ?? "GET")} ${url}`, {
|
|
140
|
+
attempt: attempt + 1,
|
|
141
|
+
error: classified instanceof Error ? classified.message : String(classified)
|
|
142
|
+
});
|
|
156
143
|
await sleepBeforeRetry(undefined, retries, attempt);
|
|
157
144
|
attempt += 1;
|
|
158
145
|
}
|
|
159
146
|
}
|
|
160
147
|
}
|
|
148
|
+
function emitHttpDebug(options, message, data) {
|
|
149
|
+
options.diagnostics?.emit({
|
|
150
|
+
level: "debug",
|
|
151
|
+
message,
|
|
152
|
+
category: "http",
|
|
153
|
+
data
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function emitHttpTrace(options, message, lines) {
|
|
157
|
+
options.diagnostics?.emit({
|
|
158
|
+
level: "trace",
|
|
159
|
+
message,
|
|
160
|
+
category: "http",
|
|
161
|
+
data: {
|
|
162
|
+
transcript: formatTranscriptLines(lines)
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
161
166
|
function shouldRetryStatus(status, retryOn) {
|
|
162
167
|
return retryOn?.includes(status) === true;
|
|
163
168
|
}
|
package/dist/runtime.js
CHANGED
|
@@ -68,7 +68,7 @@ function createRuntimeCommand(command) {
|
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
function createRuntimeHandler(command) {
|
|
71
|
-
return async ({ params, baseUrl, tokenSource, fetch, fs, env }) => {
|
|
71
|
+
return async ({ params, baseUrl, tokenSource, fetch, fs, env, diagnostics }) => {
|
|
72
72
|
const resolvedValues = executePreflightBlocks(command.preflightBlocks, params);
|
|
73
73
|
const requestShape = buildRequestShape(command.requestFields, command.sectionRenders, command.optionalSections, params, resolvedValues);
|
|
74
74
|
const preparedRequestShape = await prepareMultipartFileInputs(requestShape, {
|
|
@@ -89,7 +89,7 @@ function createRuntimeHandler(command) {
|
|
|
89
89
|
multipartBinaryFields: command.multipartBinaryFields,
|
|
90
90
|
tokenSource,
|
|
91
91
|
fetch,
|
|
92
|
-
|
|
92
|
+
diagnostics,
|
|
93
93
|
...preparedRequestShape
|
|
94
94
|
});
|
|
95
95
|
return writeBinaryResponseOutput(result, command.responseMode === "binary" ? params.output : undefined, { fs, env });
|
|
@@ -108,10 +108,10 @@ const RUNTIME_DEFINITION_BUILDERS = {
|
|
|
108
108
|
const itemDefinition = createRuntimeDefinition(definition.itemDefinition, undefined, undefined, undefined);
|
|
109
109
|
return options === undefined ? S.Array(itemDefinition) : S.Array(itemDefinition, options);
|
|
110
110
|
},
|
|
111
|
-
boolean: (_definition, options) => options === undefined ? S.Boolean() : S.Boolean(options),
|
|
111
|
+
boolean: (_definition, options) => (options === undefined ? S.Boolean() : S.Boolean(options)),
|
|
112
112
|
enum: (definition, options) => options === undefined ? S.Enum(definition.enumValues) : S.Enum(definition.enumValues, options),
|
|
113
113
|
json: (_definition) => S.Json(),
|
|
114
|
-
number: (_definition, options) => options === undefined ? S.Number() : S.Number(options),
|
|
114
|
+
number: (_definition, options) => (options === undefined ? S.Number() : S.Number(options)),
|
|
115
115
|
object: (definition, options) => {
|
|
116
116
|
const shape = Object.fromEntries(definition.properties.map((property) => {
|
|
117
117
|
const propertySchema = createRuntimeDefinition(property.definition, undefined, undefined, undefined);
|
|
@@ -119,7 +119,7 @@ const RUNTIME_DEFINITION_BUILDERS = {
|
|
|
119
119
|
}));
|
|
120
120
|
return options === undefined ? S.Object(shape) : S.Object(shape, options);
|
|
121
121
|
},
|
|
122
|
-
string: (_definition, options) => options === undefined ? S.String() : S.String(options)
|
|
122
|
+
string: (_definition, options) => (options === undefined ? S.String() : S.String(options))
|
|
123
123
|
};
|
|
124
124
|
function createRuntimeSchemaOptions(definition, description, shortFlag, scope, global) {
|
|
125
125
|
const options = Object.fromEntries(collectSchemaOptionEntries({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft-openapi",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.69",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"toolcraft-openapi-generate": "dist/bin/generate.js"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"toolcraft": "0.0.
|
|
31
|
+
"toolcraft": "0.0.69",
|
|
32
32
|
"auth-store": "^0.0.1",
|
|
33
33
|
"fast-string-width": "^3.0.2",
|
|
34
34
|
"fast-wrap-ansi": "^0.2.0",
|