@executor-js/plugin-openapi 1.5.17 → 1.5.18
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-U7AYB224.js → AddOpenApiSource-IBZQRCTW.js} +4 -4
- package/dist/{OpenApiAccountsPanel-GHFHHE6P.js → OpenApiAccountsPanel-U47OVLYG.js} +3 -3
- package/dist/{UpdateSpecSection-PLCBUU4I.js → UpdateSpecSection-FFYVB3VH.js} +3 -3
- package/dist/{chunk-CPPTKUOW.js → chunk-2RNIMASA.js} +2 -2
- package/dist/{chunk-CKBX4SXK.js → chunk-5IDND4UF.js} +2 -2
- package/dist/{chunk-UEKOP6NZ.js → chunk-ELCKZJE4.js} +234 -210
- package/dist/chunk-ELCKZJE4.js.map +1 -0
- package/dist/{chunk-KVPUDOJZ.js → chunk-R3X27XS6.js} +587 -77
- package/dist/chunk-R3X27XS6.js.map +1 -0
- package/dist/client.js +3 -3
- package/dist/core.js +27 -3
- package/dist/core.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/sdk/backing.d.ts +91 -1
- package/dist/sdk/definitions.d.ts +33 -1
- package/dist/sdk/extract.d.ts +66 -0
- package/dist/sdk/index.d.ts +3 -2
- package/dist/sdk/split.d.ts +84 -0
- package/dist/sdk/store.d.ts +19 -0
- package/package.json +3 -3
- package/dist/chunk-KVPUDOJZ.js.map +0 -1
- package/dist/chunk-UEKOP6NZ.js.map +0 -1
- /package/dist/{AddOpenApiSource-U7AYB224.js.map → AddOpenApiSource-IBZQRCTW.js.map} +0 -0
- /package/dist/{OpenApiAccountsPanel-GHFHHE6P.js.map → OpenApiAccountsPanel-U47OVLYG.js.map} +0 -0
- /package/dist/{UpdateSpecSection-PLCBUU4I.js.map → UpdateSpecSection-FFYVB3VH.js.map} +0 -0
- /package/dist/{chunk-CPPTKUOW.js.map → chunk-2RNIMASA.js.map} +0 -0
- /package/dist/{chunk-CKBX4SXK.js.map → chunk-5IDND4UF.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deriveAuthenticationTemplateFromPreview,
|
|
3
3
|
firstBaseUrlForPreview
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5IDND4UF.js";
|
|
5
5
|
import {
|
|
6
6
|
openApiPresets
|
|
7
7
|
} from "./chunk-QQFCICLX.js";
|
|
@@ -11,13 +11,19 @@ import {
|
|
|
11
11
|
OpenApiInvocationError,
|
|
12
12
|
OpenApiParseError,
|
|
13
13
|
OperationBinding,
|
|
14
|
+
buildInputSchema,
|
|
15
|
+
compileToolDefinitions,
|
|
14
16
|
extract,
|
|
15
17
|
normalizeOpenApiAuthInputs,
|
|
16
18
|
parse,
|
|
19
|
+
parseEntry,
|
|
17
20
|
previewSpecText,
|
|
18
21
|
resolveServerUrl,
|
|
19
|
-
resolveSpecText
|
|
20
|
-
|
|
22
|
+
resolveSpecText,
|
|
23
|
+
streamOperationBindings,
|
|
24
|
+
streamOperationBindingsFromStructure,
|
|
25
|
+
structuralSplit
|
|
26
|
+
} from "./chunk-R3X27XS6.js";
|
|
21
27
|
|
|
22
28
|
// src/sdk/config.ts
|
|
23
29
|
import { Option, Schema } from "effect";
|
|
@@ -78,7 +84,12 @@ var toJsonRecord = (value) => value;
|
|
|
78
84
|
var OperationStorage = Schema2.Struct({
|
|
79
85
|
integration: Schema2.String,
|
|
80
86
|
toolName: Schema2.String,
|
|
81
|
-
binding: Schema2.Unknown
|
|
87
|
+
binding: Schema2.Unknown,
|
|
88
|
+
// Resolved tool description (operation description / summary / method+path
|
|
89
|
+
// fallback), persisted so the serve path can rebuild the tool def without
|
|
90
|
+
// re-parsing the spec. Optional: legacy rows predate it and resolve via the
|
|
91
|
+
// parse fallback.
|
|
92
|
+
description: Schema2.optional(Schema2.String)
|
|
82
93
|
});
|
|
83
94
|
var decodeOperationStorage = Schema2.decodeUnknownOption(OperationStorage);
|
|
84
95
|
var rowToOperation = (row) => {
|
|
@@ -90,7 +101,8 @@ var rowToOperation = (row) => {
|
|
|
90
101
|
toolName: operation.toolName,
|
|
91
102
|
binding: decodeBinding(
|
|
92
103
|
typeof operation.binding === "string" ? decodeBindingJson(operation.binding) : operation.binding
|
|
93
|
-
)
|
|
104
|
+
),
|
|
105
|
+
...operation.description !== void 0 ? { description: operation.description } : {}
|
|
94
106
|
};
|
|
95
107
|
};
|
|
96
108
|
var stableKeyHash = (value) => {
|
|
@@ -106,11 +118,13 @@ var stableKeyHash = (value) => {
|
|
|
106
118
|
var operationKey = (integration, toolName) => `${OPERATION_KEY_VERSION}.${stableKeyHash(integration)}.${stableKeyHash(toolName)}`;
|
|
107
119
|
var legacyOperationKey = (integration, toolName) => `${integration}.${toolName}`;
|
|
108
120
|
var specBlobKey = (specHash) => `spec/${specHash}`;
|
|
121
|
+
var defsBlobKey = (specHash) => `defs/${specHash}`;
|
|
109
122
|
var makeDefaultOpenapiStore = ({ pluginStorage, blobs }) => {
|
|
110
123
|
const operationData = (operation) => ({
|
|
111
124
|
integration: operation.integration,
|
|
112
125
|
toolName: operation.toolName,
|
|
113
|
-
binding: toJsonRecord(encodeBinding(operation.binding))
|
|
126
|
+
binding: toJsonRecord(encodeBinding(operation.binding)),
|
|
127
|
+
...operation.description !== void 0 ? { description: operation.description } : {}
|
|
114
128
|
});
|
|
115
129
|
const listRows = (integration) => pluginStorage.list({ collection: OPERATION_COLLECTION }).pipe(
|
|
116
130
|
Effect.map(
|
|
@@ -124,18 +138,20 @@ var makeDefaultOpenapiStore = ({ pluginStorage, blobs }) => {
|
|
|
124
138
|
entries: rows.map((row) => ({ collection: OPERATION_COLLECTION, key: row.key }))
|
|
125
139
|
});
|
|
126
140
|
});
|
|
141
|
+
const appendOperations = (integration, operations) => pluginStorage.putMany({
|
|
142
|
+
owner: STORE_OWNER,
|
|
143
|
+
entries: operations.map((operation) => ({
|
|
144
|
+
collection: OPERATION_COLLECTION,
|
|
145
|
+
key: operationKey(integration, operation.toolName),
|
|
146
|
+
data: operationData(operation)
|
|
147
|
+
}))
|
|
148
|
+
});
|
|
127
149
|
return {
|
|
128
150
|
putOperations: (integration, operations) => Effect.gen(function* () {
|
|
129
151
|
yield* removeOperations(integration);
|
|
130
|
-
yield*
|
|
131
|
-
owner: STORE_OWNER,
|
|
132
|
-
entries: operations.map((operation) => ({
|
|
133
|
-
collection: OPERATION_COLLECTION,
|
|
134
|
-
key: operationKey(integration, operation.toolName),
|
|
135
|
-
data: operationData(operation)
|
|
136
|
-
}))
|
|
137
|
-
});
|
|
152
|
+
yield* appendOperations(integration, operations);
|
|
138
153
|
}),
|
|
154
|
+
appendOperations,
|
|
139
155
|
getOperation: (integration, toolName) => Effect.gen(function* () {
|
|
140
156
|
const row = yield* pluginStorage.get({
|
|
141
157
|
collection: OPERATION_COLLECTION,
|
|
@@ -155,7 +171,9 @@ var makeDefaultOpenapiStore = ({ pluginStorage, blobs }) => {
|
|
|
155
171
|
),
|
|
156
172
|
removeOperations,
|
|
157
173
|
putSpec: (specHash, specText) => blobs.put(specBlobKey(specHash), specText, { owner: STORE_OWNER }),
|
|
158
|
-
getSpec: (specHash) => blobs.get(specBlobKey(specHash))
|
|
174
|
+
getSpec: (specHash) => blobs.get(specBlobKey(specHash)),
|
|
175
|
+
putDefs: (specHash, defsJson) => blobs.put(defsBlobKey(specHash), defsJson, { owner: STORE_OWNER }),
|
|
176
|
+
getDefs: (specHash) => blobs.get(defsBlobKey(specHash))
|
|
159
177
|
};
|
|
160
178
|
};
|
|
161
179
|
|
|
@@ -656,160 +674,13 @@ var annotationsForOperation = (method, pathTemplate) => {
|
|
|
656
674
|
};
|
|
657
675
|
|
|
658
676
|
// src/sdk/backing.ts
|
|
659
|
-
import { Effect as Effect3, Option as
|
|
677
|
+
import { Effect as Effect3, Option as Option4, Schema as Schema3 } from "effect";
|
|
660
678
|
import {
|
|
661
679
|
ToolFileJsonSchema,
|
|
662
680
|
ToolName,
|
|
663
681
|
ToolResult,
|
|
664
682
|
authToolFailure
|
|
665
683
|
} from "@executor-js/sdk/core";
|
|
666
|
-
|
|
667
|
-
// src/sdk/definitions.ts
|
|
668
|
-
import { Option as Option4 } from "effect";
|
|
669
|
-
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);
|
|
670
|
-
var normalizeWord = (value) => value.toLowerCase();
|
|
671
|
-
var toCamelCase = (value) => {
|
|
672
|
-
const words = splitWords(value).map(normalizeWord);
|
|
673
|
-
if (words.length === 0) return "tool";
|
|
674
|
-
const [first, ...rest] = words;
|
|
675
|
-
return `${first}${rest.map((p) => `${p[0]?.toUpperCase() ?? ""}${p.slice(1)}`).join("")}`;
|
|
676
|
-
};
|
|
677
|
-
var toPascalCase = (value) => {
|
|
678
|
-
const camel = toCamelCase(value);
|
|
679
|
-
return `${camel[0]?.toUpperCase() ?? ""}${camel.slice(1)}`;
|
|
680
|
-
};
|
|
681
|
-
var VERSION_SEGMENT_REGEX = /^v\d+(?:[._-]\d+)?$/i;
|
|
682
|
-
var IGNORED_PATH_SEGMENTS = /* @__PURE__ */ new Set(["api"]);
|
|
683
|
-
var pathSegmentsFromTemplate = (pathTemplate) => pathTemplate.split("/").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
684
|
-
var isPathParameterSegment = (segment) => segment.startsWith("{") && segment.endsWith("}");
|
|
685
|
-
var normalizeGroupSegment = (value) => {
|
|
686
|
-
const candidate = value?.trim();
|
|
687
|
-
if (!candidate) return null;
|
|
688
|
-
return toCamelCase(candidate);
|
|
689
|
-
};
|
|
690
|
-
var deriveVersionSegment = (pathTemplate) => pathSegmentsFromTemplate(pathTemplate).map((s) => s.toLowerCase()).find((s) => VERSION_SEGMENT_REGEX.test(s));
|
|
691
|
-
var derivePathGroup = (pathTemplate) => {
|
|
692
|
-
for (const segment of pathSegmentsFromTemplate(pathTemplate)) {
|
|
693
|
-
const lower = segment.toLowerCase();
|
|
694
|
-
if (VERSION_SEGMENT_REGEX.test(lower)) continue;
|
|
695
|
-
if (IGNORED_PATH_SEGMENTS.has(lower)) continue;
|
|
696
|
-
if (isPathParameterSegment(segment)) continue;
|
|
697
|
-
return normalizeGroupSegment(segment) ?? "root";
|
|
698
|
-
}
|
|
699
|
-
return "root";
|
|
700
|
-
};
|
|
701
|
-
var splitOperationIdSegments = (value) => value.split(/[/.]+/).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
702
|
-
var deriveLeafSeed = (operationId, group) => {
|
|
703
|
-
const segments = splitOperationIdSegments(operationId);
|
|
704
|
-
if (segments.length > 1) {
|
|
705
|
-
const [first, ...rest] = segments;
|
|
706
|
-
if ((normalizeGroupSegment(first) ?? first) === group && rest.length > 0) {
|
|
707
|
-
return rest.join(" ");
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
return operationId;
|
|
711
|
-
};
|
|
712
|
-
var fallbackLeafSeed = (method, pathTemplate, group) => {
|
|
713
|
-
const relevantSegments = pathSegmentsFromTemplate(pathTemplate).filter((s) => !VERSION_SEGMENT_REGEX.test(s.toLowerCase())).filter((s) => !IGNORED_PATH_SEGMENTS.has(s.toLowerCase())).filter((s) => !isPathParameterSegment(s)).map((s) => normalizeGroupSegment(s) ?? s).filter((s) => s !== group);
|
|
714
|
-
const segmentSuffix = relevantSegments.map((s) => toPascalCase(s)).join("");
|
|
715
|
-
return `${method}${segmentSuffix || "Operation"}`;
|
|
716
|
-
};
|
|
717
|
-
var deriveLeaf = (operationId, method, pathTemplate, group) => {
|
|
718
|
-
const preferred = toCamelCase(deriveLeafSeed(operationId, group));
|
|
719
|
-
if (preferred.length > 0 && preferred !== group) return preferred;
|
|
720
|
-
return toCamelCase(fallbackLeafSeed(method, pathTemplate, group));
|
|
721
|
-
};
|
|
722
|
-
var resolveCollisions = (definitions) => {
|
|
723
|
-
const staged = definitions.map((d) => ({ ...d }));
|
|
724
|
-
const applyFactory = (items, factory) => {
|
|
725
|
-
const byPath = /* @__PURE__ */ new Map();
|
|
726
|
-
for (const item of items) {
|
|
727
|
-
const bucket = byPath.get(item.toolPath) ?? [];
|
|
728
|
-
bucket.push(item);
|
|
729
|
-
byPath.set(item.toolPath, bucket);
|
|
730
|
-
}
|
|
731
|
-
for (const bucket of byPath.values()) {
|
|
732
|
-
if (bucket.length < 2) continue;
|
|
733
|
-
for (const d of bucket) {
|
|
734
|
-
d.toolPath = factory(d);
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
};
|
|
738
|
-
applyFactory(
|
|
739
|
-
staged,
|
|
740
|
-
(d) => d.versionSegment ? `${d.group}.${d.versionSegment}.${d.leaf}` : d.toolPath
|
|
741
|
-
);
|
|
742
|
-
applyFactory(staged, (d) => {
|
|
743
|
-
const prefix = d.versionSegment ? `${d.group}.${d.versionSegment}` : d.group;
|
|
744
|
-
return `${prefix}.${d.leaf}${toPascalCase(d.method)}`;
|
|
745
|
-
});
|
|
746
|
-
applyFactory(staged, (d) => {
|
|
747
|
-
const prefix = d.versionSegment ? `${d.group}.${d.versionSegment}` : d.group;
|
|
748
|
-
return `${prefix}.${d.leaf}${toPascalCase(d.method)}${d.operationHash.slice(0, 8)}`;
|
|
749
|
-
});
|
|
750
|
-
return staged.map((d) => ({
|
|
751
|
-
toolPath: d.toolPath,
|
|
752
|
-
group: d.group,
|
|
753
|
-
leaf: d.leaf,
|
|
754
|
-
operationIndex: d.operationIndex,
|
|
755
|
-
operation: d.operation
|
|
756
|
-
}));
|
|
757
|
-
};
|
|
758
|
-
var stableHash = (value) => {
|
|
759
|
-
const str = JSON.stringify(value, Object.keys(value).sort());
|
|
760
|
-
let hash = 0;
|
|
761
|
-
for (let i = 0; i < str.length; i++) {
|
|
762
|
-
hash = (hash << 5) - hash + str.charCodeAt(i) | 0;
|
|
763
|
-
}
|
|
764
|
-
return Math.abs(hash).toString(36).padStart(8, "0");
|
|
765
|
-
};
|
|
766
|
-
var compileToolDefinitions = (operations) => {
|
|
767
|
-
const raw = operations.map((op, index) => {
|
|
768
|
-
const operationId = op.operationId;
|
|
769
|
-
const explicitToolPath = Option4.getOrUndefined(op.toolPath);
|
|
770
|
-
if (explicitToolPath) {
|
|
771
|
-
const [group2 = "root", ...leafParts] = explicitToolPath.split(".").filter(Boolean);
|
|
772
|
-
const leaf2 = leafParts.join(".") || group2;
|
|
773
|
-
const versionSegment2 = deriveVersionSegment(op.pathTemplate);
|
|
774
|
-
const operationHash2 = stableHash({
|
|
775
|
-
method: op.method,
|
|
776
|
-
path: op.pathTemplate,
|
|
777
|
-
operationId
|
|
778
|
-
});
|
|
779
|
-
return {
|
|
780
|
-
toolPath: explicitToolPath,
|
|
781
|
-
group: group2,
|
|
782
|
-
leaf: leaf2,
|
|
783
|
-
versionSegment: versionSegment2,
|
|
784
|
-
method: op.method,
|
|
785
|
-
operationHash: operationHash2,
|
|
786
|
-
operationIndex: index,
|
|
787
|
-
operation: op
|
|
788
|
-
};
|
|
789
|
-
}
|
|
790
|
-
const group = normalizeGroupSegment(op.tags[0]) ?? derivePathGroup(op.pathTemplate);
|
|
791
|
-
const leaf = deriveLeaf(operationId, op.method, op.pathTemplate, group);
|
|
792
|
-
const versionSegment = deriveVersionSegment(op.pathTemplate);
|
|
793
|
-
const operationHash = stableHash({
|
|
794
|
-
method: op.method,
|
|
795
|
-
path: op.pathTemplate,
|
|
796
|
-
operationId
|
|
797
|
-
});
|
|
798
|
-
return {
|
|
799
|
-
toolPath: `${group}.${leaf}`,
|
|
800
|
-
group,
|
|
801
|
-
leaf,
|
|
802
|
-
versionSegment,
|
|
803
|
-
method: op.method,
|
|
804
|
-
operationHash,
|
|
805
|
-
operationIndex: index,
|
|
806
|
-
operation: op
|
|
807
|
-
};
|
|
808
|
-
});
|
|
809
|
-
return resolveCollisions(raw).sort((a, b) => a.toolPath.localeCompare(b.toolPath));
|
|
810
|
-
};
|
|
811
|
-
|
|
812
|
-
// src/sdk/backing.ts
|
|
813
684
|
var STRINGIFIED_BODY_CAP = 1024;
|
|
814
685
|
var UpstreamMessageBody = Schema3.Struct({ message: Schema3.String });
|
|
815
686
|
var UpstreamErrorMessageBody = Schema3.Struct({ errorMessage: Schema3.String });
|
|
@@ -847,11 +718,11 @@ var extractOpenApiUpstreamMessage = (body, status) => {
|
|
|
847
718
|
if (typeof body === "string") {
|
|
848
719
|
return body.length > 0 ? body : `Upstream returned HTTP ${status}`;
|
|
849
720
|
}
|
|
850
|
-
const nested =
|
|
851
|
-
const messageBody =
|
|
852
|
-
const errorMessageBody =
|
|
853
|
-
const errorsBody =
|
|
854
|
-
const descriptionBody =
|
|
721
|
+
const nested = Option4.getOrUndefined(decodeUpstreamNestedErrorBody(body));
|
|
722
|
+
const messageBody = Option4.getOrUndefined(decodeUpstreamMessageBody(body));
|
|
723
|
+
const errorMessageBody = Option4.getOrUndefined(decodeUpstreamErrorMessageBody(body));
|
|
724
|
+
const errorsBody = Option4.getOrUndefined(decodeUpstreamErrorsArrayBody(body));
|
|
725
|
+
const descriptionBody = Option4.getOrUndefined(decodeUpstreamDescriptionBody(body));
|
|
855
726
|
const arrayMessage = errorsBody?.errors.map(
|
|
856
727
|
({
|
|
857
728
|
detail,
|
|
@@ -926,11 +797,15 @@ var toBinding = (def) => OperationBinding.make({
|
|
|
926
797
|
});
|
|
927
798
|
var descriptionFor = (def) => {
|
|
928
799
|
const op = def.operation;
|
|
929
|
-
return
|
|
800
|
+
return Option4.getOrElse(
|
|
930
801
|
op.description,
|
|
931
|
-
() =>
|
|
802
|
+
() => Option4.getOrElse(op.summary, () => `${op.method.toUpperCase()} ${op.pathTemplate}`)
|
|
932
803
|
);
|
|
933
804
|
};
|
|
805
|
+
var FILE_OUTPUT_HINT = `Returns a ToolFile: the file bytes already decoded into { _tag: "ToolFile", mimeType, encoding, data, byteLength }. To display or forward it, pass the result's data straight to emit(result.data). Do not rebuild the envelope or read upstream fields like size.`;
|
|
806
|
+
var withFileEmitHint = (description, returnsFile) => returnsFile ? `${description}
|
|
807
|
+
|
|
808
|
+
${FILE_OUTPUT_HINT}` : description;
|
|
934
809
|
var compileOpenApiDocument = (doc) => Effect3.gen(function* () {
|
|
935
810
|
const result = yield* extract(doc);
|
|
936
811
|
const hoistedDefs = {};
|
|
@@ -942,38 +817,181 @@ var compileOpenApiDocument = (doc) => Effect3.gen(function* () {
|
|
|
942
817
|
return {
|
|
943
818
|
definitions: compileToolDefinitions(result.operations),
|
|
944
819
|
hoistedDefs,
|
|
945
|
-
title:
|
|
946
|
-
description:
|
|
820
|
+
title: Option4.getOrUndefined(result.title),
|
|
821
|
+
description: Option4.getOrUndefined(result.description)
|
|
947
822
|
};
|
|
948
823
|
});
|
|
949
824
|
var compileOpenApiSpec = (specText) => Effect3.gen(function* () {
|
|
950
825
|
const doc = yield* parse(specText);
|
|
951
826
|
return yield* compileOpenApiDocument(doc);
|
|
952
827
|
});
|
|
953
|
-
var openApiToolDefsFromCompiled = (compiled) => compiled.definitions.map(
|
|
954
|
-
(def
|
|
828
|
+
var openApiToolDefsFromCompiled = (compiled) => compiled.definitions.map((def) => {
|
|
829
|
+
const returnsFile = Option4.match(def.operation.responseBody, {
|
|
830
|
+
onNone: () => false,
|
|
831
|
+
onSome: (responseBody) => Option4.isSome(responseBody.fileHint)
|
|
832
|
+
});
|
|
833
|
+
return {
|
|
955
834
|
name: ToolName.make(def.toolPath),
|
|
956
|
-
description: descriptionFor(def),
|
|
957
|
-
inputSchema: normalizeOpenApiRefs(
|
|
958
|
-
outputSchema:
|
|
959
|
-
onNone: () => normalizeOpenApiRefs(Option5.getOrUndefined(def.operation.outputSchema)),
|
|
960
|
-
onSome: (responseBody) => Option5.isSome(responseBody.fileHint) ? ToolFileJsonSchema : normalizeOpenApiRefs(Option5.getOrUndefined(def.operation.outputSchema))
|
|
961
|
-
}),
|
|
835
|
+
description: withFileEmitHint(descriptionFor(def), returnsFile),
|
|
836
|
+
inputSchema: normalizeOpenApiRefs(Option4.getOrUndefined(def.operation.inputSchema)),
|
|
837
|
+
outputSchema: returnsFile ? ToolFileJsonSchema : normalizeOpenApiRefs(Option4.getOrUndefined(def.operation.outputSchema)),
|
|
962
838
|
annotations: annotationsForOperation(def.operation.method, def.operation.pathTemplate)
|
|
963
|
-
}
|
|
964
|
-
);
|
|
839
|
+
};
|
|
840
|
+
});
|
|
965
841
|
var openApiStoredOperationsFromCompiled = (integration, compiled) => compiled.definitions.map((def) => ({
|
|
966
842
|
integration,
|
|
967
843
|
toolName: def.toolPath,
|
|
968
|
-
binding: toBinding(def)
|
|
844
|
+
binding: toBinding(def),
|
|
845
|
+
description: descriptionFor(def)
|
|
969
846
|
}));
|
|
847
|
+
var buildDefsJson = (doc) => {
|
|
848
|
+
const schemas = doc.components?.schemas;
|
|
849
|
+
if (!schemas) return "{}";
|
|
850
|
+
let json = "{";
|
|
851
|
+
let first = true;
|
|
852
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
853
|
+
const serialized = JSON.stringify(normalizeOpenApiRefs(schema));
|
|
854
|
+
if (serialized === void 0) continue;
|
|
855
|
+
json += `${first ? "" : ","}${JSON.stringify(name)}:${serialized}`;
|
|
856
|
+
first = false;
|
|
857
|
+
}
|
|
858
|
+
return `${json}}`;
|
|
859
|
+
};
|
|
860
|
+
var buildDefsJsonStreaming = (structure) => {
|
|
861
|
+
let json = "{";
|
|
862
|
+
let first = true;
|
|
863
|
+
for (const range of structure.schemas) {
|
|
864
|
+
const entry = parseEntry(structure.text, range, 4);
|
|
865
|
+
if (!entry) continue;
|
|
866
|
+
const [name, schema] = entry;
|
|
867
|
+
const serialized = JSON.stringify(normalizeOpenApiRefs(schema));
|
|
868
|
+
if (serialized === void 0) continue;
|
|
869
|
+
json += `${first ? "" : ","}${JSON.stringify(name)}:${serialized}`;
|
|
870
|
+
first = false;
|
|
871
|
+
}
|
|
872
|
+
return `${json}}`;
|
|
873
|
+
};
|
|
874
|
+
var DefsJson = Schema3.Record(Schema3.String, Schema3.Unknown);
|
|
875
|
+
var decodeDefsJson = Schema3.decodeUnknownOption(Schema3.fromJsonString(DefsJson));
|
|
876
|
+
var toolDefFromStoredOperation = (op) => {
|
|
877
|
+
const binding = op.binding;
|
|
878
|
+
const returnsFile = Option4.match(binding.responseBody, {
|
|
879
|
+
onNone: () => false,
|
|
880
|
+
onSome: (responseBody) => Option4.isSome(responseBody.fileHint)
|
|
881
|
+
});
|
|
882
|
+
return {
|
|
883
|
+
name: ToolName.make(op.toolName),
|
|
884
|
+
description: withFileEmitHint(
|
|
885
|
+
op.description ?? `${binding.method.toUpperCase()} ${binding.pathTemplate}`,
|
|
886
|
+
returnsFile
|
|
887
|
+
),
|
|
888
|
+
inputSchema: normalizeOpenApiRefs(
|
|
889
|
+
buildInputSchema(
|
|
890
|
+
binding.parameters,
|
|
891
|
+
Option4.getOrUndefined(binding.requestBody),
|
|
892
|
+
binding.servers ?? []
|
|
893
|
+
)
|
|
894
|
+
),
|
|
895
|
+
outputSchema: returnsFile ? ToolFileJsonSchema : Option4.match(binding.responseBody, {
|
|
896
|
+
onNone: () => void 0,
|
|
897
|
+
onSome: (responseBody) => normalizeOpenApiRefs(Option4.getOrUndefined(responseBody.schema))
|
|
898
|
+
}),
|
|
899
|
+
annotations: annotationsForOperation(binding.method, binding.pathTemplate)
|
|
900
|
+
};
|
|
901
|
+
};
|
|
902
|
+
var compileAndPersistOpenApiOperations = ({
|
|
903
|
+
doc,
|
|
904
|
+
integration,
|
|
905
|
+
storage,
|
|
906
|
+
specHash,
|
|
907
|
+
chunkSize
|
|
908
|
+
}) => Effect3.gen(function* () {
|
|
909
|
+
yield* storage.removeOperations(integration);
|
|
910
|
+
const result = yield* streamOperationBindings(
|
|
911
|
+
doc,
|
|
912
|
+
chunkSize ?? 500,
|
|
913
|
+
(chunk) => storage.appendOperations(
|
|
914
|
+
integration,
|
|
915
|
+
chunk.map((item) => ({
|
|
916
|
+
integration,
|
|
917
|
+
toolName: item.toolName,
|
|
918
|
+
binding: item.binding,
|
|
919
|
+
description: item.description
|
|
920
|
+
}))
|
|
921
|
+
)
|
|
922
|
+
);
|
|
923
|
+
if (specHash != null) {
|
|
924
|
+
yield* storage.putDefs(specHash, buildDefsJson(doc));
|
|
925
|
+
}
|
|
926
|
+
return result;
|
|
927
|
+
});
|
|
928
|
+
var compileAndPersistOpenApiSpec = ({
|
|
929
|
+
specText,
|
|
930
|
+
integration,
|
|
931
|
+
storage,
|
|
932
|
+
specHash,
|
|
933
|
+
chunkSize
|
|
934
|
+
}) => Effect3.gen(function* () {
|
|
935
|
+
const doc = yield* parse(specText);
|
|
936
|
+
return yield* compileAndPersistOpenApiOperations({
|
|
937
|
+
doc,
|
|
938
|
+
integration,
|
|
939
|
+
storage,
|
|
940
|
+
specHash,
|
|
941
|
+
chunkSize
|
|
942
|
+
});
|
|
943
|
+
});
|
|
944
|
+
var compileAndPersistOpenApiSpecStreaming = ({
|
|
945
|
+
specText,
|
|
946
|
+
integration,
|
|
947
|
+
storage,
|
|
948
|
+
specHash,
|
|
949
|
+
chunkSize,
|
|
950
|
+
keepPathItem
|
|
951
|
+
}) => Effect3.gen(function* () {
|
|
952
|
+
const structure = structuralSplit(specText);
|
|
953
|
+
if (!structure) {
|
|
954
|
+
return yield* new OpenApiExtractionError({
|
|
955
|
+
message: "OpenAPI spec is not in the streamable block-YAML profile (no top-level `paths:` block); cannot stream-compile a spec this large in-band."
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
yield* storage.removeOperations(integration);
|
|
959
|
+
const result = yield* streamOperationBindingsFromStructure(
|
|
960
|
+
structure,
|
|
961
|
+
{ chunkSize: chunkSize ?? 500, keepPathItem },
|
|
962
|
+
(chunk) => storage.appendOperations(
|
|
963
|
+
integration,
|
|
964
|
+
chunk.map((item) => ({
|
|
965
|
+
integration,
|
|
966
|
+
toolName: item.toolName,
|
|
967
|
+
binding: item.binding,
|
|
968
|
+
description: item.description
|
|
969
|
+
}))
|
|
970
|
+
)
|
|
971
|
+
);
|
|
972
|
+
if (specHash != null) {
|
|
973
|
+
yield* storage.putDefs(specHash, buildDefsJsonStreaming(structure));
|
|
974
|
+
}
|
|
975
|
+
return result;
|
|
976
|
+
});
|
|
970
977
|
var loadOpenApiSpecText = (storage, config) => config.specHash != null ? storage.getSpec(config.specHash) : Effect3.succeed(null);
|
|
971
978
|
var resolveOpenApiBackedTools = ({
|
|
979
|
+
integration,
|
|
972
980
|
config,
|
|
973
981
|
storage
|
|
974
982
|
}) => Effect3.gen(function* () {
|
|
975
983
|
const openApiConfig = decodeOpenApiIntegrationConfig(config);
|
|
976
984
|
if (!openApiConfig) return { tools: [], definitions: {} };
|
|
985
|
+
if (openApiConfig.specHash != null) {
|
|
986
|
+
const defsJson = yield* storage.getDefs(openApiConfig.specHash);
|
|
987
|
+
if (defsJson != null) {
|
|
988
|
+
const definitions = Option4.getOrNull(decodeDefsJson(defsJson));
|
|
989
|
+
if (definitions != null) {
|
|
990
|
+
const ops = yield* storage.listOperations(String(integration.slug));
|
|
991
|
+
return { tools: ops.map(toolDefFromStoredOperation), definitions };
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
977
995
|
const specText = yield* loadOpenApiSpecText(storage, openApiConfig);
|
|
978
996
|
if (specText == null) return { tools: [], definitions: {} };
|
|
979
997
|
const compiled = yield* compileOpenApiSpec(specText).pipe(
|
|
@@ -989,7 +1007,7 @@ var invokeOpenApiBackedTool = (input) => Effect3.gen(function* () {
|
|
|
989
1007
|
const integration = input.toolRow.integration;
|
|
990
1008
|
const config = decodeOpenApiIntegrationConfig(input.credential.config);
|
|
991
1009
|
let binding = (yield* input.ctx.storage.getOperation(integration, input.toolRow.name))?.binding;
|
|
992
|
-
if (
|
|
1010
|
+
if (!binding && config) {
|
|
993
1011
|
const specText = yield* loadOpenApiSpecText(input.ctx.storage, config).pipe(
|
|
994
1012
|
Effect3.catch(() => Effect3.succeed(null))
|
|
995
1013
|
);
|
|
@@ -1078,7 +1096,7 @@ var resolveOpenApiBackedAnnotations = (input) => Effect3.gen(function* () {
|
|
|
1078
1096
|
});
|
|
1079
1097
|
|
|
1080
1098
|
// src/sdk/plugin.ts
|
|
1081
|
-
import { Effect as Effect4, Option as
|
|
1099
|
+
import { Effect as Effect4, Option as Option5, Schema as Schema4 } from "effect";
|
|
1082
1100
|
import {
|
|
1083
1101
|
IntegrationAlreadyExistsError,
|
|
1084
1102
|
IntegrationDetectionResult,
|
|
@@ -1209,18 +1227,18 @@ var openApiToolFailure = (code, message, details) => ToolResult2.fail({
|
|
|
1209
1227
|
...details === void 0 ? {} : { details }
|
|
1210
1228
|
});
|
|
1211
1229
|
var staticPreviewOutput = (preview) => ({
|
|
1212
|
-
title:
|
|
1213
|
-
version:
|
|
1230
|
+
title: Option5.getOrNull(preview.title),
|
|
1231
|
+
version: Option5.getOrNull(preview.version),
|
|
1214
1232
|
servers: preview.servers.map((server) => ({
|
|
1215
1233
|
url: server.url,
|
|
1216
|
-
description:
|
|
1217
|
-
variables:
|
|
1218
|
-
Object.entries(
|
|
1234
|
+
description: Option5.getOrNull(server.description),
|
|
1235
|
+
variables: Option5.getOrNull(server.variables) ? Object.fromEntries(
|
|
1236
|
+
Object.entries(Option5.getOrNull(server.variables) ?? {}).map(([name, variable]) => [
|
|
1219
1237
|
name,
|
|
1220
1238
|
{
|
|
1221
1239
|
default: variable.default,
|
|
1222
|
-
enum:
|
|
1223
|
-
description:
|
|
1240
|
+
enum: Option5.getOrNull(variable.enum),
|
|
1241
|
+
description: Option5.getOrNull(variable.description)
|
|
1224
1242
|
}
|
|
1225
1243
|
])
|
|
1226
1244
|
) : null
|
|
@@ -1230,25 +1248,25 @@ var staticPreviewOutput = (preview) => ({
|
|
|
1230
1248
|
securitySchemes: preview.securitySchemes.map((scheme) => ({
|
|
1231
1249
|
name: scheme.name,
|
|
1232
1250
|
type: scheme.type,
|
|
1233
|
-
scheme:
|
|
1234
|
-
bearerFormat:
|
|
1235
|
-
in:
|
|
1236
|
-
headerName:
|
|
1237
|
-
description:
|
|
1238
|
-
flows:
|
|
1239
|
-
authorizationCode:
|
|
1251
|
+
scheme: Option5.getOrNull(scheme.scheme),
|
|
1252
|
+
bearerFormat: Option5.getOrNull(scheme.bearerFormat),
|
|
1253
|
+
in: Option5.getOrNull(scheme.in),
|
|
1254
|
+
headerName: Option5.getOrNull(scheme.headerName),
|
|
1255
|
+
description: Option5.getOrNull(scheme.description),
|
|
1256
|
+
flows: Option5.isSome(scheme.flows) ? {
|
|
1257
|
+
authorizationCode: Option5.isSome(scheme.flows.value.authorizationCode) ? {
|
|
1240
1258
|
authorizationUrl: scheme.flows.value.authorizationCode.value.authorizationUrl,
|
|
1241
1259
|
tokenUrl: scheme.flows.value.authorizationCode.value.tokenUrl,
|
|
1242
|
-
refreshUrl:
|
|
1260
|
+
refreshUrl: Option5.getOrNull(scheme.flows.value.authorizationCode.value.refreshUrl),
|
|
1243
1261
|
scopes: scheme.flows.value.authorizationCode.value.scopes
|
|
1244
1262
|
} : null,
|
|
1245
|
-
clientCredentials:
|
|
1263
|
+
clientCredentials: Option5.isSome(scheme.flows.value.clientCredentials) ? {
|
|
1246
1264
|
tokenUrl: scheme.flows.value.clientCredentials.value.tokenUrl,
|
|
1247
|
-
refreshUrl:
|
|
1265
|
+
refreshUrl: Option5.getOrNull(scheme.flows.value.clientCredentials.value.refreshUrl),
|
|
1248
1266
|
scopes: scheme.flows.value.clientCredentials.value.scopes
|
|
1249
1267
|
} : null
|
|
1250
1268
|
} : null,
|
|
1251
|
-
openIdConnectUrl:
|
|
1269
|
+
openIdConnectUrl: Option5.getOrNull(scheme.openIdConnectUrl)
|
|
1252
1270
|
})),
|
|
1253
1271
|
authStrategies: preview.authStrategies,
|
|
1254
1272
|
headerPresets: preview.headerPresets,
|
|
@@ -1256,9 +1274,9 @@ var staticPreviewOutput = (preview) => ({
|
|
|
1256
1274
|
label: preset.label,
|
|
1257
1275
|
securitySchemeName: preset.securitySchemeName,
|
|
1258
1276
|
flow: preset.flow,
|
|
1259
|
-
authorizationUrl:
|
|
1277
|
+
authorizationUrl: Option5.getOrNull(preset.authorizationUrl),
|
|
1260
1278
|
tokenUrl: preset.tokenUrl,
|
|
1261
|
-
refreshUrl:
|
|
1279
|
+
refreshUrl: Option5.getOrNull(preset.refreshUrl),
|
|
1262
1280
|
scopes: preset.scopes,
|
|
1263
1281
|
identityScopes: preset.identityScopes
|
|
1264
1282
|
}))
|
|
@@ -1344,6 +1362,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1344
1362
|
} : derivedAuthenticationTemplate && derivedAuthenticationTemplate.length > 0 ? { authenticationTemplate: derivedAuthenticationTemplate } : {}
|
|
1345
1363
|
};
|
|
1346
1364
|
yield* ctx.storage.putSpec(specHash, resolved.specText);
|
|
1365
|
+
yield* ctx.storage.putDefs(specHash, JSON.stringify(compiled.hoistedDefs));
|
|
1347
1366
|
yield* ctx.transaction(
|
|
1348
1367
|
Effect4.gen(function* () {
|
|
1349
1368
|
yield* ctx.core.integrations.register({
|
|
@@ -1382,6 +1401,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1382
1401
|
const nextNames = new Set(compiled.definitions.map((def) => def.toolPath));
|
|
1383
1402
|
const specHash = yield* sha256Hex(resolved.specText);
|
|
1384
1403
|
yield* ctx.storage.putSpec(specHash, resolved.specText);
|
|
1404
|
+
yield* ctx.storage.putDefs(specHash, JSON.stringify(compiled.hoistedDefs));
|
|
1385
1405
|
const nextConfig = {
|
|
1386
1406
|
...current,
|
|
1387
1407
|
specHash,
|
|
@@ -1543,7 +1563,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1543
1563
|
// operation bindings invokeTool needs are persisted at addSpec time; this
|
|
1544
1564
|
// hook only shapes the per-connection ToolDefs from the spec blob the
|
|
1545
1565
|
// catalog config points at.
|
|
1546
|
-
resolveTools: ({ config, storage }) => resolveOpenApiBackedTools({ config, storage }),
|
|
1566
|
+
resolveTools: ({ integration, config, storage }) => resolveOpenApiBackedTools({ integration, config, storage }),
|
|
1547
1567
|
invokeTool: ({ ctx: invokeCtx, toolRow, credential, args }) => {
|
|
1548
1568
|
const httpClientLayer = options?.httpClientLayer ?? invokeCtx.httpClientLayer;
|
|
1549
1569
|
return invokeOpenApiBackedTool({
|
|
@@ -1571,7 +1591,7 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1571
1591
|
try: () => new URL(trimmed),
|
|
1572
1592
|
catch: (error) => error
|
|
1573
1593
|
}).pipe(Effect4.option);
|
|
1574
|
-
if (
|
|
1594
|
+
if (Option5.isNone(parsed)) return null;
|
|
1575
1595
|
const specText = yield* resolveSpecText(trimmed).pipe(
|
|
1576
1596
|
Effect4.provide(httpClientLayer),
|
|
1577
1597
|
Effect4.catch(() => Effect4.succeed(null))
|
|
@@ -1581,8 +1601,8 @@ var openApiPlugin = definePlugin((options) => {
|
|
|
1581
1601
|
if (!doc) return null;
|
|
1582
1602
|
const result = yield* extract(doc).pipe(Effect4.catch(() => Effect4.succeed(null)));
|
|
1583
1603
|
if (!result) return null;
|
|
1584
|
-
const slug =
|
|
1585
|
-
const name =
|
|
1604
|
+
const slug = Option5.getOrElse(result.title, () => "api").toLowerCase().replace(/[^a-z0-9]+/g, "_");
|
|
1605
|
+
const name = Option5.getOrElse(result.title, () => slug);
|
|
1586
1606
|
return IntegrationDetectionResult.make({
|
|
1587
1607
|
kind: "openapi",
|
|
1588
1608
|
confidence: "high",
|
|
@@ -1609,10 +1629,14 @@ export {
|
|
|
1609
1629
|
compileOpenApiSpec,
|
|
1610
1630
|
openApiToolDefsFromCompiled,
|
|
1611
1631
|
openApiStoredOperationsFromCompiled,
|
|
1632
|
+
buildDefsJsonStreaming,
|
|
1633
|
+
compileAndPersistOpenApiOperations,
|
|
1634
|
+
compileAndPersistOpenApiSpec,
|
|
1635
|
+
compileAndPersistOpenApiSpecStreaming,
|
|
1612
1636
|
loadOpenApiSpecText,
|
|
1613
1637
|
resolveOpenApiBackedTools,
|
|
1614
1638
|
invokeOpenApiBackedTool,
|
|
1615
1639
|
resolveOpenApiBackedAnnotations,
|
|
1616
1640
|
openApiPlugin
|
|
1617
1641
|
};
|
|
1618
|
-
//# sourceMappingURL=chunk-
|
|
1642
|
+
//# sourceMappingURL=chunk-ELCKZJE4.js.map
|