@executor-js/plugin-openapi 1.5.22 → 2.0.0

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 (34) hide show
  1. package/dist/{AddOpenApiSource-26V6EZD4.js → AddOpenApiSource-6PJZWRRZ.js} +17 -12
  2. package/dist/AddOpenApiSource-6PJZWRRZ.js.map +1 -0
  3. package/dist/{OpenApiAccountsPanel-XNDADPBL.js → OpenApiAccountsPanel-W6IMUY7Q.js} +4 -4
  4. package/dist/{UpdateSpecSection-MWC5DBXF.js → UpdateSpecSection-R2RF2QV2.js} +3 -3
  5. package/dist/api/group.d.ts +10 -0
  6. package/dist/api/index.d.ts +12 -0
  7. package/dist/{chunk-UYPLGACO.js → chunk-562TAVB2.js} +5 -3
  8. package/dist/chunk-562TAVB2.js.map +1 -0
  9. package/dist/{chunk-RCBR3QMJ.js → chunk-56PVOO6X.js} +10 -4
  10. package/dist/{chunk-RCBR3QMJ.js.map → chunk-56PVOO6X.js.map} +1 -1
  11. package/dist/{chunk-5YG34JIY.js → chunk-DBA2BHE4.js} +194 -18
  12. package/dist/chunk-DBA2BHE4.js.map +1 -0
  13. package/dist/{chunk-QQFCICLX.js → chunk-HG5JB2UJ.js} +9 -1
  14. package/dist/{chunk-QQFCICLX.js.map → chunk-HG5JB2UJ.js.map} +1 -1
  15. package/dist/{chunk-W6DGFLYT.js → chunk-IVRAOG3T.js} +5 -3
  16. package/dist/{chunk-W6DGFLYT.js.map → chunk-IVRAOG3T.js.map} +1 -1
  17. package/dist/{chunk-XFJWX2CY.js → chunk-WWZ7B34D.js} +8 -2
  18. package/dist/{chunk-XFJWX2CY.js.map → chunk-WWZ7B34D.js.map} +1 -1
  19. package/dist/client.js +4 -4
  20. package/dist/core.js +4 -4
  21. package/dist/index.js +4 -4
  22. package/dist/react/AddOpenApiSource.d.ts +1 -0
  23. package/dist/react/AddOpenApiSource.test.d.ts +1 -0
  24. package/dist/react/atoms.d.ts +12 -0
  25. package/dist/react/client.d.ts +10 -0
  26. package/dist/sdk/config.d.ts +4 -0
  27. package/dist/sdk/plugin.d.ts +2 -0
  28. package/dist/sdk/preview.d.ts +16 -0
  29. package/package.json +3 -3
  30. package/dist/AddOpenApiSource-26V6EZD4.js.map +0 -1
  31. package/dist/chunk-5YG34JIY.js.map +0 -1
  32. package/dist/chunk-UYPLGACO.js.map +0 -1
  33. /package/dist/{OpenApiAccountsPanel-XNDADPBL.js.map → OpenApiAccountsPanel-W6IMUY7Q.js.map} +0 -0
  34. /package/dist/{UpdateSpecSection-MWC5DBXF.js.map → UpdateSpecSection-R2RF2QV2.js.map} +0 -0
@@ -1,16 +1,20 @@
1
1
  import {
2
2
  deriveAuthenticationTemplateFromPreview,
3
3
  firstBaseUrlForPreview
4
- } from "./chunk-W6DGFLYT.js";
4
+ } from "./chunk-IVRAOG3T.js";
5
5
  import {
6
6
  openApiPresets
7
- } from "./chunk-QQFCICLX.js";
7
+ } from "./chunk-HG5JB2UJ.js";
8
8
  import {
9
9
  InvocationResult,
10
+ OAuth2AuthorizationCodeFlow,
11
+ OAuth2Flows,
12
+ OAuth2Preset,
10
13
  OpenApiExtractionError,
11
14
  OpenApiInvocationError,
12
15
  OpenApiParseError,
13
16
  OperationBinding,
17
+ SecurityScheme,
14
18
  buildInputSchema,
15
19
  compileToolDefinitions,
16
20
  extract,
@@ -23,7 +27,7 @@ import {
23
27
  streamOperationBindings,
24
28
  streamOperationBindingsFromStructure,
25
29
  structuralSplit
26
- } from "./chunk-XFJWX2CY.js";
30
+ } from "./chunk-WWZ7B34D.js";
27
31
 
