@executor-js/plugin-openapi 1.5.15 → 1.5.17

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.
Files changed (59) hide show
  1. package/dist/AddOpenApiSource-U7AYB224.js +369 -0
  2. package/dist/AddOpenApiSource-U7AYB224.js.map +1 -0
  3. package/dist/{OpenApiAccountsPanel-X5Z5XKRM.js → OpenApiAccountsPanel-GHFHHE6P.js} +15 -39
  4. package/dist/OpenApiAccountsPanel-GHFHHE6P.js.map +1 -0
  5. package/dist/{UpdateSpecSection-Z2DEEWZW.js → UpdateSpecSection-PLCBUU4I.js} +4 -4
  6. package/dist/UpdateSpecSection-PLCBUU4I.js.map +1 -0
  7. package/dist/api/group.d.ts +0 -21
  8. package/dist/api/index.d.ts +0 -21
  9. package/dist/chunk-CKBX4SXK.js +95 -0
  10. package/dist/chunk-CKBX4SXK.js.map +1 -0
  11. package/dist/{chunk-NJ4Q3VF4.js → chunk-CPPTKUOW.js} +5 -14
  12. package/dist/chunk-CPPTKUOW.js.map +1 -0
  13. package/dist/{chunk-O54VFSWE.js → chunk-KVPUDOJZ.js} +18 -4
  14. package/dist/chunk-KVPUDOJZ.js.map +1 -0
  15. package/dist/{chunk-PAHWRRS3.js → chunk-QQFCICLX.js} +4 -13
  16. package/dist/chunk-QQFCICLX.js.map +1 -0
  17. package/dist/{chunk-ZTOOUP67.js → chunk-UEKOP6NZ.js} +544 -580
  18. package/dist/chunk-UEKOP6NZ.js.map +1 -0
  19. package/dist/client.js +4 -5
  20. package/dist/client.js.map +1 -1
  21. package/dist/core.js +25 -15
  22. package/dist/core.js.map +1 -1
  23. package/dist/index.js +4 -5
  24. package/dist/index.js.map +1 -1
  25. package/dist/react/atoms.d.ts +0 -22
  26. package/dist/react/client.d.ts +0 -21
  27. package/dist/react/index.d.ts +2 -0
  28. package/dist/sdk/backing.d.ts +54 -0
  29. package/dist/sdk/config.d.ts +0 -2
  30. package/dist/sdk/derive-auth.d.ts +5 -3
  31. package/dist/sdk/index.d.ts +2 -1
  32. package/dist/sdk/plugin.d.ts +4 -10
  33. package/dist/sdk/presets.d.ts +0 -1
  34. package/dist/sdk/preview.d.ts +79 -0
  35. package/dist/testing/index.d.ts +0 -6
  36. package/package.json +6 -5
  37. package/dist/AddOpenApiSource-IRMLVLDK.js +0 -765
  38. package/dist/AddOpenApiSource-IRMLVLDK.js.map +0 -1
  39. package/dist/OpenApiAccountsPanel-X5Z5XKRM.js.map +0 -1
  40. package/dist/UpdateSpecSection-Z2DEEWZW.js.map +0 -1
  41. package/dist/chunk-MZWZQ24W.js +0 -226
  42. package/dist/chunk-MZWZQ24W.js.map +0 -1
  43. package/dist/chunk-NJ4Q3VF4.js.map +0 -1
  44. package/dist/chunk-O54VFSWE.js.map +0 -1
  45. package/dist/chunk-PAHWRRS3.js.map +0 -1
  46. package/dist/chunk-UOLBAX5D.js +0 -712
  47. package/dist/chunk-UOLBAX5D.js.map +0 -1
  48. package/dist/chunk-ZTOOUP67.js.map +0 -1
  49. package/dist/react/GoogleProductPicker.d.ts +0 -9
  50. package/dist/sdk/google-discovery.d.ts +0 -43
  51. package/dist/sdk/google-oauth-batches.d.ts +0 -13
  52. package/dist/sdk/google-oauth-batches.test.d.ts +0 -1
  53. package/dist/sdk/google-oauth-scopes.d.ts +0 -3
  54. package/dist/sdk/google-oauth-scopes.test.d.ts +0 -1
  55. package/dist/sdk/google-presets.d.ts +0 -16
  56. package/dist/sdk/google-presets.test.d.ts +0 -1
  57. package/dist/sdk/google-product-picker-scopes.test.d.ts +0 -1
  58. /package/dist/sdk/{google-bundle.test.d.ts → request-user-agent.test.d.ts} +0 -0
  59. /package/dist/sdk/{google-discovery.test.d.ts → store.test.d.ts} +0 -0
