@postman/sdk-config 0.0.3 → 0.1.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 (36) hide show
  1. package/README.md +42 -17
  2. package/dist/index.cjs +2017 -180
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +3 -1
  5. package/dist/index.d.ts +3 -1
  6. package/dist/index.js +1980 -181
  7. package/dist/index.js.map +1 -1
  8. package/dist/sdk-config/index.cjs +2233 -0
  9. package/dist/sdk-config/index.cjs.map +1 -0
  10. package/dist/sdk-config/index.d.cts +3 -0
  11. package/dist/sdk-config/index.d.ts +3 -0
  12. package/dist/sdk-config/index.js +2192 -0
  13. package/dist/sdk-config/index.js.map +1 -0
  14. package/dist/sdk-config/v1/index.cjs +2233 -0
  15. package/dist/sdk-config/v1/index.cjs.map +1 -0
  16. package/dist/sdk-config/v1/index.d.cts +8644 -0
  17. package/dist/sdk-config/v1/index.d.ts +8644 -0
  18. package/dist/sdk-config/v1/index.js +2192 -0
  19. package/dist/sdk-config/v1/index.js.map +1 -0
  20. package/dist/sdk-config-ir/index.cjs +155 -19
  21. package/dist/sdk-config-ir/index.cjs.map +1 -1
  22. package/dist/sdk-config-ir/index.d.cts +2 -1
  23. package/dist/sdk-config-ir/index.d.ts +2 -1
  24. package/dist/sdk-config-ir/index.js +154 -20
  25. package/dist/sdk-config-ir/index.js.map +1 -1
  26. package/dist/sdk-config-ir/v1/index.cjs +155 -19
  27. package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
  28. package/dist/sdk-config-ir/v1/index.d.cts +448 -398
  29. package/dist/sdk-config-ir/v1/index.d.ts +448 -398
  30. package/dist/sdk-config-ir/v1/index.js +154 -20
  31. package/dist/sdk-config-ir/v1/index.js.map +1 -1
  32. package/dist/typescript-ByDbin_v.d.cts +426 -0
  33. package/dist/typescript-ByDbin_v.d.ts +426 -0
  34. package/package.json +15 -2
  35. package/src/sdk-config/v1/README.md +135 -0
  36. package/src/sdk-config-ir/v1/README.md +46 -27
package/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
8
  var semver__default = /*#__PURE__*/_interopDefault(semver);
9
9
 
10
- // src/sdk-config-ir/v1/api.ts
10
+ // src/sdk-config-domain/v1/api.ts
11
11
  var nonEmptyStringSchema = zod.z.string().min(1);