28
32
  // src/sdk/config.ts
29
33
  import { Option, Schema } from "effect";
@@ -38,7 +42,9 @@ var OAuthAuthenticationSchema = Schema.Struct({
38
42
  kind: Schema.Literal("oauth2"),
39
43
  authorizationUrl: Schema.String,
40
44
  tokenUrl: Schema.String,
41
- scopes: Schema.Array(Schema.String)
45
+ resource: Schema.optional(Schema.NullOr(Schema.String)),
46
+ scopes: Schema.Array(Schema.String),
47
+ supportsClientIdMetadataDocument: Schema.optional(Schema.Boolean)
42
48
  });
43
49
  var AuthenticationSchema = Schema.Union([OAuthAuthenticationSchema, ApiKeyAuthMethod]);
44
50
  var OpenApiIntegrationConfigSchema = Schema.Struct({
@@ -1170,15 +1176,14 @@ var invokeOpenApiBackedTool = (input) => Effect3.gen(function* () {
1170
1176
  });
1171
1177
  });
1172
1178
  var resolveOpenApiBackedAnnotations = (input) => Effect3.gen(function* () {
1173
- const ops = yield* input.ctx.storage.listOperations(String(input.integration));
1174
- const byName = /* @__PURE__ */ new Map();
1175
- for (const op of ops) byName.set(op.toolName, op.binding);
1176
1179
  const out = {};
1177
1180
  for (const row of input.toolRows) {
1178
- const binding = byName.get(row.name);
1179
- if (binding) {
1180
- out[row.name] = annotationsForOperation(binding.method, binding.pathTemplate);
1181
- }
1181
+ const operation = yield* input.ctx.storage.getOperation(input.integration, row.name);
1182
+ if (!operation) continue;
1183
+ out[row.name] = annotationsForOperation(
1184
+ operation.binding.method,
1185
+ operation.binding.pathTemplate
1186
+ );
1182
1187
  }
1183
1188
  return out;
1184
1189
  });
@@ -1242,13 +1247,15 @@ var StaticPreviewOAuth2PresetSchema = Schema4.Struct({
1242
1247
  flow: Schema4.Literals(["authorizationCode", "clientCredentials"]),
1243
1248
  authorizationUrl: Schema4.NullOr(Schema4.String),
1244
1249
  tokenUrl: Schema4.String,
1250
+ resource: Schema4.NullOr(Schema4.String),
1245
1251
  refreshUrl: Schema4.NullOr(Schema4.String),
1246
1252
  scopes: Schema4.Record(Schema4.String, Schema4.String),
1247
1253
  identityScopes: Schema4.Union([
1248
1254
  Schema4.Literal("auto"),
1249
1255
  Schema4.Literal(false),
1250
1256
  Schema4.Array(Schema4.String)
1251
- ])
1257
+ ]),
1258
+ supportsClientIdMetadataDocument: Schema4.optional(Schema4.Boolean)
1252
1259
  });
1253
1260
  var StaticPreviewSpecOutputSchema = Schema4.Struct({
1254
1261
  title: Schema4.NullOr(Schema4.String),
@@ -1277,7 +1284,9 @@ var AuthenticationSchema2 = Schema4.Union([
1277
1284
  kind: Schema4.Literal("oauth2"),
1278
1285
  authorizationUrl: Schema4.String,
1279
1286
  tokenUrl: Schema4.String,
1280
- scopes: Schema4.Array(Schema4.String)
1287
+ resource: Schema4.optional(Schema4.NullOr(Schema4.String)),
1288
+ scopes: Schema4.Array(Schema4.String),
1289
+ supportsClientIdMetadataDocument: Schema4.optional(Schema4.Boolean)
1281
1290
  }),
1282
1291
  // Credential methods are authored request-shaped - the ONE apikey input
1283
1292
  // dialect: `{ type: "apiKey", headers: { Authorization: ["Bearer ",
@@ -1364,12 +1373,135 @@ var staticPreviewOutput = (preview) => ({
1364
1373
  flow: preset.flow,
1365
1374
  authorizationUrl: Option5.getOrNull(preset.authorizationUrl),
1366
1375
  tokenUrl: preset.tokenUrl,
1376
+ resource: Option5.getOrNull(preset.resource),
1367
1377
  refreshUrl: Option5.getOrNull(preset.refreshUrl),
1368
1378
  scopes: preset.scopes,
1369
- identityScopes: preset.identityScopes
1379
+ identityScopes: preset.identityScopes,
1380
+ supportsClientIdMetadataDocument: preset.supportsClientIdMetadataDocument
1370
1381
  }))
1371
1382
  });