@@ -1,712 +0,0 @@
1
- import {
2
- OpenApiParseError,
3
- resolveServerUrl
4
- } from "./chunk-O54VFSWE.js";
5
-
6
- // src/sdk/google-discovery.ts
7
- import { Effect, Option, Predicate, Schema, SchemaGetter } from "effect";
8
- import { HttpClient, HttpClientRequest } from "effect/unstable/http";
9
-
10
- // src/sdk/google-oauth-scopes.ts
11
- var googleUserConsentBlockedScopes = /* @__PURE__ */ new Set([
12
- "https://www.googleapis.com/auth/chat.bot",
13
- "https://www.googleapis.com/auth/chat.import",
14
- "https://www.googleapis.com/auth/keep",
15
- "https://www.googleapis.com/auth/keep.readonly"
16
- ]);
17
- var googleUserConsentBlockedScopePrefixes = ["https://www.googleapis.com/auth/chat.app."];
18
- var googleBroadScopeGroups = [
19
- {
20
- broad: "https://mail.google.com/",
21
- prefixes: ["https://www.googleapis.com/auth/gmail."]
22
- },
23
- {
24
- broad: "https://www.googleapis.com/auth/calendar",
25
- prefixes: ["https://www.googleapis.com/auth/calendar."]
26
- },
27
- {
28
- broad: "https://www.googleapis.com/auth/drive",
29
- prefixes: ["https://www.googleapis.com/auth/drive."]
30
- }
31
- ];
32
- var normalizeGoogleIdentityScope = (scope) => scope === "https://www.googleapis.com/auth/userinfo.email" ? "email" : scope === "https://www.googleapis.com/auth/userinfo.profile" ? "profile" : scope;
33
- var orderedUniqueScopes = (scopes) => {
34
- const ordered = [];
35
- const seen = /* @__PURE__ */ new Set();
36
- for (const scope of scopes) {
37
- const trimmed = scope.trim();
38
- if (!trimmed || seen.has(trimmed)) continue;
39
- seen.add(trimmed);
40
- ordered.push(trimmed);
41
- }
42
- return ordered;
43
- };
44
- var isGoogleUserConsentOAuthScope = (scope) => !googleUserConsentBlockedScopes.has(scope) && !googleUserConsentBlockedScopePrefixes.some((prefix) => scope.startsWith(prefix));
45
- var filterGoogleUserConsentOAuthScopes = (scopes) => orderedUniqueScopes(scopes).filter(isGoogleUserConsentOAuthScope);
46
- var compactGoogleOAuthScopes = (scopes) => {
47
- const ordered = filterGoogleUserConsentOAuthScopes([...scopes].map(normalizeGoogleIdentityScope));
48
- const present = new Set(ordered);
49
- return ordered.filter(
50
- (scope) => !googleBroadScopeGroups.some(
51
- (group) => scope !== group.broad && present.has(group.broad) && group.prefixes.some((prefix) => scope.startsWith(prefix))
52
- )
53
- );
54
- };
55
-
56
- // src/sdk/google-discovery.ts
57
- import { AuthTemplateSlug } from "@executor-js/sdk/shared";
58
- var DISCOVERY_SERVICE_HOST = "https://www.googleapis.com/discovery/v1/apis";
59
- var GOOGLE_BUNDLE_BASE_URL = "https://www.googleapis.com/";
60
- var GOOGLE_OAUTH_AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/v2/auth";
61
- var GOOGLE_OAUTH_TOKEN_URL = "https://oauth2.googleapis.com/token";
62
- var OPENAPI_SCHEMA_TYPES = /* @__PURE__ */ new Set([
63
- "array",
64
- "boolean",
65
- "integer",
66
- "null",
67
- "number",
68
- "object",
69
- "string"
70
- ]);
71
- var TextOption = Schema.OptionFromOptional(Schema.Trim).pipe(
72
- Schema.decode({
73
- decode: SchemaGetter.transform((value) => Option.filter(value, (text) => text.length > 0)),
74
- encode: SchemaGetter.transform((value) => value)
75
- }),
76
- Schema.withDecodingDefaultType(Effect.succeed(Option.none()))
77
- );
78
- var TextArray = Schema.optional(Schema.Array(Schema.String)).pipe(
79
- Schema.withDecodingDefaultType(Effect.succeed([]))
80
- );
81
- var UnknownRecord = Schema.Record(Schema.String, Schema.Unknown);
82
- var UnknownRecordWithDefault = Schema.optional(UnknownRecord).pipe(
83
- Schema.withDecodingDefaultType(Effect.succeed({}))
84
- );
85
- var DiscoveryParameter = Schema.Struct({
86
- type: Schema.optional(Schema.String),
87
- description: TextOption,
88
- properties: UnknownRecordWithDefault,
89
- items: Schema.optional(Schema.Unknown),
90
- additionalProperties: Schema.optional(Schema.Union([Schema.Boolean, Schema.Unknown])),
91
- enum: TextArray,
92
- format: Schema.optional(Schema.String),
93
- readOnly: Schema.optional(Schema.Boolean),
94
- default: Schema.optional(Schema.Union([Schema.String, Schema.Number, Schema.Boolean])),
95
- $ref: Schema.optional(Schema.String),
96
- location: Schema.optional(Schema.Literals(["path", "query", "header"])),
97
- required: Schema.optional(Schema.Boolean),
98
- repeated: Schema.optional(Schema.Boolean)
99
- });
100
- var DiscoveryRef = Schema.Struct({
101
- $ref: Schema.optional(Schema.String)
102
- });
103
- var DiscoveryMethod = Schema.Struct({
104
- id: TextOption,
105
- description: TextOption,
106
- httpMethod: Schema.optional(Schema.String),
107
- path: TextOption,
108
- parameters: UnknownRecordWithDefault,
109
- request: Schema.optional(DiscoveryRef),
110
- response: Schema.optional(DiscoveryRef),
111
- scopes: TextArray
112
- });
113
- var DiscoveryResource = Schema.Struct({
114
- methods: UnknownRecordWithDefault,
115
- resources: UnknownRecordWithDefault
116
- });
117
- var DiscoveryDocument = Schema.Struct({
118
- name: TextOption,
119
- version: TextOption,
120
- title: TextOption,
121
- rootUrl: TextOption,
122
- servicePath: Schema.optional(Schema.Trim).pipe(
123
- Schema.withDecodingDefaultType(Effect.succeed(""))
124
- ),
125
- parameters: UnknownRecordWithDefault,
126
- methods: UnknownRecordWithDefault,
127
- resources: UnknownRecordWithDefault,
128
- schemas: UnknownRecordWithDefault,
129
- auth: Schema.optional(
130
- Schema.Struct({
131
- oauth2: Schema.optional(
132
- Schema.Struct({
133
- scopes: Schema.optional(
134
- Schema.Record(
135
- Schema.String,
136
- Schema.Struct({
137
- description: TextOption
138
- })
139
- )
140
- ).pipe(Schema.withDecodingDefaultType(Effect.succeed({})))
141
- })
142
- )
143
- })
144
- )
145
- });
146
- var decodeDiscoveryDocument = Schema.decodeUnknownSync(DiscoveryDocument);
147
- var decodeDiscoveryParameter = Schema.decodeUnknownSync(DiscoveryParameter);
148
- var decodeDiscoveryMethod = Schema.decodeUnknownSync(DiscoveryMethod);
149
- var decodeDiscoveryResource = Schema.decodeUnknownSync(DiscoveryResource);
150
- var parseJson = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Unknown));
151
- var normalizeDiscoveryUrl = (discoveryUrl) => {
152
- const trimmed = discoveryUrl.trim();
153
- if (!URL.canParse(trimmed)) return trimmed;
154
- const parsed = new URL(trimmed);
155
- if (parsed.pathname !== "/$discovery/rest") return trimmed;
156
- const version = parsed.searchParams.get("version")?.trim();
157
- if (!version) return trimmed;
158
- const host = parsed.hostname.toLowerCase();
159
- if (!host.endsWith(".googleapis.com")) return trimmed;
160
- const rawService = host.slice(0, -".googleapis.com".length);
161
- const service = rawService === "calendar-json" ? "calendar" : rawService.endsWith("-json") ? rawService.slice(0, -5) : rawService;
162
- return service ? `${DISCOVERY_SERVICE_HOST}/${service}/${version}/rest` : trimmed;
163
- };
164
- var isGoogleDiscoveryUrl = (url) => {
165
- const trimmed = url.trim();
166
- if (!URL.canParse(trimmed)) return false;
167
- const parsed = new URL(trimmed);
168
- const host = parsed.hostname.toLowerCase();
169
- if (!host.endsWith("googleapis.com")) return false;
170
- return parsed.pathname.includes("/discovery/") || parsed.pathname.includes("$discovery");
171
- };
172
- var fetchGoogleDiscoveryDocument = Effect.fn("OpenApi.fetchGoogleDiscoveryDocument")(
173
- function* (discoveryUrl, credentials) {
174
- const client = yield* HttpClient.HttpClient;
175
- const requestUrl = new URL(discoveryUrl);
176
- for (const [name, value] of Object.entries(credentials?.queryParams ?? {})) {
177
- requestUrl.searchParams.set(name, value);
178
- }
179
- let request = HttpClientRequest.get(requestUrl.toString()).pipe(
180
- HttpClientRequest.setHeader("Accept", "application/json, */*")
181
- );
182
- for (const [name, value] of Object.entries(credentials?.headers ?? {})) {
183
- request = HttpClientRequest.setHeader(request, name, value);
184
- }
185
- const response = yield* client.execute(request).pipe(
186
- Effect.mapError(
187
- () => new OpenApiParseError({
188
- message: "Failed to fetch Google Discovery document"
189
- })
190
- )
191
- );
192
- if (response.status < 200 || response.status >= 300) {
193
- return yield* new OpenApiParseError({
194
- message: `Failed to fetch Google Discovery document: HTTP ${response.status}`
195
- });
196
- }
197
- return yield* response.text.pipe(
198
- Effect.mapError(
199
- () => new OpenApiParseError({
200
- message: "Failed to read Google Discovery document body"
201
- })
202
- )
203
- );
204
- }
205
- );
206
- var schemaRef = (name) => `#/components/schemas/${name}`;
207
- var identitySchemaName = (name) => name;
208
- var schemaComponentPart = (value) => value.trim().replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "") || "schema";
209
- var normalizeDiscoveryPathTemplate = (pathTemplate) => pathTemplate.replaceAll(/\{\+([^{}]+)\}/g, "{$1}");
210
- var pathUsesReservedExpansion = (pathTemplate, parameterName) => pathTemplate.includes(`{+${parameterName}}`);
211
- var uniquePathKey = (paths, preferredPath, method, toolPath) => {
212
- if (!paths[preferredPath]?.[method]) return preferredPath;
213
- const disambiguated = `/${toolPath.replace(/[^A-Za-z0-9._~-]+/g, "/")}`;
214
- if (!paths[disambiguated]?.[method]) return disambiguated;
215
- let index = 2;
216
- while (paths[`${disambiguated}/${index}`]?.[method]) index += 1;
217
- return `${disambiguated}/${index}`;
218
- };
219
- var discoveryDescription = (value) => typeof value === "string" ? value : Option.isOption(value) && Option.isSome(value) ? typeof value.value === "string" ? value.value : void 0 : void 0;
220
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
221
- var jsonValue = (value) => {
222
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
223
- return value;
224
- }
225
- if (Array.isArray(value)) {
226
- const values = value.map(jsonValue);
227
- return values.every(Predicate.isNotUndefined) ? values : void 0;
228
- }
229
- if (!isRecord(value)) return void 0;
230
- const entries = Object.entries(value).flatMap(([key, item]) => {
231
- const converted = jsonValue(item);
232
- return converted === void 0 ? [] : [[key, converted]];
233
- });
234
- return Object.fromEntries(entries);
235
- };
236
- var stringArray = (value) => {
237
- if (!Array.isArray(value)) return void 0;
238
- const strings = value.filter((item) => typeof item === "string");
239
- return strings.length === value.length ? strings : void 0;
240
- };
241
- var schemaType = (value) => typeof value === "string" && OPENAPI_SCHEMA_TYPES.has(value) ? value : void 0;
242
- var discoverySchemaToOpenApiSchema = (raw, schemaNameForRef = identitySchemaName) => {
243
- if (!isRecord(raw)) return {};
244
- const schema = raw;
245
- if (typeof schema.$ref === "string") return { $ref: schemaRef(schemaNameForRef(schema.$ref)) };
246
- const description = discoveryDescription(schema.description);
247
- const title = discoveryDescription(schema.title);
248
- const defaultValue = jsonValue(schema.default);
249
- const enumValues = Array.isArray(schema.enum) ? schema.enum.map(jsonValue).filter(Predicate.isNotUndefined) : [];
250
- const format = typeof schema.format === "string" ? schema.format : void 0;
251
- const readOnly = typeof schema.readOnly === "boolean" ? schema.readOnly : void 0;
252
- const type = schemaType(schema.type);
253
- const base = {
254
- ...description !== void 0 ? { description } : {},
255
- ...title !== void 0 ? { title } : {},
256
- ...format !== void 0 ? { format } : {},
257
- ...readOnly !== void 0 ? { readOnly } : {},
258
- ...defaultValue !== void 0 ? { default: defaultValue } : {},
259
- ...enumValues.length > 0 ? { enum: enumValues } : {}
260
- };
261
- if (type === "array") {
262
- return {
263
- ...base,
264
- type: "array",
265
- items: discoverySchemaToOpenApiSchema(schema.items, schemaNameForRef)
266
- };
267
- }
268
- const properties = schema.properties;
269
- if (type === "object" || isRecord(properties) && Object.keys(properties).length > 0 || schema.additionalProperties !== void 0) {
270
- const convertedProperties = isRecord(properties) ? Object.fromEntries(
271
- Object.entries(properties).map(([name, value]) => [
272
- name,
273
- discoverySchemaToOpenApiSchema(value, schemaNameForRef)
274
- ])
275
- ) : void 0;
276
- const required = stringArray(schema.required);
277
- const additionalProperties = schema.additionalProperties === void 0 ? void 0 : typeof schema.additionalProperties === "boolean" ? schema.additionalProperties : discoverySchemaToOpenApiSchema(schema.additionalProperties, schemaNameForRef);
278
- return {
279
- ...base,
280
- type: "object",
281
- ...convertedProperties && Object.keys(convertedProperties).length > 0 ? { properties: convertedProperties } : {},
282
- ...required && required.length > 0 ? { required } : {},
283
- ...additionalProperties !== void 0 ? { additionalProperties } : {}
284
- };
285
- }
286
- return type !== void 0 ? { ...base, type } : base;
287
- };
288
- var parameterSchema = (parameter, schemaNameForRef = identitySchemaName) => {
289
- const base = discoverySchemaToOpenApiSchema(parameter, schemaNameForRef);
290
- return parameter.repeated ? {
291
- type: "array",
292
- items: base
293
- } : base;
294
- };
295
- var methodToolPath = (service, methodId) => methodId.startsWith(`${service}.`) ? methodId.slice(service.length + 1) : methodId;
296
- var collectMethods = (resource) => {
297
- const decoded = decodeDiscoveryResource(resource);
298
- const direct = Object.values(decoded.methods ?? {}).map((raw) => decodeDiscoveryMethod(raw));
299
- const nested = Object.values(decoded.resources ?? {}).flatMap(collectMethods);
300
- return [...direct, ...nested];
301
- };
302
- var discoveryScopes = (document) => Object.fromEntries(
303
- Object.entries(document.auth?.oauth2?.scopes ?? {}).map(([scope, value]) => [
304
- scope,
305
- Option.getOrElse(value.description, () => "")
306
- ])
307
- );
308
- var compactDiscoveryScopeMap = (raw) => {
309
- const descriptionFor = (scope) => {
310
- if (raw[scope] !== void 0) return raw[scope];
311
- if (scope === "email") return raw["https://www.googleapis.com/auth/userinfo.email"] ?? "";
312
- if (scope === "profile") return raw["https://www.googleapis.com/auth/userinfo.profile"] ?? "";
313
- return "";
314
- };
315
- return Object.fromEntries(
316
- compactGoogleOAuthScopes(Object.keys(raw)).map((scope) => [scope, descriptionFor(scope)])
317
- );
318
- };
319
- var allDiscoveryMethods = (document) => [
320
- ...Object.values(document.methods ?? {}).map((raw) => decodeDiscoveryMethod(raw)),
321
- ...Object.values(document.resources ?? {}).flatMap(collectMethods)
322
- ];
323
- var discoveryDocumentInfo = (document, discoveryUrl) => Effect.gen(function* () {
324
- const service = Option.getOrUndefined(document.name);
325
- const version = Option.getOrUndefined(document.version);
326
- const rootUrl = Option.getOrUndefined(document.rootUrl);
327
- if (!service || !version || !rootUrl) {
328
- return yield* new OpenApiParseError({
329
- message: "Google Discovery document is missing one of: name, version, rootUrl"
330
- });
331
- }
332
- return {
333
- discoveryUrl,
334
- document,
335
- service,
336
- version,
337
- rootUrl,
338
- baseUrl: new URL(document.servicePath || "", rootUrl).toString(),
339
- title: Option.getOrElse(document.title, () => `${service} ${version}`)
340
- };
341
- });
342
- var buildDiscoveryOperation = (input) => {
343
- const mergedParameters = /* @__PURE__ */ new Map();
344
- for (const [name, raw] of Object.entries(input.document.parameters ?? {})) {
345
- const parameter = decodeDiscoveryParameter(raw);
346
- if (parameter.location) mergedParameters.set(name, parameter);
347
- }
348
- for (const [name, raw] of Object.entries(input.method.parameters ?? {})) {
349
- const parameter = decodeDiscoveryParameter(raw);
350
- if (parameter.location) mergedParameters.set(name, parameter);
351
- }
352
- const methodScopes = input.method.scopes ?? [];
353
- const methodDescription = Option.getOrUndefined(input.method.description);
354
- const schemaNameForRef = input.schemaNameForRef ?? identitySchemaName;
355
- return {
356
- operationId: input.toolPath,
357
- "x-executor-toolPath": input.toolPath,
358
- "x-executor-pathTemplate": input.pathTemplate,
359
- ...input.tags && input.tags.length > 0 ? { tags: input.tags } : {},
360
- ...methodDescription !== void 0 ? { description: methodDescription } : {},
361
- ...input.serverUrl ? { servers: [{ url: input.serverUrl }] } : {},
362
- parameters: [...mergedParameters.entries()].flatMap(([name, parameter]) => {
363
- const location = parameter.location;
364
- if (!location) return [];
365
- const description = Option.getOrUndefined(parameter.description);
366
- const allowReserved = location === "path" && pathUsesReservedExpansion(input.pathTemplate, name);
367
- return [
368
- {
369
- name,
370
- in: location,
371
- required: location === "path" ? true : parameter.required === true,
372
- ...description !== void 0 ? { description } : {},
373
- schema: parameterSchema(parameter, schemaNameForRef),
374
- ...location === "query" ? { style: "form", explode: parameter.repeated === true } : {},
375
- ...allowReserved ? { allowReserved: true } : {}
376
- }
377
- ];
378
- }),
379
- ...input.method.request?.$ref ? {
380
- requestBody: {
381
- required: false,
382
- content: {
383
- "application/json": {
384
- schema: { $ref: schemaRef(schemaNameForRef(input.method.request.$ref)) }
385
- }
386
- }
387
- }
388
- } : {},
389
- responses: {
390
- "200": {
391
- description: "Successful response",
392
- content: {
393
- "application/json": {
394
- schema: input.method.response?.$ref ? { $ref: schemaRef(schemaNameForRef(input.method.response.$ref)) } : {}
395
- }
396
- }
397
- }
398
- },
399
- ...methodScopes.length > 0 ? { security: [{ googleOAuth2: methodScopes }] } : {},
400
- "x-google-scopes": methodScopes
401
- };
402
- };
403
- var GOOGLE_OAUTH_SECURITY_SCHEME = "googleOAuth2";
404
- var googleOauthTemplate = (scopes) => (
405
- // A Google-discovery integration is ALWAYS OAuth, so it ALWAYS declares its
406
- // oauth method — even when the compacted scope set is empty (e.g. a bundle of
407
- // only limited-consent APIs like Google Keep, whose scopes Google won't grant
408
- // through standard consent). Without this the integration declares no auth
409
- // method and the "Add account" / "Add a connection" actions are disabled, so
410
- // you can't even start the flow. Empty `scopes` just requests no scope.
411
- [
412
- {
413
- slug: AuthTemplateSlug.make(GOOGLE_OAUTH_SECURITY_SCHEME),
414
- kind: "oauth2",
415
- authorizationUrl: GOOGLE_OAUTH_AUTHORIZATION_URL,
416
- tokenUrl: GOOGLE_OAUTH_TOKEN_URL,
417
- scopes: Object.keys(scopes)
418
- }
419
- ]
420
- );
421
- var convertGoogleDiscoveryToOpenApi = Effect.fn("OpenApi.convertGoogleDiscovery")(
422
- function* (input) {
423
- const parsed = yield* parseJson(input.documentText).pipe(
424
- Effect.mapError(
425
- () => new OpenApiParseError({
426
- message: "Failed to parse Google Discovery document"
427
- })
428
- )
429
- );
430
- const document = yield* Effect.try({
431
- try: () => decodeDiscoveryDocument(parsed),
432
- catch: () => new OpenApiParseError({
433
- message: "Failed to decode Google Discovery document"
434
- })
435
- });
436
- const info = yield* discoveryDocumentInfo(document, input.discoveryUrl);
437
- const { service, version, baseUrl, title } = info;
438
- const paths = {};
439
- for (const method of allDiscoveryMethods(document)) {
440
- const methodId = Option.getOrUndefined(method.id);
441
- const pathTemplate = Option.getOrUndefined(method.path);
442
- if (!methodId || !pathTemplate || !method.httpMethod) continue;
443
- const toolPath = methodToolPath(service, methodId);
444
- const path = normalizeDiscoveryPathTemplate(
445
- pathTemplate.startsWith("/") ? pathTemplate : `/${pathTemplate}`
446
- );
447
- const methodKey = method.httpMethod.toLowerCase();
448
- const pathKey = uniquePathKey(paths, path, methodKey, toolPath);
449
- paths[pathKey] ??= {};
450
- paths[pathKey][methodKey] = buildDiscoveryOperation({
451
- document,
452
- method,
453
- toolPath,
454
- pathTemplate: pathTemplate.startsWith("/") ? pathTemplate : `/${pathTemplate}`
455
- });
456
- }
457
- const scopes = compactDiscoveryScopeMap(discoveryScopes(document));
458
- const authenticationTemplate = googleOauthTemplate(scopes);
459
- const spec = {
460
- openapi: "3.1.0",
461
- info: {
462
- title,
463
- version
464
- },
465
- servers: [{ url: baseUrl }],
466
- paths,
467
- components: {
468
- schemas: Object.fromEntries(
469
- Object.entries(document.schemas ?? {}).map(([name, schema]) => [
470
- name,
471
- discoverySchemaToOpenApiSchema(schema)
472
- ])
473
- ),
474
- ...authenticationTemplate ? {
475
- securitySchemes: {
476
- googleOAuth2: {
477
- type: "oauth2",
478
- flows: {
479
- authorizationCode: {
480
- authorizationUrl: GOOGLE_OAUTH_AUTHORIZATION_URL,
481
- tokenUrl: GOOGLE_OAUTH_TOKEN_URL,
482
- scopes
483
- }
484
- }
485
- }
486
- }
487
- } : {}
488
- },
489
- ...authenticationTemplate ? { security: [{ googleOAuth2: Object.keys(scopes) }] } : {},
490
- "x-executor-origin": {
491
- kind: "googleDiscovery",
492
- discoveryUrl: normalizeDiscoveryUrl(input.discoveryUrl),
493
- service,
494
- version
495
- }
496
- };
497
- return {
498
- // @effect-diagnostics-next-line preferSchemaOverJson:off
499
- specText: JSON.stringify(spec),
500
- baseUrl,
501
- title,
502
- service,
503
- version,
504
- ...authenticationTemplate ? { authenticationTemplate } : {}
505
- };
506
- }
507
- );
508
- var convertGoogleDiscoveryBundleToOpenApi = Effect.fn(
509
- "OpenApi.convertGoogleDiscoveryBundle"
510
- )(function* (input) {
511
- if (input.documents.length === 0) {
512
- return yield* new OpenApiParseError({
513
- message: "Google Discovery bundle requires at least one document"
514
- });
515
- }
516
- const infos = yield* Effect.forEach(
517
- input.documents,
518
- ({ discoveryUrl, documentText }) => Effect.gen(function* () {
519
- const parsed = yield* parseJson(documentText).pipe(
520
- Effect.mapError(
521
- () => new OpenApiParseError({
522
- message: "Failed to parse Google Discovery document"
523
- })
524
- )
525
- );
526
- const document = yield* Effect.try({
527
- try: () => decodeDiscoveryDocument(parsed),
528
- catch: () => new OpenApiParseError({
529
- message: "Failed to decode Google Discovery document"
530
- })
531
- });
532
- return yield* discoveryDocumentInfo(document, discoveryUrl);
533
- })
534
- );
535
- const paths = {};
536
- const schemas = {};
537
- const rawScopes = {};
538
- for (const info of infos) {
539
- const schemaPrefix = schemaComponentPart(`${info.service}_${info.version}`);
540
- const schemaNameForRef = (name) => `${schemaPrefix}_${schemaComponentPart(name)}`;
541
- for (const [scope, description] of Object.entries(discoveryScopes(info.document))) {
542
- rawScopes[scope] ??= description;
543
- }
544
- for (const [name, schema] of Object.entries(info.document.schemas ?? {})) {
545
- schemas[schemaNameForRef(name)] = discoverySchemaToOpenApiSchema(schema, schemaNameForRef);
546
- }
547
- for (const method of allDiscoveryMethods(info.document)) {
548
- const methodId = Option.getOrUndefined(method.id);
549
- const rawPathTemplate = Option.getOrUndefined(method.path);
550
- if (!methodId || !rawPathTemplate || !method.httpMethod) continue;
551
- const toolPath = methodId;
552
- const wirePath = rawPathTemplate.startsWith("/") ? rawPathTemplate : `/${rawPathTemplate}`;
553
- const openApiPath = normalizeDiscoveryPathTemplate(wirePath);
554
- const methodKey = method.httpMethod.toLowerCase();
555
- const pathKey = uniquePathKey(paths, openApiPath, methodKey, toolPath);
556
- paths[pathKey] ??= {};
557
- paths[pathKey][methodKey] = buildDiscoveryOperation({
558
- document: info.document,
559
- method,
560
- toolPath,
561
- pathTemplate: wirePath,
562
- schemaNameForRef,
563
- serverUrl: info.baseUrl,
564
- tags: [info.title]
565
- });
566
- }
567
- }
568
- const scopes = compactDiscoveryScopeMap(rawScopes);
569
- const authenticationTemplate = googleOauthTemplate(scopes);
570
- const spec = {
571
- openapi: "3.1.0",
572
- info: {
573
- title: "Google",
574
- version: "google-discovery-bundle"
575
- },
576
- servers: [{ url: GOOGLE_BUNDLE_BASE_URL }],
577
- paths,
578
- components: {
579
- schemas,
580
- ...authenticationTemplate ? {
581
- securitySchemes: {
582
- googleOAuth2: {
583
- type: "oauth2",
584
- flows: {
585
- authorizationCode: {
586
- authorizationUrl: GOOGLE_OAUTH_AUTHORIZATION_URL,
587
- tokenUrl: GOOGLE_OAUTH_TOKEN_URL,
588
- scopes
589
- }
590
- }
591
- }
592
- }
593
- } : {}
594
- },
595
- ...authenticationTemplate ? { security: [{ googleOAuth2: Object.keys(scopes) }] } : {},
596
- "x-executor-origin": {
597
- kind: "googleDiscoveryBundle",
598
- services: infos.map((info) => ({
599
- discoveryUrl: normalizeDiscoveryUrl(info.discoveryUrl),
600
- service: info.service,
601
- version: info.version
602
- }))
603
- }
604
- };
605
- return {
606
- // @effect-diagnostics-next-line preferSchemaOverJson:off
607
- specText: JSON.stringify(spec),
608
- baseUrl: GOOGLE_BUNDLE_BASE_URL,
609
- title: "Google",
610
- service: "google",
611
- version: "google-discovery-bundle",
612
- discoveryUrls: infos.map((info) => normalizeDiscoveryUrl(info.discoveryUrl)),
613
- ...authenticationTemplate ? { authenticationTemplate } : {}
614
- };
615
- });
616
-
617
- // src/sdk/derive-auth.ts
618
- import * as Option2 from "effect/Option";
619
- import { AuthTemplateSlug as AuthTemplateSlug2 } from "@executor-js/sdk/shared";
620
- function resolveOAuthUrl(url, baseUrl) {
621
- if (!url) return url;
622
- try {
623
- new URL(url);
624
- return url;
625
- } catch {
626
- if (!baseUrl) return url;
627
- try {
628
- return new URL(url, baseUrl).toString();
629
- } catch {
630
- return url;
631
- }
632
- }
633
- }
634
- var standardOidcIdentityScopes = ["openid", "email", "profile"];
635
- var identityScopesForPreset = (identityScopes) => {
636
- if (identityScopes === false) return [];
637
- return identityScopes === "auto" ? standardOidcIdentityScopes : identityScopes;
638
- };
639
- var resolvedOAuthScopes = (apiScopes, identityScopes) => {
640
- const merged = new Set(apiScopes);
641
- for (const scope of identityScopesForPreset(identityScopes)) merged.add(scope);
642
- return [...merged];
643
- };
644
- var headerPrefix = (preset, headerName) => {
645
- const label = preset.label.toLowerCase();
646
- if (headerName.toLowerCase() === "authorization") {
647
- if (label.includes("bearer")) return "Bearer ";
648
- if (label.includes("basic")) return "Basic ";
649
- }
650
- return void 0;
651
- };
652
- var apiKeyTemplateFromHeaderPreset = (preset, slug) => ({
653
- slug,
654
- kind: "apikey",
655
- // Every secret header shares the one credential input (the canonical
656
- // `token`, stored as an absent placement variable).
657
- placements: preset.secretHeaders.map((headerName) => {
658
- const prefix = headerPrefix(preset, headerName);
659
- return { carrier: "header", name: headerName, ...prefix ? { prefix } : {} };
660
- })
661
- });
662
- var oauthTemplateFromPreset = (preset, baseUrl, slug, scopes) => ({
663
- slug,
664
- kind: "oauth2",
665
- authorizationUrl: resolveOAuthUrl(
666
- Option2.getOrElse(preset.authorizationUrl, () => ""),
667
- baseUrl
668
- ),
669
- tokenUrl: resolveOAuthUrl(preset.tokenUrl, baseUrl),
670
- scopes: [...scopes]
671
- });
672
- var detectedAuthenticationTemplates = (headerPresets, oauth2Presets, baseUrl) => {
673
- const templates = [];
674
- headerPresets.forEach((preset, index) => {
675
- templates.push(
676
- apiKeyTemplateFromHeaderPreset(preset, AuthTemplateSlug2.make(`apikey-${index}`))
677
- );
678
- });
679
- for (const preset of oauth2Presets) {
680
- const scopes = resolvedOAuthScopes(Object.keys(preset.scopes), preset.identityScopes);
681
- templates.push(
682
- oauthTemplateFromPreset(
683
- preset,
684
- baseUrl,
685
- AuthTemplateSlug2.make(`oauth-${preset.securitySchemeName}`),
686
- scopes
687
- )
688
- );
689
- }
690
- return templates;
691
- };
692
- var firstBaseUrlForPreview = (preview) => {
693
- const firstServer = preview.servers[0];
694
- return firstServer ? resolveServerUrl(firstServer.url, Option2.getOrUndefined(firstServer.variables), {}) : "";
695
- };
696
- var deriveAuthenticationTemplateFromPreview = (preview, baseUrl) => detectedAuthenticationTemplates(
697
- preview.headerPresets,
698
- preview.oauth2Presets,
699
- baseUrl ?? firstBaseUrlForPreview(preview)
700
- );
701
-
702
- export {
703
- compactGoogleOAuthScopes,
704
- isGoogleDiscoveryUrl,
705
- fetchGoogleDiscoveryDocument,
706
- convertGoogleDiscoveryToOpenApi,
707
- convertGoogleDiscoveryBundleToOpenApi,
708
- detectedAuthenticationTemplates,
709
- firstBaseUrlForPreview,
710
- deriveAuthenticationTemplateFromPreview
711
- };
712
- //# sourceMappingURL=chunk-UOLBAX5D.js.map