12
12
  var exactSemverSchema = zod.z.string().refine(
13
13
  (value) => {
@@ -31,7 +31,7 @@ var jsonValueSchema = zod.z.lazy(
31
31
  );
32
32
  var jsonObjectSchema = zod.z.record(zod.z.string(), jsonValueSchema);
33
33
 
34
- // src/sdk-config-ir/v1/api.ts
34
+ // src/sdk-config-domain/v1/api.ts
35
35
  var authVariableSchema = zod.z.strictObject({
36
36
  name: nonEmptyStringSchema.optional(),
37
37
  environmentVariable: nonEmptyStringSchema.optional(),
@@ -181,8 +181,20 @@ var apiConfigSchema = zod.z.strictObject({
181
181
  environmentVariables: zod.z.array(environmentVariableSchema).default([]),
182
182
  defaultEnvironment: nonEmptyStringSchema.optional(),
183
183
  auth: authConfigSchema.optional(),
184
- headers: zod.z.array(headerSchema).optional()
184
+ headers: zod.z.array(headerSchema).optional(),
185
+ /**
186
+ * Selects the named `x-fern-audiences`.
187
+ *
188
+ * Absent means all audiences. A present empty array selects no tagged audience: untagged nodes
189
+ * remain included, while every audience-tagged node is excluded.
190
+ */
191
+ audiences: zod.z.array(nonEmptyStringSchema).optional()
185
192
  });
193
+
194
+ // src/sdk-config/v1/api.ts
195
+ var sdkConfigV1AuthSchemeSchema = authSchemeSchema;
196
+ var sdkConfigV1AuthConfigSchema = authConfigSchema;
197
+ var sdkConfigV1ApiConfigSchema = apiConfigSchema;
186
198
  var retryConfigSchema = zod.z.strictObject({
187
199
  enabled: zod.z.boolean().default(true),
188
200
  maxAttempts: zod.z.number().int().min(1).default(3),
@@ -235,34 +247,89 @@ var clientConfigSchema = zod.z.strictObject({
235
247
  pathParameterStyle: parameterStyleSchema.optional(),
236
248
  filePropertyStyle: parameterStyleSchema.optional(),
237
249
  useDefaultRequestParameterValues: zod.z.boolean().optional(),
250
+ respectOptionalRequestBody: zod.z.boolean().optional(),
238
251
  tokenRefresh: tokenRefreshConfigSchema.optional()
239
252
  });
240
- var unsupportedFieldSchema = zod.z.strictObject({
241
- source: zod.z.enum(["fern", "postman", "sdk-config-ir"]),
242
- path: zod.z.array(zod.z.union([nonEmptyStringSchema, zod.z.number().int().nonnegative()])).min(1),
243
- code: nonEmptyStringSchema.optional(),
244
- reason: nonEmptyStringSchema,
245
- severity: zod.z.enum(["error", "warning", "info"]),
246
- risk: zod.z.enum(["high", "medium", "low"]),
247
- owner: nonEmptyStringSchema,
248
- suggestedAction: nonEmptyStringSchema
253
+
254
+ // src/sdk-config/v1/client.ts
255
+ var sdkConfigV1ClientConfigSchema = clientConfigSchema;
256
+ var goModulePathSchema = nonEmptyStringSchema.regex(
257
+ /^(?!.*(?:^|\/)\.{1,2}(?:\/|$))[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)+$/,
258
+ "Go module path must be a slash-delimited path using letters, numbers, dots, dashes, underscores, or tildes"
259
+ );
260
+ var composerPackageNameSchema = nonEmptyStringSchema.regex(
261
+ /^[a-z0-9]([_.-]?[a-z0-9]+)*\/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$/,
262
+ 'Composer package name must be a lowercase "vendor/package" name'
263
+ );
264
+ var authorSchema = zod.z.strictObject({
265
+ name: nonEmptyStringSchema,
266
+ email: zod.z.email().optional()
249
267
  });
250
- var postmanLegacyInputSchema = zod.z.strictObject({
251
- kind: zod.z.literal("postman-build-parameters"),
252
- value: jsonObjectSchema
268
+ var developerSchema = zod.z.strictObject({
269
+ name: nonEmptyStringSchema,
270
+ email: zod.z.email().optional(),
271
+ organization: nonEmptyStringSchema.optional(),
272
+ organizationUrl: nonEmptyStringSchema.optional()
253
273
  });
254
- var fernLegacyInputSchema = zod.z.strictObject({
255
- kind: zod.z.literal("fern-generator-invocation"),
256
- value: jsonObjectSchema
274
+ var licenseSchema = zod.z.strictObject({
275
+ type: nonEmptyStringSchema,
276
+ name: nonEmptyStringSchema.optional(),
277
+ url: nonEmptyStringSchema.optional(),
278
+ path: nonEmptyStringSchema.optional()
257
279
  });
258
- var legacyInputSchema = zod.z.discriminatedUnion("kind", [
259
- postmanLegacyInputSchema,
260
- fernLegacyInputSchema
280
+ var dependencySourceSchema = zod.z.discriminatedUnion("type", [
281
+ zod.z.strictObject({
282
+ type: zod.z.literal("registry"),
283
+ registry: nonEmptyStringSchema.optional()
284
+ }),
285
+ zod.z.strictObject({
286
+ type: zod.z.literal("git"),
287
+ url: nonEmptyStringSchema,
288
+ ref: nonEmptyStringSchema.optional(),
289
+ subdirectory: nonEmptyStringSchema.optional()
290
+ }),
291
+ zod.z.strictObject({
292
+ type: zod.z.literal("path"),
293
+ path: nonEmptyStringSchema
294
+ })
261
295
  ]);
262
- var compatibilityConfigSchema = zod.z.strictObject({
263
- outputProfile: zod.z.enum(["converged", "postman-legacy", "fern-legacy"]),
264
- legacyInput: legacyInputSchema.optional(),
265
- unsupportedFields: zod.z.array(unsupportedFieldSchema).optional()
296
+ var dependencySchema = zod.z.strictObject({
297
+ name: nonEmptyStringSchema,
298
+ version: nonEmptyStringSchema.optional(),
299
+ source: dependencySourceSchema.optional(),
300
+ packageName: nonEmptyStringSchema.optional(),
301
+ features: zod.z.array(nonEmptyStringSchema).optional(),
302
+ extras: zod.z.array(nonEmptyStringSchema).optional(),
303
+ optional: zod.z.boolean().optional(),
304
+ defaultFeatures: zod.z.boolean().optional(),
305
+ environmentMarker: nonEmptyStringSchema.optional()
306
+ }).refine(({ source, version }) => source !== void 0 || version !== void 0, {
307
+ message: "dependency must define a version or a source"
308
+ });
309
+ var projectUrlSchema = zod.z.strictObject({
310
+ label: nonEmptyStringSchema,
311
+ url: nonEmptyStringSchema
312
+ });
313
+ var packageConfigSchema = zod.z.strictObject({
314
+ packageName: nonEmptyStringSchema.optional(),
315
+ moduleName: nonEmptyStringSchema.optional(),
316
+ modulePath: goModulePathSchema.optional(),
317
+ namespace: nonEmptyStringSchema.optional(),
318
+ groupId: nonEmptyStringSchema.optional(),
319
+ artifactId: nonEmptyStringSchema.optional(),
320
+ description: zod.z.string().optional(),
321
+ repository: nonEmptyStringSchema.optional(),
322
+ homepage: nonEmptyStringSchema.optional(),
323
+ documentationUrl: nonEmptyStringSchema.optional(),
324
+ authors: zod.z.array(authorSchema).optional(),
325
+ developers: zod.z.array(developerSchema).optional(),
326
+ license: licenseSchema.optional(),
327
+ keywords: zod.z.array(nonEmptyStringSchema).optional(),
328
+ classifiers: zod.z.array(nonEmptyStringSchema).optional(),
329
+ projectUrls: zod.z.array(projectUrlSchema).optional(),
330
+ extraDependencies: zod.z.array(dependencySchema).optional(),
331
+ extraDevDependencies: zod.z.array(dependencySchema).optional(),
332
+ extraPeerDependencies: zod.z.array(dependencySchema).optional()
266
333
  });
267
334
  var httpMethodSchema = zod.z.enum([
268
335
  "GET",
@@ -280,12 +347,17 @@ var readmeEndpointSchema = zod.z.strictObject({
280
347
  path: nonEmptyStringSchema,
281
348
  stream: zod.z.boolean().optional()
282
349
  });
350
+ var readmeCustomSectionSchema = zod.z.strictObject({
351
+ title: nonEmptyStringSchema,
352
+ content: zod.z.string()
353
+ });
283
354
  var readmeConfigSchema = zod.z.strictObject({
284
355
  apiName: nonEmptyStringSchema.optional(),
285
356
  introduction: zod.z.string().optional(),
286
357
  apiReferenceLink: nonEmptyStringSchema.optional(),
287
358
  bannerLink: nonEmptyStringSchema.optional(),
288
359
  disabledSections: zod.z.array(nonEmptyStringSchema).optional(),
360
+ customSections: zod.z.array(readmeCustomSectionSchema).optional(),
289
361
  defaultEndpoint: readmeEndpointSchema.optional(),
290
362
  features: zod.z.record(zod.z.string(), zod.z.array(readmeEndpointSchema)).optional()
291
363
  });
@@ -300,6 +372,737 @@ var docsConfigSchema = zod.z.strictObject({
300
372
  referenceBaseUrl: nonEmptyStringSchema.optional(),
301
373
  includeApiReference: zod.z.boolean().optional()
302
374
  });
375
+
376
+ // src/sdk-config/v1/docs.ts
377
+ var sdkConfigV1ReadmeEndpointSchema = readmeEndpointSchema;
378
+ var sdkConfigV1ReadmeCustomSectionSchema = readmeCustomSectionSchema;
379
+ var sdkConfigV1DocsConfigSchema = docsConfigSchema;
380
+
381
+ // src/sdk-config/v1/fern-config-mapper-types.ts
382
+ var FernConfigMappingError = class extends Error {
383
+ constructor(issues) {
384
+ super(issues.map(({ path, reason }) => `${path.join(".")}: ${reason}`).join("\n"));
385
+ this.issues = issues;
386
+ this.name = "FernConfigMappingError";
387
+ }
388
+ issues;
389
+ };
390
+
391
+ // src/sdk-config/v1/fern-config-mapper-helpers.ts
392
+ function fail(code, path, reason, suggestedAction, sdkConfigPath) {
393
+ throw new FernConfigMappingError([
394
+ {
395
+ code,
396
+ severity: "error",
397
+ path,
398
+ reason,
399
+ suggestedAction,
400
+ ...optional("sdkConfigPath", sdkConfigPath)
401
+ }
402
+ ]);
403
+ }
404
+ function takeTimeoutMs(value, state, basePath) {
405
+ const milliseconds = locate(value, ["defaultTimeout", "defaultTimeoutInMilliseconds"], basePath);
406
+ if (milliseconds && (milliseconds.value === "infinity" || isNonNegativeNumber(milliseconds.value))) {
407
+ consume(state, milliseconds.path);
408
+ return milliseconds.value;
409
+ }
410
+ const seconds = locate(
411
+ value,
412
+ ["defaultTimeoutInSeconds", "timeoutInSeconds", "timeout"],
413
+ basePath
414
+ );
415
+ if (seconds && (seconds.value === "infinity" || isNonNegativeNumber(seconds.value))) {
416
+ consume(state, seconds.path);
417
+ return seconds.value === "infinity" ? "infinity" : seconds.value * 1e3;
418
+ }
419
+ return void 0;
420
+ }
421
+ function locate(value, aliases, basePath) {
422
+ for (const [key, child] of Object.entries(value)) {
423
+ if (aliases.some((alias) => normalizeKey(alias) === normalizeKey(key))) {
424
+ return { value: child, path: [...basePath, key] };
425
+ }
426
+ }
427
+ return void 0;
428
+ }
429
+ function takeObject(value, aliases, _state, basePath) {
430
+ const located = locate(value, aliases, basePath);
431
+ return located && isObject(located.value) ? { value: located.value, path: located.path } : void 0;
432
+ }
433
+ function takeString(value, aliases, state, basePath) {
434
+ const located = locate(value, aliases, basePath);
435
+ if (!located || typeof located.value !== "string" || located.value.length === 0) return void 0;
436
+ consume(state, located.path);
437
+ return located.value;
438
+ }
439
+ function takeGoModulePath(value, aliases, state, basePath) {
440
+ const located = locate(value, aliases, basePath);
441
+ if (!located || !goModulePathSchema.safeParse(located.value).success) return void 0;
442
+ consume(state, located.path);
443
+ return located.value;
444
+ }
445
+ function takeBoolean(value, aliases, state, basePath) {
446
+ const located = locate(value, aliases, basePath);
447
+ if (!located || typeof located.value !== "boolean") return void 0;
448
+ consume(state, located.path);
449
+ return located.value;
450
+ }
451
+ function takeNumber(value, aliases, state, basePath) {
452
+ const located = locate(value, aliases, basePath);
453
+ if (!located || !isNonNegativeNumber(located.value) || !Number.isInteger(located.value))
454
+ return void 0;
455
+ consume(state, located.path);
456
+ return located.value;
457
+ }
458
+ function takeEnum(value, aliases, values, state, basePath) {
459
+ const located = locate(value, aliases, basePath);
460
+ if (!located || typeof located.value !== "string" || !values.includes(located.value))
461
+ return void 0;
462
+ consume(state, located.path);
463
+ return located.value;
464
+ }
465
+ function takeEnumArray(value, aliases, values, state, basePath) {
466
+ const located = locate(value, aliases, basePath);
467
+ if (!located || !Array.isArray(located.value) || located.value.some((item) => typeof item !== "string" || !values.includes(item)))
468
+ return void 0;
469
+ consume(state, located.path);
470
+ return located.value;
471
+ }
472
+ function takeStringArray(value, aliases, state, basePath) {
473
+ const located = locate(value, aliases, basePath);
474
+ const strings = located ? stringArrayValue(located.value) : void 0;
475
+ if (!located || !strings) return void 0;
476
+ consume(state, located.path);
477
+ return strings;
478
+ }
479
+ function takeStringArrayRecord(value, aliases, state, basePath) {
480
+ const located = locate(value, aliases, basePath);
481
+ if (!located || !isObject(located.value)) return void 0;
482
+ const entries = Object.entries(located.value);
483
+ if (entries.some(([, item]) => !stringArrayValue(item))) return void 0;
484
+ consume(state, located.path);
485
+ return Object.fromEntries(entries);
486
+ }
487
+ function collectUnsupported(value, basePath, state) {
488
+ return collectLeafPaths(value, basePath).filter((path) => {
489
+ const key = pathKey(path);
490
+ return ![...state.consumedPaths].some(
491
+ (consumed) => key === consumed || key.startsWith(`${consumed}.`)
492
+ );
493
+ }).map((path) => ({
494
+ code: "FERN_CONFIG_FIELD_UNSUPPORTED",
495
+ severity: "warning",
496
+ path,
497
+ reason: "Fern configuration field is not represented by SDK Config v1",
498
+ suggestedAction: "Review this value and set the closest SDK Config field manually, or preserve the setting outside SDK Config if no equivalent exists."
499
+ }));
500
+ }
501
+ function collectLeafPaths(value, path) {
502
+ if (Array.isArray(value))
503
+ return value.flatMap((item, index) => collectLeafPaths(item, [...path, index]));
504
+ if (isObject(value))
505
+ return Object.entries(value).flatMap(([key, child]) => collectLeafPaths(child, [...path, key]));
506
+ return value === void 0 ? [] : [path];
507
+ }
508
+ function consume(state, path) {
509
+ state.consumedPaths.add(pathKey(path));
510
+ }
511
+ function pathKey(path) {
512
+ return path.join(".");
513
+ }
514
+ function normalizeKey(value) {
515
+ return value.replace(/[-_]/g, "").toLowerCase();
516
+ }
517
+ function compact(value) {
518
+ return Object.fromEntries(Object.entries(value).filter(([, child]) => child !== void 0));
519
+ }
520
+ function optional(key, value) {
521
+ return value === void 0 ? {} : { [key]: value };
522
+ }
523
+ function isObject(value) {
524
+ return value !== null && typeof value === "object" && !Array.isArray(value);
525
+ }
526
+ function isNonNegativeNumber(value) {
527
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
528
+ }
529
+ function stringValue(value) {
530
+ return typeof value === "string" && value.length > 0 ? value : void 0;
531
+ }
532
+ function stringArrayValue(value) {
533
+ return Array.isArray(value) && value.every((item) => typeof item === "string" && item.length > 0) ? value : void 0;
534
+ }
535
+ function stableJson(value) {
536
+ return JSON.stringify(sortKeys(value));
537
+ }
538
+ function sortKeys(value) {
539
+ if (Array.isArray(value)) return value.map(sortKeys);
540
+ if (!isObject(value)) return value;
541
+ return Object.fromEntries(
542
+ Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, sortKeys(child)])
543
+ );
544
+ }
545
+
546
+ // src/sdk-config/v1/fern-config-mapper-output.ts
547
+ function mapOutput(generator, language, index) {
548
+ const raw = isObject(generator.raw) ? generator.raw : void 0;
549
+ const rawOutput = raw && isObject(raw.output) ? raw.output : void 0;
550
+ const outputPath = ["group", "generators", index, "outputMode"];
551
+ const state = { consumedPaths: /* @__PURE__ */ new Set() };
552
+ if (rawOutput?.location === "local-file-system") {
553
+ if (isObject(generator.outputMode)) consume(state, [...outputPath, "type"]);
554
+ return finishOutputMapping(
555
+ {
556
+ output: {
557
+ delivery: "files",
558
+ ...typeof rawOutput.path === "string" && rawOutput.path ? { path: rawOutput.path } : {}
559
+ }
560
+ },
561
+ generator.outputMode,
562
+ outputPath,
563
+ state,
564
+ index
565
+ );
566
+ }
567
+ if (!isObject(generator.outputMode) || typeof generator.outputMode.type !== "string") {
568
+ fail(
569
+ "FERN_OUTPUT_REQUIRED",
570
+ ["group", "generators", index, "outputMode"],
571
+ `Cannot map output for Fern generator ${generator.name}`,
572
+ "Set generator.output to a public SDK Config output, or provide the resolved Fern outputMode.",
573
+ ["targets", index, "output"]
574
+ );
575
+ }
576
+ const output = generator.outputMode;
577
+ consume(state, [...outputPath, "type"]);
578
+ switch (output.type) {
579
+ case "downloadFiles":
580
+ return finishOutputMapping({ output: { delivery: "zip" } }, output, outputPath, state, index);
581
+ case "github":
582
+ return finishOutputMapping(
583
+ githubOutput(output, output.publishInfo, language, outputPath, state, index),
584
+ output,
585
+ outputPath,
586
+ state,
587
+ index
588
+ );
589
+ case "githubV2": {
590
+ if (!isObject(output.githubV2))
591
+ fail(
592
+ "FERN_GITHUB_OUTPUT_INVALID",
593
+ ["group", "generators", index, "outputMode", "githubV2"],
594
+ "Fern githubV2 output is missing its configuration",
595
+ 'Set target.output manually with delivery "github" and the intended repository.',
596
+ ["targets", index, "output"]
597
+ );
598
+ const githubPath = [...outputPath, "githubV2"];
599
+ return finishOutputMapping(
600
+ githubOutput(
601
+ output.githubV2,
602
+ output.githubV2.publishInfo,
603
+ language,
604
+ githubPath,
605
+ state,
606
+ index
607
+ ),
608
+ output,
609
+ outputPath,
610
+ state,
611
+ index
612
+ );
613
+ }
614
+ case "publishV2": {
615
+ const publication = mapPublication(
616
+ output.publishV2,
617
+ language,
618
+ [...outputPath, "publishV2"],
619
+ state,
620
+ index
621
+ );
622
+ return finishOutputMapping(
623
+ {
624
+ output: { delivery: "zip", publish: publication.publish },
625
+ ...optional("package", publication.package)
626
+ },
627
+ output,
628
+ outputPath,
629
+ state,
630
+ index
631
+ );
632
+ }
633
+ case "publish": {
634
+ const publication = mapLegacyPublication(
635
+ output.registryOverrides,
636
+ language,
637
+ [...outputPath, "registryOverrides"],
638
+ state,
639
+ index
640
+ );
641
+ return finishOutputMapping(
642
+ {
643
+ output: { delivery: "zip", publish: publication.publish },
644
+ ...optional("package", publication.package)
645
+ },
646
+ output,
647
+ outputPath,
648
+ state,
649
+ index
650
+ );
651
+ }
652
+ default:
653
+ fail(
654
+ "FERN_OUTPUT_UNSUPPORTED",
655
+ ["group", "generators", index, "outputMode", "type"],
656
+ `Unsupported Fern output mode "${output.type}"`,
657
+ "Choose the equivalent files, zip, or github SDK Config output manually.",
658
+ ["targets", index, "output"]
659
+ );
660
+ }
661
+ }
662
+ function githubOutput(value, publishInfo, language, sourcePath, state, index) {
663
+ const owner = stringValue(value.owner);
664
+ const repo = stringValue(value.repo);
665
+ if (!owner || !repo)
666
+ fail(
667
+ "FERN_GITHUB_REPOSITORY_REQUIRED",
668
+ sourcePath,
669
+ "Fern GitHub output requires owner and repo",
670
+ 'Set target.output.github.repository manually as "owner/repository".',
671
+ ["targets", index, "output", "github", "repository"]
672
+ );
673
+ consume(state, [...sourcePath, "owner"]);
674
+ consume(state, [...sourcePath, "repo"]);
675
+ const publication = publishInfo ? mapPublication(publishInfo, language, [...sourcePath, "publishInfo"], state, index) : void 0;
676
+ const type = stringValue(value.type);
677
+ const reviewers = mapReviewers(value.reviewers, [...sourcePath, "reviewers"], state);
678
+ if (type) consume(state, [...sourcePath, "type"]);
679
+ if (typeof value.makePr === "boolean") consume(state, [...sourcePath, "makePr"]);
680
+ if (stringValue(value.host)) consume(state, [...sourcePath, "host"]);
681
+ if (stringValue(value.branch)) consume(state, [...sourcePath, "branch"]);
682
+ return {
683
+ output: {
684
+ delivery: "github",
685
+ github: {
686
+ repository: `${owner}/${repo}`,
687
+ ...optional("host", stringValue(value.host)),
688
+ ...optional("branch", stringValue(value.branch)),
689
+ mode: value.makePr === true || type === "pullRequest" ? "pull-request" : type === "push" ? "push" : "release",
690
+ ...optional("reviewers", reviewers)
691
+ },
692
+ ...publication ? { publish: publication.publish } : {}
693
+ },
694
+ ...optional("package", publication?.package)
695
+ };
696
+ }
697
+ function mapReviewers(value, sourcePath, state) {
698
+ if (Array.isArray(value)) {
699
+ const teams2 = reviewerNames(value, "team", sourcePath, state);
700
+ const users2 = reviewerNames(value, "user", sourcePath, state);
701
+ return teams2 || users2 ? { ...optional("teams", teams2), ...optional("users", users2) } : void 0;
702
+ }
703
+ if (!isObject(value)) return void 0;
704
+ const teams = reviewerNames(value.teams, "team", [...sourcePath, "teams"], state);
705
+ const users = reviewerNames(value.users, "user", [...sourcePath, "users"], state);
706
+ return teams || users ? { ...optional("teams", teams), ...optional("users", users) } : void 0;
707
+ }
708
+ function reviewerNames(value, expectedType, sourcePath, state) {
709
+ if (!Array.isArray(value)) return void 0;
710
+ const names = value.flatMap((reviewer, index) => {
711
+ if (typeof reviewer === "string") {
712
+ consume(state, [...sourcePath, index]);
713
+ return [reviewer];
714
+ }
715
+ if (!isObject(reviewer) || reviewer.type !== expectedType || typeof reviewer.name !== "string") {
716
+ return [];
717
+ }
718
+ consume(state, [...sourcePath, index, "type"]);
719
+ consume(state, [...sourcePath, index, "name"]);
720
+ return [reviewer.name];
721
+ });
722
+ return names.length ? names : void 0;
723
+ }
724
+ function mapPublication(value, language, sourcePath, state, index) {
725
+ if (!isObject(value))
726
+ fail(
727
+ "FERN_PUBLICATION_INVALID",
728
+ sourcePath,
729
+ "Fern publication output is invalid",
730
+ "Set target.output.publish and target.package manually.",
731
+ ["targets", index, "output", "publish"]
732
+ );
733
+ const type = stringValue(value.type);
734
+ if (type) consume(state, [...sourcePath, "type"]);
735
+ const nested = type && isObject(value[type]) ? value[type] : value;
736
+ const nestedPath = nested === value ? sourcePath : [...sourcePath, type];
737
+ const registry = publicationRegistry(type, language, [...sourcePath, "type"], index);
738
+ const registryUrl = stringValue(nested.registryUrl);
739
+ if (registryUrl) consume(state, [...nestedPath, "registryUrl"]);
740
+ if (registry === "maven") {
741
+ const coordinate = stringValue(nested.coordinate);
742
+ if (coordinate) consume(state, [...nestedPath, "coordinate"]);
743
+ return {
744
+ publish: compact({ registry, url: registryUrl }),
745
+ ...coordinate ? { package: mavenPackage(coordinate, [...nestedPath, "coordinate"], index) } : {}
746
+ };
747
+ }
748
+ const packageNameField = stringValue(nested.packageName) ? "packageName" : "coordinate";
749
+ const packageName = stringValue(nested[packageNameField]);
750
+ if (packageName) consume(state, [...nestedPath, packageNameField]);
751
+ const metadata = registry === "pypi" ? mapPypiMetadata(nested.pypiMetadata, nestedPath, state) : {};
752
+ return {
753
+ publish: compact({ registry, url: registryUrl }),
754
+ ...packageName || Object.keys(metadata).length ? { package: { ...optional("packageName", packageName), ...metadata } } : {}
755
+ };
756
+ }
757
+ function mapLegacyPublication(value, language, sourcePath, state, index) {
758
+ const registry = defaultRegistry(language, sourcePath, index);
759
+ const overrides = isObject(value) ? value : {};
760
+ const override = isObject(overrides[registry]) ? overrides[registry] : {};
761
+ return mapPublication(override, language, [...sourcePath, registry], state, index);
762
+ }
763
+ function publicationRegistry(type, language, sourcePath, index) {
764
+ if (type === "postman") {
765
+ fail(
766
+ "FERN_POSTMAN_PUBLICATION_UNSUPPORTED",
767
+ sourcePath,
768
+ "Postman collection publication is not an SDK output",
769
+ "Remove this non-SDK target or convert it separately from the SDK Config document."
770
+ );
771
+ }
772
+ const normalized = type?.replace(/Override$/, "").toLowerCase();
773
+ if (normalized === "rubygems") return "rubygems";
774
+ if (normalized && ["npm", "pypi", "maven", "nuget", "crates"].includes(normalized)) {
775
+ return normalized;
776
+ }
777
+ if (normalized !== void 0) {
778
+ fail(
779
+ "FERN_PUBLICATION_UNSUPPORTED",
780
+ sourcePath,
781
+ `Unsupported Fern publication type "${type}"`,
782
+ "Set target.output.publish and target.package manually if SDK Config supports the registry.",
783
+ ["targets", index, "output", "publish"]
784
+ );
785
+ }
786
+ return defaultRegistry(language, sourcePath, index);
787
+ }
788
+ function defaultRegistry(language, sourcePath, index) {
789
+ const registries = {
790
+ typescript: "npm",
791
+ mcp: "npm",
792
+ python: "pypi",
793
+ java: "maven",
794
+ kotlin: "maven",
795
+ csharp: "nuget",
796
+ ruby: "rubygems",
797
+ rust: "crates",
798
+ go: "go",
799
+ php: "composer"
800
+ };
801
+ const registry = registries[language];
802
+ if (!registry)
803
+ fail(
804
+ "FERN_PUBLICATION_REGISTRY_REQUIRED",
805
+ sourcePath,
806
+ `No publication registry can be inferred for ${language}`,
807
+ "Set target.output.publish.registry manually.",
808
+ ["targets", index, "output", "publish", "registry"]
809
+ );
810
+ return registry;
811
+ }
812
+ function mavenPackage(coordinate, sourcePath, index) {
813
+ const parts = coordinate.split(":");
814
+ const [groupId, artifactId] = parts;
815
+ if (parts.length !== 2 || !groupId || !artifactId)
816
+ fail(
817
+ "FERN_MAVEN_COORDINATE_INVALID",
818
+ sourcePath,
819
+ `Invalid Maven coordinate ${coordinate}`,
820
+ "Set target.package.groupId and target.package.artifactId manually.",
821
+ ["targets", index, "package"]
822
+ );
823
+ return { groupId, artifactId };
824
+ }
825
+ function mapPypiMetadata(value, sourcePath, state) {
826
+ if (!isObject(value)) return {};
827
+ const metadataPath = [...sourcePath, "pypiMetadata"];
828
+ const description = stringValue(value.description);
829
+ const keywords = stringArrayValue(value.keywords);
830
+ const documentationUrl = stringValue(value.documentationLink);
831
+ const homepage = stringValue(value.homepageLink);
832
+ const authors = mapAuthors(value.authors, [...metadataPath, "authors"], state);
833
+ if (description) consume(state, [...metadataPath, "description"]);
834
+ if (keywords) consume(state, [...metadataPath, "keywords"]);
835
+ if (documentationUrl) consume(state, [...metadataPath, "documentationLink"]);
836
+ if (homepage) consume(state, [...metadataPath, "homepageLink"]);
837
+ return compact({ description, authors, keywords, documentationUrl, homepage });
838
+ }
839
+ function mapAuthors(value, sourcePath, state) {
840
+ if (!Array.isArray(value)) return void 0;
841
+ const authors = value.flatMap((author) => {
842
+ if (!isObject(author)) return [];
843
+ const name = stringValue(author.name);
844
+ const email = stringValue(author.email);
845
+ return name ? [{ name, ...optional("email", email) }] : [];
846
+ });
847
+ if (authors.length !== value.length) return void 0;
848
+ value.forEach((author, index) => {
849
+ consume(state, [...sourcePath, index, "name"]);
850
+ if (isObject(author) && stringValue(author.email)) {
851
+ consume(state, [...sourcePath, index, "email"]);
852
+ }
853
+ });
854
+ return authors;
855
+ }
856
+ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
857
+ for (const path of collectLeafPaths(outputMode, sourcePath)) {
858
+ if (path[path.length - 1] === "_visit") consume(state, path);
859
+ }
860
+ return {
861
+ ...mapping,
862
+ unsupportedFields: collectUnsupported(outputMode, sourcePath, state).map(
863
+ (diagnostic) => outputDiagnostic(diagnostic.path, index)
864
+ )
865
+ };
866
+ }
867
+ function outputDiagnostic(path, index) {
868
+ const fields = path.filter((part) => typeof part === "string");
869
+ const field = fields[fields.length - 1];
870
+ const credential = fields.some((part) => part === "credentials" || part === "signature") || ["apiKey", "keyId", "password", "secretKey", "token", "username"].includes(field ?? "");
871
+ if (credential) {
872
+ return {
873
+ code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
874
+ severity: "warning",
875
+ path,
876
+ reason: "Fern output credentials and signatures are not represented by SDK Config v1",
877
+ suggestedAction: "Configure publication credentials and signing secrets outside SDK Config."
878
+ };
879
+ }
880
+ const guidance = {
881
+ directory: {
882
+ suggestedAction: "Preserve the GitHub output subdirectory outside SDK Config; public v1 has no repository subdirectory field."
883
+ },
884
+ license: {
885
+ sdkConfigPath: ["targets", index, "package", "license"],
886
+ suggestedAction: "Set target.package.license manually using portable license metadata."
887
+ },
888
+ id: {
889
+ sdkConfigPath: ["targets", index, "package", "license"],
890
+ suggestedAction: "Set target.package.license manually using portable license metadata."
891
+ },
892
+ contents: {
893
+ sdkConfigPath: ["targets", index, "package", "license"],
894
+ suggestedAction: "Set target.package.license manually without embedding license contents."
895
+ },
896
+ downloadSnippets: {
897
+ sdkConfigPath: ["docs", "snippets", "enabled"],
898
+ suggestedAction: "Set docs.snippets.enabled manually and choose a portable output path if needed."
899
+ },
900
+ version: {
901
+ sdkConfigPath: ["targets", index, "sdkVersion"],
902
+ suggestedAction: "Set target.sdkVersion manually if this output version identifies the SDK artifact."
903
+ },
904
+ description: {
905
+ sdkConfigPath: ["targets", index, "package", "description"],
906
+ suggestedAction: "Set target.package.description manually to a valid value."
907
+ },
908
+ authors: {
909
+ sdkConfigPath: ["targets", index, "package", "authors"],
910
+ suggestedAction: "Set target.package.authors manually using valid author metadata."
911
+ },
912
+ keywords: {
913
+ sdkConfigPath: ["targets", index, "package", "keywords"],
914
+ suggestedAction: "Set target.package.keywords manually using non-empty strings."
915
+ },
916
+ documentationLink: {
917
+ sdkConfigPath: ["targets", index, "package", "documentationUrl"],
918
+ suggestedAction: "Set target.package.documentationUrl manually to a valid URL."
919
+ },
920
+ homepageLink: {
921
+ sdkConfigPath: ["targets", index, "package", "homepage"],
922
+ suggestedAction: "Set target.package.homepage manually to a valid URL."
923
+ }
924
+ };
925
+ const fieldGuidance = field ? guidance[field] : void 0;
926
+ const resolvedGuidance = fields.includes("license") ? guidance.license : fieldGuidance;
927
+ return {
928
+ code: "FERN_OUTPUT_FIELD_UNSUPPORTED",
929
+ severity: "warning",
930
+ path,
931
+ reason: "Fern output field is not represented by SDK Config v1",
932
+ ...optional("sdkConfigPath", resolvedGuidance?.sdkConfigPath),
933
+ suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
934
+ };
935
+ }
936
+ var customerGenerationAssetSchema = zod.z.discriminatedUnion("type", [
937
+ zod.z.strictObject({ type: zod.z.literal("path"), location: nonEmptyStringSchema }),
938
+ zod.z.strictObject({ type: zod.z.literal("url"), location: nonEmptyStringSchema })
939
+ ]);
940
+ var hookDependencySchema = zod.z.strictObject({
941
+ name: nonEmptyStringSchema,
942
+ version: nonEmptyStringSchema,
943
+ groupId: nonEmptyStringSchema.optional()
944
+ });
945
+ var hooksConfigSchema = zod.z.strictObject({
946
+ enabled: zod.z.boolean(),
947
+ source: customerGenerationAssetSchema.optional(),
948
+ dependencies: zod.z.array(hookDependencySchema).optional()
949
+ });
950
+ var customCodeConfigSchema = zod.z.strictObject({
951
+ enabled: zod.z.boolean(),
952
+ source: customerGenerationAssetSchema.optional(),
953
+ conflictStrategy: zod.z.enum(["mark", "ours", "theirs"]).optional(),
954
+ trackChanges: zod.z.boolean().optional(),
955
+ protectedFiles: zod.z.array(nonEmptyStringSchema).optional()
956
+ });
957
+ var workflowConfigSchema = zod.z.strictObject({
958
+ path: nonEmptyStringSchema,
959
+ outputName: nonEmptyStringSchema.optional()
960
+ });
961
+ var analyticsHeaderSchema = zod.z.union([
962
+ zod.z.strictObject({ name: nonEmptyStringSchema, value: zod.z.string() }),
963
+ zod.z.strictObject({
964
+ name: nonEmptyStringSchema,
965
+ valueRef: nonEmptyStringSchema
966
+ })
967
+ ]);
968
+ var analyticsConfigSchema = zod.z.strictObject({
969
+ enabled: zod.z.boolean(),
970
+ endpoint: nonEmptyStringSchema.optional(),
971
+ exporter: zod.z.enum(["otlp-http", "console"]).optional(),
972
+ headers: zod.z.array(analyticsHeaderSchema).optional(),
973
+ batchSize: zod.z.number().int().positive().optional(),
974
+ scheduledDelayMs: zod.z.number().nonnegative().optional(),
975
+ exportTimeoutMs: zod.z.number().nonnegative().optional()
976
+ }).superRefine(({ enabled, endpoint }, context) => {
977
+ if (enabled && endpoint === void 0) {
978
+ context.addIssue({
979
+ code: "custom",
980
+ message: "endpoint is required when analytics is enabled",
981
+ path: ["endpoint"]
982
+ });
983
+ }
984
+ });
985
+ var wireTestsSchema = zod.z.strictObject({
986
+ enabled: zod.z.boolean(),
987
+ exclusions: zod.z.array(nonEmptyStringSchema).optional(),
988
+ fallbackToGeneratedErrorExamples: zod.z.boolean().optional(),
989
+ fixtureSource: zod.z.enum(["synthetic", "recorded", "auto"]).optional()
990
+ });
991
+ var unitTestsSchema = zod.z.strictObject({
992
+ enabled: zod.z.boolean(),
993
+ mode: zod.z.enum(["core-runtime", "schema-driven", "both"]).optional(),
994
+ exclusions: zod.z.array(nonEmptyStringSchema).optional()
995
+ });
996
+ var streamsSchema = zod.z.strictObject({
997
+ enabled: zod.z.boolean(),
998
+ responseType: zod.z.enum(["wrapper", "native", "web"]).optional(),
999
+ fileResponseType: zod.z.enum(["stream", "binary-response"]).optional(),
1000
+ defaultChunkSizeBytes: zod.z.number().int().positive().optional()
1001
+ });
1002
+ var namingConfigSchema = zod.z.strictObject({
1003
+ clientName: nonEmptyStringSchema.optional(),
1004
+ exportedClientName: nonEmptyStringSchema.optional(),
1005
+ environmentTypeName: nonEmptyStringSchema.optional(),
1006
+ apiErrorName: nonEmptyStringSchema.optional(),
1007
+ baseErrorName: nonEmptyStringSchema.optional(),
1008
+ pagerName: nonEmptyStringSchema.optional()
1009
+ });
1010
+ var layoutConfigSchema = zod.z.strictObject({
1011
+ outputDirectory: zod.z.enum(["project-root", "source-root"]).optional(),
1012
+ packagePath: nonEmptyStringSchema.optional()
1013
+ });
1014
+ var serializationConfigSchema = zod.z.strictObject({
1015
+ enumRepresentation: zod.z.enum(["enum", "union", "literal", "forward-compatible-enum", "language-default"]).optional(),
1016
+ additionalProperties: zod.z.enum(["allow", "forbid", "ignore", "language-default"]).optional(),
1017
+ inlineTypes: zod.z.boolean().optional(),
1018
+ omitUndefined: zod.z.boolean().optional()
1019
+ });
1020
+ var sdkConfigV1GenerationConfigSchema = zod.z.strictObject({
1021
+ includeWatermark: zod.z.boolean().default(false),
1022
+ ai: zod.z.boolean().default(false),
1023
+ includeOptionalSnippetParameters: zod.z.boolean().optional(),
1024
+ buildAllModels: zod.z.boolean().default(false),
1025
+ inferServiceNames: zod.z.boolean().default(false),
1026
+ includeDeprecatedOperations: zod.z.boolean().default(true),
1027
+ multipleResponses: zod.z.boolean().default(false),
1028
+ devContainer: zod.z.boolean().default(false),
1029
+ allowMockClient: zod.z.boolean().default(false),
1030
+ ignoreFiles: zod.z.array(nonEmptyStringSchema).optional(),
1031
+ reservedKeywords: zod.z.array(nonEmptyStringSchema).optional(),
1032
+ hooks: hooksConfigSchema.optional(),
1033
+ customCode: customCodeConfigSchema.optional(),
1034
+ workflows: zod.z.array(workflowConfigSchema).optional(),
1035
+ customQueryPaths: zod.z.array(nonEmptyStringSchema).optional(),
1036
+ analytics: analyticsConfigSchema.optional(),
1037
+ wireTests: wireTestsSchema.optional(),
1038
+ unitTests: unitTestsSchema.optional(),
1039
+ webSockets: zod.z.boolean().optional(),
1040
+ streams: streamsSchema.optional(),
1041
+ naming: namingConfigSchema.optional(),
1042
+ layout: layoutConfigSchema.optional(),
1043
+ serialization: serializationConfigSchema.optional()
1044
+ });
1045
+ var sdkConfigV1PublishRegistrySchema = zod.z.enum([
1046
+ "npm",
1047
+ "pypi",
1048
+ "maven",
1049
+ "nuget",
1050
+ "rubygems",
1051
+ "crates",
1052
+ "go",
1053
+ "composer"
1054
+ ]);
1055
+ var commonPublishShape = {
1056
+ url: nonEmptyStringSchema.optional(),
1057
+ releaseBranch: nonEmptyStringSchema.optional(),
1058
+ tolerateRepublish: zod.z.boolean().optional()
1059
+ };
1060
+ var sdkConfigV1PublishConfigSchema = zod.z.discriminatedUnion("registry", [
1061
+ zod.z.strictObject({ registry: zod.z.literal("npm"), ...commonPublishShape }),
1062
+ zod.z.strictObject({ registry: zod.z.literal("pypi"), ...commonPublishShape }),
1063
+ zod.z.strictObject({ registry: zod.z.literal("maven"), ...commonPublishShape }),
1064
+ zod.z.strictObject({ registry: zod.z.literal("nuget"), ...commonPublishShape }),
1065
+ zod.z.strictObject({ registry: zod.z.literal("rubygems"), ...commonPublishShape }),
1066
+ zod.z.strictObject({ registry: zod.z.literal("crates"), ...commonPublishShape }),
1067
+ zod.z.strictObject({ registry: zod.z.literal("go"), ...commonPublishShape }),
1068
+ zod.z.strictObject({ registry: zod.z.literal("composer"), ...commonPublishShape })
1069
+ ]);
1070
+ var reviewersSchema = zod.z.strictObject({
1071
+ teams: zod.z.array(nonEmptyStringSchema).optional(),
1072
+ users: zod.z.array(nonEmptyStringSchema).optional()
1073
+ });
1074
+ var githubOutputSchema = zod.z.strictObject({
1075
+ repository: nonEmptyStringSchema,
1076
+ host: nonEmptyStringSchema.optional(),
1077
+ branch: nonEmptyStringSchema.optional(),
1078
+ mode: zod.z.enum(["release", "pull-request", "push"]).optional(),
1079
+ reviewers: reviewersSchema.optional(),
1080
+ privateRepository: zod.z.boolean().optional()
1081
+ });
1082
+ var filesOutputSchema = zod.z.strictObject({
1083
+ delivery: zod.z.literal("files"),
1084
+ path: nonEmptyStringSchema.optional(),
1085
+ publish: sdkConfigV1PublishConfigSchema.optional()
1086
+ });
1087
+ var zipOutputSchema = zod.z.strictObject({
1088
+ delivery: zod.z.literal("zip"),
1089
+ fileName: nonEmptyStringSchema.optional(),
1090
+ publish: sdkConfigV1PublishConfigSchema.optional()
1091
+ });
1092
+ var githubDeliverySchema = zod.z.strictObject({
1093
+ delivery: zod.z.literal("github"),
1094
+ github: githubOutputSchema,
1095
+ publish: sdkConfigV1PublishConfigSchema.optional()
1096
+ });
1097
+ var sdkConfigV1OutputConfigSchema = zod.z.discriminatedUnion(
1098
+ "delivery",
1099
+ [filesOutputSchema, zipOutputSchema, githubDeliverySchema],
1100
+ { error: 'output.delivery must be one of "files", "zip", or "github"' }
1101
+ );
1102
+
1103
+ // src/sdk-config/v1/package.ts
1104
+ var sdkConfigV1DependencySchema = dependencySchema;
1105
+ var sdkConfigV1PackageConfigSchema = packageConfigSchema;
303
1106
  var cliGenerationConfigSchema = zod.z.strictObject({
304
1107
  paginationParameters: zod.z.array(nonEmptyStringSchema).optional(),
305
1108
  skills: zod.z.boolean().optional()
@@ -309,10 +1112,15 @@ var csharpGenerationConfigSchema = zod.z.strictObject({
309
1112
  simplifyObjectDictionaries: zod.z.boolean().optional(),
310
1113
  explicitNamespaces: zod.z.boolean().optional(),
311
1114
  rootNamespaceForCoreClasses: zod.z.boolean().optional(),
312
- includeExceptionHandler: zod.z.boolean().optional()
1115
+ includeExceptionHandler: zod.z.boolean().optional(),
1116
+ experimentalExplicitNullableOptional: zod.z.boolean().optional()
313
1117
  });
314
1118
  var goGenerationConfigSchema = zod.z.strictObject({
315
1119
  legacyComplexModels: zod.z.boolean().optional(),
1120
+ /** Uppercase common initialisms in generated names (`UserID` rather than `UserId`). */
1121
+ smartCasing: zod.z.boolean().optional(),
1122
+ /** Overrides the fern root-client constructor independently from the client type name. */
1123
+ clientConstructorName: nonEmptyStringSchema.optional(),
316
1124
  unionVersion: zod.z.enum(["v0", "v1"]).optional(),
317
1125
  includeLegacyClientOptions: zod.z.boolean().optional()
318
1126
  });
@@ -322,15 +1130,17 @@ var jvmGenerationConfigSchema = zod.z.strictObject({
322
1130
  collapseOptionalNullable: zod.z.boolean().optional(),
323
1131
  gradleDistributionUrl: zod.z.string().min(1).optional(),
324
1132
  gradlePluginManagement: zod.z.string().optional(),
325
- gradleCentralDependencyManagement: zod.z.boolean().optional()
1133
+ gradleCentralDependencyManagement: zod.z.boolean().optional(),
1134
+ /** Selects co-located async methods or a separate async client surface. */
1135
+ asyncStyle: zod.z.enum(["dedicated-client", "twin-methods"]).optional()
326
1136
  });
327
1137
 
328
- // src/sdk-config-ir/v1/language/java.ts
1138
+ // src/sdk-config-domain/v1/language/java.ts
329
1139
  var javaGenerationConfigSchema = jvmGenerationConfigSchema.extend({
330
1140
  includeKotlinSnippets: zod.z.boolean().optional()
331
1141
  });
332
1142
 
333
- // src/sdk-config-ir/v1/language/kotlin.ts
1143
+ // src/sdk-config-domain/v1/language/kotlin.ts
334
1144
  var kotlinGenerationConfigSchema = jvmGenerationConfigSchema;
335
1145
  var compilerOptionsSchema = zod.z.strictObject({
336
1146
  target: nonEmptyStringSchema.optional(),
@@ -362,8 +1172,32 @@ var typescriptGenerationConfigSchema = zod.z.strictObject({
362
1172
  scripts: zod.z.array(packageScriptSchema).optional()
363
1173
  });
364
1174
 
365
- // src/sdk-config-ir/v1/language/mcp.ts
366
- var mcpGenerationConfigSchema = typescriptGenerationConfigSchema;
1175
+ // src/sdk-config-domain/v1/language/mcp.ts
1176
+ var mcpAvailabilityStatuses = [
1177
+ "IN_DEVELOPMENT",
1178
+ "PRE_RELEASE",
1179
+ "GENERAL_AVAILABILITY",
1180
+ "DEPRECATED",
1181
+ "ALPHA",
1182
+ "BETA",
1183
+ "PREVIEW",
1184
+ "LEGACY"
1185
+ ];
1186
+ var mcpToolFilterSchema = zod.z.strictObject({
1187
+ include: zod.z.array(nonEmptyStringSchema).optional(),
1188
+ exclude: zod.z.array(nonEmptyStringSchema).optional()
1189
+ });
1190
+ var mcpToolsetNameSchema = nonEmptyStringSchema.refine(
1191
+ (name) => name !== "default" && /^[a-z0-9-]+$/.test(name),
1192
+ 'toolset names must match [a-z0-9-]+ and cannot be "default"'
1193
+ );
1194
+ var mcpGenerationConfigSchema = typescriptGenerationConfigSchema.extend({
1195
+ serverName: nonEmptyStringSchema.optional(),
1196
+ serverDescription: nonEmptyStringSchema.optional(),
1197
+ excludeAvailability: zod.z.array(zod.z.enum(mcpAvailabilityStatuses)).optional(),
1198
+ tools: mcpToolFilterSchema.optional(),
1199
+ toolsets: zod.z.record(mcpToolsetNameSchema, mcpToolFilterSchema).optional()
1200
+ });
367
1201
  var phpGenerationConfigSchema = zod.z.strictObject({
368
1202
  propertyAccess: zod.z.enum(["public", "private"]).optional(),
369
1203
  generateClientInterfaces: zod.z.boolean().optional()
@@ -404,126 +1238,1002 @@ var rustGenerationConfigSchema = zod.z.strictObject({
404
1238
  defaultFeatures: zod.z.array(nonEmptyStringSchema).optional()
405
1239
  });
406
1240
  var swiftGenerationConfigSchema = zod.z.strictObject({
407
- moduleName: nonEmptyStringSchema.optional()
1241
+ moduleName: nonEmptyStringSchema.optional(),
1242
+ nullableAsOptional: zod.z.boolean().optional()
408
1243
  });
409
- var goModulePathSchema = nonEmptyStringSchema.regex(
410
- /^(?!.*(?:^|\/)\.{1,2}(?:\/|$))[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)+$/,
411
- "Go module path must be a slash-delimited path using letters, numbers, dots, dashes, underscores, or tildes"
412
- );
413
- var composerPackageNameSchema = nonEmptyStringSchema.regex(
414
- /^[a-z0-9]([_.-]?[a-z0-9]+)*\/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$/,
415
- 'Composer package name must be a lowercase "vendor/package" name'
416
- );
417
- var authorSchema = zod.z.strictObject({
418
- name: nonEmptyStringSchema,
419
- email: zod.z.email().optional()
1244
+ var planModifierSourceSchema = zod.z.discriminatedUnion("enabled", [
1245
+ zod.z.strictObject({ enabled: zod.z.literal(true), sourceDir: nonEmptyStringSchema }),
1246
+ zod.z.strictObject({ enabled: zod.z.literal(false) })
1247
+ ]);
1248
+ var planModifiersSchema = zod.z.strictObject({
1249
+ resources: planModifierSourceSchema,
1250
+ attributes: planModifierSourceSchema
420
1251
  });
421
- var developerSchema = zod.z.strictObject({
422
- name: nonEmptyStringSchema,
423
- email: zod.z.email().optional(),
424
- organization: nonEmptyStringSchema.optional(),
425
- organizationUrl: nonEmptyStringSchema.optional()
1252
+ var providerSchemaSchema = zod.z.strictObject({
1253
+ addressKey: nonEmptyStringSchema,
1254
+ authTokenKey: nonEmptyStringSchema
426
1255
  });
427
- var licenseSchema = zod.z.strictObject({
428
- type: nonEmptyStringSchema,
429
- name: nonEmptyStringSchema.optional(),
430
- url: nonEmptyStringSchema.optional(),
431
- path: nonEmptyStringSchema.optional()
1256
+ var terraformGenerationConfigSchema = zod.z.strictObject({
1257
+ providerName: nonEmptyStringSchema.optional(),
1258
+ providerVersion: nonEmptyStringSchema.optional(),
1259
+ providerModulePath: goModulePathSchema.optional(),
1260
+ mockAcceptance: zod.z.boolean().optional(),
1261
+ hideComputedDiff: zod.z.boolean().optional(),
1262
+ providerSchema: providerSchemaSchema.optional(),
1263
+ planModifiers: planModifiersSchema.optional()
1264
+ });
1265
+
1266
+ // src/sdk-config/v1/target.ts
1267
+ var targetOverrideShape = {
1268
+ generatorVersion: exactSemverSchema.optional(),
1269
+ sdkName: nonEmptyStringSchema.optional(),
1270
+ sdkVersion: nonEmptyStringSchema.optional(),
1271
+ package: sdkConfigV1PackageConfigSchema.optional(),
1272
+ output: sdkConfigV1OutputConfigSchema.optional()
1273
+ };
1274
+ var sdkConfigV1TargetSchema = zod.z.discriminatedUnion("language", [
1275
+ zod.z.strictObject({
1276
+ language: zod.z.literal("typescript"),
1277
+ generation: typescriptGenerationConfigSchema.optional(),
1278
+ ...targetOverrideShape
1279
+ }),
1280
+ zod.z.strictObject({
1281
+ language: zod.z.literal("python"),
1282
+ generation: pythonGenerationConfigSchema.optional(),
1283
+ ...targetOverrideShape
1284
+ }),
1285
+ zod.z.strictObject({
1286
+ language: zod.z.literal("java"),
1287
+ generation: javaGenerationConfigSchema.optional(),
1288
+ ...targetOverrideShape
1289
+ }),
1290
+ zod.z.strictObject({
1291
+ language: zod.z.literal("kotlin"),
1292
+ generation: kotlinGenerationConfigSchema.optional(),
1293
+ ...targetOverrideShape
1294
+ }),
1295
+ zod.z.strictObject({
1296
+ language: zod.z.literal("go"),
1297
+ generation: goGenerationConfigSchema.optional(),
1298
+ ...targetOverrideShape
1299
+ }),
1300
+ zod.z.strictObject({
1301
+ language: zod.z.literal("csharp"),
1302
+ generation: csharpGenerationConfigSchema.optional(),
1303
+ ...targetOverrideShape
1304
+ }),
1305
+ zod.z.strictObject({
1306
+ language: zod.z.literal("php"),
1307
+ generation: phpGenerationConfigSchema.optional(),
1308
+ ...targetOverrideShape
1309
+ }),
1310
+ zod.z.strictObject({
1311
+ language: zod.z.literal("ruby"),
1312
+ generation: rubyGenerationConfigSchema.optional(),
1313
+ ...targetOverrideShape
1314
+ }),
1315
+ zod.z.strictObject({
1316
+ language: zod.z.literal("rust"),
1317
+ generation: rustGenerationConfigSchema.optional(),
1318
+ ...targetOverrideShape
1319
+ }),
1320
+ zod.z.strictObject({
1321
+ language: zod.z.literal("swift"),
1322
+ generation: swiftGenerationConfigSchema.optional(),
1323
+ ...targetOverrideShape
1324
+ }),
1325
+ zod.z.strictObject({
1326
+ language: zod.z.literal("cli"),
1327
+ generation: cliGenerationConfigSchema.optional(),
1328
+ ...targetOverrideShape
1329
+ }),
1330
+ zod.z.strictObject({
1331
+ language: zod.z.literal("mcp"),
1332
+ generation: mcpGenerationConfigSchema.optional(),
1333
+ ...targetOverrideShape
1334
+ }),
1335
+ zod.z.strictObject({
1336
+ language: zod.z.literal("terraform"),
1337
+ generation: terraformGenerationConfigSchema.optional(),
1338
+ ...targetOverrideShape
1339
+ })
1340
+ ]);
1341
+
1342
+ // src/sdk-config/v1/sdk-config-v1.ts
1343
+ var SDK_CONFIG_V1_SCHEMA_VERSION = "sdk-config/v1";
1344
+ var publishRegistryLanguages = {
1345
+ npm: ["typescript", "mcp"],
1346
+ pypi: ["python"],
1347
+ maven: ["java", "kotlin"],
1348
+ nuget: ["csharp"],
1349
+ rubygems: ["ruby"],
1350
+ crates: ["rust"],
1351
+ go: ["go"],
1352
+ composer: ["php"]
1353
+ };
1354
+ var packageNameRegistries = /* @__PURE__ */ new Set([
1355
+ "npm",
1356
+ "pypi",
1357
+ "nuget",
1358
+ "rubygems",
1359
+ "crates",
1360
+ "composer"
1361
+ ]);
1362
+ function validatePublishingIdentity(packageConfig, registry, targetIndex, context) {
1363
+ const pathPrefix = ["targets", targetIndex, "package"];
1364
+ if (packageNameRegistries.has(registry) && !packageConfig.packageName) {
1365
+ context.addIssue({
1366
+ code: "custom",
1367
+ message: `packageName is required when publishing to "${registry}"`,
1368
+ path: [...pathPrefix, "packageName"]
1369
+ });
1370
+ }
1371
+ if (registry === "composer" && packageConfig.packageName) {
1372
+ const result = composerPackageNameSchema.safeParse(packageConfig.packageName);
1373
+ if (!result.success) {
1374
+ context.addIssue({
1375
+ code: "custom",
1376
+ message: result.error.issues[0]?.message ?? "Invalid Composer package name",
1377
+ path: [...pathPrefix, "packageName"]
1378
+ });
1379
+ }
1380
+ }
1381
+ if (registry === "go" && !packageConfig.modulePath) {
1382
+ context.addIssue({
1383
+ code: "custom",
1384
+ message: "modulePath is required when publishing a Go module",
1385
+ path: [...pathPrefix, "modulePath"]
1386
+ });
1387
+ }
1388
+ if (registry === "maven") {
1389
+ ["groupId", "artifactId"].forEach((field) => {
1390
+ if (!packageConfig[field]) {
1391
+ context.addIssue({
1392
+ code: "custom",
1393
+ message: `${field} is required when publishing to Maven`,
1394
+ path: [...pathPrefix, field]
1395
+ });
1396
+ }
1397
+ });
1398
+ }
1399
+ }
1400
+ function validateTargetPublishing(target, targetIndex, globalPackage, globalOutput, context) {
1401
+ const output = target.output ?? globalOutput;
1402
+ if (!output.publish) {
1403
+ return;
1404
+ }
1405
+ const registry = output.publish.registry;
1406
+ if (!publishRegistryLanguages[registry].some((language) => language === target.language)) {
1407
+ context.addIssue({
1408
+ code: "custom",
1409
+ message: `registry "${registry}" is not supported for target language "${target.language}"`,
1410
+ path: ["targets", targetIndex, target.output ? "output" : "language"]
1411
+ });
1412
+ return;
1413
+ }
1414
+ validatePublishingIdentity(
1415
+ { ...globalPackage, ...target.package },
1416
+ registry,
1417
+ targetIndex,
1418
+ context
1419
+ );
1420
+ }
1421
+ var sdkConfigV1Schema = zod.z.strictObject({
1422
+ schemaVersion: zod.z.literal(SDK_CONFIG_V1_SCHEMA_VERSION),
1423
+ sdkName: nonEmptyStringSchema,
1424
+ sdkVersion: nonEmptyStringSchema.default("1.0.0"),
1425
+ apiVersion: nonEmptyStringSchema.optional(),
1426
+ api: sdkConfigV1ApiConfigSchema,
1427
+ client: sdkConfigV1ClientConfigSchema,
1428
+ package: sdkConfigV1PackageConfigSchema,
1429
+ output: sdkConfigV1OutputConfigSchema,
1430
+ docs: sdkConfigV1DocsConfigSchema,
1431
+ generation: sdkConfigV1GenerationConfigSchema,
1432
+ targets: zod.z.array(sdkConfigV1TargetSchema).min(1)
1433
+ }).superRefine(({ output, package: globalPackage, targets }, context) => {
1434
+ const configuredLanguages = /* @__PURE__ */ new Set();
1435
+ targets.forEach((target, targetIndex) => {
1436
+ if (configuredLanguages.has(target.language)) {
1437
+ context.addIssue({
1438
+ code: "custom",
1439
+ message: `target language "${target.language}" must be unique`,
1440
+ path: ["targets", targetIndex, "language"]
1441
+ });
1442
+ }
1443
+ configuredLanguages.add(target.language);
1444
+ validateTargetPublishing(target, targetIndex, globalPackage, output, context);
1445
+ });
432
1446
  });
433
- var dependencySourceSchema = zod.z.discriminatedUnion("type", [
434
- zod.z.strictObject({
435
- type: zod.z.literal("registry"),
436
- registry: nonEmptyStringSchema.optional()
437
- }),
438
- zod.z.strictObject({
439
- type: zod.z.literal("git"),
440
- url: nonEmptyStringSchema,
441
- ref: nonEmptyStringSchema.optional(),
442
- subdirectory: nonEmptyStringSchema.optional()
443
- }),
444
- zod.z.strictObject({
445
- type: zod.z.literal("path"),
446
- path: nonEmptyStringSchema
447
- })
448
- ]);
449
- var dependencySchema = zod.z.strictObject({
450
- name: nonEmptyStringSchema,
451
- version: nonEmptyStringSchema.optional(),
452
- source: dependencySourceSchema.optional(),
453
- packageName: nonEmptyStringSchema.optional(),
454
- features: zod.z.array(nonEmptyStringSchema).optional(),
455
- extras: zod.z.array(nonEmptyStringSchema).optional(),
456
- optional: zod.z.boolean().optional(),
457
- defaultFeatures: zod.z.boolean().optional(),
458
- environmentMarker: nonEmptyStringSchema.optional()
459
- }).refine(({ source, version }) => source !== void 0 || version !== void 0, {
460
- message: "dependency must define a version or a source"
1447
+ function parseSdkConfigV1(value) {
1448
+ return sdkConfigV1Schema.parse(value);
1449
+ }
1450
+
1451
+ // src/sdk-config/v1/fern-config-mapper.ts
1452
+ var generatorLanguages = {
1453
+ "fernapi/fern-typescript": "typescript",
1454
+ "fernapi/fern-typescript-sdk": "typescript",
1455
+ "fernapi/fern-typescript-node-sdk": "typescript",
1456
+ "fernapi/fern-typescript-browser-sdk": "typescript",
1457
+ "fernapi/fern-python-sdk": "python",
1458
+ "fernapi/fern-java-sdk": "java",
1459
+ "fernapi/fern-kotlin-sdk": "kotlin",
1460
+ "fernapi/fern-go-sdk": "go",
1461
+ "fernapi/fern-csharp-sdk": "csharp",
1462
+ "fernapi/fern-php-sdk": "php",
1463
+ "fernapi/fern-ruby-sdk": "ruby",
1464
+ "fernapi/fern-ruby-sdk-v2": "ruby",
1465
+ "fernapi/fern-rust-sdk": "rust",
1466
+ "fernapi/fern-swift-sdk": "swift",
1467
+ "fernapi/fern-cli": "cli",
1468
+ "fernapi/fern-cli-generator": "cli",
1469
+ "fernapi/fern-mcp-server": "mcp"
1470
+ };
1471
+ function mapFernConfigToSdkConfigV1(input) {
1472
+ if (input.group.generators.length === 0) {
1473
+ fail(
1474
+ "FERN_GENERATORS_REQUIRED",
1475
+ ["group", "generators"],
1476
+ "Fern generator group must contain at least one generator",
1477
+ "Select a Fern generator group containing at least one SDK generator."
1478
+ );
1479
+ }
1480
+ const mapped = input.group.generators.map((generator, index) => {
1481
+ const language = resolveLanguage(generator, index);
1482
+ const invocation = mapInvocation(generator, language, index);
1483
+ const outputMapping = generator.output ? { output: generator.output, unsupportedFields: [] } : mapOutput(generator, language, index);
1484
+ return {
1485
+ generator,
1486
+ language,
1487
+ invocation,
1488
+ ...outputMapping
1489
+ };
1490
+ });
1491
+ requireUniqueLanguages(mapped.map(({ language }) => language));
1492
+ const client = requireSharedBlock(
1493
+ mapped.map(({ invocation }) => invocation.client),
1494
+ "client",
1495
+ (value) => sdkConfigV1ClientConfigSchema.parse(value)
1496
+ );
1497
+ const docs = requireSharedBlock(
1498
+ mapped.map(({ invocation }) => invocation.docs),
1499
+ "docs",
1500
+ (value) => sdkConfigV1DocsConfigSchema.parse(value)
1501
+ );
1502
+ const generation = requireSharedBlock(
1503
+ mapped.map(({ invocation }) => invocation.generation),
1504
+ "generation",
1505
+ (value) => sdkConfigV1GenerationConfigSchema.parse(value)
1506
+ );
1507
+ const api = { ...input.api ?? {} };
1508
+ delete api.audiences;
1509
+ if (input.group.audiences.type === "select") {
1510
+ api.audiences = [...input.group.audiences.audiences];
1511
+ }
1512
+ const targets = mapped.map(
1513
+ ({ generator, invocation, language, output, package: outputPackage }, index) => {
1514
+ const target = {
1515
+ language,
1516
+ output,
1517
+ ...optional("sdkName", generator.sdkName),
1518
+ ...optional("sdkVersion", generator.sdkVersion)
1519
+ };
1520
+ if (Object.keys(invocation.package).length > 0 || outputPackage || generator.package) {
1521
+ target.package = { ...invocation.package, ...outputPackage, ...generator.package };
1522
+ }
1523
+ if (Object.keys(invocation.targetGeneration).length > 0) {
1524
+ target.generation = invocation.targetGeneration;
1525
+ }
1526
+ if (generator.version) {
1527
+ if (exactSemverSchema.safeParse(generator.version).success) {
1528
+ target.generatorVersion = generator.version;
1529
+ } else {
1530
+ invocation.unsupportedFields.push({
1531
+ code: "FERN_GENERATOR_VERSION_NOT_EXACT",
1532
+ severity: "warning",
1533
+ path: ["group", "generators", index, "version"],
1534
+ reason: "SDK Config requires an exact generator semantic version",
1535
+ sdkConfigPath: ["targets", index, "generatorVersion"],
1536
+ suggestedAction: "Resolve the Fern generator tag to an exact semantic version and set target.generatorVersion manually, or leave it omitted."
1537
+ });
1538
+ }
1539
+ }
1540
+ return target;
1541
+ }
1542
+ );
1543
+ const parsed = sdkConfigV1Schema.safeParse({
1544
+ schemaVersion: "sdk-config/v1",
1545
+ sdkName: input.apiName,
1546
+ ...optional("sdkVersion", input.sdkVersion),
1547
+ ...optional("apiVersion", input.apiVersion),
1548
+ api,
1549
+ client,
1550
+ package: {},
1551
+ output: mapped[0].output,
1552
+ docs,
1553
+ generation,
1554
+ targets
1555
+ });
1556
+ if (!parsed.success) {
1557
+ throw new FernConfigMappingError(
1558
+ parsed.error.issues.map((issue) => {
1559
+ const path = issue.path.map(
1560
+ (part) => typeof part === "symbol" ? part.description ?? part.toString() : part
1561
+ );
1562
+ return {
1563
+ code: "SDK_CONFIG_VALIDATION_FAILED",
1564
+ severity: "error",
1565
+ path: ["mappedSdkConfig", ...path],
1566
+ reason: issue.message,
1567
+ sdkConfigPath: path,
1568
+ suggestedAction: `Set ${path.join(".")} manually to a valid SDK Config v1 value.`
1569
+ };
1570
+ })
1571
+ );
1572
+ }
1573
+ return {
1574
+ sdkConfig: parsed.data,
1575
+ unsupportedFields: mapped.flatMap(({ invocation, unsupportedFields }) => [
1576
+ ...invocation.unsupportedFields,
1577
+ ...unsupportedFields
1578
+ ])
1579
+ };
1580
+ }
1581
+ function resolveLanguage(generator, index) {
1582
+ const language = generator.sdkLanguage ?? generatorLanguages[generator.name];
1583
+ if (!language || !isFernLanguage(language)) {
1584
+ fail(
1585
+ "FERN_SDK_LANGUAGE_REQUIRED",
1586
+ ["group", "generators", index, "name"],
1587
+ `Cannot determine an SDK language for Fern generator ${generator.name}`,
1588
+ "Set sdkLanguage explicitly if this custom generator produces one of the SDK Config v1 target languages.",
1589
+ ["targets", index, "language"]
1590
+ );
1591
+ }
1592
+ return language;
1593
+ }
1594
+ function isFernLanguage(value) {
1595
+ return [
1596
+ "typescript",
1597
+ "python",
1598
+ "java",
1599
+ "kotlin",
1600
+ "go",
1601
+ "csharp",
1602
+ "php",
1603
+ "ruby",
1604
+ "rust",
1605
+ "swift",
1606
+ "cli",
1607
+ "mcp",
1608
+ "terraform"
1609
+ ].includes(value);
1610
+ }
1611
+ function requireUniqueLanguages(languages) {
1612
+ const seen = /* @__PURE__ */ new Set();
1613
+ for (const language of languages) {
1614
+ if (seen.has(language)) {
1615
+ fail(
1616
+ "FERN_DUPLICATE_TARGET_LANGUAGE",
1617
+ ["group", "generators"],
1618
+ `SDK Config v1 cannot represent multiple Fern generators for language "${language}"`,
1619
+ "Create a separate SDK Config document for each generator that targets the same language.",
1620
+ ["targets"]
1621
+ );
1622
+ }
1623
+ seen.add(language);
1624
+ }
1625
+ }
1626
+ function requireSharedBlock(values, name, normalize) {
1627
+ const first = normalize(values[0]);
1628
+ const serialized = stableJson(first);
1629
+ if (values.some((value) => stableJson(normalize(value)) !== serialized)) {
1630
+ fail(
1631
+ "FERN_TARGET_SPECIFIC_SHARED_CONFIG",
1632
+ ["group", "generators"],
1633
+ `SDK Config v1 cannot represent target-specific Fern ${name} configuration`,
1634
+ `Choose one shared ${name} configuration manually or create separate SDK Config documents for the differing targets.`,
1635
+ [name]
1636
+ );
1637
+ }
1638
+ return first;
1639
+ }
1640
+ function mapInvocation(generator, language, index) {
1641
+ const prefix = ["group", "generators", index];
1642
+ const state = { consumedPaths: /* @__PURE__ */ new Set() };
1643
+ const config = isObject(generator.config) ? generator.config : {};
1644
+ const client = {};
1645
+ const generation = {};
1646
+ const packageConfig = {};
1647
+ mapCommonConfig(config, state, client, generation, packageConfig, [...prefix, "config"]);
1648
+ const targetGeneration = mapLanguageConfig(language, config, state, packageConfig, [
1649
+ ...prefix,
1650
+ "config"
1651
+ ]);
1652
+ mapPublishMetadata(generator.publishMetadata, packageConfig);
1653
+ if (language === "go" && generator.smartCasing !== void 0) {
1654
+ targetGeneration.smartCasing = generator.smartCasing;
1655
+ }
1656
+ if (generator.keywords?.length) {
1657
+ generation.reservedKeywords = [...generator.keywords];
1658
+ }
1659
+ const settings = isObject(generator.settings) ? generator.settings : void 0;
1660
+ if (settings) {
1661
+ const inlinePathParameters = takeBoolean(settings, ["inlinePathParameters"], state, [
1662
+ ...prefix,
1663
+ "settings"
1664
+ ]);
1665
+ if (inlinePathParameters !== void 0 && client.pathParameterStyle === void 0) {
1666
+ client.pathParameterStyle = inlinePathParameters ? "inline" : "wrapped";
1667
+ }
1668
+ }
1669
+ const docs = mapReadme(generator.readme, state, [...prefix, "readme"]);
1670
+ const unsupportedFields = [
1671
+ ...collectUnsupported(config, [...prefix, "config"], state),
1672
+ ...settings ? collectUnsupported(settings, [...prefix, "settings"], state) : [],
1673
+ ...isObject(generator.readme) ? collectUnsupported(generator.readme, [...prefix, "readme"], state) : [],
1674
+ ...unsupportedResolvedFields(generator, index, language)
1675
+ ];
1676
+ return { client, docs, generation, package: packageConfig, targetGeneration, unsupportedFields };
1677
+ }
1678
+ function unsupportedResolvedFields(generator, index, language) {
1679
+ const values = [
1680
+ ["automation", isDefaultAutomation(generator.automation) ? void 0 : generator.automation],
1681
+ ["containerImage", generator.containerImage],
1682
+ ["irVersionOverride", generator.irVersionOverride],
1683
+ ["idempotencyKeyGenerationConfig", generator.idempotencyKeyGenerationConfig],
1684
+ ["absolutePathToLocalSnippets", generator.absolutePathToLocalSnippets],
1685
+ [
1686
+ "smartCasingDigitWordBoundary",
1687
+ generator.smartCasingDigitWordBoundary === false ? void 0 : generator.smartCasingDigitWordBoundary
1688
+ ],
1689
+ [
1690
+ "disableExamples",
1691
+ generator.disableExamples === false ? void 0 : generator.disableExamples
1692
+ ],
1693
+ ["apiOverride", generator.apiOverride],
1694
+ ...language === "go" || generator.smartCasing === true ? [] : [["smartCasing", generator.smartCasing]]
1695
+ ];
1696
+ return values.flatMap(([field, value]) => {
1697
+ if (value === void 0) return [];
1698
+ const guidance = resolvedFieldGuidance(field);
1699
+ return [
1700
+ {
1701
+ code: "FERN_RESOLVED_FIELD_UNSUPPORTED",
1702
+ severity: "warning",
1703
+ path: ["group", "generators", index, field],
1704
+ reason: "Resolved Fern field is not represented by SDK Config v1",
1705
+ ...optional("sdkConfigPath", guidance.sdkConfigPath),
1706
+ suggestedAction: guidance.suggestedAction
1707
+ }
1708
+ ];
1709
+ });
1710
+ }
1711
+ function resolvedFieldGuidance(field) {
1712
+ if (field === "absolutePathToLocalSnippets") {
1713
+ return {
1714
+ sdkConfigPath: ["docs", "snippets", "outputPath"],
1715
+ suggestedAction: "Choose a portable relative snippet path and set docs.snippets.outputPath manually."
1716
+ };
1717
+ }
1718
+ if (field === "idempotencyKeyGenerationConfig") {
1719
+ return {
1720
+ suggestedAction: "Preserve this orchestration setting outside SDK Config; public v1 has no idempotency-generation field."
1721
+ };
1722
+ }
1723
+ return {
1724
+ suggestedAction: "Review this Fern setting and preserve it outside SDK Config, or set an equivalent SDK Config field manually if one is introduced."
1725
+ };
1726
+ }
1727
+ function isDefaultAutomation(value) {
1728
+ return isObject(value) && value.generate === true && value.upgrade === true && value.preview === true && value.verify === true;
1729
+ }
1730
+ function mapCommonConfig(config, state, client, generation, packageConfig, basePath) {
1731
+ const inlinePath = takeBoolean(config, ["inlinePathParameters"], state, basePath);
1732
+ const inlineFile = takeBoolean(config, ["inlineFileProperties"], state, basePath);
1733
+ const inlineRequest = takeBoolean(config, ["inlineRequestParams"], state, basePath);
1734
+ if (inlinePath !== void 0) client.pathParameterStyle = inlinePath ? "inline" : "wrapped";
1735
+ if (inlineFile !== void 0) client.filePropertyStyle = inlineFile ? "inline" : "wrapped";
1736
+ if (inlineRequest !== void 0)
1737
+ client.requestParameterStyle = inlineRequest ? "inline" : "wrapped";
1738
+ const timeoutMs = takeTimeoutMs(config, state, basePath);
1739
+ if (timeoutMs !== void 0) client.timeoutMs = timeoutMs;
1740
+ const skipValidation = takeBoolean(
1741
+ config,
1742
+ ["skipResponseValidation", "skipValidation"],
1743
+ state,
1744
+ basePath
1745
+ );
1746
+ if (skipValidation !== void 0) client.responseValidation = !skipValidation;
1747
+ const useDefaults = takeBoolean(config, ["useDefaultRequestParameterValues"], state, basePath);
1748
+ if (useDefaults !== void 0) client.useDefaultRequestParameterValues = useDefaults;
1749
+ const respectOptionalBody = takeBoolean(config, ["respectOptionalRequestBody"], state, basePath);
1750
+ if (respectOptionalBody !== void 0) client.respectOptionalRequestBody = respectOptionalBody;
1751
+ const maxRetries = takeNumber(config, ["maxRetries"], state, basePath);
1752
+ const statusCodeProfile = takeEnum(
1753
+ config,
1754
+ ["retryStatusCodes"],
1755
+ ["legacy", "recommended"],
1756
+ state,
1757
+ basePath
1758
+ );
1759
+ if (maxRetries !== void 0 || statusCodeProfile !== void 0) {
1760
+ client.retry = {
1761
+ ...maxRetries === void 0 ? {} : { maxAttempts: maxRetries + 1 },
1762
+ ...optional("statusCodeProfile", statusCodeProfile)
1763
+ };
1764
+ }
1765
+ const naming = compact({
1766
+ pagerName: takeString(
1767
+ config,
1768
+ ["customPagerName", "customPagerClassname", "customPagerClassName"],
1769
+ state,
1770
+ basePath
1771
+ ),
1772
+ clientName: takeString(config, ["clientName", "clientClassName"], state, basePath),
1773
+ exportedClientName: takeString(
1774
+ config,
1775
+ ["exportedClientName", "exportedClientClassName"],
1776
+ state,
1777
+ basePath
1778
+ ),
1779
+ environmentTypeName: takeString(
1780
+ config,
1781
+ ["environmentClassName", "environmentEnumName"],
1782
+ state,
1783
+ basePath
1784
+ ),
1785
+ apiErrorName: takeString(config, ["baseApiExceptionClassName"], state, basePath),
1786
+ baseErrorName: takeString(config, ["baseExceptionClassName"], state, basePath)
1787
+ });
1788
+ if (Object.keys(naming).length) generation.naming = naming;
1789
+ const wireTests = takeBoolean(config, ["enableWireTests", "generateWireTests"], state, basePath);
1790
+ if (wireTests !== void 0) generation.wireTests = { enabled: wireTests };
1791
+ const webSockets = takeBoolean(
1792
+ config,
1793
+ ["generateWebSocketClients", "shouldGenerateWebsocketClients", "enableWebsockets"],
1794
+ state,
1795
+ basePath
1796
+ );
1797
+ if (webSockets !== void 0) generation.webSockets = webSockets;
1798
+ const inlineTypes = takeBoolean(config, ["enableInlineTypes"], state, basePath);
1799
+ const omitUndefined = takeBoolean(config, ["omitUndefined"], state, basePath);
1800
+ const forwardEnums = takeBoolean(config, ["enableForwardCompatibleEnums"], state, basePath);
1801
+ const serialization = compact({
1802
+ inlineTypes,
1803
+ omitUndefined,
1804
+ enumRepresentation: forwardEnums === void 0 ? void 0 : forwardEnums ? "forward-compatible-enum" : "language-default"
1805
+ });
1806
+ if (Object.keys(serialization).length) generation.serialization = serialization;
1807
+ const namespace = takeString(config, ["namespace", "packagePrefix"], state, basePath);
1808
+ if (namespace !== void 0) packageConfig.namespace = namespace;
1809
+ const packagePath = takeString(config, ["packagePath"], state, basePath);
1810
+ if (packagePath !== void 0) generation.layout = { packagePath };
1811
+ mapDependencies(config, state, packageConfig, basePath);
1812
+ }
1813
+ function mapLanguageConfig(language, config, state, packageConfig, basePath) {
1814
+ switch (language) {
1815
+ case "typescript":
1816
+ return mapTypescript(config, state, packageConfig, basePath);
1817
+ case "mcp":
1818
+ return {
1819
+ ...mapTypescript(config, state, packageConfig, basePath),
1820
+ ...mapMcp(config, state, basePath)
1821
+ };
1822
+ case "python":
1823
+ return mapPython(config, state, packageConfig, basePath);
1824
+ case "java":
1825
+ case "kotlin":
1826
+ return mapJvm(language, config, state, packageConfig, basePath);
1827
+ case "go":
1828
+ return mapGo(config, state, packageConfig, basePath);
1829
+ case "csharp":
1830
+ return mapCsharp(config, state, packageConfig, basePath);
1831
+ case "php":
1832
+ return mapPhp(config, state, packageConfig, basePath);
1833
+ case "ruby":
1834
+ return mapRuby(config, state, packageConfig, basePath);
1835
+ case "rust":
1836
+ return mapRust(config, state, packageConfig, basePath);
1837
+ case "swift":
1838
+ return compact({ moduleName: takeString(config, ["moduleName"], state, basePath) });
1839
+ case "cli":
1840
+ return mapCli(config, state, packageConfig, basePath);
1841
+ case "terraform":
1842
+ return mapTerraform(config, state, packageConfig, basePath);
1843
+ }
1844
+ }
1845
+ function mapTypescript(config, state, packageConfig, basePath) {
1846
+ const packageJson = takeObject(config, ["packageJson"], state, basePath);
1847
+ const packageName = packageJson ? takeString(packageJson.value, ["name"], state, packageJson.path) : void 0;
1848
+ if (packageName !== void 0) packageConfig.packageName = packageName;
1849
+ const serdeLayer = takeBoolean(config, ["serdeLayer"], state, basePath);
1850
+ const noSerdeLayer = takeBoolean(config, ["noSerdeLayer"], state, basePath);
1851
+ return compact({
1852
+ typescriptVersion: takeString(config, ["typescriptVersion"], state, basePath),
1853
+ zodVersion: takeString(config, ["zodVersion"], state, basePath),
1854
+ packageManager: takeEnum(config, ["packageManager"], ["pnpm", "yarn"], state, basePath),
1855
+ testFramework: takeEnum(config, ["testFramework"], ["jest", "vitest"], state, basePath),
1856
+ bundle: takeBoolean(config, ["bundle"], state, basePath),
1857
+ exportClassDefault: takeBoolean(config, ["exportClassDefault"], state, basePath),
1858
+ allowCustomFetcher: takeBoolean(config, ["allowCustomFetcher"], state, basePath),
1859
+ useBrandedStringAliases: takeBoolean(config, ["useBrandedStringAliases"], state, basePath),
1860
+ useLegacyExports: takeBoolean(config, ["useLegacyExports"], state, basePath),
1861
+ useBigInt: takeBoolean(config, ["useBigInt"], state, basePath),
1862
+ serdeLayer: serdeLayer ?? (noSerdeLayer === void 0 ? void 0 : !noSerdeLayer)
1863
+ });
1864
+ }
1865
+ function mapPython(config, state, packageConfig, basePath) {
1866
+ const moduleName = takeString(config, ["packageName"], state, basePath);
1867
+ const packageName = takeString(config, ["pypiPackageName"], state, basePath);
1868
+ if (moduleName !== void 0) packageConfig.moduleName = moduleName;
1869
+ if (packageName !== void 0) packageConfig.packageName = packageName;
1870
+ return compact({
1871
+ pythonVersion: takeString(config, ["pythonVersion", "pyprojectPythonVersion"], state, basePath),
1872
+ pydanticVersion: takeString(config, ["pydanticVersion"], state, basePath),
1873
+ alwaysInitializeOptionals: takeBoolean(config, ["alwaysInitializeOptionals"], state, basePath),
1874
+ useTypedDictRequests: takeBoolean(config, ["useTypedDictRequests"], state, basePath)
1875
+ });
1876
+ }
1877
+ function mapJvm(language, config, state, packageConfig, basePath) {
1878
+ const namespace = takeString(config, ["packageName", "packagePrefix"], state, basePath);
1879
+ const groupId = takeString(config, ["group", "groupId"], state, basePath);
1880
+ const artifactId = takeString(config, ["artifact", "artifactId"], state, basePath);
1881
+ if (namespace !== void 0) packageConfig.namespace = namespace;
1882
+ if (groupId !== void 0) packageConfig.groupId = groupId;
1883
+ if (artifactId !== void 0) packageConfig.artifactId = artifactId;
1884
+ return compact({
1885
+ packageLayout: takeEnum(config, ["packageLayout"], ["flat", "nested"], state, basePath),
1886
+ useLocalDateForDates: takeBoolean(config, ["useLocalDateForDates"], state, basePath),
1887
+ collapseOptionalNullable: takeBoolean(config, ["collapseOptionalNullable"], state, basePath),
1888
+ gradleDistributionUrl: takeString(config, ["gradleDistributionUrl"], state, basePath),
1889
+ gradlePluginManagement: takeString(config, ["gradlePluginManagement"], state, basePath),
1890
+ gradleCentralDependencyManagement: takeBoolean(
1891
+ config,
1892
+ ["gradleCentralDependencyManagement"],
1893
+ state,
1894
+ basePath
1895
+ ),
1896
+ asyncStyle: takeEnum(
1897
+ config,
1898
+ ["asyncStyle"],
1899
+ ["dedicated-client", "twin-methods"],
1900
+ state,
1901
+ basePath
1902
+ ),
1903
+ ...language === "java" ? {
1904
+ includeKotlinSnippets: takeBoolean(config, ["includeKotlinSnippets"], state, basePath)
1905
+ } : {}
1906
+ });
1907
+ }
1908
+ function mapGo(config, state, packageConfig, basePath) {
1909
+ const module = takeObject(config, ["module"], state, basePath);
1910
+ const modulePath = module ? takeGoModulePath(module.value, ["path"], state, module.path) : void 0;
1911
+ const packageName = takeString(config, ["packageName"], state, basePath);
1912
+ if (modulePath !== void 0) packageConfig.modulePath = modulePath;
1913
+ if (packageName !== void 0) packageConfig.packageName = packageName;
1914
+ return compact({
1915
+ legacyComplexModels: takeBoolean(config, ["legacyComplexModels"], state, basePath),
1916
+ unionVersion: takeEnum(config, ["union"], ["v0", "v1"], state, basePath),
1917
+ includeLegacyClientOptions: takeBoolean(
1918
+ config,
1919
+ ["includeLegacyClientOptions"],
1920
+ state,
1921
+ basePath
1922
+ ),
1923
+ clientConstructorName: takeString(config, ["clientConstructorName"], state, basePath)
1924
+ });
1925
+ }
1926
+ function mapCsharp(config, state, packageConfig, basePath) {
1927
+ const packageName = takeString(config, ["packageId"], state, basePath);
1928
+ if (packageName !== void 0) packageConfig.packageName = packageName;
1929
+ return compact({
1930
+ useOptionalWrapper: takeBoolean(config, ["useOptionalWrapper"], state, basePath),
1931
+ simplifyObjectDictionaries: takeBoolean(
1932
+ config,
1933
+ ["simplifyObjectDictionaries"],
1934
+ state,
1935
+ basePath
1936
+ ),
1937
+ explicitNamespaces: takeBoolean(config, ["explicitNamespaces"], state, basePath),
1938
+ rootNamespaceForCoreClasses: takeBoolean(
1939
+ config,
1940
+ ["rootNamespaceForCoreClasses"],
1941
+ state,
1942
+ basePath
1943
+ ),
1944
+ includeExceptionHandler: takeBoolean(config, ["includeExceptionHandler"], state, basePath),
1945
+ experimentalExplicitNullableOptional: takeBoolean(
1946
+ config,
1947
+ ["experimentalExplicitNullableOptional"],
1948
+ state,
1949
+ basePath
1950
+ )
1951
+ });
1952
+ }
1953
+ function mapPhp(config, state, packageConfig, basePath) {
1954
+ const packageName = takeString(config, ["packageName"], state, basePath);
1955
+ if (packageName !== void 0) packageConfig.packageName = packageName;
1956
+ return compact({
1957
+ propertyAccess: takeEnum(config, ["propertyAccess"], ["public", "private"], state, basePath),
1958
+ generateClientInterfaces: takeBoolean(config, ["generateClientInterfaces"], state, basePath)
1959
+ });
1960
+ }
1961
+ function mapRuby(config, state, packageConfig, basePath) {
1962
+ const moduleName = takeString(config, ["moduleName"], state, basePath);
1963
+ if (moduleName !== void 0) packageConfig.moduleName = moduleName;
1964
+ return compact({ requirePaths: takeStringArray(config, ["requirePaths"], state, basePath) });
1965
+ }
1966
+ function mapRust(config, state, packageConfig, basePath) {
1967
+ const packageName = takeString(config, ["crateName"], state, basePath);
1968
+ const repository = takeString(config, ["packageRepository"], state, basePath);
1969
+ const description = takeString(config, ["packageDescription"], state, basePath);
1970
+ const documentationUrl = takeString(config, ["packageDocumentation"], state, basePath);
1971
+ Object.assign(packageConfig, compact({ packageName, repository, description, documentationUrl }));
1972
+ return compact({
1973
+ dateTimeType: takeEnum(config, ["dateTimeType"], ["offset", "utc"], state, basePath),
1974
+ capitalizeInitialisms: takeBoolean(config, ["capitalizeInitialisms"], state, basePath),
1975
+ features: takeStringArrayRecord(config, ["features"], state, basePath),
1976
+ defaultFeatures: takeStringArray(config, ["defaultFeatures"], state, basePath)
1977
+ });
1978
+ }
1979
+ function mapCli(config, state, packageConfig, basePath) {
1980
+ const identity = takeObject(config, ["packageIdentity"], state, basePath);
1981
+ if (identity) {
1982
+ Object.assign(
1983
+ packageConfig,
1984
+ compact({
1985
+ packageName: takeString(identity.value, ["name"], state, identity.path),
1986
+ repository: takeString(identity.value, ["repository"], state, identity.path),
1987
+ description: takeString(identity.value, ["description"], state, identity.path)
1988
+ })
1989
+ );
1990
+ }
1991
+ return compact({
1992
+ paginationParameters: takeStringArray(config, ["paginationParameters"], state, basePath),
1993
+ skills: takeBoolean(config, ["skills"], state, basePath)
1994
+ });
1995
+ }
1996
+ function mapTerraform(config, state, packageConfig, basePath) {
1997
+ const providerModulePath = takeString(
1998
+ config,
1999
+ ["providerModulePath", "providerGoModuleName"],
2000
+ state,
2001
+ basePath
2002
+ );
2003
+ if (providerModulePath !== void 0) packageConfig.modulePath = providerModulePath;
2004
+ return compact({
2005
+ providerName: takeString(config, ["providerName"], state, basePath),
2006
+ providerVersion: takeString(config, ["providerVersion"], state, basePath),
2007
+ providerModulePath,
2008
+ mockAcceptance: takeBoolean(config, ["mockAcceptance"], state, basePath),
2009
+ hideComputedDiff: takeBoolean(config, ["hideComputedDiff"], state, basePath)
2010
+ });
2011
+ }
2012
+ function mapMcp(config, state, basePath) {
2013
+ return compact({
2014
+ serverName: takeString(config, ["serverName"], state, basePath),
2015
+ serverDescription: takeString(config, ["serverDescription"], state, basePath),
2016
+ excludeAvailability: takeEnumArray(
2017
+ config,
2018
+ ["excludeAvailability"],
2019
+ [
2020
+ "IN_DEVELOPMENT",
2021
+ "PRE_RELEASE",
2022
+ "GENERAL_AVAILABILITY",
2023
+ "DEPRECATED",
2024
+ "ALPHA",
2025
+ "BETA",
2026
+ "PREVIEW",
2027
+ "LEGACY"
2028
+ ],
2029
+ state,
2030
+ basePath
2031
+ ),
2032
+ tools: takeToolFilter(config, ["tools"], state, basePath),
2033
+ toolsets: takeToolsets(config, ["toolsets"], state, basePath)
2034
+ });
2035
+ }
2036
+ function mapReadme(value, state, basePath) {
2037
+ if (!isObject(value)) return {};
2038
+ const readme = compact({
2039
+ apiName: takeString(value, ["apiName"], state, basePath),
2040
+ introduction: takeString(value, ["introduction"], state, basePath),
2041
+ apiReferenceLink: takeString(value, ["apiReferenceLink"], state, basePath),
2042
+ bannerLink: takeString(value, ["bannerLink"], state, basePath),
2043
+ disabledSections: takeStringArray(value, ["disabledSections"], state, basePath),
2044
+ customSections: takeCustomSections(value, state, basePath),
2045
+ defaultEndpoint: takeReadmeEndpoint(value, ["defaultEndpoint"], state, basePath),
2046
+ features: takeReadmeFeatures(value, state, basePath)
2047
+ });
2048
+ return Object.keys(readme).length ? { readme } : {};
2049
+ }
2050
+ function mapPublishMetadata(value, packageConfig) {
2051
+ if (!isObject(value)) return;
2052
+ const publisherName = stringValue(value.publisherName);
2053
+ const publisherEmail = stringValue(value.publisherEmail);
2054
+ Object.assign(
2055
+ packageConfig,
2056
+ compact({
2057
+ description: stringValue(value.packageDescription),
2058
+ documentationUrl: stringValue(value.referenceUrl),
2059
+ authors: publisherName ? [{ name: publisherName, ...optional("email", publisherEmail) }] : void 0
2060
+ })
2061
+ );
2062
+ }
2063
+ function mapDependencies(config, state, packageConfig, basePath) {
2064
+ for (const field of [
2065
+ "extraDependencies",
2066
+ "extraDevDependencies",
2067
+ "extraPeerDependencies"
2068
+ ]) {
2069
+ const located = takeObject(config, [field], state, basePath);
2070
+ if (!located) continue;
2071
+ const dependencies = Object.entries(located.value).flatMap(
2072
+ ([name, dependency]) => mapDependency(name, dependency, state, [...located.path, name])
2073
+ );
2074
+ if (dependencies.length) packageConfig[field] = dependencies;
2075
+ }
2076
+ }
2077
+ function mapDependency(name, value, state, path) {
2078
+ if (typeof value === "string" && value) {
2079
+ consume(state, path);
2080
+ return [{ name, version: value }];
2081
+ }
2082
+ if (!isObject(value)) return [];
2083
+ const version = takeString(value, ["version"], state, path);
2084
+ const gitUrl = takeString(value, ["git"], state, path);
2085
+ const localPath = takeString(value, ["path"], state, path);
2086
+ const source = gitUrl ? {
2087
+ type: "git",
2088
+ url: gitUrl,
2089
+ ...optional("ref", takeString(value, ["ref"], state, path))
2090
+ } : localPath ? { type: "path", path: localPath } : void 0;
2091
+ if (!version && !source) return [];
2092
+ return [
2093
+ {
2094
+ name,
2095
+ ...optional("version", version),
2096
+ ...optional("source", source),
2097
+ ...optional("packageName", takeString(value, ["package"], state, path)),
2098
+ ...optional("features", takeStringArray(value, ["features"], state, path)),
2099
+ ...optional("extras", takeStringArray(value, ["extras"], state, path)),
2100
+ ...optional("optional", takeBoolean(value, ["optional"], state, path)),
2101
+ ...optional("defaultFeatures", takeBoolean(value, ["defaultFeatures"], state, path)),
2102
+ ...optional("environmentMarker", takeString(value, ["python"], state, path))
2103
+ }
2104
+ ];
2105
+ }
2106
+ function takeCustomSections(value, state, basePath) {
2107
+ const located = locate(value, ["customSections"], basePath);
2108
+ if (!located || !Array.isArray(located.value)) return void 0;
2109
+ const sections = located.value.flatMap(
2110
+ (section) => isObject(section) && section.language === void 0 && typeof section.title === "string" && typeof section.content === "string" ? [{ title: section.title, content: section.content }] : []
2111
+ );
2112
+ if (sections.length !== located.value.length) return void 0;
2113
+ consume(state, located.path);
2114
+ return sections;
2115
+ }
2116
+ function takeReadmeEndpoint(value, aliases, state, basePath) {
2117
+ const located = locate(value, aliases, basePath);
2118
+ if (!located) return void 0;
2119
+ const endpoint = parseReadmeEndpoint(located.value);
2120
+ if (endpoint) consume(state, located.path);
2121
+ return endpoint;
2122
+ }
2123
+ function takeReadmeFeatures(value, state, basePath) {
2124
+ const located = locate(value, ["features"], basePath);
2125
+ if (!located || !isObject(located.value)) return void 0;
2126
+ const features = {};
2127
+ for (const [name, endpoints] of Object.entries(located.value)) {
2128
+ if (!Array.isArray(endpoints)) return void 0;
2129
+ const parsed = endpoints.map(parseReadmeEndpoint);
2130
+ if (parsed.some((endpoint) => !endpoint)) return void 0;
2131
+ features[name] = parsed;
2132
+ }
2133
+ consume(state, located.path);
2134
+ return features;
2135
+ }
2136
+ function parseReadmeEndpoint(value) {
2137
+ if (typeof value === "string") {
2138
+ const match = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS|TRACE|CONNECT)\s+(\/\S*)$/.exec(
2139
+ value.trim()
2140
+ );
2141
+ return match ? { method: match[1], path: match[2] } : void 0;
2142
+ }
2143
+ if (!isObject(value) || typeof value.method !== "string" || typeof value.path !== "string") {
2144
+ return void 0;
2145
+ }
2146
+ const method = value.method.toUpperCase();
2147
+ if (!["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", "TRACE", "CONNECT"].includes(
2148
+ method
2149
+ )) {
2150
+ return void 0;
2151
+ }
2152
+ return {
2153
+ method,
2154
+ path: value.path,
2155
+ ...optional("stream", typeof value.stream === "boolean" ? value.stream : void 0)
2156
+ };
2157
+ }
2158
+ function takeToolFilter(value, aliases, state, basePath) {
2159
+ const located = takeObject(value, aliases, state, basePath);
2160
+ if (!located) return void 0;
2161
+ const filter = compact({
2162
+ include: stringArrayValue(located.value.include),
2163
+ exclude: stringArrayValue(located.value.exclude)
2164
+ });
2165
+ if (Object.keys(filter).length === 0 && Object.keys(located.value).length > 0) return void 0;
2166
+ consume(state, located.path);
2167
+ return filter;
2168
+ }
2169
+ function takeToolsets(value, aliases, state, basePath) {
2170
+ const located = takeObject(value, aliases, state, basePath);
2171
+ if (!located) return void 0;
2172
+ const entries = Object.entries(located.value).map(([name, filter]) => {
2173
+ if (name === "default" || !/^[a-z0-9-]+$/.test(name)) {
2174
+ fail(
2175
+ "FERN_MCP_TOOLSET_NAME_INVALID",
2176
+ [...located.path, name],
2177
+ `MCP toolset name "${name}" is not valid in SDK Config v1`,
2178
+ 'Rename the toolset to lowercase letters, numbers, or hyphens; "default" is reserved.',
2179
+ ["targets", basePath[2], "generation", "toolsets", name]
2180
+ );
2181
+ }
2182
+ if (!isObject(filter)) return void 0;
2183
+ return [
2184
+ name,
2185
+ compact({
2186
+ include: stringArrayValue(filter.include),
2187
+ exclude: stringArrayValue(filter.exclude)
2188
+ })
2189
+ ];
2190
+ });
2191
+ if (entries.some((entry) => !entry)) return void 0;
2192
+ consume(state, located.path);
2193
+ return Object.fromEntries(entries.filter((entry) => entry !== void 0));
2194
+ }
2195
+ var unsupportedFieldSchema = zod.z.strictObject({
2196
+ source: zod.z.enum(["fern", "postman", "sdk-config-ir"]),
2197
+ path: zod.z.array(zod.z.union([nonEmptyStringSchema, zod.z.number().int().nonnegative()])).min(1),
2198
+ code: nonEmptyStringSchema.optional(),
2199
+ reason: nonEmptyStringSchema,
2200
+ severity: zod.z.enum(["error", "warning", "info"]),
2201
+ risk: zod.z.enum(["high", "medium", "low"]),
2202
+ owner: nonEmptyStringSchema,
2203
+ suggestedAction: nonEmptyStringSchema
461
2204
  });
462
- var projectUrlSchema = zod.z.strictObject({
463
- label: nonEmptyStringSchema,
464
- url: nonEmptyStringSchema
2205
+ var postmanLegacyInputSchema = zod.z.strictObject({
2206
+ kind: zod.z.literal("postman-build-parameters"),
2207
+ value: jsonObjectSchema
465
2208
  });
466
- var packageConfigSchema = zod.z.strictObject({
467
- packageName: nonEmptyStringSchema.optional(),
468
- moduleName: nonEmptyStringSchema.optional(),
469
- modulePath: goModulePathSchema.optional(),
470
- namespace: nonEmptyStringSchema.optional(),
471
- groupId: nonEmptyStringSchema.optional(),
472
- artifactId: nonEmptyStringSchema.optional(),
473
- description: zod.z.string().optional(),
474
- repository: nonEmptyStringSchema.optional(),
475
- homepage: nonEmptyStringSchema.optional(),
476
- documentationUrl: nonEmptyStringSchema.optional(),
477
- authors: zod.z.array(authorSchema).optional(),
478
- developers: zod.z.array(developerSchema).optional(),
479
- license: licenseSchema.optional(),
480
- keywords: zod.z.array(nonEmptyStringSchema).optional(),
481
- classifiers: zod.z.array(nonEmptyStringSchema).optional(),
482
- projectUrls: zod.z.array(projectUrlSchema).optional(),
483
- extraDependencies: zod.z.array(dependencySchema).optional(),
484
- extraDevDependencies: zod.z.array(dependencySchema).optional(),
485
- extraPeerDependencies: zod.z.array(dependencySchema).optional()
2209
+ var fernLegacyInputSchema = zod.z.strictObject({
2210
+ kind: zod.z.literal("fern-generator-invocation"),
2211
+ value: jsonObjectSchema
486
2212
  });
487
-
488
- // src/sdk-config-ir/v1/language/terraform.ts
489
- var planModifierSourceSchema = zod.z.discriminatedUnion("enabled", [
490
- zod.z.strictObject({ enabled: zod.z.literal(true), sourceDir: nonEmptyStringSchema }),
491
- zod.z.strictObject({ enabled: zod.z.literal(false) })
2213
+ var legacyInputSchema = zod.z.discriminatedUnion("kind", [
2214
+ postmanLegacyInputSchema,
2215
+ fernLegacyInputSchema
492
2216
  ]);
493
- var planModifiersSchema = zod.z.strictObject({
494
- resources: planModifierSourceSchema,
495
- attributes: planModifierSourceSchema
496
- });
497
- var providerSchemaSchema = zod.z.strictObject({
498
- addressKey: nonEmptyStringSchema,
499
- authTokenKey: nonEmptyStringSchema
500
- });
501
- var terraformGenerationConfigSchema = zod.z.strictObject({
502
- providerName: nonEmptyStringSchema.optional(),
503
- providerVersion: nonEmptyStringSchema.optional(),
504
- providerModulePath: goModulePathSchema.optional(),
505
- mockAcceptance: zod.z.boolean().optional(),
506
- hideComputedDiff: zod.z.boolean().optional(),
507
- providerSchema: providerSchemaSchema.optional(),
508
- planModifiers: planModifiersSchema.optional()
2217
+ var compatibilityConfigSchema = zod.z.strictObject({
2218
+ outputProfile: zod.z.enum(["converged", "postman-legacy", "fern-legacy"]),
2219
+ legacyInput: legacyInputSchema.optional(),
2220
+ unsupportedFields: zod.z.array(unsupportedFieldSchema).optional()
509
2221
  });
510
-
511
- // src/sdk-config-ir/v1/generation.ts
512
2222
  var generationAssetSchema = zod.z.strictObject({
513
2223
  type: zod.z.enum(["path", "url", "artifact"]),
514
2224
  location: nonEmptyStringSchema
515
2225
  });
516
- var hookDependencySchema = zod.z.strictObject({
2226
+ var hookDependencySchema2 = zod.z.strictObject({
517
2227
  name: nonEmptyStringSchema,
518
2228
  version: nonEmptyStringSchema,
519
2229
  groupId: nonEmptyStringSchema.optional()
520
2230
  });
521
- var hooksConfigSchema = zod.z.strictObject({
2231
+ var hooksConfigSchema2 = zod.z.strictObject({
522
2232
  enabled: zod.z.boolean(),
523
2233
  source: generationAssetSchema.optional(),
524
- dependencies: zod.z.array(hookDependencySchema).optional()
2234
+ dependencies: zod.z.array(hookDependencySchema2).optional()
525
2235
  });
526
- var customCodeConfigSchema = zod.z.strictObject({
2236
+ var customCodeConfigSchema2 = zod.z.strictObject({
527
2237
  enabled: zod.z.boolean(),
528
2238
  source: generationAssetSchema.optional(),
529
2239
  conflictStrategy: zod.z.enum(["mark", "ours", "theirs"]).optional(),
@@ -531,19 +2241,19 @@ var customCodeConfigSchema = zod.z.strictObject({
531
2241
  previousBuildId: zod.z.number().int().positive().optional(),
532
2242
  protectedFiles: zod.z.array(nonEmptyStringSchema).optional()
533
2243
  });
534
- var workflowConfigSchema = zod.z.strictObject({
2244
+ var workflowConfigSchema2 = zod.z.strictObject({
535
2245
  path: nonEmptyStringSchema,
536
2246
  outputName: nonEmptyStringSchema.optional()
537
2247
  });
538
- var analyticsHeaderSchema = zod.z.union([
2248
+ var analyticsHeaderSchema2 = zod.z.union([
539
2249
  zod.z.strictObject({ name: nonEmptyStringSchema, value: zod.z.string() }),
540
2250
  zod.z.strictObject({ name: nonEmptyStringSchema, valueRef: nonEmptyStringSchema })
541
2251
  ]);
542
- var analyticsConfigSchema = zod.z.strictObject({
2252
+ var analyticsConfigSchema2 = zod.z.strictObject({
543
2253
  enabled: zod.z.boolean(),
544
2254
  endpoint: nonEmptyStringSchema.optional(),
545
2255
  exporter: zod.z.enum(["otlp-http", "console"]).optional(),
546
- headers: zod.z.array(analyticsHeaderSchema).optional(),
2256
+ headers: zod.z.array(analyticsHeaderSchema2).optional(),
547
2257
  batchSize: zod.z.number().int().positive().optional(),
548
2258
  scheduledDelayMs: zod.z.number().nonnegative().optional(),
549
2259
  exportTimeoutMs: zod.z.number().nonnegative().optional()
@@ -556,18 +2266,29 @@ var analyticsConfigSchema = zod.z.strictObject({
556
2266
  });
557
2267
  }
558
2268
  });
559
- var wireTestsSchema = zod.z.strictObject({
2269
+ var wireTestsSchema2 = zod.z.strictObject({
560
2270
  enabled: zod.z.boolean(),
561
2271
  exclusions: zod.z.array(nonEmptyStringSchema).optional(),
562
- fallbackToGeneratedErrorExamples: zod.z.boolean().optional()
2272
+ fallbackToGeneratedErrorExamples: zod.z.boolean().optional(),
2273
+ fixtureSource: zod.z.enum(["synthetic", "recorded", "auto"]).optional()
563
2274
  });
564
- var streamsSchema = zod.z.strictObject({
2275
+ var unitTestsSchema2 = zod.z.strictObject({
2276
+ enabled: zod.z.boolean(),
2277
+ mode: zod.z.enum(["core-runtime", "schema-driven", "both"]).optional(),
2278
+ exclusions: zod.z.array(nonEmptyStringSchema).optional()
2279
+ });
2280
+ var fernDefinitionMetadataSchema = zod.z.strictObject({
2281
+ definitionS3DownloadUrl: nonEmptyStringSchema,
2282
+ outputPath: nonEmptyStringSchema.optional(),
2283
+ cliVersion: nonEmptyStringSchema.optional()
2284
+ });
2285
+ var streamsSchema2 = zod.z.strictObject({
565
2286
  enabled: zod.z.boolean(),
566
2287
  responseType: zod.z.enum(["wrapper", "native", "web"]).optional(),
567
2288
  fileResponseType: zod.z.enum(["stream", "binary-response"]).optional(),
568
2289
  defaultChunkSizeBytes: zod.z.number().int().positive().optional()
569
2290
  });
570
- var namingConfigSchema = zod.z.strictObject({
2291
+ var namingConfigSchema2 = zod.z.strictObject({
571
2292
  clientName: nonEmptyStringSchema.optional(),
572
2293
  exportedClientName: nonEmptyStringSchema.optional(),
573
2294
  environmentTypeName: nonEmptyStringSchema.optional(),
@@ -575,11 +2296,11 @@ var namingConfigSchema = zod.z.strictObject({
575
2296
  baseErrorName: nonEmptyStringSchema.optional(),
576
2297
  pagerName: nonEmptyStringSchema.optional()
577
2298
  });
578
- var layoutConfigSchema = zod.z.strictObject({
2299
+ var layoutConfigSchema2 = zod.z.strictObject({
579
2300
  outputDirectory: zod.z.enum(["project-root", "source-root"]).optional(),
580
2301
  packagePath: nonEmptyStringSchema.optional()
581
2302
  });
582
- var serializationConfigSchema = zod.z.strictObject({
2303
+ var serializationConfigSchema2 = zod.z.strictObject({
583
2304
  enumRepresentation: zod.z.enum(["enum", "union", "literal", "forward-compatible-enum", "language-default"]).optional(),
584
2305
  additionalProperties: zod.z.enum(["allow", "forbid", "ignore", "language-default"]).optional(),
585
2306
  inlineTypes: zod.z.boolean().optional(),
@@ -612,18 +2333,30 @@ var generationConfigSchema = zod.z.strictObject({
612
2333
  devContainer: zod.z.boolean().default(false),
613
2334
  allowMockClient: zod.z.boolean().default(false),
614
2335
  ignoreFiles: zod.z.array(nonEmptyStringSchema).optional(),
2336
+ /**
2337
+ * Raw .fernignore file contents supplied to external publishers that need Fern ignore semantics.
2338
+ * This is separate from generation.ignoreFiles because raw contents preserve comments, ordering,
2339
+ * blank lines, and negation rules.
2340
+ */
2341
+ fernignoreContents: zod.z.string().optional(),
2342
+ /**
2343
+ * Optional Fern definition metadata for publisher paths that need to write definition or
2344
+ * mock-server support files. This is not required for core GitHub artifact publishing.
2345
+ */
2346
+ fernDefinitionMetadata: fernDefinitionMetadataSchema.optional(),
615
2347
  reservedKeywords: zod.z.array(nonEmptyStringSchema).optional(),
616
- hooks: hooksConfigSchema.optional(),
617
- customCode: customCodeConfigSchema.optional(),
618
- workflows: zod.z.array(workflowConfigSchema).optional(),
2348
+ hooks: hooksConfigSchema2.optional(),
2349
+ customCode: customCodeConfigSchema2.optional(),
2350
+ workflows: zod.z.array(workflowConfigSchema2).optional(),
619
2351
  customQueryPaths: zod.z.array(nonEmptyStringSchema).optional(),
620
- analytics: analyticsConfigSchema.optional(),
621
- wireTests: wireTestsSchema.optional(),
2352
+ analytics: analyticsConfigSchema2.optional(),
2353
+ wireTests: wireTestsSchema2.optional(),
2354
+ unitTests: unitTestsSchema2.optional(),
622
2355
  webSockets: zod.z.boolean().optional(),
623
- streams: streamsSchema.optional(),
624
- naming: namingConfigSchema.optional(),
625
- layout: layoutConfigSchema.optional(),
626
- serialization: serializationConfigSchema.optional(),
2356
+ streams: streamsSchema2.optional(),
2357
+ naming: namingConfigSchema2.optional(),
2358
+ layout: layoutConfigSchema2.optional(),
2359
+ serialization: serializationConfigSchema2.optional(),
627
2360
  language: languageGenerationConfigSchema.optional()
628
2361
  });
629
2362
  var publishRegistrySchema = zod.z.enum([
@@ -636,57 +2369,95 @@ var publishRegistrySchema = zod.z.enum([
636
2369
  "go",
637
2370
  "composer"
638
2371
  ]);
639
- var commonPublishShape = {
2372
+ var credentialResolutionSchema = zod.z.enum([
2373
+ "refs-only",
2374
+ "resolved-by-orchestrator",
2375
+ "resolved-by-fiddle"
2376
+ ]);
2377
+ var commonPublishShape2 = {
640
2378
  url: nonEmptyStringSchema.optional(),
2379
+ /**
2380
+ * Reference to registry publishing credentials. Raw tokens/passwords are intentionally not part of
2381
+ * SDK Config IR; the external publisher or orchestrator resolves this reference before use.
2382
+ */
641
2383
  credentialsRef: nonEmptyStringSchema.optional(),
642
2384
  releaseBranch: nonEmptyStringSchema.optional(),
643
2385
  tolerateRepublish: zod.z.boolean().optional()
644
2386
  };
645
2387
  var publishConfigSchema = zod.z.discriminatedUnion("registry", [
646
- zod.z.strictObject({ registry: zod.z.literal("npm"), ...commonPublishShape }),
647
- zod.z.strictObject({ registry: zod.z.literal("pypi"), ...commonPublishShape }),
648
- zod.z.strictObject({ registry: zod.z.literal("nuget"), ...commonPublishShape }),
649
- zod.z.strictObject({ registry: zod.z.literal("rubygems"), ...commonPublishShape }),
650
- zod.z.strictObject({ registry: zod.z.literal("crates"), ...commonPublishShape }),
651
- zod.z.strictObject({ registry: zod.z.literal("go"), ...commonPublishShape }),
652
- zod.z.strictObject({ registry: zod.z.literal("composer"), ...commonPublishShape }),
2388
+ zod.z.strictObject({ registry: zod.z.literal("npm"), ...commonPublishShape2 }),
2389
+ zod.z.strictObject({ registry: zod.z.literal("pypi"), ...commonPublishShape2 }),
2390
+ zod.z.strictObject({ registry: zod.z.literal("nuget"), ...commonPublishShape2 }),
2391
+ zod.z.strictObject({ registry: zod.z.literal("rubygems"), ...commonPublishShape2 }),
2392
+ zod.z.strictObject({ registry: zod.z.literal("crates"), ...commonPublishShape2 }),
2393
+ zod.z.strictObject({ registry: zod.z.literal("go"), ...commonPublishShape2 }),
2394
+ zod.z.strictObject({ registry: zod.z.literal("composer"), ...commonPublishShape2 }),
653
2395
  zod.z.strictObject({
654
2396
  registry: zod.z.literal("maven"),
2397
+ /**
2398
+ * Reference to Maven signing credentials. Raw signing keys are intentionally not part of SDK
2399
+ * Config IR; the external publisher or orchestrator resolves this reference before use.
2400
+ */
655
2401
  signingCredentialsRef: nonEmptyStringSchema.optional(),
656
- ...commonPublishShape
2402
+ ...commonPublishShape2
657
2403
  })
658
2404
  ]);
659
- var reviewersSchema = zod.z.strictObject({
2405
+ var reviewersSchema2 = zod.z.strictObject({
660
2406
  teams: zod.z.array(nonEmptyStringSchema).optional(),
661
2407
  users: zod.z.array(nonEmptyStringSchema).optional()
662
2408
  });
663
- var githubOutputSchema = zod.z.strictObject({
2409
+ var replayControlSchema = zod.z.strictObject({
2410
+ enabled: zod.z.boolean()
2411
+ });
2412
+ var githubOutputSchema2 = zod.z.strictObject({
664
2413
  repository: nonEmptyStringSchema,
665
2414
  host: nonEmptyStringSchema.optional(),
666
2415
  branch: nonEmptyStringSchema.optional(),
667
2416
  mode: zod.z.enum(["release", "pull-request", "push"]).optional(),
668
- reviewers: reviewersSchema.optional(),
2417
+ reviewers: reviewersSchema2.optional(),
2418
+ /**
2419
+ * Reference to GitHub credentials. Raw tokens are intentionally not part of SDK Config IR; the
2420
+ * external publisher or orchestrator resolves this reference before use.
2421
+ */
669
2422
  credentialsRef: nonEmptyStringSchema.optional(),
670
- privateRepository: zod.z.boolean().optional()
671
- });
672
- var filesOutputSchema = zod.z.strictObject({
2423
+ privateRepository: zod.z.boolean().optional(),
2424
+ /** GitHub replay control. If omitted, the external publisher applies its default behavior. */
2425
+ replay: replayControlSchema.optional(),
2426
+ /** Run GitHub publishing verification. Defaults to false to match current Fiddle job behavior. */
2427
+ verify: zod.z.boolean().default(false),
2428
+ /** Skip creating/updating a GitHub PR when no files changed. Defaults to false. */
2429
+ skipIfNoDiff: zod.z.boolean().default(false),
2430
+ /** Automatically merge the GitHub publishing PR. Defaults to false. */
2431
+ autoMerge: zod.z.boolean().default(false)
2432
+ });
2433
+ var credentialResolutionShape = {
2434
+ /**
2435
+ * Where output credential references are resolved. SDK Config IR carries refs only; raw resolved
2436
+ * credentials belong at the external publisher/orchestrator boundary, not in this config.
2437
+ */
2438
+ credentialResolution: credentialResolutionSchema.default("refs-only")
2439
+ };
2440
+ var filesOutputSchema2 = zod.z.strictObject({
673
2441
  delivery: zod.z.literal("files"),
674
2442
  path: nonEmptyStringSchema.optional(),
675
- publish: publishConfigSchema.optional()
2443
+ publish: publishConfigSchema.optional(),
2444
+ ...credentialResolutionShape
676
2445
  });
677
- var zipOutputSchema = zod.z.strictObject({
2446
+ var zipOutputSchema2 = zod.z.strictObject({
678
2447
  delivery: zod.z.literal("zip"),
679
2448
  fileName: nonEmptyStringSchema.optional(),
680
- publish: publishConfigSchema.optional()
2449
+ publish: publishConfigSchema.optional(),
2450
+ ...credentialResolutionShape
681
2451
  });
682
- var githubDeliverySchema = zod.z.strictObject({
2452
+ var githubDeliverySchema2 = zod.z.strictObject({
683
2453
  delivery: zod.z.literal("github"),
684
- github: githubOutputSchema,
685
- publish: publishConfigSchema.optional()
2454
+ github: githubOutputSchema2,
2455
+ publish: publishConfigSchema.optional(),
2456
+ ...credentialResolutionShape
686
2457
  });
687
2458
  var outputConfigSchema = zod.z.discriminatedUnion(
688
2459
  "delivery",
689
- [filesOutputSchema, zipOutputSchema, githubDeliverySchema],
2460
+ [filesOutputSchema2, zipOutputSchema2, githubDeliverySchema2],
690
2461
  {
691
2462
  error: 'output.delivery must be one of "files", "zip", or "github"'
692
2463
  }
@@ -702,7 +2473,8 @@ var apiImportSettingsSchema = zod.z.strictObject({
702
2473
  onlyIncludeReferencedSchemas: zod.z.boolean().optional(),
703
2474
  objectQueryParameters: zod.z.boolean().optional(),
704
2475
  typeDatesAsStrings: zod.z.boolean().optional(),
705
- groupMultiApiEnvironments: zod.z.boolean().optional()
2476
+ groupMultiApiEnvironments: zod.z.boolean().optional(),
2477
+ defaultIntegerFormat: zod.z.enum(["int32", "int64", "uint32", "uint64"]).optional()
706
2478
  });
707
2479
  var sourceSpecTypeSchema = zod.z.enum([
708
2480
  "openapi",
@@ -759,15 +2531,27 @@ var targetConfigSchema = zod.z.strictObject({
759
2531
  generatorVersion: exactSemverSchema.optional(),
760
2532
  sourceOrigin: zod.z.enum(["postman", "fern"]),
761
2533
  sdkName: nonEmptyStringSchema,
2534
+ /**
2535
+ * Stable Fern/Fiddle API identity for external publishing.
2536
+ * Producers must set this explicitly for GitHub or registry publishing; it is not inferred from
2537
+ * target.sdkName because SDK display names and Fern API names are not equivalent.
2538
+ */
2539
+ apiName: nonEmptyStringSchema.optional(),
762
2540
  organization: nonEmptyStringSchema.optional(),
2541
+ /**
2542
+ * Stable Fern/Fiddle organization identity for external publishing.
2543
+ * Producers must set this explicitly for GitHub or registry publishing; it is not inferred from
2544
+ * target.organization because source organization metadata is optional and may not match Fern.
2545
+ */
2546
+ organizationName: nonEmptyStringSchema.optional(),
763
2547
  sdkVersion: nonEmptyStringSchema.default("1.0.0"),
764
2548
  apiVersion: nonEmptyStringSchema.optional()
765
2549
  });
766
2550
 
767
2551
  // src/sdk-config-ir/v1/sdk-config-ir-v1.ts
768
2552
  var SDK_CONFIG_IR_V1_SCHEMA_VERSION = "sdk-config-ir/v1";
769
- var publishRegistryLanguages = {
770
- npm: ["typescript"],
2553
+ var publishRegistryLanguages2 = {
2554
+ npm: ["typescript", "mcp"],
771
2555
  pypi: ["python"],
772
2556
  maven: ["java", "kotlin"],
773
2557
  nuget: ["csharp"],
@@ -776,7 +2560,7 @@ var publishRegistryLanguages = {
776
2560
  go: ["go"],
777
2561
  composer: ["php"]
778
2562
  };
779
- var packageNameRegistries = /* @__PURE__ */ new Set([
2563
+ var packageNameRegistries2 = /* @__PURE__ */ new Set([
780
2564
  "npm",
781
2565
  "pypi",
782
2566
  "nuget",
@@ -784,8 +2568,8 @@ var packageNameRegistries = /* @__PURE__ */ new Set([
784
2568
  "crates",
785
2569
  "composer"
786
2570
  ]);
787
- function validatePublishingIdentity(packageConfig, registry, context) {
788
- if (packageNameRegistries.has(registry) && !packageConfig.packageName) {
2571
+ function validatePublishingIdentity2(packageConfig, registry, context) {
2572
+ if (packageNameRegistries2.has(registry) && !packageConfig.packageName) {
789
2573
  context.addIssue({
790
2574
  code: "custom",
791
2575
  message: `package.packageName is required when publishing to "${registry}"`,
@@ -835,6 +2619,21 @@ var sdkConfigIrV1Schema = zod.z.strictObject({
835
2619
  compatibility: compatibilityConfigSchema.optional()
836
2620
  }).superRefine(({ compatibility, generation, output, package: packageConfig, target }, context) => {
837
2621
  const configuredLanguages = Object.keys(generation.language ?? {});
2622
+ const requiresExternalPublishIdentity = output.delivery === "github" || output.publish !== void 0;
2623
+ if (requiresExternalPublishIdentity) {
2624
+ [
2625
+ ["apiName", "target.apiName is required for external publishing"],
2626
+ ["organizationName", "target.organizationName is required for external publishing"]
2627
+ ].forEach(([field, message]) => {
2628
+ if (!target[field]) {
2629
+ context.addIssue({
2630
+ code: "custom",
2631
+ message,
2632
+ path: ["target", field]
2633
+ });
2634
+ }
2635
+ });
2636
+ }
838
2637
  configuredLanguages.forEach((language) => {
839
2638
  if (language !== target.language) {
840
2639
  context.addIssue({
@@ -844,7 +2643,7 @@ var sdkConfigIrV1Schema = zod.z.strictObject({
844
2643
  });
845
2644
  }
846
2645
  });
847
- if (output.publish && !publishRegistryLanguages[output.publish.registry].some(
2646
+ if (output.publish && !publishRegistryLanguages2[output.publish.registry].some(
848
2647
  (language) => language === target.language
849
2648
  )) {
850
2649
  context.addIssue({
@@ -854,7 +2653,7 @@ var sdkConfigIrV1Schema = zod.z.strictObject({
854
2653
  });
855
2654
  }
856
2655
  if (output.publish) {
857
- validatePublishingIdentity(packageConfig, output.publish.registry, context);
2656
+ validatePublishingIdentity2(packageConfig, output.publish.registry, context);
858
2657
  }
859
2658
  if (compatibility?.legacyInput) {
860
2659
  const expectedKind = target.sourceOrigin === "postman" ? "postman-build-parameters" : "fern-generator-invocation";
@@ -871,7 +2670,9 @@ function parseSdkConfigIrV1(value) {
871
2670
  return sdkConfigIrV1Schema.parse(value);
872
2671
  }
873
2672
 
2673
+ exports.FernConfigMappingError = FernConfigMappingError;
874
2674
  exports.SDK_CONFIG_IR_V1_SCHEMA_VERSION = SDK_CONFIG_IR_V1_SCHEMA_VERSION;
2675
+ exports.SDK_CONFIG_V1_SCHEMA_VERSION = SDK_CONFIG_V1_SCHEMA_VERSION;
875
2676
  exports.apiConfigSchema = apiConfigSchema;
876
2677
  exports.apiImportSettingsSchema = apiImportSettingsSchema;
877
2678
  exports.authConfigSchema = authConfigSchema;
@@ -893,19 +2694,55 @@ exports.jsonValueSchema = jsonValueSchema;
893
2694
  exports.kotlinGenerationConfigSchema = kotlinGenerationConfigSchema;
894
2695
  exports.languageGenerationConfigSchema = languageGenerationConfigSchema;
895
2696
  exports.legacyInputSchema = legacyInputSchema;
2697
+ exports.mapFernConfigToSdkConfigV1 = mapFernConfigToSdkConfigV1;
2698
+ exports.mcpAvailabilityStatuses = mcpAvailabilityStatuses;
896
2699
  exports.mcpGenerationConfigSchema = mcpGenerationConfigSchema;
897
2700
  exports.nonEmptyStringSchema = nonEmptyStringSchema;
898
2701
  exports.outputConfigSchema = outputConfigSchema;
899
2702
  exports.packageConfigSchema = packageConfigSchema;
900
2703
  exports.parseSdkConfigIrV1 = parseSdkConfigIrV1;
2704
+ exports.parseSdkConfigV1 = parseSdkConfigV1;
901
2705
  exports.phpGenerationConfigSchema = phpGenerationConfigSchema;
902
2706
  exports.publishConfigSchema = publishConfigSchema;
903
2707
  exports.publishRegistrySchema = publishRegistrySchema;
904
2708
  exports.pythonGenerationConfigSchema = pythonGenerationConfigSchema;
2709
+ exports.readmeCustomSectionSchema = readmeCustomSectionSchema;
905
2710
  exports.readmeEndpointSchema = readmeEndpointSchema;
906
2711
  exports.rubyGenerationConfigSchema = rubyGenerationConfigSchema;
907
2712
  exports.rustGenerationConfigSchema = rustGenerationConfigSchema;
908
2713
  exports.sdkConfigIrV1Schema = sdkConfigIrV1Schema;
2714
+ exports.sdkConfigV1ApiConfigSchema = sdkConfigV1ApiConfigSchema;
2715
+ exports.sdkConfigV1AuthConfigSchema = sdkConfigV1AuthConfigSchema;
2716
+ exports.sdkConfigV1AuthSchemeSchema = sdkConfigV1AuthSchemeSchema;
2717
+ exports.sdkConfigV1CliGenerationConfigSchema = cliGenerationConfigSchema;
2718
+ exports.sdkConfigV1ClientConfigSchema = sdkConfigV1ClientConfigSchema;
2719
+ exports.sdkConfigV1ComposerPackageNameSchema = composerPackageNameSchema;
2720
+ exports.sdkConfigV1CsharpGenerationConfigSchema = csharpGenerationConfigSchema;
2721
+ exports.sdkConfigV1DependencySchema = sdkConfigV1DependencySchema;
2722
+ exports.sdkConfigV1DocsConfigSchema = sdkConfigV1DocsConfigSchema;
2723
+ exports.sdkConfigV1ExactSemverSchema = exactSemverSchema;
2724
+ exports.sdkConfigV1GenerationConfigSchema = sdkConfigV1GenerationConfigSchema;
2725
+ exports.sdkConfigV1GoGenerationConfigSchema = goGenerationConfigSchema;
2726
+ exports.sdkConfigV1GoModulePathSchema = goModulePathSchema;
2727
+ exports.sdkConfigV1JavaGenerationConfigSchema = javaGenerationConfigSchema;
2728
+ exports.sdkConfigV1KotlinGenerationConfigSchema = kotlinGenerationConfigSchema;
2729
+ exports.sdkConfigV1McpGenerationConfigSchema = mcpGenerationConfigSchema;
2730
+ exports.sdkConfigV1NonEmptyStringSchema = nonEmptyStringSchema;
2731
+ exports.sdkConfigV1OutputConfigSchema = sdkConfigV1OutputConfigSchema;
2732
+ exports.sdkConfigV1PackageConfigSchema = sdkConfigV1PackageConfigSchema;
2733
+ exports.sdkConfigV1PhpGenerationConfigSchema = phpGenerationConfigSchema;
2734
+ exports.sdkConfigV1PublishConfigSchema = sdkConfigV1PublishConfigSchema;
2735
+ exports.sdkConfigV1PublishRegistrySchema = sdkConfigV1PublishRegistrySchema;
2736
+ exports.sdkConfigV1PythonGenerationConfigSchema = pythonGenerationConfigSchema;
2737
+ exports.sdkConfigV1ReadmeCustomSectionSchema = sdkConfigV1ReadmeCustomSectionSchema;
2738
+ exports.sdkConfigV1ReadmeEndpointSchema = sdkConfigV1ReadmeEndpointSchema;
2739
+ exports.sdkConfigV1RubyGenerationConfigSchema = rubyGenerationConfigSchema;
2740
+ exports.sdkConfigV1RustGenerationConfigSchema = rustGenerationConfigSchema;
2741
+ exports.sdkConfigV1Schema = sdkConfigV1Schema;
2742
+ exports.sdkConfigV1SwiftGenerationConfigSchema = swiftGenerationConfigSchema;
2743
+ exports.sdkConfigV1TargetSchema = sdkConfigV1TargetSchema;
2744
+ exports.sdkConfigV1TerraformGenerationConfigSchema = terraformGenerationConfigSchema;
2745
+ exports.sdkConfigV1TypescriptGenerationConfigSchema = typescriptGenerationConfigSchema;
909
2746
  exports.sourceConfigSchema = sourceConfigSchema;
910
2747
  exports.sourceSpecConfigSchema = sourceSpecConfigSchema;
911
2748
  exports.sourceSpecTypeSchema = sourceSpecTypeSchema;