apps 0.0.1-beta.0 → 0.0.1-beta.2
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/README.md +97 -4
- package/framework-reference.json +1 -1
- package/js/browser-XIPJGLH2.js +65 -0
- package/js/{chunk-SBKHUC5L.js → chunk-4LPG6RCH.js} +2 -2
- package/js/chunk-5MQZEB6Y.js +172 -0
- package/js/{chunk-7JXHF5IF.js → chunk-BMOIAIVR.js} +1 -1
- package/js/chunk-CZ7CSFO4.js +39 -0
- package/js/chunk-D47C7KG5.js +172 -0
- package/js/{chunk-YDR4CPJA.js → chunk-EVJUVWN2.js} +8 -8
- package/js/chunk-FDNTX5QJ.js +78 -0
- package/js/{chunk-2OTCEKL2.js → chunk-FW5HBOIK.js} +2352 -1493
- package/js/{chunk-EP6AEUZO.js → chunk-FZJOYIZO.js} +1 -1
- package/js/{chunk-VFUZI3NY.js → chunk-HDJH3RPR.js} +4 -4
- package/js/{chunk-WIDTG42X.js → chunk-HDTGZWP2.js} +79 -26
- package/js/{chunk-Q2FD5IBM.js → chunk-J7O55ZV7.js} +298 -37
- package/js/{chunk-X3YBZCJW.js → chunk-JN55AYQH.js} +8 -41
- package/js/chunk-LGIYBDWA.js +85 -0
- package/js/{chunk-D6BKYP2L.js → chunk-M6ZRRIBI.js} +4 -4
- package/js/{chunk-HP7E42X6.js → chunk-MYYEW3RA.js} +767 -249
- package/js/{chunk-3ANFZFCV.js → chunk-OHRT55C4.js} +15 -15
- package/js/{chunk-R6JMJSVT.js → chunk-PLCMJREA.js} +2 -2
- package/js/{chunk-C24KEZXR.js → chunk-PYUYJRSK.js} +36 -2
- package/js/{chunk-W7Q5EOTS.js → chunk-QKHR7BMF.js} +32 -32
- package/js/{chunk-KWTCHVLT.js → chunk-RN2MXB4R.js} +47 -51
- package/js/{chunk-36DNRFZQ.js → chunk-SATWJKN6.js} +1 -1
- package/js/chunk-SWPD52J7.js +35 -0
- package/js/{chunk-BKVL7XAJ.js → chunk-TE4KO4HI.js} +1 -1
- package/js/chunk-UVL56Z6E.js +6641 -0
- package/js/chunk-W7D7WVSY.js +18 -0
- package/js/{chunk-BPEFS4YF.js → chunk-WFSQXYUT.js} +109 -17
- package/js/chunk-YEJOQEII.js +104 -0
- package/js/{chunk-LOKGDT6B.js → chunk-Z5NMEGJN.js} +5 -4
- package/js/{chunk-OWD2YICM.js → chunk-ZCAMUXSG.js} +116 -87
- package/js/chunk-ZJWDMTE3.js +63 -0
- package/js/client.js +11 -11
- package/js/contracts.js +88 -25
- package/js/effect.js +21 -15
- package/js/es-APDZKREY.js +40968 -0
- package/js/graphql.js +224 -121
- package/js/host.js +76 -19
- package/js/index.js +193 -51
- package/js/mcp/effect.js +25 -17
- package/js/mcp/stdio.js +23 -17
- package/js/mcp.js +110 -24
- package/js/openapi.js +3045 -105
- package/js/operations/approval.js +1 -1
- package/js/react.js +4 -4
- package/js/skills/effect.js +11 -0
- package/js/skills.js +894 -0
- package/js/storage/facet.js +7 -7
- package/js/ui/auth/contracts.js +6 -6
- package/js/ui/auth.js +8 -8
- package/js/ui/contracts.js +5 -5
- package/js/ui/serving.js +12 -12
- package/package.json +9 -1
- package/runtime.json +1 -1
- package/types/app-cache/src/contracts/cache.d.ts +119 -0
- package/types/app-cache/src/index.d.ts +93 -0
- package/types/apps/src/contracts/api-response-error.d.ts +43 -0
- package/types/apps/src/contracts/app.d.ts +11 -0
- package/types/apps/src/contracts/cache.d.ts +44 -0
- package/types/apps/src/contracts/dynamic-skills.d.ts +10 -0
- package/types/apps/src/contracts/dynamic-tools.d.ts +13 -0
- package/types/apps/src/contracts/graphql.d.ts +18 -1
- package/types/apps/src/contracts/host.d.ts +54 -525
- package/types/apps/src/contracts/mcp.d.ts +3 -1
- package/types/apps/src/contracts/openapi-compile.d.ts +11 -0
- package/types/apps/src/contracts/openapi-document.d.ts +53 -0
- package/types/apps/src/contracts/openapi.d.ts +156 -30
- package/types/apps/src/contracts/protocol-version.d.ts +6 -0
- package/types/apps/src/contracts/protocols/1.d.ts +1575 -0
- package/types/apps/src/contracts/provider-error.d.ts +15 -0
- package/types/apps/src/contracts/provider.d.ts +18 -1
- package/types/apps/src/contracts/skills.d.ts +122 -0
- package/types/apps/src/contracts/swagger-client.d.ts +29 -0
- package/types/apps/src/graphql.d.ts +6 -6
- package/types/apps/src/host.d.ts +1 -0
- package/types/apps/src/implementation/account-operations.d.ts +122 -3
- package/types/apps/src/implementation/app.d.ts +1 -1
- package/types/apps/src/implementation/cache-session.d.ts +7 -0
- package/types/apps/src/implementation/cache.d.ts +8 -0
- package/types/apps/src/implementation/catalog-cache.d.ts +29 -0
- package/types/apps/src/implementation/dynamic-skills.d.ts +7 -0
- package/types/apps/src/implementation/dynamic-tools.d.ts +8 -0
- package/types/apps/src/implementation/elicitation.d.ts +12 -12
- package/types/apps/src/implementation/git.d.ts +25 -0
- package/types/apps/src/implementation/graphql-catalog.d.ts +10 -0
- package/types/apps/src/implementation/graphql.d.ts +81 -3
- package/types/apps/src/implementation/inflate.d.ts +16 -0
- package/types/apps/src/implementation/input-problems.d.ts +3 -0
- package/types/apps/src/implementation/mcp-call.d.ts +3 -2
- package/types/apps/src/implementation/mcp-catalog.d.ts +12 -0
- package/types/apps/src/implementation/mcp-client.d.ts +9 -8
- package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
- package/types/apps/src/implementation/mcp-tools.d.ts +6 -3
- package/types/apps/src/implementation/mcp.d.ts +39 -2
- package/types/apps/src/implementation/openapi-compile.d.ts +119 -0
- package/types/apps/src/implementation/openapi-document.d.ts +51 -0
- package/types/apps/src/implementation/openapi-names.d.ts +18 -0
- package/types/apps/src/implementation/openapi-request.d.ts +10 -4
- package/types/apps/src/implementation/openapi-source.d.ts +40 -0
- package/types/apps/src/implementation/openapi.d.ts +39 -3
- package/types/apps/src/implementation/provider-error.d.ts +10 -0
- package/types/apps/src/implementation/schema.d.ts +6 -5
- package/types/apps/src/implementation/skill-files.d.ts +10 -0
- package/types/apps/src/implementation/skills.d.ts +43 -0
- package/types/apps/src/implementation/swagger-client.d.ts +28 -0
- package/types/apps/src/index.d.ts +7 -0
- package/types/apps/src/mcp.d.ts +5 -5
- package/types/apps/src/openapi.d.ts +3 -1
- package/types/apps/src/skills.d.ts +75 -0
- package/types/telemetry/src/config.d.ts +2 -0
- package/js/chunk-22WRQZT7.js +0 -389
- package/js/chunk-MLKGABMK.js +0 -9
package/js/openapi.js
CHANGED
|
@@ -1,64 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parse
|
|
3
|
+
} from "./chunk-UVL56Z6E.js";
|
|
1
4
|
import {
|
|
2
5
|
protocolOperations
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import
|
|
6
|
+
} from "./chunk-Z5NMEGJN.js";
|
|
7
|
+
import {
|
|
8
|
+
fromPromise,
|
|
9
|
+
nativeOperation,
|
|
10
|
+
toPromise
|
|
11
|
+
} from "./chunk-PYUYJRSK.js";
|
|
12
|
+
import {
|
|
13
|
+
accountProviderError,
|
|
14
|
+
httpProviderError
|
|
15
|
+
} from "./chunk-ZJWDMTE3.js";
|
|
16
|
+
import {
|
|
17
|
+
ApiErrorRecovery,
|
|
18
|
+
ApiErrorResponse,
|
|
19
|
+
OpenapiResponseError,
|
|
20
|
+
defaultOpenapiErrorLimits
|
|
21
|
+
} from "./chunk-SWPD52J7.js";
|
|
22
|
+
import {
|
|
23
|
+
ProviderError
|
|
24
|
+
} from "./chunk-W7D7WVSY.js";
|
|
5
25
|
import {
|
|
6
26
|
FetchHttpClient_exports
|
|
7
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-HDJH3RPR.js";
|
|
8
28
|
import {
|
|
9
29
|
HttpClientRequest_exports,
|
|
10
30
|
HttpClient_exports
|
|
11
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-QKHR7BMF.js";
|
|
12
32
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
33
|
+
jsonSchema,
|
|
34
|
+
lazyJsonSchemaDecoder,
|
|
35
|
+
once,
|
|
36
|
+
wrap
|
|
37
|
+
} from "./chunk-WFSQXYUT.js";
|
|
15
38
|
import {
|
|
39
|
+
AccountId,
|
|
16
40
|
HttpUrl,
|
|
17
|
-
JsonObject
|
|
18
|
-
|
|
41
|
+
JsonObject,
|
|
42
|
+
JsonValue
|
|
43
|
+
} from "./chunk-SATWJKN6.js";
|
|
19
44
|
import {
|
|
45
|
+
Duration_exports,
|
|
20
46
|
Effect_exports,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
47
|
+
Encoding_exports,
|
|
48
|
+
JsonPointer_exports,
|
|
49
|
+
JsonSchema_exports,
|
|
50
|
+
Option_exports,
|
|
51
|
+
Schema_exports,
|
|
52
|
+
Stream_exports
|
|
53
|
+
} from "./chunk-FW5HBOIK.js";
|
|
54
|
+
import "./chunk-CZ7CSFO4.js";
|
|
24
55
|
|
|
25
56
|
// src/contracts/openapi.ts
|
|
26
|
-
var
|
|
57
|
+
var OpenapiErrorResponse = Schema_exports.Struct({
|
|
58
|
+
code: ApiErrorResponse.fields.code,
|
|
59
|
+
status: ApiErrorResponse.fields.status,
|
|
60
|
+
message: Schema_exports.Union([
|
|
61
|
+
Schema_exports.Struct({ source: Schema_exports.Literal("body") }),
|
|
62
|
+
Schema_exports.Struct({ source: Schema_exports.Literal("schema"), value: ApiErrorResponse.fields.message })
|
|
63
|
+
]),
|
|
64
|
+
schema: JsonObject
|
|
65
|
+
});
|
|
66
|
+
var OpenapiParameter = Schema_exports.Struct({
|
|
27
67
|
name: Schema_exports.String,
|
|
28
|
-
in: Schema_exports.Literals(["path", "query", "header"]),
|
|
29
|
-
|
|
30
|
-
|
|
68
|
+
in: Schema_exports.Literals(["path", "query", "header", "cookie"]),
|
|
69
|
+
required: Schema_exports.optionalKey(Schema_exports.Boolean),
|
|
70
|
+
schema: Schema_exports.optionalKey(JsonObject),
|
|
71
|
+
style: Schema_exports.optionalKey(Schema_exports.String),
|
|
72
|
+
explode: Schema_exports.optionalKey(Schema_exports.Boolean),
|
|
73
|
+
allowReserved: Schema_exports.optionalKey(Schema_exports.Boolean),
|
|
74
|
+
allowEmptyValue: Schema_exports.optionalKey(Schema_exports.Boolean),
|
|
75
|
+
content: Schema_exports.optionalKey(JsonObject)
|
|
76
|
+
});
|
|
77
|
+
var OpenapiRequestBody = Schema_exports.Struct({
|
|
78
|
+
required: Schema_exports.optionalKey(Schema_exports.Boolean),
|
|
79
|
+
content: Schema_exports.Record(
|
|
80
|
+
Schema_exports.String,
|
|
81
|
+
Schema_exports.Struct({
|
|
82
|
+
schema: Schema_exports.optionalKey(JsonObject),
|
|
83
|
+
encoding: Schema_exports.optionalKey(JsonObject)
|
|
84
|
+
})
|
|
85
|
+
)
|
|
31
86
|
});
|
|
32
87
|
var OpenapiOperation = Schema_exports.Struct({
|
|
88
|
+
/** The tool name after `queries.` or `mutations.`, grouped as `<group>.<leaf>`. */
|
|
33
89
|
name: Schema_exports.NonEmptyString,
|
|
90
|
+
/** The document's operationId, when it declares one. `kinds` overrides are keyed by it. */
|
|
91
|
+
operationId: Schema_exports.optionalKey(Schema_exports.String),
|
|
34
92
|
description: Schema_exports.String,
|
|
35
93
|
method: Schema_exports.Literals(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]),
|
|
36
94
|
path: Schema_exports.String,
|
|
37
95
|
baseUrl: HttpUrl,
|
|
38
|
-
|
|
39
|
-
|
|
96
|
+
openapi: Schema_exports.String,
|
|
97
|
+
securitySchemes: Schema_exports.Record(Schema_exports.String, JsonObject),
|
|
98
|
+
/** The resolved OpenAPI Operation Object; Executor schemas remain separate. */
|
|
99
|
+
request: Schema_exports.Struct({
|
|
100
|
+
parameters: Schema_exports.Array(OpenapiParameter),
|
|
101
|
+
requestBody: Schema_exports.optionalKey(OpenapiRequestBody),
|
|
102
|
+
security: Schema_exports.Array(Schema_exports.Record(Schema_exports.String, Schema_exports.Array(Schema_exports.String))),
|
|
103
|
+
responses: Schema_exports.Record(Schema_exports.String, JsonObject)
|
|
104
|
+
}),
|
|
40
105
|
/** Streams remain in the metadata but cannot run through a single-result tool call. */
|
|
41
106
|
streaming: Schema_exports.optionalKey(Schema_exports.Literal(true)),
|
|
42
|
-
security: Schema_exports.Array(Schema_exports.Array(Schema_exports.String)),
|
|
43
107
|
input: JsonObject,
|
|
44
|
-
outputSchema: Schema_exports.optionalKey(JsonObject)
|
|
108
|
+
outputSchema: Schema_exports.optionalKey(JsonObject),
|
|
109
|
+
errorResponses: Schema_exports.optionalKey(Schema_exports.Array(OpenapiErrorResponse))
|
|
45
110
|
});
|
|
46
111
|
var CredentialBinding = Schema_exports.Struct({
|
|
47
112
|
scheme: Schema_exports.String,
|
|
48
113
|
field: Schema_exports.String,
|
|
49
|
-
|
|
50
|
-
name: Schema_exports.String,
|
|
114
|
+
part: Schema_exports.Literals(["value", "username", "password"]),
|
|
51
115
|
prefix: Schema_exports.String
|
|
52
116
|
});
|
|
53
117
|
var OpenapiAccount = Schema_exports.Struct({
|
|
118
|
+
id: Schema_exports.optional(AccountId),
|
|
54
119
|
method: Schema_exports.String,
|
|
55
120
|
fields: Schema_exports.Record(Schema_exports.String, Schema_exports.Unknown)
|
|
56
121
|
});
|
|
122
|
+
var OpenapiParameterDefaults = Schema_exports.Struct({
|
|
123
|
+
path: Schema_exports.optionalKey(Schema_exports.Record(Schema_exports.String, Schema_exports.String)),
|
|
124
|
+
query: Schema_exports.optionalKey(Schema_exports.Record(Schema_exports.String, Schema_exports.String)),
|
|
125
|
+
headers: Schema_exports.optionalKey(Schema_exports.Record(Schema_exports.String, Schema_exports.String))
|
|
126
|
+
});
|
|
57
127
|
var OpenapiToolsOptions = Schema_exports.Struct({
|
|
58
128
|
operations: Schema_exports.Array(OpenapiOperation),
|
|
129
|
+
/**
|
|
130
|
+
* Component schemas stored once per app and referenced as `#/$defs/<name>`. Operations
|
|
131
|
+
* generated before shared definitions carry their own `$defs` and omit this.
|
|
132
|
+
*/
|
|
133
|
+
definitions: Schema_exports.optional(Schema_exports.Record(Schema_exports.String, JsonObject)),
|
|
59
134
|
methods: Schema_exports.Record(Schema_exports.String, Schema_exports.Array(CredentialBinding)),
|
|
60
135
|
oauth: Schema_exports.Array(Schema_exports.String),
|
|
61
136
|
account: Schema_exports.optional(OpenapiAccount),
|
|
137
|
+
parameterDefaults: Schema_exports.optional(OpenapiParameterDefaults),
|
|
62
138
|
signal: Schema_exports.optional(Schema_exports.instanceOf(AbortSignal)),
|
|
63
139
|
fetch: Schema_exports.optional(
|
|
64
140
|
Schema_exports.declare((value) => typeof value === "function")
|
|
@@ -69,99 +145,244 @@ var OpenapiError = class extends Schema_exports.TaggedError()("OpenapiError", {
|
|
|
69
145
|
status: Schema_exports.optional(Schema_exports.Number)
|
|
70
146
|
}) {
|
|
71
147
|
};
|
|
148
|
+
var defaultOpenapiResponseLimits = {
|
|
149
|
+
maxBodyBytes: 16777216,
|
|
150
|
+
readTimeoutMs: 3e4
|
|
151
|
+
};
|
|
152
|
+
var isOpenapiTextMedia = (type) => /^(?:text\/|application\/(?:[\w.-]+\+)?(?:json|xml)|application\/(?:javascript|x-ndjson|x-www-form-urlencoded))/i.test(
|
|
153
|
+
type
|
|
154
|
+
);
|
|
155
|
+
var isOpenapiFileSchema = (shape) => shape.contentMediaType !== void 0 && shape.contentEncoding === void 0 || shape.type === "string" && shape.format === "binary";
|
|
156
|
+
var openapiBinaryResultSchema = {
|
|
157
|
+
type: "object",
|
|
158
|
+
properties: {
|
|
159
|
+
base64: { type: "string", contentEncoding: "base64" },
|
|
160
|
+
contentType: { type: "string" }
|
|
161
|
+
},
|
|
162
|
+
required: ["base64", "contentType"],
|
|
163
|
+
additionalProperties: false
|
|
164
|
+
};
|
|
165
|
+
var openapiMediaKind = (type) => type.includes("json") && !type.includes("ndjson") ? "json" : type === "application/x-www-form-urlencoded" ? "form" : type === "multipart/form-data" ? "multipart" : isOpenapiTextMedia(type) ? "text" : "binary";
|
|
166
|
+
|
|
167
|
+
// src/implementation/swagger-client.ts
|
|
168
|
+
var loadSwaggerClient = () => import("./es-APDZKREY.js").then((module) => module.default);
|
|
72
169
|
|
|
73
170
|
// src/implementation/openapi-request.ts
|
|
171
|
+
var bodyRecovery = Schema_exports.decodeUnknownOption(Schema_exports.Struct({ recovery: ApiErrorRecovery }));
|
|
172
|
+
function responseError(response, errors) {
|
|
173
|
+
return Effect_exports.gen(function* () {
|
|
174
|
+
const candidates = errors.filter((error) => error.status === response.status);
|
|
175
|
+
if (candidates.length === 0 || !/^application\/(?:[\w.-]+\+)?json$/i.test(
|
|
176
|
+
response.headers["content-type"]?.split(";")[0]?.trim() ?? ""
|
|
177
|
+
))
|
|
178
|
+
return;
|
|
179
|
+
const length = response.headers["content-length"];
|
|
180
|
+
if (length !== void 0 && Number(length) > defaultOpenapiErrorLimits.maxBodyBytes) return;
|
|
181
|
+
const json = yield* response.stream.pipe(
|
|
182
|
+
Stream_exports.mapError(() => new OpenapiError({ reason: "request", status: response.status })),
|
|
183
|
+
Stream_exports.limitBytes(
|
|
184
|
+
defaultOpenapiErrorLimits.maxBodyBytes,
|
|
185
|
+
() => Stream_exports.fail(new OpenapiError({ reason: "request", status: response.status }))
|
|
186
|
+
),
|
|
187
|
+
Stream_exports.decodeText,
|
|
188
|
+
Stream_exports.mkString,
|
|
189
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(Schema_exports.fromJsonString(Schema_exports.Json))),
|
|
190
|
+
Effect_exports.timeout(defaultOpenapiErrorLimits.readTimeoutMs)
|
|
191
|
+
);
|
|
192
|
+
for (const candidate of candidates) {
|
|
193
|
+
const parsed = yield* Schema_exports.decodeUnknownEffect(candidate.decoder)(json).pipe(Effect_exports.option);
|
|
194
|
+
if (Option_exports.isSome(parsed)) {
|
|
195
|
+
const message = candidate.message.source === "schema" ? Option_exports.some({ message: candidate.message.value }) : Schema_exports.decodeUnknownOption(
|
|
196
|
+
Schema_exports.Struct({ message: ApiErrorResponse.fields.message })
|
|
197
|
+
)(parsed.value);
|
|
198
|
+
if (Option_exports.isNone(message)) continue;
|
|
199
|
+
const recovery = bodyRecovery(parsed.value);
|
|
200
|
+
return new OpenapiResponseError({
|
|
201
|
+
code: candidate.code,
|
|
202
|
+
status: response.status,
|
|
203
|
+
message: message.value.message,
|
|
204
|
+
...Option_exports.isSome(recovery) ? { recovery: recovery.value.recovery } : {}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}).pipe(Effect_exports.catch(() => Effect_exports.succeed(void 0)));
|
|
209
|
+
}
|
|
74
210
|
var object = Schema_exports.decodeUnknownSync(Schema_exports.Record(Schema_exports.String, Schema_exports.Unknown));
|
|
75
211
|
function scalar(value) {
|
|
76
212
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
77
213
|
return String(value);
|
|
78
214
|
throw new Error("This parameter requires scalar values");
|
|
79
215
|
}
|
|
80
|
-
|
|
81
|
-
|
|
216
|
+
var swaggerRequest = Schema_exports.decodeUnknownSync(
|
|
217
|
+
Schema_exports.Struct({
|
|
218
|
+
url: Schema_exports.String,
|
|
219
|
+
method: Schema_exports.String,
|
|
220
|
+
headers: Schema_exports.Record(Schema_exports.String, Schema_exports.String),
|
|
221
|
+
body: Schema_exports.optional(
|
|
222
|
+
Schema_exports.Union([Schema_exports.String, Schema_exports.instanceOf(Blob), Schema_exports.instanceOf(FormData)])
|
|
223
|
+
)
|
|
224
|
+
})
|
|
225
|
+
);
|
|
226
|
+
var reservedPath = /* @__PURE__ */ new Set([
|
|
227
|
+
":",
|
|
228
|
+
"@",
|
|
229
|
+
"!",
|
|
230
|
+
"$",
|
|
231
|
+
"&",
|
|
232
|
+
"'",
|
|
233
|
+
"(",
|
|
234
|
+
")",
|
|
235
|
+
"*",
|
|
236
|
+
"+",
|
|
237
|
+
",",
|
|
238
|
+
";",
|
|
239
|
+
"=",
|
|
240
|
+
"/"
|
|
241
|
+
]);
|
|
242
|
+
function reservedPathValue(value) {
|
|
243
|
+
const text = Array.isArray(value) ? value.map(scalar).join(",") : scalar(value);
|
|
244
|
+
if (/[?#\\]/.test(text)) throw new Error("This path value contains a forbidden character");
|
|
245
|
+
const encoded = text.replace(/%[0-9A-Fa-f]{2}|[^]/gu, (part) => {
|
|
246
|
+
if (part.length === 3 && part.startsWith("%")) {
|
|
247
|
+
if ("./\\?#%".includes(String.fromCharCode(Number.parseInt(part.slice(1), 16))))
|
|
248
|
+
throw new Error("This path value contains a forbidden escape");
|
|
249
|
+
return part;
|
|
250
|
+
}
|
|
251
|
+
return reservedPath.has(part) ? part : encodeURIComponent(part);
|
|
252
|
+
});
|
|
253
|
+
if (encoded.split("/").some((segment) => segment === "" || segment === "." || segment === ".."))
|
|
254
|
+
throw new Error("This path value would change the request path");
|
|
255
|
+
return encoded;
|
|
82
256
|
}
|
|
83
|
-
function
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
257
|
+
function operationPath(op) {
|
|
258
|
+
const template = op.baseUrl.replace(/\/$/, "") + op.path;
|
|
259
|
+
let marker = "executorPathParameter";
|
|
260
|
+
while (template.includes(marker)) marker += "_";
|
|
261
|
+
const expansions = [];
|
|
262
|
+
const address = template.replace(/\{[^{}]+\}/g, (placeholder) => {
|
|
263
|
+
const parameter = op.request.parameters.find(
|
|
264
|
+
(p) => p.in === "path" && p.name === placeholder.slice(1, -1)
|
|
265
|
+
);
|
|
266
|
+
if (parameter === void 0) throw new Error("A path parameter is not declared");
|
|
267
|
+
const token = `${marker}_${expansions.length}_`;
|
|
268
|
+
expansions.push({
|
|
269
|
+
token,
|
|
270
|
+
pattern: parameter.allowReserved === true && parameter.content === void 0 ? ".+" : "[^/]+"
|
|
271
|
+
});
|
|
272
|
+
return token;
|
|
273
|
+
});
|
|
274
|
+
let pattern = new URL(address).pathname.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
275
|
+
for (const expansion of expansions)
|
|
276
|
+
pattern = pattern.replaceAll(expansion.token, expansion.pattern);
|
|
277
|
+
return new RegExp("^" + pattern + "$");
|
|
89
278
|
}
|
|
279
|
+
var bytes = (value) => Uint8Array.from(atob(scalar(value)), (char) => char.charCodeAt(0));
|
|
90
280
|
function createRequest(config) {
|
|
91
281
|
const { methods, oauth } = config;
|
|
92
|
-
function
|
|
93
|
-
if (method === void 0) return [];
|
|
94
|
-
if (oauth.includes(method)) return [method];
|
|
95
|
-
const bindings = Object.hasOwn(methods, method) ? methods[method] : void 0;
|
|
96
|
-
return bindings?.map((binding) => binding.scheme) ?? [];
|
|
97
|
-
}
|
|
98
|
-
function selectedSecurity(op, method) {
|
|
282
|
+
function selectedCredentials(op, account) {
|
|
99
283
|
if (op.streaming === true) return void 0;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
284
|
+
const authorized = {};
|
|
285
|
+
if (account !== void 0) {
|
|
286
|
+
if (oauth.includes(account.method)) {
|
|
287
|
+
const token = account.fields.access_token;
|
|
288
|
+
if (typeof token === "string" && token.length > 0)
|
|
289
|
+
authorized[account.method] = { token: { access_token: token } };
|
|
290
|
+
} else if (Object.hasOwn(methods, account.method)) {
|
|
291
|
+
const bindings = methods[account.method] ?? [];
|
|
292
|
+
for (const scheme of new Set(bindings.map((binding) => binding.scheme))) {
|
|
293
|
+
const parts = bindings.filter((binding) => binding.scheme === scheme);
|
|
294
|
+
if (parts.some(
|
|
295
|
+
({ field }) => typeof account.fields[field] !== "string" || account.fields[field] === ""
|
|
296
|
+
))
|
|
297
|
+
continue;
|
|
298
|
+
for (const { part, field, prefix } of parts) {
|
|
299
|
+
const value = scalar(account.fields[field]);
|
|
300
|
+
authorized[scheme] = part === "value" ? prefix + value : { ...object(authorized[scheme] ?? {}), [part]: value };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const security = op.request.security;
|
|
306
|
+
const keys = security.length === 0 ? [] : security.map(Object.keys).find((keys2) => keys2.every((key) => Object.hasOwn(authorized, key)));
|
|
307
|
+
return keys === void 0 ? void 0 : Object.fromEntries(keys.map((key) => [key, authorized[key]]));
|
|
103
308
|
}
|
|
104
|
-
const call = (op, input, account) => Effect_exports.scoped(
|
|
309
|
+
const call = (op, input, account, errors) => Effect_exports.scoped(
|
|
105
310
|
Effect_exports.gen(function* () {
|
|
311
|
+
const swagger = yield* Effect_exports.promise(loadSwaggerClient);
|
|
106
312
|
const prepared = yield* Effect_exports.try({
|
|
107
313
|
try: () => {
|
|
108
314
|
const args = object(input);
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
315
|
+
const authorized = selectedCredentials(op, account);
|
|
316
|
+
if (authorized === void 0)
|
|
111
317
|
throw new Error("The selected account cannot call this tool");
|
|
318
|
+
const parameters = {};
|
|
112
319
|
let path = op.path;
|
|
113
|
-
const
|
|
114
|
-
const headers = new Headers();
|
|
115
|
-
for (const p of op.parameters) {
|
|
320
|
+
const swaggerParameters = op.request.parameters.filter((p) => {
|
|
116
321
|
const group = args[p.in === "header" ? "headers" : p.in];
|
|
117
322
|
const value = group === void 0 ? void 0 : object(group)[p.name];
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
path = path.replaceAll(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
323
|
+
if (p.in === "path" && p.allowReserved === true && p.content === void 0) {
|
|
324
|
+
if (value === void 0) throw new Error("A required path parameter is missing");
|
|
325
|
+
path = path.replaceAll(`{${p.name}}`, reservedPathValue(value));
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
if (group !== void 0) parameters[`${p.in}.${p.name}`] = value;
|
|
329
|
+
return true;
|
|
330
|
+
});
|
|
331
|
+
const content = op.request.requestBody?.content ?? {};
|
|
332
|
+
const contentType2 = args.contentType === void 0 ? Object.keys(content)[0] : scalar(args.contentType);
|
|
333
|
+
const media = contentType2 === void 0 ? void 0 : content[contentType2];
|
|
334
|
+
let body = args.body;
|
|
335
|
+
if (body !== void 0 && media !== void 0 && contentType2 !== void 0) {
|
|
336
|
+
const kind = openapiMediaKind(contentType2);
|
|
337
|
+
if (kind === "json") body = JSON.stringify(body);
|
|
338
|
+
else if (kind === "binary") body = new Blob([bytes(body)]);
|
|
339
|
+
else if (kind === "multipart") {
|
|
340
|
+
const fields = { ...object(body) };
|
|
341
|
+
for (const [name, property] of Object.entries(
|
|
342
|
+
object(media.schema?.properties ?? {})
|
|
343
|
+
)) {
|
|
344
|
+
if (isOpenapiFileSchema(object(property)) && fields[name] !== void 0)
|
|
345
|
+
fields[name] = new File([bytes(fields[name])], name);
|
|
346
|
+
}
|
|
347
|
+
body = fields;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const prepared2 = swaggerRequest(
|
|
351
|
+
swagger.buildRequest({
|
|
352
|
+
spec: {
|
|
353
|
+
openapi: op.openapi,
|
|
354
|
+
servers: [{ url: op.baseUrl }],
|
|
355
|
+
components: { securitySchemes: op.securitySchemes },
|
|
356
|
+
paths: {
|
|
357
|
+
[path]: {
|
|
358
|
+
[op.method.toLowerCase()]: {
|
|
359
|
+
...op.request,
|
|
360
|
+
parameters: swaggerParameters,
|
|
361
|
+
operationId: op.name
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
operationId: op.name,
|
|
367
|
+
pathName: path,
|
|
368
|
+
method: op.method.toLowerCase(),
|
|
369
|
+
parameters,
|
|
370
|
+
securities: { authorized },
|
|
371
|
+
...contentType2 === void 0 ? {} : { requestContentType: contentType2 },
|
|
372
|
+
...body === void 0 ? {} : { requestBody: body }
|
|
373
|
+
})
|
|
374
|
+
);
|
|
375
|
+
const pathname = prepared2.url.replace(/^[^:]+:\/\/[^/]*/, "").split(/[?#]/)[0] ?? "";
|
|
376
|
+
if (pathname.split("/").some((segment) => /^(?:\.|%2e){1,2}$/i.test(segment)))
|
|
377
|
+
throw new Error("This path value would change the request path");
|
|
378
|
+
const url = new URL(prepared2.url);
|
|
379
|
+
const origin = new URL(op.baseUrl).origin;
|
|
380
|
+
if (url.origin !== origin || !operationPath(op).test(url.pathname) || url.username || url.password)
|
|
381
|
+
throw new Error("The request escaped its API operation");
|
|
382
|
+
const headers = new Headers(prepared2.headers);
|
|
383
|
+
if (!headers.has("user-agent")) headers.set("user-agent", "Executor");
|
|
384
|
+
if (prepared2.body instanceof FormData) headers.delete("content-type");
|
|
385
|
+
return { ...prepared2, url, headers };
|
|
165
386
|
},
|
|
166
387
|
catch: () => new OpenapiError({ reason: "invalid_input" })
|
|
167
388
|
});
|
|
@@ -177,10 +398,34 @@ function createRequest(config) {
|
|
|
177
398
|
catch: () => new OpenapiError({ reason: "invalid_input" })
|
|
178
399
|
});
|
|
179
400
|
const response = yield* HttpClient_exports.withScope(client).execute(request);
|
|
180
|
-
if (response.status < 200 || response.status >= 300)
|
|
181
|
-
|
|
401
|
+
if (response.status < 200 || response.status >= 300) {
|
|
402
|
+
const provider = httpProviderError(response.status, response.headers);
|
|
403
|
+
if (provider !== void 0 && provider.reason !== "rejected") return yield* provider;
|
|
404
|
+
const declared = yield* responseError(response, errors);
|
|
405
|
+
return yield* declared ?? provider ?? new OpenapiError({ reason: "request", status: response.status });
|
|
406
|
+
}
|
|
182
407
|
if (response.status === 204 || prepared.method === "HEAD") return null;
|
|
183
|
-
|
|
408
|
+
const contentType = response.headers["content-type"] ?? "text/plain";
|
|
409
|
+
const chunks = yield* response.stream.pipe(
|
|
410
|
+
Stream_exports.mapError(() => new OpenapiError({ reason: "request" })),
|
|
411
|
+
Stream_exports.limitBytes(
|
|
412
|
+
defaultOpenapiResponseLimits.maxBodyBytes,
|
|
413
|
+
() => Stream_exports.fail(new OpenapiError({ reason: "request" }))
|
|
414
|
+
),
|
|
415
|
+
Stream_exports.runCollect,
|
|
416
|
+
Effect_exports.timeout(defaultOpenapiResponseLimits.readTimeoutMs),
|
|
417
|
+
Effect_exports.withSpan("provider.http.response.read")
|
|
418
|
+
);
|
|
419
|
+
const data = new Uint8Array(chunks.reduce((size, chunk) => size + chunk.length, 0));
|
|
420
|
+
let offset = 0;
|
|
421
|
+
for (const chunk of chunks) {
|
|
422
|
+
data.set(chunk, offset);
|
|
423
|
+
offset += chunk.length;
|
|
424
|
+
}
|
|
425
|
+
if (!isOpenapiTextMedia(contentType))
|
|
426
|
+
return { base64: Encoding_exports.encodeBase64(data), contentType };
|
|
427
|
+
const text = new TextDecoder().decode(data);
|
|
428
|
+
return contentType.includes("json") && !contentType.includes("ndjson") ? yield* Schema_exports.decodeUnknownEffect(Schema_exports.fromJsonString(Schema_exports.Json))(text) : text;
|
|
184
429
|
})
|
|
185
430
|
).pipe(
|
|
186
431
|
Effect_exports.withSpan("provider.openapi.call", {
|
|
@@ -189,36 +434,145 @@ function createRequest(config) {
|
|
|
189
434
|
Effect_exports.provideService(FetchHttpClient_exports.RequestInit, { redirect: "manual" }),
|
|
190
435
|
Effect_exports.provide(FetchHttpClient_exports.layer),
|
|
191
436
|
Effect_exports.mapError(
|
|
192
|
-
(error) => error instanceof OpenapiError ? error : new OpenapiError({ reason: "request" })
|
|
437
|
+
(error) => error instanceof ProviderError && account?.id !== void 0 ? accountProviderError(error, account.id) : error instanceof OpenapiError || error instanceof OpenapiResponseError || error instanceof ProviderError ? error : new OpenapiError({ reason: "request" })
|
|
193
438
|
)
|
|
194
439
|
);
|
|
195
440
|
return {
|
|
196
|
-
available: (op,
|
|
441
|
+
available: (op, account) => selectedCredentials(op, account) !== void 0,
|
|
197
442
|
call
|
|
198
443
|
};
|
|
199
444
|
}
|
|
200
445
|
|
|
201
446
|
// src/implementation/openapi.ts
|
|
202
|
-
|
|
447
|
+
function references(value, found = /* @__PURE__ */ new Set()) {
|
|
448
|
+
if (Array.isArray(value)) for (const item of value) references(item, found);
|
|
449
|
+
else if (value !== null && typeof value === "object")
|
|
450
|
+
for (const [key, item] of Object.entries(value)) {
|
|
451
|
+
if (key !== "$ref" || typeof item !== "string") references(item, found);
|
|
452
|
+
else {
|
|
453
|
+
const path = item.startsWith("#/$defs/") ? JsonPointer_exports.parseUriFragment(item) : void 0;
|
|
454
|
+
if (path?.[1] !== void 0) found.add(path[1]);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return found;
|
|
458
|
+
}
|
|
459
|
+
var bundler = (definitions) => {
|
|
460
|
+
const direct = /* @__PURE__ */ new Map();
|
|
461
|
+
return (schema2) => {
|
|
462
|
+
const reached = /* @__PURE__ */ new Map();
|
|
463
|
+
const pending = [...references(schema2)];
|
|
464
|
+
for (let name = pending.pop(); name !== void 0; name = pending.pop()) {
|
|
465
|
+
const definition = Object.hasOwn(definitions, name) ? definitions[name] : void 0;
|
|
466
|
+
if (definition === void 0 || reached.has(name)) continue;
|
|
467
|
+
reached.set(name, definition);
|
|
468
|
+
let names = direct.get(name);
|
|
469
|
+
if (names === void 0) direct.set(name, names = references(definition));
|
|
470
|
+
pending.push(...names);
|
|
471
|
+
}
|
|
472
|
+
if (reached.size === 0) return schema2;
|
|
473
|
+
const own = schema2.$defs;
|
|
474
|
+
return {
|
|
475
|
+
...schema2,
|
|
476
|
+
$defs: {
|
|
477
|
+
...Object.fromEntries(reached),
|
|
478
|
+
...own !== null && typeof own === "object" && !Array.isArray(own) ? own : {}
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
};
|
|
482
|
+
};
|
|
483
|
+
var parameterGroups = { path: "path", query: "query", headers: "header" };
|
|
484
|
+
var isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
485
|
+
var boundParameters = (op, defaults) => Object.keys(parameterGroups).flatMap(
|
|
486
|
+
(group) => Object.entries(defaults?.[group] ?? {}).filter(
|
|
487
|
+
([name]) => op.request.parameters.some((p) => p.name === name && p.in === parameterGroups[group])
|
|
488
|
+
).map(([name, value]) => ({ group, name, value }))
|
|
489
|
+
);
|
|
490
|
+
var parameterDefaultsInput = (op, defaults, publish) => {
|
|
491
|
+
const bound = boundParameters(op, defaults);
|
|
492
|
+
if (!bound.length || !isObject(op.input.properties)) return op.input;
|
|
493
|
+
const properties = { ...op.input.properties };
|
|
494
|
+
let required = Array.isArray(op.input.required) ? op.input.required : [];
|
|
495
|
+
for (const group of new Set(bound.map((entry) => entry.group))) {
|
|
496
|
+
const shape = properties[group];
|
|
497
|
+
if (!isObject(shape)) continue;
|
|
498
|
+
const names = bound.filter((entry) => entry.group === group);
|
|
499
|
+
const remaining = (Array.isArray(shape.required) ? shape.required : []).filter(
|
|
500
|
+
(name) => !names.some((entry) => entry.name === name)
|
|
501
|
+
);
|
|
502
|
+
const fields = isObject(shape.properties) ? shape.properties : {};
|
|
503
|
+
properties[group] = {
|
|
504
|
+
...shape,
|
|
505
|
+
required: remaining,
|
|
506
|
+
...publish ? {
|
|
507
|
+
properties: {
|
|
508
|
+
...fields,
|
|
509
|
+
...Object.fromEntries(
|
|
510
|
+
names.map(({ name, value }) => {
|
|
511
|
+
const field = isObject(fields[name]) ? fields[name] : {};
|
|
512
|
+
const note = "Optional; defaults to the value bound to the selected account.";
|
|
513
|
+
const description = typeof field.description === "string" ? `${field.description} ${note}` : note;
|
|
514
|
+
return [name, { ...field, description, default: value }];
|
|
515
|
+
})
|
|
516
|
+
)
|
|
517
|
+
}
|
|
518
|
+
} : {}
|
|
519
|
+
};
|
|
520
|
+
if (!remaining.length) required = required.filter((key) => key !== group);
|
|
521
|
+
}
|
|
522
|
+
return { ...op.input, properties, required };
|
|
523
|
+
};
|
|
524
|
+
var fillParameterDefaults = (op, defaults, value) => {
|
|
525
|
+
const bound = boundParameters(op, defaults);
|
|
526
|
+
if (!bound.length || !isObject(value)) return value;
|
|
527
|
+
const result = { ...value };
|
|
528
|
+
for (const { group, name, value: fallback } of bound) {
|
|
529
|
+
const current = result[group] ?? {};
|
|
530
|
+
if (!isObject(current)) return value;
|
|
531
|
+
if (!Object.hasOwn(current, name)) result[group] = { ...current, [name]: fallback };
|
|
532
|
+
}
|
|
533
|
+
return result;
|
|
534
|
+
};
|
|
535
|
+
var prepareOpenapiOperation = (op, definitions, defaults) => Effect_exports.gen(function* () {
|
|
536
|
+
const bundle = bundler(definitions);
|
|
537
|
+
const input = yield* lazyJsonSchemaDecoder(
|
|
538
|
+
() => bundle(parameterDefaultsInput(op, defaults, false))
|
|
539
|
+
);
|
|
540
|
+
const errors = yield* Effect_exports.forEach(
|
|
541
|
+
op.errorResponses ?? [],
|
|
542
|
+
(response) => lazyJsonSchemaDecoder(() => bundle(response.schema)).pipe(
|
|
543
|
+
Effect_exports.map((decoder) => ({ ...response, decoder }))
|
|
544
|
+
)
|
|
545
|
+
);
|
|
546
|
+
return {
|
|
547
|
+
input,
|
|
548
|
+
errors,
|
|
549
|
+
output: once(() => op.outputSchema === void 0 ? void 0 : bundle(op.outputSchema))
|
|
550
|
+
};
|
|
551
|
+
});
|
|
552
|
+
var openapiToolsEffect = (options, prepared) => Effect_exports.gen(function* () {
|
|
203
553
|
const config = yield* Schema_exports.decodeUnknownEffect(OpenapiToolsOptions)(options).pipe(
|
|
204
554
|
Effect_exports.mapError(() => new OpenapiError({ reason: "invalid_definition" }))
|
|
205
555
|
);
|
|
206
556
|
const request = createRequest(config);
|
|
207
557
|
const entries = yield* Effect_exports.forEach(
|
|
208
|
-
config.operations.filter((op) => request.available(op, config.account
|
|
558
|
+
config.operations.filter((op) => request.available(op, config.account)),
|
|
209
559
|
(op) => Effect_exports.gen(function* () {
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
560
|
+
const schemas = prepared?.get(op.name) ?? (yield* prepareOpenapiOperation(
|
|
561
|
+
op,
|
|
562
|
+
config.definitions ?? {},
|
|
563
|
+
config.parameterDefaults
|
|
564
|
+
));
|
|
565
|
+
const { input, errors } = schemas;
|
|
213
566
|
const tool = {
|
|
214
567
|
description: op.description,
|
|
215
568
|
readOnly: ["GET", "HEAD", "OPTIONS"].includes(op.method),
|
|
216
569
|
input,
|
|
217
|
-
|
|
218
|
-
|
|
570
|
+
run: (_context, value) => Schema_exports.decodeUnknownEffect(input)(
|
|
571
|
+
fillParameterDefaults(op, config.parameterDefaults, value)
|
|
572
|
+
).pipe(
|
|
219
573
|
Effect_exports.mapError(() => new OpenapiError({ reason: "invalid_input" })),
|
|
220
574
|
Effect_exports.flatMap(
|
|
221
|
-
(parsed) => request.call(op, parsed, config.account).pipe(
|
|
575
|
+
(parsed) => request.call(op, parsed, config.account, errors).pipe(
|
|
222
576
|
Effect_exports.provideService(
|
|
223
577
|
FetchHttpClient_exports.Fetch,
|
|
224
578
|
config.fetch ?? globalThis.fetch
|
|
@@ -227,12 +581,2589 @@ var openapiToolsEffect = (options) => Effect_exports.gen(function* () {
|
|
|
227
581
|
)
|
|
228
582
|
)
|
|
229
583
|
};
|
|
584
|
+
const output = op.outputSchema;
|
|
585
|
+
if (output !== void 0)
|
|
586
|
+
Object.defineProperty(tool, "outputSchema", {
|
|
587
|
+
enumerable: true,
|
|
588
|
+
get: schemas.output
|
|
589
|
+
});
|
|
230
590
|
return [op.name, tool];
|
|
231
591
|
})
|
|
232
592
|
);
|
|
233
593
|
return Object.fromEntries(entries);
|
|
234
594
|
});
|
|
235
595
|
|
|
596
|
+
// src/contracts/openapi-compile.ts
|
|
597
|
+
var OpenapiCompileErrorCode = Schema_exports.Literals([
|
|
598
|
+
"server_protocol",
|
|
599
|
+
"server_url",
|
|
600
|
+
"external_reference",
|
|
601
|
+
"circular_reference",
|
|
602
|
+
"schema_keyword",
|
|
603
|
+
"schema_reference",
|
|
604
|
+
"missing_component",
|
|
605
|
+
"openapi_version",
|
|
606
|
+
"auth_helper",
|
|
607
|
+
"auth_missing",
|
|
608
|
+
"operation_path",
|
|
609
|
+
"duplicate_operation",
|
|
610
|
+
"server_missing",
|
|
611
|
+
"multiple_hosts",
|
|
612
|
+
"parameter_encoding",
|
|
613
|
+
"parameter_style",
|
|
614
|
+
"request_body",
|
|
615
|
+
"combined_oauth",
|
|
616
|
+
"auth_method",
|
|
617
|
+
"input_schema",
|
|
618
|
+
"no_operations",
|
|
619
|
+
"no_supported_operations",
|
|
620
|
+
"invalid_document",
|
|
621
|
+
"source_generation",
|
|
622
|
+
"authoring_reference"
|
|
623
|
+
]);
|
|
624
|
+
var OpenapiCompileError = class extends Schema_exports.TaggedError()(
|
|
625
|
+
"OpenapiCompileError",
|
|
626
|
+
{
|
|
627
|
+
code: OpenapiCompileErrorCode,
|
|
628
|
+
reason: Schema_exports.String
|
|
629
|
+
}
|
|
630
|
+
) {
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// src/contracts/openapi-document.ts
|
|
634
|
+
var Server = Schema_exports.Struct({ url: Schema_exports.String, variables: Schema_exports.optionalKey(JsonObject) });
|
|
635
|
+
var Specification = Schema_exports.Struct({
|
|
636
|
+
openapi: Schema_exports.String,
|
|
637
|
+
servers: Schema_exports.optionalKey(Schema_exports.Array(Server)),
|
|
638
|
+
paths: Schema_exports.Record(Schema_exports.String, JsonObject),
|
|
639
|
+
components: Schema_exports.optionalKey(
|
|
640
|
+
Schema_exports.Struct({
|
|
641
|
+
schemas: Schema_exports.optionalKey(Schema_exports.Record(Schema_exports.String, JsonObject)),
|
|
642
|
+
securitySchemes: Schema_exports.optionalKey(Schema_exports.Record(Schema_exports.String, JsonObject))
|
|
643
|
+
})
|
|
644
|
+
),
|
|
645
|
+
security: Schema_exports.optionalKey(
|
|
646
|
+
Schema_exports.Array(Schema_exports.Record(Schema_exports.String, Schema_exports.Array(Schema_exports.String)))
|
|
647
|
+
)
|
|
648
|
+
});
|
|
649
|
+
var Operation = Schema_exports.Struct({
|
|
650
|
+
operationId: Schema_exports.optionalKey(Schema_exports.String),
|
|
651
|
+
responses: Schema_exports.optionalKey(Schema_exports.Record(Schema_exports.String, JsonObject)),
|
|
652
|
+
summary: Schema_exports.optionalKey(Schema_exports.String),
|
|
653
|
+
description: Schema_exports.optionalKey(Schema_exports.String),
|
|
654
|
+
parameters: Schema_exports.optionalKey(Schema_exports.Array(JsonObject)),
|
|
655
|
+
requestBody: Schema_exports.optionalKey(JsonObject),
|
|
656
|
+
security: Schema_exports.optionalKey(
|
|
657
|
+
Schema_exports.Array(Schema_exports.Record(Schema_exports.String, Schema_exports.Array(Schema_exports.String)))
|
|
658
|
+
),
|
|
659
|
+
servers: Schema_exports.optionalKey(Schema_exports.Array(Server))
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
// ../../node_modules/.bun/@scalar+helpers@0.14.0/node_modules/@scalar/helpers/dist/object/is-object.js
|
|
663
|
+
var isObject2 = (value) => {
|
|
664
|
+
if (value === null || typeof value !== "object") {
|
|
665
|
+
return false;
|
|
666
|
+
}
|
|
667
|
+
const proto = Object.getPrototypeOf(value);
|
|
668
|
+
return proto === Object.prototype || proto === null;
|
|
669
|
+
};
|
|
670
|
+
var isObjectLike = (value) => typeof value === "object" && value !== null;
|
|
671
|
+
|
|
672
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/helpers/clone-document.js
|
|
673
|
+
var ALIAS_EXPANSION_ENTRY_FLOOR = 1e5;
|
|
674
|
+
var MAX_ALIAS_EXPANSION_RATIO = 10;
|
|
675
|
+
var cloneDocument = (document) => {
|
|
676
|
+
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
677
|
+
const expansion = { sourceEntries: 0, copiedEntries: 0, sizes: /* @__PURE__ */ new Map() };
|
|
678
|
+
const clone = (value) => {
|
|
679
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "undefined") {
|
|
680
|
+
return value;
|
|
681
|
+
}
|
|
682
|
+
if (!Array.isArray(value) && !isObject2(value)) {
|
|
683
|
+
return structuredClone(value);
|
|
684
|
+
}
|
|
685
|
+
if (ancestors.has(value)) {
|
|
686
|
+
throw new Error("Cannot upgrade to OpenAPI 3.2: cyclic objects cannot be represented in JSON. Use $ref instead.");
|
|
687
|
+
}
|
|
688
|
+
const size = expansion.sizes.get(value) ?? 1 + (Array.isArray(value) ? value.length : Object.keys(value).length);
|
|
689
|
+
if (!expansion.sizes.has(value)) {
|
|
690
|
+
expansion.sizes.set(value, size);
|
|
691
|
+
expansion.sourceEntries += size;
|
|
692
|
+
}
|
|
693
|
+
expansion.copiedEntries += size;
|
|
694
|
+
if (expansion.copiedEntries > ALIAS_EXPANSION_ENTRY_FLOOR && expansion.copiedEntries > expansion.sourceEntries * MAX_ALIAS_EXPANSION_RATIO) {
|
|
695
|
+
throw new Error("Cannot upgrade to OpenAPI 3.2: excessive YAML alias expansion. Use $ref for shared schemas.");
|
|
696
|
+
}
|
|
697
|
+
ancestors.add(value);
|
|
698
|
+
const result = Array.isArray(value) ? value.map(clone) : Object.fromEntries(Object.entries(value).map(([key, item]) => [key, clone(item)]));
|
|
699
|
+
ancestors.delete(value);
|
|
700
|
+
return result;
|
|
701
|
+
};
|
|
702
|
+
return clone(document);
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
// ../../node_modules/.bun/@scalar+helpers@0.14.0/node_modules/@scalar/helpers/dist/json/escape-json-pointer.js
|
|
706
|
+
var escapeJsonPointer = (str) => str.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
707
|
+
|
|
708
|
+
// ../../node_modules/.bun/@scalar+helpers@0.14.0/node_modules/@scalar/helpers/dist/json/unescape-json-pointer.js
|
|
709
|
+
var unescapeJsonPointer = (uri) => decodeURI(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
710
|
+
|
|
711
|
+
// ../../node_modules/.bun/@scalar+helpers@0.14.0/node_modules/@scalar/helpers/dist/json/parse-json-pointer-segments.js
|
|
712
|
+
var parseJsonPointerSegments = (path) => path.split("/").slice(1).map(unescapeJsonPointer);
|
|
713
|
+
|
|
714
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/upgrade-incompatibility-error.js
|
|
715
|
+
var UpgradeIncompatibilityError = class extends AggregateError {
|
|
716
|
+
errors;
|
|
717
|
+
constructor(errors) {
|
|
718
|
+
super(errors, errors.map((error) => error.message).join("\n"));
|
|
719
|
+
this.errors = errors;
|
|
720
|
+
this.name = "UpgradeIncompatibilityError";
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/3.1-to-3.2/migrate-objects.js
|
|
725
|
+
var schemaMaps = ["properties", "patternProperties", "$defs", "dependentSchemas"];
|
|
726
|
+
var schemaArrays = ["allOf", "anyOf", "oneOf", "prefixItems"];
|
|
727
|
+
var schemaSingles = [
|
|
728
|
+
"items",
|
|
729
|
+
"contains",
|
|
730
|
+
"additionalProperties",
|
|
731
|
+
"unevaluatedProperties",
|
|
732
|
+
"unevaluatedItems",
|
|
733
|
+
"propertyNames",
|
|
734
|
+
"not",
|
|
735
|
+
"if",
|
|
736
|
+
"then",
|
|
737
|
+
"else",
|
|
738
|
+
"contentSchema"
|
|
739
|
+
];
|
|
740
|
+
var migrateObjects = (document) => {
|
|
741
|
+
const properties = /* @__PURE__ */ new WeakMap();
|
|
742
|
+
const own = (value, key) => {
|
|
743
|
+
const entries = properties.get(value) ?? new Map(Object.entries(Object.getOwnPropertyDescriptors(value)).filter(([, descriptor]) => Object.hasOwn(descriptor, "value")).map(([name, descriptor]) => [name, descriptor.value]));
|
|
744
|
+
properties.set(value, entries);
|
|
745
|
+
return entries.get(key);
|
|
746
|
+
};
|
|
747
|
+
const operationTags = /* @__PURE__ */ new Set();
|
|
748
|
+
const errors = [];
|
|
749
|
+
const requiredCache = /* @__PURE__ */ new WeakMap();
|
|
750
|
+
const cyclicRequired = /* @__PURE__ */ new WeakSet();
|
|
751
|
+
const requiredWork = { evaluations: 0 };
|
|
752
|
+
const propertySchemas = /* @__PURE__ */ new WeakSet();
|
|
753
|
+
const xmlRoots = [];
|
|
754
|
+
const markPropertySchema = (schema2) => {
|
|
755
|
+
if (!isObject2(schema2) || propertySchemas.has(schema2)) {
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
propertySchemas.add(schema2);
|
|
759
|
+
markPropertySchema(schema2.items);
|
|
760
|
+
if (Array.isArray(schema2.prefixItems)) {
|
|
761
|
+
schema2.prefixItems.forEach(markPropertySchema);
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
const xmlCache = /* @__PURE__ */ new WeakMap();
|
|
765
|
+
const visited = /* @__PURE__ */ new WeakMap();
|
|
766
|
+
const fail3 = (path, message) => {
|
|
767
|
+
errors.push(new Error(`Cannot upgrade to OpenAPI 3.2 at ${path}: ${message}`));
|
|
768
|
+
};
|
|
769
|
+
const resolve = (ref, schemaReference = false) => {
|
|
770
|
+
if (typeof ref !== "string" || !ref.startsWith("#/")) {
|
|
771
|
+
return void 0;
|
|
772
|
+
}
|
|
773
|
+
try {
|
|
774
|
+
return parseJsonPointerSegments(decodeURIComponent(ref.slice(1))).reduce((value, key) => {
|
|
775
|
+
if (schemaReference && isObject2(value) && (value.$id !== void 0 || value.$schema !== void 0)) {
|
|
776
|
+
return void 0;
|
|
777
|
+
}
|
|
778
|
+
if (Array.isArray(value) && !/^(0|[1-9]\d*)$/.test(key)) {
|
|
779
|
+
return void 0;
|
|
780
|
+
}
|
|
781
|
+
if (!isObject2(value) && !Array.isArray(value) || !Object.hasOwn(value, key)) {
|
|
782
|
+
return void 0;
|
|
783
|
+
}
|
|
784
|
+
return own(value, key);
|
|
785
|
+
}, document);
|
|
786
|
+
} catch {
|
|
787
|
+
return void 0;
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
const repeatedVariables = (value, path) => {
|
|
791
|
+
if (typeof value !== "string") {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
const names = [...value.matchAll(/\{([^{}]+)\}/g)].map((match) => match[1]);
|
|
795
|
+
if (new Set(names).size !== names.length) {
|
|
796
|
+
fail3(path, "Template variables must not be repeated. Rename the repeated variable and define it separately.");
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
const requires = (schema2, name, seen = /* @__PURE__ */ new Set()) => {
|
|
800
|
+
if (schema2 === false) {
|
|
801
|
+
return true;
|
|
802
|
+
}
|
|
803
|
+
if (schema2 === true) {
|
|
804
|
+
return false;
|
|
805
|
+
}
|
|
806
|
+
if (!isObject2(schema2) || schema2.$id !== void 0 || schema2.$schema !== void 0) {
|
|
807
|
+
return void 0;
|
|
808
|
+
}
|
|
809
|
+
if (seen.has(schema2)) {
|
|
810
|
+
for (const ancestor of seen) {
|
|
811
|
+
cyclicRequired.add(ancestor);
|
|
812
|
+
}
|
|
813
|
+
return void 0;
|
|
814
|
+
}
|
|
815
|
+
const cached = requiredCache.get(schema2) ?? /* @__PURE__ */ new Map();
|
|
816
|
+
if (cached.has(name)) {
|
|
817
|
+
return cached.get(name);
|
|
818
|
+
}
|
|
819
|
+
if (++requiredWork.evaluations > 1e5) {
|
|
820
|
+
if (requiredWork.evaluations === 100001) {
|
|
821
|
+
fail3("#", "Discriminator requiredness analysis was truncated after 100,000 evaluations.");
|
|
822
|
+
}
|
|
823
|
+
return void 0;
|
|
824
|
+
}
|
|
825
|
+
const remember2 = (result) => {
|
|
826
|
+
if (result !== void 0 || !cyclicRequired.has(schema2)) {
|
|
827
|
+
cached.set(name, result);
|
|
828
|
+
requiredCache.set(schema2, cached);
|
|
829
|
+
}
|
|
830
|
+
return result;
|
|
831
|
+
};
|
|
832
|
+
if (Array.isArray(schema2.required) && schema2.required.includes(name)) {
|
|
833
|
+
return remember2(true);
|
|
834
|
+
}
|
|
835
|
+
const next = /* @__PURE__ */ new Set([...seen, schema2]);
|
|
836
|
+
const constraints = [];
|
|
837
|
+
if (schema2.$ref !== void 0) {
|
|
838
|
+
constraints.push(requires(resolve(schema2.$ref, true), name, next));
|
|
839
|
+
}
|
|
840
|
+
if (Array.isArray(schema2.allOf)) {
|
|
841
|
+
constraints.push(...schema2.allOf.map((item) => requires(item, name, next)));
|
|
842
|
+
}
|
|
843
|
+
for (const keyword of ["oneOf", "anyOf"]) {
|
|
844
|
+
if (Array.isArray(schema2[keyword])) {
|
|
845
|
+
const alternatives = schema2[keyword].map((item) => requires(item, name, next));
|
|
846
|
+
if (alternatives.every((value) => value === true)) {
|
|
847
|
+
constraints.push(true);
|
|
848
|
+
} else if (alternatives.every((value) => value === false)) {
|
|
849
|
+
constraints.push(false);
|
|
850
|
+
} else {
|
|
851
|
+
constraints.push(void 0);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
if (constraints.includes(true)) {
|
|
856
|
+
return remember2(true);
|
|
857
|
+
}
|
|
858
|
+
if (constraints.includes(void 0) || ["if", "not", "$dynamicRef", "const", "enum", "minProperties", "dependentRequired", "dependentSchemas"].some((key) => key in schema2)) {
|
|
859
|
+
return remember2(void 0);
|
|
860
|
+
}
|
|
861
|
+
return remember2(false);
|
|
862
|
+
};
|
|
863
|
+
const validateXmlNames = (schema2, path, { inferredName, propertyName, dialect, ancestors = /* @__PURE__ */ new Set(), baseChanged = false }) => {
|
|
864
|
+
if (!isObject2(schema2) || ancestors.has(schema2) || (schema2.$schema ?? dialect) !== void 0) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const changedBase = baseChanged || schema2.$id !== void 0;
|
|
868
|
+
const context = [inferredName, propertyName, changedBase].join(":");
|
|
869
|
+
const completed = xmlCache.get(schema2) ?? /* @__PURE__ */ new Set();
|
|
870
|
+
if (completed.has(context)) {
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
const xml = isObject2(schema2.xml) ? schema2.xml : {};
|
|
874
|
+
const defaultNodeType = schema2.$ref !== void 0 || schema2.$dynamicRef !== void 0 || schema2.type === "array" ? "none" : "element";
|
|
875
|
+
const wrappedNodeType = xml.wrapped === true ? "element" : defaultNodeType;
|
|
876
|
+
const nodeType = xml.nodeType ?? (xml.attribute === true ? "attribute" : wrappedNodeType);
|
|
877
|
+
if ((nodeType === "element" || nodeType === "attribute") && !inferredName && xml.name === void 0) {
|
|
878
|
+
fail3(path, "An inline XML element needs an explicit xml.name.");
|
|
879
|
+
}
|
|
880
|
+
const childContext = { dialect, ancestors: /* @__PURE__ */ new Set([...ancestors, schema2]), baseChanged: changedBase };
|
|
881
|
+
if (!changedBase && typeof schema2.$ref === "string") {
|
|
882
|
+
const target = resolve(schema2.$ref, true);
|
|
883
|
+
if (isObject2(target)) {
|
|
884
|
+
const segments2 = parseJsonPointerSegments(decodeURIComponent(schema2.$ref.slice(1)));
|
|
885
|
+
const componentRoot = segments2.length === 3 && segments2[0] === "components" && segments2[1] === "schemas";
|
|
886
|
+
const fromProperty = propertySchemas.has(target);
|
|
887
|
+
validateXmlNames(target, schema2.$ref, {
|
|
888
|
+
...childContext,
|
|
889
|
+
inferredName: componentRoot || fromProperty,
|
|
890
|
+
propertyName: fromProperty
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
for (const keyword of ["allOf", "anyOf", "oneOf"]) {
|
|
895
|
+
const branches = schema2[keyword];
|
|
896
|
+
if (Array.isArray(branches)) {
|
|
897
|
+
branches.forEach((branch, index) => validateXmlNames(branch, path + "/" + keyword + "/" + index, {
|
|
898
|
+
...childContext,
|
|
899
|
+
inferredName: false,
|
|
900
|
+
propertyName: false
|
|
901
|
+
}));
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
validateXmlNames(schema2.items, path + "/items", { ...childContext, inferredName: propertyName, propertyName });
|
|
905
|
+
if (Array.isArray(schema2.prefixItems)) {
|
|
906
|
+
schema2.prefixItems.forEach((item, index) => validateXmlNames(item, path + "/prefixItems/" + index, {
|
|
907
|
+
...childContext,
|
|
908
|
+
inferredName: propertyName,
|
|
909
|
+
propertyName
|
|
910
|
+
}));
|
|
911
|
+
}
|
|
912
|
+
if (isObject2(schema2.properties)) {
|
|
913
|
+
for (const [name, property] of Object.entries(schema2.properties)) {
|
|
914
|
+
validateXmlNames(property, path + "/properties/" + escapeJsonPointer(name), {
|
|
915
|
+
...childContext,
|
|
916
|
+
inferredName: true,
|
|
917
|
+
propertyName: true
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
completed.add(context);
|
|
922
|
+
xmlCache.set(schema2, completed);
|
|
923
|
+
};
|
|
924
|
+
const visit = (value, kind, path, dialect = document.jsonSchemaDialect, baseChanged = false) => {
|
|
925
|
+
if (!isObject2(value)) {
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
const schemaDialect = kind === "schema" ? value.$schema ?? dialect : dialect;
|
|
929
|
+
const schemaBaseChanged = baseChanged || kind === "schema" && value.$id !== void 0;
|
|
930
|
+
const visitKey = `${kind}:${String(schemaDialect)}:${schemaBaseChanged}`;
|
|
931
|
+
const seen = visited.get(value) ?? /* @__PURE__ */ new Set();
|
|
932
|
+
if (seen.has(visitKey)) {
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
seen.add(visitKey);
|
|
936
|
+
visited.set(value, seen);
|
|
937
|
+
const child = (key, type) => visit(own(value, key), type, `${path}/${escapeJsonPointer(key)}`, schemaDialect, schemaBaseChanged);
|
|
938
|
+
const list = (key, type) => {
|
|
939
|
+
const items = own(value, key);
|
|
940
|
+
if (Array.isArray(items)) {
|
|
941
|
+
items.forEach((item, index) => visit(item, type, `${path}/${key}/${index}`, schemaDialect, schemaBaseChanged));
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
const map = (key, type) => {
|
|
945
|
+
const items = own(value, key);
|
|
946
|
+
if (isObject2(items)) {
|
|
947
|
+
for (const [name, item] of Object.entries(items)) {
|
|
948
|
+
if (key === "responses" && name.startsWith("x-")) {
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
if (kind === "schema" && key === "properties") {
|
|
952
|
+
markPropertySchema(item);
|
|
953
|
+
}
|
|
954
|
+
visit(item, type, `${path}/${key}/${escapeJsonPointer(name)}`, schemaDialect, schemaBaseChanged);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
if (kind === "schema") {
|
|
959
|
+
if (schemaDialect !== void 0) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
const xml = own(value, "xml");
|
|
963
|
+
if (isObject2(xml)) {
|
|
964
|
+
if (xml.wrapped === true && xml.attribute === true) {
|
|
965
|
+
fail3(`${path}/xml`, "wrapped and attribute cannot both be true.");
|
|
966
|
+
}
|
|
967
|
+
if (xml.wrapped === true || xml.attribute === true) {
|
|
968
|
+
xml.nodeType = xml.attribute === true ? "attribute" : "element";
|
|
969
|
+
delete xml.wrapped;
|
|
970
|
+
delete xml.attribute;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
if (!schemaBaseChanged && value.$ref !== void 0) {
|
|
974
|
+
visit(resolve(value.$ref, true), "schema", String(value.$ref), schemaDialect);
|
|
975
|
+
}
|
|
976
|
+
const discriminator = value.discriminator;
|
|
977
|
+
if (isObject2(discriminator) && typeof discriminator.propertyName === "string" && discriminator.defaultMapping === void 0 && !schemaBaseChanged && requires(value, discriminator.propertyName) === false) {
|
|
978
|
+
fail3(`${path}/discriminator`, "An optional discriminating property needs an explicit defaultMapping.");
|
|
979
|
+
}
|
|
980
|
+
for (const key of schemaMaps) {
|
|
981
|
+
map(key, "schema");
|
|
982
|
+
}
|
|
983
|
+
for (const key of schemaArrays) {
|
|
984
|
+
list(key, "schema");
|
|
985
|
+
}
|
|
986
|
+
for (const key of schemaSingles) {
|
|
987
|
+
child(key, "schema");
|
|
988
|
+
}
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
if (value.$ref !== void 0) {
|
|
992
|
+
visit(resolve(value.$ref), kind, String(value.$ref), schemaDialect);
|
|
993
|
+
}
|
|
994
|
+
switch (kind) {
|
|
995
|
+
case "document": {
|
|
996
|
+
const paths = own(value, "paths");
|
|
997
|
+
if (isObject2(paths)) {
|
|
998
|
+
for (const [name, item] of Object.entries(paths)) {
|
|
999
|
+
if (!name.startsWith("/")) {
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1002
|
+
const location = `${path}/paths/${escapeJsonPointer(name)}`;
|
|
1003
|
+
repeatedVariables(name, location);
|
|
1004
|
+
visit(item, "pathItem", location);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
map("webhooks", "pathItem");
|
|
1008
|
+
list("servers", "server");
|
|
1009
|
+
const componentObjects = own(value, "components");
|
|
1010
|
+
if (isObject2(componentObjects)) {
|
|
1011
|
+
const components = {
|
|
1012
|
+
schemas: "schema",
|
|
1013
|
+
parameters: "parameter",
|
|
1014
|
+
headers: "header",
|
|
1015
|
+
requestBodies: "body",
|
|
1016
|
+
responses: "response",
|
|
1017
|
+
callbacks: "callback",
|
|
1018
|
+
pathItems: "pathItem"
|
|
1019
|
+
};
|
|
1020
|
+
for (const [key, type] of Object.entries(components)) {
|
|
1021
|
+
const entries = own(componentObjects, key);
|
|
1022
|
+
if (isObject2(entries)) {
|
|
1023
|
+
for (const [name, item] of Object.entries(entries)) {
|
|
1024
|
+
visit(item, type, `${path}/components/${key}/${escapeJsonPointer(name)}`);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
break;
|
|
1030
|
+
}
|
|
1031
|
+
case "pathItem":
|
|
1032
|
+
for (const method of ["get", "put", "post", "delete", "options", "head", "patch", "trace"]) {
|
|
1033
|
+
child(method, "operation");
|
|
1034
|
+
}
|
|
1035
|
+
list("parameters", "parameter");
|
|
1036
|
+
list("servers", "server");
|
|
1037
|
+
break;
|
|
1038
|
+
case "operation":
|
|
1039
|
+
if (Array.isArray(value.tags)) {
|
|
1040
|
+
for (const tag of value.tags) {
|
|
1041
|
+
if (typeof tag === "string") {
|
|
1042
|
+
operationTags.add(tag);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
list("parameters", "parameter");
|
|
1047
|
+
list("servers", "server");
|
|
1048
|
+
child("requestBody", "body");
|
|
1049
|
+
map("responses", "response");
|
|
1050
|
+
map("callbacks", "callback");
|
|
1051
|
+
break;
|
|
1052
|
+
case "callback":
|
|
1053
|
+
for (const [name, item] of Object.entries(value)) {
|
|
1054
|
+
if (!name.startsWith("x-") && name !== "$ref") {
|
|
1055
|
+
visit(item, "pathItem", `${path}/${escapeJsonPointer(name)}`, schemaDialect, schemaBaseChanged);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
break;
|
|
1059
|
+
case "parameter":
|
|
1060
|
+
if (value.in === "path" || value.in === "cookie") {
|
|
1061
|
+
delete value.allowReserved;
|
|
1062
|
+
}
|
|
1063
|
+
child("schema", "schema");
|
|
1064
|
+
map("content", "media");
|
|
1065
|
+
break;
|
|
1066
|
+
case "header":
|
|
1067
|
+
child("schema", "schema");
|
|
1068
|
+
map("content", "media");
|
|
1069
|
+
break;
|
|
1070
|
+
case "response":
|
|
1071
|
+
map("headers", "header");
|
|
1072
|
+
map("content", "media");
|
|
1073
|
+
break;
|
|
1074
|
+
case "body":
|
|
1075
|
+
map("content", "media");
|
|
1076
|
+
break;
|
|
1077
|
+
case "media":
|
|
1078
|
+
if (/\/(?:[^;]+\+)?xml(?:\s*;|$)/i.test(path.slice(path.lastIndexOf("/") + 1).replace(/~1/g, "/"))) {
|
|
1079
|
+
xmlRoots.push({ schema: value.schema, path: `${path}/schema`, dialect: schemaDialect });
|
|
1080
|
+
}
|
|
1081
|
+
child("schema", "schema");
|
|
1082
|
+
map("encoding", "encoding");
|
|
1083
|
+
break;
|
|
1084
|
+
case "encoding":
|
|
1085
|
+
map("headers", "header");
|
|
1086
|
+
break;
|
|
1087
|
+
case "server":
|
|
1088
|
+
repeatedVariables(value.url, `${path}/url`);
|
|
1089
|
+
break;
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
1092
|
+
visit(document, "document", "#");
|
|
1093
|
+
for (const { schema: schema2, path, dialect } of xmlRoots) {
|
|
1094
|
+
validateXmlNames(schema2, path, { inferredName: false, propertyName: false, dialect });
|
|
1095
|
+
}
|
|
1096
|
+
if (errors.length > 0) {
|
|
1097
|
+
throw new UpgradeIncompatibilityError(errors);
|
|
1098
|
+
}
|
|
1099
|
+
return operationTags;
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/3.1-to-3.2/migrate-tag-groups.js
|
|
1103
|
+
var migrateTagGroups = (document, operationTags) => {
|
|
1104
|
+
const groups = document["x-tagGroups"];
|
|
1105
|
+
if (!Array.isArray(groups) || groups.length === 0) {
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
if (document.tags !== void 0 && !Array.isArray(document.tags)) {
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
const tags = document.tags ?? [];
|
|
1112
|
+
if (!tags.every((tag) => isObject2(tag) && typeof tag.name === "string")) {
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
const existing = new Map(tags.map((tag) => [tag.name, tag]));
|
|
1116
|
+
const parents = /* @__PURE__ */ new Set();
|
|
1117
|
+
const children = /* @__PURE__ */ new Set();
|
|
1118
|
+
for (const group of groups) {
|
|
1119
|
+
if (!isObject2(group) || typeof group.name !== "string" || !group.name || !Array.isArray(group.tags) || !group.tags.every((name) => typeof name === "string") || Object.keys(group).some((key) => key !== "name" && key !== "tags") || parents.has(group.name) || existing.has(group.name) || operationTags.has(group.name)) {
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
parents.add(group.name);
|
|
1123
|
+
for (const name of group.tags) {
|
|
1124
|
+
if (children.has(name) || existing.get(name)?.parent !== void 0) {
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
children.add(name);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
if ([...parents].some((name) => children.has(name)) || existing.size !== tags.length) {
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
const result = [];
|
|
1134
|
+
for (const group of groups) {
|
|
1135
|
+
result.push({ name: group.name, kind: "nav" });
|
|
1136
|
+
for (const name of group.tags) {
|
|
1137
|
+
result.push({ ...existing.get(name) ?? { name }, parent: group.name });
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
document.tags = [...result, ...tags.filter((tag) => !children.has(tag.name))];
|
|
1141
|
+
};
|
|
1142
|
+
|
|
1143
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/3.1-to-3.2/upgrade-from-three-one-to-three-two.js
|
|
1144
|
+
var isThreeOneDocument = (document) => {
|
|
1145
|
+
if (!isObject2(document) || typeof document.openapi !== "string") {
|
|
1146
|
+
return false;
|
|
1147
|
+
}
|
|
1148
|
+
if (/^3\.1\.\d+$/.test(document.openapi)) {
|
|
1149
|
+
return true;
|
|
1150
|
+
}
|
|
1151
|
+
if (/^3\.1(?:\D|$)/.test(document.openapi)) {
|
|
1152
|
+
throw new Error(`Cannot upgrade to OpenAPI 3.2: invalid OpenAPI version "${document.openapi}". Expected 3.1.x with a numeric patch version.`);
|
|
1153
|
+
}
|
|
1154
|
+
return false;
|
|
1155
|
+
};
|
|
1156
|
+
var migrateThreeOneToThreeTwo = (document) => {
|
|
1157
|
+
if (!isThreeOneDocument(document)) {
|
|
1158
|
+
return document;
|
|
1159
|
+
}
|
|
1160
|
+
const operationTags = migrateObjects(document);
|
|
1161
|
+
migrateTagGroups(document, operationTags);
|
|
1162
|
+
document.openapi = "3.2.0";
|
|
1163
|
+
return document;
|
|
1164
|
+
};
|
|
1165
|
+
|
|
1166
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/helpers/traverse.js
|
|
1167
|
+
function traverse(content, transform, path = []) {
|
|
1168
|
+
const result = {};
|
|
1169
|
+
for (const [key, value] of Object.entries(content)) {
|
|
1170
|
+
const currentPath = [...path, key];
|
|
1171
|
+
if (Array.isArray(value)) {
|
|
1172
|
+
result[key] = value.map((item, index) => {
|
|
1173
|
+
if (typeof item === "object" && !Array.isArray(item) && item !== null) {
|
|
1174
|
+
return traverse(item, transform, [...currentPath, index.toString()]);
|
|
1175
|
+
}
|
|
1176
|
+
return item;
|
|
1177
|
+
});
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
1180
|
+
if (isObjectLike(value)) {
|
|
1181
|
+
result[key] = traverse(value, transform, currentPath);
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
result[key] = value;
|
|
1185
|
+
}
|
|
1186
|
+
return transform(result, path);
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/2.0-to-3.0/upgrade-from-two-to-three.js
|
|
1190
|
+
var DEFAULT_MEDIA_TYPE = "application/json";
|
|
1191
|
+
function extractXExampleExtensions(obj) {
|
|
1192
|
+
const xExample = obj["x-example"];
|
|
1193
|
+
const xExamples = obj["x-examples"];
|
|
1194
|
+
delete obj["x-example"];
|
|
1195
|
+
delete obj["x-examples"];
|
|
1196
|
+
return { xExample, xExamples };
|
|
1197
|
+
}
|
|
1198
|
+
function isNonEmptyObject(value) {
|
|
1199
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0;
|
|
1200
|
+
}
|
|
1201
|
+
function isNamedExamplesCollection(value) {
|
|
1202
|
+
return isNonEmptyObject(value) && Object.values(value).every((v) => typeof v === "object" && v !== null && !Array.isArray(v));
|
|
1203
|
+
}
|
|
1204
|
+
function isEmptySchema(schema2) {
|
|
1205
|
+
if (!isObjectLike(schema2)) {
|
|
1206
|
+
return true;
|
|
1207
|
+
}
|
|
1208
|
+
const s = schema2;
|
|
1209
|
+
const substantiveValidationKeywords = [
|
|
1210
|
+
"enum",
|
|
1211
|
+
"const",
|
|
1212
|
+
"not",
|
|
1213
|
+
"format",
|
|
1214
|
+
"multipleOf",
|
|
1215
|
+
"maximum",
|
|
1216
|
+
"exclusiveMaximum",
|
|
1217
|
+
"minimum",
|
|
1218
|
+
"exclusiveMinimum",
|
|
1219
|
+
"maxLength",
|
|
1220
|
+
"minLength",
|
|
1221
|
+
"pattern",
|
|
1222
|
+
"maxItems",
|
|
1223
|
+
"minItems",
|
|
1224
|
+
"uniqueItems",
|
|
1225
|
+
"maxProperties",
|
|
1226
|
+
"minProperties",
|
|
1227
|
+
"required"
|
|
1228
|
+
];
|
|
1229
|
+
if (s.allOf || s.oneOf || s.anyOf || s.items || s.$ref || "additionalProperties" in s || substantiveValidationKeywords.some((key) => key in s)) {
|
|
1230
|
+
return false;
|
|
1231
|
+
}
|
|
1232
|
+
if (typeof s.properties === "object" && s.properties !== null && Object.keys(s.properties).length > 0) {
|
|
1233
|
+
return false;
|
|
1234
|
+
}
|
|
1235
|
+
return true;
|
|
1236
|
+
}
|
|
1237
|
+
function removeEmptySchemaOnlyContentEntries(content) {
|
|
1238
|
+
const keys = Object.keys(content);
|
|
1239
|
+
const hasEntryWithExample = keys.some((key) => {
|
|
1240
|
+
const entry = content[key];
|
|
1241
|
+
return isObjectLike(entry) && (entry.example !== void 0 || entry.examples !== void 0);
|
|
1242
|
+
});
|
|
1243
|
+
if (!hasEntryWithExample) {
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
for (const key of keys) {
|
|
1247
|
+
const entry = content[key];
|
|
1248
|
+
if (!isObjectLike(entry))
|
|
1249
|
+
continue;
|
|
1250
|
+
const hasExample = entry.example !== void 0 || entry.examples !== void 0;
|
|
1251
|
+
const hasOnlySchema = entry.schema !== void 0 && !hasExample && Object.keys(entry).length === 1;
|
|
1252
|
+
if (hasOnlySchema && isEmptySchema(entry.schema)) {
|
|
1253
|
+
delete content[key];
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
var EXAMPLE_OBJECT_PROPERTIES = /* @__PURE__ */ new Set(["summary", "description", "value", "externalValue"]);
|
|
1258
|
+
function isExampleObject(value) {
|
|
1259
|
+
if (typeof value !== "object" || value === null) {
|
|
1260
|
+
return false;
|
|
1261
|
+
}
|
|
1262
|
+
const obj = value;
|
|
1263
|
+
const hasValueOrExternalValue = "value" in obj || "externalValue" in obj;
|
|
1264
|
+
const onlyHasAllowedProperties = Object.keys(obj).every((key) => EXAMPLE_OBJECT_PROPERTIES.has(key));
|
|
1265
|
+
return hasValueOrExternalValue && onlyHasAllowedProperties;
|
|
1266
|
+
}
|
|
1267
|
+
function wrapAsExampleObject(value) {
|
|
1268
|
+
if (isExampleObject(value)) {
|
|
1269
|
+
return value;
|
|
1270
|
+
}
|
|
1271
|
+
return { value };
|
|
1272
|
+
}
|
|
1273
|
+
var MEDIA_TYPE_KEY_PATTERN = /^[a-zA-Z0-9*+.-]+\/[a-zA-Z0-9*+.+-]+$/;
|
|
1274
|
+
function isMediaTypeKey(key) {
|
|
1275
|
+
return MEDIA_TYPE_KEY_PATTERN.test(key);
|
|
1276
|
+
}
|
|
1277
|
+
function transformXExampleToExamples(xExample) {
|
|
1278
|
+
return Object.entries(xExample).reduce((acc, [key, value]) => {
|
|
1279
|
+
acc[key] = { value };
|
|
1280
|
+
return acc;
|
|
1281
|
+
}, {});
|
|
1282
|
+
}
|
|
1283
|
+
var upgradeFlow = (flow) => {
|
|
1284
|
+
switch (flow) {
|
|
1285
|
+
case "application":
|
|
1286
|
+
return "clientCredentials";
|
|
1287
|
+
case "accessCode":
|
|
1288
|
+
return "authorizationCode";
|
|
1289
|
+
case "implicit":
|
|
1290
|
+
return "implicit";
|
|
1291
|
+
case "password":
|
|
1292
|
+
return "password";
|
|
1293
|
+
default:
|
|
1294
|
+
return flow;
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
function upgradeFromTwoToThree(originalSpecification) {
|
|
1298
|
+
let document = originalSpecification;
|
|
1299
|
+
if (document !== null && typeof document === "object" && typeof document.swagger === "string" && document.swagger?.startsWith("2.0")) {
|
|
1300
|
+
document.openapi = "3.0.4";
|
|
1301
|
+
delete document.swagger;
|
|
1302
|
+
} else {
|
|
1303
|
+
return document;
|
|
1304
|
+
}
|
|
1305
|
+
if (document.host) {
|
|
1306
|
+
const schemes = Array.isArray(document.schemes) && document.schemes?.length ? document.schemes : ["http"];
|
|
1307
|
+
document.servers = schemes.map((scheme) => ({
|
|
1308
|
+
url: `${scheme}://${document.host}${document.basePath ?? ""}`
|
|
1309
|
+
}));
|
|
1310
|
+
delete document.basePath;
|
|
1311
|
+
delete document.schemes;
|
|
1312
|
+
delete document.host;
|
|
1313
|
+
} else if (document.basePath) {
|
|
1314
|
+
document.servers = [{ url: document.basePath }];
|
|
1315
|
+
delete document.basePath;
|
|
1316
|
+
}
|
|
1317
|
+
if (document.definitions) {
|
|
1318
|
+
for (const schema2 of Object.values(document.definitions)) {
|
|
1319
|
+
migrateSchemaNullability(schema2);
|
|
1320
|
+
}
|
|
1321
|
+
document.components = Object.assign({}, document.components, {
|
|
1322
|
+
schemas: document.definitions
|
|
1323
|
+
});
|
|
1324
|
+
delete document.definitions;
|
|
1325
|
+
document = traverse(document, (schema2) => {
|
|
1326
|
+
if (typeof schema2.$ref === "string" && schema2.$ref.startsWith("#/definitions/")) {
|
|
1327
|
+
schema2.$ref = schema2.$ref.replace(/^#\/definitions\//, "#/components/schemas/");
|
|
1328
|
+
}
|
|
1329
|
+
return schema2;
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
document = traverse(document, (schema2) => {
|
|
1333
|
+
if (schema2.type === "file") {
|
|
1334
|
+
schema2.type = "string";
|
|
1335
|
+
schema2.format = "binary";
|
|
1336
|
+
}
|
|
1337
|
+
return schema2;
|
|
1338
|
+
});
|
|
1339
|
+
if (Object.hasOwn(document, "parameters")) {
|
|
1340
|
+
document = traverse(document, (schema2) => {
|
|
1341
|
+
if (typeof schema2.$ref === "string" && schema2.$ref.startsWith("#/parameters/")) {
|
|
1342
|
+
const schemaName = schema2.$ref.split("/")[2];
|
|
1343
|
+
if (!schemaName) {
|
|
1344
|
+
return schema2;
|
|
1345
|
+
}
|
|
1346
|
+
const param = isObjectLike(document.parameters) && schemaName in document.parameters ? document.parameters[schemaName] : void 0;
|
|
1347
|
+
if (param && typeof param === "object" && "in" in param && (param.in === "body" || param.in === "formData")) {
|
|
1348
|
+
schema2.$ref = schema2.$ref.replace(/^#\/parameters\//, "#/components/requestBodies/");
|
|
1349
|
+
} else {
|
|
1350
|
+
schema2.$ref = schema2.$ref.replace(/^#\/parameters\//, "#/components/parameters/");
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
return schema2;
|
|
1354
|
+
});
|
|
1355
|
+
document.components ??= {};
|
|
1356
|
+
const params = {};
|
|
1357
|
+
const bodyParams = {};
|
|
1358
|
+
const parameters = isObjectLike(document.parameters) ? document.parameters : {};
|
|
1359
|
+
for (const [name, param] of Object.entries(parameters)) {
|
|
1360
|
+
if (param && typeof param === "object") {
|
|
1361
|
+
if ("$ref" in param) {
|
|
1362
|
+
const convertedParam = transformParameterObject(param);
|
|
1363
|
+
params[name] = convertedParam;
|
|
1364
|
+
} else if ("in" in param) {
|
|
1365
|
+
if (param.in === "body") {
|
|
1366
|
+
bodyParams[name] = migrateBodyParameter(param, document.consumes ?? [DEFAULT_MEDIA_TYPE]);
|
|
1367
|
+
} else if (param.in === "formData") {
|
|
1368
|
+
bodyParams[name] = migrateFormDataParameter([param], document.consumes);
|
|
1369
|
+
} else {
|
|
1370
|
+
const convertedParam = transformParameterObject(param);
|
|
1371
|
+
params[name] = convertedParam;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
if (Object.keys(params).length > 0) {
|
|
1377
|
+
;
|
|
1378
|
+
document.components.parameters = params;
|
|
1379
|
+
}
|
|
1380
|
+
if (Object.keys(bodyParams).length > 0) {
|
|
1381
|
+
;
|
|
1382
|
+
document.components.requestBodies = bodyParams;
|
|
1383
|
+
}
|
|
1384
|
+
delete document.parameters;
|
|
1385
|
+
}
|
|
1386
|
+
if (Object.hasOwn(document, "responses") && typeof document.responses === "object" && document.responses !== null) {
|
|
1387
|
+
document = traverse(document, (schema2) => {
|
|
1388
|
+
if (typeof schema2.$ref === "string" && schema2.$ref.startsWith("#/responses/")) {
|
|
1389
|
+
schema2.$ref = schema2.$ref.replace(/^#\/responses\//, "#/components/responses/");
|
|
1390
|
+
}
|
|
1391
|
+
return schema2;
|
|
1392
|
+
});
|
|
1393
|
+
document.components ??= {};
|
|
1394
|
+
const migratedResponses = {};
|
|
1395
|
+
const responses = document.responses;
|
|
1396
|
+
for (const [name, response] of Object.entries(responses)) {
|
|
1397
|
+
if (isObjectLike(response)) {
|
|
1398
|
+
if ("$ref" in response) {
|
|
1399
|
+
migratedResponses[name] = response;
|
|
1400
|
+
} else {
|
|
1401
|
+
const responseObj = response;
|
|
1402
|
+
const produces = document.produces ?? [DEFAULT_MEDIA_TYPE];
|
|
1403
|
+
if (responseObj.schema) {
|
|
1404
|
+
migrateSchemaNullability(responseObj.schema);
|
|
1405
|
+
if (typeof responseObj.content !== "object") {
|
|
1406
|
+
responseObj.content = {};
|
|
1407
|
+
}
|
|
1408
|
+
for (const type of produces) {
|
|
1409
|
+
;
|
|
1410
|
+
responseObj.content[type] = {
|
|
1411
|
+
schema: responseObj.schema
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
delete responseObj.schema;
|
|
1415
|
+
}
|
|
1416
|
+
if (responseObj.examples && typeof responseObj.examples === "object") {
|
|
1417
|
+
if (typeof responseObj.content !== "object") {
|
|
1418
|
+
responseObj.content = {};
|
|
1419
|
+
}
|
|
1420
|
+
const defaultMediaType = produces[0] ?? DEFAULT_MEDIA_TYPE;
|
|
1421
|
+
for (const [key, exampleValue] of Object.entries(responseObj.examples)) {
|
|
1422
|
+
if (isMediaTypeKey(key)) {
|
|
1423
|
+
if (typeof responseObj.content[key] !== "object") {
|
|
1424
|
+
;
|
|
1425
|
+
responseObj.content[key] = {};
|
|
1426
|
+
}
|
|
1427
|
+
;
|
|
1428
|
+
responseObj.content[key].example = exampleValue;
|
|
1429
|
+
} else {
|
|
1430
|
+
if (typeof responseObj.content[defaultMediaType] !== "object") {
|
|
1431
|
+
;
|
|
1432
|
+
responseObj.content[defaultMediaType] = {};
|
|
1433
|
+
}
|
|
1434
|
+
const mediaEntry = responseObj.content[defaultMediaType];
|
|
1435
|
+
if (typeof mediaEntry.examples !== "object") {
|
|
1436
|
+
mediaEntry.examples = {};
|
|
1437
|
+
}
|
|
1438
|
+
;
|
|
1439
|
+
mediaEntry.examples[key] = wrapAsExampleObject(exampleValue);
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
delete responseObj.examples;
|
|
1443
|
+
}
|
|
1444
|
+
if (responseObj.content && typeof responseObj.content === "object") {
|
|
1445
|
+
removeEmptySchemaOnlyContentEntries(responseObj.content);
|
|
1446
|
+
}
|
|
1447
|
+
if (isObjectLike(responseObj.headers)) {
|
|
1448
|
+
responseObj.headers = Object.entries(responseObj.headers).reduce((acc, [headerName, header]) => {
|
|
1449
|
+
if (header && typeof header === "object") {
|
|
1450
|
+
return {
|
|
1451
|
+
[headerName]: transformResponseHeader(header),
|
|
1452
|
+
...acc
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
return acc;
|
|
1456
|
+
}, {});
|
|
1457
|
+
}
|
|
1458
|
+
migratedResponses[name] = responseObj;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
if (Object.keys(migratedResponses).length > 0) {
|
|
1463
|
+
;
|
|
1464
|
+
document.components.responses = migratedResponses;
|
|
1465
|
+
}
|
|
1466
|
+
delete document.responses;
|
|
1467
|
+
}
|
|
1468
|
+
if (typeof document.paths === "object") {
|
|
1469
|
+
for (const path in document.paths) {
|
|
1470
|
+
if (Object.hasOwn(document.paths, path)) {
|
|
1471
|
+
const pathItem = isObjectLike(document.paths) && path in document.paths ? document.paths[path] : void 0;
|
|
1472
|
+
if (!pathItem || typeof pathItem !== "object") {
|
|
1473
|
+
continue;
|
|
1474
|
+
}
|
|
1475
|
+
let requestBodyObject;
|
|
1476
|
+
for (const methodOrParameters in pathItem) {
|
|
1477
|
+
if (methodOrParameters === "parameters" && Object.hasOwn(pathItem, methodOrParameters)) {
|
|
1478
|
+
const pathItemParameters = migrateParameters(pathItem.parameters, document.consumes ?? [DEFAULT_MEDIA_TYPE]);
|
|
1479
|
+
pathItem.parameters = pathItemParameters.parameters;
|
|
1480
|
+
requestBodyObject = pathItemParameters.requestBody;
|
|
1481
|
+
} else if (Object.hasOwn(pathItem, methodOrParameters)) {
|
|
1482
|
+
const operationItem = pathItem[methodOrParameters];
|
|
1483
|
+
if (requestBodyObject) {
|
|
1484
|
+
operationItem.requestBody = requestBodyObject;
|
|
1485
|
+
}
|
|
1486
|
+
if (operationItem.parameters) {
|
|
1487
|
+
const migrationResult = migrateParameters(operationItem.parameters, operationItem.consumes ?? document.consumes ?? [DEFAULT_MEDIA_TYPE]);
|
|
1488
|
+
operationItem.parameters = migrationResult.parameters;
|
|
1489
|
+
if (migrationResult.requestBody) {
|
|
1490
|
+
operationItem.requestBody = migrationResult.requestBody;
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
delete operationItem.consumes;
|
|
1494
|
+
if (operationItem.responses) {
|
|
1495
|
+
for (const response in operationItem.responses) {
|
|
1496
|
+
if (Object.hasOwn(operationItem.responses, response)) {
|
|
1497
|
+
const responseItem = operationItem.responses[response];
|
|
1498
|
+
if (responseItem.headers && typeof responseItem.headers === "object") {
|
|
1499
|
+
responseItem.headers = Object.entries(responseItem.headers).reduce((acc, [name, header]) => {
|
|
1500
|
+
if (header && typeof header === "object") {
|
|
1501
|
+
return {
|
|
1502
|
+
[name]: transformResponseHeader(header),
|
|
1503
|
+
...acc
|
|
1504
|
+
};
|
|
1505
|
+
}
|
|
1506
|
+
return acc;
|
|
1507
|
+
}, {});
|
|
1508
|
+
}
|
|
1509
|
+
if (responseItem.schema) {
|
|
1510
|
+
migrateSchemaNullability(responseItem.schema);
|
|
1511
|
+
const produces = document.produces ?? operationItem.produces ?? [DEFAULT_MEDIA_TYPE];
|
|
1512
|
+
if (typeof responseItem.content !== "object") {
|
|
1513
|
+
responseItem.content = {};
|
|
1514
|
+
}
|
|
1515
|
+
for (const type of produces) {
|
|
1516
|
+
responseItem.content[type] = {
|
|
1517
|
+
schema: responseItem.schema
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
delete responseItem.schema;
|
|
1521
|
+
}
|
|
1522
|
+
if (responseItem.examples && typeof responseItem.examples === "object") {
|
|
1523
|
+
if (typeof responseItem.content !== "object") {
|
|
1524
|
+
responseItem.content = {};
|
|
1525
|
+
}
|
|
1526
|
+
const produces = document.produces ?? operationItem.produces ?? [DEFAULT_MEDIA_TYPE];
|
|
1527
|
+
const defaultMediaType = produces[0] ?? DEFAULT_MEDIA_TYPE;
|
|
1528
|
+
for (const [key, exampleValue] of Object.entries(responseItem.examples)) {
|
|
1529
|
+
if (isMediaTypeKey(key)) {
|
|
1530
|
+
if (typeof responseItem.content[key] !== "object") {
|
|
1531
|
+
responseItem.content[key] = {};
|
|
1532
|
+
}
|
|
1533
|
+
responseItem.content[key].example = exampleValue;
|
|
1534
|
+
} else {
|
|
1535
|
+
if (typeof responseItem.content[defaultMediaType] !== "object") {
|
|
1536
|
+
responseItem.content[defaultMediaType] = {};
|
|
1537
|
+
}
|
|
1538
|
+
const mediaEntry = responseItem.content[defaultMediaType];
|
|
1539
|
+
if (typeof mediaEntry.examples !== "object") {
|
|
1540
|
+
mediaEntry.examples = {};
|
|
1541
|
+
}
|
|
1542
|
+
mediaEntry.examples[key] = wrapAsExampleObject(exampleValue);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
delete responseItem.examples;
|
|
1546
|
+
}
|
|
1547
|
+
if (responseItem.content && typeof responseItem.content === "object") {
|
|
1548
|
+
removeEmptySchemaOnlyContentEntries(responseItem.content);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
delete operationItem.produces;
|
|
1554
|
+
if (operationItem.parameters?.length === 0) {
|
|
1555
|
+
delete operationItem.parameters;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
if (document.securityDefinitions) {
|
|
1563
|
+
if (typeof document.components !== "object" || document.components === null) {
|
|
1564
|
+
document.components = {};
|
|
1565
|
+
}
|
|
1566
|
+
if (document.components && typeof document.components === "object") {
|
|
1567
|
+
Object.assign(document.components, { securitySchemes: {} });
|
|
1568
|
+
}
|
|
1569
|
+
for (const [key, securityScheme] of Object.entries(document.securityDefinitions)) {
|
|
1570
|
+
if (typeof securityScheme === "object") {
|
|
1571
|
+
if ("type" in securityScheme && securityScheme.type === "oauth2") {
|
|
1572
|
+
const { flow, authorizationUrl, tokenUrl, scopes } = securityScheme;
|
|
1573
|
+
if (document.components && typeof document.components === "object" && "securitySchemes" in document.components && document.components.securitySchemes) {
|
|
1574
|
+
Object.assign(document.components.securitySchemes, {
|
|
1575
|
+
[key]: {
|
|
1576
|
+
type: "oauth2",
|
|
1577
|
+
flows: {
|
|
1578
|
+
[upgradeFlow(flow || "implicit")]: Object.assign({}, authorizationUrl && { authorizationUrl }, tokenUrl && { tokenUrl }, scopes && { scopes })
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
} else if ("type" in securityScheme && securityScheme.type === "basic") {
|
|
1584
|
+
if (document.components && typeof document.components === "object" && "securitySchemes" in document.components && document.components.securitySchemes) {
|
|
1585
|
+
Object.assign(document.components.securitySchemes, {
|
|
1586
|
+
[key]: {
|
|
1587
|
+
type: "http",
|
|
1588
|
+
scheme: "basic"
|
|
1589
|
+
}
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
} else {
|
|
1593
|
+
if (document.components && typeof document.components === "object" && "securitySchemes" in document.components && document.components.securitySchemes) {
|
|
1594
|
+
Object.assign(document.components.securitySchemes, {
|
|
1595
|
+
[key]: securityScheme
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
delete document.securityDefinitions;
|
|
1602
|
+
}
|
|
1603
|
+
delete document.consumes;
|
|
1604
|
+
delete document.produces;
|
|
1605
|
+
return document;
|
|
1606
|
+
}
|
|
1607
|
+
var migrateSchemaNullability = (schema2) => {
|
|
1608
|
+
if (!isObjectLike(schema2)) {
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
if (typeof schema2["x-nullable"] === "boolean") {
|
|
1612
|
+
if (schema2["x-nullable"]) {
|
|
1613
|
+
schema2.nullable = true;
|
|
1614
|
+
}
|
|
1615
|
+
delete schema2["x-nullable"];
|
|
1616
|
+
}
|
|
1617
|
+
if (isObjectLike(schema2.properties)) {
|
|
1618
|
+
for (const property of Object.values(schema2.properties)) {
|
|
1619
|
+
migrateSchemaNullability(property);
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
migrateSchemaNullability(schema2.items);
|
|
1623
|
+
migrateSchemaNullability(schema2.additionalProperties);
|
|
1624
|
+
if (Array.isArray(schema2.allOf)) {
|
|
1625
|
+
for (const member of schema2.allOf) {
|
|
1626
|
+
migrateSchemaNullability(member);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
};
|
|
1630
|
+
function transformItemsObject(obj) {
|
|
1631
|
+
const schemaProperties = [
|
|
1632
|
+
"type",
|
|
1633
|
+
"format",
|
|
1634
|
+
"default",
|
|
1635
|
+
"items",
|
|
1636
|
+
"maximum",
|
|
1637
|
+
"exclusiveMaximum",
|
|
1638
|
+
"minimum",
|
|
1639
|
+
"exclusiveMinimum",
|
|
1640
|
+
"maxLength",
|
|
1641
|
+
"minLength",
|
|
1642
|
+
"pattern",
|
|
1643
|
+
"maxItems",
|
|
1644
|
+
"minItems",
|
|
1645
|
+
"uniqueItems",
|
|
1646
|
+
"enum",
|
|
1647
|
+
"multipleOf",
|
|
1648
|
+
"x-nullable"
|
|
1649
|
+
];
|
|
1650
|
+
const schema2 = schemaProperties.reduce((acc, property) => {
|
|
1651
|
+
if (Object.hasOwn(obj, property)) {
|
|
1652
|
+
acc[property] = obj[property];
|
|
1653
|
+
delete obj[property];
|
|
1654
|
+
}
|
|
1655
|
+
return acc;
|
|
1656
|
+
}, {});
|
|
1657
|
+
migrateSchemaNullability(schema2);
|
|
1658
|
+
return schema2;
|
|
1659
|
+
}
|
|
1660
|
+
function getParameterLocation(location) {
|
|
1661
|
+
if (location === "formData") {
|
|
1662
|
+
throw new Error("Encountered a formData parameter which should have been filtered out by the caller");
|
|
1663
|
+
}
|
|
1664
|
+
if (location === "body") {
|
|
1665
|
+
throw new Error("Encountered a body parameter which should have been filtered out by the caller");
|
|
1666
|
+
}
|
|
1667
|
+
return location;
|
|
1668
|
+
}
|
|
1669
|
+
function transformParameterObject(parameter) {
|
|
1670
|
+
if (Object.hasOwn(parameter, "$ref") && typeof parameter.$ref === "string") {
|
|
1671
|
+
return {
|
|
1672
|
+
$ref: parameter.$ref
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
const serializationStyle = getParameterSerializationStyle(parameter);
|
|
1676
|
+
const schema2 = transformItemsObject(parameter);
|
|
1677
|
+
const { xExample, xExamples } = extractXExampleExtensions(parameter);
|
|
1678
|
+
if (isNonEmptyObject(xExample)) {
|
|
1679
|
+
parameter.examples = transformXExampleToExamples(xExample);
|
|
1680
|
+
} else if (isNonEmptyObject(xExamples)) {
|
|
1681
|
+
parameter.examples = Object.entries(xExamples).reduce((acc, [key, exampleValue]) => {
|
|
1682
|
+
acc[key] = wrapAsExampleObject(exampleValue);
|
|
1683
|
+
return acc;
|
|
1684
|
+
}, {});
|
|
1685
|
+
}
|
|
1686
|
+
delete parameter.collectionFormat;
|
|
1687
|
+
delete parameter.default;
|
|
1688
|
+
if (!parameter.in) {
|
|
1689
|
+
throw new Error('Parameter object must have an "in" property');
|
|
1690
|
+
}
|
|
1691
|
+
return {
|
|
1692
|
+
schema: schema2,
|
|
1693
|
+
...serializationStyle,
|
|
1694
|
+
...parameter,
|
|
1695
|
+
in: getParameterLocation(parameter.in)
|
|
1696
|
+
};
|
|
1697
|
+
}
|
|
1698
|
+
function transformResponseHeader(header) {
|
|
1699
|
+
if (Object.hasOwn(header, "$ref") && typeof header.$ref === "string") {
|
|
1700
|
+
return {
|
|
1701
|
+
$ref: header.$ref
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
const schema2 = transformItemsObject(header);
|
|
1705
|
+
return {
|
|
1706
|
+
...header,
|
|
1707
|
+
schema: schema2
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
var querySerialization = {
|
|
1711
|
+
ssv: {
|
|
1712
|
+
style: "spaceDelimited",
|
|
1713
|
+
explode: false
|
|
1714
|
+
},
|
|
1715
|
+
pipes: {
|
|
1716
|
+
style: "pipeDelimited",
|
|
1717
|
+
explode: false
|
|
1718
|
+
},
|
|
1719
|
+
multi: {
|
|
1720
|
+
style: "form",
|
|
1721
|
+
explode: true
|
|
1722
|
+
},
|
|
1723
|
+
csv: {
|
|
1724
|
+
style: "form",
|
|
1725
|
+
explode: false
|
|
1726
|
+
},
|
|
1727
|
+
tsv: {}
|
|
1728
|
+
};
|
|
1729
|
+
var pathAndHeaderSerialization = {
|
|
1730
|
+
ssv: {},
|
|
1731
|
+
pipes: {},
|
|
1732
|
+
multi: {},
|
|
1733
|
+
csv: {
|
|
1734
|
+
style: "simple",
|
|
1735
|
+
explode: false
|
|
1736
|
+
},
|
|
1737
|
+
tsv: {}
|
|
1738
|
+
};
|
|
1739
|
+
var serializationStyles = {
|
|
1740
|
+
header: pathAndHeaderSerialization,
|
|
1741
|
+
query: querySerialization,
|
|
1742
|
+
path: pathAndHeaderSerialization
|
|
1743
|
+
};
|
|
1744
|
+
function getParameterSerializationStyle(parameter) {
|
|
1745
|
+
if (parameter.type !== "array" || !(parameter.in === "query" || parameter.in === "path" || parameter.in === "header")) {
|
|
1746
|
+
return {};
|
|
1747
|
+
}
|
|
1748
|
+
const collectionFormat = parameter.collectionFormat ?? "csv";
|
|
1749
|
+
if (parameter.in in serializationStyles && collectionFormat in serializationStyles[parameter.in]) {
|
|
1750
|
+
return serializationStyles[parameter.in][collectionFormat];
|
|
1751
|
+
}
|
|
1752
|
+
return {};
|
|
1753
|
+
}
|
|
1754
|
+
function getFormDataEncoding(parameter) {
|
|
1755
|
+
if (parameter.type !== "array" || typeof parameter.collectionFormat !== "string") {
|
|
1756
|
+
return void 0;
|
|
1757
|
+
}
|
|
1758
|
+
const encoding = querySerialization[parameter.collectionFormat];
|
|
1759
|
+
if (!encoding || Object.keys(encoding).length === 0) {
|
|
1760
|
+
return void 0;
|
|
1761
|
+
}
|
|
1762
|
+
return encoding;
|
|
1763
|
+
}
|
|
1764
|
+
function migrateBodyParameter(bodyParameter, consumes) {
|
|
1765
|
+
const { xExample, xExamples } = extractXExampleExtensions(bodyParameter);
|
|
1766
|
+
delete bodyParameter.name;
|
|
1767
|
+
delete bodyParameter.in;
|
|
1768
|
+
const { schema: schema2, ...requestBody } = bodyParameter;
|
|
1769
|
+
migrateSchemaNullability(schema2);
|
|
1770
|
+
const requestBodyObject = {
|
|
1771
|
+
content: {},
|
|
1772
|
+
...requestBody
|
|
1773
|
+
};
|
|
1774
|
+
if (requestBodyObject.content) {
|
|
1775
|
+
for (const type of consumes) {
|
|
1776
|
+
requestBodyObject.content[type] = {
|
|
1777
|
+
schema: schema2
|
|
1778
|
+
};
|
|
1779
|
+
if (isNonEmptyObject(xExamples) && type in xExamples) {
|
|
1780
|
+
const examples = xExamples[type];
|
|
1781
|
+
const isExamplesCollection = isNonEmptyObject(examples) && Object.values(examples).every((example) => isExampleObject(example));
|
|
1782
|
+
if (isExamplesCollection) {
|
|
1783
|
+
requestBodyObject.content[type].examples = examples;
|
|
1784
|
+
} else if (isNamedExamplesCollection(examples)) {
|
|
1785
|
+
requestBodyObject.content[type].examples = Object.entries(examples).reduce((acc, [key, exampleValue]) => {
|
|
1786
|
+
acc[key] = wrapAsExampleObject(exampleValue);
|
|
1787
|
+
return acc;
|
|
1788
|
+
}, {});
|
|
1789
|
+
} else {
|
|
1790
|
+
requestBodyObject.content[type].examples = {
|
|
1791
|
+
default: wrapAsExampleObject(examples)
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
} else if (isNonEmptyObject(xExamples) && !Object.keys(xExamples).some(isMediaTypeKey)) {
|
|
1795
|
+
requestBodyObject.content[type].examples = Object.entries(xExamples).reduce((acc, [key, exampleValue]) => {
|
|
1796
|
+
acc[key] = wrapAsExampleObject(exampleValue);
|
|
1797
|
+
return acc;
|
|
1798
|
+
}, {});
|
|
1799
|
+
}
|
|
1800
|
+
if (!requestBodyObject.content[type].examples && isNonEmptyObject(xExample) && type in xExample) {
|
|
1801
|
+
requestBodyObject.content[type].example = xExample[type];
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
return requestBodyObject;
|
|
1806
|
+
}
|
|
1807
|
+
function migrateFormDataParameter(parameters, consumes = ["multipart/form-data"]) {
|
|
1808
|
+
const requestBodyObject = {
|
|
1809
|
+
content: {}
|
|
1810
|
+
};
|
|
1811
|
+
const filtered = consumes.filter((type) => type === "multipart/form-data" || type === "application/x-www-form-urlencoded");
|
|
1812
|
+
const contentTypes = filtered.length > 0 ? filtered : ["multipart/form-data"];
|
|
1813
|
+
if (requestBodyObject.content) {
|
|
1814
|
+
for (const contentType of contentTypes) {
|
|
1815
|
+
requestBodyObject.content[contentType] = {
|
|
1816
|
+
schema: {
|
|
1817
|
+
type: "object",
|
|
1818
|
+
properties: {},
|
|
1819
|
+
required: []
|
|
1820
|
+
// Initialize required array
|
|
1821
|
+
}
|
|
1822
|
+
};
|
|
1823
|
+
const formContent = requestBodyObject.content?.[contentType];
|
|
1824
|
+
if (formContent?.schema && typeof formContent.schema === "object" && "properties" in formContent.schema) {
|
|
1825
|
+
for (const param of parameters) {
|
|
1826
|
+
if (param.name && formContent.schema.properties) {
|
|
1827
|
+
formContent.schema.properties[param.name] = {
|
|
1828
|
+
...transformItemsObject(structuredClone(param)),
|
|
1829
|
+
// Only carry the description over when it exists, so a parameter without one does not
|
|
1830
|
+
// end up with an explicit `description: undefined` on its schema.
|
|
1831
|
+
...param.description !== void 0 ? { description: param.description } : {}
|
|
1832
|
+
};
|
|
1833
|
+
const encoding = getFormDataEncoding(param);
|
|
1834
|
+
if (encoding) {
|
|
1835
|
+
formContent.encoding ??= {};
|
|
1836
|
+
formContent.encoding[param.name] = encoding;
|
|
1837
|
+
}
|
|
1838
|
+
if (param.required && Array.isArray(formContent.schema.required)) {
|
|
1839
|
+
formContent.schema.required.push(param.name);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
return requestBodyObject;
|
|
1847
|
+
}
|
|
1848
|
+
function migrateParameters(parameters, consumes) {
|
|
1849
|
+
const result = {
|
|
1850
|
+
parameters: parameters.filter((parameter) => !(parameter.in === "body" || parameter.in === "formData")).map((parameter) => transformParameterObject(parameter))
|
|
1851
|
+
};
|
|
1852
|
+
const bodyParameter = structuredClone(parameters.find((parameter) => parameter.in === "body") ?? {});
|
|
1853
|
+
if (bodyParameter && Object.keys(bodyParameter).length) {
|
|
1854
|
+
result.requestBody = migrateBodyParameter(bodyParameter, consumes);
|
|
1855
|
+
}
|
|
1856
|
+
const formDataParameters = parameters.filter((parameter) => parameter.in === "formData");
|
|
1857
|
+
if (formDataParameters.length > 0) {
|
|
1858
|
+
const requestBodyObject = migrateFormDataParameter(formDataParameters, consumes);
|
|
1859
|
+
if (typeof result.requestBody !== "object") {
|
|
1860
|
+
result.requestBody = requestBodyObject;
|
|
1861
|
+
} else {
|
|
1862
|
+
result.requestBody = {
|
|
1863
|
+
...result.requestBody,
|
|
1864
|
+
content: {
|
|
1865
|
+
...result.requestBody.content,
|
|
1866
|
+
...requestBodyObject.content
|
|
1867
|
+
}
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
if (typeof result.requestBody !== "object") {
|
|
1871
|
+
result.requestBody = {
|
|
1872
|
+
content: {}
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
return result;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
// ../../node_modules/.bun/@scalar+helpers@0.14.0/node_modules/@scalar/helpers/dist/openapi/is-schema-path.js
|
|
1880
|
+
var SCHEMA_SEGMENTS = /* @__PURE__ */ new Set([
|
|
1881
|
+
"properties",
|
|
1882
|
+
"items",
|
|
1883
|
+
"allOf",
|
|
1884
|
+
"anyOf",
|
|
1885
|
+
"oneOf",
|
|
1886
|
+
"not",
|
|
1887
|
+
"additionalProperties",
|
|
1888
|
+
"schema",
|
|
1889
|
+
// Reusable schemas live under `components/schemas`, and `schemas` is not a
|
|
1890
|
+
// fixed keyword anywhere else in the document.
|
|
1891
|
+
"schemas"
|
|
1892
|
+
]);
|
|
1893
|
+
var USER_KEYED_MAPS = /* @__PURE__ */ new Set([
|
|
1894
|
+
"paths",
|
|
1895
|
+
"webhooks",
|
|
1896
|
+
"responses",
|
|
1897
|
+
"content",
|
|
1898
|
+
"headers",
|
|
1899
|
+
"examples",
|
|
1900
|
+
"links",
|
|
1901
|
+
"encoding",
|
|
1902
|
+
"variables",
|
|
1903
|
+
"parameters",
|
|
1904
|
+
"requestBodies",
|
|
1905
|
+
"securitySchemes",
|
|
1906
|
+
"pathItems",
|
|
1907
|
+
"scopes"
|
|
1908
|
+
]);
|
|
1909
|
+
var isSchemaPath = (path) => {
|
|
1910
|
+
if (!path) {
|
|
1911
|
+
return false;
|
|
1912
|
+
}
|
|
1913
|
+
const segments2 = path[0] === "x-ext" && path[1] !== void 0 ? path.slice(2) : path;
|
|
1914
|
+
let userKeySegments = 0;
|
|
1915
|
+
for (const segment of segments2) {
|
|
1916
|
+
if (userKeySegments > 0) {
|
|
1917
|
+
userKeySegments--;
|
|
1918
|
+
continue;
|
|
1919
|
+
}
|
|
1920
|
+
if (SCHEMA_SEGMENTS.has(segment) || segment.endsWith("Schema")) {
|
|
1921
|
+
return true;
|
|
1922
|
+
}
|
|
1923
|
+
if (segment === "callbacks") {
|
|
1924
|
+
userKeySegments = 2;
|
|
1925
|
+
continue;
|
|
1926
|
+
}
|
|
1927
|
+
if (USER_KEYED_MAPS.has(segment)) {
|
|
1928
|
+
userKeySegments = 1;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
return false;
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1934
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/3.0-to-3.1/upgrade-from-three-to-three-one.js
|
|
1935
|
+
var NAMED_SCHEMA_MAP_SEGMENTS = /* @__PURE__ */ new Set(["properties", "patternProperties", "$defs", "definitions"]);
|
|
1936
|
+
function isNamedSchemaMap(path) {
|
|
1937
|
+
const last = path?.[path.length - 1];
|
|
1938
|
+
if (last === void 0) {
|
|
1939
|
+
return false;
|
|
1940
|
+
}
|
|
1941
|
+
if (last === "schemas" && path?.[path.length - 2] === "components") {
|
|
1942
|
+
return true;
|
|
1943
|
+
}
|
|
1944
|
+
return NAMED_SCHEMA_MAP_SEGMENTS.has(last);
|
|
1945
|
+
}
|
|
1946
|
+
var DATA_KEYWORDS = /* @__PURE__ */ new Set(["example", "default", "const", "enum"]);
|
|
1947
|
+
function isInsideDataValue(path) {
|
|
1948
|
+
if (!path) {
|
|
1949
|
+
return false;
|
|
1950
|
+
}
|
|
1951
|
+
for (const [index, segment] of path.entries()) {
|
|
1952
|
+
if (DATA_KEYWORDS.has(segment) && !isNamedSchemaMap(path.slice(0, index))) {
|
|
1953
|
+
return true;
|
|
1954
|
+
}
|
|
1955
|
+
if (segment === "value" && path[index - 2] === "examples" && !isNamedSchemaMap(path.slice(0, index - 2))) {
|
|
1956
|
+
return true;
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
return false;
|
|
1960
|
+
}
|
|
1961
|
+
function upgradeFromThreeToThreeOne(originalContent) {
|
|
1962
|
+
let content = originalContent;
|
|
1963
|
+
if (content === null || typeof content.openapi !== "string" || !content.openapi.startsWith("3.0")) {
|
|
1964
|
+
return content;
|
|
1965
|
+
}
|
|
1966
|
+
content.openapi = "3.1.1";
|
|
1967
|
+
content = traverse(content, applyChangesToDocument);
|
|
1968
|
+
return content;
|
|
1969
|
+
}
|
|
1970
|
+
var applyChangesToDocument = (schema2, path) => {
|
|
1971
|
+
if (isInsideDataValue(path)) {
|
|
1972
|
+
return schema2;
|
|
1973
|
+
}
|
|
1974
|
+
if (schema2.type !== void 0 && schema2.nullable === true) {
|
|
1975
|
+
schema2.type = [schema2.type, "null"];
|
|
1976
|
+
delete schema2.nullable;
|
|
1977
|
+
} else if (schema2.nullable === true && schema2.type === void 0) {
|
|
1978
|
+
if (typeof schema2.$ref === "string") {
|
|
1979
|
+
const { nullable: _nullable, $ref, ...rest2 } = schema2;
|
|
1980
|
+
return { ...rest2, anyOf: [{ $ref }, { type: "null" }] };
|
|
1981
|
+
}
|
|
1982
|
+
if (Array.isArray(schema2.allOf)) {
|
|
1983
|
+
const { nullable: _nullable, allOf, ...rest2 } = schema2;
|
|
1984
|
+
const base = allOf.length === 1 ? allOf[0] : { allOf };
|
|
1985
|
+
return { ...rest2, anyOf: [base, { type: "null" }] };
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
if (schema2.exclusiveMinimum === true && schema2.minimum !== void 0) {
|
|
1989
|
+
schema2.exclusiveMinimum = schema2.minimum;
|
|
1990
|
+
delete schema2.minimum;
|
|
1991
|
+
} else if (typeof schema2.exclusiveMinimum === "boolean") {
|
|
1992
|
+
delete schema2.exclusiveMinimum;
|
|
1993
|
+
}
|
|
1994
|
+
if (schema2.exclusiveMaximum === true && schema2.maximum !== void 0) {
|
|
1995
|
+
schema2.exclusiveMaximum = schema2.maximum;
|
|
1996
|
+
delete schema2.maximum;
|
|
1997
|
+
} else if (typeof schema2.exclusiveMaximum === "boolean") {
|
|
1998
|
+
delete schema2.exclusiveMaximum;
|
|
1999
|
+
}
|
|
2000
|
+
const isInsideExamplesMap = path?.some((segment, index) => {
|
|
2001
|
+
if (segment === "examples" && index > 0) {
|
|
2002
|
+
return !isNamedSchemaMap(path.slice(0, index));
|
|
2003
|
+
}
|
|
2004
|
+
return false;
|
|
2005
|
+
});
|
|
2006
|
+
if (schema2.example !== void 0 && !isInsideExamplesMap && !isNamedSchemaMap(path)) {
|
|
2007
|
+
if (isSchemaPath(path)) {
|
|
2008
|
+
schema2.examples = [schema2.example];
|
|
2009
|
+
} else {
|
|
2010
|
+
schema2.examples = {
|
|
2011
|
+
default: {
|
|
2012
|
+
value: schema2.example
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
delete schema2.example;
|
|
2017
|
+
}
|
|
2018
|
+
const { format: _, ...rest } = schema2;
|
|
2019
|
+
if (schema2.type === "string" || Array.isArray(schema2.type) && schema2.type.includes("string")) {
|
|
2020
|
+
if (schema2.format === "binary") {
|
|
2021
|
+
const { type: _type, ...binarySchema } = rest;
|
|
2022
|
+
const hasMediaType = path?.at(-1) === "schema" && path.at(-3) === "content";
|
|
2023
|
+
return hasMediaType ? binarySchema : { contentMediaType: "application/octet-stream", ...binarySchema };
|
|
2024
|
+
}
|
|
2025
|
+
if (schema2.format === "base64" || schema2.format === "byte") {
|
|
2026
|
+
return {
|
|
2027
|
+
...rest,
|
|
2028
|
+
contentEncoding: "base64"
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
if (schema2["x-webhooks"] !== void 0 && (path === void 0 || path.length === 0)) {
|
|
2033
|
+
schema2.webhooks = schema2["x-webhooks"];
|
|
2034
|
+
delete schema2["x-webhooks"];
|
|
2035
|
+
}
|
|
2036
|
+
return schema2;
|
|
2037
|
+
};
|
|
2038
|
+
|
|
2039
|
+
// ../../node_modules/.bun/@scalar+openapi-upgrader@0.3.1/node_modules/@scalar/openapi-upgrader/dist/upgrade.js
|
|
2040
|
+
function upgrade(value, targetVersion, options) {
|
|
2041
|
+
if (targetVersion === "3.2") {
|
|
2042
|
+
const input = cloneDocument(value);
|
|
2043
|
+
const openapi302 = upgradeFromTwoToThree(input);
|
|
2044
|
+
const openapi31 = upgradeFromThreeToThreeOne(openapi302);
|
|
2045
|
+
try {
|
|
2046
|
+
const document = migrateThreeOneToThreeTwo(openapi31);
|
|
2047
|
+
return options?.onIncompatible === "collect" ? { document, diagnostics: [] } : document;
|
|
2048
|
+
} catch (error) {
|
|
2049
|
+
if (options?.onIncompatible !== "collect" || !(error instanceof UpgradeIncompatibilityError)) {
|
|
2050
|
+
throw error;
|
|
2051
|
+
}
|
|
2052
|
+
return {
|
|
2053
|
+
document: upgrade(cloneDocument(value), "3.1"),
|
|
2054
|
+
diagnostics: error.errors
|
|
2055
|
+
};
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
const openapi30 = upgradeFromTwoToThree(value);
|
|
2059
|
+
return targetVersion === "3.0" ? openapi30 : upgradeFromThreeToThreeOne(openapi30);
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
// src/implementation/openapi-document.ts
|
|
2063
|
+
var record = Schema_exports.decodeUnknownSync(JsonObject);
|
|
2064
|
+
function fail(code, reason) {
|
|
2065
|
+
throw new OpenapiCompileError({ code, reason });
|
|
2066
|
+
}
|
|
2067
|
+
async function openApiDocument(input) {
|
|
2068
|
+
const root = record(upgrade(structuredClone(record(input)), "3.1"));
|
|
2069
|
+
const spec = Schema_exports.decodeUnknownSync(Specification)(root);
|
|
2070
|
+
if (!spec.openapi.startsWith("3.1."))
|
|
2071
|
+
fail("openapi_version", "This importer supports Swagger 2.0 and OpenAPI 3.0 and 3.1.");
|
|
2072
|
+
const components = spec.components?.schemas ?? {};
|
|
2073
|
+
const convert = JsonSchema_exports.fromSchemaOpenApi3_1;
|
|
2074
|
+
const schemas = [];
|
|
2075
|
+
const componentsObject = root.components === void 0 ? {} : record(root.components);
|
|
2076
|
+
const masked = JSON.parse(
|
|
2077
|
+
JSON.stringify(
|
|
2078
|
+
{ ...root, components: { ...componentsObject, schemas: {} } },
|
|
2079
|
+
(key, value) => {
|
|
2080
|
+
if (key !== "schema") return value;
|
|
2081
|
+
const index = schemas.push(Schema_exports.decodeUnknownSync(Schema_exports.Json)(value)) - 1;
|
|
2082
|
+
return { "x-executor-schema": index };
|
|
2083
|
+
}
|
|
2084
|
+
)
|
|
2085
|
+
);
|
|
2086
|
+
const resolved2 = await (await loadSwaggerClient()).resolve({
|
|
2087
|
+
spec: masked,
|
|
2088
|
+
skipNormalization: true,
|
|
2089
|
+
useCircularStructures: false,
|
|
2090
|
+
// Spec import uses the host's guarded download. References must not acquire
|
|
2091
|
+
// a second, unguarded network capability inside the resolver.
|
|
2092
|
+
requestInterceptor: () => fail("external_reference", "External OpenAPI references are not supported yet.")
|
|
2093
|
+
});
|
|
2094
|
+
const restored = record(
|
|
2095
|
+
JSON.parse(JSON.stringify(resolved2.spec), (key, value) => {
|
|
2096
|
+
if (key !== "schema") return value;
|
|
2097
|
+
const marker = record(value)["x-executor-schema"];
|
|
2098
|
+
if (typeof marker !== "number" || schemas[marker] === void 0)
|
|
2099
|
+
return fail("invalid_document", "The API resolver did not preserve a schema.");
|
|
2100
|
+
return schemas[marker];
|
|
2101
|
+
})
|
|
2102
|
+
);
|
|
2103
|
+
const parsed = Schema_exports.decodeUnknownSync(Specification)({
|
|
2104
|
+
...restored,
|
|
2105
|
+
components: { ...record(restored.components), schemas: components }
|
|
2106
|
+
});
|
|
2107
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
2108
|
+
const references2 = /* @__PURE__ */ new Map();
|
|
2109
|
+
return {
|
|
2110
|
+
spec: parsed,
|
|
2111
|
+
definitions,
|
|
2112
|
+
/** Inspect a component schema without expanding its children. OpenAPI object refs must already be resolved by Swagger. */
|
|
2113
|
+
resolve(value) {
|
|
2114
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2115
|
+
while (value.$ref !== void 0) {
|
|
2116
|
+
const ref = value.$ref;
|
|
2117
|
+
const path = typeof ref === "string" ? JsonPointer_exports.parseUriFragment(ref) : void 0;
|
|
2118
|
+
if (typeof ref !== "string" || path?.length !== 3 || path[0] !== "components" || path[1] !== "schemas" || path[2] === void 0)
|
|
2119
|
+
fail("external_reference", "An OpenAPI object reference could not be resolved locally.");
|
|
2120
|
+
if (visited.has(ref))
|
|
2121
|
+
fail("circular_reference", "A circular schema alias cannot be imported.");
|
|
2122
|
+
visited.add(ref);
|
|
2123
|
+
value = record(Object.hasOwn(components, path[2]) ? components[path[2]] : void 0);
|
|
2124
|
+
}
|
|
2125
|
+
return value;
|
|
2126
|
+
},
|
|
2127
|
+
/** Compose a Draft 2020-12 schema around API Schema Objects. Only values passed to
|
|
2128
|
+
* `api` use the document's OpenAPI dialect; Executor-authored wrappers are already
|
|
2129
|
+
* Draft 2020-12 and must not be reinterpreted. Reached components are converted once into
|
|
2130
|
+
* the shared `definitions` and stay references here; nothing is inlined or copied per operation.
|
|
2131
|
+
*/
|
|
2132
|
+
schema(build) {
|
|
2133
|
+
const added = [];
|
|
2134
|
+
const direct = /* @__PURE__ */ new Set();
|
|
2135
|
+
const local = {};
|
|
2136
|
+
const visit = (input2, direct2) => {
|
|
2137
|
+
const document = convert(input2, {
|
|
2138
|
+
onReference(ref) {
|
|
2139
|
+
const path = JsonPointer_exports.parseUriFragment(ref);
|
|
2140
|
+
const name = path?.[2];
|
|
2141
|
+
if (path?.length !== 3 || path[0] !== "components" || path[1] !== "schemas" || name === void 0)
|
|
2142
|
+
fail("schema_reference", "Only local component schema references are supported.");
|
|
2143
|
+
const component = Object.hasOwn(components, name) ? components[name] : void 0;
|
|
2144
|
+
if (component === void 0)
|
|
2145
|
+
fail("missing_component", "An API schema references a missing component.");
|
|
2146
|
+
direct2.add(name);
|
|
2147
|
+
if (!definitions.has(name)) {
|
|
2148
|
+
added.push(name);
|
|
2149
|
+
definitions.set(name, {});
|
|
2150
|
+
const names = /* @__PURE__ */ new Set();
|
|
2151
|
+
definitions.set(name, visit(component, names));
|
|
2152
|
+
references2.set(name, names);
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
});
|
|
2156
|
+
return record({
|
|
2157
|
+
...document.schema,
|
|
2158
|
+
...Object.keys(document.definitions).length ? { $defs: document.definitions } : {}
|
|
2159
|
+
});
|
|
2160
|
+
};
|
|
2161
|
+
const api = (input2) => {
|
|
2162
|
+
const { $defs, ...converted } = visit(record(input2), direct);
|
|
2163
|
+
for (const [name, definition] of Object.entries($defs === void 0 ? {} : record($defs))) {
|
|
2164
|
+
if (Object.hasOwn(local, name) && JSON.stringify(local[name]) !== JSON.stringify(definition))
|
|
2165
|
+
fail("schema_reference", "An API schema has conflicting local definitions.");
|
|
2166
|
+
local[name] = definition;
|
|
2167
|
+
}
|
|
2168
|
+
return converted;
|
|
2169
|
+
};
|
|
2170
|
+
try {
|
|
2171
|
+
const converted = build(api);
|
|
2172
|
+
if (Object.keys(local).length) {
|
|
2173
|
+
const reached = /* @__PURE__ */ new Set();
|
|
2174
|
+
const pending = [...direct];
|
|
2175
|
+
for (let name = pending.pop(); name !== void 0; name = pending.pop()) {
|
|
2176
|
+
if (reached.has(name)) continue;
|
|
2177
|
+
reached.add(name);
|
|
2178
|
+
pending.push(...references2.get(name) ?? []);
|
|
2179
|
+
}
|
|
2180
|
+
if ([...reached].some((name) => Object.hasOwn(local, name)))
|
|
2181
|
+
fail(
|
|
2182
|
+
"schema_reference",
|
|
2183
|
+
"An API schema has conflicting local and component definitions."
|
|
2184
|
+
);
|
|
2185
|
+
}
|
|
2186
|
+
return {
|
|
2187
|
+
...converted,
|
|
2188
|
+
...Object.keys(local).length ? { $defs: local } : {},
|
|
2189
|
+
$schema: JsonSchema_exports.META_SCHEMA_URI_DRAFT_2020_12
|
|
2190
|
+
};
|
|
2191
|
+
} catch (error) {
|
|
2192
|
+
for (const name of added) {
|
|
2193
|
+
definitions.delete(name);
|
|
2194
|
+
references2.delete(name);
|
|
2195
|
+
}
|
|
2196
|
+
if (error instanceof OpenapiCompileError) throw error;
|
|
2197
|
+
return fail(
|
|
2198
|
+
"schema_keyword",
|
|
2199
|
+
"An API schema cannot be converted without changing its constraints."
|
|
2200
|
+
);
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
// src/implementation/openapi-names.ts
|
|
2207
|
+
var words = (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((word) => word.length > 0).map((word) => word.toLowerCase());
|
|
2208
|
+
var camel = (value) => {
|
|
2209
|
+
const [first, ...rest] = words(value);
|
|
2210
|
+
return first === void 0 ? "" : `${first}${rest.map((word) => `${word[0]?.toUpperCase() ?? ""}${word.slice(1)}`).join("")}`;
|
|
2211
|
+
};
|
|
2212
|
+
var pascal = (value) => {
|
|
2213
|
+
const name = camel(value);
|
|
2214
|
+
return `${name[0]?.toUpperCase() ?? ""}${name.slice(1)}`;
|
|
2215
|
+
};
|
|
2216
|
+
var version = /^v\d+(?:[._-]\d+)?$/i;
|
|
2217
|
+
var segments = (path) => path.split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
|
|
2218
|
+
var resourceSegments = (path) => segments(path).filter(
|
|
2219
|
+
(segment) => !version.test(segment) && segment.toLowerCase() !== "api" && !(segment.startsWith("{") && segment.endsWith("}")) && camel(segment) !== ""
|
|
2220
|
+
);
|
|
2221
|
+
var groupOf = (input) => camel(input.tag ?? "") || camel(resourceSegments(input.path)[0] ?? "") || // Keep "root" for an operation on `/` or a path of only versions and parameters.
|
|
2222
|
+
"root";
|
|
2223
|
+
var fallbackLeaf = (input, group) => {
|
|
2224
|
+
const resources = resourceSegments(input.path).map(camel);
|
|
2225
|
+
const others = resources.filter((segment) => segment !== group);
|
|
2226
|
+
const suffix = (others.length ? others : resources).map(pascal).join("");
|
|
2227
|
+
return camel(`${input.method.toLowerCase()}${suffix || "Operation"}`);
|
|
2228
|
+
};
|
|
2229
|
+
var leafOf = (input, group) => {
|
|
2230
|
+
if (input.operationId === void 0) return fallbackLeaf(input, group);
|
|
2231
|
+
const [first, ...rest] = input.operationId.split(/[._/]+/).filter((part) => part.length > 0);
|
|
2232
|
+
const seed = first !== void 0 && rest.length > 0 && camel(first).toLowerCase() === group.toLowerCase() ? rest.join(" ") : input.operationId;
|
|
2233
|
+
const leaf = camel(seed);
|
|
2234
|
+
return leaf === "" || leaf === group ? fallbackLeaf(input, group) : leaf;
|
|
2235
|
+
};
|
|
2236
|
+
var hash = (input) => {
|
|
2237
|
+
const text = JSON.stringify([input.method.toUpperCase(), input.path, input.operationId ?? null]);
|
|
2238
|
+
let value = 0;
|
|
2239
|
+
for (let i = 0; i < text.length; i++) value = (value << 5) - value + text.charCodeAt(i) | 0;
|
|
2240
|
+
return Math.abs(value).toString(36).padStart(8, "0").slice(0, 8);
|
|
2241
|
+
};
|
|
2242
|
+
var planOperationNames = (inputs) => {
|
|
2243
|
+
const staged = inputs.map((input) => {
|
|
2244
|
+
const group = groupOf(input);
|
|
2245
|
+
const leaf = leafOf(input, group);
|
|
2246
|
+
const versionSegment = segments(input.path).map((segment) => segment.toLowerCase()).find((segment) => version.test(segment));
|
|
2247
|
+
const prefix = versionSegment === void 0 ? group : `${group}.${camel(versionSegment)}`;
|
|
2248
|
+
return { input, group, leaf, prefix, versionSegment, name: `${group}.${leaf}` };
|
|
2249
|
+
});
|
|
2250
|
+
const refine = (rename) => {
|
|
2251
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
2252
|
+
for (const item of staged) buckets.set(item.name, [...buckets.get(item.name) ?? [], item]);
|
|
2253
|
+
for (const bucket of buckets.values())
|
|
2254
|
+
if (bucket.length > 1) for (const item of bucket) item.name = rename(item);
|
|
2255
|
+
};
|
|
2256
|
+
refine((item) => item.versionSegment === void 0 ? item.name : `${item.prefix}.${item.leaf}`);
|
|
2257
|
+
refine((item) => `${item.prefix}.${item.leaf}${pascal(item.input.method)}`);
|
|
2258
|
+
refine((item) => `${item.prefix}.${item.leaf}${pascal(item.input.method)}${hash(item.input)}`);
|
|
2259
|
+
return staged.map((item) => item.name);
|
|
2260
|
+
};
|
|
2261
|
+
|
|
2262
|
+
// src/implementation/openapi-compile.ts
|
|
2263
|
+
function fail2(code, reason) {
|
|
2264
|
+
throw new OpenapiCompileError({ code, reason });
|
|
2265
|
+
}
|
|
2266
|
+
var record2 = (value) => Schema_exports.decodeUnknownSync(JsonObject)(value);
|
|
2267
|
+
var OperationNaming = Schema_exports.Struct({
|
|
2268
|
+
operationId: Schema_exports.optionalKey(Schema_exports.String),
|
|
2269
|
+
tags: Schema_exports.optionalKey(Schema_exports.Array(Schema_exports.String))
|
|
2270
|
+
});
|
|
2271
|
+
var identifier = (name) => name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2272
|
+
function absolute(value) {
|
|
2273
|
+
const url = new URL(value);
|
|
2274
|
+
if (url.protocol !== "https:" && url.protocol !== "http:")
|
|
2275
|
+
fail2("server_protocol", "Only HTTP APIs can be imported.");
|
|
2276
|
+
if (url.username || url.password || url.hash || url.search || /[{}]/.test(value))
|
|
2277
|
+
fail2("server_url", "This API needs a configured server URL before import.");
|
|
2278
|
+
return url.href.replace(/\/$/, "");
|
|
2279
|
+
}
|
|
2280
|
+
function serverAddress(swagger, server, connectUrl, documentServer) {
|
|
2281
|
+
const variables = { ...documentServer?.variables, ...server.variables };
|
|
2282
|
+
const request = record2(
|
|
2283
|
+
swagger.buildRequest({
|
|
2284
|
+
spec: {
|
|
2285
|
+
openapi: "3.1.0",
|
|
2286
|
+
servers: [{ url: server.url, variables }],
|
|
2287
|
+
paths: { "/": { get: { operationId: "server" } } }
|
|
2288
|
+
},
|
|
2289
|
+
operationId: "server"
|
|
2290
|
+
})
|
|
2291
|
+
);
|
|
2292
|
+
return absolute(new URL(Schema_exports.decodeUnknownSync(Schema_exports.String)(request.url), connectUrl).href);
|
|
2293
|
+
}
|
|
2294
|
+
var binaryInput = {
|
|
2295
|
+
type: "string",
|
|
2296
|
+
description: "File bytes encoded as base64.",
|
|
2297
|
+
contentEncoding: "base64"
|
|
2298
|
+
};
|
|
2299
|
+
function responseSchema(document, operation, method) {
|
|
2300
|
+
if (method === "HEAD") return { type: "null" };
|
|
2301
|
+
const success = Object.entries(operation.responses ?? {}).filter(
|
|
2302
|
+
([status]) => /^2(?:[0-9]{2}|XX)$/i.test(status)
|
|
2303
|
+
);
|
|
2304
|
+
if (success.length === 0) return void 0;
|
|
2305
|
+
const shapes = [];
|
|
2306
|
+
for (const [status, response] of success) {
|
|
2307
|
+
if (status === "204") {
|
|
2308
|
+
shapes.push(() => ({ type: "null" }));
|
|
2309
|
+
continue;
|
|
2310
|
+
}
|
|
2311
|
+
const content = document.resolve(response).content;
|
|
2312
|
+
if (content === void 0) return void 0;
|
|
2313
|
+
const media = Object.entries(record2(content));
|
|
2314
|
+
if (media.length === 0) return void 0;
|
|
2315
|
+
for (const [type, body] of media) {
|
|
2316
|
+
if (!type.includes("json")) {
|
|
2317
|
+
shapes.push(
|
|
2318
|
+
() => isOpenapiTextMedia(type) ? { type: "string" } : openapiBinaryResultSchema
|
|
2319
|
+
);
|
|
2320
|
+
continue;
|
|
2321
|
+
}
|
|
2322
|
+
const schema2 = record2(body).schema;
|
|
2323
|
+
if (schema2 === void 0) return void 0;
|
|
2324
|
+
shapes.push((api) => api(schema2));
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
return document.schema((api) => ({
|
|
2328
|
+
anyOf: shapes.map((shape) => shape(api))
|
|
2329
|
+
}));
|
|
2330
|
+
}
|
|
2331
|
+
function resolvedOrUndefined(document, value) {
|
|
2332
|
+
try {
|
|
2333
|
+
return document.resolve(record2(value));
|
|
2334
|
+
} catch (error) {
|
|
2335
|
+
if (!(error instanceof OpenapiCompileError) && !Schema_exports.isSchemaError(error)) throw error;
|
|
2336
|
+
return void 0;
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
function errorContent(document, response) {
|
|
2340
|
+
try {
|
|
2341
|
+
return document.resolve(response).content;
|
|
2342
|
+
} catch (error) {
|
|
2343
|
+
if (!(error instanceof OpenapiCompileError) && !Schema_exports.isSchemaError(error)) throw error;
|
|
2344
|
+
return void 0;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
function errorResponses(document, operation) {
|
|
2348
|
+
const errors = [];
|
|
2349
|
+
const tagged = Schema_exports.Struct({
|
|
2350
|
+
description: Schema_exports.optionalKey(Schema_exports.String),
|
|
2351
|
+
required: Schema_exports.Array(Schema_exports.String),
|
|
2352
|
+
properties: Schema_exports.Record(Schema_exports.String, JsonObject)
|
|
2353
|
+
});
|
|
2354
|
+
const visit = (status, input, visited = /* @__PURE__ */ new Set(), parents = []) => {
|
|
2355
|
+
const object2 = Schema_exports.decodeUnknownOption(JsonObject)(input);
|
|
2356
|
+
if (Option_exports.isNone(object2)) return;
|
|
2357
|
+
const value = object2.value;
|
|
2358
|
+
try {
|
|
2359
|
+
if (typeof value.$ref === "string" && visited.has(value.$ref)) return;
|
|
2360
|
+
const next = typeof value.$ref === "string" ? /* @__PURE__ */ new Set([...visited, value.$ref]) : visited;
|
|
2361
|
+
const shape = document.resolve(value);
|
|
2362
|
+
const variants = shape.anyOf;
|
|
2363
|
+
if (Array.isArray(variants)) {
|
|
2364
|
+
for (const variant of variants) visit(status, variant, next, [...parents, value]);
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
const parsed = Schema_exports.decodeUnknownOption(tagged)(shape);
|
|
2368
|
+
if (Option_exports.isNone(parsed) || !parsed.value.required.includes("_tag")) return;
|
|
2369
|
+
const tag = parsed.value.properties._tag;
|
|
2370
|
+
if (tag === void 0) return;
|
|
2371
|
+
const code = typeof tag.const === "string" ? tag.const : Array.isArray(tag.enum) && tag.enum.length === 1 ? tag.enum[0] : void 0;
|
|
2372
|
+
const message = parsed.value.properties.message;
|
|
2373
|
+
const messageShape = message === void 0 ? void 0 : document.resolve(message);
|
|
2374
|
+
const hasMessage = messageShape !== void 0 && (messageShape.type === "string" || typeof messageShape.const === "string" || Array.isArray(messageShape.enum) && messageShape.enum.length > 0 && messageShape.enum.every((value2) => typeof value2 === "string"));
|
|
2375
|
+
const declaration = Schema_exports.decodeUnknownOption(OpenapiErrorResponse)({
|
|
2376
|
+
code,
|
|
2377
|
+
status,
|
|
2378
|
+
message: hasMessage ? { source: "body" } : { source: "schema", value: parsed.value.description },
|
|
2379
|
+
schema: document.schema((api) => ({ allOf: [...parents, value].map(api) }))
|
|
2380
|
+
});
|
|
2381
|
+
if (Option_exports.isSome(declaration)) errors.push(declaration.value);
|
|
2382
|
+
} catch (error) {
|
|
2383
|
+
if (!(error instanceof OpenapiCompileError) && !Schema_exports.isSchemaError(error)) throw error;
|
|
2384
|
+
}
|
|
2385
|
+
};
|
|
2386
|
+
for (const [status, response] of Object.entries(operation.responses ?? {})) {
|
|
2387
|
+
if (!/^[45][0-9]{2}$/.test(status)) continue;
|
|
2388
|
+
const content = errorContent(document, response);
|
|
2389
|
+
if (content === void 0) continue;
|
|
2390
|
+
for (const [type, body] of Object.entries(record2(content))) {
|
|
2391
|
+
if (!type.split(";")[0]?.trim().match(/^application\/(?:[\w.-]+\+)?json$/i))
|
|
2392
|
+
continue;
|
|
2393
|
+
const schema2 = record2(body).schema;
|
|
2394
|
+
if (schema2 !== void 0) visit(Number(status), schema2);
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
return errors;
|
|
2398
|
+
}
|
|
2399
|
+
var compileOpenApiDocument = (entry, inputDocument, options = {}) => Effect_exports.tryPromise({
|
|
2400
|
+
try: async () => {
|
|
2401
|
+
const document = await openApiDocument(inputDocument);
|
|
2402
|
+
const swagger = await loadSwaggerClient();
|
|
2403
|
+
const { spec } = document;
|
|
2404
|
+
const schemes = { ...options.securitySchemes ?? spec.components?.securitySchemes };
|
|
2405
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
2406
|
+
const oauth = [];
|
|
2407
|
+
for (const [name, source] of Object.entries(schemes)) {
|
|
2408
|
+
const scheme = document.resolve(source);
|
|
2409
|
+
if (scheme.type === "http" && scheme.scheme === "bearer" || scheme.type === "apiKey" && (scheme.in === "header" || scheme.in === "query" || scheme.in === "cookie") && typeof scheme.name === "string") {
|
|
2410
|
+
bindings.set(name, [
|
|
2411
|
+
{
|
|
2412
|
+
scheme: name,
|
|
2413
|
+
field: "token",
|
|
2414
|
+
part: "value",
|
|
2415
|
+
prefix: ""
|
|
2416
|
+
}
|
|
2417
|
+
]);
|
|
2418
|
+
} else if (scheme.type === "http" && scheme.scheme === "basic") {
|
|
2419
|
+
bindings.set(name, [
|
|
2420
|
+
{ scheme: name, field: "username", part: "username", prefix: "" },
|
|
2421
|
+
{ scheme: name, field: "password", part: "password", prefix: "" }
|
|
2422
|
+
]);
|
|
2423
|
+
} else if (scheme.type === "oauth2") {
|
|
2424
|
+
const code = record2(scheme.flows).authorizationCode;
|
|
2425
|
+
if (code !== void 0) {
|
|
2426
|
+
const flow = record2(code);
|
|
2427
|
+
if (typeof flow.authorizationUrl === "string" && typeof flow.tokenUrl === "string")
|
|
2428
|
+
oauth.push({
|
|
2429
|
+
name,
|
|
2430
|
+
config: entry.oauthDiscoveryUrl === void 0 ? {
|
|
2431
|
+
authorizationUrl: absolute(
|
|
2432
|
+
new URL(flow.authorizationUrl, entry.connectUrl).href
|
|
2433
|
+
),
|
|
2434
|
+
tokenUrl: absolute(new URL(flow.tokenUrl, entry.connectUrl).href),
|
|
2435
|
+
scopes: [
|
|
2436
|
+
...entry.scopes ?? Object.keys(record2(flow.scopes ?? {}))
|
|
2437
|
+
].sort()
|
|
2438
|
+
} : { discover: absolute(entry.oauthDiscoveryUrl) }
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
let fallback = options.fallbackSecurity;
|
|
2444
|
+
if (bindings.size === 0 && Object.keys(schemes).length === 0 && entry.auth?.header !== void 0) {
|
|
2445
|
+
const header = /^([!#$%&'*+.^_`|~A-Za-z0-9-]+):\s*([^{}\r\n]*)\{[A-Za-z0-9_]+\}$/.exec(
|
|
2446
|
+
entry.auth.header
|
|
2447
|
+
);
|
|
2448
|
+
if (!header?.[1] || header[2] === void 0)
|
|
2449
|
+
fail2("auth_helper", "This catalog entry needs a custom authentication helper.");
|
|
2450
|
+
bindings.set("apiKey", [
|
|
2451
|
+
{
|
|
2452
|
+
scheme: "apiKey",
|
|
2453
|
+
field: "token",
|
|
2454
|
+
part: "value",
|
|
2455
|
+
prefix: header[2]
|
|
2456
|
+
}
|
|
2457
|
+
]);
|
|
2458
|
+
schemes.apiKey = { type: "apiKey", in: "header", name: header[1] };
|
|
2459
|
+
fallback = [{ apiKey: [] }];
|
|
2460
|
+
}
|
|
2461
|
+
if (!fallback && !Object.keys(schemes).length && entry.auth && !["none", "public"].includes(entry.auth.kind))
|
|
2462
|
+
fail2(
|
|
2463
|
+
"auth_missing",
|
|
2464
|
+
"This entry does not declare enough authentication details to generate an app."
|
|
2465
|
+
);
|
|
2466
|
+
const methods = /* @__PURE__ */ new Map();
|
|
2467
|
+
const operations = [];
|
|
2468
|
+
const skipped = /* @__PURE__ */ new Set();
|
|
2469
|
+
const causes = /* @__PURE__ */ new Map();
|
|
2470
|
+
const built = [];
|
|
2471
|
+
const documentServer = spec.servers?.[0];
|
|
2472
|
+
const candidates = Object.entries(spec.paths).flatMap(([path, source]) => {
|
|
2473
|
+
const item = document.resolve(source);
|
|
2474
|
+
return ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"].filter((method) => item[method.toLowerCase()] !== void 0).map((method) => ({ path, item, method }));
|
|
2475
|
+
});
|
|
2476
|
+
if (!candidates.length) fail2("no_operations", "This API does not contain any operations.");
|
|
2477
|
+
const names = planOperationNames(
|
|
2478
|
+
candidates.map(({ path, item, method }) => {
|
|
2479
|
+
const naming = Schema_exports.decodeUnknownOption(OperationNaming)(
|
|
2480
|
+
resolvedOrUndefined(document, item[method.toLowerCase()])
|
|
2481
|
+
).pipe(Option_exports.getOrUndefined);
|
|
2482
|
+
return {
|
|
2483
|
+
operationId: naming?.operationId,
|
|
2484
|
+
tag: naming?.tags?.find((tag) => tag.trim() !== ""),
|
|
2485
|
+
method,
|
|
2486
|
+
path
|
|
2487
|
+
};
|
|
2488
|
+
})
|
|
2489
|
+
);
|
|
2490
|
+
for (const [index, { path, item, method }] of candidates.entries()) {
|
|
2491
|
+
try {
|
|
2492
|
+
if (!path.startsWith("/") || path.includes("?") || path.includes("#"))
|
|
2493
|
+
fail2("operation_path", "An operation has an invalid API path.");
|
|
2494
|
+
const operationMethods = [];
|
|
2495
|
+
const operation = Schema_exports.decodeUnknownSync(Operation)(
|
|
2496
|
+
document.resolve(record2(item[method.toLowerCase()]))
|
|
2497
|
+
);
|
|
2498
|
+
const name = names[index] ?? fail2("operation_path", "An operation has no name.");
|
|
2499
|
+
if (built.some((op) => op.operation.name === name))
|
|
2500
|
+
fail2(
|
|
2501
|
+
"duplicate_operation",
|
|
2502
|
+
"The API has duplicate tool names. Update its operation IDs first."
|
|
2503
|
+
);
|
|
2504
|
+
const serverList = operation.servers ?? (Array.isArray(item.servers) ? Schema_exports.decodeUnknownSync(Specification.fields.servers)(item.servers) : void 0) ?? spec.servers;
|
|
2505
|
+
const server = serverList?.[0];
|
|
2506
|
+
const serverUrl = options.baseUrl ?? server?.url;
|
|
2507
|
+
if (serverUrl === void 0)
|
|
2508
|
+
fail2("server_missing", "The API has no server URL. Set an API base URL and try again.");
|
|
2509
|
+
const baseUrl = serverAddress(
|
|
2510
|
+
swagger,
|
|
2511
|
+
options.baseUrl === void 0 && server !== void 0 ? server : { url: serverUrl },
|
|
2512
|
+
entry.connectUrl,
|
|
2513
|
+
documentServer
|
|
2514
|
+
);
|
|
2515
|
+
const combined = [
|
|
2516
|
+
...Array.isArray(item.parameters) ? item.parameters : [],
|
|
2517
|
+
...operation.parameters ?? []
|
|
2518
|
+
];
|
|
2519
|
+
const parameters = /* @__PURE__ */ new Map();
|
|
2520
|
+
for (const parameter of combined) {
|
|
2521
|
+
const p = Schema_exports.decodeUnknownSync(OpenapiParameter)(document.resolve(record2(parameter)));
|
|
2522
|
+
parameters.set(`${p.in}:${p.name}`, p);
|
|
2523
|
+
}
|
|
2524
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2525
|
+
for (const p of parameters.values()) {
|
|
2526
|
+
const key = p.in === "header" ? "headers" : p.in;
|
|
2527
|
+
const group = groups.get(key) ?? { properties: {}, required: [] };
|
|
2528
|
+
const content = p.content === void 0 ? void 0 : Object.values(p.content)[0];
|
|
2529
|
+
group.properties[p.name] = p.schema ?? (content === void 0 ? {} : record2(content).schema ?? {});
|
|
2530
|
+
if (p.required || p.in === "path") group.required.push(p.name);
|
|
2531
|
+
groups.set(key, group);
|
|
2532
|
+
}
|
|
2533
|
+
const properties = {};
|
|
2534
|
+
const required = [];
|
|
2535
|
+
for (const [key, group] of groups) {
|
|
2536
|
+
properties[key] = (api) => ({
|
|
2537
|
+
type: "object",
|
|
2538
|
+
properties: Object.fromEntries(
|
|
2539
|
+
Object.entries(group.properties).map(([name2, schema2]) => [name2, api(schema2)])
|
|
2540
|
+
),
|
|
2541
|
+
required: group.required,
|
|
2542
|
+
additionalProperties: false
|
|
2543
|
+
});
|
|
2544
|
+
if (group.required.length) required.push(key);
|
|
2545
|
+
}
|
|
2546
|
+
const bodyVariants = [];
|
|
2547
|
+
let retainedBody;
|
|
2548
|
+
if (operation.requestBody) {
|
|
2549
|
+
const request = Schema_exports.decodeUnknownSync(OpenapiRequestBody)(
|
|
2550
|
+
document.resolve(operation.requestBody)
|
|
2551
|
+
);
|
|
2552
|
+
const retainedContent = {};
|
|
2553
|
+
for (const [contentType, content] of Object.entries(request.content)) {
|
|
2554
|
+
const kind = openapiMediaKind(contentType);
|
|
2555
|
+
const schema2 = document.resolve(content.schema ?? {});
|
|
2556
|
+
const declared = content.schema ?? {};
|
|
2557
|
+
const retainedFiles = {};
|
|
2558
|
+
let inputSchema = kind === "binary" ? () => binaryInput : kind === "text" ? () => ({ type: "string" }) : (api) => api(declared);
|
|
2559
|
+
if (kind === "multipart") {
|
|
2560
|
+
const fields = { ...record2(schema2.properties ?? {}) };
|
|
2561
|
+
const files = {};
|
|
2562
|
+
for (const [key, field] of Object.entries(fields)) {
|
|
2563
|
+
const shape = document.resolve(record2(field));
|
|
2564
|
+
if (isOpenapiFileSchema(shape)) {
|
|
2565
|
+
delete fields[key];
|
|
2566
|
+
files[key] = binaryInput;
|
|
2567
|
+
retainedFiles[key] = shape;
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
const form = schema2;
|
|
2571
|
+
inputSchema = (api) => {
|
|
2572
|
+
const converted = api({ ...form, properties: fields });
|
|
2573
|
+
return {
|
|
2574
|
+
...converted,
|
|
2575
|
+
properties: { ...record2(converted.properties ?? {}), ...files }
|
|
2576
|
+
};
|
|
2577
|
+
};
|
|
2578
|
+
}
|
|
2579
|
+
retainedContent[contentType] = {
|
|
2580
|
+
...content.encoding === void 0 ? {} : { encoding: content.encoding },
|
|
2581
|
+
...Object.keys(retainedFiles).length ? { schema: { type: "object", properties: retainedFiles } } : {}
|
|
2582
|
+
};
|
|
2583
|
+
const first = bodyVariants.length === 0;
|
|
2584
|
+
bodyVariants.push((api) => ({
|
|
2585
|
+
properties: { contentType: { enum: [contentType] }, body: inputSchema(api) },
|
|
2586
|
+
...first ? {} : { required: ["contentType"] }
|
|
2587
|
+
}));
|
|
2588
|
+
}
|
|
2589
|
+
retainedBody = { ...request, content: retainedContent };
|
|
2590
|
+
if (!bodyVariants.length)
|
|
2591
|
+
fail2("request_body", `Tool ${name} has no request media types.`);
|
|
2592
|
+
properties.body = () => ({});
|
|
2593
|
+
properties.contentType = () => ({
|
|
2594
|
+
type: "string",
|
|
2595
|
+
enum: Object.keys(request.content),
|
|
2596
|
+
description: "Request media type. Defaults to the first declared type."
|
|
2597
|
+
});
|
|
2598
|
+
if (request.required) required.push("body");
|
|
2599
|
+
}
|
|
2600
|
+
const security = operation.security ?? spec.security ?? fallback ?? [];
|
|
2601
|
+
for (const requirement of security) {
|
|
2602
|
+
const keys = Object.keys(requirement).sort();
|
|
2603
|
+
if (!keys.length) continue;
|
|
2604
|
+
if (!keys.every((key) => bindings.has(key))) continue;
|
|
2605
|
+
const parts = keys.flatMap((key) => bindings.get(key) ?? []);
|
|
2606
|
+
const methodName = bindings.size === 1 && keys.length === 1 ? "apiKey" : keys.join("_and_");
|
|
2607
|
+
operationMethods.push({
|
|
2608
|
+
name: methodName,
|
|
2609
|
+
label: parts.length === 1 ? "API key" : keys.join(" + "),
|
|
2610
|
+
bindings: parts.map((part) => ({
|
|
2611
|
+
...part,
|
|
2612
|
+
field: keys.length === 1 ? part.field : `${identifier(part.scheme)}_${part.field}`
|
|
2613
|
+
}))
|
|
2614
|
+
});
|
|
2615
|
+
}
|
|
2616
|
+
const input = document.schema((api) => ({
|
|
2617
|
+
type: "object",
|
|
2618
|
+
properties: Object.fromEntries(
|
|
2619
|
+
Object.entries(properties).map(([key, shape]) => [key, shape(api)])
|
|
2620
|
+
),
|
|
2621
|
+
required,
|
|
2622
|
+
...bodyVariants.length ? { anyOf: bodyVariants.map((variant) => variant(api)) } : {},
|
|
2623
|
+
additionalProperties: false
|
|
2624
|
+
}));
|
|
2625
|
+
try {
|
|
2626
|
+
jsonSchema(input);
|
|
2627
|
+
} catch {
|
|
2628
|
+
fail2(
|
|
2629
|
+
"input_schema",
|
|
2630
|
+
`Tool ${name} has an input schema this importer cannot preserve yet.`
|
|
2631
|
+
);
|
|
2632
|
+
}
|
|
2633
|
+
const outputSchema = responseSchema(document, operation, method);
|
|
2634
|
+
const streaming = Object.values(operation.responses ?? {}).some((response) => {
|
|
2635
|
+
const content = errorContent(document, response);
|
|
2636
|
+
return content !== void 0 && Object.hasOwn(record2(content), "text/event-stream");
|
|
2637
|
+
});
|
|
2638
|
+
built.push({
|
|
2639
|
+
methods: operationMethods,
|
|
2640
|
+
operation: {
|
|
2641
|
+
...streaming ? { streaming: true } : {},
|
|
2642
|
+
name,
|
|
2643
|
+
...operation.operationId === void 0 ? {} : { operationId: operation.operationId },
|
|
2644
|
+
description: operation.summary ?? operation.description ?? name,
|
|
2645
|
+
method,
|
|
2646
|
+
path,
|
|
2647
|
+
baseUrl,
|
|
2648
|
+
openapi: spec.openapi,
|
|
2649
|
+
securitySchemes: Object.fromEntries(
|
|
2650
|
+
[...new Set(security.flatMap(Object.keys))].map((key) => [
|
|
2651
|
+
key,
|
|
2652
|
+
schemes[key] ?? fail2("auth_method", "A security requirement names a missing scheme.")
|
|
2653
|
+
])
|
|
2654
|
+
),
|
|
2655
|
+
request: {
|
|
2656
|
+
parameters: [...parameters.values()],
|
|
2657
|
+
...retainedBody === void 0 ? {} : { requestBody: retainedBody },
|
|
2658
|
+
security,
|
|
2659
|
+
responses: Object.fromEntries(
|
|
2660
|
+
Object.entries(operation.responses ?? {}).flatMap(([status, response]) => {
|
|
2661
|
+
const content = errorContent(document, response);
|
|
2662
|
+
return content === void 0 ? [] : [
|
|
2663
|
+
[
|
|
2664
|
+
status,
|
|
2665
|
+
{
|
|
2666
|
+
content: Object.fromEntries(
|
|
2667
|
+
Object.keys(record2(content)).map((type) => [type, {}])
|
|
2668
|
+
)
|
|
2669
|
+
}
|
|
2670
|
+
]
|
|
2671
|
+
];
|
|
2672
|
+
})
|
|
2673
|
+
)
|
|
2674
|
+
},
|
|
2675
|
+
input,
|
|
2676
|
+
...outputSchema === void 0 ? {} : { outputSchema },
|
|
2677
|
+
errorResponses: errorResponses(document, operation)
|
|
2678
|
+
}
|
|
2679
|
+
});
|
|
2680
|
+
} catch (error) {
|
|
2681
|
+
if (!(error instanceof OpenapiCompileError) && !Schema_exports.isSchemaError(error)) throw error;
|
|
2682
|
+
const code = error instanceof OpenapiCompileError ? error.code : "invalid_document";
|
|
2683
|
+
if (error instanceof OpenapiCompileError && !causes.has(code)) causes.set(code, error);
|
|
2684
|
+
skipped.add(code);
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2688
|
+
for (const { operation } of built) {
|
|
2689
|
+
const origin = new URL(operation.baseUrl).origin;
|
|
2690
|
+
counts.set(origin, (counts.get(origin) ?? 0) + 1);
|
|
2691
|
+
}
|
|
2692
|
+
let documentOrigin;
|
|
2693
|
+
try {
|
|
2694
|
+
if (documentServer !== void 0)
|
|
2695
|
+
documentOrigin = new URL(serverAddress(swagger, documentServer, entry.connectUrl)).origin;
|
|
2696
|
+
} catch (error) {
|
|
2697
|
+
if (!(error instanceof OpenapiCompileError)) throw error;
|
|
2698
|
+
}
|
|
2699
|
+
let pinnedOrigin = options.allowedOrigin;
|
|
2700
|
+
for (const [origin, count] of options.allowedOrigin === void 0 ? counts : []) {
|
|
2701
|
+
const best = pinnedOrigin === void 0 ? 0 : counts.get(pinnedOrigin) ?? 0;
|
|
2702
|
+
if (count > best || count === best && origin === documentOrigin) pinnedOrigin = origin;
|
|
2703
|
+
}
|
|
2704
|
+
for (const { operation, methods: operationMethods } of built) {
|
|
2705
|
+
if (new URL(operation.baseUrl).origin !== pinnedOrigin) {
|
|
2706
|
+
skipped.add("multiple_hosts");
|
|
2707
|
+
continue;
|
|
2708
|
+
}
|
|
2709
|
+
operations.push(operation);
|
|
2710
|
+
for (const method of operationMethods) methods.set(method.name, method);
|
|
2711
|
+
}
|
|
2712
|
+
if (!operations.length) {
|
|
2713
|
+
const [only, ...others] = causes.values();
|
|
2714
|
+
if (only !== void 0 && others.length === 0 && [...skipped].every((reason) => reason === only.code))
|
|
2715
|
+
throw only;
|
|
2716
|
+
fail2(
|
|
2717
|
+
"no_supported_operations",
|
|
2718
|
+
"Executor cannot import any operation in this API definition."
|
|
2719
|
+
);
|
|
2720
|
+
}
|
|
2721
|
+
if (!operations.some(
|
|
2722
|
+
(operation) => operation.streaming !== true && (operation.request.security.length === 0 || operation.request.security.some((requirement) => {
|
|
2723
|
+
const keys = Object.keys(requirement);
|
|
2724
|
+
return keys.every((key) => bindings.has(key)) || keys.length === 1 && oauth.some((method) => method.name === keys[0]);
|
|
2725
|
+
}))
|
|
2726
|
+
))
|
|
2727
|
+
fail2(
|
|
2728
|
+
"no_supported_operations",
|
|
2729
|
+
"This API has no operations supported by the available authentication and response transports."
|
|
2730
|
+
);
|
|
2731
|
+
return {
|
|
2732
|
+
operations,
|
|
2733
|
+
definitions: Object.fromEntries(document.definitions),
|
|
2734
|
+
methods: Object.fromEntries(
|
|
2735
|
+
[...methods.values()].map((method) => [method.name, method.bindings])
|
|
2736
|
+
),
|
|
2737
|
+
secrets: [...methods.values()],
|
|
2738
|
+
oauth,
|
|
2739
|
+
schemes,
|
|
2740
|
+
pinnedOrigin,
|
|
2741
|
+
fallback
|
|
2742
|
+
};
|
|
2743
|
+
},
|
|
2744
|
+
catch: (error) => error instanceof OpenapiCompileError ? error : new OpenapiCompileError({
|
|
2745
|
+
code: "invalid_document",
|
|
2746
|
+
reason: "This API definition could not be read. It may contain unsupported OpenAPI features."
|
|
2747
|
+
})
|
|
2748
|
+
});
|
|
2749
|
+
|
|
2750
|
+
// src/implementation/openapi-source.ts
|
|
2751
|
+
var Manifest = Schema_exports.Struct({ revision: Schema_exports.String, pages: Schema_exports.Number });
|
|
2752
|
+
var Names = Schema_exports.Array(Schema_exports.String);
|
|
2753
|
+
var StoredEntry = Schema_exports.fromJsonString(Schema_exports.Struct({ value: JsonValue }));
|
|
2754
|
+
var schema = (decoder) => wrap(decoder, false);
|
|
2755
|
+
var invoke = (work) => Effect_exports.tryPromise({ try: work, catch: (error) => error });
|
|
2756
|
+
var invalid = () => new OpenapiError({ reason: "invalid_definition" });
|
|
2757
|
+
var pageSize = 64;
|
|
2758
|
+
var format = "openapi-v2";
|
|
2759
|
+
var sha256 = (text) => invoke(() => crypto.subtle.digest("SHA-256", new TextEncoder().encode(text))).pipe(
|
|
2760
|
+
Effect_exports.map(
|
|
2761
|
+
(hash2) => Array.from(new Uint8Array(hash2), (byte) => byte.toString(16).padStart(2, "0")).join("")
|
|
2762
|
+
)
|
|
2763
|
+
);
|
|
2764
|
+
var partConcurrency = 4;
|
|
2765
|
+
var resolved = /* @__PURE__ */ new Map();
|
|
2766
|
+
var resolvedBytes = 0;
|
|
2767
|
+
var remember = (key, entry) => {
|
|
2768
|
+
const bytes2 = new TextEncoder().encode(
|
|
2769
|
+
JSON.stringify([entry.operation, entry.definitions])
|
|
2770
|
+
).byteLength;
|
|
2771
|
+
if (bytes2 > 8e6) return;
|
|
2772
|
+
const previous = resolved.get(key);
|
|
2773
|
+
if (previous !== void 0) {
|
|
2774
|
+
resolvedBytes -= previous.bytes;
|
|
2775
|
+
resolved.delete(key);
|
|
2776
|
+
}
|
|
2777
|
+
while (resolved.size >= 32 || resolvedBytes + bytes2 > 8e6) {
|
|
2778
|
+
const oldest = resolved.keys().next().value;
|
|
2779
|
+
if (oldest === void 0) break;
|
|
2780
|
+
resolvedBytes -= resolved.get(oldest)?.bytes ?? 0;
|
|
2781
|
+
resolved.delete(oldest);
|
|
2782
|
+
}
|
|
2783
|
+
resolved.set(key, { ...entry, bytes: bytes2 });
|
|
2784
|
+
resolvedBytes += bytes2;
|
|
2785
|
+
};
|
|
2786
|
+
var stored = /* @__PURE__ */ new Map();
|
|
2787
|
+
var storedBytes = 0;
|
|
2788
|
+
var storedPart = (kind, name) => JSON.stringify([kind, name]);
|
|
2789
|
+
var retain = (revision, parts, bytes2) => {
|
|
2790
|
+
if (bytes2 > 8e6) return;
|
|
2791
|
+
const previous = stored.get(revision);
|
|
2792
|
+
if (previous !== void 0) {
|
|
2793
|
+
storedBytes -= previous.bytes;
|
|
2794
|
+
stored.delete(revision);
|
|
2795
|
+
}
|
|
2796
|
+
while (stored.size >= 4 || storedBytes + bytes2 > 8e6) {
|
|
2797
|
+
const oldest = stored.keys().next().value;
|
|
2798
|
+
if (oldest === void 0) break;
|
|
2799
|
+
storedBytes -= stored.get(oldest)?.bytes ?? 0;
|
|
2800
|
+
stored.delete(oldest);
|
|
2801
|
+
}
|
|
2802
|
+
stored.set(revision, { parts, bytes: bytes2 });
|
|
2803
|
+
storedBytes += bytes2;
|
|
2804
|
+
};
|
|
2805
|
+
function patchOpenapi(root, patches) {
|
|
2806
|
+
let result = root;
|
|
2807
|
+
for (const patch of patches ?? []) {
|
|
2808
|
+
if (!patch.path.startsWith("/")) throw invalid();
|
|
2809
|
+
const path = patch.path.slice(1).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
2810
|
+
if (path.some((part) => ["__proto__", "constructor", "prototype"].includes(part)))
|
|
2811
|
+
throw invalid();
|
|
2812
|
+
const update = (node, parts) => {
|
|
2813
|
+
const [head, ...rest] = parts;
|
|
2814
|
+
if (head === void 0) throw invalid();
|
|
2815
|
+
if (rest.length)
|
|
2816
|
+
return {
|
|
2817
|
+
...node,
|
|
2818
|
+
[head]: update(
|
|
2819
|
+
Schema_exports.decodeUnknownSync(JsonObject)(
|
|
2820
|
+
Object.hasOwn(node, head) ? node[head] : void 0
|
|
2821
|
+
),
|
|
2822
|
+
rest
|
|
2823
|
+
)
|
|
2824
|
+
};
|
|
2825
|
+
if (patch.op !== "add" && !Object.hasOwn(node, head)) throw invalid();
|
|
2826
|
+
if (patch.op === "remove")
|
|
2827
|
+
return Object.fromEntries(Object.entries(node).filter(([name]) => name !== head));
|
|
2828
|
+
if (patch.value === void 0) throw invalid();
|
|
2829
|
+
return { ...node, [head]: patch.value };
|
|
2830
|
+
};
|
|
2831
|
+
result = update(result, path);
|
|
2832
|
+
}
|
|
2833
|
+
return result;
|
|
2834
|
+
}
|
|
2835
|
+
var download = (url, context) => Effect_exports.gen(function* () {
|
|
2836
|
+
const response = yield* invoke(
|
|
2837
|
+
() => context.fetch(url, { signal: context.signal, redirect: "manual" })
|
|
2838
|
+
);
|
|
2839
|
+
if (!response.ok || response.body === null) return yield* invalid();
|
|
2840
|
+
const reader = response.body.getReader();
|
|
2841
|
+
const text = yield* Effect_exports.acquireUseRelease(
|
|
2842
|
+
Effect_exports.succeed(reader),
|
|
2843
|
+
(reader2) => Effect_exports.gen(function* () {
|
|
2844
|
+
const decoder = new TextDecoder();
|
|
2845
|
+
const chunks = [];
|
|
2846
|
+
let bytes2 = 0;
|
|
2847
|
+
while (true) {
|
|
2848
|
+
const chunk = yield* invoke(() => reader2.read());
|
|
2849
|
+
if (chunk.done) break;
|
|
2850
|
+
bytes2 += chunk.value.byteLength;
|
|
2851
|
+
if (bytes2 > 4e7) return yield* invalid();
|
|
2852
|
+
chunks.push(decoder.decode(chunk.value, { stream: true }));
|
|
2853
|
+
}
|
|
2854
|
+
chunks.push(decoder.decode());
|
|
2855
|
+
return chunks.join("");
|
|
2856
|
+
}),
|
|
2857
|
+
(reader2) => invoke(() => reader2.cancel()).pipe(Effect_exports.catch(() => Effect_exports.void))
|
|
2858
|
+
);
|
|
2859
|
+
return yield* Effect_exports.try({
|
|
2860
|
+
try: () => Schema_exports.decodeUnknownSync(JsonObject)(
|
|
2861
|
+
text.trimStart().startsWith("{") ? JSON.parse(text) : parse(text)
|
|
2862
|
+
),
|
|
2863
|
+
catch: invalid
|
|
2864
|
+
});
|
|
2865
|
+
});
|
|
2866
|
+
var liveOpenapiOperations = (options) => {
|
|
2867
|
+
const freshFor = options.freshFor ?? "5 minutes";
|
|
2868
|
+
const staleFor = options.staleFor ?? "1 day";
|
|
2869
|
+
const retention = Duration_exports.toMillis(Duration_exports.fromInputUnsafe(freshFor)) + Duration_exports.toMillis(Duration_exports.fromInputUnsafe(staleFor)) + 3e5;
|
|
2870
|
+
const identity = Effect_exports.cached(
|
|
2871
|
+
Effect_exports.tryPromise({
|
|
2872
|
+
try: async () => {
|
|
2873
|
+
const bytes2 = new TextEncoder().encode(
|
|
2874
|
+
JSON.stringify({
|
|
2875
|
+
source: options.source,
|
|
2876
|
+
allowedOrigin: options.allowedOrigin,
|
|
2877
|
+
baseUrl: options.baseUrl,
|
|
2878
|
+
securitySchemes: options.securitySchemes,
|
|
2879
|
+
patches: options.patches,
|
|
2880
|
+
fallbackSecurity: options.fallbackSecurity
|
|
2881
|
+
})
|
|
2882
|
+
);
|
|
2883
|
+
const hash2 = await crypto.subtle.digest("SHA-256", bytes2);
|
|
2884
|
+
return Array.from(new Uint8Array(hash2), (byte) => byte.toString(16).padStart(2, "0")).join(
|
|
2885
|
+
""
|
|
2886
|
+
);
|
|
2887
|
+
},
|
|
2888
|
+
catch: invalid
|
|
2889
|
+
})
|
|
2890
|
+
);
|
|
2891
|
+
const sourceId = Effect_exports.runSync(identity);
|
|
2892
|
+
const pointer = sourceId.pipe(Effect_exports.map((id) => [format, id, "current"]));
|
|
2893
|
+
const partKey = (revision, kind, name) => [
|
|
2894
|
+
format,
|
|
2895
|
+
revision,
|
|
2896
|
+
kind,
|
|
2897
|
+
name
|
|
2898
|
+
];
|
|
2899
|
+
const refresh = (context) => Effect_exports.gen(function* () {
|
|
2900
|
+
const raw = "url" in options.source ? yield* download(options.source.url, context) : options.source.document;
|
|
2901
|
+
const document = patchOpenapi(raw, options.patches);
|
|
2902
|
+
const compiled = yield* compileOpenApiDocument(
|
|
2903
|
+
{ name: "API", ..."url" in options.source ? { connectUrl: options.source.url } : {} },
|
|
2904
|
+
document,
|
|
2905
|
+
{
|
|
2906
|
+
allowedOrigin: options.allowedOrigin,
|
|
2907
|
+
securitySchemes: options.securitySchemes,
|
|
2908
|
+
...options.fallbackSecurity === void 0 ? {} : { fallbackSecurity: options.fallbackSecurity },
|
|
2909
|
+
...options.baseUrl === void 0 ? {} : { baseUrl: options.baseUrl }
|
|
2910
|
+
}
|
|
2911
|
+
);
|
|
2912
|
+
const revision = yield* sha256(JSON.stringify([format, yield* sourceId, document]));
|
|
2913
|
+
const names = compiled.operations.map((operation) => operation.name);
|
|
2914
|
+
const parts = [
|
|
2915
|
+
...compiled.operations.map((operation) => ({
|
|
2916
|
+
kind: "operation",
|
|
2917
|
+
name: operation.name,
|
|
2918
|
+
value: operation
|
|
2919
|
+
})),
|
|
2920
|
+
...Object.entries(compiled.definitions).map(([name, value]) => ({
|
|
2921
|
+
kind: "definition",
|
|
2922
|
+
name,
|
|
2923
|
+
value
|
|
2924
|
+
}))
|
|
2925
|
+
];
|
|
2926
|
+
const pages = Math.ceil(names.length / pageSize);
|
|
2927
|
+
for (let page = 0; page < pages; page++)
|
|
2928
|
+
parts.push({
|
|
2929
|
+
kind: "names",
|
|
2930
|
+
name: page,
|
|
2931
|
+
value: names.slice(page * pageSize, (page + 1) * pageSize)
|
|
2932
|
+
});
|
|
2933
|
+
const batches = [];
|
|
2934
|
+
let batch = [];
|
|
2935
|
+
let size = 0;
|
|
2936
|
+
const retained = /* @__PURE__ */ new Map();
|
|
2937
|
+
let retainedBytes = 0;
|
|
2938
|
+
for (const part of parts) {
|
|
2939
|
+
const entry = { key: partKey(revision, part.kind, part.name), value: part.value };
|
|
2940
|
+
const text = JSON.stringify(entry);
|
|
2941
|
+
const bytes2 = new TextEncoder().encode(text).byteLength;
|
|
2942
|
+
if (batch.length && (batch.length >= 64 || size + bytes2 > 4e6)) {
|
|
2943
|
+
batches.push({ entries: batch, bytes: size });
|
|
2944
|
+
batch = [];
|
|
2945
|
+
size = 0;
|
|
2946
|
+
}
|
|
2947
|
+
batch.push(entry);
|
|
2948
|
+
size += bytes2;
|
|
2949
|
+
retainedBytes += bytes2;
|
|
2950
|
+
if (retainedBytes <= 8e6)
|
|
2951
|
+
retained.set(
|
|
2952
|
+
storedPart(part.kind, part.name),
|
|
2953
|
+
Schema_exports.decodeUnknownSync(StoredEntry)(text).value
|
|
2954
|
+
);
|
|
2955
|
+
}
|
|
2956
|
+
if (batch.length) batches.push({ entries: batch, bytes: size });
|
|
2957
|
+
yield* Effect_exports.forEach(
|
|
2958
|
+
batches,
|
|
2959
|
+
({ entries, bytes: bytes2 }, index) => fromPromise(context.cache.write)(entries, retention).pipe(
|
|
2960
|
+
Effect_exports.withSpan("app.cache.flush", {
|
|
2961
|
+
attributes: {
|
|
2962
|
+
"cache.flush.index": index,
|
|
2963
|
+
"cache.flush.count": batches.length,
|
|
2964
|
+
"cache.flush.entries": entries.length,
|
|
2965
|
+
"cache.flush.bytes": bytes2
|
|
2966
|
+
}
|
|
2967
|
+
})
|
|
2968
|
+
),
|
|
2969
|
+
{
|
|
2970
|
+
concurrency: partConcurrency,
|
|
2971
|
+
discard: true
|
|
2972
|
+
}
|
|
2973
|
+
);
|
|
2974
|
+
retain(revision, retained, retainedBytes);
|
|
2975
|
+
return { revision, pages };
|
|
2976
|
+
});
|
|
2977
|
+
const current = Effect_exports.gen(function* () {
|
|
2978
|
+
const key = yield* pointer;
|
|
2979
|
+
return yield* fromPromise(options.cache.get)({
|
|
2980
|
+
key,
|
|
2981
|
+
schema: schema(Manifest),
|
|
2982
|
+
freshFor,
|
|
2983
|
+
staleFor,
|
|
2984
|
+
load: toPromise(refresh)
|
|
2985
|
+
});
|
|
2986
|
+
});
|
|
2987
|
+
const read = (revision, kind, names, decoder) => {
|
|
2988
|
+
const retained = stored.get(revision);
|
|
2989
|
+
return retained === void 0 ? fromPromise(options.cache.readMany)(
|
|
2990
|
+
names.map((name) => partKey(revision, kind, name)),
|
|
2991
|
+
schema(decoder)
|
|
2992
|
+
) : Effect_exports.forEach(names, (name) => {
|
|
2993
|
+
const value = retained.parts.get(storedPart(kind, name));
|
|
2994
|
+
return value === void 0 ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoder)(value);
|
|
2995
|
+
});
|
|
2996
|
+
};
|
|
2997
|
+
const namesFor = (manifest) => Effect_exports.gen(function* () {
|
|
2998
|
+
const names = [];
|
|
2999
|
+
for (let page = 0; page < manifest.pages; page += pageSize) {
|
|
3000
|
+
const pages = yield* read(
|
|
3001
|
+
manifest.revision,
|
|
3002
|
+
"names",
|
|
3003
|
+
Array.from({ length: Math.min(pageSize, manifest.pages - page) }, (_, i) => page + i),
|
|
3004
|
+
Names
|
|
3005
|
+
);
|
|
3006
|
+
for (const values of pages) {
|
|
3007
|
+
if (values === void 0) return void 0;
|
|
3008
|
+
names.push(...values);
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
return names;
|
|
3012
|
+
});
|
|
3013
|
+
const definitionsFor = (revision, operation) => Effect_exports.gen(function* () {
|
|
3014
|
+
const definitions = {};
|
|
3015
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3016
|
+
let pending = [...references(operation)];
|
|
3017
|
+
while (pending.length) {
|
|
3018
|
+
const names = [...new Set(pending.splice(0, pageSize * partConcurrency))].filter(
|
|
3019
|
+
(name) => !seen.has(name)
|
|
3020
|
+
);
|
|
3021
|
+
names.forEach((name) => seen.add(name));
|
|
3022
|
+
if (!names.length) continue;
|
|
3023
|
+
const values = (yield* Effect_exports.forEach(
|
|
3024
|
+
Array.from(
|
|
3025
|
+
{ length: Math.ceil(names.length / pageSize) },
|
|
3026
|
+
(_, page) => names.slice(page * pageSize, (page + 1) * pageSize)
|
|
3027
|
+
),
|
|
3028
|
+
(batch) => read(revision, "definition", batch, JsonObject),
|
|
3029
|
+
{ concurrency: partConcurrency }
|
|
3030
|
+
)).flat();
|
|
3031
|
+
for (let i = 0; i < names.length; i++) {
|
|
3032
|
+
const name = names[i];
|
|
3033
|
+
const value = values[i];
|
|
3034
|
+
if (name === void 0 || value === void 0) return void 0;
|
|
3035
|
+
definitions[name] = value;
|
|
3036
|
+
pending.push(...references(value));
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
return definitions;
|
|
3040
|
+
});
|
|
3041
|
+
const defaultedNames = JSON.stringify(
|
|
3042
|
+
Object.entries(options.parameterDefaults ?? {}).map(([group, values]) => [
|
|
3043
|
+
group,
|
|
3044
|
+
Object.keys(values ?? {}).sort()
|
|
3045
|
+
])
|
|
3046
|
+
);
|
|
3047
|
+
const kindOf = (op) => {
|
|
3048
|
+
const key = op.operationId ?? op.name;
|
|
3049
|
+
const kinds = options.kinds ?? {};
|
|
3050
|
+
return Object.hasOwn(kinds, key) ? kinds[key] ?? "mutation" : ["GET", "HEAD", "OPTIONS"].includes(op.method) ? "query" : "mutation";
|
|
3051
|
+
};
|
|
3052
|
+
const qualified = (op) => `${kindOf(op) === "query" ? "queries" : "mutations"}.${op.name}`;
|
|
3053
|
+
const operationsFor = (manifest) => Effect_exports.gen(function* () {
|
|
3054
|
+
const names = yield* namesFor(manifest);
|
|
3055
|
+
if (names === void 0) return void 0;
|
|
3056
|
+
const pages = yield* Effect_exports.forEach(
|
|
3057
|
+
Array.from(
|
|
3058
|
+
{ length: Math.ceil(names.length / pageSize) },
|
|
3059
|
+
(_, page) => names.slice(page * pageSize, (page + 1) * pageSize)
|
|
3060
|
+
),
|
|
3061
|
+
(batch) => read(manifest.revision, "operation", batch, OpenapiOperation),
|
|
3062
|
+
{ concurrency: partConcurrency }
|
|
3063
|
+
);
|
|
3064
|
+
const all = [];
|
|
3065
|
+
for (const operations of pages) {
|
|
3066
|
+
for (const operation of operations) {
|
|
3067
|
+
if (operation === void 0) return void 0;
|
|
3068
|
+
all.push(operation);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
return all;
|
|
3072
|
+
});
|
|
3073
|
+
const summarize = (operation) => {
|
|
3074
|
+
const name = qualified(operation);
|
|
3075
|
+
return { name, description: operation.description, readOnly: name.startsWith("queries.") };
|
|
3076
|
+
};
|
|
3077
|
+
const describe = (operation, bundle) => ({
|
|
3078
|
+
...summarize(operation),
|
|
3079
|
+
inputSchema: bundle(parameterDefaultsInput(operation, options.parameterDefaults, true)),
|
|
3080
|
+
...operation.outputSchema === void 0 ? {} : { outputSchema: bundle(operation.outputSchema) }
|
|
3081
|
+
});
|
|
3082
|
+
const withRevision = (work) => Effect_exports.gen(function* () {
|
|
3083
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
3084
|
+
const result = yield* work(yield* current);
|
|
3085
|
+
if (result !== void 0) return result.value;
|
|
3086
|
+
yield* fromPromise(options.cache.invalidate)(yield* pointer);
|
|
3087
|
+
}
|
|
3088
|
+
return yield* invalid();
|
|
3089
|
+
});
|
|
3090
|
+
return {
|
|
3091
|
+
queries: {},
|
|
3092
|
+
mutations: {},
|
|
3093
|
+
dynamicTools: {
|
|
3094
|
+
resolve: (name) => withRevision(
|
|
3095
|
+
(manifest) => Effect_exports.gen(function* () {
|
|
3096
|
+
const raw = name.replace(/^(queries|mutations)\./, "");
|
|
3097
|
+
const memoKey = `${manifest.revision}/${defaultedNames}/${raw}`;
|
|
3098
|
+
const memo = resolved.get(memoKey);
|
|
3099
|
+
const operation = memo?.operation ?? (yield* read(manifest.revision, "operation", [raw], OpenapiOperation))[0];
|
|
3100
|
+
if (operation === void 0) {
|
|
3101
|
+
const names = yield* namesFor(manifest);
|
|
3102
|
+
return names === void 0 || names.includes(raw) ? void 0 : { value: void 0 };
|
|
3103
|
+
}
|
|
3104
|
+
if (qualified(operation) !== name) return { value: void 0 };
|
|
3105
|
+
const definitions = memo?.definitions ?? (yield* definitionsFor(manifest.revision, operation));
|
|
3106
|
+
if (definitions === void 0) return void 0;
|
|
3107
|
+
const schemas = memo?.schemas ?? (yield* prepareOpenapiOperation(operation, definitions, options.parameterDefaults));
|
|
3108
|
+
if (memo === void 0) remember(memoKey, { operation, definitions, schemas });
|
|
3109
|
+
const tools = yield* openapiToolsEffect(
|
|
3110
|
+
{ ...options, operations: [operation], definitions },
|
|
3111
|
+
/* @__PURE__ */ new Map([[operation.name, schemas]])
|
|
3112
|
+
);
|
|
3113
|
+
const declarations = protocolOperations(tools, {
|
|
3114
|
+
[operation.name]: kindOf(operation)
|
|
3115
|
+
});
|
|
3116
|
+
const declaration = declarations.queries[raw] ?? declarations.mutations[raw];
|
|
3117
|
+
return { value: declaration === void 0 ? void 0 : nativeOperation(declaration) };
|
|
3118
|
+
})
|
|
3119
|
+
),
|
|
3120
|
+
list: () => withRevision(
|
|
3121
|
+
(manifest) => Effect_exports.gen(function* () {
|
|
3122
|
+
const all = yield* operationsFor(manifest);
|
|
3123
|
+
if (all === void 0) return void 0;
|
|
3124
|
+
const definitions = yield* definitionsFor(manifest.revision, all);
|
|
3125
|
+
if (definitions === void 0) return void 0;
|
|
3126
|
+
const bundle = bundler(definitions);
|
|
3127
|
+
const request = createRequest(options);
|
|
3128
|
+
return {
|
|
3129
|
+
value: all.filter((op) => request.available(op, options.account)).map((operation) => describe(operation, bundle))
|
|
3130
|
+
};
|
|
3131
|
+
})
|
|
3132
|
+
),
|
|
3133
|
+
summaries: () => withRevision(
|
|
3134
|
+
(manifest) => Effect_exports.gen(function* () {
|
|
3135
|
+
const all = yield* operationsFor(manifest);
|
|
3136
|
+
if (all === void 0) return void 0;
|
|
3137
|
+
const request = createRequest(options);
|
|
3138
|
+
return {
|
|
3139
|
+
value: all.filter((op) => request.available(op, options.account)).map((operation) => summarize(operation))
|
|
3140
|
+
};
|
|
3141
|
+
})
|
|
3142
|
+
),
|
|
3143
|
+
describe: (name) => withRevision(
|
|
3144
|
+
(manifest) => Effect_exports.gen(function* () {
|
|
3145
|
+
const raw = name.replace(/^(queries|mutations)\./, "");
|
|
3146
|
+
const operation = (yield* read(
|
|
3147
|
+
manifest.revision,
|
|
3148
|
+
"operation",
|
|
3149
|
+
[raw],
|
|
3150
|
+
OpenapiOperation
|
|
3151
|
+
))[0];
|
|
3152
|
+
if (operation === void 0) {
|
|
3153
|
+
const names = yield* namesFor(manifest);
|
|
3154
|
+
return names === void 0 || names.includes(raw) ? void 0 : { value: void 0 };
|
|
3155
|
+
}
|
|
3156
|
+
if (qualified(operation) !== name || !createRequest(options).available(operation, options.account))
|
|
3157
|
+
return { value: void 0 };
|
|
3158
|
+
const definitions = yield* definitionsFor(manifest.revision, operation);
|
|
3159
|
+
if (definitions === void 0) return void 0;
|
|
3160
|
+
return { value: describe(operation, bundler(definitions)) };
|
|
3161
|
+
})
|
|
3162
|
+
)
|
|
3163
|
+
}
|
|
3164
|
+
};
|
|
3165
|
+
};
|
|
3166
|
+
|
|
236
3167
|
// src/openapi.ts
|
|
237
3168
|
var openapiOperations = (options, kinds = {}) => Effect_exports.runPromise(
|
|
238
3169
|
openapiToolsEffect(options).pipe(
|
|
@@ -241,6 +3172,15 @@ var openapiOperations = (options, kinds = {}) => Effect_exports.runPromise(
|
|
|
241
3172
|
options.signal === void 0 ? {} : { signal: options.signal }
|
|
242
3173
|
);
|
|
243
3174
|
export {
|
|
3175
|
+
OpenapiCompileError,
|
|
3176
|
+
OpenapiCompileErrorCode,
|
|
244
3177
|
OpenapiError,
|
|
3178
|
+
OpenapiErrorResponse,
|
|
3179
|
+
OpenapiParameter,
|
|
3180
|
+
OpenapiRequestBody,
|
|
3181
|
+
isOpenapiTextMedia,
|
|
3182
|
+
liveOpenapiOperations,
|
|
3183
|
+
openapiBinaryResultSchema,
|
|
3184
|
+
openapiMediaKind,
|
|
245
3185
|
openapiOperations
|
|
246
3186
|
};
|