@redonvn/open-claw-sdk 0.1.2 → 0.1.4
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/{chunk-VZE5THET.js → chunk-6QQXCYPZ.js} +67 -3
- package/dist/chunk-6QQXCYPZ.js.map +1 -0
- package/dist/cli.cjs +66 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +183 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +118 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-VZE5THET.js.map +0 -1
|
@@ -134,6 +134,68 @@ var openApiSchemaToJsonSchema = (schema, document, seen = /* @__PURE__ */ new Se
|
|
|
134
134
|
}
|
|
135
135
|
return jsonSchema;
|
|
136
136
|
};
|
|
137
|
+
var isObjectSchema = (schema) => {
|
|
138
|
+
const type = schema?.type;
|
|
139
|
+
if (type === "object") {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
if (Array.isArray(type)) {
|
|
143
|
+
return type.includes("object");
|
|
144
|
+
}
|
|
145
|
+
return Boolean(schema?.properties || schema?.additionalProperties);
|
|
146
|
+
};
|
|
147
|
+
var isArraySchema = (schema) => {
|
|
148
|
+
const type = schema?.type;
|
|
149
|
+
if (type === "array") {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
if (Array.isArray(type)) {
|
|
153
|
+
return type.includes("array");
|
|
154
|
+
}
|
|
155
|
+
return Boolean(schema?.items);
|
|
156
|
+
};
|
|
157
|
+
var jsonSchemasEqual = (left, right) => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
158
|
+
var normalizeBodySchemaForAgent = (schema) => {
|
|
159
|
+
if (schema.oneOf?.length) {
|
|
160
|
+
const normalizedVariants = schema.oneOf.map(normalizeBodySchemaForAgent);
|
|
161
|
+
const objectVariant = normalizedVariants.find((item) => isObjectSchema(item));
|
|
162
|
+
const arrayVariant = normalizedVariants.find((item) => isArraySchema(item));
|
|
163
|
+
if (objectVariant && arrayVariant?.items && jsonSchemasEqual(objectVariant, arrayVariant.items)) {
|
|
164
|
+
return objectVariant;
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
...schema,
|
|
168
|
+
oneOf: normalizedVariants
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (schema.anyOf?.length) {
|
|
172
|
+
return {
|
|
173
|
+
...schema,
|
|
174
|
+
anyOf: schema.anyOf.map(normalizeBodySchemaForAgent)
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (schema.allOf?.length) {
|
|
178
|
+
return {
|
|
179
|
+
...schema,
|
|
180
|
+
allOf: schema.allOf.map(normalizeBodySchemaForAgent)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (schema.items) {
|
|
184
|
+
return {
|
|
185
|
+
...schema,
|
|
186
|
+
items: normalizeBodySchemaForAgent(schema.items)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (schema.properties) {
|
|
190
|
+
return {
|
|
191
|
+
...schema,
|
|
192
|
+
properties: Object.fromEntries(
|
|
193
|
+
Object.entries(schema.properties).map(([key, value]) => [key, normalizeBodySchemaForAgent(value)])
|
|
194
|
+
)
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return schema;
|
|
198
|
+
};
|
|
137
199
|
var buildParameterSection = (sectionName, parameters, document) => {
|
|
138
200
|
if (!parameters.length) {
|
|
139
201
|
return null;
|
|
@@ -178,7 +240,7 @@ var buildToolParameters = (document, path2, operation, options, pathParameters,
|
|
|
178
240
|
}
|
|
179
241
|
}
|
|
180
242
|
if (requestBodySchema) {
|
|
181
|
-
properties.body = openApiSchemaToJsonSchema(requestBodySchema, document);
|
|
243
|
+
properties.body = normalizeBodySchemaForAgent(openApiSchemaToJsonSchema(requestBodySchema, document));
|
|
182
244
|
if (operation.requestBody?.required) {
|
|
183
245
|
required.push("body");
|
|
184
246
|
}
|
|
@@ -257,6 +319,7 @@ var convertOpenApiToTools = (document, options) => {
|
|
|
257
319
|
return {
|
|
258
320
|
pluginId: options.pluginId,
|
|
259
321
|
pluginName: options.pluginName ?? toTitleCase(options.pluginId),
|
|
322
|
+
version: options.pluginVersion,
|
|
260
323
|
description: document.info?.description?.trim() ?? `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,
|
|
261
324
|
serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,
|
|
262
325
|
optional: options.optional ?? true,
|
|
@@ -271,7 +334,7 @@ var serialize = (value) => JSON.stringify(value, null, 2);
|
|
|
271
334
|
var renderPluginManifest = (catalog) => `${serialize({
|
|
272
335
|
id: catalog.pluginId,
|
|
273
336
|
name: catalog.pluginName,
|
|
274
|
-
version: "0.1.0",
|
|
337
|
+
version: catalog.version ?? "0.1.0",
|
|
275
338
|
description: catalog.description,
|
|
276
339
|
configSchema: {
|
|
277
340
|
type: "object",
|
|
@@ -357,6 +420,7 @@ var generatePluginFromOpenApi = async (options) => {
|
|
|
357
420
|
const convertOptions = {
|
|
358
421
|
pluginId: options.pluginId,
|
|
359
422
|
pluginName: options.pluginName,
|
|
423
|
+
pluginVersion: options.pluginVersion,
|
|
360
424
|
toolPrefix: options.toolPrefix,
|
|
361
425
|
optional: options.optional,
|
|
362
426
|
includeHeaders: options.includeHeaders,
|
|
@@ -377,4 +441,4 @@ export {
|
|
|
377
441
|
writeGeneratedPlugin,
|
|
378
442
|
generatePluginFromOpenApi
|
|
379
443
|
};
|
|
380
|
-
//# sourceMappingURL=chunk-
|
|
444
|
+
//# sourceMappingURL=chunk-6QQXCYPZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/openapi.ts","../src/utils.ts","../src/generator.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport {\n ConvertOpenApiOptions,\n JsonSchema,\n OpenApiDocument,\n OpenApiOperationObject,\n OpenClawPluginCatalog,\n OpenClawToolDefinition\n} from \"./types\";\nimport {\n AUTH_HEADER_NAMES,\n HTTP_METHODS,\n buildOperationId,\n buildToolName,\n compactObject,\n dedupeParameters,\n hasSchemaContent,\n pickContentSchema,\n toTitleCase\n} from \"./utils\";\n\nconst isHttpUrl = (value: string): boolean => /^https?:\\/\\//i.test(value);\n\nconst readUrl = async (url: string): Promise<string> => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Unable to load OpenAPI document from ${url}: ${response.status} ${response.statusText}`);\n }\n\n return response.text();\n};\n\nexport const loadOpenApiDocument = async (source: string): Promise<OpenApiDocument> => {\n const raw = isHttpUrl(source)\n ? await readUrl(source)\n : await fs.readFile(source, \"utf8\");\n\n const document = JSON.parse(raw) as OpenApiDocument;\n\n if (!document.openapi || !document.paths) {\n throw new Error(\"Invalid OpenAPI document: missing `openapi` or `paths`.\");\n }\n\n return document;\n};\n\nconst cloneJsonSchema = (value: JsonSchema): JsonSchema => JSON.parse(JSON.stringify(value)) as JsonSchema;\n\nconst resolveRefName = (ref: string): string => ref.split(\"/\").pop() ?? \"UnknownSchema\";\n\nconst resolveSchemaRef = (\n document: OpenApiDocument,\n ref: string\n): import(\"./types\").OpenApiSchemaObject | undefined => {\n const schemaName = resolveRefName(ref);\n return document.components?.schemas?.[schemaName];\n};\n\nexport const openApiSchemaToJsonSchema = (\n schema: import(\"./types\").OpenApiSchemaObject | undefined,\n document: OpenApiDocument,\n seen = new Set<string>()\n): JsonSchema => {\n if (!schema) {\n return { type: \"object\", additionalProperties: true };\n }\n\n if (schema.$ref) {\n if (seen.has(schema.$ref)) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const resolved = resolveSchemaRef(document, schema.$ref);\n\n if (!resolved) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const nextSeen = new Set(seen);\n nextSeen.add(schema.$ref);\n return openApiSchemaToJsonSchema(resolved, document, nextSeen);\n }\n\n const jsonSchema: JsonSchema = compactObject({\n type: Array.isArray(schema.type) ? [...schema.type] : schema.type,\n description: schema.description,\n default: schema.default,\n enum: schema.enum ? [...schema.enum] : undefined\n });\n\n if (schema.oneOf?.length) {\n jsonSchema.oneOf = schema.oneOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.anyOf?.length) {\n jsonSchema.anyOf = schema.anyOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.allOf?.length) {\n jsonSchema.allOf = schema.allOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.items) {\n jsonSchema.items = openApiSchemaToJsonSchema(schema.items, document, seen);\n }\n\n if (schema.properties) {\n jsonSchema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [\n key,\n openApiSchemaToJsonSchema(value, document, seen)\n ])\n );\n }\n\n if (schema.required?.length) {\n jsonSchema.required = [...schema.required];\n }\n\n if (schema.additionalProperties !== undefined) {\n jsonSchema.additionalProperties =\n schema.additionalProperties === true || schema.additionalProperties === false\n ? schema.additionalProperties\n : openApiSchemaToJsonSchema(schema.additionalProperties, document, seen);\n }\n\n if (schema.nullable) {\n const currentType = jsonSchema.type;\n\n if (Array.isArray(currentType)) {\n jsonSchema.type = currentType.includes(\"null\") ? currentType : [...currentType, \"null\"];\n } else if (currentType) {\n jsonSchema.type = currentType === \"null\" ? \"null\" : [currentType, \"null\"];\n } else {\n jsonSchema.type = [\"object\", \"null\"];\n }\n }\n\n return jsonSchema;\n};\n\nconst isObjectSchema = (schema: JsonSchema | undefined): boolean => {\n const type = schema?.type;\n\n if (type === \"object\") {\n return true;\n }\n\n if (Array.isArray(type)) {\n return type.includes(\"object\");\n }\n\n return Boolean(schema?.properties || schema?.additionalProperties);\n};\n\nconst isArraySchema = (schema: JsonSchema | undefined): boolean => {\n const type = schema?.type;\n\n if (type === \"array\") {\n return true;\n }\n\n if (Array.isArray(type)) {\n return type.includes(\"array\");\n }\n\n return Boolean(schema?.items);\n};\n\nconst jsonSchemasEqual = (left: JsonSchema | undefined, right: JsonSchema | undefined): boolean =>\n JSON.stringify(left ?? null) === JSON.stringify(right ?? null);\n\nconst normalizeBodySchemaForAgent = (schema: JsonSchema): JsonSchema => {\n if (schema.oneOf?.length) {\n const normalizedVariants = schema.oneOf.map(normalizeBodySchemaForAgent);\n const objectVariant = normalizedVariants.find((item) => isObjectSchema(item));\n const arrayVariant = normalizedVariants.find((item) => isArraySchema(item));\n\n if (\n objectVariant &&\n arrayVariant?.items &&\n jsonSchemasEqual(objectVariant, arrayVariant.items)\n ) {\n // AI-facing tools are much more reliable when a request body has one clear object shape.\n // When OpenAPI exposes \"single object OR array of same object\", prefer the single-object form.\n return objectVariant;\n }\n\n return {\n ...schema,\n oneOf: normalizedVariants\n };\n }\n\n if (schema.anyOf?.length) {\n return {\n ...schema,\n anyOf: schema.anyOf.map(normalizeBodySchemaForAgent)\n };\n }\n\n if (schema.allOf?.length) {\n return {\n ...schema,\n allOf: schema.allOf.map(normalizeBodySchemaForAgent)\n };\n }\n\n if (schema.items) {\n return {\n ...schema,\n items: normalizeBodySchemaForAgent(schema.items)\n };\n }\n\n if (schema.properties) {\n return {\n ...schema,\n properties: Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [key, normalizeBodySchemaForAgent(value)])\n )\n };\n }\n\n return schema;\n};\n\nconst buildParameterSection = (\n sectionName: string,\n parameters: import(\"./types\").OpenApiParameterObject[],\n document: OpenApiDocument\n): { name: string; schema: JsonSchema; required: boolean } | null => {\n if (!parameters.length) {\n return null;\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const parameter of parameters) {\n properties[parameter.name] = compactObject({\n ...openApiSchemaToJsonSchema(parameter.schema, document),\n description: parameter.description ?? parameter.schema?.description\n });\n\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n return {\n name: sectionName,\n required: required.length > 0,\n schema: compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false\n })\n };\n};\n\nconst buildToolParameters = (\n document: OpenApiDocument,\n path: string,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): JsonSchema => {\n const requestBodySchema = pickContentSchema(operation.requestBody?.content);\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n const sections = [\n buildParameterSection(\"path\", pathParameters, document),\n buildParameterSection(\"query\", queryParameters, document),\n options.includeHeaders ? buildParameterSection(\"headers\", headerParameters, document) : null\n ].filter((value): value is { name: string; schema: JsonSchema; required: boolean } => Boolean(value));\n\n for (const section of sections) {\n if (hasSchemaContent(section.schema)) {\n properties[section.name] = section.schema;\n if (section.required) {\n required.push(section.name);\n }\n }\n }\n\n if (requestBodySchema) {\n properties.body = normalizeBodySchemaForAgent(openApiSchemaToJsonSchema(requestBodySchema, document));\n if (operation.requestBody?.required) {\n required.push(\"body\");\n }\n }\n\n return compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false,\n description: `${operation.summary ?? operation.operationId ?? `${path} request`} tool arguments`\n });\n};\n\nconst buildToolDescription = (path: string, method: string, operation: OpenApiOperationObject): string => {\n const summary = operation.summary?.trim();\n const description = operation.description?.trim();\n\n if (summary && description && description !== summary) {\n return `${summary}. ${description}`;\n }\n\n if (summary) {\n return summary;\n }\n\n if (description) {\n return description;\n }\n\n return `${method.toUpperCase()} ${path}`;\n};\n\nconst buildToolDefinition = (\n document: OpenApiDocument,\n path: string,\n method: import(\"./types\").HttpMethod,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): OpenClawToolDefinition => {\n const operationId = buildOperationId(method, path, operation.operationId);\n\n return {\n name: buildToolName(options.toolPrefix, operationId),\n description: buildToolDescription(path, method, operation),\n method: method.toUpperCase() as Uppercase<typeof method>,\n path,\n operationId,\n parameters: buildToolParameters(\n document,\n path,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n ),\n tags: operation.tags ?? []\n };\n};\n\nexport const convertOpenApiToTools = (\n document: OpenApiDocument,\n options: ConvertOpenApiOptions\n): OpenClawPluginCatalog => {\n const tools: OpenClawToolDefinition[] = [];\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const parameters = dedupeParameters(pathItem.parameters, operation.parameters);\n const pathParameters = parameters.filter((parameter) => parameter.in === \"path\");\n const queryParameters = parameters.filter((parameter) => parameter.in === \"query\");\n const headerParameters = parameters.filter(\n (parameter) =>\n parameter.in === \"header\" &&\n !AUTH_HEADER_NAMES.has(parameter.name.toLowerCase())\n );\n\n tools.push(\n buildToolDefinition(\n document,\n path,\n method,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n )\n );\n }\n }\n\n tools.sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n pluginId: options.pluginId,\n pluginName: options.pluginName ?? toTitleCase(options.pluginId),\n version: options.pluginVersion,\n description:\n document.info?.description?.trim() ??\n `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,\n serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,\n optional: options.optional ?? true,\n tools\n };\n};\n","import { HttpMethod, JsonSchema, OpenApiParameterObject } from \"./types\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"options\",\n \"head\"\n];\n\nexport const AUTH_HEADER_NAMES = new Set([\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"dt-jwt\"\n]);\n\nexport const sanitizeIdentifier = (value: string): string =>\n value\n .trim()\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .replace(/_{2,}/g, \"_\")\n .toLowerCase() || \"tool\";\n\nexport const toTitleCase = (value: string): string =>\n value\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\nexport const buildToolName = (toolPrefix: string | undefined, rawName: string): string => {\n const base = sanitizeIdentifier(rawName);\n const prefix = sanitizeIdentifier(toolPrefix ?? \"\");\n return prefix ? `${prefix}_${base}` : base;\n};\n\nexport const buildOperationId = (method: HttpMethod, path: string, operationId?: string): string => {\n if (operationId?.trim()) {\n return sanitizeIdentifier(operationId);\n }\n\n const pathPart = path\n .replace(/\\{([^}]+)\\}/g, \"by_$1\")\n .replace(/\\/+/g, \"_\");\n\n return sanitizeIdentifier(`${method}_${pathPart}`);\n};\n\nexport const pickContentSchema = (\n content: Record<string, { schema?: import(\"./types\").OpenApiSchemaObject | undefined }> | undefined\n): import(\"./types\").OpenApiSchemaObject | undefined =>\n content?.[\"application/json\"]?.schema ??\n content?.[\"application/*+json\"]?.schema ??\n Object.values(content ?? {})[0]?.schema;\n\nexport const dedupeParameters = (\n pathLevel: OpenApiParameterObject[] | undefined,\n operationLevel: OpenApiParameterObject[] | undefined\n): OpenApiParameterObject[] => {\n const byKey = new Map<string, OpenApiParameterObject>();\n\n for (const param of [...(pathLevel ?? []), ...(operationLevel ?? [])]) {\n byKey.set(`${param.in}:${param.name}`, param);\n }\n\n return [...byKey.values()];\n};\n\nexport const compactObject = <T extends Record<string, unknown>>(value: T): T => {\n const output = {} as T;\n\n for (const [key, item] of Object.entries(value)) {\n if (item !== undefined) {\n output[key as keyof T] = item as T[keyof T];\n }\n }\n\n return output;\n};\n\nexport const hasSchemaContent = (schema: JsonSchema | undefined): boolean =>\n Boolean(\n schema &&\n ((schema.properties && Object.keys(schema.properties).length > 0) ||\n (schema.required && schema.required.length > 0) ||\n schema.type ||\n schema.oneOf ||\n schema.anyOf ||\n schema.allOf)\n );\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n ConvertOpenApiOptions,\n GeneratedPluginFiles,\n GeneratePluginOptions,\n OpenClawPluginCatalog\n} from \"./types\";\nimport { convertOpenApiToTools, loadOpenApiDocument } from \"./openapi\";\n\nconst serialize = (value: unknown): string => JSON.stringify(value, null, 2);\n\nexport const renderPluginManifest = (catalog: OpenClawPluginCatalog): string =>\n `${serialize({\n id: catalog.pluginId,\n name: catalog.pluginName,\n version: catalog.version ?? \"0.1.0\",\n description: catalog.description,\n configSchema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n baseUrl: {\n type: \"string\",\n description: \"Base URL of the target HTTP API\"\n },\n bearerToken: {\n type: \"string\",\n description: \"Bearer token used for Authorization header\"\n },\n apiKey: {\n type: \"string\",\n description: \"Static API key for the upstream API\"\n },\n apiKeyHeader: {\n type: \"string\",\n description: \"Header name used when apiKey is set\",\n default: \"x-api-key\"\n },\n timeoutMs: {\n type: \"number\",\n description: \"Timeout in milliseconds for outbound tool calls\"\n },\n defaultHeaders: {\n type: \"object\",\n additionalProperties: {\n type: \"string\"\n },\n description: \"Additional headers added to every request\"\n }\n }\n },\n uiHints: {\n baseUrl: {\n label: \"Base URL\",\n placeholder: catalog.serverUrl ?? \"https://api.example.com\"\n },\n bearerToken: {\n label: \"Bearer Token\",\n sensitive: true\n },\n apiKey: {\n label: \"API Key\",\n sensitive: true\n },\n apiKeyHeader: {\n label: \"API Key Header\"\n },\n timeoutMs: {\n label: \"Timeout (ms)\"\n }\n }\n })}\\n`;\n\nexport const renderPluginModule = (catalog: OpenClawPluginCatalog): string =>\n `import { createOpenApiPlugin } from \"@redonvn/open-claw-sdk\";\n\nexport const catalog = ${serialize(catalog)} as const;\n\nexport default createOpenApiPlugin(catalog);\n`;\n\nexport const renderCatalogFile = (catalog: OpenClawPluginCatalog): string =>\n `${serialize(catalog)}\\n`;\n\nconst ensureDir = async (dirPath: string): Promise<void> => {\n await fs.mkdir(dirPath, { recursive: true });\n};\n\nexport const writeGeneratedPlugin = async (\n catalog: OpenClawPluginCatalog,\n outDir: string\n): Promise<GeneratedPluginFiles> => {\n await ensureDir(outDir);\n\n const manifestPath = path.join(outDir, \"openclaw.plugin.json\");\n const indexPath = path.join(outDir, \"index.ts\");\n const catalogPath = path.join(outDir, \"tool-catalog.json\");\n\n await Promise.all([\n fs.writeFile(manifestPath, renderPluginManifest(catalog), \"utf8\"),\n fs.writeFile(indexPath, renderPluginModule(catalog), \"utf8\"),\n fs.writeFile(catalogPath, renderCatalogFile(catalog), \"utf8\")\n ]);\n\n return { manifestPath, indexPath, catalogPath };\n};\n\nexport const generatePluginFromOpenApi = async (\n options: GeneratePluginOptions\n): Promise<{ catalog: OpenClawPluginCatalog; files: GeneratedPluginFiles }> => {\n const document = await loadOpenApiDocument(options.input);\n const convertOptions: ConvertOpenApiOptions = {\n pluginId: options.pluginId,\n pluginName: options.pluginName,\n pluginVersion: options.pluginVersion,\n toolPrefix: options.toolPrefix,\n optional: options.optional,\n includeHeaders: options.includeHeaders,\n defaultServerUrl: options.defaultServerUrl\n };\n const catalog = convertOpenApiToTools(document, convertOptions);\n const files = await writeGeneratedPlugin(catalog, options.outDir);\n\n return { catalog, files };\n};\n"],"mappings":"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","names":["path","path","fs","fs"]}
|
package/dist/cli.cjs
CHANGED
|
@@ -163,6 +163,68 @@ var openApiSchemaToJsonSchema = (schema, document, seen = /* @__PURE__ */ new Se
|
|
|
163
163
|
}
|
|
164
164
|
return jsonSchema;
|
|
165
165
|
};
|
|
166
|
+
var isObjectSchema = (schema) => {
|
|
167
|
+
const type = schema?.type;
|
|
168
|
+
if (type === "object") {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
if (Array.isArray(type)) {
|
|
172
|
+
return type.includes("object");
|
|
173
|
+
}
|
|
174
|
+
return Boolean(schema?.properties || schema?.additionalProperties);
|
|
175
|
+
};
|
|
176
|
+
var isArraySchema = (schema) => {
|
|
177
|
+
const type = schema?.type;
|
|
178
|
+
if (type === "array") {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
if (Array.isArray(type)) {
|
|
182
|
+
return type.includes("array");
|
|
183
|
+
}
|
|
184
|
+
return Boolean(schema?.items);
|
|
185
|
+
};
|
|
186
|
+
var jsonSchemasEqual = (left, right) => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
187
|
+
var normalizeBodySchemaForAgent = (schema) => {
|
|
188
|
+
if (schema.oneOf?.length) {
|
|
189
|
+
const normalizedVariants = schema.oneOf.map(normalizeBodySchemaForAgent);
|
|
190
|
+
const objectVariant = normalizedVariants.find((item) => isObjectSchema(item));
|
|
191
|
+
const arrayVariant = normalizedVariants.find((item) => isArraySchema(item));
|
|
192
|
+
if (objectVariant && arrayVariant?.items && jsonSchemasEqual(objectVariant, arrayVariant.items)) {
|
|
193
|
+
return objectVariant;
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
...schema,
|
|
197
|
+
oneOf: normalizedVariants
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (schema.anyOf?.length) {
|
|
201
|
+
return {
|
|
202
|
+
...schema,
|
|
203
|
+
anyOf: schema.anyOf.map(normalizeBodySchemaForAgent)
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
if (schema.allOf?.length) {
|
|
207
|
+
return {
|
|
208
|
+
...schema,
|
|
209
|
+
allOf: schema.allOf.map(normalizeBodySchemaForAgent)
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
if (schema.items) {
|
|
213
|
+
return {
|
|
214
|
+
...schema,
|
|
215
|
+
items: normalizeBodySchemaForAgent(schema.items)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
if (schema.properties) {
|
|
219
|
+
return {
|
|
220
|
+
...schema,
|
|
221
|
+
properties: Object.fromEntries(
|
|
222
|
+
Object.entries(schema.properties).map(([key, value]) => [key, normalizeBodySchemaForAgent(value)])
|
|
223
|
+
)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return schema;
|
|
227
|
+
};
|
|
166
228
|
var buildParameterSection = (sectionName, parameters, document) => {
|
|
167
229
|
if (!parameters.length) {
|
|
168
230
|
return null;
|
|
@@ -207,7 +269,7 @@ var buildToolParameters = (document, path2, operation, options, pathParameters,
|
|
|
207
269
|
}
|
|
208
270
|
}
|
|
209
271
|
if (requestBodySchema) {
|
|
210
|
-
properties.body = openApiSchemaToJsonSchema(requestBodySchema, document);
|
|
272
|
+
properties.body = normalizeBodySchemaForAgent(openApiSchemaToJsonSchema(requestBodySchema, document));
|
|
211
273
|
if (operation.requestBody?.required) {
|
|
212
274
|
required.push("body");
|
|
213
275
|
}
|
|
@@ -286,6 +348,7 @@ var convertOpenApiToTools = (document, options) => {
|
|
|
286
348
|
return {
|
|
287
349
|
pluginId: options.pluginId,
|
|
288
350
|
pluginName: options.pluginName ?? toTitleCase(options.pluginId),
|
|
351
|
+
version: options.pluginVersion,
|
|
289
352
|
description: document.info?.description?.trim() ?? `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,
|
|
290
353
|
serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,
|
|
291
354
|
optional: options.optional ?? true,
|
|
@@ -298,7 +361,7 @@ var serialize = (value) => JSON.stringify(value, null, 2);
|
|
|
298
361
|
var renderPluginManifest = (catalog) => `${serialize({
|
|
299
362
|
id: catalog.pluginId,
|
|
300
363
|
name: catalog.pluginName,
|
|
301
|
-
version: "0.1.0",
|
|
364
|
+
version: catalog.version ?? "0.1.0",
|
|
302
365
|
description: catalog.description,
|
|
303
366
|
configSchema: {
|
|
304
367
|
type: "object",
|
|
@@ -384,6 +447,7 @@ var generatePluginFromOpenApi = async (options) => {
|
|
|
384
447
|
const convertOptions = {
|
|
385
448
|
pluginId: options.pluginId,
|
|
386
449
|
pluginName: options.pluginName,
|
|
450
|
+
pluginVersion: options.pluginVersion,
|
|
387
451
|
toolPrefix: options.toolPrefix,
|
|
388
452
|
optional: options.optional,
|
|
389
453
|
includeHeaders: options.includeHeaders,
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/generator.ts","../src/openapi.ts","../src/utils.ts","../src/cli.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n ConvertOpenApiOptions,\n GeneratedPluginFiles,\n GeneratePluginOptions,\n OpenClawPluginCatalog\n} from \"./types\";\nimport { convertOpenApiToTools, loadOpenApiDocument } from \"./openapi\";\n\nconst serialize = (value: unknown): string => JSON.stringify(value, null, 2);\n\nexport const renderPluginManifest = (catalog: OpenClawPluginCatalog): string =>\n `${serialize({\n id: catalog.pluginId,\n name: catalog.pluginName,\n version: \"0.1.0\",\n description: catalog.description,\n configSchema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n baseUrl: {\n type: \"string\",\n description: \"Base URL of the target HTTP API\"\n },\n bearerToken: {\n type: \"string\",\n description: \"Bearer token used for Authorization header\"\n },\n apiKey: {\n type: \"string\",\n description: \"Static API key for the upstream API\"\n },\n apiKeyHeader: {\n type: \"string\",\n description: \"Header name used when apiKey is set\",\n default: \"x-api-key\"\n },\n timeoutMs: {\n type: \"number\",\n description: \"Timeout in milliseconds for outbound tool calls\"\n },\n defaultHeaders: {\n type: \"object\",\n additionalProperties: {\n type: \"string\"\n },\n description: \"Additional headers added to every request\"\n }\n }\n },\n uiHints: {\n baseUrl: {\n label: \"Base URL\",\n placeholder: catalog.serverUrl ?? \"https://api.example.com\"\n },\n bearerToken: {\n label: \"Bearer Token\",\n sensitive: true\n },\n apiKey: {\n label: \"API Key\",\n sensitive: true\n },\n apiKeyHeader: {\n label: \"API Key Header\"\n },\n timeoutMs: {\n label: \"Timeout (ms)\"\n }\n }\n })}\\n`;\n\nexport const renderPluginModule = (catalog: OpenClawPluginCatalog): string =>\n `import { createOpenApiPlugin } from \"@redonvn/open-claw-sdk\";\n\nexport const catalog = ${serialize(catalog)} as const;\n\nexport default createOpenApiPlugin(catalog);\n`;\n\nexport const renderCatalogFile = (catalog: OpenClawPluginCatalog): string =>\n `${serialize(catalog)}\\n`;\n\nconst ensureDir = async (dirPath: string): Promise<void> => {\n await fs.mkdir(dirPath, { recursive: true });\n};\n\nexport const writeGeneratedPlugin = async (\n catalog: OpenClawPluginCatalog,\n outDir: string\n): Promise<GeneratedPluginFiles> => {\n await ensureDir(outDir);\n\n const manifestPath = path.join(outDir, \"openclaw.plugin.json\");\n const indexPath = path.join(outDir, \"index.ts\");\n const catalogPath = path.join(outDir, \"tool-catalog.json\");\n\n await Promise.all([\n fs.writeFile(manifestPath, renderPluginManifest(catalog), \"utf8\"),\n fs.writeFile(indexPath, renderPluginModule(catalog), \"utf8\"),\n fs.writeFile(catalogPath, renderCatalogFile(catalog), \"utf8\")\n ]);\n\n return { manifestPath, indexPath, catalogPath };\n};\n\nexport const generatePluginFromOpenApi = async (\n options: GeneratePluginOptions\n): Promise<{ catalog: OpenClawPluginCatalog; files: GeneratedPluginFiles }> => {\n const document = await loadOpenApiDocument(options.input);\n const convertOptions: ConvertOpenApiOptions = {\n pluginId: options.pluginId,\n pluginName: options.pluginName,\n toolPrefix: options.toolPrefix,\n optional: options.optional,\n includeHeaders: options.includeHeaders,\n defaultServerUrl: options.defaultServerUrl\n };\n const catalog = convertOpenApiToTools(document, convertOptions);\n const files = await writeGeneratedPlugin(catalog, options.outDir);\n\n return { catalog, files };\n};\n","import { promises as fs } from \"node:fs\";\nimport {\n ConvertOpenApiOptions,\n JsonSchema,\n OpenApiDocument,\n OpenApiOperationObject,\n OpenClawPluginCatalog,\n OpenClawToolDefinition\n} from \"./types\";\nimport {\n AUTH_HEADER_NAMES,\n HTTP_METHODS,\n buildOperationId,\n buildToolName,\n compactObject,\n dedupeParameters,\n hasSchemaContent,\n pickContentSchema,\n toTitleCase\n} from \"./utils\";\n\nconst isHttpUrl = (value: string): boolean => /^https?:\\/\\//i.test(value);\n\nconst readUrl = async (url: string): Promise<string> => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Unable to load OpenAPI document from ${url}: ${response.status} ${response.statusText}`);\n }\n\n return response.text();\n};\n\nexport const loadOpenApiDocument = async (source: string): Promise<OpenApiDocument> => {\n const raw = isHttpUrl(source)\n ? await readUrl(source)\n : await fs.readFile(source, \"utf8\");\n\n const document = JSON.parse(raw) as OpenApiDocument;\n\n if (!document.openapi || !document.paths) {\n throw new Error(\"Invalid OpenAPI document: missing `openapi` or `paths`.\");\n }\n\n return document;\n};\n\nconst cloneJsonSchema = (value: JsonSchema): JsonSchema => JSON.parse(JSON.stringify(value)) as JsonSchema;\n\nconst resolveRefName = (ref: string): string => ref.split(\"/\").pop() ?? \"UnknownSchema\";\n\nconst resolveSchemaRef = (\n document: OpenApiDocument,\n ref: string\n): import(\"./types\").OpenApiSchemaObject | undefined => {\n const schemaName = resolveRefName(ref);\n return document.components?.schemas?.[schemaName];\n};\n\nexport const openApiSchemaToJsonSchema = (\n schema: import(\"./types\").OpenApiSchemaObject | undefined,\n document: OpenApiDocument,\n seen = new Set<string>()\n): JsonSchema => {\n if (!schema) {\n return { type: \"object\", additionalProperties: true };\n }\n\n if (schema.$ref) {\n if (seen.has(schema.$ref)) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const resolved = resolveSchemaRef(document, schema.$ref);\n\n if (!resolved) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const nextSeen = new Set(seen);\n nextSeen.add(schema.$ref);\n return openApiSchemaToJsonSchema(resolved, document, nextSeen);\n }\n\n const jsonSchema: JsonSchema = compactObject({\n type: Array.isArray(schema.type) ? [...schema.type] : schema.type,\n description: schema.description,\n default: schema.default,\n enum: schema.enum ? [...schema.enum] : undefined\n });\n\n if (schema.oneOf?.length) {\n jsonSchema.oneOf = schema.oneOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.anyOf?.length) {\n jsonSchema.anyOf = schema.anyOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.allOf?.length) {\n jsonSchema.allOf = schema.allOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.items) {\n jsonSchema.items = openApiSchemaToJsonSchema(schema.items, document, seen);\n }\n\n if (schema.properties) {\n jsonSchema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [\n key,\n openApiSchemaToJsonSchema(value, document, seen)\n ])\n );\n }\n\n if (schema.required?.length) {\n jsonSchema.required = [...schema.required];\n }\n\n if (schema.additionalProperties !== undefined) {\n jsonSchema.additionalProperties =\n schema.additionalProperties === true || schema.additionalProperties === false\n ? schema.additionalProperties\n : openApiSchemaToJsonSchema(schema.additionalProperties, document, seen);\n }\n\n if (schema.nullable) {\n const currentType = jsonSchema.type;\n\n if (Array.isArray(currentType)) {\n jsonSchema.type = currentType.includes(\"null\") ? currentType : [...currentType, \"null\"];\n } else if (currentType) {\n jsonSchema.type = currentType === \"null\" ? \"null\" : [currentType, \"null\"];\n } else {\n jsonSchema.type = [\"object\", \"null\"];\n }\n }\n\n return jsonSchema;\n};\n\nconst buildParameterSection = (\n sectionName: string,\n parameters: import(\"./types\").OpenApiParameterObject[],\n document: OpenApiDocument\n): { name: string; schema: JsonSchema; required: boolean } | null => {\n if (!parameters.length) {\n return null;\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const parameter of parameters) {\n properties[parameter.name] = compactObject({\n ...openApiSchemaToJsonSchema(parameter.schema, document),\n description: parameter.description ?? parameter.schema?.description\n });\n\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n return {\n name: sectionName,\n required: required.length > 0,\n schema: compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false\n })\n };\n};\n\nconst buildToolParameters = (\n document: OpenApiDocument,\n path: string,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): JsonSchema => {\n const requestBodySchema = pickContentSchema(operation.requestBody?.content);\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n const sections = [\n buildParameterSection(\"path\", pathParameters, document),\n buildParameterSection(\"query\", queryParameters, document),\n options.includeHeaders ? buildParameterSection(\"headers\", headerParameters, document) : null\n ].filter((value): value is { name: string; schema: JsonSchema; required: boolean } => Boolean(value));\n\n for (const section of sections) {\n if (hasSchemaContent(section.schema)) {\n properties[section.name] = section.schema;\n if (section.required) {\n required.push(section.name);\n }\n }\n }\n\n if (requestBodySchema) {\n properties.body = openApiSchemaToJsonSchema(requestBodySchema, document);\n if (operation.requestBody?.required) {\n required.push(\"body\");\n }\n }\n\n return compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false,\n description: `${operation.summary ?? operation.operationId ?? `${path} request`} tool arguments`\n });\n};\n\nconst buildToolDescription = (path: string, method: string, operation: OpenApiOperationObject): string => {\n const summary = operation.summary?.trim();\n const description = operation.description?.trim();\n\n if (summary && description && description !== summary) {\n return `${summary}. ${description}`;\n }\n\n if (summary) {\n return summary;\n }\n\n if (description) {\n return description;\n }\n\n return `${method.toUpperCase()} ${path}`;\n};\n\nconst buildToolDefinition = (\n document: OpenApiDocument,\n path: string,\n method: import(\"./types\").HttpMethod,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): OpenClawToolDefinition => {\n const operationId = buildOperationId(method, path, operation.operationId);\n\n return {\n name: buildToolName(options.toolPrefix, operationId),\n description: buildToolDescription(path, method, operation),\n method: method.toUpperCase() as Uppercase<typeof method>,\n path,\n operationId,\n parameters: buildToolParameters(\n document,\n path,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n ),\n tags: operation.tags ?? []\n };\n};\n\nexport const convertOpenApiToTools = (\n document: OpenApiDocument,\n options: ConvertOpenApiOptions\n): OpenClawPluginCatalog => {\n const tools: OpenClawToolDefinition[] = [];\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const parameters = dedupeParameters(pathItem.parameters, operation.parameters);\n const pathParameters = parameters.filter((parameter) => parameter.in === \"path\");\n const queryParameters = parameters.filter((parameter) => parameter.in === \"query\");\n const headerParameters = parameters.filter(\n (parameter) =>\n parameter.in === \"header\" &&\n !AUTH_HEADER_NAMES.has(parameter.name.toLowerCase())\n );\n\n tools.push(\n buildToolDefinition(\n document,\n path,\n method,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n )\n );\n }\n }\n\n tools.sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n pluginId: options.pluginId,\n pluginName: options.pluginName ?? toTitleCase(options.pluginId),\n description:\n document.info?.description?.trim() ??\n `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,\n serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,\n optional: options.optional ?? true,\n tools\n };\n};\n","import { HttpMethod, JsonSchema, OpenApiParameterObject } from \"./types\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"options\",\n \"head\"\n];\n\nexport const AUTH_HEADER_NAMES = new Set([\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"dt-jwt\"\n]);\n\nexport const sanitizeIdentifier = (value: string): string =>\n value\n .trim()\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .replace(/_{2,}/g, \"_\")\n .toLowerCase() || \"tool\";\n\nexport const toTitleCase = (value: string): string =>\n value\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\nexport const buildToolName = (toolPrefix: string | undefined, rawName: string): string => {\n const base = sanitizeIdentifier(rawName);\n const prefix = sanitizeIdentifier(toolPrefix ?? \"\");\n return prefix ? `${prefix}_${base}` : base;\n};\n\nexport const buildOperationId = (method: HttpMethod, path: string, operationId?: string): string => {\n if (operationId?.trim()) {\n return sanitizeIdentifier(operationId);\n }\n\n const pathPart = path\n .replace(/\\{([^}]+)\\}/g, \"by_$1\")\n .replace(/\\/+/g, \"_\");\n\n return sanitizeIdentifier(`${method}_${pathPart}`);\n};\n\nexport const pickContentSchema = (\n content: Record<string, { schema?: import(\"./types\").OpenApiSchemaObject | undefined }> | undefined\n): import(\"./types\").OpenApiSchemaObject | undefined =>\n content?.[\"application/json\"]?.schema ??\n content?.[\"application/*+json\"]?.schema ??\n Object.values(content ?? {})[0]?.schema;\n\nexport const dedupeParameters = (\n pathLevel: OpenApiParameterObject[] | undefined,\n operationLevel: OpenApiParameterObject[] | undefined\n): OpenApiParameterObject[] => {\n const byKey = new Map<string, OpenApiParameterObject>();\n\n for (const param of [...(pathLevel ?? []), ...(operationLevel ?? [])]) {\n byKey.set(`${param.in}:${param.name}`, param);\n }\n\n return [...byKey.values()];\n};\n\nexport const compactObject = <T extends Record<string, unknown>>(value: T): T => {\n const output = {} as T;\n\n for (const [key, item] of Object.entries(value)) {\n if (item !== undefined) {\n output[key as keyof T] = item as T[keyof T];\n }\n }\n\n return output;\n};\n\nexport const hasSchemaContent = (schema: JsonSchema | undefined): boolean =>\n Boolean(\n schema &&\n ((schema.properties && Object.keys(schema.properties).length > 0) ||\n (schema.required && schema.required.length > 0) ||\n schema.type ||\n schema.oneOf ||\n schema.anyOf ||\n schema.allOf)\n );\n","#!/usr/bin/env node\nimport { generatePluginFromOpenApi } from \"./generator\";\nimport { GeneratePluginOptions } from \"./types\";\n\nconst printUsage = (): void => {\n console.log(\"Usage: open-claw-sdk generate --input=<openapi.json> --outDir=<dir> --pluginId=<id> [options]\");\n console.log(\"\");\n console.log(\"Options:\");\n console.log(\" --pluginName=<name> Human-readable plugin name\");\n console.log(\" --toolPrefix=<prefix> Prefix added to every tool name\");\n console.log(\" --defaultServerUrl=<url> Override OpenAPI server URL\");\n console.log(\" --includeHeaders=true Include non-auth header params in tool schema\");\n console.log(\" --optional=false Register tools as required instead of opt-in\");\n};\n\nconst parseArgs = (argv: string[]): Record<string, string> => {\n const output: Record<string, string> = {};\n\n for (const item of argv) {\n if (!item.startsWith(\"--\")) {\n continue;\n }\n\n const [rawKey, ...rest] = item.slice(2).split(\"=\");\n if (!rawKey) {\n continue;\n }\n output[rawKey] = rest.length ? rest.join(\"=\") : \"true\";\n }\n\n return output;\n};\n\nconst parseBoolean = (value: string | undefined, defaultValue: boolean): boolean => {\n if (value === undefined) {\n return defaultValue;\n }\n\n return [\"1\", \"true\", \"yes\", \"on\"].includes(value.toLowerCase());\n};\n\nconst toGenerateOptions = (args: Record<string, string>): GeneratePluginOptions => {\n const input = args.input;\n const outDir = args.outDir;\n const pluginId = args.pluginId;\n\n if (!input || !outDir || !pluginId) {\n throw new Error(\"Missing required arguments: --input, --outDir, --pluginId\");\n }\n\n return {\n input,\n outDir,\n pluginId,\n pluginName: args.pluginName,\n toolPrefix: args.toolPrefix,\n defaultServerUrl: args.defaultServerUrl,\n includeHeaders: parseBoolean(args.includeHeaders, false),\n optional: parseBoolean(args.optional, true)\n };\n};\n\nconst main = async (): Promise<void> => {\n const command = process.argv[2];\n\n if (!command || command === \"help\" || command === \"--help\" || command === \"-h\") {\n printUsage();\n return;\n }\n\n if (command !== \"generate\") {\n throw new Error(`Unknown command: ${command}`);\n }\n\n const options = toGenerateOptions(parseArgs(process.argv.slice(3)));\n const { catalog, files } = await generatePluginFromOpenApi(options);\n\n console.log(`Generated ${catalog.tools.length} tools for plugin ${catalog.pluginId}`);\n console.log(`Manifest: ${files.manifestPath}`);\n console.log(`Module: ${files.indexPath}`);\n console.log(`Catalog: ${files.catalogPath}`);\n};\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":"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","names":["import_node_fs","path","fs","path","fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/generator.ts","../src/openapi.ts","../src/utils.ts","../src/cli.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n ConvertOpenApiOptions,\n GeneratedPluginFiles,\n GeneratePluginOptions,\n OpenClawPluginCatalog\n} from \"./types\";\nimport { convertOpenApiToTools, loadOpenApiDocument } from \"./openapi\";\n\nconst serialize = (value: unknown): string => JSON.stringify(value, null, 2);\n\nexport const renderPluginManifest = (catalog: OpenClawPluginCatalog): string =>\n `${serialize({\n id: catalog.pluginId,\n name: catalog.pluginName,\n version: catalog.version ?? \"0.1.0\",\n description: catalog.description,\n configSchema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n baseUrl: {\n type: \"string\",\n description: \"Base URL of the target HTTP API\"\n },\n bearerToken: {\n type: \"string\",\n description: \"Bearer token used for Authorization header\"\n },\n apiKey: {\n type: \"string\",\n description: \"Static API key for the upstream API\"\n },\n apiKeyHeader: {\n type: \"string\",\n description: \"Header name used when apiKey is set\",\n default: \"x-api-key\"\n },\n timeoutMs: {\n type: \"number\",\n description: \"Timeout in milliseconds for outbound tool calls\"\n },\n defaultHeaders: {\n type: \"object\",\n additionalProperties: {\n type: \"string\"\n },\n description: \"Additional headers added to every request\"\n }\n }\n },\n uiHints: {\n baseUrl: {\n label: \"Base URL\",\n placeholder: catalog.serverUrl ?? \"https://api.example.com\"\n },\n bearerToken: {\n label: \"Bearer Token\",\n sensitive: true\n },\n apiKey: {\n label: \"API Key\",\n sensitive: true\n },\n apiKeyHeader: {\n label: \"API Key Header\"\n },\n timeoutMs: {\n label: \"Timeout (ms)\"\n }\n }\n })}\\n`;\n\nexport const renderPluginModule = (catalog: OpenClawPluginCatalog): string =>\n `import { createOpenApiPlugin } from \"@redonvn/open-claw-sdk\";\n\nexport const catalog = ${serialize(catalog)} as const;\n\nexport default createOpenApiPlugin(catalog);\n`;\n\nexport const renderCatalogFile = (catalog: OpenClawPluginCatalog): string =>\n `${serialize(catalog)}\\n`;\n\nconst ensureDir = async (dirPath: string): Promise<void> => {\n await fs.mkdir(dirPath, { recursive: true });\n};\n\nexport const writeGeneratedPlugin = async (\n catalog: OpenClawPluginCatalog,\n outDir: string\n): Promise<GeneratedPluginFiles> => {\n await ensureDir(outDir);\n\n const manifestPath = path.join(outDir, \"openclaw.plugin.json\");\n const indexPath = path.join(outDir, \"index.ts\");\n const catalogPath = path.join(outDir, \"tool-catalog.json\");\n\n await Promise.all([\n fs.writeFile(manifestPath, renderPluginManifest(catalog), \"utf8\"),\n fs.writeFile(indexPath, renderPluginModule(catalog), \"utf8\"),\n fs.writeFile(catalogPath, renderCatalogFile(catalog), \"utf8\")\n ]);\n\n return { manifestPath, indexPath, catalogPath };\n};\n\nexport const generatePluginFromOpenApi = async (\n options: GeneratePluginOptions\n): Promise<{ catalog: OpenClawPluginCatalog; files: GeneratedPluginFiles }> => {\n const document = await loadOpenApiDocument(options.input);\n const convertOptions: ConvertOpenApiOptions = {\n pluginId: options.pluginId,\n pluginName: options.pluginName,\n pluginVersion: options.pluginVersion,\n toolPrefix: options.toolPrefix,\n optional: options.optional,\n includeHeaders: options.includeHeaders,\n defaultServerUrl: options.defaultServerUrl\n };\n const catalog = convertOpenApiToTools(document, convertOptions);\n const files = await writeGeneratedPlugin(catalog, options.outDir);\n\n return { catalog, files };\n};\n","import { promises as fs } from \"node:fs\";\nimport {\n ConvertOpenApiOptions,\n JsonSchema,\n OpenApiDocument,\n OpenApiOperationObject,\n OpenClawPluginCatalog,\n OpenClawToolDefinition\n} from \"./types\";\nimport {\n AUTH_HEADER_NAMES,\n HTTP_METHODS,\n buildOperationId,\n buildToolName,\n compactObject,\n dedupeParameters,\n hasSchemaContent,\n pickContentSchema,\n toTitleCase\n} from \"./utils\";\n\nconst isHttpUrl = (value: string): boolean => /^https?:\\/\\//i.test(value);\n\nconst readUrl = async (url: string): Promise<string> => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Unable to load OpenAPI document from ${url}: ${response.status} ${response.statusText}`);\n }\n\n return response.text();\n};\n\nexport const loadOpenApiDocument = async (source: string): Promise<OpenApiDocument> => {\n const raw = isHttpUrl(source)\n ? await readUrl(source)\n : await fs.readFile(source, \"utf8\");\n\n const document = JSON.parse(raw) as OpenApiDocument;\n\n if (!document.openapi || !document.paths) {\n throw new Error(\"Invalid OpenAPI document: missing `openapi` or `paths`.\");\n }\n\n return document;\n};\n\nconst cloneJsonSchema = (value: JsonSchema): JsonSchema => JSON.parse(JSON.stringify(value)) as JsonSchema;\n\nconst resolveRefName = (ref: string): string => ref.split(\"/\").pop() ?? \"UnknownSchema\";\n\nconst resolveSchemaRef = (\n document: OpenApiDocument,\n ref: string\n): import(\"./types\").OpenApiSchemaObject | undefined => {\n const schemaName = resolveRefName(ref);\n return document.components?.schemas?.[schemaName];\n};\n\nexport const openApiSchemaToJsonSchema = (\n schema: import(\"./types\").OpenApiSchemaObject | undefined,\n document: OpenApiDocument,\n seen = new Set<string>()\n): JsonSchema => {\n if (!schema) {\n return { type: \"object\", additionalProperties: true };\n }\n\n if (schema.$ref) {\n if (seen.has(schema.$ref)) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const resolved = resolveSchemaRef(document, schema.$ref);\n\n if (!resolved) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const nextSeen = new Set(seen);\n nextSeen.add(schema.$ref);\n return openApiSchemaToJsonSchema(resolved, document, nextSeen);\n }\n\n const jsonSchema: JsonSchema = compactObject({\n type: Array.isArray(schema.type) ? [...schema.type] : schema.type,\n description: schema.description,\n default: schema.default,\n enum: schema.enum ? [...schema.enum] : undefined\n });\n\n if (schema.oneOf?.length) {\n jsonSchema.oneOf = schema.oneOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.anyOf?.length) {\n jsonSchema.anyOf = schema.anyOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.allOf?.length) {\n jsonSchema.allOf = schema.allOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.items) {\n jsonSchema.items = openApiSchemaToJsonSchema(schema.items, document, seen);\n }\n\n if (schema.properties) {\n jsonSchema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [\n key,\n openApiSchemaToJsonSchema(value, document, seen)\n ])\n );\n }\n\n if (schema.required?.length) {\n jsonSchema.required = [...schema.required];\n }\n\n if (schema.additionalProperties !== undefined) {\n jsonSchema.additionalProperties =\n schema.additionalProperties === true || schema.additionalProperties === false\n ? schema.additionalProperties\n : openApiSchemaToJsonSchema(schema.additionalProperties, document, seen);\n }\n\n if (schema.nullable) {\n const currentType = jsonSchema.type;\n\n if (Array.isArray(currentType)) {\n jsonSchema.type = currentType.includes(\"null\") ? currentType : [...currentType, \"null\"];\n } else if (currentType) {\n jsonSchema.type = currentType === \"null\" ? \"null\" : [currentType, \"null\"];\n } else {\n jsonSchema.type = [\"object\", \"null\"];\n }\n }\n\n return jsonSchema;\n};\n\nconst isObjectSchema = (schema: JsonSchema | undefined): boolean => {\n const type = schema?.type;\n\n if (type === \"object\") {\n return true;\n }\n\n if (Array.isArray(type)) {\n return type.includes(\"object\");\n }\n\n return Boolean(schema?.properties || schema?.additionalProperties);\n};\n\nconst isArraySchema = (schema: JsonSchema | undefined): boolean => {\n const type = schema?.type;\n\n if (type === \"array\") {\n return true;\n }\n\n if (Array.isArray(type)) {\n return type.includes(\"array\");\n }\n\n return Boolean(schema?.items);\n};\n\nconst jsonSchemasEqual = (left: JsonSchema | undefined, right: JsonSchema | undefined): boolean =>\n JSON.stringify(left ?? null) === JSON.stringify(right ?? null);\n\nconst normalizeBodySchemaForAgent = (schema: JsonSchema): JsonSchema => {\n if (schema.oneOf?.length) {\n const normalizedVariants = schema.oneOf.map(normalizeBodySchemaForAgent);\n const objectVariant = normalizedVariants.find((item) => isObjectSchema(item));\n const arrayVariant = normalizedVariants.find((item) => isArraySchema(item));\n\n if (\n objectVariant &&\n arrayVariant?.items &&\n jsonSchemasEqual(objectVariant, arrayVariant.items)\n ) {\n // AI-facing tools are much more reliable when a request body has one clear object shape.\n // When OpenAPI exposes \"single object OR array of same object\", prefer the single-object form.\n return objectVariant;\n }\n\n return {\n ...schema,\n oneOf: normalizedVariants\n };\n }\n\n if (schema.anyOf?.length) {\n return {\n ...schema,\n anyOf: schema.anyOf.map(normalizeBodySchemaForAgent)\n };\n }\n\n if (schema.allOf?.length) {\n return {\n ...schema,\n allOf: schema.allOf.map(normalizeBodySchemaForAgent)\n };\n }\n\n if (schema.items) {\n return {\n ...schema,\n items: normalizeBodySchemaForAgent(schema.items)\n };\n }\n\n if (schema.properties) {\n return {\n ...schema,\n properties: Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [key, normalizeBodySchemaForAgent(value)])\n )\n };\n }\n\n return schema;\n};\n\nconst buildParameterSection = (\n sectionName: string,\n parameters: import(\"./types\").OpenApiParameterObject[],\n document: OpenApiDocument\n): { name: string; schema: JsonSchema; required: boolean } | null => {\n if (!parameters.length) {\n return null;\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const parameter of parameters) {\n properties[parameter.name] = compactObject({\n ...openApiSchemaToJsonSchema(parameter.schema, document),\n description: parameter.description ?? parameter.schema?.description\n });\n\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n return {\n name: sectionName,\n required: required.length > 0,\n schema: compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false\n })\n };\n};\n\nconst buildToolParameters = (\n document: OpenApiDocument,\n path: string,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): JsonSchema => {\n const requestBodySchema = pickContentSchema(operation.requestBody?.content);\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n const sections = [\n buildParameterSection(\"path\", pathParameters, document),\n buildParameterSection(\"query\", queryParameters, document),\n options.includeHeaders ? buildParameterSection(\"headers\", headerParameters, document) : null\n ].filter((value): value is { name: string; schema: JsonSchema; required: boolean } => Boolean(value));\n\n for (const section of sections) {\n if (hasSchemaContent(section.schema)) {\n properties[section.name] = section.schema;\n if (section.required) {\n required.push(section.name);\n }\n }\n }\n\n if (requestBodySchema) {\n properties.body = normalizeBodySchemaForAgent(openApiSchemaToJsonSchema(requestBodySchema, document));\n if (operation.requestBody?.required) {\n required.push(\"body\");\n }\n }\n\n return compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false,\n description: `${operation.summary ?? operation.operationId ?? `${path} request`} tool arguments`\n });\n};\n\nconst buildToolDescription = (path: string, method: string, operation: OpenApiOperationObject): string => {\n const summary = operation.summary?.trim();\n const description = operation.description?.trim();\n\n if (summary && description && description !== summary) {\n return `${summary}. ${description}`;\n }\n\n if (summary) {\n return summary;\n }\n\n if (description) {\n return description;\n }\n\n return `${method.toUpperCase()} ${path}`;\n};\n\nconst buildToolDefinition = (\n document: OpenApiDocument,\n path: string,\n method: import(\"./types\").HttpMethod,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): OpenClawToolDefinition => {\n const operationId = buildOperationId(method, path, operation.operationId);\n\n return {\n name: buildToolName(options.toolPrefix, operationId),\n description: buildToolDescription(path, method, operation),\n method: method.toUpperCase() as Uppercase<typeof method>,\n path,\n operationId,\n parameters: buildToolParameters(\n document,\n path,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n ),\n tags: operation.tags ?? []\n };\n};\n\nexport const convertOpenApiToTools = (\n document: OpenApiDocument,\n options: ConvertOpenApiOptions\n): OpenClawPluginCatalog => {\n const tools: OpenClawToolDefinition[] = [];\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const parameters = dedupeParameters(pathItem.parameters, operation.parameters);\n const pathParameters = parameters.filter((parameter) => parameter.in === \"path\");\n const queryParameters = parameters.filter((parameter) => parameter.in === \"query\");\n const headerParameters = parameters.filter(\n (parameter) =>\n parameter.in === \"header\" &&\n !AUTH_HEADER_NAMES.has(parameter.name.toLowerCase())\n );\n\n tools.push(\n buildToolDefinition(\n document,\n path,\n method,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n )\n );\n }\n }\n\n tools.sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n pluginId: options.pluginId,\n pluginName: options.pluginName ?? toTitleCase(options.pluginId),\n version: options.pluginVersion,\n description:\n document.info?.description?.trim() ??\n `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,\n serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,\n optional: options.optional ?? true,\n tools\n };\n};\n","import { HttpMethod, JsonSchema, OpenApiParameterObject } from \"./types\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"options\",\n \"head\"\n];\n\nexport const AUTH_HEADER_NAMES = new Set([\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"dt-jwt\"\n]);\n\nexport const sanitizeIdentifier = (value: string): string =>\n value\n .trim()\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .replace(/_{2,}/g, \"_\")\n .toLowerCase() || \"tool\";\n\nexport const toTitleCase = (value: string): string =>\n value\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\nexport const buildToolName = (toolPrefix: string | undefined, rawName: string): string => {\n const base = sanitizeIdentifier(rawName);\n const prefix = sanitizeIdentifier(toolPrefix ?? \"\");\n return prefix ? `${prefix}_${base}` : base;\n};\n\nexport const buildOperationId = (method: HttpMethod, path: string, operationId?: string): string => {\n if (operationId?.trim()) {\n return sanitizeIdentifier(operationId);\n }\n\n const pathPart = path\n .replace(/\\{([^}]+)\\}/g, \"by_$1\")\n .replace(/\\/+/g, \"_\");\n\n return sanitizeIdentifier(`${method}_${pathPart}`);\n};\n\nexport const pickContentSchema = (\n content: Record<string, { schema?: import(\"./types\").OpenApiSchemaObject | undefined }> | undefined\n): import(\"./types\").OpenApiSchemaObject | undefined =>\n content?.[\"application/json\"]?.schema ??\n content?.[\"application/*+json\"]?.schema ??\n Object.values(content ?? {})[0]?.schema;\n\nexport const dedupeParameters = (\n pathLevel: OpenApiParameterObject[] | undefined,\n operationLevel: OpenApiParameterObject[] | undefined\n): OpenApiParameterObject[] => {\n const byKey = new Map<string, OpenApiParameterObject>();\n\n for (const param of [...(pathLevel ?? []), ...(operationLevel ?? [])]) {\n byKey.set(`${param.in}:${param.name}`, param);\n }\n\n return [...byKey.values()];\n};\n\nexport const compactObject = <T extends Record<string, unknown>>(value: T): T => {\n const output = {} as T;\n\n for (const [key, item] of Object.entries(value)) {\n if (item !== undefined) {\n output[key as keyof T] = item as T[keyof T];\n }\n }\n\n return output;\n};\n\nexport const hasSchemaContent = (schema: JsonSchema | undefined): boolean =>\n Boolean(\n schema &&\n ((schema.properties && Object.keys(schema.properties).length > 0) ||\n (schema.required && schema.required.length > 0) ||\n schema.type ||\n schema.oneOf ||\n schema.anyOf ||\n schema.allOf)\n );\n","#!/usr/bin/env node\nimport { generatePluginFromOpenApi } from \"./generator\";\nimport { GeneratePluginOptions } from \"./types\";\n\nconst printUsage = (): void => {\n console.log(\"Usage: open-claw-sdk generate --input=<openapi.json> --outDir=<dir> --pluginId=<id> [options]\");\n console.log(\"\");\n console.log(\"Options:\");\n console.log(\" --pluginName=<name> Human-readable plugin name\");\n console.log(\" --toolPrefix=<prefix> Prefix added to every tool name\");\n console.log(\" --defaultServerUrl=<url> Override OpenAPI server URL\");\n console.log(\" --includeHeaders=true Include non-auth header params in tool schema\");\n console.log(\" --optional=false Register tools as required instead of opt-in\");\n};\n\nconst parseArgs = (argv: string[]): Record<string, string> => {\n const output: Record<string, string> = {};\n\n for (const item of argv) {\n if (!item.startsWith(\"--\")) {\n continue;\n }\n\n const [rawKey, ...rest] = item.slice(2).split(\"=\");\n if (!rawKey) {\n continue;\n }\n output[rawKey] = rest.length ? rest.join(\"=\") : \"true\";\n }\n\n return output;\n};\n\nconst parseBoolean = (value: string | undefined, defaultValue: boolean): boolean => {\n if (value === undefined) {\n return defaultValue;\n }\n\n return [\"1\", \"true\", \"yes\", \"on\"].includes(value.toLowerCase());\n};\n\nconst toGenerateOptions = (args: Record<string, string>): GeneratePluginOptions => {\n const input = args.input;\n const outDir = args.outDir;\n const pluginId = args.pluginId;\n\n if (!input || !outDir || !pluginId) {\n throw new Error(\"Missing required arguments: --input, --outDir, --pluginId\");\n }\n\n return {\n input,\n outDir,\n pluginId,\n pluginName: args.pluginName,\n toolPrefix: args.toolPrefix,\n defaultServerUrl: args.defaultServerUrl,\n includeHeaders: parseBoolean(args.includeHeaders, false),\n optional: parseBoolean(args.optional, true)\n };\n};\n\nconst main = async (): Promise<void> => {\n const command = process.argv[2];\n\n if (!command || command === \"help\" || command === \"--help\" || command === \"-h\") {\n printUsage();\n return;\n }\n\n if (command !== \"generate\") {\n throw new Error(`Unknown command: ${command}`);\n }\n\n const options = toGenerateOptions(parseArgs(process.argv.slice(3)));\n const { catalog, files } = await generatePluginFromOpenApi(options);\n\n console.log(`Generated ${catalog.tools.length} tools for plugin ${catalog.pluginId}`);\n console.log(`Manifest: ${files.manifestPath}`);\n console.log(`Module: ${files.indexPath}`);\n console.log(`Catalog: ${files.catalogPath}`);\n};\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":"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","names":["import_node_fs","path","fs","path","fs","path"]}
|
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -182,6 +182,68 @@ var openApiSchemaToJsonSchema = (schema, document, seen = /* @__PURE__ */ new Se
|
|
|
182
182
|
}
|
|
183
183
|
return jsonSchema;
|
|
184
184
|
};
|
|
185
|
+
var isObjectSchema = (schema) => {
|
|
186
|
+
const type = schema?.type;
|
|
187
|
+
if (type === "object") {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
if (Array.isArray(type)) {
|
|
191
|
+
return type.includes("object");
|
|
192
|
+
}
|
|
193
|
+
return Boolean(schema?.properties || schema?.additionalProperties);
|
|
194
|
+
};
|
|
195
|
+
var isArraySchema = (schema) => {
|
|
196
|
+
const type = schema?.type;
|
|
197
|
+
if (type === "array") {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
if (Array.isArray(type)) {
|
|
201
|
+
return type.includes("array");
|
|
202
|
+
}
|
|
203
|
+
return Boolean(schema?.items);
|
|
204
|
+
};
|
|
205
|
+
var jsonSchemasEqual = (left, right) => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
206
|
+
var normalizeBodySchemaForAgent = (schema) => {
|
|
207
|
+
if (schema.oneOf?.length) {
|
|
208
|
+
const normalizedVariants = schema.oneOf.map(normalizeBodySchemaForAgent);
|
|
209
|
+
const objectVariant = normalizedVariants.find((item) => isObjectSchema(item));
|
|
210
|
+
const arrayVariant = normalizedVariants.find((item) => isArraySchema(item));
|
|
211
|
+
if (objectVariant && arrayVariant?.items && jsonSchemasEqual(objectVariant, arrayVariant.items)) {
|
|
212
|
+
return objectVariant;
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
...schema,
|
|
216
|
+
oneOf: normalizedVariants
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
if (schema.anyOf?.length) {
|
|
220
|
+
return {
|
|
221
|
+
...schema,
|
|
222
|
+
anyOf: schema.anyOf.map(normalizeBodySchemaForAgent)
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (schema.allOf?.length) {
|
|
226
|
+
return {
|
|
227
|
+
...schema,
|
|
228
|
+
allOf: schema.allOf.map(normalizeBodySchemaForAgent)
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
if (schema.items) {
|
|
232
|
+
return {
|
|
233
|
+
...schema,
|
|
234
|
+
items: normalizeBodySchemaForAgent(schema.items)
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
if (schema.properties) {
|
|
238
|
+
return {
|
|
239
|
+
...schema,
|
|
240
|
+
properties: Object.fromEntries(
|
|
241
|
+
Object.entries(schema.properties).map(([key, value]) => [key, normalizeBodySchemaForAgent(value)])
|
|
242
|
+
)
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return schema;
|
|
246
|
+
};
|
|
185
247
|
var buildParameterSection = (sectionName, parameters, document) => {
|
|
186
248
|
if (!parameters.length) {
|
|
187
249
|
return null;
|
|
@@ -226,7 +288,7 @@ var buildToolParameters = (document, path2, operation, options, pathParameters,
|
|
|
226
288
|
}
|
|
227
289
|
}
|
|
228
290
|
if (requestBodySchema) {
|
|
229
|
-
properties.body = openApiSchemaToJsonSchema(requestBodySchema, document);
|
|
291
|
+
properties.body = normalizeBodySchemaForAgent(openApiSchemaToJsonSchema(requestBodySchema, document));
|
|
230
292
|
if (operation.requestBody?.required) {
|
|
231
293
|
required.push("body");
|
|
232
294
|
}
|
|
@@ -305,6 +367,7 @@ var convertOpenApiToTools = (document, options) => {
|
|
|
305
367
|
return {
|
|
306
368
|
pluginId: options.pluginId,
|
|
307
369
|
pluginName: options.pluginName ?? toTitleCase(options.pluginId),
|
|
370
|
+
version: options.pluginVersion,
|
|
308
371
|
description: document.info?.description?.trim() ?? `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,
|
|
309
372
|
serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,
|
|
310
373
|
optional: options.optional ?? true,
|
|
@@ -317,7 +380,7 @@ var serialize = (value) => JSON.stringify(value, null, 2);
|
|
|
317
380
|
var renderPluginManifest = (catalog) => `${serialize({
|
|
318
381
|
id: catalog.pluginId,
|
|
319
382
|
name: catalog.pluginName,
|
|
320
|
-
version: "0.1.0",
|
|
383
|
+
version: catalog.version ?? "0.1.0",
|
|
321
384
|
description: catalog.description,
|
|
322
385
|
configSchema: {
|
|
323
386
|
type: "object",
|
|
@@ -403,6 +466,7 @@ var generatePluginFromOpenApi = async (options) => {
|
|
|
403
466
|
const convertOptions = {
|
|
404
467
|
pluginId: options.pluginId,
|
|
405
468
|
pluginName: options.pluginName,
|
|
469
|
+
pluginVersion: options.pluginVersion,
|
|
406
470
|
toolPrefix: options.toolPrefix,
|
|
407
471
|
optional: options.optional,
|
|
408
472
|
includeHeaders: options.includeHeaders,
|
|
@@ -493,6 +557,106 @@ var formatToolResult = (payload) => ({
|
|
|
493
557
|
}
|
|
494
558
|
]
|
|
495
559
|
});
|
|
560
|
+
var isJsonLikeString = (value) => {
|
|
561
|
+
const trimmed = value.trim();
|
|
562
|
+
return trimmed.startsWith("{") || trimmed.startsWith("[");
|
|
563
|
+
};
|
|
564
|
+
var normalizeJsonBody = (value) => {
|
|
565
|
+
if (typeof value !== "string") {
|
|
566
|
+
return value;
|
|
567
|
+
}
|
|
568
|
+
if (!isJsonLikeString(value)) {
|
|
569
|
+
return value;
|
|
570
|
+
}
|
|
571
|
+
try {
|
|
572
|
+
return JSON.parse(value);
|
|
573
|
+
} catch {
|
|
574
|
+
return value;
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
var schemaMatchesType = (schemaType, value) => {
|
|
578
|
+
if (!schemaType) {
|
|
579
|
+
return true;
|
|
580
|
+
}
|
|
581
|
+
const allowed = Array.isArray(schemaType) ? schemaType : [schemaType];
|
|
582
|
+
return allowed.some((type) => {
|
|
583
|
+
if (type === "null") {
|
|
584
|
+
return value === null;
|
|
585
|
+
}
|
|
586
|
+
if (type === "array") {
|
|
587
|
+
return Array.isArray(value);
|
|
588
|
+
}
|
|
589
|
+
if (type === "object") {
|
|
590
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
591
|
+
}
|
|
592
|
+
return typeof value === type;
|
|
593
|
+
});
|
|
594
|
+
};
|
|
595
|
+
var validateAgainstSchema = (value, schema, path2 = "body") => {
|
|
596
|
+
if (!schema) {
|
|
597
|
+
return [];
|
|
598
|
+
}
|
|
599
|
+
const errors = [];
|
|
600
|
+
if (schema.oneOf?.length) {
|
|
601
|
+
const matches = schema.oneOf.filter((variant) => validateAgainstSchema(value, variant, path2).length === 0);
|
|
602
|
+
if (matches.length !== 1) {
|
|
603
|
+
errors.push(`${path2} must match exactly one allowed shape`);
|
|
604
|
+
}
|
|
605
|
+
return errors;
|
|
606
|
+
}
|
|
607
|
+
if (schema.anyOf?.length) {
|
|
608
|
+
const matches = schema.anyOf.some((variant) => validateAgainstSchema(value, variant, path2).length === 0);
|
|
609
|
+
if (!matches) {
|
|
610
|
+
errors.push(`${path2} must match at least one allowed shape`);
|
|
611
|
+
}
|
|
612
|
+
return errors;
|
|
613
|
+
}
|
|
614
|
+
if (schema.allOf?.length) {
|
|
615
|
+
for (const variant of schema.allOf) {
|
|
616
|
+
errors.push(...validateAgainstSchema(value, variant, path2));
|
|
617
|
+
}
|
|
618
|
+
return errors;
|
|
619
|
+
}
|
|
620
|
+
if (!schemaMatchesType(schema.type, value)) {
|
|
621
|
+
const expected = Array.isArray(schema.type) ? schema.type.join("|") : schema.type;
|
|
622
|
+
errors.push(`${path2} must be of type ${expected}`);
|
|
623
|
+
return errors;
|
|
624
|
+
}
|
|
625
|
+
if (schema.enum && !schema.enum.includes(value)) {
|
|
626
|
+
errors.push(`${path2} must be one of: ${schema.enum.join(", ")}`);
|
|
627
|
+
}
|
|
628
|
+
if (Array.isArray(value)) {
|
|
629
|
+
if (schema.items) {
|
|
630
|
+
value.forEach((item, index) => {
|
|
631
|
+
errors.push(...validateAgainstSchema(item, schema.items, `${path2}[${index}]`));
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
return errors;
|
|
635
|
+
}
|
|
636
|
+
if (typeof value === "object" && value !== null) {
|
|
637
|
+
const objectValue = value;
|
|
638
|
+
const properties = schema.properties ?? {};
|
|
639
|
+
const required = schema.required ?? [];
|
|
640
|
+
for (const key of required) {
|
|
641
|
+
if (objectValue[key] === void 0) {
|
|
642
|
+
errors.push(`${path2}.${key} is required`);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
for (const [key, childValue] of Object.entries(objectValue)) {
|
|
646
|
+
const childSchema = properties[key];
|
|
647
|
+
if (!childSchema) {
|
|
648
|
+
if (schema.additionalProperties === false) {
|
|
649
|
+
errors.push(`${path2}.${key} is not allowed`);
|
|
650
|
+
} else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
651
|
+
errors.push(...validateAgainstSchema(childValue, schema.additionalProperties, `${path2}.${key}`));
|
|
652
|
+
}
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
errors.push(...validateAgainstSchema(childValue, childSchema, `${path2}.${key}`));
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
return errors;
|
|
659
|
+
};
|
|
496
660
|
var createOpenApiPlugin = (catalog, options) => {
|
|
497
661
|
return function register(api) {
|
|
498
662
|
for (const tool of catalog.tools) {
|
|
@@ -516,14 +680,29 @@ var createOpenApiPlugin = (catalog, options) => {
|
|
|
516
680
|
const timeoutMs = runtimeConfig.timeoutMs ?? options?.timeoutMs;
|
|
517
681
|
const timeout = timeoutMs ? setTimeout(() => controller.abort(), timeoutMs) : void 0;
|
|
518
682
|
try {
|
|
519
|
-
const
|
|
683
|
+
const normalizedBody = normalizeJsonBody(input.body);
|
|
684
|
+
const hasBody = normalizedBody !== void 0;
|
|
520
685
|
const requestInit = {
|
|
521
686
|
method: tool.method,
|
|
522
687
|
headers: buildHeaders(runtimeConfig, input.headers, hasBody),
|
|
523
688
|
signal: controller.signal
|
|
524
689
|
};
|
|
525
690
|
if (hasBody) {
|
|
526
|
-
|
|
691
|
+
const bodySchema = tool.parameters.properties?.body;
|
|
692
|
+
const bodyValidationErrors = validateAgainstSchema(normalizedBody, bodySchema);
|
|
693
|
+
if (bodyValidationErrors.length > 0) {
|
|
694
|
+
return formatToolResult({
|
|
695
|
+
ok: false,
|
|
696
|
+
status: 400,
|
|
697
|
+
statusText: "INVALID_TOOL_INPUT",
|
|
698
|
+
data: {
|
|
699
|
+
message: "Tool input body does not match the generated schema.",
|
|
700
|
+
errors: bodyValidationErrors,
|
|
701
|
+
received: normalizedBody
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
requestInit.body = JSON.stringify(normalizedBody);
|
|
527
706
|
}
|
|
528
707
|
const response = await fetch(finalUrl, requestInit);
|
|
529
708
|
const payload = await parseResponse(response);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/generator.ts","../src/openapi.ts","../src/utils.ts","../src/runtime.ts"],"sourcesContent":["export * from \"./generator\";\nexport * from \"./openapi\";\nexport * from \"./runtime\";\nexport * from \"./types\";\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n ConvertOpenApiOptions,\n GeneratedPluginFiles,\n GeneratePluginOptions,\n OpenClawPluginCatalog\n} from \"./types\";\nimport { convertOpenApiToTools, loadOpenApiDocument } from \"./openapi\";\n\nconst serialize = (value: unknown): string => JSON.stringify(value, null, 2);\n\nexport const renderPluginManifest = (catalog: OpenClawPluginCatalog): string =>\n `${serialize({\n id: catalog.pluginId,\n name: catalog.pluginName,\n version: \"0.1.0\",\n description: catalog.description,\n configSchema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n baseUrl: {\n type: \"string\",\n description: \"Base URL of the target HTTP API\"\n },\n bearerToken: {\n type: \"string\",\n description: \"Bearer token used for Authorization header\"\n },\n apiKey: {\n type: \"string\",\n description: \"Static API key for the upstream API\"\n },\n apiKeyHeader: {\n type: \"string\",\n description: \"Header name used when apiKey is set\",\n default: \"x-api-key\"\n },\n timeoutMs: {\n type: \"number\",\n description: \"Timeout in milliseconds for outbound tool calls\"\n },\n defaultHeaders: {\n type: \"object\",\n additionalProperties: {\n type: \"string\"\n },\n description: \"Additional headers added to every request\"\n }\n }\n },\n uiHints: {\n baseUrl: {\n label: \"Base URL\",\n placeholder: catalog.serverUrl ?? \"https://api.example.com\"\n },\n bearerToken: {\n label: \"Bearer Token\",\n sensitive: true\n },\n apiKey: {\n label: \"API Key\",\n sensitive: true\n },\n apiKeyHeader: {\n label: \"API Key Header\"\n },\n timeoutMs: {\n label: \"Timeout (ms)\"\n }\n }\n })}\\n`;\n\nexport const renderPluginModule = (catalog: OpenClawPluginCatalog): string =>\n `import { createOpenApiPlugin } from \"@redonvn/open-claw-sdk\";\n\nexport const catalog = ${serialize(catalog)} as const;\n\nexport default createOpenApiPlugin(catalog);\n`;\n\nexport const renderCatalogFile = (catalog: OpenClawPluginCatalog): string =>\n `${serialize(catalog)}\\n`;\n\nconst ensureDir = async (dirPath: string): Promise<void> => {\n await fs.mkdir(dirPath, { recursive: true });\n};\n\nexport const writeGeneratedPlugin = async (\n catalog: OpenClawPluginCatalog,\n outDir: string\n): Promise<GeneratedPluginFiles> => {\n await ensureDir(outDir);\n\n const manifestPath = path.join(outDir, \"openclaw.plugin.json\");\n const indexPath = path.join(outDir, \"index.ts\");\n const catalogPath = path.join(outDir, \"tool-catalog.json\");\n\n await Promise.all([\n fs.writeFile(manifestPath, renderPluginManifest(catalog), \"utf8\"),\n fs.writeFile(indexPath, renderPluginModule(catalog), \"utf8\"),\n fs.writeFile(catalogPath, renderCatalogFile(catalog), \"utf8\")\n ]);\n\n return { manifestPath, indexPath, catalogPath };\n};\n\nexport const generatePluginFromOpenApi = async (\n options: GeneratePluginOptions\n): Promise<{ catalog: OpenClawPluginCatalog; files: GeneratedPluginFiles }> => {\n const document = await loadOpenApiDocument(options.input);\n const convertOptions: ConvertOpenApiOptions = {\n pluginId: options.pluginId,\n pluginName: options.pluginName,\n toolPrefix: options.toolPrefix,\n optional: options.optional,\n includeHeaders: options.includeHeaders,\n defaultServerUrl: options.defaultServerUrl\n };\n const catalog = convertOpenApiToTools(document, convertOptions);\n const files = await writeGeneratedPlugin(catalog, options.outDir);\n\n return { catalog, files };\n};\n","import { promises as fs } from \"node:fs\";\nimport {\n ConvertOpenApiOptions,\n JsonSchema,\n OpenApiDocument,\n OpenApiOperationObject,\n OpenClawPluginCatalog,\n OpenClawToolDefinition\n} from \"./types\";\nimport {\n AUTH_HEADER_NAMES,\n HTTP_METHODS,\n buildOperationId,\n buildToolName,\n compactObject,\n dedupeParameters,\n hasSchemaContent,\n pickContentSchema,\n toTitleCase\n} from \"./utils\";\n\nconst isHttpUrl = (value: string): boolean => /^https?:\\/\\//i.test(value);\n\nconst readUrl = async (url: string): Promise<string> => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Unable to load OpenAPI document from ${url}: ${response.status} ${response.statusText}`);\n }\n\n return response.text();\n};\n\nexport const loadOpenApiDocument = async (source: string): Promise<OpenApiDocument> => {\n const raw = isHttpUrl(source)\n ? await readUrl(source)\n : await fs.readFile(source, \"utf8\");\n\n const document = JSON.parse(raw) as OpenApiDocument;\n\n if (!document.openapi || !document.paths) {\n throw new Error(\"Invalid OpenAPI document: missing `openapi` or `paths`.\");\n }\n\n return document;\n};\n\nconst cloneJsonSchema = (value: JsonSchema): JsonSchema => JSON.parse(JSON.stringify(value)) as JsonSchema;\n\nconst resolveRefName = (ref: string): string => ref.split(\"/\").pop() ?? \"UnknownSchema\";\n\nconst resolveSchemaRef = (\n document: OpenApiDocument,\n ref: string\n): import(\"./types\").OpenApiSchemaObject | undefined => {\n const schemaName = resolveRefName(ref);\n return document.components?.schemas?.[schemaName];\n};\n\nexport const openApiSchemaToJsonSchema = (\n schema: import(\"./types\").OpenApiSchemaObject | undefined,\n document: OpenApiDocument,\n seen = new Set<string>()\n): JsonSchema => {\n if (!schema) {\n return { type: \"object\", additionalProperties: true };\n }\n\n if (schema.$ref) {\n if (seen.has(schema.$ref)) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const resolved = resolveSchemaRef(document, schema.$ref);\n\n if (!resolved) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const nextSeen = new Set(seen);\n nextSeen.add(schema.$ref);\n return openApiSchemaToJsonSchema(resolved, document, nextSeen);\n }\n\n const jsonSchema: JsonSchema = compactObject({\n type: Array.isArray(schema.type) ? [...schema.type] : schema.type,\n description: schema.description,\n default: schema.default,\n enum: schema.enum ? [...schema.enum] : undefined\n });\n\n if (schema.oneOf?.length) {\n jsonSchema.oneOf = schema.oneOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.anyOf?.length) {\n jsonSchema.anyOf = schema.anyOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.allOf?.length) {\n jsonSchema.allOf = schema.allOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.items) {\n jsonSchema.items = openApiSchemaToJsonSchema(schema.items, document, seen);\n }\n\n if (schema.properties) {\n jsonSchema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [\n key,\n openApiSchemaToJsonSchema(value, document, seen)\n ])\n );\n }\n\n if (schema.required?.length) {\n jsonSchema.required = [...schema.required];\n }\n\n if (schema.additionalProperties !== undefined) {\n jsonSchema.additionalProperties =\n schema.additionalProperties === true || schema.additionalProperties === false\n ? schema.additionalProperties\n : openApiSchemaToJsonSchema(schema.additionalProperties, document, seen);\n }\n\n if (schema.nullable) {\n const currentType = jsonSchema.type;\n\n if (Array.isArray(currentType)) {\n jsonSchema.type = currentType.includes(\"null\") ? currentType : [...currentType, \"null\"];\n } else if (currentType) {\n jsonSchema.type = currentType === \"null\" ? \"null\" : [currentType, \"null\"];\n } else {\n jsonSchema.type = [\"object\", \"null\"];\n }\n }\n\n return jsonSchema;\n};\n\nconst buildParameterSection = (\n sectionName: string,\n parameters: import(\"./types\").OpenApiParameterObject[],\n document: OpenApiDocument\n): { name: string; schema: JsonSchema; required: boolean } | null => {\n if (!parameters.length) {\n return null;\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const parameter of parameters) {\n properties[parameter.name] = compactObject({\n ...openApiSchemaToJsonSchema(parameter.schema, document),\n description: parameter.description ?? parameter.schema?.description\n });\n\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n return {\n name: sectionName,\n required: required.length > 0,\n schema: compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false\n })\n };\n};\n\nconst buildToolParameters = (\n document: OpenApiDocument,\n path: string,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): JsonSchema => {\n const requestBodySchema = pickContentSchema(operation.requestBody?.content);\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n const sections = [\n buildParameterSection(\"path\", pathParameters, document),\n buildParameterSection(\"query\", queryParameters, document),\n options.includeHeaders ? buildParameterSection(\"headers\", headerParameters, document) : null\n ].filter((value): value is { name: string; schema: JsonSchema; required: boolean } => Boolean(value));\n\n for (const section of sections) {\n if (hasSchemaContent(section.schema)) {\n properties[section.name] = section.schema;\n if (section.required) {\n required.push(section.name);\n }\n }\n }\n\n if (requestBodySchema) {\n properties.body = openApiSchemaToJsonSchema(requestBodySchema, document);\n if (operation.requestBody?.required) {\n required.push(\"body\");\n }\n }\n\n return compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false,\n description: `${operation.summary ?? operation.operationId ?? `${path} request`} tool arguments`\n });\n};\n\nconst buildToolDescription = (path: string, method: string, operation: OpenApiOperationObject): string => {\n const summary = operation.summary?.trim();\n const description = operation.description?.trim();\n\n if (summary && description && description !== summary) {\n return `${summary}. ${description}`;\n }\n\n if (summary) {\n return summary;\n }\n\n if (description) {\n return description;\n }\n\n return `${method.toUpperCase()} ${path}`;\n};\n\nconst buildToolDefinition = (\n document: OpenApiDocument,\n path: string,\n method: import(\"./types\").HttpMethod,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): OpenClawToolDefinition => {\n const operationId = buildOperationId(method, path, operation.operationId);\n\n return {\n name: buildToolName(options.toolPrefix, operationId),\n description: buildToolDescription(path, method, operation),\n method: method.toUpperCase() as Uppercase<typeof method>,\n path,\n operationId,\n parameters: buildToolParameters(\n document,\n path,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n ),\n tags: operation.tags ?? []\n };\n};\n\nexport const convertOpenApiToTools = (\n document: OpenApiDocument,\n options: ConvertOpenApiOptions\n): OpenClawPluginCatalog => {\n const tools: OpenClawToolDefinition[] = [];\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const parameters = dedupeParameters(pathItem.parameters, operation.parameters);\n const pathParameters = parameters.filter((parameter) => parameter.in === \"path\");\n const queryParameters = parameters.filter((parameter) => parameter.in === \"query\");\n const headerParameters = parameters.filter(\n (parameter) =>\n parameter.in === \"header\" &&\n !AUTH_HEADER_NAMES.has(parameter.name.toLowerCase())\n );\n\n tools.push(\n buildToolDefinition(\n document,\n path,\n method,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n )\n );\n }\n }\n\n tools.sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n pluginId: options.pluginId,\n pluginName: options.pluginName ?? toTitleCase(options.pluginId),\n description:\n document.info?.description?.trim() ??\n `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,\n serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,\n optional: options.optional ?? true,\n tools\n };\n};\n","import { HttpMethod, JsonSchema, OpenApiParameterObject } from \"./types\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"options\",\n \"head\"\n];\n\nexport const AUTH_HEADER_NAMES = new Set([\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"dt-jwt\"\n]);\n\nexport const sanitizeIdentifier = (value: string): string =>\n value\n .trim()\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .replace(/_{2,}/g, \"_\")\n .toLowerCase() || \"tool\";\n\nexport const toTitleCase = (value: string): string =>\n value\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\nexport const buildToolName = (toolPrefix: string | undefined, rawName: string): string => {\n const base = sanitizeIdentifier(rawName);\n const prefix = sanitizeIdentifier(toolPrefix ?? \"\");\n return prefix ? `${prefix}_${base}` : base;\n};\n\nexport const buildOperationId = (method: HttpMethod, path: string, operationId?: string): string => {\n if (operationId?.trim()) {\n return sanitizeIdentifier(operationId);\n }\n\n const pathPart = path\n .replace(/\\{([^}]+)\\}/g, \"by_$1\")\n .replace(/\\/+/g, \"_\");\n\n return sanitizeIdentifier(`${method}_${pathPart}`);\n};\n\nexport const pickContentSchema = (\n content: Record<string, { schema?: import(\"./types\").OpenApiSchemaObject | undefined }> | undefined\n): import(\"./types\").OpenApiSchemaObject | undefined =>\n content?.[\"application/json\"]?.schema ??\n content?.[\"application/*+json\"]?.schema ??\n Object.values(content ?? {})[0]?.schema;\n\nexport const dedupeParameters = (\n pathLevel: OpenApiParameterObject[] | undefined,\n operationLevel: OpenApiParameterObject[] | undefined\n): OpenApiParameterObject[] => {\n const byKey = new Map<string, OpenApiParameterObject>();\n\n for (const param of [...(pathLevel ?? []), ...(operationLevel ?? [])]) {\n byKey.set(`${param.in}:${param.name}`, param);\n }\n\n return [...byKey.values()];\n};\n\nexport const compactObject = <T extends Record<string, unknown>>(value: T): T => {\n const output = {} as T;\n\n for (const [key, item] of Object.entries(value)) {\n if (item !== undefined) {\n output[key as keyof T] = item as T[keyof T];\n }\n }\n\n return output;\n};\n\nexport const hasSchemaContent = (schema: JsonSchema | undefined): boolean =>\n Boolean(\n schema &&\n ((schema.properties && Object.keys(schema.properties).length > 0) ||\n (schema.required && schema.required.length > 0) ||\n schema.type ||\n schema.oneOf ||\n schema.anyOf ||\n schema.allOf)\n );\n","import { CreatePluginFactoryOptions, OpenClawApiLike, OpenClawPluginCatalog, PluginRuntimeConfig } from \"./types\";\n\nconst encodeQueryValue = (value: unknown): string => {\n if (value === null) {\n return \"null\";\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n return JSON.stringify(value);\n};\n\nconst applyPathParams = (pathTemplate: string, pathParams: Record<string, unknown> | undefined): string =>\n pathTemplate.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const raw = pathParams?.[key];\n\n if (raw === undefined || raw === null) {\n throw new Error(`Missing required path parameter: ${key}`);\n }\n\n return encodeURIComponent(String(raw));\n });\n\nconst createRequestUrl = (baseUrl: string, requestPath: string): URL => {\n const url = new URL(baseUrl);\n const normalizedBasePath = url.pathname.replace(/\\/+$/, \"\");\n const normalizedRequestPath = requestPath.startsWith(\"/\") ? requestPath : `/${requestPath}`;\n\n url.pathname = `${normalizedBasePath}${normalizedRequestPath}`.replace(/\\/{2,}/g, \"/\");\n\n return url;\n};\n\nconst appendQueryParams = (url: URL, query: Record<string, unknown> | undefined): void => {\n if (!query) {\n return;\n }\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, encodeQueryValue(item));\n }\n continue;\n }\n\n url.searchParams.set(key, encodeQueryValue(value));\n }\n};\n\nconst resolvePluginConfig = (api: OpenClawApiLike, pluginId: string): PluginRuntimeConfig =>\n api.config?.plugins?.entries?.[pluginId]?.config ?? {};\n\nconst buildHeaders = (\n runtimeConfig: PluginRuntimeConfig,\n requestHeaders: Record<string, unknown> | undefined,\n hasBody: boolean\n): Headers => {\n const headers = new Headers();\n\n for (const [key, value] of Object.entries(runtimeConfig.defaultHeaders ?? {})) {\n headers.set(key, value);\n }\n\n if (runtimeConfig.bearerToken) {\n headers.set(\"authorization\", `Bearer ${runtimeConfig.bearerToken}`);\n } else if (runtimeConfig.apiKey) {\n headers.set(runtimeConfig.apiKeyHeader ?? \"x-api-key\", runtimeConfig.apiKey);\n }\n\n for (const [key, value] of Object.entries(requestHeaders ?? {})) {\n if (value !== undefined && value !== null) {\n headers.set(key, String(value));\n }\n }\n\n if (hasBody && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return headers;\n};\n\nconst parseResponse = async (response: Response): Promise<unknown> => {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n};\n\nconst formatToolResult = (payload: unknown): { content: Array<{ type: \"text\"; text: string }> } => ({\n content: [\n {\n type: \"text\",\n text: typeof payload === \"string\" ? payload : JSON.stringify(payload, null, 2)\n }\n ]\n});\n\nexport const createOpenApiPlugin = (\n catalog: OpenClawPluginCatalog,\n options?: CreatePluginFactoryOptions\n) => {\n return function register(api: OpenClawApiLike): void {\n for (const tool of catalog.tools) {\n api.registerTool(\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n execute: async (_id, params) => {\n const runtimeConfig = resolvePluginConfig(api, catalog.pluginId);\n const baseUrl = runtimeConfig.baseUrl ?? catalog.serverUrl;\n\n if (!baseUrl) {\n throw new Error(\n `Missing baseUrl for plugin ${catalog.pluginId}. Set plugins.entries.${catalog.pluginId}.config.baseUrl.`\n );\n }\n\n const input = (params ?? {}) as {\n path?: Record<string, unknown>;\n query?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n body?: unknown;\n };\n\n const finalUrl = createRequestUrl(baseUrl, applyPathParams(tool.path, input.path));\n\n appendQueryParams(finalUrl, input.query);\n\n const controller = new AbortController();\n const timeoutMs = runtimeConfig.timeoutMs ?? options?.timeoutMs;\n const timeout = timeoutMs\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n try {\n const hasBody = input.body !== undefined;\n const requestInit: RequestInit = {\n method: tool.method,\n headers: buildHeaders(runtimeConfig, input.headers, hasBody),\n signal: controller.signal\n };\n\n if (hasBody) {\n requestInit.body = JSON.stringify(input.body);\n }\n\n const response = await fetch(finalUrl, requestInit);\n\n const payload = await parseResponse(response);\n\n if (!response.ok) {\n return formatToolResult({\n ok: false,\n status: response.status,\n statusText: response.statusText,\n data: payload\n });\n }\n\n return formatToolResult(payload);\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n }\n }\n },\n { optional: catalog.optional ?? true }\n );\n }\n };\n};\n"],"mappings":"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","names":["import_node_fs","path","fs","path","fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/generator.ts","../src/openapi.ts","../src/utils.ts","../src/runtime.ts"],"sourcesContent":["export * from \"./generator\";\nexport * from \"./openapi\";\nexport * from \"./runtime\";\nexport * from \"./types\";\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n ConvertOpenApiOptions,\n GeneratedPluginFiles,\n GeneratePluginOptions,\n OpenClawPluginCatalog\n} from \"./types\";\nimport { convertOpenApiToTools, loadOpenApiDocument } from \"./openapi\";\n\nconst serialize = (value: unknown): string => JSON.stringify(value, null, 2);\n\nexport const renderPluginManifest = (catalog: OpenClawPluginCatalog): string =>\n `${serialize({\n id: catalog.pluginId,\n name: catalog.pluginName,\n version: catalog.version ?? \"0.1.0\",\n description: catalog.description,\n configSchema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n baseUrl: {\n type: \"string\",\n description: \"Base URL of the target HTTP API\"\n },\n bearerToken: {\n type: \"string\",\n description: \"Bearer token used for Authorization header\"\n },\n apiKey: {\n type: \"string\",\n description: \"Static API key for the upstream API\"\n },\n apiKeyHeader: {\n type: \"string\",\n description: \"Header name used when apiKey is set\",\n default: \"x-api-key\"\n },\n timeoutMs: {\n type: \"number\",\n description: \"Timeout in milliseconds for outbound tool calls\"\n },\n defaultHeaders: {\n type: \"object\",\n additionalProperties: {\n type: \"string\"\n },\n description: \"Additional headers added to every request\"\n }\n }\n },\n uiHints: {\n baseUrl: {\n label: \"Base URL\",\n placeholder: catalog.serverUrl ?? \"https://api.example.com\"\n },\n bearerToken: {\n label: \"Bearer Token\",\n sensitive: true\n },\n apiKey: {\n label: \"API Key\",\n sensitive: true\n },\n apiKeyHeader: {\n label: \"API Key Header\"\n },\n timeoutMs: {\n label: \"Timeout (ms)\"\n }\n }\n })}\\n`;\n\nexport const renderPluginModule = (catalog: OpenClawPluginCatalog): string =>\n `import { createOpenApiPlugin } from \"@redonvn/open-claw-sdk\";\n\nexport const catalog = ${serialize(catalog)} as const;\n\nexport default createOpenApiPlugin(catalog);\n`;\n\nexport const renderCatalogFile = (catalog: OpenClawPluginCatalog): string =>\n `${serialize(catalog)}\\n`;\n\nconst ensureDir = async (dirPath: string): Promise<void> => {\n await fs.mkdir(dirPath, { recursive: true });\n};\n\nexport const writeGeneratedPlugin = async (\n catalog: OpenClawPluginCatalog,\n outDir: string\n): Promise<GeneratedPluginFiles> => {\n await ensureDir(outDir);\n\n const manifestPath = path.join(outDir, \"openclaw.plugin.json\");\n const indexPath = path.join(outDir, \"index.ts\");\n const catalogPath = path.join(outDir, \"tool-catalog.json\");\n\n await Promise.all([\n fs.writeFile(manifestPath, renderPluginManifest(catalog), \"utf8\"),\n fs.writeFile(indexPath, renderPluginModule(catalog), \"utf8\"),\n fs.writeFile(catalogPath, renderCatalogFile(catalog), \"utf8\")\n ]);\n\n return { manifestPath, indexPath, catalogPath };\n};\n\nexport const generatePluginFromOpenApi = async (\n options: GeneratePluginOptions\n): Promise<{ catalog: OpenClawPluginCatalog; files: GeneratedPluginFiles }> => {\n const document = await loadOpenApiDocument(options.input);\n const convertOptions: ConvertOpenApiOptions = {\n pluginId: options.pluginId,\n pluginName: options.pluginName,\n pluginVersion: options.pluginVersion,\n toolPrefix: options.toolPrefix,\n optional: options.optional,\n includeHeaders: options.includeHeaders,\n defaultServerUrl: options.defaultServerUrl\n };\n const catalog = convertOpenApiToTools(document, convertOptions);\n const files = await writeGeneratedPlugin(catalog, options.outDir);\n\n return { catalog, files };\n};\n","import { promises as fs } from \"node:fs\";\nimport {\n ConvertOpenApiOptions,\n JsonSchema,\n OpenApiDocument,\n OpenApiOperationObject,\n OpenClawPluginCatalog,\n OpenClawToolDefinition\n} from \"./types\";\nimport {\n AUTH_HEADER_NAMES,\n HTTP_METHODS,\n buildOperationId,\n buildToolName,\n compactObject,\n dedupeParameters,\n hasSchemaContent,\n pickContentSchema,\n toTitleCase\n} from \"./utils\";\n\nconst isHttpUrl = (value: string): boolean => /^https?:\\/\\//i.test(value);\n\nconst readUrl = async (url: string): Promise<string> => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Unable to load OpenAPI document from ${url}: ${response.status} ${response.statusText}`);\n }\n\n return response.text();\n};\n\nexport const loadOpenApiDocument = async (source: string): Promise<OpenApiDocument> => {\n const raw = isHttpUrl(source)\n ? await readUrl(source)\n : await fs.readFile(source, \"utf8\");\n\n const document = JSON.parse(raw) as OpenApiDocument;\n\n if (!document.openapi || !document.paths) {\n throw new Error(\"Invalid OpenAPI document: missing `openapi` or `paths`.\");\n }\n\n return document;\n};\n\nconst cloneJsonSchema = (value: JsonSchema): JsonSchema => JSON.parse(JSON.stringify(value)) as JsonSchema;\n\nconst resolveRefName = (ref: string): string => ref.split(\"/\").pop() ?? \"UnknownSchema\";\n\nconst resolveSchemaRef = (\n document: OpenApiDocument,\n ref: string\n): import(\"./types\").OpenApiSchemaObject | undefined => {\n const schemaName = resolveRefName(ref);\n return document.components?.schemas?.[schemaName];\n};\n\nexport const openApiSchemaToJsonSchema = (\n schema: import(\"./types\").OpenApiSchemaObject | undefined,\n document: OpenApiDocument,\n seen = new Set<string>()\n): JsonSchema => {\n if (!schema) {\n return { type: \"object\", additionalProperties: true };\n }\n\n if (schema.$ref) {\n if (seen.has(schema.$ref)) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const resolved = resolveSchemaRef(document, schema.$ref);\n\n if (!resolved) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const nextSeen = new Set(seen);\n nextSeen.add(schema.$ref);\n return openApiSchemaToJsonSchema(resolved, document, nextSeen);\n }\n\n const jsonSchema: JsonSchema = compactObject({\n type: Array.isArray(schema.type) ? [...schema.type] : schema.type,\n description: schema.description,\n default: schema.default,\n enum: schema.enum ? [...schema.enum] : undefined\n });\n\n if (schema.oneOf?.length) {\n jsonSchema.oneOf = schema.oneOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.anyOf?.length) {\n jsonSchema.anyOf = schema.anyOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.allOf?.length) {\n jsonSchema.allOf = schema.allOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.items) {\n jsonSchema.items = openApiSchemaToJsonSchema(schema.items, document, seen);\n }\n\n if (schema.properties) {\n jsonSchema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [\n key,\n openApiSchemaToJsonSchema(value, document, seen)\n ])\n );\n }\n\n if (schema.required?.length) {\n jsonSchema.required = [...schema.required];\n }\n\n if (schema.additionalProperties !== undefined) {\n jsonSchema.additionalProperties =\n schema.additionalProperties === true || schema.additionalProperties === false\n ? schema.additionalProperties\n : openApiSchemaToJsonSchema(schema.additionalProperties, document, seen);\n }\n\n if (schema.nullable) {\n const currentType = jsonSchema.type;\n\n if (Array.isArray(currentType)) {\n jsonSchema.type = currentType.includes(\"null\") ? currentType : [...currentType, \"null\"];\n } else if (currentType) {\n jsonSchema.type = currentType === \"null\" ? \"null\" : [currentType, \"null\"];\n } else {\n jsonSchema.type = [\"object\", \"null\"];\n }\n }\n\n return jsonSchema;\n};\n\nconst isObjectSchema = (schema: JsonSchema | undefined): boolean => {\n const type = schema?.type;\n\n if (type === \"object\") {\n return true;\n }\n\n if (Array.isArray(type)) {\n return type.includes(\"object\");\n }\n\n return Boolean(schema?.properties || schema?.additionalProperties);\n};\n\nconst isArraySchema = (schema: JsonSchema | undefined): boolean => {\n const type = schema?.type;\n\n if (type === \"array\") {\n return true;\n }\n\n if (Array.isArray(type)) {\n return type.includes(\"array\");\n }\n\n return Boolean(schema?.items);\n};\n\nconst jsonSchemasEqual = (left: JsonSchema | undefined, right: JsonSchema | undefined): boolean =>\n JSON.stringify(left ?? null) === JSON.stringify(right ?? null);\n\nconst normalizeBodySchemaForAgent = (schema: JsonSchema): JsonSchema => {\n if (schema.oneOf?.length) {\n const normalizedVariants = schema.oneOf.map(normalizeBodySchemaForAgent);\n const objectVariant = normalizedVariants.find((item) => isObjectSchema(item));\n const arrayVariant = normalizedVariants.find((item) => isArraySchema(item));\n\n if (\n objectVariant &&\n arrayVariant?.items &&\n jsonSchemasEqual(objectVariant, arrayVariant.items)\n ) {\n // AI-facing tools are much more reliable when a request body has one clear object shape.\n // When OpenAPI exposes \"single object OR array of same object\", prefer the single-object form.\n return objectVariant;\n }\n\n return {\n ...schema,\n oneOf: normalizedVariants\n };\n }\n\n if (schema.anyOf?.length) {\n return {\n ...schema,\n anyOf: schema.anyOf.map(normalizeBodySchemaForAgent)\n };\n }\n\n if (schema.allOf?.length) {\n return {\n ...schema,\n allOf: schema.allOf.map(normalizeBodySchemaForAgent)\n };\n }\n\n if (schema.items) {\n return {\n ...schema,\n items: normalizeBodySchemaForAgent(schema.items)\n };\n }\n\n if (schema.properties) {\n return {\n ...schema,\n properties: Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [key, normalizeBodySchemaForAgent(value)])\n )\n };\n }\n\n return schema;\n};\n\nconst buildParameterSection = (\n sectionName: string,\n parameters: import(\"./types\").OpenApiParameterObject[],\n document: OpenApiDocument\n): { name: string; schema: JsonSchema; required: boolean } | null => {\n if (!parameters.length) {\n return null;\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const parameter of parameters) {\n properties[parameter.name] = compactObject({\n ...openApiSchemaToJsonSchema(parameter.schema, document),\n description: parameter.description ?? parameter.schema?.description\n });\n\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n return {\n name: sectionName,\n required: required.length > 0,\n schema: compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false\n })\n };\n};\n\nconst buildToolParameters = (\n document: OpenApiDocument,\n path: string,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): JsonSchema => {\n const requestBodySchema = pickContentSchema(operation.requestBody?.content);\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n const sections = [\n buildParameterSection(\"path\", pathParameters, document),\n buildParameterSection(\"query\", queryParameters, document),\n options.includeHeaders ? buildParameterSection(\"headers\", headerParameters, document) : null\n ].filter((value): value is { name: string; schema: JsonSchema; required: boolean } => Boolean(value));\n\n for (const section of sections) {\n if (hasSchemaContent(section.schema)) {\n properties[section.name] = section.schema;\n if (section.required) {\n required.push(section.name);\n }\n }\n }\n\n if (requestBodySchema) {\n properties.body = normalizeBodySchemaForAgent(openApiSchemaToJsonSchema(requestBodySchema, document));\n if (operation.requestBody?.required) {\n required.push(\"body\");\n }\n }\n\n return compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false,\n description: `${operation.summary ?? operation.operationId ?? `${path} request`} tool arguments`\n });\n};\n\nconst buildToolDescription = (path: string, method: string, operation: OpenApiOperationObject): string => {\n const summary = operation.summary?.trim();\n const description = operation.description?.trim();\n\n if (summary && description && description !== summary) {\n return `${summary}. ${description}`;\n }\n\n if (summary) {\n return summary;\n }\n\n if (description) {\n return description;\n }\n\n return `${method.toUpperCase()} ${path}`;\n};\n\nconst buildToolDefinition = (\n document: OpenApiDocument,\n path: string,\n method: import(\"./types\").HttpMethod,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): OpenClawToolDefinition => {\n const operationId = buildOperationId(method, path, operation.operationId);\n\n return {\n name: buildToolName(options.toolPrefix, operationId),\n description: buildToolDescription(path, method, operation),\n method: method.toUpperCase() as Uppercase<typeof method>,\n path,\n operationId,\n parameters: buildToolParameters(\n document,\n path,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n ),\n tags: operation.tags ?? []\n };\n};\n\nexport const convertOpenApiToTools = (\n document: OpenApiDocument,\n options: ConvertOpenApiOptions\n): OpenClawPluginCatalog => {\n const tools: OpenClawToolDefinition[] = [];\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const parameters = dedupeParameters(pathItem.parameters, operation.parameters);\n const pathParameters = parameters.filter((parameter) => parameter.in === \"path\");\n const queryParameters = parameters.filter((parameter) => parameter.in === \"query\");\n const headerParameters = parameters.filter(\n (parameter) =>\n parameter.in === \"header\" &&\n !AUTH_HEADER_NAMES.has(parameter.name.toLowerCase())\n );\n\n tools.push(\n buildToolDefinition(\n document,\n path,\n method,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n )\n );\n }\n }\n\n tools.sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n pluginId: options.pluginId,\n pluginName: options.pluginName ?? toTitleCase(options.pluginId),\n version: options.pluginVersion,\n description:\n document.info?.description?.trim() ??\n `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,\n serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,\n optional: options.optional ?? true,\n tools\n };\n};\n","import { HttpMethod, JsonSchema, OpenApiParameterObject } from \"./types\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"options\",\n \"head\"\n];\n\nexport const AUTH_HEADER_NAMES = new Set([\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"dt-jwt\"\n]);\n\nexport const sanitizeIdentifier = (value: string): string =>\n value\n .trim()\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .replace(/_{2,}/g, \"_\")\n .toLowerCase() || \"tool\";\n\nexport const toTitleCase = (value: string): string =>\n value\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\nexport const buildToolName = (toolPrefix: string | undefined, rawName: string): string => {\n const base = sanitizeIdentifier(rawName);\n const prefix = sanitizeIdentifier(toolPrefix ?? \"\");\n return prefix ? `${prefix}_${base}` : base;\n};\n\nexport const buildOperationId = (method: HttpMethod, path: string, operationId?: string): string => {\n if (operationId?.trim()) {\n return sanitizeIdentifier(operationId);\n }\n\n const pathPart = path\n .replace(/\\{([^}]+)\\}/g, \"by_$1\")\n .replace(/\\/+/g, \"_\");\n\n return sanitizeIdentifier(`${method}_${pathPart}`);\n};\n\nexport const pickContentSchema = (\n content: Record<string, { schema?: import(\"./types\").OpenApiSchemaObject | undefined }> | undefined\n): import(\"./types\").OpenApiSchemaObject | undefined =>\n content?.[\"application/json\"]?.schema ??\n content?.[\"application/*+json\"]?.schema ??\n Object.values(content ?? {})[0]?.schema;\n\nexport const dedupeParameters = (\n pathLevel: OpenApiParameterObject[] | undefined,\n operationLevel: OpenApiParameterObject[] | undefined\n): OpenApiParameterObject[] => {\n const byKey = new Map<string, OpenApiParameterObject>();\n\n for (const param of [...(pathLevel ?? []), ...(operationLevel ?? [])]) {\n byKey.set(`${param.in}:${param.name}`, param);\n }\n\n return [...byKey.values()];\n};\n\nexport const compactObject = <T extends Record<string, unknown>>(value: T): T => {\n const output = {} as T;\n\n for (const [key, item] of Object.entries(value)) {\n if (item !== undefined) {\n output[key as keyof T] = item as T[keyof T];\n }\n }\n\n return output;\n};\n\nexport const hasSchemaContent = (schema: JsonSchema | undefined): boolean =>\n Boolean(\n schema &&\n ((schema.properties && Object.keys(schema.properties).length > 0) ||\n (schema.required && schema.required.length > 0) ||\n schema.type ||\n schema.oneOf ||\n schema.anyOf ||\n schema.allOf)\n );\n","import { CreatePluginFactoryOptions, OpenClawApiLike, OpenClawPluginCatalog, PluginRuntimeConfig } from \"./types\";\n\nconst encodeQueryValue = (value: unknown): string => {\n if (value === null) {\n return \"null\";\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n return JSON.stringify(value);\n};\n\nconst applyPathParams = (pathTemplate: string, pathParams: Record<string, unknown> | undefined): string =>\n pathTemplate.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const raw = pathParams?.[key];\n\n if (raw === undefined || raw === null) {\n throw new Error(`Missing required path parameter: ${key}`);\n }\n\n return encodeURIComponent(String(raw));\n });\n\nconst createRequestUrl = (baseUrl: string, requestPath: string): URL => {\n const url = new URL(baseUrl);\n const normalizedBasePath = url.pathname.replace(/\\/+$/, \"\");\n const normalizedRequestPath = requestPath.startsWith(\"/\") ? requestPath : `/${requestPath}`;\n\n url.pathname = `${normalizedBasePath}${normalizedRequestPath}`.replace(/\\/{2,}/g, \"/\");\n\n return url;\n};\n\nconst appendQueryParams = (url: URL, query: Record<string, unknown> | undefined): void => {\n if (!query) {\n return;\n }\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, encodeQueryValue(item));\n }\n continue;\n }\n\n url.searchParams.set(key, encodeQueryValue(value));\n }\n};\n\nconst resolvePluginConfig = (api: OpenClawApiLike, pluginId: string): PluginRuntimeConfig =>\n api.config?.plugins?.entries?.[pluginId]?.config ?? {};\n\nconst buildHeaders = (\n runtimeConfig: PluginRuntimeConfig,\n requestHeaders: Record<string, unknown> | undefined,\n hasBody: boolean\n): Headers => {\n const headers = new Headers();\n\n for (const [key, value] of Object.entries(runtimeConfig.defaultHeaders ?? {})) {\n headers.set(key, value);\n }\n\n if (runtimeConfig.bearerToken) {\n headers.set(\"authorization\", `Bearer ${runtimeConfig.bearerToken}`);\n } else if (runtimeConfig.apiKey) {\n headers.set(runtimeConfig.apiKeyHeader ?? \"x-api-key\", runtimeConfig.apiKey);\n }\n\n for (const [key, value] of Object.entries(requestHeaders ?? {})) {\n if (value !== undefined && value !== null) {\n headers.set(key, String(value));\n }\n }\n\n if (hasBody && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return headers;\n};\n\nconst parseResponse = async (response: Response): Promise<unknown> => {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n};\n\nconst formatToolResult = (payload: unknown): { content: Array<{ type: \"text\"; text: string }> } => ({\n content: [\n {\n type: \"text\",\n text: typeof payload === \"string\" ? payload : JSON.stringify(payload, null, 2)\n }\n ]\n});\n\nconst isJsonLikeString = (value: string): boolean => {\n const trimmed = value.trim();\n return trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\");\n};\n\nconst normalizeJsonBody = (value: unknown): unknown => {\n if (typeof value !== \"string\") {\n return value;\n }\n\n if (!isJsonLikeString(value)) {\n return value;\n }\n\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n};\n\nconst schemaMatchesType = (schemaType: string | string[] | undefined, value: unknown): boolean => {\n if (!schemaType) {\n return true;\n }\n\n const allowed = Array.isArray(schemaType) ? schemaType : [schemaType];\n\n return allowed.some((type) => {\n if (type === \"null\") {\n return value === null;\n }\n\n if (type === \"array\") {\n return Array.isArray(value);\n }\n\n if (type === \"object\") {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n }\n\n return typeof value === type;\n });\n};\n\nconst validateAgainstSchema = (value: unknown, schema: any, path = \"body\"): string[] => {\n if (!schema) {\n return [];\n }\n\n const errors: string[] = [];\n\n if (schema.oneOf?.length) {\n const matches = schema.oneOf.filter((variant: any) => validateAgainstSchema(value, variant, path).length === 0);\n if (matches.length !== 1) {\n errors.push(`${path} must match exactly one allowed shape`);\n }\n return errors;\n }\n\n if (schema.anyOf?.length) {\n const matches = schema.anyOf.some((variant: any) => validateAgainstSchema(value, variant, path).length === 0);\n if (!matches) {\n errors.push(`${path} must match at least one allowed shape`);\n }\n return errors;\n }\n\n if (schema.allOf?.length) {\n for (const variant of schema.allOf) {\n errors.push(...validateAgainstSchema(value, variant, path));\n }\n return errors;\n }\n\n if (!schemaMatchesType(schema.type, value)) {\n const expected = Array.isArray(schema.type) ? schema.type.join(\"|\") : schema.type;\n errors.push(`${path} must be of type ${expected}`);\n return errors;\n }\n\n if (schema.enum && !schema.enum.includes(value)) {\n errors.push(`${path} must be one of: ${schema.enum.join(\", \")}`);\n }\n\n if (Array.isArray(value)) {\n if (schema.items) {\n value.forEach((item, index) => {\n errors.push(...validateAgainstSchema(item, schema.items, `${path}[${index}]`));\n });\n }\n return errors;\n }\n\n if (typeof value === \"object\" && value !== null) {\n const objectValue = value as Record<string, unknown>;\n const properties = schema.properties ?? {};\n const required = schema.required ?? [];\n\n for (const key of required) {\n if (objectValue[key] === undefined) {\n errors.push(`${path}.${key} is required`);\n }\n }\n\n for (const [key, childValue] of Object.entries(objectValue)) {\n const childSchema = properties[key];\n\n if (!childSchema) {\n if (schema.additionalProperties === false) {\n errors.push(`${path}.${key} is not allowed`);\n } else if (schema.additionalProperties && typeof schema.additionalProperties === \"object\") {\n errors.push(...validateAgainstSchema(childValue, schema.additionalProperties, `${path}.${key}`));\n }\n continue;\n }\n\n errors.push(...validateAgainstSchema(childValue, childSchema, `${path}.${key}`));\n }\n }\n\n return errors;\n};\n\nexport const createOpenApiPlugin = (\n catalog: OpenClawPluginCatalog,\n options?: CreatePluginFactoryOptions\n) => {\n return function register(api: OpenClawApiLike): void {\n for (const tool of catalog.tools) {\n api.registerTool(\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n execute: async (_id, params) => {\n const runtimeConfig = resolvePluginConfig(api, catalog.pluginId);\n const baseUrl = runtimeConfig.baseUrl ?? catalog.serverUrl;\n\n if (!baseUrl) {\n throw new Error(\n `Missing baseUrl for plugin ${catalog.pluginId}. Set plugins.entries.${catalog.pluginId}.config.baseUrl.`\n );\n }\n\n const input = (params ?? {}) as {\n path?: Record<string, unknown>;\n query?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n body?: unknown;\n };\n\n const finalUrl = createRequestUrl(baseUrl, applyPathParams(tool.path, input.path));\n\n appendQueryParams(finalUrl, input.query);\n\n const controller = new AbortController();\n const timeoutMs = runtimeConfig.timeoutMs ?? options?.timeoutMs;\n const timeout = timeoutMs\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n try {\n const normalizedBody = normalizeJsonBody(input.body);\n const hasBody = normalizedBody !== undefined;\n const requestInit: RequestInit = {\n method: tool.method,\n headers: buildHeaders(runtimeConfig, input.headers, hasBody),\n signal: controller.signal\n };\n\n if (hasBody) {\n const bodySchema = tool.parameters.properties?.body;\n const bodyValidationErrors = validateAgainstSchema(normalizedBody, bodySchema);\n\n if (bodyValidationErrors.length > 0) {\n return formatToolResult({\n ok: false,\n status: 400,\n statusText: \"INVALID_TOOL_INPUT\",\n data: {\n message: \"Tool input body does not match the generated schema.\",\n errors: bodyValidationErrors,\n received: normalizedBody\n }\n });\n }\n\n requestInit.body = JSON.stringify(normalizedBody);\n }\n\n const response = await fetch(finalUrl, requestInit);\n\n const payload = await parseResponse(response);\n\n if (!response.ok) {\n return formatToolResult({\n ok: false,\n status: response.status,\n statusText: response.statusText,\n data: payload\n });\n }\n\n return formatToolResult(payload);\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n }\n }\n },\n { optional: catalog.optional ?? true }\n );\n }\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,kBAA+B;AAC/B,uBAAiB;;;ACDjB,qBAA+B;;;ACExB,IAAM,eAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,qBAAqB,CAAC,UACjC,MACG,KAAK,EACL,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,YAAY,EAAE,EACtB,QAAQ,UAAU,GAAG,EACrB,YAAY,KAAK;AAEf,IAAM,cAAc,CAAC,UAC1B,MACG,MAAM,eAAe,EACrB,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AAEN,IAAM,gBAAgB,CAAC,YAAgC,YAA4B;AACxF,QAAM,OAAO,mBAAmB,OAAO;AACvC,QAAM,SAAS,mBAAmB,cAAc,EAAE;AAClD,SAAO,SAAS,GAAG,MAAM,IAAI,IAAI,KAAK;AACxC;AAEO,IAAM,mBAAmB,CAAC,QAAoBC,OAAc,gBAAiC;AAClG,MAAI,aAAa,KAAK,GAAG;AACvB,WAAO,mBAAmB,WAAW;AAAA,EACvC;AAEA,QAAM,WAAWA,MACd,QAAQ,gBAAgB,OAAO,EAC/B,QAAQ,QAAQ,GAAG;AAEtB,SAAO,mBAAmB,GAAG,MAAM,IAAI,QAAQ,EAAE;AACnD;AAEO,IAAM,oBAAoB,CAC/B,YAEA,UAAU,kBAAkB,GAAG,UAC/B,UAAU,oBAAoB,GAAG,UACjC,OAAO,OAAO,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG;AAE5B,IAAM,mBAAmB,CAC9B,WACA,mBAC6B;AAC7B,QAAM,QAAQ,oBAAI,IAAoC;AAEtD,aAAW,SAAS,CAAC,GAAI,aAAa,CAAC,GAAI,GAAI,kBAAkB,CAAC,CAAE,GAAG;AACrE,UAAM,IAAI,GAAG,MAAM,EAAE,IAAI,MAAM,IAAI,IAAI,KAAK;AAAA,EAC9C;AAEA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC3B;AAEO,IAAM,gBAAgB,CAAoC,UAAgB;AAC/E,QAAM,SAAS,CAAC;AAEhB,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC/C,QAAI,SAAS,QAAW;AACtB,aAAO,GAAc,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,mBAAmB,CAAC,WAC/B;AAAA,EACE,WACI,OAAO,cAAc,OAAO,KAAK,OAAO,UAAU,EAAE,SAAS,KAC5D,OAAO,YAAY,OAAO,SAAS,SAAS,KAC7C,OAAO,QACP,OAAO,SACP,OAAO,SACP,OAAO;AACb;;;ADxEF,IAAM,YAAY,CAAC,UAA2B,gBAAgB,KAAK,KAAK;AAExE,IAAM,UAAU,OAAO,QAAiC;AACtD,QAAM,WAAW,MAAM,MAAM,GAAG;AAEhC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,wCAAwC,GAAG,KAAK,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,EAC1G;AAEA,SAAO,SAAS,KAAK;AACvB;AAEO,IAAM,sBAAsB,OAAO,WAA6C;AACrF,QAAM,MAAM,UAAU,MAAM,IACxB,MAAM,QAAQ,MAAM,IACpB,MAAM,eAAAC,SAAG,SAAS,QAAQ,MAAM;AAEpC,QAAM,WAAW,KAAK,MAAM,GAAG;AAE/B,MAAI,CAAC,SAAS,WAAW,CAAC,SAAS,OAAO;AACxC,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,SAAO;AACT;AAIA,IAAM,iBAAiB,CAAC,QAAwB,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK;AAExE,IAAM,mBAAmB,CACvB,UACA,QACsD;AACtD,QAAM,aAAa,eAAe,GAAG;AACrC,SAAO,SAAS,YAAY,UAAU,UAAU;AAClD;AAEO,IAAM,4BAA4B,CACvC,QACA,UACA,OAAO,oBAAI,IAAY,MACR;AACf,MAAI,CAAC,QAAQ;AACX,WAAO,EAAE,MAAM,UAAU,sBAAsB,KAAK;AAAA,EACtD;AAEA,MAAI,OAAO,MAAM;AACf,QAAI,KAAK,IAAI,OAAO,IAAI,GAAG;AACzB,aAAO,EAAE,MAAM,UAAU,sBAAsB,KAAK;AAAA,IACtD;AAEA,UAAM,WAAW,iBAAiB,UAAU,OAAO,IAAI;AAEvD,QAAI,CAAC,UAAU;AACb,aAAO,EAAE,MAAM,UAAU,sBAAsB,KAAK;AAAA,IACtD;AAEA,UAAM,WAAW,IAAI,IAAI,IAAI;AAC7B,aAAS,IAAI,OAAO,IAAI;AACxB,WAAO,0BAA0B,UAAU,UAAU,QAAQ;AAAA,EAC/D;AAEA,QAAM,aAAyB,cAAc;AAAA,IAC3C,MAAM,MAAM,QAAQ,OAAO,IAAI,IAAI,CAAC,GAAG,OAAO,IAAI,IAAI,OAAO;AAAA,IAC7D,aAAa,OAAO;AAAA,IACpB,SAAS,OAAO;AAAA,IAChB,MAAM,OAAO,OAAO,CAAC,GAAG,OAAO,IAAI,IAAI;AAAA,EACzC,CAAC;AAED,MAAI,OAAO,OAAO,QAAQ;AACxB,eAAW,QAAQ,OAAO,MAAM,IAAI,CAAC,SAAS,0BAA0B,MAAM,UAAU,IAAI,CAAC;AAAA,EAC/F;AAEA,MAAI,OAAO,OAAO,QAAQ;AACxB,eAAW,QAAQ,OAAO,MAAM,IAAI,CAAC,SAAS,0BAA0B,MAAM,UAAU,IAAI,CAAC;AAAA,EAC/F;AAEA,MAAI,OAAO,OAAO,QAAQ;AACxB,eAAW,QAAQ,OAAO,MAAM,IAAI,CAAC,SAAS,0BAA0B,MAAM,UAAU,IAAI,CAAC;AAAA,EAC/F;AAEA,MAAI,OAAO,OAAO;AAChB,eAAW,QAAQ,0BAA0B,OAAO,OAAO,UAAU,IAAI;AAAA,EAC3E;AAEA,MAAI,OAAO,YAAY;AACrB,eAAW,aAAa,OAAO;AAAA,MAC7B,OAAO,QAAQ,OAAO,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,QACtD;AAAA,QACA,0BAA0B,OAAO,UAAU,IAAI;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,QAAQ;AAC3B,eAAW,WAAW,CAAC,GAAG,OAAO,QAAQ;AAAA,EAC3C;AAEA,MAAI,OAAO,yBAAyB,QAAW;AAC7C,eAAW,uBACT,OAAO,yBAAyB,QAAQ,OAAO,yBAAyB,QACpE,OAAO,uBACP,0BAA0B,OAAO,sBAAsB,UAAU,IAAI;AAAA,EAC7E;AAEA,MAAI,OAAO,UAAU;AACnB,UAAM,cAAc,WAAW;AAE/B,QAAI,MAAM,QAAQ,WAAW,GAAG;AAC9B,iBAAW,OAAO,YAAY,SAAS,MAAM,IAAI,cAAc,CAAC,GAAG,aAAa,MAAM;AAAA,IACxF,WAAW,aAAa;AACtB,iBAAW,OAAO,gBAAgB,SAAS,SAAS,CAAC,aAAa,MAAM;AAAA,IAC1E,OAAO;AACL,iBAAW,OAAO,CAAC,UAAU,MAAM;AAAA,IACrC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,iBAAiB,CAAC,WAA4C;AAClE,QAAM,OAAO,QAAQ;AAErB,MAAI,SAAS,UAAU;AACrB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,SAAS,QAAQ;AAAA,EAC/B;AAEA,SAAO,QAAQ,QAAQ,cAAc,QAAQ,oBAAoB;AACnE;AAEA,IAAM,gBAAgB,CAAC,WAA4C;AACjE,QAAM,OAAO,QAAQ;AAErB,MAAI,SAAS,SAAS;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,SAAS,OAAO;AAAA,EAC9B;AAEA,SAAO,QAAQ,QAAQ,KAAK;AAC9B;AAEA,IAAM,mBAAmB,CAAC,MAA8B,UACtD,KAAK,UAAU,QAAQ,IAAI,MAAM,KAAK,UAAU,SAAS,IAAI;AAE/D,IAAM,8BAA8B,CAAC,WAAmC;AACtE,MAAI,OAAO,OAAO,QAAQ;AACxB,UAAM,qBAAqB,OAAO,MAAM,IAAI,2BAA2B;AACvE,UAAM,gBAAgB,mBAAmB,KAAK,CAAC,SAAS,eAAe,IAAI,CAAC;AAC5E,UAAM,eAAe,mBAAmB,KAAK,CAAC,SAAS,cAAc,IAAI,CAAC;AAE1E,QACE,iBACA,cAAc,SACd,iBAAiB,eAAe,aAAa,KAAK,GAClD;AAGA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,OAAO,OAAO,QAAQ;AACxB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,OAAO,MAAM,IAAI,2BAA2B;AAAA,IACrD;AAAA,EACF;AAEA,MAAI,OAAO,OAAO,QAAQ;AACxB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,OAAO,MAAM,IAAI,2BAA2B;AAAA,IACrD;AAAA,EACF;AAEA,MAAI,OAAO,OAAO;AAChB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,4BAA4B,OAAO,KAAK;AAAA,IACjD;AAAA,EACF;AAEA,MAAI,OAAO,YAAY;AACrB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY,OAAO;AAAA,QACjB,OAAO,QAAQ,OAAO,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,4BAA4B,KAAK,CAAC,CAAC;AAAA,MACnG;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,wBAAwB,CAC5B,aACA,YACA,aACmE;AACnE,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,aAAyC,CAAC;AAChD,QAAM,WAAqB,CAAC;AAE5B,aAAW,aAAa,YAAY;AAClC,eAAW,UAAU,IAAI,IAAI,cAAc;AAAA,MACzC,GAAG,0BAA0B,UAAU,QAAQ,QAAQ;AAAA,MACvD,aAAa,UAAU,eAAe,UAAU,QAAQ;AAAA,IAC1D,CAAC;AAED,QAAI,UAAU,UAAU;AACtB,eAAS,KAAK,UAAU,IAAI;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,SAAS,SAAS;AAAA,IAC5B,QAAQ,cAAc;AAAA,MACpB,MAAM;AAAA,MACN;AAAA,MACA,UAAU,SAAS,SAAS,WAAW;AAAA,MACvC,sBAAsB;AAAA,IACxB,CAAC;AAAA,EACH;AACF;AAEA,IAAM,sBAAsB,CAC1B,UACAC,OACA,WACA,SACA,gBACA,iBACA,qBACe;AACf,QAAM,oBAAoB,kBAAkB,UAAU,aAAa,OAAO;AAC1E,QAAM,aAAyC,CAAC;AAChD,QAAM,WAAqB,CAAC;AAE5B,QAAM,WAAW;AAAA,IACf,sBAAsB,QAAQ,gBAAgB,QAAQ;AAAA,IACtD,sBAAsB,SAAS,iBAAiB,QAAQ;AAAA,IACxD,QAAQ,iBAAiB,sBAAsB,WAAW,kBAAkB,QAAQ,IAAI;AAAA,EAC1F,EAAE,OAAO,CAAC,UAA4E,QAAQ,KAAK,CAAC;AAEpG,aAAW,WAAW,UAAU;AAC9B,QAAI,iBAAiB,QAAQ,MAAM,GAAG;AACpC,iBAAW,QAAQ,IAAI,IAAI,QAAQ;AACnC,UAAI,QAAQ,UAAU;AACpB,iBAAS,KAAK,QAAQ,IAAI;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,mBAAmB;AACrB,eAAW,OAAO,4BAA4B,0BAA0B,mBAAmB,QAAQ,CAAC;AACpG,QAAI,UAAU,aAAa,UAAU;AACnC,eAAS,KAAK,MAAM;AAAA,IACtB;AAAA,EACF;AAEA,SAAO,cAAc;AAAA,IACnB,MAAM;AAAA,IACN;AAAA,IACA,UAAU,SAAS,SAAS,WAAW;AAAA,IACvC,sBAAsB;AAAA,IACtB,aAAa,GAAG,UAAU,WAAW,UAAU,eAAe,GAAGA,KAAI,UAAU;AAAA,EACjF,CAAC;AACH;AAEA,IAAM,uBAAuB,CAACA,OAAc,QAAgB,cAA8C;AACxG,QAAM,UAAU,UAAU,SAAS,KAAK;AACxC,QAAM,cAAc,UAAU,aAAa,KAAK;AAEhD,MAAI,WAAW,eAAe,gBAAgB,SAAS;AACrD,WAAO,GAAG,OAAO,KAAK,WAAW;AAAA,EACnC;AAEA,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAEA,MAAI,aAAa;AACf,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,OAAO,YAAY,CAAC,IAAIA,KAAI;AACxC;AAEA,IAAM,sBAAsB,CAC1B,UACAA,OACA,QACA,WACA,SACA,gBACA,iBACA,qBAC2B;AAC3B,QAAM,cAAc,iBAAiB,QAAQA,OAAM,UAAU,WAAW;AAExE,SAAO;AAAA,IACL,MAAM,cAAc,QAAQ,YAAY,WAAW;AAAA,IACnD,aAAa,qBAAqBA,OAAM,QAAQ,SAAS;AAAA,IACzD,QAAQ,OAAO,YAAY;AAAA,IAC3B,MAAAA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,MACV;AAAA,MACAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,MAAM,UAAU,QAAQ,CAAC;AAAA,EAC3B;AACF;AAEO,IAAM,wBAAwB,CACnC,UACA,YAC0B;AAC1B,QAAM,QAAkC,CAAC;AAEzC,aAAW,CAACA,OAAM,QAAQ,KAAK,OAAO,QAAQ,SAAS,KAAK,GAAG;AAC7D,eAAW,UAAU,cAAc;AACjC,YAAM,YAAY,SAAS,MAAM;AAEjC,UAAI,CAAC,WAAW;AACd;AAAA,MACF;AAEA,YAAM,aAAa,iBAAiB,SAAS,YAAY,UAAU,UAAU;AAC7E,YAAM,iBAAiB,WAAW,OAAO,CAAC,cAAc,UAAU,OAAO,MAAM;AAC/E,YAAM,kBAAkB,WAAW,OAAO,CAAC,cAAc,UAAU,OAAO,OAAO;AACjF,YAAM,mBAAmB,WAAW;AAAA,QAClC,CAAC,cACC,UAAU,OAAO,YACjB,CAAC,kBAAkB,IAAI,UAAU,KAAK,YAAY,CAAC;AAAA,MACvD;AAEA,YAAM;AAAA,QACJ;AAAA,UACE;AAAA,UACAA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,CAAC,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;AAE/D,SAAO;AAAA,IACL,UAAU,QAAQ;AAAA,IAClB,YAAY,QAAQ,cAAc,YAAY,QAAQ,QAAQ;AAAA,IAC9D,SAAS,QAAQ;AAAA,IACjB,aACE,SAAS,MAAM,aAAa,KAAK,KACjC,sCAAsC,SAAS,MAAM,SAAS,QAAQ,QAAQ;AAAA,IAChF,WAAW,QAAQ,oBAAoB,SAAS,UAAU,CAAC,GAAG;AAAA,IAC9D,UAAU,QAAQ,YAAY;AAAA,IAC9B;AAAA,EACF;AACF;;;AD9YA,IAAM,YAAY,CAAC,UAA2B,KAAK,UAAU,OAAO,MAAM,CAAC;AAEpE,IAAM,uBAAuB,CAAC,YACnC,GAAG,UAAU;AAAA,EACX,IAAI,QAAQ;AAAA,EACZ,MAAM,QAAQ;AAAA,EACd,SAAS,QAAQ,WAAW;AAAA,EAC5B,aAAa,QAAQ;AAAA,EACrB,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,sBAAsB;AAAA,IACtB,YAAY;AAAA,MACV,SAAS;AAAA,QACP,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,aAAa;AAAA,QACX,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,aAAa;AAAA,QACb,SAAS;AAAA,MACX;AAAA,MACA,WAAW;AAAA,QACT,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,gBAAgB;AAAA,QACd,MAAM;AAAA,QACN,sBAAsB;AAAA,UACpB,MAAM;AAAA,QACR;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,MACP,OAAO;AAAA,MACP,aAAa,QAAQ,aAAa;AAAA,IACpC;AAAA,IACA,aAAa;AAAA,MACX,OAAO;AAAA,MACP,WAAW;AAAA,IACb;AAAA,IACA,QAAQ;AAAA,MACN,OAAO;AAAA,MACP,WAAW;AAAA,IACb;AAAA,IACA,cAAc;AAAA,MACZ,OAAO;AAAA,IACT;AAAA,IACA,WAAW;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF,CAAC,CAAC;AAAA;AAEG,IAAM,qBAAqB,CAAC,YACjC;AAAA;AAAA,yBAEuB,UAAU,OAAO,CAAC;AAAA;AAAA;AAAA;AAKpC,IAAM,oBAAoB,CAAC,YAChC,GAAG,UAAU,OAAO,CAAC;AAAA;AAEvB,IAAM,YAAY,OAAO,YAAmC;AAC1D,QAAM,gBAAAC,SAAG,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAC7C;AAEO,IAAM,uBAAuB,OAClC,SACA,WACkC;AAClC,QAAM,UAAU,MAAM;AAEtB,QAAM,eAAe,iBAAAC,QAAK,KAAK,QAAQ,sBAAsB;AAC7D,QAAM,YAAY,iBAAAA,QAAK,KAAK,QAAQ,UAAU;AAC9C,QAAM,cAAc,iBAAAA,QAAK,KAAK,QAAQ,mBAAmB;AAEzD,QAAM,QAAQ,IAAI;AAAA,IAChB,gBAAAD,SAAG,UAAU,cAAc,qBAAqB,OAAO,GAAG,MAAM;AAAA,IAChE,gBAAAA,SAAG,UAAU,WAAW,mBAAmB,OAAO,GAAG,MAAM;AAAA,IAC3D,gBAAAA,SAAG,UAAU,aAAa,kBAAkB,OAAO,GAAG,MAAM;AAAA,EAC9D,CAAC;AAED,SAAO,EAAE,cAAc,WAAW,YAAY;AAChD;AAEO,IAAM,4BAA4B,OACvC,YAC6E;AAC7E,QAAM,WAAW,MAAM,oBAAoB,QAAQ,KAAK;AACxD,QAAM,iBAAwC;AAAA,IAC5C,UAAU,QAAQ;AAAA,IAClB,YAAY,QAAQ;AAAA,IACpB,eAAe,QAAQ;AAAA,IACvB,YAAY,QAAQ;AAAA,IACpB,UAAU,QAAQ;AAAA,IAClB,gBAAgB,QAAQ;AAAA,IACxB,kBAAkB,QAAQ;AAAA,EAC5B;AACA,QAAM,UAAU,sBAAsB,UAAU,cAAc;AAC9D,QAAM,QAAQ,MAAM,qBAAqB,SAAS,QAAQ,MAAM;AAEhE,SAAO,EAAE,SAAS,MAAM;AAC1B;;;AG3HA,IAAM,mBAAmB,CAAC,UAA2B;AACnD,MAAI,UAAU,MAAM;AAClB,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AAC3D,WAAO,OAAO,KAAK;AAAA,EACrB;AAEA,SAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,IAAM,kBAAkB,CAAC,cAAsB,eAC7C,aAAa,QAAQ,gBAAgB,CAAC,GAAG,QAAgB;AACvD,QAAM,MAAM,aAAa,GAAG;AAE5B,MAAI,QAAQ,UAAa,QAAQ,MAAM;AACrC,UAAM,IAAI,MAAM,oCAAoC,GAAG,EAAE;AAAA,EAC3D;AAEA,SAAO,mBAAmB,OAAO,GAAG,CAAC;AACvC,CAAC;AAEH,IAAM,mBAAmB,CAAC,SAAiB,gBAA6B;AACtE,QAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAM,qBAAqB,IAAI,SAAS,QAAQ,QAAQ,EAAE;AAC1D,QAAM,wBAAwB,YAAY,WAAW,GAAG,IAAI,cAAc,IAAI,WAAW;AAEzF,MAAI,WAAW,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,QAAQ,WAAW,GAAG;AAErF,SAAO;AACT;AAEA,IAAM,oBAAoB,CAAC,KAAU,UAAqD;AACxF,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,QAAW;AACvB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,iBAAW,QAAQ,OAAO;AACxB,YAAI,aAAa,OAAO,KAAK,iBAAiB,IAAI,CAAC;AAAA,MACrD;AACA;AAAA,IACF;AAEA,QAAI,aAAa,IAAI,KAAK,iBAAiB,KAAK,CAAC;AAAA,EACnD;AACF;AAEA,IAAM,sBAAsB,CAAC,KAAsB,aACjD,IAAI,QAAQ,SAAS,UAAU,QAAQ,GAAG,UAAU,CAAC;AAEvD,IAAM,eAAe,CACnB,eACA,gBACA,YACY;AACZ,QAAM,UAAU,IAAI,QAAQ;AAE5B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,kBAAkB,CAAC,CAAC,GAAG;AAC7E,YAAQ,IAAI,KAAK,KAAK;AAAA,EACxB;AAEA,MAAI,cAAc,aAAa;AAC7B,YAAQ,IAAI,iBAAiB,UAAU,cAAc,WAAW,EAAE;AAAA,EACpE,WAAW,cAAc,QAAQ;AAC/B,YAAQ,IAAI,cAAc,gBAAgB,aAAa,cAAc,MAAM;AAAA,EAC7E;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,kBAAkB,CAAC,CAAC,GAAG;AAC/D,QAAI,UAAU,UAAa,UAAU,MAAM;AACzC,cAAQ,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IAChC;AAAA,EACF;AAEA,MAAI,WAAW,CAAC,QAAQ,IAAI,cAAc,GAAG;AAC3C,YAAQ,IAAI,gBAAgB,kBAAkB;AAAA,EAChD;AAEA,SAAO;AACT;AAEA,IAAM,gBAAgB,OAAO,aAAyC;AACpE,QAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAE5D,MAAI,YAAY,SAAS,kBAAkB,GAAG;AAC5C,WAAO,SAAS,KAAK;AAAA,EACvB;AAEA,SAAO,SAAS,KAAK;AACvB;AAEA,IAAM,mBAAmB,CAAC,aAA0E;AAAA,EAClG,SAAS;AAAA,IACP;AAAA,MACE,MAAM;AAAA,MACN,MAAM,OAAO,YAAY,WAAW,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,IAC/E;AAAA,EACF;AACF;AAEA,IAAM,mBAAmB,CAAC,UAA2B;AACnD,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG;AAC1D;AAEA,IAAM,oBAAoB,CAAC,UAA4B;AACrD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,iBAAiB,KAAK,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,oBAAoB,CAAC,YAA2C,UAA4B;AAChG,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AAEpE,SAAO,QAAQ,KAAK,CAAC,SAAS;AAC5B,QAAI,SAAS,QAAQ;AACnB,aAAO,UAAU;AAAA,IACnB;AAEA,QAAI,SAAS,SAAS;AACpB,aAAO,MAAM,QAAQ,KAAK;AAAA,IAC5B;AAEA,QAAI,SAAS,UAAU;AACrB,aAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA,IAC5E;AAEA,WAAO,OAAO,UAAU;AAAA,EAC1B,CAAC;AACH;AAEA,IAAM,wBAAwB,CAAC,OAAgB,QAAaE,QAAO,WAAqB;AACtF,MAAI,CAAC,QAAQ;AACX,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAmB,CAAC;AAE1B,MAAI,OAAO,OAAO,QAAQ;AACxB,UAAM,UAAU,OAAO,MAAM,OAAO,CAAC,YAAiB,sBAAsB,OAAO,SAASA,KAAI,EAAE,WAAW,CAAC;AAC9G,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,KAAK,GAAGA,KAAI,uCAAuC;AAAA,IAC5D;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,OAAO,QAAQ;AACxB,UAAM,UAAU,OAAO,MAAM,KAAK,CAAC,YAAiB,sBAAsB,OAAO,SAASA,KAAI,EAAE,WAAW,CAAC;AAC5G,QAAI,CAAC,SAAS;AACZ,aAAO,KAAK,GAAGA,KAAI,wCAAwC;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,OAAO,QAAQ;AACxB,eAAW,WAAW,OAAO,OAAO;AAClC,aAAO,KAAK,GAAG,sBAAsB,OAAO,SAASA,KAAI,CAAC;AAAA,IAC5D;AACA,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,kBAAkB,OAAO,MAAM,KAAK,GAAG;AAC1C,UAAM,WAAW,MAAM,QAAQ,OAAO,IAAI,IAAI,OAAO,KAAK,KAAK,GAAG,IAAI,OAAO;AAC7E,WAAO,KAAK,GAAGA,KAAI,oBAAoB,QAAQ,EAAE;AACjD,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,SAAS,KAAK,GAAG;AAC/C,WAAO,KAAK,GAAGA,KAAI,oBAAoB,OAAO,KAAK,KAAK,IAAI,CAAC,EAAE;AAAA,EACjE;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAI,OAAO,OAAO;AAChB,YAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,eAAO,KAAK,GAAG,sBAAsB,MAAM,OAAO,OAAO,GAAGA,KAAI,IAAI,KAAK,GAAG,CAAC;AAAA,MAC/E,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,cAAc;AACpB,UAAM,aAAa,OAAO,cAAc,CAAC;AACzC,UAAM,WAAW,OAAO,YAAY,CAAC;AAErC,eAAW,OAAO,UAAU;AAC1B,UAAI,YAAY,GAAG,MAAM,QAAW;AAClC,eAAO,KAAK,GAAGA,KAAI,IAAI,GAAG,cAAc;AAAA,MAC1C;AAAA,IACF;AAEA,eAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,WAAW,GAAG;AAC3D,YAAM,cAAc,WAAW,GAAG;AAElC,UAAI,CAAC,aAAa;AAChB,YAAI,OAAO,yBAAyB,OAAO;AACzC,iBAAO,KAAK,GAAGA,KAAI,IAAI,GAAG,iBAAiB;AAAA,QAC7C,WAAW,OAAO,wBAAwB,OAAO,OAAO,yBAAyB,UAAU;AACzF,iBAAO,KAAK,GAAG,sBAAsB,YAAY,OAAO,sBAAsB,GAAGA,KAAI,IAAI,GAAG,EAAE,CAAC;AAAA,QACjG;AACA;AAAA,MACF;AAEA,aAAO,KAAK,GAAG,sBAAsB,YAAY,aAAa,GAAGA,KAAI,IAAI,GAAG,EAAE,CAAC;AAAA,IACjF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,sBAAsB,CACjC,SACA,YACG;AACH,SAAO,SAAS,SAAS,KAA4B;AACnD,eAAW,QAAQ,QAAQ,OAAO;AAChC,UAAI;AAAA,QACF;AAAA,UACE,MAAM,KAAK;AAAA,UACX,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK;AAAA,UACjB,SAAS,OAAO,KAAK,WAAW;AAC9B,kBAAM,gBAAgB,oBAAoB,KAAK,QAAQ,QAAQ;AAC/D,kBAAM,UAAU,cAAc,WAAW,QAAQ;AAEjD,gBAAI,CAAC,SAAS;AACZ,oBAAM,IAAI;AAAA,gBACR,8BAA8B,QAAQ,QAAQ,yBAAyB,QAAQ,QAAQ;AAAA,cACzF;AAAA,YACF;AAEA,kBAAM,QAAS,UAAU,CAAC;AAO1B,kBAAM,WAAW,iBAAiB,SAAS,gBAAgB,KAAK,MAAM,MAAM,IAAI,CAAC;AAEjF,8BAAkB,UAAU,MAAM,KAAK;AAEvC,kBAAM,aAAa,IAAI,gBAAgB;AACvC,kBAAM,YAAY,cAAc,aAAa,SAAS;AACtD,kBAAM,UAAU,YACZ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS,IAC9C;AAEJ,gBAAI;AACF,oBAAM,iBAAiB,kBAAkB,MAAM,IAAI;AACnD,oBAAM,UAAU,mBAAmB;AACnC,oBAAM,cAA2B;AAAA,gBAC/B,QAAQ,KAAK;AAAA,gBACb,SAAS,aAAa,eAAe,MAAM,SAAS,OAAO;AAAA,gBAC3D,QAAQ,WAAW;AAAA,cACrB;AAEA,kBAAI,SAAS;AACX,sBAAM,aAAa,KAAK,WAAW,YAAY;AAC/C,sBAAM,uBAAuB,sBAAsB,gBAAgB,UAAU;AAE7E,oBAAI,qBAAqB,SAAS,GAAG;AACnC,yBAAO,iBAAiB;AAAA,oBACtB,IAAI;AAAA,oBACJ,QAAQ;AAAA,oBACR,YAAY;AAAA,oBACZ,MAAM;AAAA,sBACJ,SAAS;AAAA,sBACT,QAAQ;AAAA,sBACR,UAAU;AAAA,oBACZ;AAAA,kBACF,CAAC;AAAA,gBACH;AAEA,4BAAY,OAAO,KAAK,UAAU,cAAc;AAAA,cAClD;AAEA,oBAAM,WAAW,MAAM,MAAM,UAAU,WAAW;AAElD,oBAAM,UAAU,MAAM,cAAc,QAAQ;AAE5C,kBAAI,CAAC,SAAS,IAAI;AAChB,uBAAO,iBAAiB;AAAA,kBACtB,IAAI;AAAA,kBACJ,QAAQ,SAAS;AAAA,kBACjB,YAAY,SAAS;AAAA,kBACrB,MAAM;AAAA,gBACR,CAAC;AAAA,cACH;AAEA,qBAAO,iBAAiB,OAAO;AAAA,YACjC,UAAE;AACA,kBAAI,SAAS;AACX,6BAAa,OAAO;AAAA,cACtB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,EAAE,UAAU,QAAQ,YAAY,KAAK;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;","names":["import_node_fs","path","fs","path","fs","path","path"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -94,6 +94,7 @@ type OpenClawToolDefinition = {
|
|
|
94
94
|
type OpenClawPluginCatalog = {
|
|
95
95
|
pluginId: string;
|
|
96
96
|
pluginName: string;
|
|
97
|
+
version?: string | undefined;
|
|
97
98
|
description: string;
|
|
98
99
|
serverUrl?: string | undefined;
|
|
99
100
|
optional?: boolean | undefined;
|
|
@@ -102,6 +103,7 @@ type OpenClawPluginCatalog = {
|
|
|
102
103
|
type ConvertOpenApiOptions = {
|
|
103
104
|
pluginId: string;
|
|
104
105
|
pluginName?: string | undefined;
|
|
106
|
+
pluginVersion?: string | undefined;
|
|
105
107
|
toolPrefix?: string | undefined;
|
|
106
108
|
optional?: boolean | undefined;
|
|
107
109
|
includeHeaders?: boolean | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -94,6 +94,7 @@ type OpenClawToolDefinition = {
|
|
|
94
94
|
type OpenClawPluginCatalog = {
|
|
95
95
|
pluginId: string;
|
|
96
96
|
pluginName: string;
|
|
97
|
+
version?: string | undefined;
|
|
97
98
|
description: string;
|
|
98
99
|
serverUrl?: string | undefined;
|
|
99
100
|
optional?: boolean | undefined;
|
|
@@ -102,6 +103,7 @@ type OpenClawPluginCatalog = {
|
|
|
102
103
|
type ConvertOpenApiOptions = {
|
|
103
104
|
pluginId: string;
|
|
104
105
|
pluginName?: string | undefined;
|
|
106
|
+
pluginVersion?: string | undefined;
|
|
105
107
|
toolPrefix?: string | undefined;
|
|
106
108
|
optional?: boolean | undefined;
|
|
107
109
|
includeHeaders?: boolean | undefined;
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
renderPluginManifest,
|
|
8
8
|
renderPluginModule,
|
|
9
9
|
writeGeneratedPlugin
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-6QQXCYPZ.js";
|
|
11
11
|
|
|
12
12
|
// src/runtime.ts
|
|
13
13
|
var encodeQueryValue = (value) => {
|
|
@@ -89,6 +89,106 @@ var formatToolResult = (payload) => ({
|
|
|
89
89
|
}
|
|
90
90
|
]
|
|
91
91
|
});
|
|
92
|
+
var isJsonLikeString = (value) => {
|
|
93
|
+
const trimmed = value.trim();
|
|
94
|
+
return trimmed.startsWith("{") || trimmed.startsWith("[");
|
|
95
|
+
};
|
|
96
|
+
var normalizeJsonBody = (value) => {
|
|
97
|
+
if (typeof value !== "string") {
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
if (!isJsonLikeString(value)) {
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
return JSON.parse(value);
|
|
105
|
+
} catch {
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
var schemaMatchesType = (schemaType, value) => {
|
|
110
|
+
if (!schemaType) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
const allowed = Array.isArray(schemaType) ? schemaType : [schemaType];
|
|
114
|
+
return allowed.some((type) => {
|
|
115
|
+
if (type === "null") {
|
|
116
|
+
return value === null;
|
|
117
|
+
}
|
|
118
|
+
if (type === "array") {
|
|
119
|
+
return Array.isArray(value);
|
|
120
|
+
}
|
|
121
|
+
if (type === "object") {
|
|
122
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
123
|
+
}
|
|
124
|
+
return typeof value === type;
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
var validateAgainstSchema = (value, schema, path = "body") => {
|
|
128
|
+
if (!schema) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
const errors = [];
|
|
132
|
+
if (schema.oneOf?.length) {
|
|
133
|
+
const matches = schema.oneOf.filter((variant) => validateAgainstSchema(value, variant, path).length === 0);
|
|
134
|
+
if (matches.length !== 1) {
|
|
135
|
+
errors.push(`${path} must match exactly one allowed shape`);
|
|
136
|
+
}
|
|
137
|
+
return errors;
|
|
138
|
+
}
|
|
139
|
+
if (schema.anyOf?.length) {
|
|
140
|
+
const matches = schema.anyOf.some((variant) => validateAgainstSchema(value, variant, path).length === 0);
|
|
141
|
+
if (!matches) {
|
|
142
|
+
errors.push(`${path} must match at least one allowed shape`);
|
|
143
|
+
}
|
|
144
|
+
return errors;
|
|
145
|
+
}
|
|
146
|
+
if (schema.allOf?.length) {
|
|
147
|
+
for (const variant of schema.allOf) {
|
|
148
|
+
errors.push(...validateAgainstSchema(value, variant, path));
|
|
149
|
+
}
|
|
150
|
+
return errors;
|
|
151
|
+
}
|
|
152
|
+
if (!schemaMatchesType(schema.type, value)) {
|
|
153
|
+
const expected = Array.isArray(schema.type) ? schema.type.join("|") : schema.type;
|
|
154
|
+
errors.push(`${path} must be of type ${expected}`);
|
|
155
|
+
return errors;
|
|
156
|
+
}
|
|
157
|
+
if (schema.enum && !schema.enum.includes(value)) {
|
|
158
|
+
errors.push(`${path} must be one of: ${schema.enum.join(", ")}`);
|
|
159
|
+
}
|
|
160
|
+
if (Array.isArray(value)) {
|
|
161
|
+
if (schema.items) {
|
|
162
|
+
value.forEach((item, index) => {
|
|
163
|
+
errors.push(...validateAgainstSchema(item, schema.items, `${path}[${index}]`));
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return errors;
|
|
167
|
+
}
|
|
168
|
+
if (typeof value === "object" && value !== null) {
|
|
169
|
+
const objectValue = value;
|
|
170
|
+
const properties = schema.properties ?? {};
|
|
171
|
+
const required = schema.required ?? [];
|
|
172
|
+
for (const key of required) {
|
|
173
|
+
if (objectValue[key] === void 0) {
|
|
174
|
+
errors.push(`${path}.${key} is required`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
for (const [key, childValue] of Object.entries(objectValue)) {
|
|
178
|
+
const childSchema = properties[key];
|
|
179
|
+
if (!childSchema) {
|
|
180
|
+
if (schema.additionalProperties === false) {
|
|
181
|
+
errors.push(`${path}.${key} is not allowed`);
|
|
182
|
+
} else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
183
|
+
errors.push(...validateAgainstSchema(childValue, schema.additionalProperties, `${path}.${key}`));
|
|
184
|
+
}
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
errors.push(...validateAgainstSchema(childValue, childSchema, `${path}.${key}`));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return errors;
|
|
191
|
+
};
|
|
92
192
|
var createOpenApiPlugin = (catalog, options) => {
|
|
93
193
|
return function register(api) {
|
|
94
194
|
for (const tool of catalog.tools) {
|
|
@@ -112,14 +212,29 @@ var createOpenApiPlugin = (catalog, options) => {
|
|
|
112
212
|
const timeoutMs = runtimeConfig.timeoutMs ?? options?.timeoutMs;
|
|
113
213
|
const timeout = timeoutMs ? setTimeout(() => controller.abort(), timeoutMs) : void 0;
|
|
114
214
|
try {
|
|
115
|
-
const
|
|
215
|
+
const normalizedBody = normalizeJsonBody(input.body);
|
|
216
|
+
const hasBody = normalizedBody !== void 0;
|
|
116
217
|
const requestInit = {
|
|
117
218
|
method: tool.method,
|
|
118
219
|
headers: buildHeaders(runtimeConfig, input.headers, hasBody),
|
|
119
220
|
signal: controller.signal
|
|
120
221
|
};
|
|
121
222
|
if (hasBody) {
|
|
122
|
-
|
|
223
|
+
const bodySchema = tool.parameters.properties?.body;
|
|
224
|
+
const bodyValidationErrors = validateAgainstSchema(normalizedBody, bodySchema);
|
|
225
|
+
if (bodyValidationErrors.length > 0) {
|
|
226
|
+
return formatToolResult({
|
|
227
|
+
ok: false,
|
|
228
|
+
status: 400,
|
|
229
|
+
statusText: "INVALID_TOOL_INPUT",
|
|
230
|
+
data: {
|
|
231
|
+
message: "Tool input body does not match the generated schema.",
|
|
232
|
+
errors: bodyValidationErrors,
|
|
233
|
+
received: normalizedBody
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
requestInit.body = JSON.stringify(normalizedBody);
|
|
123
238
|
}
|
|
124
239
|
const response = await fetch(finalUrl, requestInit);
|
|
125
240
|
const payload = await parseResponse(response);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["import { CreatePluginFactoryOptions, OpenClawApiLike, OpenClawPluginCatalog, PluginRuntimeConfig } from \"./types\";\n\nconst encodeQueryValue = (value: unknown): string => {\n if (value === null) {\n return \"null\";\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n return JSON.stringify(value);\n};\n\nconst applyPathParams = (pathTemplate: string, pathParams: Record<string, unknown> | undefined): string =>\n pathTemplate.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const raw = pathParams?.[key];\n\n if (raw === undefined || raw === null) {\n throw new Error(`Missing required path parameter: ${key}`);\n }\n\n return encodeURIComponent(String(raw));\n });\n\nconst createRequestUrl = (baseUrl: string, requestPath: string): URL => {\n const url = new URL(baseUrl);\n const normalizedBasePath = url.pathname.replace(/\\/+$/, \"\");\n const normalizedRequestPath = requestPath.startsWith(\"/\") ? requestPath : `/${requestPath}`;\n\n url.pathname = `${normalizedBasePath}${normalizedRequestPath}`.replace(/\\/{2,}/g, \"/\");\n\n return url;\n};\n\nconst appendQueryParams = (url: URL, query: Record<string, unknown> | undefined): void => {\n if (!query) {\n return;\n }\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, encodeQueryValue(item));\n }\n continue;\n }\n\n url.searchParams.set(key, encodeQueryValue(value));\n }\n};\n\nconst resolvePluginConfig = (api: OpenClawApiLike, pluginId: string): PluginRuntimeConfig =>\n api.config?.plugins?.entries?.[pluginId]?.config ?? {};\n\nconst buildHeaders = (\n runtimeConfig: PluginRuntimeConfig,\n requestHeaders: Record<string, unknown> | undefined,\n hasBody: boolean\n): Headers => {\n const headers = new Headers();\n\n for (const [key, value] of Object.entries(runtimeConfig.defaultHeaders ?? {})) {\n headers.set(key, value);\n }\n\n if (runtimeConfig.bearerToken) {\n headers.set(\"authorization\", `Bearer ${runtimeConfig.bearerToken}`);\n } else if (runtimeConfig.apiKey) {\n headers.set(runtimeConfig.apiKeyHeader ?? \"x-api-key\", runtimeConfig.apiKey);\n }\n\n for (const [key, value] of Object.entries(requestHeaders ?? {})) {\n if (value !== undefined && value !== null) {\n headers.set(key, String(value));\n }\n }\n\n if (hasBody && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return headers;\n};\n\nconst parseResponse = async (response: Response): Promise<unknown> => {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n};\n\nconst formatToolResult = (payload: unknown): { content: Array<{ type: \"text\"; text: string }> } => ({\n content: [\n {\n type: \"text\",\n text: typeof payload === \"string\" ? payload : JSON.stringify(payload, null, 2)\n }\n ]\n});\n\nexport const createOpenApiPlugin = (\n catalog: OpenClawPluginCatalog,\n options?: CreatePluginFactoryOptions\n) => {\n return function register(api: OpenClawApiLike): void {\n for (const tool of catalog.tools) {\n api.registerTool(\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n execute: async (_id, params) => {\n const runtimeConfig = resolvePluginConfig(api, catalog.pluginId);\n const baseUrl = runtimeConfig.baseUrl ?? catalog.serverUrl;\n\n if (!baseUrl) {\n throw new Error(\n `Missing baseUrl for plugin ${catalog.pluginId}. Set plugins.entries.${catalog.pluginId}.config.baseUrl.`\n );\n }\n\n const input = (params ?? {}) as {\n path?: Record<string, unknown>;\n query?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n body?: unknown;\n };\n\n const finalUrl = createRequestUrl(baseUrl, applyPathParams(tool.path, input.path));\n\n appendQueryParams(finalUrl, input.query);\n\n const controller = new AbortController();\n const timeoutMs = runtimeConfig.timeoutMs ?? options?.timeoutMs;\n const timeout = timeoutMs\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n try {\n const hasBody = input.body !== undefined;\n const requestInit: RequestInit = {\n method: tool.method,\n headers: buildHeaders(runtimeConfig, input.headers, hasBody),\n signal: controller.signal\n };\n\n if (hasBody) {\n requestInit.body = JSON.stringify(input.body);\n }\n\n const response = await fetch(finalUrl, requestInit);\n\n const payload = await parseResponse(response);\n\n if (!response.ok) {\n return formatToolResult({\n ok: false,\n status: response.status,\n statusText: response.statusText,\n data: payload\n });\n }\n\n return formatToolResult(payload);\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n }\n }\n },\n { optional: catalog.optional ?? true }\n );\n }\n };\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["import { CreatePluginFactoryOptions, OpenClawApiLike, OpenClawPluginCatalog, PluginRuntimeConfig } from \"./types\";\n\nconst encodeQueryValue = (value: unknown): string => {\n if (value === null) {\n return \"null\";\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n return JSON.stringify(value);\n};\n\nconst applyPathParams = (pathTemplate: string, pathParams: Record<string, unknown> | undefined): string =>\n pathTemplate.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const raw = pathParams?.[key];\n\n if (raw === undefined || raw === null) {\n throw new Error(`Missing required path parameter: ${key}`);\n }\n\n return encodeURIComponent(String(raw));\n });\n\nconst createRequestUrl = (baseUrl: string, requestPath: string): URL => {\n const url = new URL(baseUrl);\n const normalizedBasePath = url.pathname.replace(/\\/+$/, \"\");\n const normalizedRequestPath = requestPath.startsWith(\"/\") ? requestPath : `/${requestPath}`;\n\n url.pathname = `${normalizedBasePath}${normalizedRequestPath}`.replace(/\\/{2,}/g, \"/\");\n\n return url;\n};\n\nconst appendQueryParams = (url: URL, query: Record<string, unknown> | undefined): void => {\n if (!query) {\n return;\n }\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, encodeQueryValue(item));\n }\n continue;\n }\n\n url.searchParams.set(key, encodeQueryValue(value));\n }\n};\n\nconst resolvePluginConfig = (api: OpenClawApiLike, pluginId: string): PluginRuntimeConfig =>\n api.config?.plugins?.entries?.[pluginId]?.config ?? {};\n\nconst buildHeaders = (\n runtimeConfig: PluginRuntimeConfig,\n requestHeaders: Record<string, unknown> | undefined,\n hasBody: boolean\n): Headers => {\n const headers = new Headers();\n\n for (const [key, value] of Object.entries(runtimeConfig.defaultHeaders ?? {})) {\n headers.set(key, value);\n }\n\n if (runtimeConfig.bearerToken) {\n headers.set(\"authorization\", `Bearer ${runtimeConfig.bearerToken}`);\n } else if (runtimeConfig.apiKey) {\n headers.set(runtimeConfig.apiKeyHeader ?? \"x-api-key\", runtimeConfig.apiKey);\n }\n\n for (const [key, value] of Object.entries(requestHeaders ?? {})) {\n if (value !== undefined && value !== null) {\n headers.set(key, String(value));\n }\n }\n\n if (hasBody && !headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return headers;\n};\n\nconst parseResponse = async (response: Response): Promise<unknown> => {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n};\n\nconst formatToolResult = (payload: unknown): { content: Array<{ type: \"text\"; text: string }> } => ({\n content: [\n {\n type: \"text\",\n text: typeof payload === \"string\" ? payload : JSON.stringify(payload, null, 2)\n }\n ]\n});\n\nconst isJsonLikeString = (value: string): boolean => {\n const trimmed = value.trim();\n return trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\");\n};\n\nconst normalizeJsonBody = (value: unknown): unknown => {\n if (typeof value !== \"string\") {\n return value;\n }\n\n if (!isJsonLikeString(value)) {\n return value;\n }\n\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n};\n\nconst schemaMatchesType = (schemaType: string | string[] | undefined, value: unknown): boolean => {\n if (!schemaType) {\n return true;\n }\n\n const allowed = Array.isArray(schemaType) ? schemaType : [schemaType];\n\n return allowed.some((type) => {\n if (type === \"null\") {\n return value === null;\n }\n\n if (type === \"array\") {\n return Array.isArray(value);\n }\n\n if (type === \"object\") {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n }\n\n return typeof value === type;\n });\n};\n\nconst validateAgainstSchema = (value: unknown, schema: any, path = \"body\"): string[] => {\n if (!schema) {\n return [];\n }\n\n const errors: string[] = [];\n\n if (schema.oneOf?.length) {\n const matches = schema.oneOf.filter((variant: any) => validateAgainstSchema(value, variant, path).length === 0);\n if (matches.length !== 1) {\n errors.push(`${path} must match exactly one allowed shape`);\n }\n return errors;\n }\n\n if (schema.anyOf?.length) {\n const matches = schema.anyOf.some((variant: any) => validateAgainstSchema(value, variant, path).length === 0);\n if (!matches) {\n errors.push(`${path} must match at least one allowed shape`);\n }\n return errors;\n }\n\n if (schema.allOf?.length) {\n for (const variant of schema.allOf) {\n errors.push(...validateAgainstSchema(value, variant, path));\n }\n return errors;\n }\n\n if (!schemaMatchesType(schema.type, value)) {\n const expected = Array.isArray(schema.type) ? schema.type.join(\"|\") : schema.type;\n errors.push(`${path} must be of type ${expected}`);\n return errors;\n }\n\n if (schema.enum && !schema.enum.includes(value)) {\n errors.push(`${path} must be one of: ${schema.enum.join(\", \")}`);\n }\n\n if (Array.isArray(value)) {\n if (schema.items) {\n value.forEach((item, index) => {\n errors.push(...validateAgainstSchema(item, schema.items, `${path}[${index}]`));\n });\n }\n return errors;\n }\n\n if (typeof value === \"object\" && value !== null) {\n const objectValue = value as Record<string, unknown>;\n const properties = schema.properties ?? {};\n const required = schema.required ?? [];\n\n for (const key of required) {\n if (objectValue[key] === undefined) {\n errors.push(`${path}.${key} is required`);\n }\n }\n\n for (const [key, childValue] of Object.entries(objectValue)) {\n const childSchema = properties[key];\n\n if (!childSchema) {\n if (schema.additionalProperties === false) {\n errors.push(`${path}.${key} is not allowed`);\n } else if (schema.additionalProperties && typeof schema.additionalProperties === \"object\") {\n errors.push(...validateAgainstSchema(childValue, schema.additionalProperties, `${path}.${key}`));\n }\n continue;\n }\n\n errors.push(...validateAgainstSchema(childValue, childSchema, `${path}.${key}`));\n }\n }\n\n return errors;\n};\n\nexport const createOpenApiPlugin = (\n catalog: OpenClawPluginCatalog,\n options?: CreatePluginFactoryOptions\n) => {\n return function register(api: OpenClawApiLike): void {\n for (const tool of catalog.tools) {\n api.registerTool(\n {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n execute: async (_id, params) => {\n const runtimeConfig = resolvePluginConfig(api, catalog.pluginId);\n const baseUrl = runtimeConfig.baseUrl ?? catalog.serverUrl;\n\n if (!baseUrl) {\n throw new Error(\n `Missing baseUrl for plugin ${catalog.pluginId}. Set plugins.entries.${catalog.pluginId}.config.baseUrl.`\n );\n }\n\n const input = (params ?? {}) as {\n path?: Record<string, unknown>;\n query?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n body?: unknown;\n };\n\n const finalUrl = createRequestUrl(baseUrl, applyPathParams(tool.path, input.path));\n\n appendQueryParams(finalUrl, input.query);\n\n const controller = new AbortController();\n const timeoutMs = runtimeConfig.timeoutMs ?? options?.timeoutMs;\n const timeout = timeoutMs\n ? setTimeout(() => controller.abort(), timeoutMs)\n : undefined;\n\n try {\n const normalizedBody = normalizeJsonBody(input.body);\n const hasBody = normalizedBody !== undefined;\n const requestInit: RequestInit = {\n method: tool.method,\n headers: buildHeaders(runtimeConfig, input.headers, hasBody),\n signal: controller.signal\n };\n\n if (hasBody) {\n const bodySchema = tool.parameters.properties?.body;\n const bodyValidationErrors = validateAgainstSchema(normalizedBody, bodySchema);\n\n if (bodyValidationErrors.length > 0) {\n return formatToolResult({\n ok: false,\n status: 400,\n statusText: \"INVALID_TOOL_INPUT\",\n data: {\n message: \"Tool input body does not match the generated schema.\",\n errors: bodyValidationErrors,\n received: normalizedBody\n }\n });\n }\n\n requestInit.body = JSON.stringify(normalizedBody);\n }\n\n const response = await fetch(finalUrl, requestInit);\n\n const payload = await parseResponse(response);\n\n if (!response.ok) {\n return formatToolResult({\n ok: false,\n status: response.status,\n statusText: response.statusText,\n data: payload\n });\n }\n\n return formatToolResult(payload);\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n }\n }\n },\n { optional: catalog.optional ?? true }\n );\n }\n };\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/openapi.ts","../src/utils.ts","../src/generator.ts"],"sourcesContent":["import { promises as fs } from \"node:fs\";\nimport {\n ConvertOpenApiOptions,\n JsonSchema,\n OpenApiDocument,\n OpenApiOperationObject,\n OpenClawPluginCatalog,\n OpenClawToolDefinition\n} from \"./types\";\nimport {\n AUTH_HEADER_NAMES,\n HTTP_METHODS,\n buildOperationId,\n buildToolName,\n compactObject,\n dedupeParameters,\n hasSchemaContent,\n pickContentSchema,\n toTitleCase\n} from \"./utils\";\n\nconst isHttpUrl = (value: string): boolean => /^https?:\\/\\//i.test(value);\n\nconst readUrl = async (url: string): Promise<string> => {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Unable to load OpenAPI document from ${url}: ${response.status} ${response.statusText}`);\n }\n\n return response.text();\n};\n\nexport const loadOpenApiDocument = async (source: string): Promise<OpenApiDocument> => {\n const raw = isHttpUrl(source)\n ? await readUrl(source)\n : await fs.readFile(source, \"utf8\");\n\n const document = JSON.parse(raw) as OpenApiDocument;\n\n if (!document.openapi || !document.paths) {\n throw new Error(\"Invalid OpenAPI document: missing `openapi` or `paths`.\");\n }\n\n return document;\n};\n\nconst cloneJsonSchema = (value: JsonSchema): JsonSchema => JSON.parse(JSON.stringify(value)) as JsonSchema;\n\nconst resolveRefName = (ref: string): string => ref.split(\"/\").pop() ?? \"UnknownSchema\";\n\nconst resolveSchemaRef = (\n document: OpenApiDocument,\n ref: string\n): import(\"./types\").OpenApiSchemaObject | undefined => {\n const schemaName = resolveRefName(ref);\n return document.components?.schemas?.[schemaName];\n};\n\nexport const openApiSchemaToJsonSchema = (\n schema: import(\"./types\").OpenApiSchemaObject | undefined,\n document: OpenApiDocument,\n seen = new Set<string>()\n): JsonSchema => {\n if (!schema) {\n return { type: \"object\", additionalProperties: true };\n }\n\n if (schema.$ref) {\n if (seen.has(schema.$ref)) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const resolved = resolveSchemaRef(document, schema.$ref);\n\n if (!resolved) {\n return { type: \"object\", additionalProperties: true };\n }\n\n const nextSeen = new Set(seen);\n nextSeen.add(schema.$ref);\n return openApiSchemaToJsonSchema(resolved, document, nextSeen);\n }\n\n const jsonSchema: JsonSchema = compactObject({\n type: Array.isArray(schema.type) ? [...schema.type] : schema.type,\n description: schema.description,\n default: schema.default,\n enum: schema.enum ? [...schema.enum] : undefined\n });\n\n if (schema.oneOf?.length) {\n jsonSchema.oneOf = schema.oneOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.anyOf?.length) {\n jsonSchema.anyOf = schema.anyOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.allOf?.length) {\n jsonSchema.allOf = schema.allOf.map((item) => openApiSchemaToJsonSchema(item, document, seen));\n }\n\n if (schema.items) {\n jsonSchema.items = openApiSchemaToJsonSchema(schema.items, document, seen);\n }\n\n if (schema.properties) {\n jsonSchema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([key, value]) => [\n key,\n openApiSchemaToJsonSchema(value, document, seen)\n ])\n );\n }\n\n if (schema.required?.length) {\n jsonSchema.required = [...schema.required];\n }\n\n if (schema.additionalProperties !== undefined) {\n jsonSchema.additionalProperties =\n schema.additionalProperties === true || schema.additionalProperties === false\n ? schema.additionalProperties\n : openApiSchemaToJsonSchema(schema.additionalProperties, document, seen);\n }\n\n if (schema.nullable) {\n const currentType = jsonSchema.type;\n\n if (Array.isArray(currentType)) {\n jsonSchema.type = currentType.includes(\"null\") ? currentType : [...currentType, \"null\"];\n } else if (currentType) {\n jsonSchema.type = currentType === \"null\" ? \"null\" : [currentType, \"null\"];\n } else {\n jsonSchema.type = [\"object\", \"null\"];\n }\n }\n\n return jsonSchema;\n};\n\nconst buildParameterSection = (\n sectionName: string,\n parameters: import(\"./types\").OpenApiParameterObject[],\n document: OpenApiDocument\n): { name: string; schema: JsonSchema; required: boolean } | null => {\n if (!parameters.length) {\n return null;\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const parameter of parameters) {\n properties[parameter.name] = compactObject({\n ...openApiSchemaToJsonSchema(parameter.schema, document),\n description: parameter.description ?? parameter.schema?.description\n });\n\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n return {\n name: sectionName,\n required: required.length > 0,\n schema: compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false\n })\n };\n};\n\nconst buildToolParameters = (\n document: OpenApiDocument,\n path: string,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): JsonSchema => {\n const requestBodySchema = pickContentSchema(operation.requestBody?.content);\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n const sections = [\n buildParameterSection(\"path\", pathParameters, document),\n buildParameterSection(\"query\", queryParameters, document),\n options.includeHeaders ? buildParameterSection(\"headers\", headerParameters, document) : null\n ].filter((value): value is { name: string; schema: JsonSchema; required: boolean } => Boolean(value));\n\n for (const section of sections) {\n if (hasSchemaContent(section.schema)) {\n properties[section.name] = section.schema;\n if (section.required) {\n required.push(section.name);\n }\n }\n }\n\n if (requestBodySchema) {\n properties.body = openApiSchemaToJsonSchema(requestBodySchema, document);\n if (operation.requestBody?.required) {\n required.push(\"body\");\n }\n }\n\n return compactObject({\n type: \"object\",\n properties,\n required: required.length ? required : undefined,\n additionalProperties: false,\n description: `${operation.summary ?? operation.operationId ?? `${path} request`} tool arguments`\n });\n};\n\nconst buildToolDescription = (path: string, method: string, operation: OpenApiOperationObject): string => {\n const summary = operation.summary?.trim();\n const description = operation.description?.trim();\n\n if (summary && description && description !== summary) {\n return `${summary}. ${description}`;\n }\n\n if (summary) {\n return summary;\n }\n\n if (description) {\n return description;\n }\n\n return `${method.toUpperCase()} ${path}`;\n};\n\nconst buildToolDefinition = (\n document: OpenApiDocument,\n path: string,\n method: import(\"./types\").HttpMethod,\n operation: OpenApiOperationObject,\n options: ConvertOpenApiOptions,\n pathParameters: import(\"./types\").OpenApiParameterObject[],\n queryParameters: import(\"./types\").OpenApiParameterObject[],\n headerParameters: import(\"./types\").OpenApiParameterObject[]\n): OpenClawToolDefinition => {\n const operationId = buildOperationId(method, path, operation.operationId);\n\n return {\n name: buildToolName(options.toolPrefix, operationId),\n description: buildToolDescription(path, method, operation),\n method: method.toUpperCase() as Uppercase<typeof method>,\n path,\n operationId,\n parameters: buildToolParameters(\n document,\n path,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n ),\n tags: operation.tags ?? []\n };\n};\n\nexport const convertOpenApiToTools = (\n document: OpenApiDocument,\n options: ConvertOpenApiOptions\n): OpenClawPluginCatalog => {\n const tools: OpenClawToolDefinition[] = [];\n\n for (const [path, pathItem] of Object.entries(document.paths)) {\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const parameters = dedupeParameters(pathItem.parameters, operation.parameters);\n const pathParameters = parameters.filter((parameter) => parameter.in === \"path\");\n const queryParameters = parameters.filter((parameter) => parameter.in === \"query\");\n const headerParameters = parameters.filter(\n (parameter) =>\n parameter.in === \"header\" &&\n !AUTH_HEADER_NAMES.has(parameter.name.toLowerCase())\n );\n\n tools.push(\n buildToolDefinition(\n document,\n path,\n method,\n operation,\n options,\n pathParameters,\n queryParameters,\n headerParameters\n )\n );\n }\n }\n\n tools.sort((left, right) => left.name.localeCompare(right.name));\n\n return {\n pluginId: options.pluginId,\n pluginName: options.pluginName ?? toTitleCase(options.pluginId),\n description:\n document.info?.description?.trim() ??\n `Generated OpenClaw tool plugin for ${document.info?.title ?? options.pluginId}`,\n serverUrl: options.defaultServerUrl ?? document.servers?.[0]?.url,\n optional: options.optional ?? true,\n tools\n };\n};\n","import { HttpMethod, JsonSchema, OpenApiParameterObject } from \"./types\";\n\nexport const HTTP_METHODS: HttpMethod[] = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"options\",\n \"head\"\n];\n\nexport const AUTH_HEADER_NAMES = new Set([\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"dt-jwt\"\n]);\n\nexport const sanitizeIdentifier = (value: string): string =>\n value\n .trim()\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .replace(/_{2,}/g, \"_\")\n .toLowerCase() || \"tool\";\n\nexport const toTitleCase = (value: string): string =>\n value\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n\nexport const buildToolName = (toolPrefix: string | undefined, rawName: string): string => {\n const base = sanitizeIdentifier(rawName);\n const prefix = sanitizeIdentifier(toolPrefix ?? \"\");\n return prefix ? `${prefix}_${base}` : base;\n};\n\nexport const buildOperationId = (method: HttpMethod, path: string, operationId?: string): string => {\n if (operationId?.trim()) {\n return sanitizeIdentifier(operationId);\n }\n\n const pathPart = path\n .replace(/\\{([^}]+)\\}/g, \"by_$1\")\n .replace(/\\/+/g, \"_\");\n\n return sanitizeIdentifier(`${method}_${pathPart}`);\n};\n\nexport const pickContentSchema = (\n content: Record<string, { schema?: import(\"./types\").OpenApiSchemaObject | undefined }> | undefined\n): import(\"./types\").OpenApiSchemaObject | undefined =>\n content?.[\"application/json\"]?.schema ??\n content?.[\"application/*+json\"]?.schema ??\n Object.values(content ?? {})[0]?.schema;\n\nexport const dedupeParameters = (\n pathLevel: OpenApiParameterObject[] | undefined,\n operationLevel: OpenApiParameterObject[] | undefined\n): OpenApiParameterObject[] => {\n const byKey = new Map<string, OpenApiParameterObject>();\n\n for (const param of [...(pathLevel ?? []), ...(operationLevel ?? [])]) {\n byKey.set(`${param.in}:${param.name}`, param);\n }\n\n return [...byKey.values()];\n};\n\nexport const compactObject = <T extends Record<string, unknown>>(value: T): T => {\n const output = {} as T;\n\n for (const [key, item] of Object.entries(value)) {\n if (item !== undefined) {\n output[key as keyof T] = item as T[keyof T];\n }\n }\n\n return output;\n};\n\nexport const hasSchemaContent = (schema: JsonSchema | undefined): boolean =>\n Boolean(\n schema &&\n ((schema.properties && Object.keys(schema.properties).length > 0) ||\n (schema.required && schema.required.length > 0) ||\n schema.type ||\n schema.oneOf ||\n schema.anyOf ||\n schema.allOf)\n );\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n ConvertOpenApiOptions,\n GeneratedPluginFiles,\n GeneratePluginOptions,\n OpenClawPluginCatalog\n} from \"./types\";\nimport { convertOpenApiToTools, loadOpenApiDocument } from \"./openapi\";\n\nconst serialize = (value: unknown): string => JSON.stringify(value, null, 2);\n\nexport const renderPluginManifest = (catalog: OpenClawPluginCatalog): string =>\n `${serialize({\n id: catalog.pluginId,\n name: catalog.pluginName,\n version: \"0.1.0\",\n description: catalog.description,\n configSchema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n baseUrl: {\n type: \"string\",\n description: \"Base URL of the target HTTP API\"\n },\n bearerToken: {\n type: \"string\",\n description: \"Bearer token used for Authorization header\"\n },\n apiKey: {\n type: \"string\",\n description: \"Static API key for the upstream API\"\n },\n apiKeyHeader: {\n type: \"string\",\n description: \"Header name used when apiKey is set\",\n default: \"x-api-key\"\n },\n timeoutMs: {\n type: \"number\",\n description: \"Timeout in milliseconds for outbound tool calls\"\n },\n defaultHeaders: {\n type: \"object\",\n additionalProperties: {\n type: \"string\"\n },\n description: \"Additional headers added to every request\"\n }\n }\n },\n uiHints: {\n baseUrl: {\n label: \"Base URL\",\n placeholder: catalog.serverUrl ?? \"https://api.example.com\"\n },\n bearerToken: {\n label: \"Bearer Token\",\n sensitive: true\n },\n apiKey: {\n label: \"API Key\",\n sensitive: true\n },\n apiKeyHeader: {\n label: \"API Key Header\"\n },\n timeoutMs: {\n label: \"Timeout (ms)\"\n }\n }\n })}\\n`;\n\nexport const renderPluginModule = (catalog: OpenClawPluginCatalog): string =>\n `import { createOpenApiPlugin } from \"@redonvn/open-claw-sdk\";\n\nexport const catalog = ${serialize(catalog)} as const;\n\nexport default createOpenApiPlugin(catalog);\n`;\n\nexport const renderCatalogFile = (catalog: OpenClawPluginCatalog): string =>\n `${serialize(catalog)}\\n`;\n\nconst ensureDir = async (dirPath: string): Promise<void> => {\n await fs.mkdir(dirPath, { recursive: true });\n};\n\nexport const writeGeneratedPlugin = async (\n catalog: OpenClawPluginCatalog,\n outDir: string\n): Promise<GeneratedPluginFiles> => {\n await ensureDir(outDir);\n\n const manifestPath = path.join(outDir, \"openclaw.plugin.json\");\n const indexPath = path.join(outDir, \"index.ts\");\n const catalogPath = path.join(outDir, \"tool-catalog.json\");\n\n await Promise.all([\n fs.writeFile(manifestPath, renderPluginManifest(catalog), \"utf8\"),\n fs.writeFile(indexPath, renderPluginModule(catalog), \"utf8\"),\n fs.writeFile(catalogPath, renderCatalogFile(catalog), \"utf8\")\n ]);\n\n return { manifestPath, indexPath, catalogPath };\n};\n\nexport const generatePluginFromOpenApi = async (\n options: GeneratePluginOptions\n): Promise<{ catalog: OpenClawPluginCatalog; files: GeneratedPluginFiles }> => {\n const document = await loadOpenApiDocument(options.input);\n const convertOptions: ConvertOpenApiOptions = {\n pluginId: options.pluginId,\n pluginName: options.pluginName,\n toolPrefix: options.toolPrefix,\n optional: options.optional,\n includeHeaders: options.includeHeaders,\n defaultServerUrl: options.defaultServerUrl\n };\n const catalog = convertOpenApiToTools(document, convertOptions);\n const files = await writeGeneratedPlugin(catalog, options.outDir);\n\n return { catalog, files };\n};\n"],"mappings":"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","names":["path","path","fs","fs"]}
|