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 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" ? [...TRANSPORT_PARAMS, BINARY_OUTPUT_PARAM] : TRANSPORT_PARAMS;
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(" verbose: params.verbose,");
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
- verbose?: boolean;
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
- const writeStderr = options.writeStderr ?? process.stderr.write.bind(process.stderr);
32
- if (options.verbose) {
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
- if (options.verbose) {
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
- if (options.verbose) {
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
- if (options.verbose) {
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
- if (options.verbose) {
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
- if (options.verbose) {
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
- verbose: params.verbose,
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.67",
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.67",
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",