@executor-js/plugin-openapi 1.4.28 → 1.4.30
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/{AddOpenApiSource-FLMNI742.js → AddOpenApiSource-KSOMPQ2R.js} +4 -4
- package/dist/{EditOpenApiSource-I4NIGIIJ.js → EditOpenApiSource-AOA7APR2.js} +301 -192
- package/dist/EditOpenApiSource-AOA7APR2.js.map +1 -0
- package/dist/{OpenApiSourceSummary-CM46DB4L.js → OpenApiSourceSummary-Y3S6ZBOZ.js} +4 -4
- package/dist/OpenApiSourceSummary-Y3S6ZBOZ.js.map +1 -0
- package/dist/api/group.d.ts +124 -118
- package/dist/api/index.d.ts +148 -369
- package/dist/chunk-BB5IAKRG.js +136 -0
- package/dist/chunk-BB5IAKRG.js.map +1 -0
- package/dist/{chunk-E7PZ2QGD.js → chunk-EOXXE5DG.js} +17 -455
- package/dist/chunk-EOXXE5DG.js.map +1 -0
- package/dist/{chunk-OZ67JNID.js → chunk-NIKLYJ3X.js} +830 -319
- package/dist/chunk-NIKLYJ3X.js.map +1 -0
- package/dist/{chunk-TGDT6QCH.js → chunk-YJMXYKYX.js} +178 -117
- package/dist/chunk-YJMXYKYX.js.map +1 -0
- package/dist/{chunk-GFQUEZUW.js → chunk-ZZBTLFTA.js} +78 -93
- package/dist/chunk-ZZBTLFTA.js.map +1 -0
- package/dist/client.js +7 -137
- package/dist/client.js.map +1 -1
- package/dist/core.js +5 -10
- package/dist/index.js +3 -2
- package/dist/react/atoms.d.ts +83 -223
- package/dist/react/client.d.ts +123 -117
- package/dist/sdk/credential-status.d.ts +3 -3
- package/dist/sdk/extract.d.ts +19 -19
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/invoke.d.ts +7 -7
- package/dist/sdk/parse.d.ts +2 -3
- package/dist/sdk/plugin.d.ts +181 -275
- package/dist/sdk/preview.d.ts +12 -12
- package/dist/sdk/source-contracts.d.ts +55 -0
- package/dist/sdk/store.d.ts +6 -269
- package/dist/sdk/types.d.ts +16 -65
- package/dist/testing/index.d.ts +149 -11
- package/dist/testing.js +419 -33
- package/dist/testing.js.map +1 -1
- package/dist/testing.test.d.ts +1 -0
- package/package.json +3 -4
- package/dist/EditOpenApiSource-I4NIGIIJ.js.map +0 -1
- package/dist/OpenApiSourceSummary-CM46DB4L.js.map +0 -1
- package/dist/chunk-E7PZ2QGD.js.map +0 -1
- package/dist/chunk-GFQUEZUW.js.map +0 -1
- package/dist/chunk-OZ67JNID.js.map +0 -1
- package/dist/chunk-TGDT6QCH.js.map +0 -1
- /package/dist/{AddOpenApiSource-FLMNI742.js.map → AddOpenApiSource-KSOMPQ2R.js.map} +0 -0
|
@@ -1,23 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
openApiPresets
|
|
3
|
+
} from "./chunk-BB5IAKRG.js";
|
|
1
4
|
import {
|
|
2
5
|
ConfiguredHeaderBinding,
|
|
3
|
-
ConfiguredHeaderValue,
|
|
4
6
|
HeaderValue,
|
|
5
7
|
InvocationResult,
|
|
6
8
|
OAuth2SourceConfig,
|
|
7
|
-
OpenApiCredentialInput,
|
|
8
9
|
OpenApiExtractionError,
|
|
9
10
|
OpenApiInvocationError,
|
|
10
11
|
OpenApiOAuthError,
|
|
11
|
-
OpenApiSourceBindingRef,
|
|
12
12
|
OperationBinding,
|
|
13
13
|
extract,
|
|
14
|
-
makeDefaultOpenapiStore,
|
|
15
|
-
openapiSchema,
|
|
16
14
|
parse,
|
|
17
15
|
previewSpec,
|
|
18
|
-
resolveBaseUrl,
|
|
19
16
|
resolveSpecText
|
|
20
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-EOXXE5DG.js";
|
|
21
18
|
|
|
22
19
|
// src/sdk/invoke.ts
|
|
23
20
|
import { Effect, Layer, Option } from "effect";
|
|
@@ -417,13 +414,236 @@ var annotationsForOperation = (method, pathTemplate) => {
|
|
|
417
414
|
};
|
|
418
415
|
};
|
|
419
416
|
|
|
420
|
-
// src/sdk/
|
|
417
|
+
// src/sdk/store.ts
|
|
421
418
|
import { Effect as Effect2, Option as Option2, Predicate, Schema } from "effect";
|
|
419
|
+
var openapiSchema = {};
|
|
420
|
+
var SOURCE_COLLECTION = "source";
|
|
421
|
+
var OPERATION_COLLECTION = "operation";
|
|
422
|
+
var encodeBinding = Schema.encodeSync(OperationBinding);
|
|
423
|
+
var decodeBinding = Schema.decodeUnknownSync(OperationBinding);
|
|
424
|
+
var decodeBindingJson = Schema.decodeUnknownSync(Schema.fromJsonString(OperationBinding));
|
|
425
|
+
var decodeOAuth2SourceConfigOption = Schema.decodeUnknownOption(OAuth2SourceConfig);
|
|
426
|
+
var decodeOAuth2SourceConfigJsonOption = Schema.decodeUnknownOption(
|
|
427
|
+
Schema.fromJsonString(OAuth2SourceConfig)
|
|
428
|
+
);
|
|
429
|
+
var encodeOAuth2SourceConfig = Schema.encodeSync(OAuth2SourceConfig);
|
|
430
|
+
var NullableString = Schema.NullOr(Schema.String);
|
|
431
|
+
var OptionalNullableString = Schema.optional(NullableString);
|
|
432
|
+
var ConfiguredHeaderBindingStorage = Schema.Struct({
|
|
433
|
+
kind: Schema.Literal("binding"),
|
|
434
|
+
slot: Schema.String,
|
|
435
|
+
prefix: OptionalNullableString
|
|
436
|
+
});
|
|
437
|
+
var ConfiguredHeaderValueStorage = Schema.Union([Schema.String, ConfiguredHeaderBindingStorage]);
|
|
438
|
+
var ConfiguredHeaderMapStorage = Schema.Record(Schema.String, ConfiguredHeaderValueStorage);
|
|
439
|
+
var SpecFetchCredentialsStorage = Schema.Struct({
|
|
440
|
+
headers: Schema.optional(ConfiguredHeaderMapStorage),
|
|
441
|
+
queryParams: Schema.optional(ConfiguredHeaderMapStorage)
|
|
442
|
+
});
|
|
443
|
+
var SourceConfigStorage = Schema.Struct({
|
|
444
|
+
spec: Schema.String,
|
|
445
|
+
sourceUrl: Schema.optional(Schema.String),
|
|
446
|
+
baseUrl: Schema.optional(Schema.String),
|
|
447
|
+
namespace: Schema.optional(Schema.String),
|
|
448
|
+
headers: Schema.optional(ConfiguredHeaderMapStorage),
|
|
449
|
+
queryParams: Schema.optional(ConfiguredHeaderMapStorage),
|
|
450
|
+
specFetchCredentials: Schema.optional(SpecFetchCredentialsStorage),
|
|
451
|
+
oauth2: Schema.optional(Schema.Unknown)
|
|
452
|
+
});
|
|
453
|
+
var SourceStorage = Schema.Struct({
|
|
454
|
+
namespace: Schema.String,
|
|
455
|
+
scope: Schema.String,
|
|
456
|
+
name: Schema.String,
|
|
457
|
+
config: SourceConfigStorage
|
|
458
|
+
});
|
|
459
|
+
var OperationStorage = Schema.Struct({
|
|
460
|
+
toolId: Schema.String,
|
|
461
|
+
sourceId: Schema.String,
|
|
462
|
+
binding: Schema.Unknown
|
|
463
|
+
});
|
|
464
|
+
var decodeSourceStorage = Schema.decodeUnknownOption(SourceStorage);
|
|
465
|
+
var decodeOperationStorage = Schema.decodeUnknownOption(OperationStorage);
|
|
466
|
+
var toJsonRecord = (value) => value;
|
|
467
|
+
var normalizeStoredOAuth2 = (value) => {
|
|
468
|
+
if (value == null) return void 0;
|
|
469
|
+
const sourceConfig = typeof value === "string" ? decodeOAuth2SourceConfigJsonOption(value) : decodeOAuth2SourceConfigOption(value);
|
|
470
|
+
if (Option2.isSome(sourceConfig)) return sourceConfig.value;
|
|
471
|
+
return void 0;
|
|
472
|
+
};
|
|
473
|
+
var normalizeConfiguredMap = (values) => {
|
|
474
|
+
if (!values) return void 0;
|
|
475
|
+
const normalized = {};
|
|
476
|
+
for (const [name, value] of Object.entries(values)) {
|
|
477
|
+
if (typeof value === "string") {
|
|
478
|
+
normalized[name] = value;
|
|
479
|
+
} else {
|
|
480
|
+
normalized[name] = value.prefix != null ? ConfiguredHeaderBinding.make({
|
|
481
|
+
kind: "binding",
|
|
482
|
+
slot: value.slot,
|
|
483
|
+
prefix: value.prefix
|
|
484
|
+
}) : ConfiguredHeaderBinding.make({
|
|
485
|
+
kind: "binding",
|
|
486
|
+
slot: value.slot
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return normalized;
|
|
491
|
+
};
|
|
492
|
+
var encodeSourceConfig = (config) => ({
|
|
493
|
+
spec: config.spec,
|
|
494
|
+
...config.sourceUrl ? { sourceUrl: config.sourceUrl } : {},
|
|
495
|
+
...config.baseUrl ? { baseUrl: config.baseUrl } : {},
|
|
496
|
+
...config.namespace ? { namespace: config.namespace } : {},
|
|
497
|
+
...config.headers ? { headers: config.headers } : {},
|
|
498
|
+
...config.queryParams ? { queryParams: config.queryParams } : {},
|
|
499
|
+
...config.specFetchCredentials ? { specFetchCredentials: config.specFetchCredentials } : {},
|
|
500
|
+
...config.oauth2 ? { oauth2: toJsonRecord(encodeOAuth2SourceConfig(config.oauth2)) } : {}
|
|
501
|
+
});
|
|
502
|
+
var rowToSource = (row) => {
|
|
503
|
+
const decoded = decodeSourceStorage(row.data);
|
|
504
|
+
if (Option2.isNone(decoded)) return null;
|
|
505
|
+
const stored = decoded.value;
|
|
506
|
+
const oauth2 = normalizeStoredOAuth2(stored.config.oauth2);
|
|
507
|
+
return {
|
|
508
|
+
namespace: stored.namespace,
|
|
509
|
+
scope: stored.scope,
|
|
510
|
+
name: stored.name,
|
|
511
|
+
config: {
|
|
512
|
+
spec: stored.config.spec,
|
|
513
|
+
sourceUrl: stored.config.sourceUrl,
|
|
514
|
+
baseUrl: stored.config.baseUrl,
|
|
515
|
+
namespace: stored.config.namespace,
|
|
516
|
+
headers: normalizeConfiguredMap(stored.config.headers),
|
|
517
|
+
queryParams: normalizeConfiguredMap(stored.config.queryParams),
|
|
518
|
+
specFetchCredentials: stored.config.specFetchCredentials ? {
|
|
519
|
+
headers: normalizeConfiguredMap(stored.config.specFetchCredentials.headers),
|
|
520
|
+
queryParams: normalizeConfiguredMap(stored.config.specFetchCredentials.queryParams)
|
|
521
|
+
} : void 0,
|
|
522
|
+
oauth2
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
};
|
|
526
|
+
var rowToOperation = (row) => {
|
|
527
|
+
const decoded = decodeOperationStorage(row.data);
|
|
528
|
+
if (Option2.isNone(decoded)) return null;
|
|
529
|
+
const operation = decoded.value;
|
|
530
|
+
return {
|
|
531
|
+
toolId: operation.toolId,
|
|
532
|
+
sourceId: operation.sourceId,
|
|
533
|
+
binding: decodeBinding(
|
|
534
|
+
typeof operation.binding === "string" ? decodeBindingJson(operation.binding) : operation.binding
|
|
535
|
+
)
|
|
536
|
+
};
|
|
537
|
+
};
|
|
538
|
+
var makeDefaultOpenapiStore = ({
|
|
539
|
+
pluginStorage
|
|
540
|
+
}) => {
|
|
541
|
+
const sourceData = (source) => ({
|
|
542
|
+
namespace: source.namespace,
|
|
543
|
+
scope: source.scope,
|
|
544
|
+
name: source.name,
|
|
545
|
+
config: encodeSourceConfig(source.config)
|
|
546
|
+
});
|
|
547
|
+
const operationData = (operation) => ({
|
|
548
|
+
toolId: operation.toolId,
|
|
549
|
+
sourceId: operation.sourceId,
|
|
550
|
+
binding: toJsonRecord(encodeBinding(operation.binding))
|
|
551
|
+
});
|
|
552
|
+
const listOperationRowsForSourceScope = (sourceId, scope) => pluginStorage.list({
|
|
553
|
+
collection: OPERATION_COLLECTION,
|
|
554
|
+
keyPrefix: `${sourceId}.`
|
|
555
|
+
}).pipe(
|
|
556
|
+
Effect2.map(
|
|
557
|
+
(rows) => rows.filter(
|
|
558
|
+
(row) => String(row.scopeId) === scope && rowToOperation(row)?.sourceId === sourceId
|
|
559
|
+
)
|
|
560
|
+
)
|
|
561
|
+
);
|
|
562
|
+
const removeOperationsForSourceScope = (sourceId, scope) => Effect2.gen(function* () {
|
|
563
|
+
const rows = yield* listOperationRowsForSourceScope(sourceId, scope);
|
|
564
|
+
for (const row of rows) {
|
|
565
|
+
yield* pluginStorage.remove({
|
|
566
|
+
scope,
|
|
567
|
+
collection: OPERATION_COLLECTION,
|
|
568
|
+
key: row.key
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
const deleteSource = (namespace, scope) => Effect2.gen(function* () {
|
|
573
|
+
yield* removeOperationsForSourceScope(namespace, scope);
|
|
574
|
+
yield* pluginStorage.remove({
|
|
575
|
+
scope,
|
|
576
|
+
collection: SOURCE_COLLECTION,
|
|
577
|
+
key: namespace
|
|
578
|
+
});
|
|
579
|
+
});
|
|
580
|
+
return {
|
|
581
|
+
upsertSource: (input, operations) => Effect2.gen(function* () {
|
|
582
|
+
yield* deleteSource(input.namespace, input.scope);
|
|
583
|
+
yield* pluginStorage.put({
|
|
584
|
+
scope: input.scope,
|
|
585
|
+
collection: SOURCE_COLLECTION,
|
|
586
|
+
key: input.namespace,
|
|
587
|
+
data: sourceData(input)
|
|
588
|
+
});
|
|
589
|
+
for (const operation of operations) {
|
|
590
|
+
yield* pluginStorage.put({
|
|
591
|
+
scope: input.scope,
|
|
592
|
+
collection: OPERATION_COLLECTION,
|
|
593
|
+
key: operation.toolId,
|
|
594
|
+
data: operationData(operation)
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}),
|
|
598
|
+
updateSourceMeta: (namespace, scope, patch) => Effect2.gen(function* () {
|
|
599
|
+
const existing = yield* pluginStorage.getAtScope({
|
|
600
|
+
scope,
|
|
601
|
+
collection: SOURCE_COLLECTION,
|
|
602
|
+
key: namespace
|
|
603
|
+
});
|
|
604
|
+
if (!existing) return;
|
|
605
|
+
const source = rowToSource(existing);
|
|
606
|
+
if (!source) return;
|
|
607
|
+
const next = {
|
|
608
|
+
...source,
|
|
609
|
+
name: patch.name?.trim() || source.name,
|
|
610
|
+
config: {
|
|
611
|
+
...source.config,
|
|
612
|
+
...patch.baseUrl !== void 0 ? { baseUrl: patch.baseUrl } : {},
|
|
613
|
+
...patch.headers !== void 0 ? { headers: patch.headers } : {},
|
|
614
|
+
...patch.queryParams !== void 0 ? { queryParams: patch.queryParams } : {},
|
|
615
|
+
...patch.specFetchCredentials !== void 0 ? { specFetchCredentials: patch.specFetchCredentials } : {},
|
|
616
|
+
...patch.oauth2 !== void 0 ? { oauth2: patch.oauth2 } : {}
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
yield* pluginStorage.put({
|
|
620
|
+
scope,
|
|
621
|
+
collection: SOURCE_COLLECTION,
|
|
622
|
+
key: namespace,
|
|
623
|
+
data: sourceData(next)
|
|
624
|
+
});
|
|
625
|
+
}),
|
|
626
|
+
getSource: (namespace, scope) => pluginStorage.getAtScope({ scope, collection: SOURCE_COLLECTION, key: namespace }).pipe(Effect2.map((row) => row ? rowToSource(row) : null)),
|
|
627
|
+
listSources: () => pluginStorage.list({ collection: SOURCE_COLLECTION }).pipe(Effect2.map((rows) => rows.map(rowToSource).filter(Predicate.isNotNull))),
|
|
628
|
+
getOperationByToolId: (toolId, scope) => pluginStorage.getAtScope({ scope, collection: OPERATION_COLLECTION, key: toolId }).pipe(Effect2.map((row) => row ? rowToOperation(row) : null)),
|
|
629
|
+
listOperationsBySource: (sourceId, scope) => listOperationRowsForSourceScope(sourceId, scope).pipe(
|
|
630
|
+
Effect2.map((rows) => rows.map(rowToOperation).filter(Predicate.isNotNull))
|
|
631
|
+
),
|
|
632
|
+
removeSource: (namespace, scope) => deleteSource(namespace, scope)
|
|
633
|
+
};
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
// src/sdk/plugin.ts
|
|
637
|
+
import { Effect as Effect3, Option as Option3, Predicate as Predicate2, Schema as Schema2 } from "effect";
|
|
422
638
|
import {
|
|
639
|
+
ConnectionId,
|
|
640
|
+
CredentialBindingRef,
|
|
423
641
|
ScopeId,
|
|
424
642
|
SecretId,
|
|
425
643
|
SourceDetectionResult,
|
|
426
644
|
StorageError,
|
|
645
|
+
ToolResult,
|
|
646
|
+
defaultSourceInstallScopeId,
|
|
427
647
|
definePlugin,
|
|
428
648
|
tool,
|
|
429
649
|
resolveSecretBackedMap
|
|
@@ -556,46 +776,313 @@ var compileToolDefinitions = (operations) => {
|
|
|
556
776
|
};
|
|
557
777
|
|
|
558
778
|
// src/sdk/plugin.ts
|
|
559
|
-
var
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
779
|
+
var STRINGIFIED_BODY_CAP = 1024;
|
|
780
|
+
var UpstreamMessageBody = Schema2.Struct({ message: Schema2.String });
|
|
781
|
+
var UpstreamErrorMessageBody = Schema2.Struct({ errorMessage: Schema2.String });
|
|
782
|
+
var UpstreamNestedErrorBody = Schema2.Struct({ error: UpstreamMessageBody });
|
|
783
|
+
var UpstreamErrorsArrayBody = Schema2.Struct({
|
|
784
|
+
errors: Schema2.Array(
|
|
785
|
+
Schema2.Struct({
|
|
786
|
+
detail: Schema2.optional(Schema2.String),
|
|
787
|
+
message: Schema2.optional(Schema2.String),
|
|
788
|
+
title: Schema2.optional(Schema2.String)
|
|
789
|
+
})
|
|
790
|
+
)
|
|
791
|
+
});
|
|
792
|
+
var UpstreamDescriptionBody = Schema2.Struct({
|
|
793
|
+
detail: Schema2.optional(Schema2.String),
|
|
794
|
+
title: Schema2.optional(Schema2.String),
|
|
795
|
+
description: Schema2.optional(Schema2.String)
|
|
796
|
+
});
|
|
797
|
+
var decodeUpstreamMessageBody = Schema2.decodeUnknownOption(UpstreamMessageBody);
|
|
798
|
+
var decodeUpstreamErrorMessageBody = Schema2.decodeUnknownOption(UpstreamErrorMessageBody);
|
|
799
|
+
var decodeUpstreamNestedErrorBody = Schema2.decodeUnknownOption(UpstreamNestedErrorBody);
|
|
800
|
+
var decodeUpstreamErrorsArrayBody = Schema2.decodeUnknownOption(UpstreamErrorsArrayBody);
|
|
801
|
+
var decodeUpstreamDescriptionBody = Schema2.decodeUnknownOption(UpstreamDescriptionBody);
|
|
802
|
+
var clampedStringify = (value) => {
|
|
803
|
+
let s;
|
|
804
|
+
try {
|
|
805
|
+
s = JSON.stringify(value);
|
|
806
|
+
} catch {
|
|
807
|
+
s = String(value);
|
|
808
|
+
}
|
|
809
|
+
return s.length > STRINGIFIED_BODY_CAP ? `${s.slice(0, STRINGIFIED_BODY_CAP)}\u2026` : s;
|
|
810
|
+
};
|
|
811
|
+
var firstNonEmpty = (...values) => values.find((value) => value !== void 0 && value.length > 0);
|
|
812
|
+
var extractUpstreamMessage = (body, status) => {
|
|
813
|
+
if (typeof body === "string") {
|
|
814
|
+
return body.length > 0 ? body : `Upstream returned HTTP ${status}`;
|
|
815
|
+
}
|
|
816
|
+
const nested = Option3.getOrUndefined(decodeUpstreamNestedErrorBody(body));
|
|
817
|
+
const messageBody = Option3.getOrUndefined(decodeUpstreamMessageBody(body));
|
|
818
|
+
const errorMessageBody = Option3.getOrUndefined(decodeUpstreamErrorMessageBody(body));
|
|
819
|
+
const errorsBody = Option3.getOrUndefined(decodeUpstreamErrorsArrayBody(body));
|
|
820
|
+
const descriptionBody = Option3.getOrUndefined(decodeUpstreamDescriptionBody(body));
|
|
821
|
+
const arrayMessage = errorsBody?.errors.map(
|
|
822
|
+
({ detail, message: upstreamMessage, title }) => firstNonEmpty(detail, upstreamMessage, title)
|
|
823
|
+
).find((message2) => message2 !== void 0);
|
|
824
|
+
const message = firstNonEmpty(
|
|
825
|
+
nested?.error.message,
|
|
826
|
+
messageBody?.message,
|
|
827
|
+
errorMessageBody?.errorMessage,
|
|
828
|
+
arrayMessage,
|
|
829
|
+
descriptionBody?.detail,
|
|
830
|
+
descriptionBody?.title,
|
|
831
|
+
descriptionBody?.description
|
|
832
|
+
);
|
|
833
|
+
if (message !== void 0) return message;
|
|
834
|
+
if (body !== null && typeof body === "object") {
|
|
835
|
+
return clampedStringify(body);
|
|
836
|
+
}
|
|
837
|
+
return `Upstream returned HTTP ${status}`;
|
|
838
|
+
};
|
|
839
|
+
var PreviewSpecInputSchema = Schema2.Struct({
|
|
840
|
+
spec: Schema2.String,
|
|
841
|
+
specFetchCredentials: Schema2.optional(
|
|
842
|
+
Schema2.Struct({
|
|
843
|
+
headers: Schema2.optional(Schema2.Record(Schema2.String, HeaderValue)),
|
|
844
|
+
queryParams: Schema2.optional(Schema2.Record(Schema2.String, HeaderValue))
|
|
565
845
|
})
|
|
566
846
|
)
|
|
567
847
|
});
|
|
568
|
-
var
|
|
848
|
+
var StaticPreviewServerVariableSchema = Schema2.Struct({
|
|
849
|
+
default: Schema2.String,
|
|
850
|
+
enum: Schema2.NullOr(Schema2.Array(Schema2.String)),
|
|
851
|
+
description: Schema2.NullOr(Schema2.String)
|
|
852
|
+
});
|
|
853
|
+
var StaticPreviewServerSchema = Schema2.Struct({
|
|
854
|
+
url: Schema2.String,
|
|
855
|
+
description: Schema2.NullOr(Schema2.String),
|
|
856
|
+
variables: Schema2.NullOr(Schema2.Record(Schema2.String, StaticPreviewServerVariableSchema))
|
|
857
|
+
});
|
|
858
|
+
var StaticPreviewOAuthAuthorizationCodeFlowSchema = Schema2.Struct({
|
|
859
|
+
authorizationUrl: Schema2.String,
|
|
860
|
+
tokenUrl: Schema2.String,
|
|
861
|
+
refreshUrl: Schema2.NullOr(Schema2.String),
|
|
862
|
+
scopes: Schema2.Record(Schema2.String, Schema2.String)
|
|
863
|
+
});
|
|
864
|
+
var StaticPreviewOAuthClientCredentialsFlowSchema = Schema2.Struct({
|
|
865
|
+
tokenUrl: Schema2.String,
|
|
866
|
+
refreshUrl: Schema2.NullOr(Schema2.String),
|
|
867
|
+
scopes: Schema2.Record(Schema2.String, Schema2.String)
|
|
868
|
+
});
|
|
869
|
+
var StaticPreviewOAuthFlowsSchema = Schema2.Struct({
|
|
870
|
+
authorizationCode: Schema2.NullOr(StaticPreviewOAuthAuthorizationCodeFlowSchema),
|
|
871
|
+
clientCredentials: Schema2.NullOr(StaticPreviewOAuthClientCredentialsFlowSchema)
|
|
872
|
+
});
|
|
873
|
+
var StaticPreviewSecuritySchemeSchema = Schema2.Struct({
|
|
874
|
+
name: Schema2.String,
|
|
875
|
+
type: Schema2.Literals(["http", "apiKey", "oauth2", "openIdConnect"]),
|
|
876
|
+
scheme: Schema2.NullOr(Schema2.String),
|
|
877
|
+
bearerFormat: Schema2.NullOr(Schema2.String),
|
|
878
|
+
in: Schema2.NullOr(Schema2.Literals(["header", "query", "cookie"])),
|
|
879
|
+
headerName: Schema2.NullOr(Schema2.String),
|
|
880
|
+
description: Schema2.NullOr(Schema2.String),
|
|
881
|
+
flows: Schema2.NullOr(StaticPreviewOAuthFlowsSchema),
|
|
882
|
+
openIdConnectUrl: Schema2.NullOr(Schema2.String)
|
|
883
|
+
});
|
|
884
|
+
var StaticPreviewOAuth2PresetSchema = Schema2.Struct({
|
|
885
|
+
label: Schema2.String,
|
|
886
|
+
securitySchemeName: Schema2.String,
|
|
887
|
+
flow: Schema2.Literals(["authorizationCode", "clientCredentials"]),
|
|
888
|
+
authorizationUrl: Schema2.NullOr(Schema2.String),
|
|
889
|
+
tokenUrl: Schema2.String,
|
|
890
|
+
refreshUrl: Schema2.NullOr(Schema2.String),
|
|
891
|
+
scopes: Schema2.Record(Schema2.String, Schema2.String)
|
|
892
|
+
});
|
|
893
|
+
var StaticPreviewSpecOutputSchema = Schema2.Struct({
|
|
894
|
+
title: Schema2.NullOr(Schema2.String),
|
|
895
|
+
version: Schema2.NullOr(Schema2.String),
|
|
896
|
+
servers: Schema2.Array(StaticPreviewServerSchema),
|
|
897
|
+
operationCount: Schema2.Number,
|
|
898
|
+
tags: Schema2.Array(Schema2.String),
|
|
899
|
+
securitySchemes: Schema2.Array(StaticPreviewSecuritySchemeSchema),
|
|
900
|
+
authStrategies: Schema2.Array(Schema2.Struct({ schemes: Schema2.Array(Schema2.String) })),
|
|
901
|
+
headerPresets: Schema2.Array(
|
|
902
|
+
Schema2.Struct({
|
|
903
|
+
label: Schema2.String,
|
|
904
|
+
headers: Schema2.Record(Schema2.String, Schema2.NullOr(Schema2.String)),
|
|
905
|
+
secretHeaders: Schema2.Array(Schema2.String)
|
|
906
|
+
})
|
|
907
|
+
),
|
|
908
|
+
oauth2Presets: Schema2.Array(StaticPreviewOAuth2PresetSchema)
|
|
909
|
+
});
|
|
910
|
+
var OpenApiSpecInputSchema = Schema2.Union([
|
|
911
|
+
Schema2.Struct({ kind: Schema2.Literal("url"), url: Schema2.String }),
|
|
912
|
+
Schema2.Struct({ kind: Schema2.Literal("blob"), value: Schema2.String })
|
|
913
|
+
]);
|
|
914
|
+
var OpenApiSecretShapeInputSchema = Schema2.Struct({
|
|
915
|
+
kind: Schema2.Literal("secret"),
|
|
916
|
+
prefix: Schema2.optional(Schema2.String)
|
|
917
|
+
});
|
|
918
|
+
var OpenApiConfiguredValueInputSchema = Schema2.Union([
|
|
919
|
+
Schema2.String,
|
|
920
|
+
OpenApiSecretShapeInputSchema
|
|
921
|
+
]);
|
|
922
|
+
var OpenApiConfigureCredentialInputSchema = Schema2.Union([
|
|
923
|
+
Schema2.String,
|
|
924
|
+
Schema2.Struct({
|
|
925
|
+
kind: Schema2.Literal("text"),
|
|
926
|
+
text: Schema2.String,
|
|
927
|
+
prefix: Schema2.optional(Schema2.String)
|
|
928
|
+
}),
|
|
929
|
+
Schema2.Struct({
|
|
930
|
+
kind: Schema2.Literal("secret"),
|
|
931
|
+
secretId: Schema2.String,
|
|
932
|
+
secretScope: Schema2.optional(Schema2.String),
|
|
933
|
+
prefix: Schema2.optional(Schema2.String)
|
|
934
|
+
}),
|
|
935
|
+
Schema2.Struct({
|
|
936
|
+
kind: Schema2.Literal("connection"),
|
|
937
|
+
connectionId: Schema2.String
|
|
938
|
+
})
|
|
939
|
+
]);
|
|
940
|
+
var OpenApiConfigureInputSchema = Schema2.Struct({
|
|
941
|
+
scope: Schema2.String,
|
|
942
|
+
name: Schema2.optional(Schema2.String),
|
|
943
|
+
baseUrl: Schema2.optional(Schema2.String),
|
|
944
|
+
headers: Schema2.optional(Schema2.Record(Schema2.String, OpenApiConfigureCredentialInputSchema)),
|
|
945
|
+
queryParams: Schema2.optional(Schema2.Record(Schema2.String, OpenApiConfigureCredentialInputSchema)),
|
|
946
|
+
specFetchCredentials: Schema2.optional(
|
|
947
|
+
Schema2.Struct({
|
|
948
|
+
headers: Schema2.optional(Schema2.Record(Schema2.String, OpenApiConfigureCredentialInputSchema)),
|
|
949
|
+
queryParams: Schema2.optional(
|
|
950
|
+
Schema2.Record(Schema2.String, OpenApiConfigureCredentialInputSchema)
|
|
951
|
+
)
|
|
952
|
+
})
|
|
953
|
+
),
|
|
954
|
+
oauth2: Schema2.optional(
|
|
955
|
+
Schema2.Struct({
|
|
956
|
+
clientId: Schema2.optional(OpenApiConfigureCredentialInputSchema),
|
|
957
|
+
clientSecret: Schema2.optional(OpenApiConfigureCredentialInputSchema),
|
|
958
|
+
connection: Schema2.optional(OpenApiConfigureCredentialInputSchema)
|
|
959
|
+
})
|
|
960
|
+
),
|
|
961
|
+
oauth2Source: Schema2.optional(OAuth2SourceConfig)
|
|
962
|
+
});
|
|
963
|
+
var OpenApiConfigureSourceInputSchema = Schema2.Struct({
|
|
964
|
+
source: Schema2.Struct({
|
|
965
|
+
id: Schema2.String,
|
|
966
|
+
scope: Schema2.String
|
|
967
|
+
}),
|
|
968
|
+
...OpenApiConfigureInputSchema.fields
|
|
969
|
+
});
|
|
569
970
|
var OpenApiOAuthInputSchema = OAuth2SourceConfig;
|
|
570
|
-
var AddSourceInputSchema =
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
headers: Schema.optional(Schema.Record(Schema.String, HeaderValue)),
|
|
583
|
-
queryParams: Schema.optional(Schema.Record(Schema.String, HeaderValue))
|
|
971
|
+
var AddSourceInputSchema = Schema2.Struct({
|
|
972
|
+
spec: OpenApiSpecInputSchema,
|
|
973
|
+
name: Schema2.String,
|
|
974
|
+
baseUrl: Schema2.String,
|
|
975
|
+
namespace: Schema2.String,
|
|
976
|
+
headers: Schema2.optional(Schema2.Record(Schema2.String, OpenApiConfiguredValueInputSchema)),
|
|
977
|
+
queryParams: Schema2.optional(Schema2.Record(Schema2.String, OpenApiConfiguredValueInputSchema)),
|
|
978
|
+
oauth2: Schema2.optional(OpenApiOAuthInputSchema),
|
|
979
|
+
specFetchCredentials: Schema2.optional(
|
|
980
|
+
Schema2.Struct({
|
|
981
|
+
headers: Schema2.optional(Schema2.Record(Schema2.String, OpenApiConfiguredValueInputSchema)),
|
|
982
|
+
queryParams: Schema2.optional(Schema2.Record(Schema2.String, OpenApiConfiguredValueInputSchema))
|
|
584
983
|
})
|
|
585
984
|
)
|
|
586
985
|
});
|
|
587
|
-
var AddSourceOutputSchema =
|
|
588
|
-
sourceId:
|
|
589
|
-
|
|
986
|
+
var AddSourceOutputSchema = Schema2.Struct({
|
|
987
|
+
sourceId: Schema2.String,
|
|
988
|
+
source: Schema2.Struct({
|
|
989
|
+
id: Schema2.String,
|
|
990
|
+
scope: Schema2.String
|
|
991
|
+
}),
|
|
992
|
+
toolCount: Schema2.Number
|
|
993
|
+
});
|
|
994
|
+
var GetSourceInputSchema = Schema2.Struct({
|
|
995
|
+
namespace: Schema2.String,
|
|
996
|
+
scope: Schema2.String
|
|
590
997
|
});
|
|
591
|
-
var
|
|
592
|
-
|
|
998
|
+
var GetSourceOutputSchema = Schema2.Struct({
|
|
999
|
+
source: Schema2.NullOr(Schema2.Unknown)
|
|
1000
|
+
});
|
|
1001
|
+
var PreviewSpecInputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1002
|
+
Schema2.toStandardJSONSchemaV1(PreviewSpecInputSchema)
|
|
1003
|
+
);
|
|
1004
|
+
var PreviewSpecOutputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1005
|
+
Schema2.toStandardJSONSchemaV1(StaticPreviewSpecOutputSchema)
|
|
1006
|
+
);
|
|
1007
|
+
var AddSourceInputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1008
|
+
Schema2.toStandardJSONSchemaV1(AddSourceInputSchema)
|
|
1009
|
+
);
|
|
1010
|
+
var AddSourceOutputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1011
|
+
Schema2.toStandardJSONSchemaV1(AddSourceOutputSchema)
|
|
593
1012
|
);
|
|
594
|
-
var
|
|
595
|
-
|
|
1013
|
+
var OpenApiConfigureSourceInputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1014
|
+
Schema2.toStandardJSONSchemaV1(OpenApiConfigureSourceInputSchema)
|
|
596
1015
|
);
|
|
597
|
-
var
|
|
598
|
-
|
|
1016
|
+
var OpenApiConfigureSourceOutputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1017
|
+
Schema2.toStandardJSONSchemaV1(Schema2.Struct({ result: Schema2.Array(CredentialBindingRef) }))
|
|
1018
|
+
);
|
|
1019
|
+
var GetSourceInputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1020
|
+
Schema2.toStandardJSONSchemaV1(GetSourceInputSchema)
|
|
1021
|
+
);
|
|
1022
|
+
var GetSourceOutputStandardSchema = Schema2.toStandardSchemaV1(
|
|
1023
|
+
Schema2.toStandardJSONSchemaV1(GetSourceOutputSchema)
|
|
1024
|
+
);
|
|
1025
|
+
var openApiToolFailure = (code, message, details) => ToolResult.fail({
|
|
1026
|
+
code,
|
|
1027
|
+
message,
|
|
1028
|
+
...details === void 0 ? {} : { details }
|
|
1029
|
+
});
|
|
1030
|
+
var staticPreviewOutput = (preview) => ({
|
|
1031
|
+
title: Option3.getOrNull(preview.title),
|
|
1032
|
+
version: Option3.getOrNull(preview.version),
|
|
1033
|
+
servers: preview.servers.map((server) => ({
|
|
1034
|
+
url: server.url,
|
|
1035
|
+
description: Option3.getOrNull(server.description),
|
|
1036
|
+
variables: Option3.getOrNull(server.variables) ? Object.fromEntries(
|
|
1037
|
+
Object.entries(Option3.getOrNull(server.variables) ?? {}).map(([name, variable]) => [
|
|
1038
|
+
name,
|
|
1039
|
+
{
|
|
1040
|
+
default: variable.default,
|
|
1041
|
+
enum: Option3.getOrNull(variable.enum),
|
|
1042
|
+
description: Option3.getOrNull(variable.description)
|
|
1043
|
+
}
|
|
1044
|
+
])
|
|
1045
|
+
) : null
|
|
1046
|
+
})),
|
|
1047
|
+
operationCount: preview.operationCount,
|
|
1048
|
+
tags: preview.tags,
|
|
1049
|
+
securitySchemes: preview.securitySchemes.map((scheme) => ({
|
|
1050
|
+
name: scheme.name,
|
|
1051
|
+
type: scheme.type,
|
|
1052
|
+
scheme: Option3.getOrNull(scheme.scheme),
|
|
1053
|
+
bearerFormat: Option3.getOrNull(scheme.bearerFormat),
|
|
1054
|
+
in: Option3.getOrNull(scheme.in),
|
|
1055
|
+
headerName: Option3.getOrNull(scheme.headerName),
|
|
1056
|
+
description: Option3.getOrNull(scheme.description),
|
|
1057
|
+
flows: Option3.isSome(scheme.flows) ? {
|
|
1058
|
+
authorizationCode: Option3.isSome(scheme.flows.value.authorizationCode) ? {
|
|
1059
|
+
authorizationUrl: scheme.flows.value.authorizationCode.value.authorizationUrl,
|
|
1060
|
+
tokenUrl: scheme.flows.value.authorizationCode.value.tokenUrl,
|
|
1061
|
+
refreshUrl: Option3.getOrNull(scheme.flows.value.authorizationCode.value.refreshUrl),
|
|
1062
|
+
scopes: scheme.flows.value.authorizationCode.value.scopes
|
|
1063
|
+
} : null,
|
|
1064
|
+
clientCredentials: Option3.isSome(scheme.flows.value.clientCredentials) ? {
|
|
1065
|
+
tokenUrl: scheme.flows.value.clientCredentials.value.tokenUrl,
|
|
1066
|
+
refreshUrl: Option3.getOrNull(scheme.flows.value.clientCredentials.value.refreshUrl),
|
|
1067
|
+
scopes: scheme.flows.value.clientCredentials.value.scopes
|
|
1068
|
+
} : null
|
|
1069
|
+
} : null,
|
|
1070
|
+
openIdConnectUrl: Option3.getOrNull(scheme.openIdConnectUrl)
|
|
1071
|
+
})),
|
|
1072
|
+
authStrategies: preview.authStrategies,
|
|
1073
|
+
headerPresets: preview.headerPresets,
|
|
1074
|
+
oauth2Presets: preview.oauth2Presets.map((preset) => ({
|
|
1075
|
+
label: preset.label,
|
|
1076
|
+
securitySchemeName: preset.securitySchemeName,
|
|
1077
|
+
flow: preset.flow,
|
|
1078
|
+
authorizationUrl: Option3.getOrNull(preset.authorizationUrl),
|
|
1079
|
+
tokenUrl: preset.tokenUrl,
|
|
1080
|
+
refreshUrl: Option3.getOrNull(preset.refreshUrl),
|
|
1081
|
+
scopes: preset.scopes
|
|
1082
|
+
}))
|
|
1083
|
+
});
|
|
1084
|
+
var resolveStaticScopeInput = (ctx, value) => String(
|
|
1085
|
+
ctx.scopes.find((scope) => scope.name === value || String(scope.id) === value)?.id ?? value
|
|
599
1086
|
);
|
|
600
1087
|
var normalizeOpenApiRefs = (node) => {
|
|
601
1088
|
if (node == null || typeof node !== "object") return node;
|
|
@@ -631,9 +1118,9 @@ var toBinding = (def) => OperationBinding.make({
|
|
|
631
1118
|
});
|
|
632
1119
|
var descriptionFor = (def) => {
|
|
633
1120
|
const op = def.operation;
|
|
634
|
-
return
|
|
1121
|
+
return Option3.getOrElse(
|
|
635
1122
|
op.description,
|
|
636
|
-
() =>
|
|
1123
|
+
() => Option3.getOrElse(op.summary, () => `${op.method.toUpperCase()} ${op.pathTemplate}`)
|
|
637
1124
|
);
|
|
638
1125
|
};
|
|
639
1126
|
var slotPart = (value) => value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "default";
|
|
@@ -643,13 +1130,12 @@ var specFetchHeaderSlotFromName = (name) => `spec_fetch_header:${slotPart(name)}
|
|
|
643
1130
|
var specFetchQueryParamSlotFromName = (name) => `spec_fetch_query_param:${slotPart(name)}`;
|
|
644
1131
|
var canonicalizeHeaders = (headers) => {
|
|
645
1132
|
const nextHeaders = {};
|
|
646
|
-
const bindings = [];
|
|
647
1133
|
for (const [name, value] of Object.entries(headers ?? {})) {
|
|
648
1134
|
if (typeof value === "string") {
|
|
649
1135
|
nextHeaders[name] = value;
|
|
650
1136
|
continue;
|
|
651
1137
|
}
|
|
652
|
-
if (
|
|
1138
|
+
if (value.kind === "binding") {
|
|
653
1139
|
nextHeaders[name] = value;
|
|
654
1140
|
continue;
|
|
655
1141
|
}
|
|
@@ -659,27 +1145,17 @@ var canonicalizeHeaders = (headers) => {
|
|
|
659
1145
|
slot,
|
|
660
1146
|
prefix: value.prefix
|
|
661
1147
|
});
|
|
662
|
-
bindings.push({
|
|
663
|
-
slot,
|
|
664
|
-
targetScope: "targetScope" in value ? value.targetScope : void 0,
|
|
665
|
-
value: {
|
|
666
|
-
kind: "secret",
|
|
667
|
-
secretId: SecretId.make(value.secretId),
|
|
668
|
-
..."secretScopeId" in value && value.secretScopeId ? { secretScopeId: value.secretScopeId } : {}
|
|
669
|
-
}
|
|
670
|
-
});
|
|
671
1148
|
}
|
|
672
|
-
return { headers: nextHeaders
|
|
1149
|
+
return { headers: nextHeaders };
|
|
673
1150
|
};
|
|
674
1151
|
var canonicalizeCredentialMap = (values, slotForName) => {
|
|
675
1152
|
const nextValues = {};
|
|
676
|
-
const bindings = [];
|
|
677
1153
|
for (const [name, value] of Object.entries(values ?? {})) {
|
|
678
1154
|
if (typeof value === "string") {
|
|
679
1155
|
nextValues[name] = value;
|
|
680
1156
|
continue;
|
|
681
1157
|
}
|
|
682
|
-
if (
|
|
1158
|
+
if (value.kind === "binding") {
|
|
683
1159
|
nextValues[name] = value;
|
|
684
1160
|
continue;
|
|
685
1161
|
}
|
|
@@ -689,17 +1165,8 @@ var canonicalizeCredentialMap = (values, slotForName) => {
|
|
|
689
1165
|
slot,
|
|
690
1166
|
prefix: value.prefix
|
|
691
1167
|
});
|
|
692
|
-
bindings.push({
|
|
693
|
-
slot,
|
|
694
|
-
targetScope: "targetScope" in value ? value.targetScope : void 0,
|
|
695
|
-
value: {
|
|
696
|
-
kind: "secret",
|
|
697
|
-
secretId: SecretId.make(value.secretId),
|
|
698
|
-
..."secretScopeId" in value && value.secretScopeId ? { secretScopeId: value.secretScopeId } : {}
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
1168
|
}
|
|
702
|
-
return { values: nextValues
|
|
1169
|
+
return { values: nextValues };
|
|
703
1170
|
};
|
|
704
1171
|
var canonicalizeSpecFetchCredentials = (credentials) => {
|
|
705
1172
|
const headers = canonicalizeCredentialMap(credentials?.headers, specFetchHeaderSlotFromName);
|
|
@@ -712,88 +1179,162 @@ var canonicalizeSpecFetchCredentials = (credentials) => {
|
|
|
712
1179
|
...Object.keys(queryParams.values).length > 0 ? { queryParams: queryParams.values } : {}
|
|
713
1180
|
};
|
|
714
1181
|
return {
|
|
715
|
-
credentials: nextCredentials
|
|
716
|
-
bindings: [...headers.bindings, ...queryParams.bindings]
|
|
1182
|
+
credentials: nextCredentials
|
|
717
1183
|
};
|
|
718
1184
|
};
|
|
719
1185
|
var canonicalizeOAuth2 = (oauth2) => {
|
|
720
|
-
if (!oauth2) return {
|
|
1186
|
+
if (!oauth2) return {};
|
|
721
1187
|
return {
|
|
722
|
-
oauth2
|
|
723
|
-
bindings: []
|
|
1188
|
+
oauth2
|
|
724
1189
|
};
|
|
725
1190
|
};
|
|
726
|
-
var
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
const
|
|
765
|
-
const
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
1191
|
+
var configuredValueFromConfigureInput = (slot, input) => {
|
|
1192
|
+
if (typeof input === "string") {
|
|
1193
|
+
return {
|
|
1194
|
+
configured: ConfiguredHeaderBinding.make({ kind: "binding", slot }),
|
|
1195
|
+
value: { kind: "text", text: input }
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
if (input.kind === "text") {
|
|
1199
|
+
return {
|
|
1200
|
+
configured: ConfiguredHeaderBinding.make({
|
|
1201
|
+
kind: "binding",
|
|
1202
|
+
slot,
|
|
1203
|
+
prefix: input.prefix
|
|
1204
|
+
}),
|
|
1205
|
+
value: { kind: "text", text: input.text }
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
if (input.kind === "secret") {
|
|
1209
|
+
return {
|
|
1210
|
+
configured: ConfiguredHeaderBinding.make({
|
|
1211
|
+
kind: "binding",
|
|
1212
|
+
slot,
|
|
1213
|
+
prefix: input.prefix
|
|
1214
|
+
}),
|
|
1215
|
+
value: {
|
|
1216
|
+
kind: "secret",
|
|
1217
|
+
secretId: SecretId.make(input.secretId),
|
|
1218
|
+
...input.secretScope ? { secretScopeId: ScopeId.make(input.secretScope) } : {}
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
return {
|
|
1223
|
+
configured: ConfiguredHeaderBinding.make({ kind: "binding", slot }),
|
|
1224
|
+
value: { kind: "connection", connectionId: ConnectionId.make(input.connectionId) }
|
|
1225
|
+
};
|
|
1226
|
+
};
|
|
1227
|
+
var configureMap = (values, slotForName) => {
|
|
1228
|
+
const configured = {};
|
|
1229
|
+
const bindings = [];
|
|
1230
|
+
for (const [name, input] of Object.entries(values ?? {})) {
|
|
1231
|
+
const slotKey = slotForName(name);
|
|
1232
|
+
const next = configuredValueFromConfigureInput(slotKey, input);
|
|
1233
|
+
configured[name] = next.configured;
|
|
1234
|
+
bindings.push({ slotKey, value: next.value });
|
|
1235
|
+
}
|
|
1236
|
+
return { configured, bindings };
|
|
1237
|
+
};
|
|
1238
|
+
var configureOpenApiSource = (ctx, source, input) => Effect3.gen(function* () {
|
|
1239
|
+
const existing = yield* ctx.storage.getSource(source.id, source.scope);
|
|
1240
|
+
if (!existing) {
|
|
769
1241
|
return yield* new StorageError({
|
|
770
|
-
message: `OpenAPI source
|
|
1242
|
+
message: `Cannot configure OpenAPI source "${source.id}" at scope "${source.scope}": source is not visible.`,
|
|
771
1243
|
cause: void 0
|
|
772
1244
|
});
|
|
773
1245
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1246
|
+
const headers = configureMap(input.headers, headerSlotFromName);
|
|
1247
|
+
const queryParams = configureMap(input.queryParams, queryParamSlotFromName);
|
|
1248
|
+
const specFetchHeaders = configureMap(
|
|
1249
|
+
input.specFetchCredentials?.headers,
|
|
1250
|
+
specFetchHeaderSlotFromName
|
|
1251
|
+
);
|
|
1252
|
+
const specFetchQueryParams = configureMap(
|
|
1253
|
+
input.specFetchCredentials?.queryParams,
|
|
1254
|
+
specFetchQueryParamSlotFromName
|
|
1255
|
+
);
|
|
1256
|
+
const oauth2 = existing.config.oauth2;
|
|
1257
|
+
const oauth2Bindings = [];
|
|
1258
|
+
if (oauth2 && input.oauth2?.clientId) {
|
|
1259
|
+
oauth2Bindings.push({
|
|
1260
|
+
slotKey: oauth2.clientIdSlot,
|
|
1261
|
+
value: configuredValueFromConfigureInput(oauth2.clientIdSlot, input.oauth2.clientId).value
|
|
778
1262
|
});
|
|
779
1263
|
}
|
|
780
|
-
if (
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
1264
|
+
if (oauth2?.clientSecretSlot && input.oauth2?.clientSecret) {
|
|
1265
|
+
oauth2Bindings.push({
|
|
1266
|
+
slotKey: oauth2.clientSecretSlot,
|
|
1267
|
+
value: configuredValueFromConfigureInput(oauth2.clientSecretSlot, input.oauth2.clientSecret).value
|
|
784
1268
|
});
|
|
785
1269
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
1270
|
+
if (oauth2 && input.oauth2?.connection) {
|
|
1271
|
+
oauth2Bindings.push({
|
|
1272
|
+
slotKey: oauth2.connectionSlot,
|
|
1273
|
+
value: configuredValueFromConfigureInput(oauth2.connectionSlot, input.oauth2.connection).value
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
const specFetchCredentials = input.specFetchCredentials === void 0 ? existing.config.specFetchCredentials : {
|
|
1277
|
+
headers: specFetchHeaders.configured,
|
|
1278
|
+
queryParams: specFetchQueryParams.configured
|
|
1279
|
+
};
|
|
1280
|
+
const affectedPrefixes = [
|
|
1281
|
+
...input.headers !== void 0 ? ["header:"] : [],
|
|
1282
|
+
...input.queryParams !== void 0 ? ["query_param:"] : [],
|
|
1283
|
+
...input.specFetchCredentials?.headers !== void 0 ? ["spec_fetch:header:"] : [],
|
|
1284
|
+
...input.specFetchCredentials?.queryParams !== void 0 ? ["spec_fetch:query_param:"] : [],
|
|
1285
|
+
...input.oauth2 !== void 0 ? ["oauth2:"] : []
|
|
1286
|
+
];
|
|
1287
|
+
const bindings = [
|
|
1288
|
+
...headers.bindings,
|
|
1289
|
+
...queryParams.bindings,
|
|
1290
|
+
...specFetchHeaders.bindings,
|
|
1291
|
+
...specFetchQueryParams.bindings,
|
|
1292
|
+
...oauth2Bindings
|
|
1293
|
+
];
|
|
1294
|
+
const nextConfiguredValues = (current, next, provided) => {
|
|
1295
|
+
if (!provided) return current;
|
|
1296
|
+
if (Object.keys(next).length === 0) return {};
|
|
1297
|
+
return { ...current ?? {}, ...next };
|
|
1298
|
+
};
|
|
1299
|
+
return yield* ctx.transaction(
|
|
1300
|
+
Effect3.gen(function* () {
|
|
1301
|
+
yield* ctx.storage.updateSourceMeta(source.id, source.scope, {
|
|
1302
|
+
headers: nextConfiguredValues(
|
|
1303
|
+
existing.config.headers,
|
|
1304
|
+
headers.configured,
|
|
1305
|
+
input.headers !== void 0
|
|
1306
|
+
),
|
|
1307
|
+
queryParams: nextConfiguredValues(
|
|
1308
|
+
existing.config.queryParams,
|
|
1309
|
+
queryParams.configured,
|
|
1310
|
+
input.queryParams !== void 0
|
|
1311
|
+
),
|
|
1312
|
+
specFetchCredentials
|
|
1313
|
+
});
|
|
1314
|
+
if (affectedPrefixes.length > 0 || bindings.length > 0) {
|
|
1315
|
+
return yield* ctx.credentialBindings.replaceForSource({
|
|
1316
|
+
targetScope: ScopeId.make(input.scope),
|
|
1317
|
+
pluginId: OPENAPI_PLUGIN_ID,
|
|
1318
|
+
sourceId: source.id,
|
|
1319
|
+
sourceScope: ScopeId.make(source.scope),
|
|
1320
|
+
slotPrefixes: affectedPrefixes,
|
|
1321
|
+
bindings
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
return [];
|
|
793
1325
|
})
|
|
794
1326
|
);
|
|
795
|
-
};
|
|
796
|
-
var
|
|
1327
|
+
});
|
|
1328
|
+
var OPENAPI_PLUGIN_ID = "openapi";
|
|
1329
|
+
var scopeRanks = (ctx) => new Map(ctx.scopes.map((scope, index) => [String(scope.id), index]));
|
|
1330
|
+
var scopeRank = (ranks, scopeId) => ranks.get(scopeId) ?? Infinity;
|
|
1331
|
+
var resolveOpenApiCredentialBinding = (ctx, sourceId, sourceScope, slot) => ctx.credentialBindings.resolveBinding({
|
|
1332
|
+
pluginId: OPENAPI_PLUGIN_ID,
|
|
1333
|
+
sourceId,
|
|
1334
|
+
sourceScope: ScopeId.make(sourceScope),
|
|
1335
|
+
slotKey: slot
|
|
1336
|
+
});
|
|
1337
|
+
var findOuterSource = (ctx, namespace, scope) => Effect3.gen(function* () {
|
|
797
1338
|
const ranks = scopeRanks(ctx);
|
|
798
1339
|
const baseRank = scopeRank(ranks, scope);
|
|
799
1340
|
for (let index = baseRank + 1; index < ctx.scopes.length; index++) {
|
|
@@ -804,7 +1345,7 @@ var findOuterSource = (ctx, namespace, scope) => Effect2.gen(function* () {
|
|
|
804
1345
|
}
|
|
805
1346
|
return null;
|
|
806
1347
|
});
|
|
807
|
-
var resolveEffectiveSourceConfig = (ctx, base) =>
|
|
1348
|
+
var resolveEffectiveSourceConfig = (ctx, base) => Effect3.gen(function* () {
|
|
808
1349
|
const fallback = yield* findOuterSource(ctx, base.namespace, base.scope);
|
|
809
1350
|
if (!fallback) {
|
|
810
1351
|
return {
|
|
@@ -835,14 +1376,14 @@ var resolveEffectiveSourceConfig = (ctx, base) => Effect2.gen(function* () {
|
|
|
835
1376
|
oauth2Source: base.config.oauth2 ? base : fallback
|
|
836
1377
|
};
|
|
837
1378
|
});
|
|
838
|
-
var resolveConfiguredValueMap = (ctx, params) =>
|
|
1379
|
+
var resolveConfiguredValueMap = (ctx, params) => Effect3.gen(function* () {
|
|
839
1380
|
const resolved = {};
|
|
840
1381
|
for (const [name, value] of Object.entries(params.values)) {
|
|
841
1382
|
if (typeof value === "string") {
|
|
842
1383
|
resolved[name] = value;
|
|
843
1384
|
continue;
|
|
844
1385
|
}
|
|
845
|
-
const binding = yield*
|
|
1386
|
+
const binding = yield* resolveOpenApiCredentialBinding(
|
|
846
1387
|
ctx,
|
|
847
1388
|
params.sourceId,
|
|
848
1389
|
params.sourceScope,
|
|
@@ -850,9 +1391,9 @@ var resolveConfiguredValueMap = (ctx, params) => Effect2.gen(function* () {
|
|
|
850
1391
|
);
|
|
851
1392
|
if (binding?.value.kind === "secret") {
|
|
852
1393
|
const secret = yield* ctx.secrets.getAtScope(binding.value.secretId, binding.value.secretScopeId ?? binding.scopeId).pipe(
|
|
853
|
-
|
|
1394
|
+
Effect3.catchTag(
|
|
854
1395
|
"SecretOwnedByConnectionError",
|
|
855
|
-
() =>
|
|
1396
|
+
() => Effect3.fail(
|
|
856
1397
|
new OpenApiOAuthError({
|
|
857
1398
|
message: `Secret not found for header "${name}"`
|
|
858
1399
|
})
|
|
@@ -889,17 +1430,17 @@ var resolveSecretBackedValues = (ctx, values) => resolveSecretBackedMap({
|
|
|
889
1430
|
onMissing: (name) => new OpenApiOAuthError({
|
|
890
1431
|
message: `Secret not found for "${name}"`
|
|
891
1432
|
}),
|
|
892
|
-
onError: (err, name) =>
|
|
1433
|
+
onError: (err, name) => Predicate2.isTagged("SecretOwnedByConnectionError")(err) ? new OpenApiOAuthError({
|
|
893
1434
|
message: `Secret not found for "${name}"`
|
|
894
1435
|
}) : err
|
|
895
1436
|
}).pipe(
|
|
896
|
-
|
|
897
|
-
(err) =>
|
|
1437
|
+
Effect3.mapError(
|
|
1438
|
+
(err) => Predicate2.isTagged("SecretOwnedByConnectionError")(err) ? new OpenApiOAuthError({ message: "Secret resolution failed" }) : err
|
|
898
1439
|
),
|
|
899
|
-
|
|
1440
|
+
Effect3.map((resolved) => resolved ?? {})
|
|
900
1441
|
);
|
|
901
|
-
var resolveOAuthConnectionId = (ctx, params) =>
|
|
902
|
-
const binding = yield*
|
|
1442
|
+
var resolveOAuthConnectionId = (ctx, params) => Effect3.gen(function* () {
|
|
1443
|
+
const binding = yield* resolveOpenApiCredentialBinding(
|
|
903
1444
|
ctx,
|
|
904
1445
|
params.sourceId,
|
|
905
1446
|
params.sourceScope,
|
|
@@ -912,14 +1453,14 @@ var resolveOAuthConnectionId = (ctx, params) => Effect2.gen(function* () {
|
|
|
912
1453
|
}
|
|
913
1454
|
return null;
|
|
914
1455
|
});
|
|
915
|
-
var resolveSpecFetchInputCredentials = (ctx, credentials) =>
|
|
1456
|
+
var resolveSpecFetchInputCredentials = (ctx, credentials) => Effect3.gen(function* () {
|
|
916
1457
|
if (!credentials) return void 0;
|
|
917
1458
|
return {
|
|
918
1459
|
headers: yield* resolveSecretBackedValues(ctx, credentials.headers),
|
|
919
1460
|
queryParams: yield* resolveSecretBackedValues(ctx, credentials.queryParams)
|
|
920
1461
|
};
|
|
921
1462
|
});
|
|
922
|
-
var resolveStoredSpecFetchCredentials = (ctx, params) =>
|
|
1463
|
+
var resolveStoredSpecFetchCredentials = (ctx, params) => Effect3.gen(function* () {
|
|
923
1464
|
if (!params.credentials) return void 0;
|
|
924
1465
|
return {
|
|
925
1466
|
headers: yield* resolveConfiguredValueMap(ctx, {
|
|
@@ -939,13 +1480,13 @@ var resolveStoredSpecFetchCredentials = (ctx, params) => Effect2.gen(function* (
|
|
|
939
1480
|
var toOpenApiSourceConfig = (namespace, config) => {
|
|
940
1481
|
const configHeaders = {};
|
|
941
1482
|
for (const [name, value] of Object.entries(config.headers ?? {})) {
|
|
942
|
-
if (typeof value === "string"
|
|
1483
|
+
if (typeof value === "string") {
|
|
943
1484
|
configHeaders[name] = value;
|
|
944
1485
|
}
|
|
945
1486
|
}
|
|
946
1487
|
return {
|
|
947
1488
|
kind: "openapi",
|
|
948
|
-
spec: config.spec,
|
|
1489
|
+
spec: specInputToConfigString(config.spec),
|
|
949
1490
|
baseUrl: config.baseUrl,
|
|
950
1491
|
namespace,
|
|
951
1492
|
headers: headersToConfigValues(
|
|
@@ -953,12 +1494,12 @@ var toOpenApiSourceConfig = (namespace, config) => {
|
|
|
953
1494
|
)
|
|
954
1495
|
};
|
|
955
1496
|
};
|
|
956
|
-
var
|
|
1497
|
+
var specInputToConfigString = (spec) => spec.kind === "url" ? spec.url : spec.value;
|
|
957
1498
|
var openApiPlugin = definePlugin((options) => {
|
|
958
|
-
const rebuildSource = (ctx, input) =>
|
|
1499
|
+
const rebuildSource = (ctx, input) => Effect3.gen(function* () {
|
|
959
1500
|
const doc = yield* parse(input.specText);
|
|
960
1501
|
const result = yield* extract(doc);
|
|
961
|
-
const namespace = input.namespace
|
|
1502
|
+
const namespace = input.namespace;
|
|
962
1503
|
const outerSource = yield* findOuterSource(ctx, namespace, input.scope);
|
|
963
1504
|
if (outerSource && input.baseUrl !== void 0 && input.baseUrl.trim() !== "") {
|
|
964
1505
|
return yield* new OpenApiOAuthError({
|
|
@@ -971,7 +1512,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
971
1512
|
hoistedDefs[k] = normalizeOpenApiRefs(v);
|
|
972
1513
|
}
|
|
973
1514
|
}
|
|
974
|
-
const baseUrl = outerSource ? void 0 : input.baseUrl
|
|
1515
|
+
const baseUrl = outerSource ? void 0 : input.baseUrl;
|
|
975
1516
|
const canonicalHeaders = canonicalizeHeaders(input.headers);
|
|
976
1517
|
const canonicalQueryParams = canonicalizeCredentialMap(
|
|
977
1518
|
input.queryParams,
|
|
@@ -981,25 +1522,8 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
981
1522
|
input.specFetchCredentials
|
|
982
1523
|
);
|
|
983
1524
|
const canonicalOAuth2 = canonicalizeOAuth2(input.oauth2);
|
|
984
|
-
const directBindings = [
|
|
985
|
-
...canonicalHeaders.bindings,
|
|
986
|
-
...canonicalQueryParams.bindings,
|
|
987
|
-
...canonicalSpecFetchCredentials.bindings,
|
|
988
|
-
...canonicalOAuth2.bindings
|
|
989
|
-
];
|
|
990
|
-
for (const binding of directBindings) {
|
|
991
|
-
const bindingTargetScope = yield* targetScopeForBinding(
|
|
992
|
-
input.credentialTargetScope,
|
|
993
|
-
binding
|
|
994
|
-
);
|
|
995
|
-
yield* validateOpenApiBindingTarget(ctx, {
|
|
996
|
-
sourceId: namespace,
|
|
997
|
-
sourceScope: input.scope,
|
|
998
|
-
targetScope: bindingTargetScope
|
|
999
|
-
});
|
|
1000
|
-
}
|
|
1001
1525
|
const definitions = compileToolDefinitions(result.operations);
|
|
1002
|
-
const sourceName = input.name
|
|
1526
|
+
const sourceName = input.name;
|
|
1003
1527
|
const sourceConfig = {
|
|
1004
1528
|
spec: input.specText,
|
|
1005
1529
|
sourceUrl: input.sourceUrl,
|
|
@@ -1022,7 +1546,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1022
1546
|
binding: toBinding(def)
|
|
1023
1547
|
}));
|
|
1024
1548
|
yield* ctx.transaction(
|
|
1025
|
-
|
|
1549
|
+
Effect3.gen(function* () {
|
|
1026
1550
|
yield* ctx.storage.upsertSource(storedSource, storedOps);
|
|
1027
1551
|
yield* ctx.core.sources.register({
|
|
1028
1552
|
id: namespace,
|
|
@@ -1039,26 +1563,10 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1039
1563
|
tools: definitions.map((def) => ({
|
|
1040
1564
|
name: def.toolPath,
|
|
1041
1565
|
description: descriptionFor(def),
|
|
1042
|
-
inputSchema: normalizeOpenApiRefs(
|
|
1043
|
-
outputSchema: normalizeOpenApiRefs(
|
|
1566
|
+
inputSchema: normalizeOpenApiRefs(Option3.getOrUndefined(def.operation.inputSchema)),
|
|
1567
|
+
outputSchema: normalizeOpenApiRefs(Option3.getOrUndefined(def.operation.outputSchema))
|
|
1044
1568
|
}))
|
|
1045
1569
|
});
|
|
1046
|
-
if (directBindings.length > 0) {
|
|
1047
|
-
for (const binding of directBindings) {
|
|
1048
|
-
const bindingTargetScope = yield* targetScopeForBinding(
|
|
1049
|
-
input.credentialTargetScope,
|
|
1050
|
-
binding
|
|
1051
|
-
);
|
|
1052
|
-
yield* ctx.credentialBindings.set({
|
|
1053
|
-
targetScope: ScopeId.make(bindingTargetScope),
|
|
1054
|
-
pluginId: OPENAPI_PLUGIN_ID,
|
|
1055
|
-
sourceId: namespace,
|
|
1056
|
-
sourceScope: ScopeId.make(input.scope),
|
|
1057
|
-
slotKey: binding.slot,
|
|
1058
|
-
value: binding.value
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
1570
|
if (Object.keys(hoistedDefs).length > 0) {
|
|
1063
1571
|
yield* ctx.core.definitions.register({
|
|
1064
1572
|
sourceId: namespace,
|
|
@@ -1070,7 +1578,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1070
1578
|
);
|
|
1071
1579
|
return { sourceId: namespace, toolCount: definitions.length };
|
|
1072
1580
|
});
|
|
1073
|
-
const refreshSourceInternal = (ctx, sourceId, scope) =>
|
|
1581
|
+
const refreshSourceInternal = (ctx, sourceId, scope) => Effect3.gen(function* () {
|
|
1074
1582
|
const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer;
|
|
1075
1583
|
const existing = yield* ctx.storage.getSource(sourceId, scope);
|
|
1076
1584
|
if (!existing) return;
|
|
@@ -1084,78 +1592,67 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1084
1592
|
credentials: resolvedConfig.specFetchCredentials
|
|
1085
1593
|
});
|
|
1086
1594
|
const specText = yield* resolveSpecText(sourceUrl, credentials).pipe(
|
|
1087
|
-
|
|
1595
|
+
Effect3.provide(httpClientLayer)
|
|
1088
1596
|
);
|
|
1089
1597
|
yield* rebuildSource(ctx, {
|
|
1090
1598
|
specText,
|
|
1091
1599
|
scope,
|
|
1092
1600
|
sourceUrl,
|
|
1093
1601
|
name: existing.name,
|
|
1094
|
-
baseUrl:
|
|
1602
|
+
baseUrl: existing.config.baseUrl,
|
|
1095
1603
|
namespace: existing.namespace,
|
|
1096
1604
|
headers: existing.config.headers,
|
|
1097
1605
|
queryParams: existing.config.queryParams,
|
|
1098
1606
|
specFetchCredentials: existing.config.specFetchCredentials,
|
|
1099
|
-
oauth2: existing.config.oauth2
|
|
1100
|
-
credentialTargetScope: scope
|
|
1607
|
+
oauth2: existing.config.oauth2
|
|
1101
1608
|
});
|
|
1102
1609
|
});
|
|
1103
1610
|
return {
|
|
1104
1611
|
id: "openapi",
|
|
1105
1612
|
packageName: "@executor-js/plugin-openapi",
|
|
1613
|
+
sourcePresets: openApiPresets,
|
|
1106
1614
|
schema: openapiSchema,
|
|
1107
1615
|
storage: (deps) => makeDefaultOpenapiStore(deps),
|
|
1108
1616
|
extension: (ctx) => {
|
|
1109
1617
|
const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer;
|
|
1110
|
-
const addSpecInternal = (config) =>
|
|
1111
|
-
const
|
|
1112
|
-
ctx,
|
|
1113
|
-
config.specFetchCredentials
|
|
1114
|
-
);
|
|
1115
|
-
const specText = yield* resolveSpecText(config.spec, credentials).pipe(
|
|
1116
|
-
Effect2.provide(httpClientLayer)
|
|
1117
|
-
);
|
|
1618
|
+
const addSpecInternal = (config) => Effect3.gen(function* () {
|
|
1619
|
+
const specText = config.spec.kind === "url" ? yield* resolveSpecText(config.spec.url).pipe(Effect3.provide(httpClientLayer)) : config.spec.value;
|
|
1118
1620
|
return yield* rebuildSource(ctx, {
|
|
1119
1621
|
specText,
|
|
1120
1622
|
scope: config.scope,
|
|
1121
|
-
sourceUrl:
|
|
1623
|
+
sourceUrl: config.spec.kind === "url" ? config.spec.url : void 0,
|
|
1122
1624
|
name: config.name,
|
|
1123
1625
|
baseUrl: config.baseUrl,
|
|
1124
1626
|
namespace: config.namespace,
|
|
1125
1627
|
headers: config.headers,
|
|
1126
1628
|
queryParams: config.queryParams,
|
|
1127
1629
|
specFetchCredentials: config.specFetchCredentials,
|
|
1128
|
-
oauth2: config.oauth2
|
|
1129
|
-
// Default to the source's own scope. refreshSource and editSource
|
|
1130
|
-
// do the same; without this, config-sync's addSpec — which never
|
|
1131
|
-
// passes the field — fails with "credentialTargetScope is
|
|
1132
|
-
// required" the moment the jsonc declares any header secret.
|
|
1133
|
-
credentialTargetScope: config.credentialTargetScope ?? config.scope
|
|
1630
|
+
oauth2: config.oauth2
|
|
1134
1631
|
});
|
|
1135
1632
|
});
|
|
1136
1633
|
const configFile = options?.configFile;
|
|
1137
1634
|
return {
|
|
1138
|
-
previewSpec: (input) =>
|
|
1635
|
+
previewSpec: (input) => Effect3.gen(function* () {
|
|
1139
1636
|
const previewInput = typeof input === "string" ? { spec: input } : input;
|
|
1140
1637
|
const credentials = yield* resolveSpecFetchInputCredentials(
|
|
1141
1638
|
ctx,
|
|
1142
1639
|
previewInput.specFetchCredentials
|
|
1143
1640
|
);
|
|
1144
1641
|
const specText = yield* resolveSpecText(previewInput.spec, credentials).pipe(
|
|
1145
|
-
|
|
1642
|
+
Effect3.provide(httpClientLayer)
|
|
1146
1643
|
);
|
|
1147
|
-
return yield* previewSpec(specText).pipe(
|
|
1644
|
+
return yield* previewSpec(specText).pipe(Effect3.provide(httpClientLayer));
|
|
1148
1645
|
}),
|
|
1149
|
-
addSpec: (config) =>
|
|
1646
|
+
addSpec: (config) => Effect3.gen(function* () {
|
|
1150
1647
|
const result = yield* addSpecInternal(config);
|
|
1151
1648
|
if (configFile) {
|
|
1152
1649
|
yield* configFile.upsertSource(toOpenApiSourceConfig(result.sourceId, config));
|
|
1153
1650
|
}
|
|
1154
1651
|
return result;
|
|
1155
1652
|
}),
|
|
1156
|
-
removeSpec: (namespace, scope) =>
|
|
1653
|
+
removeSpec: (namespace, scope) => Effect3.gen(function* () {
|
|
1157
1654
|
yield* ctx.transaction(
|
|
1158
|
-
|
|
1655
|
+
Effect3.gen(function* () {
|
|
1159
1656
|
yield* ctx.credentialBindings.removeForSource({
|
|
1160
1657
|
pluginId: OPENAPI_PLUGIN_ID,
|
|
1161
1658
|
sourceId: namespace,
|
|
@@ -1172,7 +1669,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1172
1669
|
yield* configFile.removeSource(namespace);
|
|
1173
1670
|
}
|
|
1174
1671
|
}),
|
|
1175
|
-
getSource: (namespace, scope) =>
|
|
1672
|
+
getSource: (namespace, scope) => Effect3.gen(function* () {
|
|
1176
1673
|
const source = yield* ctx.storage.getSource(namespace, scope);
|
|
1177
1674
|
if (!source) return null;
|
|
1178
1675
|
const effective = yield* resolveEffectiveSourceConfig(ctx, source);
|
|
@@ -1181,95 +1678,31 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1181
1678
|
config: effective.config
|
|
1182
1679
|
};
|
|
1183
1680
|
}),
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
...canonicalOAuth2?.bindings ?? []
|
|
1194
|
-
];
|
|
1195
|
-
const affectedPrefixes = [
|
|
1196
|
-
...input.headers !== void 0 ? ["header:"] : [],
|
|
1197
|
-
...input.queryParams !== void 0 ? ["query_param:"] : [],
|
|
1198
|
-
...input.oauth2 !== void 0 ? ["oauth2:"] : []
|
|
1199
|
-
];
|
|
1200
|
-
const targetScope = input.credentialTargetScope ?? scope;
|
|
1681
|
+
configure: (source, input) => configureOpenApiSource(ctx, source, input)
|
|
1682
|
+
};
|
|
1683
|
+
},
|
|
1684
|
+
sourceConfigure: {
|
|
1685
|
+
type: "openapi",
|
|
1686
|
+
schema: OpenApiConfigureInputSchema,
|
|
1687
|
+
configure: ({ ctx, sourceId, sourceScope, config }) => Effect3.gen(function* () {
|
|
1688
|
+
const input = config;
|
|
1689
|
+
if (input.name !== void 0 || input.baseUrl !== void 0 || input.oauth2Source !== void 0) {
|
|
1201
1690
|
if (input.baseUrl !== void 0 && input.baseUrl.trim() !== "") {
|
|
1202
|
-
const outerSource = yield* findOuterSource(ctx,
|
|
1691
|
+
const outerSource = yield* findOuterSource(ctx, sourceId, sourceScope);
|
|
1203
1692
|
if (outerSource) {
|
|
1204
1693
|
return yield* new OpenApiOAuthError({
|
|
1205
1694
|
message: "OpenAPI source shadows inherit the outer source base URL"
|
|
1206
1695
|
});
|
|
1207
1696
|
}
|
|
1208
1697
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
targetScope
|
|
1214
|
-
});
|
|
1215
|
-
}
|
|
1216
|
-
yield* ctx.transaction(
|
|
1217
|
-
Effect2.gen(function* () {
|
|
1218
|
-
yield* ctx.storage.updateSourceMeta(namespace, scope, {
|
|
1219
|
-
name: input.name?.trim() || void 0,
|
|
1220
|
-
baseUrl: input.baseUrl,
|
|
1221
|
-
headers: canonicalHeaders?.headers,
|
|
1222
|
-
queryParams: canonicalQueryParams?.values,
|
|
1223
|
-
oauth2: canonicalOAuth2?.oauth2
|
|
1224
|
-
});
|
|
1225
|
-
if (affectedPrefixes.length > 0 || directBindings.length > 0) {
|
|
1226
|
-
yield* ctx.credentialBindings.replaceForSource({
|
|
1227
|
-
targetScope: ScopeId.make(targetScope),
|
|
1228
|
-
pluginId: OPENAPI_PLUGIN_ID,
|
|
1229
|
-
sourceId: namespace,
|
|
1230
|
-
sourceScope: ScopeId.make(scope),
|
|
1231
|
-
slotPrefixes: affectedPrefixes,
|
|
1232
|
-
bindings: directBindings.map((binding) => ({
|
|
1233
|
-
slotKey: binding.slot,
|
|
1234
|
-
value: binding.value
|
|
1235
|
-
}))
|
|
1236
|
-
});
|
|
1237
|
-
}
|
|
1238
|
-
})
|
|
1239
|
-
);
|
|
1240
|
-
}),
|
|
1241
|
-
listSourceBindings: (sourceId, sourceScope) => listOpenApiSourceBindings(ctx, sourceId, sourceScope),
|
|
1242
|
-
setSourceBinding: (input) => Effect2.gen(function* () {
|
|
1243
|
-
yield* validateOpenApiBindingTarget(ctx, {
|
|
1244
|
-
sourceId: input.sourceId,
|
|
1245
|
-
sourceScope: input.sourceScope,
|
|
1246
|
-
targetScope: input.scope
|
|
1247
|
-
});
|
|
1248
|
-
const binding = yield* ctx.credentialBindings.set({
|
|
1249
|
-
targetScope: input.scope,
|
|
1250
|
-
pluginId: OPENAPI_PLUGIN_ID,
|
|
1251
|
-
sourceId: input.sourceId,
|
|
1252
|
-
sourceScope: input.sourceScope,
|
|
1253
|
-
slotKey: input.slot,
|
|
1254
|
-
value: input.value
|
|
1255
|
-
});
|
|
1256
|
-
return coreBindingToOpenApiBinding(binding);
|
|
1257
|
-
}),
|
|
1258
|
-
removeSourceBinding: (sourceId, sourceScope, slot, scope) => Effect2.gen(function* () {
|
|
1259
|
-
yield* validateOpenApiBindingTarget(ctx, {
|
|
1260
|
-
sourceId,
|
|
1261
|
-
sourceScope,
|
|
1262
|
-
targetScope: scope
|
|
1698
|
+
yield* ctx.storage.updateSourceMeta(sourceId, sourceScope, {
|
|
1699
|
+
name: input.name?.trim() || void 0,
|
|
1700
|
+
baseUrl: input.baseUrl,
|
|
1701
|
+
oauth2: input.oauth2Source
|
|
1263
1702
|
});
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
sourceId,
|
|
1268
|
-
sourceScope: ScopeId.make(sourceScope),
|
|
1269
|
-
slotKey: slot
|
|
1270
|
-
});
|
|
1271
|
-
})
|
|
1272
|
-
};
|
|
1703
|
+
}
|
|
1704
|
+
return yield* configureOpenApiSource(ctx, { id: sourceId, scope: sourceScope }, input);
|
|
1705
|
+
})
|
|
1273
1706
|
},
|
|
1274
1707
|
staticSources: (self) => [
|
|
1275
1708
|
{
|
|
@@ -1279,25 +1712,88 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1279
1712
|
tools: [
|
|
1280
1713
|
tool({
|
|
1281
1714
|
name: "previewSpec",
|
|
1282
|
-
description: "Preview an OpenAPI document before adding it as a source",
|
|
1715
|
+
description: "Preview an OpenAPI document before adding it as a source. Call this first when the user provides a spec URL/blob so you can inspect servers, auth schemes, operation count, tags, and credential slots before `addSource`. This agent-facing preview intentionally omits the full operations list; use `operationCount` and `tags` for full-size specs. Do not collect API keys or OAuth client secrets in chat; use `executor.coreTools.secrets.create` for those values.",
|
|
1283
1716
|
inputSchema: PreviewSpecInputStandardSchema,
|
|
1284
|
-
|
|
1717
|
+
outputSchema: PreviewSpecOutputStandardSchema,
|
|
1718
|
+
execute: (input) => self.previewSpec(input).pipe(
|
|
1719
|
+
Effect3.map((preview) => ToolResult.ok(staticPreviewOutput(preview))),
|
|
1720
|
+
Effect3.catchTags({
|
|
1721
|
+
OpenApiParseError: ({ message }) => Effect3.succeed(openApiToolFailure("openapi_parse_failed", message)),
|
|
1722
|
+
OpenApiExtractionError: ({ message }) => Effect3.succeed(openApiToolFailure("openapi_extraction_failed", message)),
|
|
1723
|
+
OpenApiOAuthError: ({ message }) => Effect3.succeed(openApiToolFailure("openapi_oauth_failed", message))
|
|
1724
|
+
})
|
|
1725
|
+
)
|
|
1726
|
+
}),
|
|
1727
|
+
tool({
|
|
1728
|
+
name: "getSource",
|
|
1729
|
+
description: "Inspect an existing OpenAPI source, including effective base URL, configured headers/query params, OAuth settings, and stored credential slots. Use this before repairing an existing source with `openapi.configureSource`, `secrets.create`, or `oauth.start`.",
|
|
1730
|
+
inputSchema: GetSourceInputStandardSchema,
|
|
1731
|
+
outputSchema: GetSourceOutputStandardSchema,
|
|
1732
|
+
execute: (input, { ctx }) => Effect3.map(
|
|
1733
|
+
self.getSource(input.namespace, resolveStaticScopeInput(ctx, input.scope)),
|
|
1734
|
+
(source) => ToolResult.ok({ source })
|
|
1735
|
+
)
|
|
1285
1736
|
}),
|
|
1286
1737
|
tool({
|
|
1287
1738
|
name: "addSource",
|
|
1288
|
-
description: "Add an OpenAPI source and register its operations as tools",
|
|
1739
|
+
description: "Add an OpenAPI source and register its operations as tools. Executor chooses the source install scope (local scope locally, organization scope in cloud) and returns it as `source`. Recommended flow: call `previewSpec`, choose or confirm namespace/name/baseUrl from the preview (baseUrl is only needed when the spec cannot infer one or the user wants an override), declare credential slots here for sensitive headers/query params, then call `secrets.create` and `openapi.configureSource` with the user's chosen credential scope for per-scope bindings. Use `oauth.start` with `credentialScope` set to the user's chosen personal or organization credential scope for browser OAuth sign-in.",
|
|
1289
1740
|
annotations: {
|
|
1290
1741
|
requiresApproval: true,
|
|
1291
1742
|
approvalDescription: "Add an OpenAPI source"
|
|
1292
1743
|
},
|
|
1293
1744
|
inputSchema: AddSourceInputStandardSchema,
|
|
1294
1745
|
outputSchema: AddSourceOutputStandardSchema,
|
|
1295
|
-
execute: (input) =>
|
|
1746
|
+
execute: (input, { ctx }) => {
|
|
1747
|
+
const sourceScope = defaultSourceInstallScopeId(ctx.scopes);
|
|
1748
|
+
if (sourceScope === null) {
|
|
1749
|
+
return Effect3.succeed(
|
|
1750
|
+
openApiToolFailure(
|
|
1751
|
+
"source_scope_unavailable",
|
|
1752
|
+
"Cannot add an OpenAPI source because this executor has no source install scope."
|
|
1753
|
+
)
|
|
1754
|
+
);
|
|
1755
|
+
}
|
|
1756
|
+
return self.addSpec({ ...input, scope: sourceScope }).pipe(
|
|
1757
|
+
Effect3.map(
|
|
1758
|
+
(result) => ToolResult.ok({
|
|
1759
|
+
...result,
|
|
1760
|
+
source: { id: result.sourceId, scope: sourceScope }
|
|
1761
|
+
})
|
|
1762
|
+
),
|
|
1763
|
+
Effect3.catchTags({
|
|
1764
|
+
OpenApiParseError: ({ message }) => Effect3.succeed(openApiToolFailure("openapi_parse_failed", message)),
|
|
1765
|
+
OpenApiExtractionError: ({ message }) => Effect3.succeed(openApiToolFailure("openapi_extraction_failed", message)),
|
|
1766
|
+
OpenApiOAuthError: ({ message }) => Effect3.succeed(openApiToolFailure("openapi_oauth_failed", message))
|
|
1767
|
+
})
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
}),
|
|
1771
|
+
tool({
|
|
1772
|
+
name: "configureSource",
|
|
1773
|
+
description: 'Configure an existing OpenAPI source with concrete fields. Use `source` returned by `openapi.addSource` or `sources.list`. The top-level `scope` is the credential target scope for bindings; in cloud, choose the user or organization credential scope deliberately. Pass secret refs as `{kind:"secret", secretId}` and OAuth connections as `{kind:"connection", connectionId}`.',
|
|
1774
|
+
annotations: {
|
|
1775
|
+
requiresApproval: true,
|
|
1776
|
+
approvalDescription: "Configure an OpenAPI source"
|
|
1777
|
+
},
|
|
1778
|
+
inputSchema: OpenApiConfigureSourceInputStandardSchema,
|
|
1779
|
+
outputSchema: OpenApiConfigureSourceOutputStandardSchema,
|
|
1780
|
+
execute: (input, { ctx }) => {
|
|
1781
|
+
const { source, ...config } = input;
|
|
1782
|
+
const sourceScope = resolveStaticScopeInput(ctx, source.scope);
|
|
1783
|
+
const targetScope = resolveStaticScopeInput(ctx, config.scope);
|
|
1784
|
+
return Effect3.map(
|
|
1785
|
+
self.configure(
|
|
1786
|
+
{ id: source.id, scope: sourceScope },
|
|
1787
|
+
{ ...config, scope: targetScope }
|
|
1788
|
+
),
|
|
1789
|
+
(result) => ToolResult.ok({ result })
|
|
1790
|
+
);
|
|
1791
|
+
}
|
|
1296
1792
|
})
|
|
1297
1793
|
]
|
|
1298
1794
|
}
|
|
1299
1795
|
],
|
|
1300
|
-
invokeTool: ({ ctx, toolRow, args }) =>
|
|
1796
|
+
invokeTool: ({ ctx, toolRow, args }) => Effect3.gen(function* () {
|
|
1301
1797
|
const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer;
|
|
1302
1798
|
const toolScope = toolRow.scope_id;
|
|
1303
1799
|
const op = yield* ctx.storage.getOperationByToolId(toolRow.id, toolScope);
|
|
@@ -1337,7 +1833,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1337
1833
|
});
|
|
1338
1834
|
}
|
|
1339
1835
|
const accessToken = yield* ctx.connections.accessTokenAtScope(connection.connectionId, connection.scopeId).pipe(
|
|
1340
|
-
|
|
1836
|
+
Effect3.mapError(
|
|
1341
1837
|
() => new OpenApiOAuthError({
|
|
1342
1838
|
message: "OAuth connection resolution failed"
|
|
1343
1839
|
})
|
|
@@ -1353,16 +1849,29 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1353
1849
|
resolvedQueryParams,
|
|
1354
1850
|
httpClientLayer
|
|
1355
1851
|
);
|
|
1356
|
-
|
|
1852
|
+
const ok = result.status >= 200 && result.status < 300;
|
|
1853
|
+
if (!ok) {
|
|
1854
|
+
return ToolResult.fail({
|
|
1855
|
+
code: "upstream_http_error",
|
|
1856
|
+
status: result.status,
|
|
1857
|
+
message: extractUpstreamMessage(result.error, result.status),
|
|
1858
|
+
details: result.error
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
return ToolResult.ok({
|
|
1862
|
+
status: result.status,
|
|
1863
|
+
headers: result.headers,
|
|
1864
|
+
data: result.data
|
|
1865
|
+
});
|
|
1357
1866
|
}),
|
|
1358
|
-
resolveAnnotations: ({ ctx, sourceId, toolRows }) =>
|
|
1867
|
+
resolveAnnotations: ({ ctx, sourceId, toolRows }) => Effect3.gen(function* () {
|
|
1359
1868
|
const scopes = /* @__PURE__ */ new Set();
|
|
1360
1869
|
for (const row of toolRows) {
|
|
1361
1870
|
scopes.add(row.scope_id);
|
|
1362
1871
|
}
|
|
1363
|
-
const entries = yield*
|
|
1872
|
+
const entries = yield* Effect3.forEach(
|
|
1364
1873
|
[...scopes],
|
|
1365
|
-
(scope) =>
|
|
1874
|
+
(scope) => Effect3.gen(function* () {
|
|
1366
1875
|
const ops = yield* ctx.storage.listOperationsBySource(sourceId, scope);
|
|
1367
1876
|
const byId = /* @__PURE__ */ new Map();
|
|
1368
1877
|
for (const op of ops) byId.set(op.toolId, op.binding);
|
|
@@ -1380,9 +1889,9 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1380
1889
|
}
|
|
1381
1890
|
return out;
|
|
1382
1891
|
}),
|
|
1383
|
-
removeSource: ({ ctx, sourceId, scope }) =>
|
|
1892
|
+
removeSource: ({ ctx, sourceId, scope }) => Effect3.gen(function* () {
|
|
1384
1893
|
yield* ctx.transaction(
|
|
1385
|
-
|
|
1894
|
+
Effect3.gen(function* () {
|
|
1386
1895
|
yield* ctx.credentialBindings.removeForSource({
|
|
1387
1896
|
pluginId: OPENAPI_PLUGIN_ID,
|
|
1388
1897
|
sourceId,
|
|
@@ -1397,8 +1906,8 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1397
1906
|
}),
|
|
1398
1907
|
// OpenAPI credential usages are reported by the core `credential_binding`
|
|
1399
1908
|
// table. Source storage carries only source-owned slot structure.
|
|
1400
|
-
usagesForSecret: () =>
|
|
1401
|
-
usagesForConnection: () =>
|
|
1909
|
+
usagesForSecret: () => Effect3.succeed([]),
|
|
1910
|
+
usagesForConnection: () => Effect3.succeed([]),
|
|
1402
1911
|
// Re-fetch the spec from its origin URL (captured at addSpec time)
|
|
1403
1912
|
// and replay the same parse → extract → upsertSource → register
|
|
1404
1913
|
// path used by addSpec. Sources without a stored URL surface a
|
|
@@ -1406,26 +1915,26 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1406
1915
|
// when `canRefresh: true`, so a raw-text source reaching here
|
|
1407
1916
|
// means stale UI state, which is worth surfacing to the caller.
|
|
1408
1917
|
refreshSource: ({ ctx, sourceId, scope }) => refreshSourceInternal(ctx, sourceId, scope),
|
|
1409
|
-
detect: ({ ctx, url }) =>
|
|
1918
|
+
detect: ({ ctx, url }) => Effect3.gen(function* () {
|
|
1410
1919
|
const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer;
|
|
1411
1920
|
const trimmed = url.trim();
|
|
1412
1921
|
if (!trimmed) return null;
|
|
1413
|
-
const parsed = yield*
|
|
1922
|
+
const parsed = yield* Effect3.try({
|
|
1414
1923
|
try: () => new URL(trimmed),
|
|
1415
1924
|
catch: (error) => error
|
|
1416
|
-
}).pipe(
|
|
1417
|
-
if (
|
|
1925
|
+
}).pipe(Effect3.option);
|
|
1926
|
+
if (Option3.isNone(parsed)) return null;
|
|
1418
1927
|
const specText = yield* resolveSpecText(trimmed).pipe(
|
|
1419
|
-
|
|
1420
|
-
|
|
1928
|
+
Effect3.provide(httpClientLayer),
|
|
1929
|
+
Effect3.catch(() => Effect3.succeed(null))
|
|
1421
1930
|
);
|
|
1422
1931
|
if (specText === null) return null;
|
|
1423
|
-
const doc = yield* parse(specText).pipe(
|
|
1932
|
+
const doc = yield* parse(specText).pipe(Effect3.catch(() => Effect3.succeed(null)));
|
|
1424
1933
|
if (!doc) return null;
|
|
1425
|
-
const result = yield* extract(doc).pipe(
|
|
1934
|
+
const result = yield* extract(doc).pipe(Effect3.catch(() => Effect3.succeed(null)));
|
|
1426
1935
|
if (!result) return null;
|
|
1427
|
-
const namespace =
|
|
1428
|
-
const name =
|
|
1936
|
+
const namespace = Option3.getOrElse(result.title, () => "api").toLowerCase().replace(/[^a-z0-9]+/g, "_");
|
|
1937
|
+
const name = Option3.getOrElse(result.title, () => namespace);
|
|
1429
1938
|
return SourceDetectionResult.make({
|
|
1430
1939
|
kind: "openapi",
|
|
1431
1940
|
confidence: "high",
|
|
@@ -1442,6 +1951,8 @@ export {
|
|
|
1442
1951
|
invoke,
|
|
1443
1952
|
invokeWithLayer,
|
|
1444
1953
|
annotationsForOperation,
|
|
1954
|
+
openapiSchema,
|
|
1955
|
+
makeDefaultOpenapiStore,
|
|
1445
1956
|
openApiPlugin
|
|
1446
1957
|
};
|
|
1447
|
-
//# sourceMappingURL=chunk-
|
|
1958
|
+
//# sourceMappingURL=chunk-NIKLYJ3X.js.map
|