1372
1383
  var specInputToSourceUrl = (spec) => spec.kind === "url" ? spec.url : void 0;
1384
+ var OAUTH_DISCOVERED_SCHEME_NAME = "DiscoveredOAuth2";
1385
+ var OPENAPI_HTTP_METHODS = /* @__PURE__ */ new Set([
1386
+ "get",
1387
+ "put",
1388
+ "post",
1389
+ "delete",
1390
+ "patch",
1391
+ "head",
1392
+ "options",
1393
+ "trace"
1394
+ ]);
1395
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1396
+ var maybeUrl = (value) => {
1397
+ try {
1398
+ return new URL(value);
1399
+ } catch {
1400
+ return null;
1401
+ }
1402
+ };
1403
+ var addProbeCandidate = (candidates, value) => {
1404
+ const trimmed = value?.trim();
1405
+ if (!trimmed) return;
1406
+ const parsed = maybeUrl(trimmed);
1407
+ if (!parsed || parsed.protocol !== "https:" && parsed.protocol !== "http:") return;
1408
+ const normalized = parsed.toString();
1409
+ const origin = parsed.origin;
1410
+ if (!candidates.includes(normalized)) candidates.push(normalized);
1411
+ if (!candidates.includes(origin)) candidates.push(origin);
1412
+ };
1413
+ var oauthProbeCandidates = (preview, sourceUrl, baseUrl) => {
1414
+ const candidates = [];
1415
+ addProbeCandidate(candidates, baseUrl);
1416
+ for (const server of preview.servers) {
1417
+ addProbeCandidate(
1418
+ candidates,
1419
+ resolveServerUrl(server.url, Option5.getOrUndefined(server.variables), {})
1420
+ );
1421
+ }
1422
+ addProbeCandidate(candidates, sourceUrl);
1423
+ return candidates;
1424
+ };
1425
+ var securityRequirementScopes = (security, targetSchemes) => {
1426
+ if (!Array.isArray(security)) return [];
1427
+ const scopes = /* @__PURE__ */ new Set();
1428
+ for (const requirement of security) {
1429
+ if (!isRecord(requirement)) continue;
1430
+ for (const [scheme, rawScopes] of Object.entries(requirement)) {
1431
+ if (targetSchemes.size > 0 && !targetSchemes.has(scheme)) continue;
1432
+ if (!Array.isArray(rawScopes)) continue;
1433
+ for (const scope of rawScopes) {
1434
+ if (typeof scope === "string" && scope.trim().length > 0) scopes.add(scope.trim());
1435
+ }
1436
+ }
1437
+ }
1438
+ return [...scopes];
1439
+ };
1440
+ var collectDeclaredSecurityScopes = (doc, targetSchemes) => {
1441
+ const scopes = /* @__PURE__ */ new Set();
1442
+ if (!isRecord(doc)) return [];
1443
+ for (const scope of securityRequirementScopes(doc.security, targetSchemes)) scopes.add(scope);
1444
+ const paths = doc.paths;
1445
+ if (!isRecord(paths)) return [...scopes].sort();
1446
+ for (const pathItem of Object.values(paths)) {
1447
+ if (!isRecord(pathItem)) continue;
1448
+ for (const [method, operation] of Object.entries(pathItem)) {
1449
+ if (!OPENAPI_HTTP_METHODS.has(method.toLowerCase()) || !isRecord(operation)) continue;
1450
+ for (const scope of securityRequirementScopes(operation.security, targetSchemes)) {
1451
+ scopes.add(scope);
1452
+ }
1453
+ }
1454
+ }
1455
+ return [...scopes].sort();
1456
+ };
1457
+ var nonOAuthSecuritySchemeNames = (preview) => new Set(
1458
+ preview.securitySchemes.filter((scheme) => scheme.type === "http" || scheme.type === "apiKey").map((scheme) => scheme.name)
1459
+ );
1460
+ var discoveredOAuthPreview = (input) => {
1461
+ const scopes = Object.fromEntries(input.scopes.map((scope) => [scope, ""]));
1462
+ const flow = OAuth2AuthorizationCodeFlow.make({
1463
+ authorizationUrl: input.authorizationUrl,
1464
+ tokenUrl: input.tokenUrl,
1465
+ refreshUrl: Option5.none(),
1466
+ scopes
1467
+ });
1468
+ const flows = OAuth2Flows.make({
1469
+ authorizationCode: Option5.some(flow),
1470
+ clientCredentials: Option5.none()
1471
+ });
1472
+ return {
1473
+ ...input.preview,
1474
+ securitySchemes: [
1475
+ ...input.preview.securitySchemes,
1476
+ SecurityScheme.make({
1477
+ name: OAUTH_DISCOVERED_SCHEME_NAME,
1478
+ type: "oauth2",
1479
+ scheme: Option5.none(),
1480
+ bearerFormat: Option5.none(),
1481
+ in: Option5.none(),
1482
+ headerName: Option5.none(),
1483
+ description: Option5.some("Discovered from OAuth authorization-server metadata"),
1484
+ flows: Option5.some(flows),
1485
+ openIdConnectUrl: Option5.none()
1486
+ })
1487
+ ],
1488
+ oauth2Presets: [
1489
+ ...input.preview.oauth2Presets,
1490
+ OAuth2Preset.make({
1491
+ label: `OAuth2 Authorization Code \xB7 ${OAUTH_DISCOVERED_SCHEME_NAME}`,
1492
+ securitySchemeName: OAUTH_DISCOVERED_SCHEME_NAME,
1493
+ flow: "authorizationCode",
1494
+ authorizationUrl: Option5.some(input.authorizationUrl),
1495
+ tokenUrl: input.tokenUrl,
1496
+ resource: input.resource ? Option5.some(input.resource) : Option5.none(),
1497
+ refreshUrl: Option5.none(),
1498
+ scopes,
1499
+ identityScopes: "auto",
1500
+ ...input.supportsClientIdMetadataDocument === true ? { supportsClientIdMetadataDocument: true } : {}
1501
+ })
1502
+ ]
1503
+ };
1504
+ };
1373
1505
  var describeOpenApiAuthMethods = (record) => {
1374
1506
  const config = decodeOpenApiIntegrationConfig(record.config);
1375
1507
  if (!config) return [];
@@ -1384,7 +1516,9 @@ var describeOpenApiAuthMethods = (record) => {
1384
1516
  oauth: {
1385
1517
  authorizationUrl: template.authorizationUrl,
1386
1518
  tokenUrl: template.tokenUrl,
1387
- scopes: template.scopes
1519
+ resource: template.resource ?? null,
1520
+ scopes: template.scopes,
1521
+ supportsClientIdMetadataDocument: template.supportsClientIdMetadataDocument
1388
1522
  }
1389
1523
  };
1390
1524
  }
