@executor-js/plugin-openapi 1.5.21 → 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 (35) hide show
  1. package/dist/{AddOpenApiSource-SSXZBQEK.js → AddOpenApiSource-6PJZWRRZ.js} +17 -12
  2. package/dist/AddOpenApiSource-6PJZWRRZ.js.map +1 -0
  3. package/dist/{OpenApiAccountsPanel-U47OVLYG.js → OpenApiAccountsPanel-W6IMUY7Q.js} +4 -4
  4. package/dist/{UpdateSpecSection-FFYVB3VH.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-2RNIMASA.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-3O3PGRRG.js → chunk-DBA2BHE4.js} +287 -23
  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-MWF55JPY.js → chunk-IVRAOG3T.js} +5 -3
  16. package/dist/{chunk-MWF55JPY.js.map → chunk-IVRAOG3T.js.map} +1 -1
  17. package/dist/{chunk-R3X27XS6.js → chunk-WWZ7B34D.js} +35 -4
  18. package/dist/chunk-WWZ7B34D.js.map +1 -0
  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-SSXZBQEK.js.map +0 -1
  31. package/dist/chunk-2RNIMASA.js.map +0 -1
  32. package/dist/chunk-3O3PGRRG.js.map +0 -1
  33. package/dist/chunk-R3X27XS6.js.map +0 -1
  34. /package/dist/{OpenApiAccountsPanel-U47OVLYG.js.map → OpenApiAccountsPanel-W6IMUY7Q.js.map} +0 -0
  35. /package/dist/{UpdateSpecSection-FFYVB3VH.js.map → UpdateSpecSection-R2RF2QV2.js.map} +0 -0
@@ -1,16 +1,20 @@
1
1
  import {
2
2
  deriveAuthenticationTemplateFromPreview,
3
3
  firstBaseUrlForPreview
4
- } from "./chunk-MWF55JPY.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-R3X27XS6.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({
@@ -343,6 +349,23 @@ var bytesFromBase64Prefix = (base64) => {
343
349
  return bytes;
344
350
  };
345
351
  var sniffMimeTypeFromBase64 = (base64) => sniffMimeType(bytesFromBase64Prefix(base64));
352
+ var base64ToUint8Array = (value) => {
353
+ let binary = "";
354
+ try {
355
+ binary = atob(normalizeBase64(value, "base64"));
356
+ } catch {
357
+ return null;
358
+ }
359
+ const bytes = new Uint8Array(binary.length);
360
+ for (let index = 0; index < binary.length; index += 1) {
361
+ bytes[index] = binary.charCodeAt(index);
362
+ }
363
+ return bytes;
364
+ };
365
+ var decodeBase64Body = (value) => {
366
+ const bytes = base64ToUint8Array(value);
367
+ return bytes ? { ok: true, bytes } : { ok: false };
368
+ };
346
369
  var toUint8Array = (value) => {
347
370
  if (value instanceof Uint8Array) return value;
348
371
  if (value instanceof ArrayBuffer) return new Uint8Array(value);
@@ -355,6 +378,7 @@ var toUint8Array = (value) => {
355
378
  }
356
379
  return null;
357
380
  };
381
+ var readNestedBodyBase64 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "bodyBase64") ? value.bodyBase64 : void 0;
358
382
  var readHintString = (option, fallback) => Option3.getOrElse(option, () => fallback);
359
383
  var readHintMimeType = (hint, fallback) => Option3.getOrElse(hint.mimeType, () => fallback);
360
384
  var readHintEncoding = (hint) => Option3.getOrElse(hint.encoding, () => "base64");
