@sdk-it/typescript 0.44.0 → 0.46.0
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/index.js +18 -11
- package/dist/index.js.map +2 -2
- package/dist/lib/emitters/interface.d.ts +1 -1
- package/dist/lib/emitters/interface.d.ts.map +1 -1
- package/dist/lib/emitters/zod.d.ts.map +1 -1
- package/dist/lib/generate.d.ts.map +1 -1
- package/dist/lib/pagination-emit.d.ts.map +1 -1
- package/dist/lib/sdk.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -66,7 +66,7 @@ function createTool(entry, operation) {
|
|
|
66
66
|
inputSchema: schemas.${schemaName},
|
|
67
67
|
execute: async (input, options) => {
|
|
68
68
|
console.log('Executing ${operation.operationId} tool with input:', input);
|
|
69
|
-
const context = coerceContext(options.
|
|
69
|
+
const context = coerceContext(options.context);
|
|
70
70
|
const response = await context.client.request(
|
|
71
71
|
'${entry.method.toUpperCase()} ${entry.path}' ,
|
|
72
72
|
input,
|
|
@@ -117,7 +117,7 @@ function createTool2(entry, operation) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
// packages/typescript/src/lib/agent/utils.txt
|
|
120
|
-
var utils_default = "function coerceContext(context?: any) {\n if (!context) {\n throw new Error('Context is required');\n }\n return context as {\n client: any\n };\n}\n/**\n * Takes a Zod object schema and makes all optional properties nullable as well.\n * This is useful for APIs where optional fields can be explicitly set to null.\n *\n * @param schema - The Zod object schema to transform\n * @returns A new Zod schema with optional properties made nullable\n */\nfunction makeOptionalPropsNullable<T extends z.ZodRawShape>(\n schema: z.ZodObject<T>,\n) {\n const shape = schema.shape;\n const newShape = {} as Record<string, z.ZodType>;\n\n for (const [key, value] of Object.entries(shape)) {\n if (value instanceof z.ZodOptional) {\n // Make optional properties also nullable\n newShape[key] = value.
|
|
120
|
+
var utils_default = "function coerceContext(context?: any) {\n if (!context) {\n throw new Error('Context is required');\n }\n return context as {\n client: any\n };\n}\n/**\n * Takes a Zod object schema and makes all optional properties nullable as well.\n * This is useful for APIs where optional fields can be explicitly set to null.\n *\n * @param schema - The Zod object schema to transform\n * @returns A new Zod schema with optional properties made nullable\n */\nfunction makeOptionalPropsNullable<T extends z.ZodRawShape>(\n schema: z.ZodObject<T>,\n) {\n const shape = schema.shape;\n const newShape = {} as Record<string, z.ZodType>;\n\n for (const [key, value] of Object.entries(shape) as [string, z.ZodType][]) {\n if (value instanceof z.ZodOptional) {\n // Make optional properties also nullable\n newShape[key] = value.nullable();\n } else {\n // Keep non-optional properties as they are\n newShape[key] = value;\n }\n }\n\n return z.object(newShape);\n}\n";
|
|
121
121
|
|
|
122
122
|
// packages/typescript/src/lib/client.ts
|
|
123
123
|
import { toLitObject } from "@sdk-it/core";
|
|
@@ -619,7 +619,13 @@ export async function prepare<const E extends keyof typeof schemas>(
|
|
|
619
619
|
};
|
|
620
620
|
|
|
621
621
|
// packages/typescript/src/lib/emitters/interface.ts
|
|
622
|
-
import {
|
|
622
|
+
import {
|
|
623
|
+
followRef as followRef2,
|
|
624
|
+
isRef as isRef2,
|
|
625
|
+
parseRef as parseRef2,
|
|
626
|
+
pascalcase as pascalcase2,
|
|
627
|
+
resolveRef
|
|
628
|
+
} from "@sdk-it/core";
|
|
623
629
|
import { isPrimitiveSchema as isPrimitiveSchema2, sanitizeTag as sanitizeTag2 } from "@sdk-it/spec";
|
|
624
630
|
var TypeScriptEmitter = class {
|
|
625
631
|
#spec;
|
|
@@ -629,7 +635,7 @@ var TypeScriptEmitter = class {
|
|
|
629
635
|
#stringifyKey = (value) => {
|
|
630
636
|
return `'${value}'`;
|
|
631
637
|
};
|
|
632
|
-
object(schema,
|
|
638
|
+
object(schema, _required = false) {
|
|
633
639
|
const properties = schema.properties || {};
|
|
634
640
|
const propEntries = Object.entries(properties).map(([key, propSchema]) => {
|
|
635
641
|
const isRequired = (schema.required ?? []).includes(key);
|
|
@@ -649,7 +655,7 @@ var TypeScriptEmitter = class {
|
|
|
649
655
|
/**
|
|
650
656
|
* Handle arrays (items could be a single schema or a tuple)
|
|
651
657
|
*/
|
|
652
|
-
#array(schema,
|
|
658
|
+
#array(schema, _required = false) {
|
|
653
659
|
const { items } = schema;
|
|
654
660
|
if (!items) {
|
|
655
661
|
return "any[]";
|
|
@@ -855,9 +861,7 @@ function describe(p) {
|
|
|
855
861
|
nextPageMapping: `${p.pageNumberParamName}: nextPageParams.page, ${p.pageSizeParamName}: nextPageParams.pageSize`
|
|
856
862
|
};
|
|
857
863
|
}
|
|
858
|
-
throw new Error(
|
|
859
|
-
`Unknown pagination type: ${p.type}`
|
|
860
|
-
);
|
|
864
|
+
throw new Error(`Unknown pagination type: ${p.type}`);
|
|
861
865
|
}
|
|
862
866
|
function paginationOperation(pagination) {
|
|
863
867
|
const shape = describe(pagination);
|
|
@@ -1332,7 +1336,7 @@ var dispatcher_default = "export type Unionize<T> = T extends [infer Single exte
|
|
|
1332
1336
|
var interceptors_default = "export interface Interceptor {\n before?: (config: RequestConfig) => Promise<RequestConfig> | RequestConfig;\n after?: (response: Response) => Promise<Response> | Response;\n}\n\nexport const createHeadersInterceptor = (\n headers: Record<string, string | undefined>,\n requestHeaders: HeadersInit,\n):Interceptor => {\n return {\n before({init, url}) {\n // Priority Levels\n // 1. Headers Input\n // 2. Request Headers\n // 3. Default Headers\n\n for (const [key, value] of new Headers(requestHeaders)) {\n // Only set the header if it doesn't already exist and has a value\n // even though these headers are passed at operation level\n // still they are lower priority compared to the headers input\n if (value !== undefined && !init.headers.has(key)) {\n init.headers.set(key, value);\n }\n }\n\n for (const [key, value] of Object.entries(headers)) {\n // Only set the header if it doesn't already exist and has a value\n if (value !== undefined && !init.headers.has(key)) {\n init.headers.set(key, value);\n }\n }\n\n return {init, url};\n },\n };\n};\n\nexport const createBaseUrlInterceptor = (baseUrl: string): Interceptor => {\n return {\n before({ init, url }) {\n if (url.protocol === 'local:') {\n return {\n init,\n url: new URL(url.href.replace('local://', baseUrl))\n };\n }\n return { init, url };\n },\n };\n};\n\nexport const logInterceptor: Interceptor = {\n before({ url, init }) {\n console.log('Request:', { url, init });\n return { url, init };\n },\n after(response) {\n console.log('Response:', response);\n return response;\n },\n};\n\n/**\n * Creates an interceptor that logs detailed information about requests and responses.\n * @param options Configuration options for the logger\n * @returns An interceptor object with before and after handlers\n */\nexport const createDetailedLogInterceptor = (options?: {\n logLevel?: 'debug' | 'info' | 'warn' | 'error';\n includeRequestBody?: boolean;\n includeResponseBody?: boolean;\n}) => {\n const logLevel = options?.logLevel || 'info';\n const includeRequestBody = options?.includeRequestBody || false;\n const includeResponseBody = options?.includeResponseBody || false;\n\n return {\n async before(request: Request) {\n const logData = {\n url: request.url,\n method: request.method,\n contentType: request.headers.get('Content-Type'),\n headers: Object.fromEntries([...request.headers.entries()]),\n };\n\n console[logLevel]('\u{1F680} Outgoing Request:', logData);\n\n if (includeRequestBody) {\n try {\n // Clone the request to avoid consuming the body stream\n const clonedRequest = request.clone();\n if (clonedRequest.headers.get('Content-Type')?.includes('application/json')) {\n const body = await clonedRequest.json().catch(() => null);\n console[logLevel]('Request Body:', body);\n } else {\n const body = await clonedRequest.text().catch(() => null);\n console[logLevel]('Request Body:', body);\n }\n } catch (error) {\n console.error('Could not log request body:', error);\n }\n }\n\n return request;\n },\n\n async after(response: Response) {\n const logData = {\n status: response.status,\n statusText: response.statusText,\n url: response.url,\n headers: Object.fromEntries([...response.headers.entries()]),\n };\n\n console[logLevel]('\u{1F4E5} Incoming Response:', logData);\n\n if (includeResponseBody && response.body) {\n try {\n // Clone the response to avoid consuming the body stream\n const clonedResponse = response.clone();\n if (clonedResponse.headers.get('Content-Type')?.includes('application/json')) {\n const body = await clonedResponse.json().catch(() => null);\n console[logLevel]('Response Body:', body);\n } else {\n const body = await clonedResponse.text().catch(() => null);\n if (body) {\n console[logLevel]('Response Body:', body.substring(0, 500) + (body.length > 500 ? '...' : ''));\n } else {\n console[logLevel]('No response body');\n }\n }\n } catch (error) {\n console.error('Could not log response body:', error);\n }\n }\n\n return response;\n },\n };\n};\n";
|
|
1333
1337
|
|
|
1334
1338
|
// packages/typescript/src/lib/http/parse-response.txt
|
|
1335
|
-
var parse_response_default = 'import { parse } from "fast-content-type-parse";\n\nfunction isBinaryContentType(contentType: string) {\n const type = contentType.toLowerCase();\n if (type.startsWith("image/")) {\n return true;\n }\n if (type.startsWith("audio/")) {\n return true;\n }\n if (type.startsWith("video/")) {\n return true;\n }\n switch (type) {\n case "application/pdf":\n case "application/zip":\n case "application/gzip":\n case "application/x-7z-compressed":\n case "application/x-tar":\n case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":\n case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":\n case "application/vnd.openxmlformats-officedocument.presentationml.presentation":\n case "application/vnd.ms-excel":\n case "application/vnd.ms-powerpoint":\n case "application/msword":\n case "application/octet-stream":\n return true;\n default:\n return false;\n }\n}\n\nasync function handleChunkedResponse(response: Response, contentType: string) {\n const { type } = parse(contentType);\n\n switch (type) {\n case "application/json": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return JSON.parse(buffer);\n }\n case "text/html":\n case "text/plain": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return buffer;\n }\n default:\n return response.body;\n }\n}\n\nexport function chunked(response: Response) {\n return response.body!;\n}\n\nexport async function buffered(response: Response) {\n // Statuses that, per the HTTP spec, carry no message body. These responses\n // usually omit Content-Type entirely, so this must run before the guard below.\n if (\n response.status === 204 ||\n response.status === 205 ||\n response.status === 304\n ) {\n return null;\n }\n\n const contentType = response.headers.get("Content-Type");\n if (!contentType) {\n throw new Error("Content-Type header is missing");\n }\n\n const { type } = parse(contentType);\n if (isBinaryContentType(type)) {\n return response.blob();\n }\n if (type.startsWith("text/")) {\n return response.text();\n }\n switch (type) {\n case "application/json":\n return response.json();\n case "application/xml":\n return response.text();\n case "application/x-www-form-urlencoded": {\n const text = await response.text();\n return Object.fromEntries(new URLSearchParams(text));\n }\n case "multipart/form-data":\n return response.formData();\n default:\n throw new Error(`Unsupported content type: ${contentType}`);\n }\n}\n';
|
|
1339
|
+
var parse_response_default = 'import { parse } from "fast-content-type-parse";\n\nfunction isBinaryContentType(contentType: string) {\n const type = contentType.toLowerCase();\n if (type.startsWith("image/")) {\n return true;\n }\n if (type.startsWith("audio/")) {\n return true;\n }\n if (type.startsWith("video/")) {\n return true;\n }\n switch (type) {\n case "application/pdf":\n case "application/zip":\n case "application/gzip":\n case "application/x-7z-compressed":\n case "application/x-tar":\n case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":\n case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":\n case "application/vnd.openxmlformats-officedocument.presentationml.presentation":\n case "application/vnd.ms-excel":\n case "application/vnd.ms-powerpoint":\n case "application/msword":\n case "application/octet-stream":\n return true;\n default:\n return false;\n }\n}\n\nfunction isAttachment(response: Response) {\n const contentDisposition = response.headers.get("Content-Disposition");\n const dispositionType = contentDisposition?.split(";", 1)[0];\n return dispositionType?.trim().toLowerCase() === "attachment";\n}\n\nasync function handleChunkedResponse(response: Response, contentType: string) {\n const { type } = parse(contentType);\n\n switch (type) {\n case "application/json": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return JSON.parse(buffer);\n }\n case "text/html":\n case "text/plain": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return buffer;\n }\n default:\n return response.body;\n }\n}\n\nexport function chunked(response: Response) {\n return response.body!;\n}\n\nexport async function buffered(response: Response) {\n // Statuses that, per the HTTP spec, carry no message body. These responses\n // usually omit Content-Type entirely, so this must run before the guard below.\n if (\n response.status === 204 ||\n response.status === 205 ||\n response.status === 304\n ) {\n return null;\n }\n if (isAttachment(response)) {\n return response.blob();\n }\n\n const contentType = response.headers.get("Content-Type");\n if (!contentType) {\n throw new Error("Content-Type header is missing");\n }\n\n const { type } = parse(contentType);\n if (isBinaryContentType(type)) {\n return response.blob();\n }\n if (type.startsWith("text/")) {\n return response.text();\n }\n switch (type) {\n case "application/json":\n return response.json();\n case "application/xml":\n return response.text();\n case "application/x-www-form-urlencoded": {\n const text = await response.text();\n return Object.fromEntries(new URLSearchParams(text));\n }\n case "multipart/form-data":\n return response.formData();\n default:\n throw new Error(`Unsupported content type: ${contentType}`);\n }\n}\n';
|
|
1336
1340
|
|
|
1337
1341
|
// packages/typescript/src/lib/http/parser.txt
|
|
1338
1342
|
var parser_default = "import { z } from 'zod';\n\nexport class ParseError<T extends z.ZodType> extends Error {\n public data: z.core.$ZodFlattenedError<z.output<T>, z.core.$ZodIssue>;\n constructor(\n data: z.core.$ZodFlattenedError<z.output<T>, z.core.$ZodIssue>,\n ) {\n super('Validation failed');\n this.name = 'ParseError';\n this.data = data;\n }\n}\n\nexport function parseInput<T extends z.ZodType>(\n schema: T,\n input: unknown,\n): z.infer<T> {\n const result = schema.safeParse(input);\n if (!result.success) {\n const error = z.flattenError(result.error, (issue) => issue);\n throw new ParseError<T>(error);\n }\n return result.data as z.infer<T>;\n}\n";
|
|
@@ -2695,7 +2699,7 @@ function availablePaginationTypes(spec) {
|
|
|
2695
2699
|
|
|
2696
2700
|
// packages/typescript/src/lib/generate.ts
|
|
2697
2701
|
async function generate(openapi, settings) {
|
|
2698
|
-
const spec = toIR(
|
|
2702
|
+
const spec = await toIR(
|
|
2699
2703
|
{
|
|
2700
2704
|
spec: openapi,
|
|
2701
2705
|
responses: { flattenErrorResponses: true },
|
|
@@ -2860,6 +2864,7 @@ ${utils_default}`
|
|
|
2860
2864
|
name: packageName,
|
|
2861
2865
|
version: "0.0.1",
|
|
2862
2866
|
type: "module",
|
|
2867
|
+
...settings.agentTools === "ai-sdk" ? { engines: { node: ">=22" } } : {},
|
|
2863
2868
|
main: "./src/index.ts",
|
|
2864
2869
|
module: "./src/index.ts",
|
|
2865
2870
|
types: "./src/index.ts",
|
|
@@ -2876,7 +2881,9 @@ ${utils_default}`
|
|
|
2876
2881
|
},
|
|
2877
2882
|
dependencies: {
|
|
2878
2883
|
"fast-content-type-parse": "^3.0.0",
|
|
2879
|
-
zod: "^4.3.0"
|
|
2884
|
+
zod: "^4.3.0",
|
|
2885
|
+
...settings.agentTools === "ai-sdk" ? { ai: "^7.0.29" } : {},
|
|
2886
|
+
...settings.agentTools === "openai-agents" ? { "@openai/agents": "^0.13.4" } : {}
|
|
2880
2887
|
}
|
|
2881
2888
|
},
|
|
2882
2889
|
null,
|