@@ -1418,13 +1552,50 @@ var openApiPlugin = definePlugin((options) => {
1418
1552
  storage: (deps) => makeDefaultOpenapiStore(deps),
1419
1553
  extension: (ctx) => {
1420
1554
  const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer;
1555
+ const enrichPreviewWithDiscoveredOAuth = (input) => Effect4.gen(function* () {
1556
+ if (input.preview.oauth2Presets.length > 0) return input.preview;
1557
+ const candidates = oauthProbeCandidates(input.preview, input.sourceUrl, input.baseUrl);
1558
+ if (candidates.length === 0) return input.preview;
1559
+ for (const candidate of candidates) {
1560
+ const oauth = yield* ctx.oauth.probe({ url: candidate }).pipe(
1561
+ Effect4.map((result) => ({ ok: true, result })),
1562
+ Effect4.catch(() => Effect4.succeed({ ok: false, result: null }))
1563
+ );
1564
+ if (!oauth.ok) continue;
1565
+ const doc = yield* parse(input.specText);
1566
+ const declaredScopes = collectDeclaredSecurityScopes(
1567
+ doc,
1568
+ nonOAuthSecuritySchemeNames(input.preview)
1569
+ );
1570
+ const supportedScopes = oauth.result.scopesSupported && oauth.result.scopesSupported.length > 0 ? new Set(oauth.result.scopesSupported) : null;
1571
+ const scopes = supportedScopes ? declaredScopes.filter((scope) => supportedScopes.has(scope)) : declaredScopes;
1572
+ return discoveredOAuthPreview({
1573
+ preview: input.preview,
1574
+ authorizationUrl: oauth.result.authorizationUrl,
1575
+ tokenUrl: oauth.result.tokenUrl,
1576
+ resource: oauth.result.resource ?? null,
1577
+ scopes,
1578
+ supportsClientIdMetadataDocument: oauth.result.clientIdMetadataDocumentSupported === true
1579
+ });
1580
+ }
1581
+ return input.preview;
1582
+ });
1421
1583
  const addSpec = (config) => Effect4.gen(function* () {
1422
1584
  const resolved = yield* resolveSpecForInput(config.spec, httpClientLayer);
1423
1585
  const compiled = yield* compileOpenApiSpec(resolved.specText);
1424
1586
  const explicitBaseUrl = config.baseUrl;
1425
1587
  const needsDerivedBaseUrl = explicitBaseUrl == null;
1426
1588
  const needsDerivedAuth = config.authenticationTemplate == null;
1427
- const preview = needsDerivedBaseUrl || needsDerivedAuth ? yield* previewSpecText(resolved.specText) : void 0;
1589
+ const preview = needsDerivedBaseUrl || needsDerivedAuth ? yield* previewSpecText(resolved.specText).pipe(
1590
+ Effect4.flatMap(
1591
+ (rawPreview) => enrichPreviewWithDiscoveredOAuth({
1592
+ specText: resolved.specText,
1593
+ preview: rawPreview,
1594
+ sourceUrl: specInputToSourceUrl(config.spec),
1595
+ baseUrl: config.baseUrl
1596
+ })
1597
+ )
1598
+ ) : void 0;
1428
1599
  const derivedBaseUrl = needsDerivedBaseUrl && preview ? firstBaseUrlForPreview(preview) : void 0;
1429
1600
  const effectiveBaseUrl = explicitBaseUrl ?? (derivedBaseUrl || void 0);
1430
1601
  const derivedAuthenticationTemplate = needsDerivedAuth && preview ? deriveAuthenticationTemplateFromPreview(preview, effectiveBaseUrl) : void 0;
@@ -1538,7 +1709,12 @@ var openApiPlugin = definePlugin((options) => {
1538
1709
  const specText = yield* resolveSpecText(previewInput.spec).pipe(
1539
1710
  Effect4.provide(httpClientLayer)
1540
1711
  );
1541
- return yield* previewSpecText(specText);
1712
+ const preview = yield* previewSpecText(specText);
1713
+ return yield* enrichPreviewWithDiscoveredOAuth({
1714
+ specText,
1715
+ preview,
1716
+ sourceUrl: maybeUrl(previewInput.spec.trim()) ? previewInput.spec.trim() : void 0
1717
+ });
1542
1718
  }),
1543
1719
  addSpec,
1544
1720
  updateSpec,
@@ -1727,4 +1903,4 @@ export {
1727
1903
  resolveOpenApiBackedAnnotations,
1728
1904
  openApiPlugin
1729
1905
  };
1730
- //# sourceMappingURL=chunk-5YG34JIY.js.map
1906
+ //# sourceMappingURL=chunk-DBA2BHE4.js.map