@executor-js/plugin-openapi 0.0.1-beta.4 → 0.0.1-beta.6

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.
@@ -14,9 +14,7 @@ var OpenApiExtractionError = class extends Schema.TaggedError()(
14
14
  }
15
15
  ) {
16
16
  };
17
- var OpenApiInvocationError = class extends Data.TaggedError(
18
- "OpenApiInvocationError"
19
- ) {
17
+ var OpenApiInvocationError = class extends Data.TaggedError("OpenApiInvocationError") {
20
18
  };
21
19
 
22
20
  // src/sdk/parse.ts
@@ -25,11 +23,15 @@ import { Effect } from "effect";
25
23
  import YAML from "yaml";
26
24
  var parse = Effect.fn("OpenApi.parse")(function* (input) {
27
25
  const api = yield* Effect.tryPromise({
28
- try: () => {
29
- if (input.startsWith("http://") || input.startsWith("https://")) {
30
- return SwaggerParser.bundle(input);
26
+ try: async () => {
27
+ const source = input.startsWith("http://") || input.startsWith("https://") ? input : parseTextToObject(input);
28
+ try {
29
+ return await SwaggerParser.bundle(source);
30
+ } catch {
31
+ const parsed = await SwaggerParser.parse(source);
32
+ resolveRefsInPlace(parsed);
33
+ return parsed;
31
34
  }
32
- return SwaggerParser.bundle(parseTextToObject(input));
33
35
  },
34
36
  catch: (error) => new OpenApiParseError({
35
37
  message: `Failed to parse OpenAPI document: ${error instanceof Error ? error.message : String(error)}`
@@ -59,6 +61,67 @@ var parseTextToObject = (text) => {
59
61
  }
60
62
  return parsed;
61
63
  };
64
+ var resolveRefsInPlace = (doc) => {
65
+ const lookup = (pointer) => {
66
+ if (!pointer.startsWith("#/")) return void 0;
67
+ const parts = pointer.slice(2).split("/");
68
+ let current = doc;
69
+ for (const part of parts) {
70
+ if (typeof current !== "object" || current === null) return void 0;
71
+ current = current[part];
72
+ }
73
+ return current;
74
+ };
75
+ const resolving = /* @__PURE__ */ new Set();
76
+ const resolveRef = (pointer) => {
77
+ if (resolving.has(pointer)) return void 0;
78
+ const target = lookup(pointer);
79
+ if (!target) return void 0;
80
+ resolving.add(pointer);
81
+ const cloned = deepClone(target);
82
+ walk(cloned);
83
+ resolving.delete(pointer);
84
+ return cloned;
85
+ };
86
+ const deepClone = (obj) => {
87
+ if (!obj || typeof obj !== "object") return obj;
88
+ if (Array.isArray(obj)) return obj.map(deepClone);
89
+ const result = {};
90
+ for (const [k, v] of Object.entries(obj)) {
91
+ result[k] = deepClone(v);
92
+ }
93
+ return result;
94
+ };
95
+ const walk = (obj) => {
96
+ if (!obj || typeof obj !== "object") return;
97
+ if (Array.isArray(obj)) {
98
+ for (let i = 0; i < obj.length; i++) {
99
+ const item = obj[i];
100
+ if (isRef(item)) {
101
+ const resolved = resolveRef(item.$ref);
102
+ if (resolved) obj[i] = resolved;
103
+ else obj[i] = { description: `Unresolved: ${item.$ref}` };
104
+ } else {
105
+ walk(item);
106
+ }
107
+ }
108
+ return;
109
+ }
110
+ const record = obj;
111
+ for (const [k, v] of Object.entries(record)) {
112
+ if (k === "$ref") continue;
113
+ if (isRef(v)) {
114
+ const resolved = resolveRef(v.$ref);
115
+ if (resolved) record[k] = resolved;
116
+ else record[k] = { description: `Unresolved: ${v.$ref}` };
117
+ } else {
118
+ walk(v);
119
+ }
120
+ }
121
+ };
122
+ walk(doc);
123
+ };
124
+ var isRef = (v) => typeof v === "object" && v !== null && "$ref" in v && typeof v.$ref === "string";
62
125
 
63
126
  // src/sdk/openapi-utils.ts
64
127
  import { Option } from "effect";
@@ -69,7 +132,7 @@ var DocResolver = class {
69
132
  doc;
70
133
  /** Resolve a value that might be a $ref, returning the resolved object */
71
134
  resolve(value) {
72
- if (isRef(value)) {
135
+ if (isRef2(value)) {
73
136
  const resolved = this.resolvePointer(value.$ref);
74
137
  return resolved;
75
138
  }
@@ -86,7 +149,7 @@ var DocResolver = class {
86
149
  return current;
87
150
  }
88
151
  };
89
- var isRef = (value) => typeof value === "object" && value !== null && "$ref" in value;
152
+ var isRef2 = (value) => typeof value === "object" && value !== null && "$ref" in value;
90
153
  var resolveBaseUrl = (servers) => {
91
154
  const server = servers[0];
92
155
  if (!server) return "";
@@ -119,9 +182,7 @@ var HttpMethod = Schema2.Literal(
119
182
  "trace"
120
183
  );
121
184
  var ParameterLocation = Schema2.Literal("path", "query", "header", "cookie");
122
- var OperationParameter = class extends Schema2.Class(
123
- "OperationParameter"
124
- )({
185
+ var OperationParameter = class extends Schema2.Class("OperationParameter")({
125
186
  name: Schema2.String,
126
187
  location: ParameterLocation,
127
188
  required: Schema2.Boolean,
@@ -140,9 +201,7 @@ var OperationRequestBody = class extends Schema2.Class(
140
201
  schema: Schema2.optionalWith(Schema2.Unknown, { as: "Option" })
141
202
  }) {
142
203
  };
143
- var ExtractedOperation = class extends Schema2.Class(
144
- "ExtractedOperation"
145
- )({
204
+ var ExtractedOperation = class extends Schema2.Class("ExtractedOperation")({
146
205
  operationId: OperationId,
147
206
  method: HttpMethod,
148
207
  pathTemplate: Schema2.String,
@@ -158,24 +217,19 @@ var ExtractedOperation = class extends Schema2.Class(
158
217
  };
159
218
  var ServerInfo = class extends Schema2.Class("ServerInfo")({
160
219
  url: Schema2.String,
161
- variables: Schema2.optionalWith(
162
- Schema2.Record({ key: Schema2.String, value: Schema2.String }),
163
- { as: "Option" }
164
- )
220
+ variables: Schema2.optionalWith(Schema2.Record({ key: Schema2.String, value: Schema2.String }), {
221
+ as: "Option"
222
+ })
165
223
  }) {
166
224
  };
167
- var ExtractionResult = class extends Schema2.Class(
168
- "ExtractionResult"
169
- )({
225
+ var ExtractionResult = class extends Schema2.Class("ExtractionResult")({
170
226
  title: Schema2.optionalWith(Schema2.String, { as: "Option" }),
171
227
  version: Schema2.optionalWith(Schema2.String, { as: "Option" }),
172
228
  servers: Schema2.Array(ServerInfo),
173
229
  operations: Schema2.Array(ExtractedOperation)
174
230
  }) {
175
231
  };
176
- var OperationBinding = class extends Schema2.Class(
177
- "OperationBinding"
178
- )({
232
+ var OperationBinding = class extends Schema2.Class("OperationBinding")({
179
233
  method: HttpMethod,
180
234
  pathTemplate: Schema2.String,
181
235
  parameters: Schema2.Array(OperationParameter),
@@ -189,20 +243,15 @@ var HeaderValue = Schema2.Union(
189
243
  prefix: Schema2.optional(Schema2.String)
190
244
  })
191
245
  );
192
- var InvocationConfig = class extends Schema2.Class(
193
- "InvocationConfig"
194
- )({
246
+ var InvocationConfig = class extends Schema2.Class("InvocationConfig")({
195
247
  baseUrl: Schema2.String,
196
248
  /** Headers applied to every request. Values can reference secrets. */
197
- headers: Schema2.optionalWith(
198
- Schema2.Record({ key: Schema2.String, value: HeaderValue }),
199
- { default: () => ({}) }
200
- )
249
+ headers: Schema2.optionalWith(Schema2.Record({ key: Schema2.String, value: HeaderValue }), {
250
+ default: () => ({})
251
+ })
201
252
  }) {
202
253
  };
203
- var InvocationResult = class extends Schema2.Class(
204
- "InvocationResult"
205
- )({
254
+ var InvocationResult = class extends Schema2.Class("InvocationResult")({
206
255
  status: Schema2.Number,
207
256
  headers: Schema2.Record({ key: Schema2.String, value: Schema2.String }),
208
257
  data: Schema2.NullOr(Schema2.Unknown),
@@ -243,9 +292,7 @@ var extractParameters = (pathItem, operation, r) => {
243
292
  schema: Option2.fromNullable(p.schema),
244
293
  style: Option2.fromNullable(p.style),
245
294
  explode: Option2.fromNullable(p.explode),
246
- allowReserved: Option2.fromNullable(
247
- "allowReserved" in p ? p.allowReserved : void 0
248
- ),
295
+ allowReserved: Option2.fromNullable("allowReserved" in p ? p.allowReserved : void 0),
249
296
  description: Option2.fromNullable(p.description)
250
297
  })
251
298
  );
@@ -296,10 +343,7 @@ var buildInputSchema = (parameters, requestBody) => {
296
343
  additionalProperties: false
297
344
  };
298
345
  };
299
- var deriveOperationId = (method, pathTemplate, operation) => operation.operationId ?? (`${method}_${pathTemplate.replace(/[^a-zA-Z0-9]+/g, "_")}`.replace(
300
- /^_+|_+$/g,
301
- ""
302
- ) || `${method}_operation`);
346
+ var deriveOperationId = (method, pathTemplate, operation) => operation.operationId ?? (`${method}_${pathTemplate.replace(/[^a-zA-Z0-9]+/g, "_")}`.replace(/^_+|_+$/g, "") || `${method}_operation`);
303
347
  var extractServers = (doc) => (doc.servers ?? []).flatMap((server) => {
304
348
  if (!server.url) return [];
305
349
  const vars = server.variables ? Object.fromEntries(
@@ -337,9 +381,7 @@ var extract = Effect2.fn("OpenApi.extract")(function* (doc) {
337
381
  const tags = (operation.tags ?? []).filter((t) => t.trim().length > 0);
338
382
  operations.push(
339
383
  new ExtractedOperation({
340
- operationId: OperationId.make(
341
- deriveOperationId(method, pathTemplate, operation)
342
- ),
384
+ operationId: OperationId.make(deriveOperationId(method, pathTemplate, operation)),
343
385
  method,
344
386
  pathTemplate,
345
387
  summary: Option2.fromNullable(operation.summary),
@@ -364,14 +406,11 @@ var extract = Effect2.fn("OpenApi.extract")(function* (doc) {
364
406
 
365
407
  // src/sdk/invoke.ts
366
408
  import { Effect as Effect3, Layer, Option as Option3 } from "effect";
367
- import {
368
- HttpClient,
369
- HttpClientRequest
370
- } from "@effect/platform";
409
+ import { HttpClient, HttpClientRequest } from "@effect/platform";
371
410
  import {
372
411
  ToolInvocationResult,
373
412
  ToolInvocationError
374
- } from "@executor-js/sdk/core";
413
+ } from "@executor-js/sdk";
375
414
  var CONTAINER_KEYS = {
376
415
  path: ["path", "pathParams", "params"],
377
416
  query: ["query", "queryParams", "params"],
@@ -404,19 +443,13 @@ var resolvePath = Effect3.fn("OpenApi.resolvePath")(function* (pathTemplate, arg
404
443
  }
405
444
  continue;
406
445
  }
407
- resolved = resolved.replaceAll(
408
- `{${param.name}}`,
409
- encodeURIComponent(String(value))
410
- );
446
+ resolved = resolved.replaceAll(`{${param.name}}`, encodeURIComponent(String(value)));
411
447
  }
412
448
  const remaining = [...resolved.matchAll(/\{([^{}]+)\}/g)].map((m) => m[1]).filter((v) => typeof v === "string");
413
449
  for (const name of remaining) {
414
450
  const value = args[name];
415
451
  if (value !== void 0 && value !== null) {
416
- resolved = resolved.replaceAll(
417
- `{${name}}`,
418
- encodeURIComponent(String(value))
419
- );
452
+ resolved = resolved.replaceAll(`{${name}}`, encodeURIComponent(String(value)));
420
453
  }
421
454
  }
422
455
  const unresolved = [...resolved.matchAll(/\{([^{}]+)\}/g)].map((m) => m[1]).filter((v) => typeof v === "string");
@@ -462,32 +495,20 @@ var isJsonContentType = (ct) => {
462
495
  };
463
496
  var invoke = Effect3.fn("OpenApi.invoke")(function* (operation, args, config, resolvedHeaders) {
464
497
  const client = yield* HttpClient.HttpClient;
465
- const resolvedPath = yield* resolvePath(
466
- operation.pathTemplate,
467
- args,
468
- operation.parameters
469
- );
498
+ const resolvedPath = yield* resolvePath(operation.pathTemplate, args, operation.parameters);
470
499
  const path = resolvedPath.startsWith("/") ? resolvedPath : `/${resolvedPath}`;
471
500
  let request = HttpClientRequest.make(operation.method.toUpperCase())(path);
472
501
  for (const param of operation.parameters) {
473
502
  if (param.location !== "query") continue;
474
503
  const value = readParamValue(args, param);
475
504
  if (value === void 0 || value === null) continue;
476
- request = HttpClientRequest.setUrlParam(
477
- request,
478
- param.name,
479
- String(value)
480
- );
505
+ request = HttpClientRequest.setUrlParam(request, param.name, String(value));
481
506
  }
482
507
  for (const param of operation.parameters) {
483
508
  if (param.location !== "header") continue;
484
509
  const value = readParamValue(args, param);
485
510
  if (value === void 0 || value === null) continue;
486
- request = HttpClientRequest.setHeader(
487
- request,
488
- param.name,
489
- String(value)
490
- );
511
+ request = HttpClientRequest.setHeader(request, param.name, String(value));
491
512
  }
492
513
  if (Option3.isSome(operation.requestBody)) {
493
514
  const rb = operation.requestBody.value;
@@ -513,9 +534,7 @@ var invoke = Effect3.fn("OpenApi.invoke")(function* (operation, args, config, re
513
534
  const status = response.status;
514
535
  const responseHeaders = { ...response.headers };
515
536
  const contentType = response.headers["content-type"] ?? null;
516
- const responseBody = status === 204 ? null : isJsonContentType(contentType) ? yield* response.json.pipe(
517
- Effect3.catchAll(() => response.text)
518
- ) : yield* response.text;
537
+ const responseBody = status === 204 ? null : isJsonContentType(contentType) ? yield* response.json.pipe(Effect3.catchAll(() => response.text)) : yield* response.text;
519
538
  const ok = status >= 200 && status < 300;
520
539
  return new InvocationResult({
521
540
  status,
@@ -549,18 +568,12 @@ var makeOpenApiInvoker = (opts) => ({
549
568
  }
550
569
  const { binding, config } = entry;
551
570
  const baseUrl = config.baseUrl;
552
- const resolvedHeaders = yield* resolveHeaders(
553
- config.headers,
554
- opts.secrets,
555
- opts.scopeId
556
- );
571
+ const resolvedHeaders = yield* resolveHeaders(config.headers, opts.secrets, opts.scopeId);
557
572
  const clientWithBaseUrl = baseUrl ? Layer.effect(
558
573
  HttpClient.HttpClient,
559
574
  Effect3.map(
560
575
  HttpClient.HttpClient,
561
- HttpClient.mapRequest(
562
- HttpClientRequest.prependUrl(baseUrl)
563
- )
576
+ HttpClient.mapRequest(HttpClientRequest.prependUrl(baseUrl))
564
577
  )
565
578
  ).pipe(Layer.provide(opts.httpClientLayer)) : opts.httpClientLayer;
566
579
  const result = yield* invoke(
@@ -591,30 +604,34 @@ var makeOpenApiInvoker = (opts) => ({
591
604
  });
592
605
 
593
606
  // src/sdk/kv-operation-store.ts
594
- import { Effect as Effect4, Schema as Schema3 } from "effect";
595
- import { scopeKv, makeInMemoryScopedKv } from "@executor-js/sdk/core";
596
- var StoredEntry = class extends Schema3.Class("StoredEntry")({
597
- namespace: Schema3.String,
598
- binding: OperationBinding,
599
- config: InvocationConfig
600
- }) {
601
- };
602
- var encodeEntry = Schema3.encodeSync(Schema3.parseJson(StoredEntry));
603
- var decodeEntry = Schema3.decodeUnknownSync(Schema3.parseJson(StoredEntry));
604
- var StoredSourceSchema = Schema3.Struct({
607
+ import { Effect as Effect4, Schema as Schema4 } from "effect";
608
+ import { scopeKv, makeInMemoryScopedKv } from "@executor-js/sdk";
609
+
610
+ // src/sdk/stored-source.ts
611
+ import { Schema as Schema3 } from "effect";
612
+ var StoredSourceSchema = class extends Schema3.Class("OpenApiStoredSource")({
605
613
  namespace: Schema3.String,
606
614
  name: Schema3.String,
607
615
  config: Schema3.Struct({
608
616
  spec: Schema3.String,
609
617
  baseUrl: Schema3.optional(Schema3.String),
610
618
  namespace: Schema3.optional(Schema3.String),
611
- headers: Schema3.optional(
612
- Schema3.Record({ key: Schema3.String, value: HeaderValue })
613
- )
619
+ headers: Schema3.optional(Schema3.Record({ key: Schema3.String, value: HeaderValue }))
614
620
  })
615
- });
616
- var encodeSource = Schema3.encodeSync(Schema3.parseJson(StoredSourceSchema));
617
- var decodeSource = Schema3.decodeUnknownSync(Schema3.parseJson(StoredSourceSchema));
621
+ }) {
622
+ };
623
+
624
+ // src/sdk/kv-operation-store.ts
625
+ var StoredEntry = class extends Schema4.Class("StoredEntry")({
626
+ namespace: Schema4.String,
627
+ binding: OperationBinding,
628
+ config: InvocationConfig
629
+ }) {
630
+ };
631
+ var encodeEntry = Schema4.encodeSync(Schema4.parseJson(StoredEntry));
632
+ var decodeEntry = Schema4.decodeUnknownSync(Schema4.parseJson(StoredEntry));
633
+ var encodeSource = Schema4.encodeSync(Schema4.parseJson(StoredSourceSchema));
634
+ var decodeSource = Schema4.decodeUnknownSync(Schema4.parseJson(StoredSourceSchema));
618
635
  var makeStore = (bindings, sources) => {
619
636
  const withKvTransaction = (kv, effect) => kv.withTransaction?.(effect) ?? effect;
620
637
  return {
@@ -626,16 +643,14 @@ var makeStore = (bindings, sources) => {
626
643
  }),
627
644
  put: (entries) => withKvTransaction(
628
645
  bindings,
629
- Effect4.forEach(
630
- entries,
631
- ({ toolId, namespace, binding, config }) => bindings.set(
632
- toolId,
633
- encodeEntry(new StoredEntry({ namespace, binding, config }))
634
- ),
635
- { discard: true }
646
+ bindings.set(
647
+ entries.map(({ toolId, namespace, binding, config }) => ({
648
+ key: toolId,
649
+ value: encodeEntry(new StoredEntry({ namespace, binding, config }))
650
+ }))
636
651
  )
637
652
  ),
638
- remove: (toolId) => bindings.delete(toolId).pipe(Effect4.asVoid),
653
+ remove: (toolId) => bindings.delete([toolId]).pipe(Effect4.asVoid),
639
654
  listByNamespace: (namespace) => Effect4.gen(function* () {
640
655
  const entries = yield* bindings.list();
641
656
  const ids = [];
@@ -650,73 +665,76 @@ var makeStore = (bindings, sources) => {
650
665
  const ids = [];
651
666
  for (const e of entries) {
652
667
  const entry = decodeEntry(e.value);
653
- if (entry.namespace === namespace) {
654
- ids.push(e.key);
655
- yield* bindings.delete(e.key);
656
- }
668
+ if (entry.namespace === namespace) ids.push(e.key);
657
669
  }
670
+ if (ids.length > 0) yield* bindings.delete(ids);
658
671
  return ids;
659
672
  }),
660
- putSource: (source) => sources.set(source.namespace, encodeSource(source)),
661
- removeSource: (namespace) => sources.delete(namespace).pipe(Effect4.asVoid),
673
+ putSource: (source) => sources.set([{ key: source.namespace, value: encodeSource(source) }]),
674
+ removeSource: (namespace) => sources.delete([namespace]).pipe(Effect4.asVoid),
662
675
  listSources: () => Effect4.gen(function* () {
663
676
  const entries = yield* sources.list();
664
677
  return entries.map((e) => decodeSource(e.value));
678
+ }),
679
+ getSource: (namespace) => Effect4.gen(function* () {
680
+ const raw = yield* sources.get(namespace);
681
+ if (!raw) return null;
682
+ return decodeSource(raw);
683
+ }),
684
+ getSourceConfig: (namespace) => Effect4.gen(function* () {
685
+ const raw = yield* sources.get(namespace);
686
+ if (!raw) return null;
687
+ const source = decodeSource(raw);
688
+ return source.config;
665
689
  })
666
690
  };
667
691
  };
668
- var makeKvOperationStore = (kv, namespace) => makeStore(
669
- scopeKv(kv, `${namespace}.bindings`),
670
- scopeKv(kv, `${namespace}.sources`)
671
- );
672
- var makeInMemoryOperationStore = () => makeStore(
673
- makeInMemoryScopedKv(),
674
- makeInMemoryScopedKv()
675
- );
692
+ var makeKvOperationStore = (kv, namespace) => makeStore(scopeKv(kv, `${namespace}.bindings`), scopeKv(kv, `${namespace}.sources`));
693
+ var makeInMemoryOperationStore = () => makeStore(makeInMemoryScopedKv(), makeInMemoryScopedKv());
676
694
 
677
695
  // src/sdk/preview.ts
678
696
  import { Effect as Effect5, Option as Option4 } from "effect";
679
- import { Schema as Schema4 } from "effect";
680
- var SecurityScheme = class extends Schema4.Class("SecurityScheme")({
697
+ import { Schema as Schema5 } from "effect";
698
+ var SecurityScheme = class extends Schema5.Class("SecurityScheme")({
681
699
  /** Key name in components.securitySchemes (e.g. "api_token") */
682
- name: Schema4.String,
700
+ name: Schema5.String,
683
701
  /** OpenAPI security scheme type */
684
- type: Schema4.Literal("http", "apiKey", "oauth2", "openIdConnect"),
702
+ type: Schema5.Literal("http", "apiKey", "oauth2", "openIdConnect"),
685
703
  /** For type: "http" — e.g. "bearer", "basic" */
686
- scheme: Schema4.optionalWith(Schema4.String, { as: "Option" }),
704
+ scheme: Schema5.optionalWith(Schema5.String, { as: "Option" }),
687
705
  /** For type: "apiKey" — where the key goes */
688
- in: Schema4.optionalWith(Schema4.Literal("header", "query", "cookie"), { as: "Option" }),
706
+ in: Schema5.optionalWith(Schema5.Literal("header", "query", "cookie"), { as: "Option" }),
689
707
  /** For type: "apiKey" — the header/query/cookie name */
690
- headerName: Schema4.optionalWith(Schema4.String, { as: "Option" }),
691
- description: Schema4.optionalWith(Schema4.String, { as: "Option" })
708
+ headerName: Schema5.optionalWith(Schema5.String, { as: "Option" }),
709
+ description: Schema5.optionalWith(Schema5.String, { as: "Option" })
692
710
  }) {
693
711
  };
694
- var AuthStrategy = class extends Schema4.Class("AuthStrategy")({
712
+ var AuthStrategy = class extends Schema5.Class("AuthStrategy")({
695
713
  /** The security schemes required together for this strategy */
696
- schemes: Schema4.Array(Schema4.String)
714
+ schemes: Schema5.Array(Schema5.String)
697
715
  }) {
698
716
  };
699
- var HeaderPreset = class extends Schema4.Class("HeaderPreset")({
717
+ var HeaderPreset = class extends Schema5.Class("HeaderPreset")({
700
718
  /** Human-readable label for the UI (e.g. "Bearer Token", "API Key + Email") */
701
- label: Schema4.String,
719
+ label: Schema5.String,
702
720
  /** Headers this strategy needs. Value is null when the user must provide it. */
703
- headers: Schema4.Record({ key: Schema4.String, value: Schema4.NullOr(Schema4.String) }),
721
+ headers: Schema5.Record({ key: Schema5.String, value: Schema5.NullOr(Schema5.String) }),
704
722
  /** Which headers should be stored as secrets */
705
- secretHeaders: Schema4.Array(Schema4.String)
723
+ secretHeaders: Schema5.Array(Schema5.String)
706
724
  }) {
707
725
  };
708
- var SpecPreview = class extends Schema4.Class("SpecPreview")({
709
- title: Schema4.optionalWith(Schema4.String, { as: "Option" }),
710
- version: Schema4.optionalWith(Schema4.String, { as: "Option" }),
726
+ var SpecPreview = class extends Schema5.Class("SpecPreview")({
727
+ title: Schema5.optionalWith(Schema5.String, { as: "Option" }),
728
+ version: Schema5.optionalWith(Schema5.String, { as: "Option" }),
711
729
  /** Reuses ServerInfo from extraction */
712
- servers: Schema4.Array(Schema4.Unknown),
713
- operationCount: Schema4.Number,
714
- tags: Schema4.Array(Schema4.String),
715
- securitySchemes: Schema4.Array(SecurityScheme),
730
+ servers: Schema5.Array(Schema5.Unknown),
731
+ operationCount: Schema5.Number,
732
+ tags: Schema5.Array(Schema5.String),
733
+ securitySchemes: Schema5.Array(SecurityScheme),
716
734
  /** Valid auth strategies (each is a set of schemes used together) */
717
- authStrategies: Schema4.Array(AuthStrategy),
735
+ authStrategies: Schema5.Array(AuthStrategy),
718
736
  /** Pre-built header presets derived from auth strategies */
719
- headerPresets: Schema4.Array(HeaderPreset)
737
+ headerPresets: Schema5.Array(HeaderPreset)
720
738
  }) {
721
739
  };
722
740
  var extractSecuritySchemes = (rawSchemes) => Object.entries(rawSchemes).flatMap(([name, schemeOrRef]) => {
@@ -730,9 +748,7 @@ var extractSecuritySchemes = (rawSchemes) => Object.entries(rawSchemes).flatMap(
730
748
  name,
731
749
  type,
732
750
  scheme: Option4.fromNullable(scheme.scheme),
733
- in: Option4.fromNullable(
734
- scheme.in
735
- ),
751
+ in: Option4.fromNullable(scheme.in),
736
752
  headerName: Option4.fromNullable(scheme.name),
737
753
  description: Option4.fromNullable(scheme.description)
738
754
  })
@@ -767,13 +783,9 @@ var buildHeaderPresets = (schemes, strategies) => {
767
783
  }
768
784
  }
769
785
  if (Object.keys(headers).length === 0 && resolved.length > 0) {
770
- return [
771
- new HeaderPreset({ label: labelParts.join(" + "), headers: {}, secretHeaders: [] })
772
- ];
786
+ return [new HeaderPreset({ label: labelParts.join(" + "), headers: {}, secretHeaders: [] })];
773
787
  }
774
- return [
775
- new HeaderPreset({ label: labelParts.join(" + "), headers, secretHeaders })
776
- ];
788
+ return [new HeaderPreset({ label: labelParts.join(" + "), headers, secretHeaders })];
777
789
  });
778
790
  };
779
791
  var collectTags = (result) => {
@@ -786,9 +798,7 @@ var collectTags = (result) => {
786
798
  var previewSpec = Effect5.fn("OpenApi.previewSpec")(function* (specText) {
787
799
  const doc = yield* parse(specText);
788
800
  const result = yield* extract(doc);
789
- const securitySchemes = extractSecuritySchemes(
790
- doc.components?.securitySchemes ?? {}
791
- );
801
+ const securitySchemes = extractSecuritySchemes(doc.components?.securitySchemes ?? {});
792
802
  const rawSecurity = doc.security ?? [];
793
803
  const authStrategies = rawSecurity.map(
794
804
  (entry) => new AuthStrategy({ schemes: Object.keys(entry) })
@@ -806,7 +816,7 @@ var previewSpec = Effect5.fn("OpenApi.previewSpec")(function* (specText) {
806
816
  });
807
817
 
808
818
  // src/sdk/plugin.ts
809
- import { Effect as Effect6, Option as Option5, Schema as Schema5 } from "effect";
819
+ import { Effect as Effect6, Option as Option5, Schema as Schema6 } from "effect";
810
820
  import { FetchHttpClient } from "@effect/platform";
811
821
  import {
812
822
  Source,
@@ -815,7 +825,7 @@ import {
815
825
  registerRuntimeTools,
816
826
  runtimeTool,
817
827
  ToolId
818
- } from "@executor-js/sdk/core";
828
+ } from "@executor-js/sdk";
819
829
 
820
830
  // src/sdk/definitions.ts
821
831
  var splitWords = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z0-9]+)/g, "$1 $2").replace(/[^a-zA-Z0-9]+/g, " ").trim().split(/\s+/).filter((part) => part.length > 0);
@@ -937,26 +947,22 @@ var compileToolDefinitions = (operations) => {
937
947
  operation: op
938
948
  };
939
949
  });
940
- return resolveCollisions(raw).sort(
941
- (a, b) => a.toolPath.localeCompare(b.toolPath)
942
- );
950
+ return resolveCollisions(raw).sort((a, b) => a.toolPath.localeCompare(b.toolPath));
943
951
  };
944
952
 
945
953
  // src/sdk/plugin.ts
946
- var PreviewSpecInputSchema = Schema5.Struct({
947
- spec: Schema5.String
954
+ var PreviewSpecInputSchema = Schema6.Struct({
955
+ spec: Schema6.String
948
956
  });
949
- var AddSourceInputSchema = Schema5.Struct({
950
- spec: Schema5.String,
951
- baseUrl: Schema5.optional(Schema5.String),
952
- namespace: Schema5.optional(Schema5.String),
953
- headers: Schema5.optional(
954
- Schema5.Record({ key: Schema5.String, value: HeaderValue })
955
- )
957
+ var AddSourceInputSchema = Schema6.Struct({
958
+ spec: Schema6.String,
959
+ baseUrl: Schema6.optional(Schema6.String),
960
+ namespace: Schema6.optional(Schema6.String),
961
+ headers: Schema6.optional(Schema6.Record({ key: Schema6.String, value: HeaderValue }))
956
962
  });
957
- var AddSourceOutputSchema = Schema5.Struct({
958
- sourceId: Schema5.String,
959
- toolCount: Schema5.Number
963
+ var AddSourceOutputSchema = Schema6.Struct({
964
+ sourceId: Schema6.String,
965
+ toolCount: Schema6.Number
960
966
  });
961
967
  var normalizeOpenApiRefs = (node) => {
962
968
  if (node == null || typeof node !== "object") return node;
@@ -988,10 +994,7 @@ var toRegistration = (def, namespace) => {
988
994
  const op = def.operation;
989
995
  const description = Option5.getOrElse(
990
996
  op.description,
991
- () => Option5.getOrElse(
992
- op.summary,
993
- () => `${op.method.toUpperCase()} ${op.pathTemplate}`
994
- )
997
+ () => Option5.getOrElse(op.summary, () => `${op.method.toUpperCase()} ${op.pathTemplate}`)
995
998
  );
996
999
  return {
997
1000
  id: ToolId.make(`${namespace}.${def.toolPath}`),
@@ -1035,7 +1038,8 @@ var openApiPlugin = (options) => {
1035
1038
  kind: "openapi",
1036
1039
  runtime: false,
1037
1040
  canRemove: true,
1038
- canRefresh: false
1041
+ canRefresh: false,
1042
+ canEdit: true
1039
1043
  })
1040
1044
  )
1041
1045
  )
@@ -1050,13 +1054,9 @@ var openApiPlugin = (options) => {
1050
1054
  if (!trimmed) return null;
1051
1055
  const parsed = yield* Effect6.try(() => new URL(trimmed)).pipe(Effect6.option);
1052
1056
  if (parsed._tag === "None") return null;
1053
- const doc = yield* parse(trimmed).pipe(
1054
- Effect6.catchAll(() => Effect6.succeed(null))
1055
- );
1057
+ const doc = yield* parse(trimmed).pipe(Effect6.catchAll(() => Effect6.succeed(null)));
1056
1058
  if (!doc) return null;
1057
- const result = yield* extract(doc).pipe(
1058
- Effect6.catchAll(() => Effect6.succeed(null))
1059
- );
1059
+ const result = yield* extract(doc).pipe(Effect6.catchAll(() => Effect6.succeed(null)));
1060
1060
  if (!result) return null;
1061
1061
  const namespace = Option5.getOrElse(result.title, () => "api").toLowerCase().replace(/[^a-z0-9]+/g, "_");
1062
1062
  const name = Option5.getOrElse(result.title, () => namespace);
@@ -1086,9 +1086,7 @@ var openApiPlugin = (options) => {
1086
1086
  headers: config.headers ?? {}
1087
1087
  });
1088
1088
  const definitions = compileToolDefinitions(result.operations);
1089
- const registrations = definitions.map(
1090
- (def) => toRegistration(def, namespace)
1091
- );
1089
+ const registrations = definitions.map((def) => toRegistration(def, namespace));
1092
1090
  yield* operationStore.put(
1093
1091
  definitions.map((def) => ({
1094
1092
  toolId: ToolId.make(`${namespace}.${def.toolPath}`),
@@ -1098,7 +1096,7 @@ var openApiPlugin = (options) => {
1098
1096
  }))
1099
1097
  );
1100
1098
  yield* ctx.tools.register(registrations);
1101
- const sourceName = Option5.getOrElse(result.title, () => namespace);
1099
+ const sourceName = config.name ?? Option5.getOrElse(result.title, () => namespace);
1102
1100
  yield* operationStore.putSource({
1103
1101
  namespace,
1104
1102
  name: sourceName,
@@ -1142,15 +1140,48 @@ var openApiPlugin = (options) => {
1142
1140
  return {
1143
1141
  extension: {
1144
1142
  previewSpec: (specText) => previewSpec(specText),
1145
- addSpec: (config) => addSpecInternal(config).pipe(
1146
- Effect6.map(({ toolCount }) => ({ toolCount }))
1147
- ),
1143
+ addSpec: (config) => addSpecInternal(config).pipe(Effect6.map(({ toolCount }) => ({ toolCount }))),
1148
1144
  removeSpec: (namespace) => Effect6.gen(function* () {
1149
1145
  const toolIds = yield* operationStore.removeByNamespace(namespace);
1150
1146
  if (toolIds.length > 0) {
1151
1147
  yield* ctx.tools.unregister(toolIds);
1152
1148
  }
1153
1149
  yield* operationStore.removeSource(namespace);
1150
+ }),
1151
+ getSource: (namespace) => operationStore.getSource(namespace),
1152
+ updateSource: (namespace, input) => Effect6.gen(function* () {
1153
+ const existingSource = yield* operationStore.getSourceConfig(namespace);
1154
+ if (!existingSource) return;
1155
+ const updatedConfig = {
1156
+ ...existingSource,
1157
+ ...input.baseUrl !== void 0 ? { baseUrl: input.baseUrl } : {},
1158
+ ...input.headers !== void 0 ? { headers: input.headers } : {}
1159
+ };
1160
+ const newInvocationConfig = new InvocationConfig({
1161
+ baseUrl: updatedConfig.baseUrl ?? resolveBaseUrl([]),
1162
+ headers: updatedConfig.headers ?? {}
1163
+ });
1164
+ const toolIds = yield* operationStore.listByNamespace(namespace);
1165
+ for (const toolId of toolIds) {
1166
+ const entry = yield* operationStore.get(toolId);
1167
+ if (entry) {
1168
+ yield* operationStore.put([
1169
+ {
1170
+ toolId,
1171
+ namespace,
1172
+ binding: entry.binding,
1173
+ config: newInvocationConfig
1174
+ }
1175
+ ]);
1176
+ }
1177
+ }
1178
+ const sources = yield* operationStore.listSources();
1179
+ const existingMeta = sources.find((s) => s.namespace === namespace);
1180
+ yield* operationStore.putSource({
1181
+ namespace,
1182
+ name: existingMeta?.name ?? namespace,
1183
+ config: updatedConfig
1184
+ });
1154
1185
  })
1155
1186
  },
1156
1187
  close: () => runtimeTools.close()
@@ -1190,4 +1221,4 @@ export {
1190
1221
  previewSpec,
1191
1222
  openApiPlugin
1192
1223
  };
1193
- //# sourceMappingURL=chunk-C57CSNPZ.js.map
1224
+ //# sourceMappingURL=chunk-V3D5A6HA.js.map