@honeybee-ai/waggle-cli 1.0.21 → 1.0.23

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.
@@ -0,0 +1,283 @@
1
+ /**
2
+ * GraphQL → FunnelToolDef[] loader.
3
+ *
4
+ * Two modes:
5
+ * 1. URL source → introspect the endpoint
6
+ * 2. File source → parse local .graphql schema (needs --graphql-url for requests)
7
+ *
8
+ * Each Query/Mutation field becomes a funnel tool.
9
+ * Zero new npm deps.
10
+ */
11
+ import { readFileSync } from 'node:fs';
12
+ import { resolve } from 'node:path';
13
+ const TIMEOUT_MS = 30_000;
14
+ const VALID_NAME_RE = /^[a-zA-Z0-9_]+$/;
15
+ const INTROSPECTION_QUERY = `{
16
+ __schema {
17
+ queryType { name }
18
+ mutationType { name }
19
+ types {
20
+ name
21
+ kind
22
+ fields {
23
+ name
24
+ description
25
+ args { name description type { kind name ofType { kind name ofType { kind name ofType { kind name } } } } }
26
+ type { kind name ofType { kind name ofType { kind name ofType { kind name } } } }
27
+ }
28
+ }
29
+ }
30
+ }`;
31
+ /** Resolve a GQL type ref to a simple type string for tool params. */
32
+ function resolveTypeName(ref) {
33
+ if (ref.name)
34
+ return ref.name;
35
+ if (ref.ofType)
36
+ return resolveTypeName(ref.ofType);
37
+ return 'String';
38
+ }
39
+ /** Map GQL scalar types to simpler param types. */
40
+ function gqlTypeToParamType(ref) {
41
+ const name = resolveTypeName(ref);
42
+ switch (name) {
43
+ case 'Int':
44
+ case 'Float': return 'number';
45
+ case 'Boolean': return 'boolean';
46
+ case 'ID':
47
+ case 'String': return 'string';
48
+ default: return 'string'; // Enums, custom scalars → string
49
+ }
50
+ }
51
+ /** Get scalar field names from a type for auto-selection sets. */
52
+ function getScalarFields(typeName, types) {
53
+ const resolvedName = typeName;
54
+ const typeDef = types.find(t => t.name === resolvedName);
55
+ if (!typeDef?.fields)
56
+ return [];
57
+ return typeDef.fields
58
+ .filter(f => {
59
+ const name = resolveTypeName(f.type);
60
+ return ['String', 'Int', 'Float', 'Boolean', 'ID'].includes(name) ||
61
+ // Also include NON_NULL wrappers of scalars
62
+ (f.type.kind === 'NON_NULL' && f.type.ofType && ['String', 'Int', 'Float', 'Boolean', 'ID'].includes(resolveTypeName(f.type.ofType)));
63
+ })
64
+ .map(f => f.name);
65
+ }
66
+ /** Build a selection set string for a return type. */
67
+ function buildSelectionSet(returnType, types) {
68
+ const typeName = resolveTypeName(returnType);
69
+ const scalars = getScalarFields(typeName, types);
70
+ if (scalars.length > 0)
71
+ return `{ ${scalars.join(' ')} }`;
72
+ return ''; // Scalar return type, no selection needed
73
+ }
74
+ /**
75
+ * Load GraphQL tools from a URL (introspection) or local schema file.
76
+ *
77
+ * @param source - URL or file path
78
+ * @param endpointUrl - Required if source is a file (where to send queries)
79
+ * @param headers - Pre-resolved headers for introspection + query requests
80
+ */
81
+ export async function loadGraphQLTools(source, endpointUrl, headers) {
82
+ const isUrl = source.startsWith('http://') || source.startsWith('https://');
83
+ const queryEndpoint = isUrl ? source : endpointUrl;
84
+ if (!queryEndpoint) {
85
+ throw new Error(`GraphQL: source "${source}" is a file — pass --graphql-url to specify the query endpoint`);
86
+ }
87
+ let schema;
88
+ if (isUrl) {
89
+ // Introspect the endpoint
90
+ schema = await introspect(source, headers);
91
+ }
92
+ else {
93
+ // Parse local schema file for type information, then introspect if possible
94
+ // For local files, we still need introspection for full type resolution.
95
+ // Try introspecting the endpoint; fall back to basic schema parsing.
96
+ try {
97
+ schema = await introspect(queryEndpoint, headers);
98
+ }
99
+ catch {
100
+ // Fall back to basic file parsing
101
+ schema = parseSchemaFile(source);
102
+ }
103
+ }
104
+ const types = schema.data.__schema.types;
105
+ const queryTypeName = schema.data.__schema.queryType?.name;
106
+ const mutationTypeName = schema.data.__schema.mutationType?.name;
107
+ const tools = [];
108
+ // Process query fields
109
+ if (queryTypeName) {
110
+ const queryType = types.find(t => t.name === queryTypeName);
111
+ if (queryType?.fields) {
112
+ for (const field of queryType.fields) {
113
+ if (field.name.startsWith('__'))
114
+ continue; // Skip introspection fields
115
+ const tool = fieldToTool(field, 'query', queryEndpoint, headers || {}, types);
116
+ if (tool)
117
+ tools.push(tool);
118
+ }
119
+ }
120
+ }
121
+ // Process mutation fields
122
+ if (mutationTypeName) {
123
+ const mutationType = types.find(t => t.name === mutationTypeName);
124
+ if (mutationType?.fields) {
125
+ for (const field of mutationType.fields) {
126
+ if (field.name.startsWith('__'))
127
+ continue;
128
+ const tool = fieldToTool(field, 'mutation', queryEndpoint, headers || {}, types);
129
+ if (tool)
130
+ tools.push(tool);
131
+ }
132
+ }
133
+ }
134
+ return tools;
135
+ }
136
+ async function introspect(url, headers) {
137
+ const controller = new AbortController();
138
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
139
+ try {
140
+ const resp = await fetch(url, {
141
+ method: 'POST',
142
+ headers: { 'Content-Type': 'application/json', ...headers },
143
+ body: JSON.stringify({ query: INTROSPECTION_QUERY }),
144
+ signal: controller.signal,
145
+ });
146
+ clearTimeout(timer);
147
+ if (!resp.ok) {
148
+ throw new Error(`GraphQL introspection failed: HTTP ${resp.status}`);
149
+ }
150
+ const result = await resp.json();
151
+ if (!result.data?.__schema) {
152
+ throw new Error('GraphQL introspection: invalid response (missing __schema)');
153
+ }
154
+ return result;
155
+ }
156
+ catch (err) {
157
+ clearTimeout(timer);
158
+ if (err instanceof Error && err.name === 'AbortError') {
159
+ throw new Error(`GraphQL introspection timed out after ${TIMEOUT_MS / 1000}s`);
160
+ }
161
+ throw err;
162
+ }
163
+ }
164
+ /** Basic .graphql schema file parser — extracts Query/Mutation types. */
165
+ function parseSchemaFile(filePath) {
166
+ const abs = resolve(filePath);
167
+ const content = readFileSync(abs, 'utf8');
168
+ const types = [];
169
+ let queryTypeName = null;
170
+ let mutationTypeName = null;
171
+ // Match type blocks: `type Query { ... }` or `type Mutation { ... }`
172
+ const typeBlockRe = /type\s+(\w+)\s*\{([^}]*)}/g;
173
+ let match;
174
+ while ((match = typeBlockRe.exec(content)) !== null) {
175
+ const typeName = match[1];
176
+ const body = match[2];
177
+ if (typeName === 'Query')
178
+ queryTypeName = 'Query';
179
+ if (typeName === 'Mutation')
180
+ mutationTypeName = 'Mutation';
181
+ // Parse fields: `fieldName(arg1: Type!, arg2: Type): ReturnType`
182
+ const fields = [];
183
+ const fieldRe = /(\w+)\s*(?:\(([^)]*)\))?\s*:\s*([^\n#![\]]+[!\]\s]*)/g;
184
+ let fieldMatch;
185
+ while ((fieldMatch = fieldRe.exec(body)) !== null) {
186
+ const fieldName = fieldMatch[1];
187
+ const argsStr = fieldMatch[2] || '';
188
+ const returnTypeStr = fieldMatch[3].trim().replace(/!$/, '');
189
+ const args = [];
190
+ if (argsStr) {
191
+ // Parse args: `name: Type!`
192
+ const argRe = /(\w+)\s*:\s*(\w+)(!?)/g;
193
+ let argMatch;
194
+ while ((argMatch = argRe.exec(argsStr)) !== null) {
195
+ args.push({
196
+ name: argMatch[1],
197
+ type: { kind: 'SCALAR', name: argMatch[2] },
198
+ });
199
+ }
200
+ }
201
+ fields.push({
202
+ name: fieldName,
203
+ args,
204
+ type: { kind: 'OBJECT', name: returnTypeStr.replace(/[[\]!]/g, '').trim() },
205
+ });
206
+ }
207
+ types.push({ name: typeName, kind: 'OBJECT', fields });
208
+ }
209
+ return {
210
+ data: {
211
+ __schema: {
212
+ queryType: queryTypeName ? { name: queryTypeName } : null,
213
+ mutationType: mutationTypeName ? { name: mutationTypeName } : null,
214
+ types,
215
+ },
216
+ },
217
+ };
218
+ }
219
+ function fieldToTool(field, opType, endpoint, headers, types) {
220
+ if (!VALID_NAME_RE.test(field.name))
221
+ return null;
222
+ const description = field.description || `GraphQL ${opType}: ${field.name}`;
223
+ // Build params from field args
224
+ const params = {};
225
+ for (const arg of field.args) {
226
+ params[arg.name] = {
227
+ type: gqlTypeToParamType(arg.type),
228
+ description: arg.description,
229
+ };
230
+ }
231
+ // Build selection set
232
+ const selectionSet = buildSelectionSet(field.type, types);
233
+ // Capture for closure
234
+ const fieldName = field.name;
235
+ const capturedArgs = field.args;
236
+ const handler = async (args) => {
237
+ // Build argument string for the query
238
+ const argParts = [];
239
+ const variables = {};
240
+ for (const arg of capturedArgs) {
241
+ if (args[arg.name] !== undefined) {
242
+ variables[arg.name] = args[arg.name];
243
+ const gqlType = resolveTypeName(arg.type);
244
+ argParts.push(`$${arg.name}: ${gqlType}${arg.type.kind === 'NON_NULL' ? '!' : ''}`);
245
+ }
246
+ }
247
+ // Build inline variable references
248
+ const fieldArgs = capturedArgs
249
+ .filter(a => args[a.name] !== undefined)
250
+ .map(a => `${a.name}: $${a.name}`)
251
+ .join(', ');
252
+ const varDecl = argParts.length > 0 ? `(${argParts.join(', ')})` : '';
253
+ const fieldArgStr = fieldArgs ? `(${fieldArgs})` : '';
254
+ const query = `${opType}${varDecl} { ${fieldName}${fieldArgStr}${selectionSet ? ' ' + selectionSet : ''} }`;
255
+ const controller = new AbortController();
256
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
257
+ try {
258
+ const resp = await fetch(endpoint, {
259
+ method: 'POST',
260
+ headers: { 'Content-Type': 'application/json', ...headers },
261
+ body: JSON.stringify({ query, variables }),
262
+ signal: controller.signal,
263
+ });
264
+ clearTimeout(timer);
265
+ const result = await resp.json();
266
+ if (result.errors?.length) {
267
+ return { ok: false, error: result.errors[0].message };
268
+ }
269
+ return { ok: true, data: result.data?.[fieldName] };
270
+ }
271
+ catch (err) {
272
+ clearTimeout(timer);
273
+ if (err instanceof Error && err.name === 'AbortError') {
274
+ return { ok: false, error: `Request timed out after ${TIMEOUT_MS / 1000}s` };
275
+ }
276
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
277
+ }
278
+ };
279
+ return { name: fieldName, description, params, handler };
280
+ }
281
+ // Exported for testing
282
+ export { parseSchemaFile, introspect };
283
+ //# sourceMappingURL=graphql-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql-loader.js","sourceRoot":"","sources":["../../src/lib/graphql-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Resolve --api-header values with ${VAR} env interpolation.
3
+ *
4
+ * Input: ["Authorization: Bearer ${API_KEY}", "X-Custom: static"]
5
+ * Output: { Authorization: "Bearer sk-...", "X-Custom": "static" }
6
+ *
7
+ * Warns on unresolved vars (missing from process.env).
8
+ */
9
+ export declare function resolveHeaders(raw: string[]): Record<string, string>;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Resolve --api-header values with ${VAR} env interpolation.
3
+ *
4
+ * Input: ["Authorization: Bearer ${API_KEY}", "X-Custom: static"]
5
+ * Output: { Authorization: "Bearer sk-...", "X-Custom": "static" }
6
+ *
7
+ * Warns on unresolved vars (missing from process.env).
8
+ */
9
+ export function resolveHeaders(raw) {
10
+ const headers = {};
11
+ for (const entry of raw) {
12
+ const colonIdx = entry.indexOf(':');
13
+ if (colonIdx <= 0) {
14
+ console.warn(`Skipping malformed header (expected "Name: value"): ${entry}`);
15
+ continue;
16
+ }
17
+ const name = entry.slice(0, colonIdx).trim();
18
+ let value = entry.slice(colonIdx + 1).trim();
19
+ // Interpolate ${VAR} from process.env
20
+ value = value.replace(/\$\{([^}]+)\}/g, (_match, varName) => {
21
+ const envVal = process.env[varName];
22
+ if (envVal === undefined) {
23
+ console.warn(`Warning: env var ${varName} not set (in header "${name}")`);
24
+ return '';
25
+ }
26
+ return envVal;
27
+ });
28
+ headers[name] = value;
29
+ }
30
+ return headers;
31
+ }
32
+ //# sourceMappingURL=header-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-resolver.js","sourceRoot":"","sources":["../../src/lib/header-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,UAAU,cAAc,CAAC,GAAa;IAC1C,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,uDAAuD,KAAK,EAAE,CAAC,CAAC;YAC7E,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE7C,sCAAsC;QACtC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAe,EAAE,EAAE;YAClE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,CAAC,IAAI,CAAC,oBAAoB,OAAO,wBAAwB,IAAI,IAAI,CAAC,CAAC;gBAC1E,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * OpenAPI 3.x → FunnelToolDef[] loader.
3
+ *
4
+ * Parses an OpenAPI spec (YAML/JSON) and converts each operation with
5
+ * an operationId into a funnel tool that proxies HTTP requests.
6
+ *
7
+ * Zero new npm deps — js-yaml already installed.
8
+ */
9
+ import type { FunnelToolDef } from './dance-loader.js';
10
+ /**
11
+ * Load an OpenAPI 3.x spec and return funnel tool definitions.
12
+ *
13
+ * @param filePath - Path to YAML/JSON spec file
14
+ * @param baseUrl - Override base URL (falls back to spec.servers[0].url)
15
+ * @param headers - Pre-resolved headers to include in every request
16
+ */
17
+ export declare function loadOpenAPITools(filePath: string, baseUrl?: string, headers?: Record<string, string>): Promise<FunnelToolDef[]>;
@@ -0,0 +1,164 @@
1
+ /**
2
+ * OpenAPI 3.x → FunnelToolDef[] loader.
3
+ *
4
+ * Parses an OpenAPI spec (YAML/JSON) and converts each operation with
5
+ * an operationId into a funnel tool that proxies HTTP requests.
6
+ *
7
+ * Zero new npm deps — js-yaml already installed.
8
+ */
9
+ import { readFileSync } from 'node:fs';
10
+ import { resolve } from 'node:path';
11
+ import yaml from 'js-yaml';
12
+ const VALID_NAME_RE = /^[a-zA-Z0-9_-]+$/;
13
+ const BODY_METHODS = new Set(['post', 'put', 'patch']);
14
+ const RESPONSE_LIMIT = 10 * 1024 * 1024; // 10MB
15
+ const TIMEOUT_MS = 30_000;
16
+ /**
17
+ * Load an OpenAPI 3.x spec and return funnel tool definitions.
18
+ *
19
+ * @param filePath - Path to YAML/JSON spec file
20
+ * @param baseUrl - Override base URL (falls back to spec.servers[0].url)
21
+ * @param headers - Pre-resolved headers to include in every request
22
+ */
23
+ export async function loadOpenAPITools(filePath, baseUrl, headers) {
24
+ const abs = resolve(filePath);
25
+ const content = readFileSync(abs, 'utf8');
26
+ const spec = (abs.endsWith('.json') ? JSON.parse(content) : yaml.load(content));
27
+ // Resolve base URL
28
+ let resolvedBase = baseUrl;
29
+ if (!resolvedBase) {
30
+ const servers = spec.servers;
31
+ if (servers?.[0]?.url) {
32
+ resolvedBase = servers[0].url;
33
+ }
34
+ }
35
+ if (!resolvedBase) {
36
+ throw new Error(`OpenAPI spec ${filePath}: no base URL — pass --api-url or add servers[0].url to spec`);
37
+ }
38
+ // Strip trailing slash
39
+ resolvedBase = resolvedBase.replace(/\/+$/, '');
40
+ const paths = spec.paths;
41
+ if (!paths)
42
+ return [];
43
+ const tools = [];
44
+ for (const [pathTemplate, methods] of Object.entries(paths)) {
45
+ for (const [method, operation] of Object.entries(methods)) {
46
+ // Skip non-operation keys (parameters, summary, etc.)
47
+ if (!operation || typeof operation !== 'object' || !operation.operationId)
48
+ continue;
49
+ const opId = operation.operationId;
50
+ if (!VALID_NAME_RE.test(opId)) {
51
+ console.warn(`OpenAPI: skipping operation with invalid operationId "${opId}"`);
52
+ continue;
53
+ }
54
+ const description = operation.summary || operation.description || `${method.toUpperCase()} ${pathTemplate}`;
55
+ // Build params from path/query/header parameters
56
+ const params = {};
57
+ const pathParams = [];
58
+ const queryParams = [];
59
+ if (operation.parameters) {
60
+ for (const p of operation.parameters) {
61
+ const paramType = p.schema?.type || 'string';
62
+ params[p.name] = { type: paramType, description: p.description };
63
+ if (p.in === 'path')
64
+ pathParams.push(p.name);
65
+ if (p.in === 'query')
66
+ queryParams.push(p.name);
67
+ }
68
+ }
69
+ // Body params for POST/PUT/PATCH
70
+ if (BODY_METHODS.has(method)) {
71
+ const bodySchema = operation.requestBody?.content?.['application/json']?.schema;
72
+ if (bodySchema?.properties) {
73
+ for (const [propName, propDef] of Object.entries(bodySchema.properties)) {
74
+ params[propName] = { type: propDef.type || 'string', description: propDef.description };
75
+ }
76
+ }
77
+ }
78
+ // Capture for closure
79
+ const httpMethod = method.toUpperCase();
80
+ const template = pathTemplate;
81
+ const base = resolvedBase;
82
+ const hdrs = headers || {};
83
+ const isBodyMethod = BODY_METHODS.has(method);
84
+ const capturedPathParams = pathParams;
85
+ const capturedQueryParams = queryParams;
86
+ const handler = async (args) => {
87
+ // Build URL: replace path params
88
+ let path = template;
89
+ for (const p of capturedPathParams) {
90
+ const val = args[p];
91
+ if (val !== undefined) {
92
+ path = path.replace(`{${p}}`, encodeURIComponent(String(val)));
93
+ }
94
+ }
95
+ // Append query params
96
+ const qParts = [];
97
+ for (const p of capturedQueryParams) {
98
+ if (args[p] !== undefined) {
99
+ qParts.push(`${encodeURIComponent(p)}=${encodeURIComponent(String(args[p]))}`);
100
+ }
101
+ }
102
+ const queryStr = qParts.length > 0 ? `?${qParts.join('&')}` : '';
103
+ const url = `${base}${path}${queryStr}`;
104
+ // Build request
105
+ const reqHeaders = { ...hdrs };
106
+ const fetchOpts = { method: httpMethod, headers: reqHeaders };
107
+ if (isBodyMethod) {
108
+ reqHeaders['Content-Type'] = 'application/json';
109
+ // Body = all args minus path and query params
110
+ const bodyArgs = {};
111
+ for (const [k, v] of Object.entries(args)) {
112
+ if (!capturedPathParams.includes(k) && !capturedQueryParams.includes(k)) {
113
+ bodyArgs[k] = v;
114
+ }
115
+ }
116
+ if (Object.keys(bodyArgs).length > 0) {
117
+ fetchOpts.body = JSON.stringify(bodyArgs);
118
+ }
119
+ }
120
+ // Execute with timeout
121
+ const controller = new AbortController();
122
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
123
+ fetchOpts.signal = controller.signal;
124
+ try {
125
+ const resp = await fetch(url, fetchOpts);
126
+ clearTimeout(timer);
127
+ // Read response with size limit
128
+ const respText = await resp.text();
129
+ if (respText.length > RESPONSE_LIMIT) {
130
+ return { ok: false, error: `Response exceeds ${RESPONSE_LIMIT / 1024 / 1024}MB limit` };
131
+ }
132
+ let body;
133
+ try {
134
+ body = JSON.parse(respText);
135
+ }
136
+ catch {
137
+ body = respText;
138
+ }
139
+ if (resp.ok) {
140
+ return {
141
+ ok: true,
142
+ data: {
143
+ status: resp.status,
144
+ headers: Object.fromEntries(resp.headers.entries()),
145
+ body,
146
+ },
147
+ };
148
+ }
149
+ return { ok: false, error: `HTTP ${resp.status}: ${typeof body === 'string' ? body : JSON.stringify(body)}` };
150
+ }
151
+ catch (err) {
152
+ clearTimeout(timer);
153
+ if (err instanceof Error && err.name === 'AbortError') {
154
+ return { ok: false, error: `Request timed out after ${TIMEOUT_MS / 1000}s` };
155
+ }
156
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
157
+ }
158
+ };
159
+ tools.push({ name: opId, description, params, handler });
160
+ }
161
+ }
162
+ return tools;
163
+ }
164
+ //# sourceMappingURL=openapi-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-loader.js","sourceRoot":"","sources":["../../src/lib/openapi-loader.ts"],"names":[],"mappings":"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"}