@@ -573,12 +597,82 @@ var invoke = Effect2.fn("OpenApi.invoke")(function* (operation, args, resolvedHe
573
597
  }
574
598
  if (Option3.isSome(operation.requestBody)) {
575
599
  const rb = operation.requestBody.value;
576
- const bodyValue = args.body ?? args.input;
600
+ const contentsOpt = Option3.getOrUndefined(rb.contents);
601
+ const requestedCt = typeof args.contentType === "string" ? args.contentType : void 0;
602
+ const octetStreamContent = contentsOpt?.find((c) => isOctetStream(c.contentType));
603
+ const bodyAcceptsOctetStream = Boolean(octetStreamContent) || isOctetStream(rb.contentType);
604
+ const hasBodyBase64 = Object.prototype.hasOwnProperty.call(args, "bodyBase64");
605
+ const bodyBase64Raw = args.bodyBase64;
606
+ const bodyBase64 = typeof bodyBase64Raw === "string" ? decodeBase64Body(bodyBase64Raw) : void 0;
607
+ if (hasBodyBase64 && typeof bodyBase64Raw !== "string") {
608
+ return yield* new OpenApiInvocationError({
609
+ message: "`bodyBase64` must be a base64 string",
610
+ statusCode: Option3.none()
611
+ });
612
+ }
613
+ if (bodyBase64?.ok === false) {
614
+ return yield* new OpenApiInvocationError({
615
+ message: "`bodyBase64` is not valid base64",
616
+ statusCode: Option3.none()
617
+ });
618
+ }
619
+ if (bodyBase64?.ok === true && !bodyAcceptsOctetStream) {
620
+ return yield* new OpenApiInvocationError({
621
+ message: "`bodyBase64` requires an application/octet-stream request body",
622
+ statusCode: Option3.none()
623
+ });
624
+ }
625
+ if (bodyBase64?.ok === true && requestedCt && !isOctetStream(requestedCt)) {
626
+ return yield* new OpenApiInvocationError({
627
+ message: "`bodyBase64` requires an application/octet-stream contentType",
628
+ statusCode: Option3.none()
629
+ });
630
+ }
631
+ const rawBodyValue = args.body ?? args.input;
632
+ const nestedBodyBase64Raw = readNestedBodyBase64(rawBodyValue);
633
+ const hasNestedBodyBase64 = nestedBodyBase64Raw !== void 0;
634
+ const nestedBodyBase64 = typeof nestedBodyBase64Raw === "string" ? decodeBase64Body(nestedBodyBase64Raw) : void 0;
635
+ if (hasNestedBodyBase64 && typeof nestedBodyBase64Raw !== "string") {
636
+ return yield* new OpenApiInvocationError({
637
+ message: "`body.bodyBase64` must be a base64 string",
638
+ statusCode: Option3.none()
639
+ });
640
+ }
641
+ if (nestedBodyBase64?.ok === false) {
642
+ return yield* new OpenApiInvocationError({
643
+ message: "`body.bodyBase64` is not valid base64",
644
+ statusCode: Option3.none()
645
+ });
646
+ }
647
+ if (nestedBodyBase64?.ok === true && !bodyAcceptsOctetStream) {
648
+ return yield* new OpenApiInvocationError({
649
+ message: "`body.bodyBase64` requires an application/octet-stream request body",
650
+ statusCode: Option3.none()
651
+ });
652
+ }
653
+ if (nestedBodyBase64?.ok === true && requestedCt && !isOctetStream(requestedCt)) {
654
+ return yield* new OpenApiInvocationError({
655
+ message: "`body.bodyBase64` requires an application/octet-stream contentType",
656
+ statusCode: Option3.none()
657
+ });
658
+ }
659
+ const binaryBody = bodyBase64?.ok === true ? bodyBase64 : nestedBodyBase64;
660
+ const bodyValue = binaryBody?.ok === true ? binaryBody.bytes : rawBodyValue;
661
+ if (rb.required && bodyValue === void 0) {
662
+ return yield* new OpenApiInvocationError({
663
+ message: bodyAcceptsOctetStream ? "Missing required request body: provide `bodyBase64`" : "Missing required request body",
664
+ statusCode: Option3.none()
665
+ });
666
+ }
577
667
  if (bodyValue !== void 0) {
578
- const contentsOpt = Option3.getOrUndefined(rb.contents);
579
- const requestedCt = typeof args.contentType === "string" ? args.contentType : void 0;
580
- const selected = contentsOpt && requestedCt ? contentsOpt.find((c) => c.contentType === requestedCt) : void 0;
581
- const chosenCt = selected?.contentType ?? rb.contentType;
668
+ const selected = binaryBody?.ok === true && octetStreamContent ? octetStreamContent : contentsOpt && requestedCt ? contentsOpt.find((c) => c.contentType === requestedCt) : void 0;
669
+ const chosenCt = binaryBody?.ok === true && !octetStreamContent && isOctetStream(rb.contentType) ? rb.contentType : selected?.contentType ?? rb.contentType;
670
+ if (isOctetStream(chosenCt) && toUint8Array(bodyValue) === null) {
671
+ return yield* new OpenApiInvocationError({
672
+ message: "application/octet-stream request body must be bytes; provide `bodyBase64`",
673
+ statusCode: Option3.none()
674
+ });
675
+ }
582
676
  const chosenEncoding = selected ? Option3.getOrUndefined(selected.encoding) : contentsOpt && contentsOpt[0] ? Option3.getOrUndefined(contentsOpt[0].encoding) : void 0;
583
677
  request = applyRequestBody(request, chosenCt, bodyValue, chosenEncoding);
584
678
  }
@@ -1082,15 +1176,14 @@ var invokeOpenApiBackedTool = (input) => Effect3.gen(function* () {
1082
1176
  });
1083
1177
  });
1084
1178
  var resolveOpenApiBackedAnnotations = (input) => Effect3.gen(function* () {
1085
- const ops = yield* input.ctx.storage.listOperations(String(input.integration));
1086
- const byName = /* @__PURE__ */ new Map();
1087
- for (const op of ops) byName.set(op.toolName, op.binding);
1088
1179
  const out = {};
1089
1180
  for (const row of input.toolRows) {
1090
- const binding = byName.get(row.name);
1091
- if (binding) {
1092
- out[row.name] = annotationsForOperation(binding.method, binding.pathTemplate);
1093
- }
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
+ );
1094
1187
  }
1095
1188
  return out;
1096
1189
  });
@@ -1154,13 +1247,15 @@ var StaticPreviewOAuth2PresetSchema = Schema4.Struct({
1154
1247
  flow: Schema4.Literals(["authorizationCode", "clientCredentials"]),
1155
1248
  authorizationUrl: Schema4.NullOr(Schema4.String),
1156
1249
  tokenUrl: Schema4.String,
1250
+ resource: Schema4.NullOr(Schema4.String),
1157
1251
  refreshUrl: Schema4.NullOr(Schema4.String),
1158
1252
  scopes: Schema4.Record(Schema4.String, Schema4.String),
1159
1253
  identityScopes: Schema4.Union([
1160
1254
  Schema4.Literal("auto"),
1161
1255
  Schema4.Literal(false),
1162
1256
  Schema4.Array(Schema4.String)
1163
- ])
1257
+ ]),
1258
+ supportsClientIdMetadataDocument: Schema4.optional(Schema4.Boolean)
1164
1259
  });
1165
1260
  var StaticPreviewSpecOutputSchema = Schema4.Struct({
1166
1261
  title: Schema4.NullOr(Schema4.String),
@@ -1189,7 +1284,9 @@ var AuthenticationSchema2 = Schema4.Union([
1189
1284
  kind: Schema4.Literal("oauth2"),
1190
1285
  authorizationUrl: Schema4.String,
1191
1286
  tokenUrl: Schema4.String,
1192
- 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)
1193
1290
  }),
1194
1291
  // Credential methods are authored request-shaped - the ONE apikey input
1195
1292
  // dialect: `{ type: "apiKey", headers: { Authorization: ["Bearer ",
@@ -1276,12 +1373,135 @@ var staticPreviewOutput = (preview) => ({
1276
1373
  flow: preset.flow,
1277
1374
  authorizationUrl: Option5.getOrNull(preset.authorizationUrl),
1278
1375
  tokenUrl: preset.tokenUrl,
1376
+ resource: Option5.getOrNull(preset.resource),
1279
1377
  refreshUrl: Option5.getOrNull(preset.refreshUrl),
1280
1378
  scopes: preset.scopes,
1281
- identityScopes: preset.identityScopes
1379
+ identityScopes: preset.identityScopes,
1380
+ supportsClientIdMetadataDocument: preset.supportsClientIdMetadataDocument
1282
1381
  }))
1283
1382
  });
1284
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
+ };
1285
1505
  var describeOpenApiAuthMethods = (record) => {
1286
1506
  const config = decodeOpenApiIntegrationConfig(record.config);
1287
1507
  if (!config) return [];
@@ -1296,7 +1516,9 @@ var describeOpenApiAuthMethods = (record) => {
1296
1516
  oauth: {
1297
1517
  authorizationUrl: template.authorizationUrl,
1298
1518
  tokenUrl: template.tokenUrl,
1299
- scopes: template.scopes
1519
+ resource: template.resource ?? null,
1520
+ scopes: template.scopes,
1521
+ supportsClientIdMetadataDocument: template.supportsClientIdMetadataDocument
1300
1522
  }
1301
1523
  };
1302
1524
  }
@@ -1330,13 +1552,50 @@ var openApiPlugin = definePlugin((options) => {
1330
1552
  storage: (deps) => makeDefaultOpenapiStore(deps),
1331
1553
  extension: (ctx) => {
1332
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
+ });
1333
1583
  const addSpec = (config) => Effect4.gen(function* () {
1334
1584
  const resolved = yield* resolveSpecForInput(config.spec, httpClientLayer);
1335
1585
  const compiled = yield* compileOpenApiSpec(resolved.specText);
1336
1586
  const explicitBaseUrl = config.baseUrl;
1337
1587
  const needsDerivedBaseUrl = explicitBaseUrl == null;
1338
1588
  const needsDerivedAuth = config.authenticationTemplate == null;
1339
- 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;
1340
1599
  const derivedBaseUrl = needsDerivedBaseUrl && preview ? firstBaseUrlForPreview(preview) : void 0;
1341
1600
  const effectiveBaseUrl = explicitBaseUrl ?? (derivedBaseUrl || void 0);
1342
1601
  const derivedAuthenticationTemplate = needsDerivedAuth && preview ? deriveAuthenticationTemplateFromPreview(preview, effectiveBaseUrl) : void 0;
@@ -1450,7 +1709,12 @@ var openApiPlugin = definePlugin((options) => {
1450
1709
  const specText = yield* resolveSpecText(previewInput.spec).pipe(
1451
1710
  Effect4.provide(httpClientLayer)
1452
1711
  );
1453
- 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
+ });
1454
1718
  }),
1455
1719
  addSpec,
1456
1720
  updateSpec,
@@ -1639,4 +1903,4 @@ export {
1639
1903
  resolveOpenApiBackedAnnotations,
1640
1904
  openApiPlugin
1641
1905
  };
1642
- //# sourceMappingURL=chunk-3O3PGRRG.js.map
1906
+ //# sourceMappingURL=chunk-DBA2BHE4.js.map