@postman/sdk-config 0.4.0 → 0.4.1

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.
@@ -581,7 +581,13 @@ function mapOutput(generator, language, index) {
581
581
  const raw = isObject(generator.raw) ? generator.raw : void 0;
582
582
  const rawOutput = raw && isObject(raw.output) ? raw.output : void 0;
583
583
  const outputPath = ["group", "generators", index, "outputMode"];
584
- const state = { consumedPaths: /* @__PURE__ */ new Set() };
584
+ const state = { consumedPaths: /* @__PURE__ */ new Set(), credentialDiagnostics: [] };
585
+ if (generator.output) {
586
+ return {
587
+ output: sanitizeNormalizedOutput(generator.output, rawOutput, state, index),
588
+ unsupportedFields: state.credentialDiagnostics ?? []
589
+ };
590
+ }
585
591
  if (rawOutput?.location === "local-file-system") {
586
592
  if (isObject(generator.outputMode)) consume(state, [...outputPath, "type"]);
587
593
  return finishOutputMapping(
@@ -613,7 +619,7 @@ function mapOutput(generator, language, index) {
613
619
  return finishOutputMapping({ output: { delivery: "zip" } }, output, outputPath, state, index);
614
620
  case "github":
615
621
  return finishOutputMapping(
616
- githubOutput(output, output.publishInfo, language, outputPath, state, index),
622
+ githubOutput(output, output.publishInfo, rawOutput, language, outputPath, state, index),
617
623
  output,
618
624
  outputPath,
619
625
  state,
@@ -633,6 +639,7 @@ function mapOutput(generator, language, index) {
633
639
  githubOutput(
634
640
  output.githubV2,
635
641
  output.githubV2.publishInfo,
642
+ rawOutput,
636
643
  language,
637
644
  githubPath,
638
645
  state,
@@ -647,6 +654,7 @@ function mapOutput(generator, language, index) {
647
654
  case "publishV2": {
648
655
  const publication = mapPublication(
649
656
  output.publishV2,
657
+ rawOutput,
650
658
  language,
651
659
  [...outputPath, "publishV2"],
652
660
  state,
@@ -666,6 +674,7 @@ function mapOutput(generator, language, index) {
666
674
  case "publish": {
667
675
  const publication = mapLegacyPublication(
668
676
  output.registryOverrides,
677
+ rawOutput,
669
678
  language,
670
679
  [...outputPath, "registryOverrides"],
671
680
  state,
@@ -692,7 +701,22 @@ function mapOutput(generator, language, index) {
692
701
  );
693
702
  }
694
703
  }
695
- function githubOutput(value, publishInfo, language, sourcePath, state, index) {
704
+ function sanitizeNormalizedOutput(output, rawOutput, state, index) {
705
+ const publish = output.publish ? sanitizePublishConfig(output.publish, output.publish, rawOutput, state, index) : void 0;
706
+ const publishShape = publish ? { publish } : {};
707
+ if (output.delivery !== "github") return { ...output, ...publishShape };
708
+ const { credentials, ...github } = output.github;
709
+ if (credentials) {
710
+ addCredentialDiagnostic(
711
+ state,
712
+ ["group", "generators", index, "output", "github", "credentials"],
713
+ ["targets", index, "output", "github", "credentials"],
714
+ "Normalized GitHub credentials have no raw environment-expression provenance"
715
+ );
716
+ }
717
+ return { ...output, github, ...publishShape };
718
+ }
719
+ function githubOutput(value, publishInfo, rawOutput, language, sourcePath, state, index) {
696
720
  const owner = stringValue(value.owner);
697
721
  const repo = stringValue(value.repo);
698
722
  if (!owner || !repo)
@@ -705,14 +729,22 @@ function githubOutput(value, publishInfo, language, sourcePath, state, index) {
705
729
  );
706
730
  consume(state, [...sourcePath, "owner"]);
707
731
  consume(state, [...sourcePath, "repo"]);
708
- const publication = publishInfo ? mapPublication(publishInfo, language, [...sourcePath, "publishInfo"], state, index) : void 0;
732
+ const publication = publishInfo ? mapPublication(publishInfo, rawOutput, language, [...sourcePath, "publishInfo"], state, index) : void 0;
709
733
  const type = stringValue(value.type);
710
734
  const reviewers = mapReviewers(value.reviewers, [...sourcePath, "reviewers"], state);
711
735
  if (type) consume(state, [...sourcePath, "type"]);
712
736
  if (typeof value.makePr === "boolean") consume(state, [...sourcePath, "makePr"]);
713
737
  if (stringValue(value.host)) consume(state, [...sourcePath, "host"]);
714
738
  if (stringValue(value.branch)) consume(state, [...sourcePath, "branch"]);
715
- const credentials = mapCredentials(value.credentials, [...sourcePath, "credentials"], state);
739
+ consumeCredentialObject(value.credentials, [...sourcePath, "credentials"], state);
740
+ if (isObject(value.credentials)) {
741
+ addCredentialDiagnostic(
742
+ state,
743
+ [...sourcePath, "credentials"],
744
+ ["targets", index, "output", "github", "credentials"],
745
+ "GitHub credentials cannot be traced safely to raw environment expressions"
746
+ );
747
+ }
716
748
  return {
717
749
  output: {
718
750
  delivery: "github",
@@ -721,57 +753,35 @@ function githubOutput(value, publishInfo, language, sourcePath, state, index) {
721
753
  ...optional("host", stringValue(value.host)),
722
754
  ...optional("branch", stringValue(value.branch)),
723
755
  mode: value.makePr === true || type === "pullRequest" ? "pull-request" : type === "push" ? "push" : "release",
724
- ...optional("reviewers", reviewers),
725
- ...optional("credentials", credentials)
756
+ ...optional("reviewers", reviewers)
726
757
  },
727
758
  ...publication ? { publish: publication.publish } : {}
728
759
  },
729
760
  ...optional("package", publication?.package)
730
761
  };
731
762
  }
732
- function mapCredentials(value, sourcePath, state) {
733
- if (!isObject(value)) return void 0;
734
- return credentialsFromObject(value, sourcePath, state);
735
- }
736
- function mapInlineCredentials(value, sourcePath, state) {
737
- const credentials = mapCredentials(value.credentials, [...sourcePath, "credentials"], state);
738
- if (credentials) return credentials;
739
- return credentialsFromObject(value, sourcePath, state);
740
- }
741
- function credentialsFromObject(value, sourcePath, state) {
742
- const credentials = {};
743
- const username = stringValue(value.username);
744
- const password = stringValue(value.password);
745
- const token = stringValue(value.token);
746
- const apiKey = stringValue(value.apiKey);
747
- if (username) {
748
- credentials.username = username;
749
- consume(state, [...sourcePath, "username"]);
763
+ function consumeCredentialObject(value, sourcePath, state) {
764
+ if (!isObject(value)) return;
765
+ for (const field of ["username", "password", "token", "apiKey"]) {
766
+ if (stringValue(value[field])) consume(state, [...sourcePath, field]);
750
767
  }
751
- if (password) {
752
- credentials.password = password;
753
- consume(state, [...sourcePath, "password"]);
768
+ }
769
+ function consumeResolvedCredentials(value, sourcePath, state) {
770
+ for (const field of ["username", "password", "token", "apiKey"]) {
771
+ if (stringValue(value[field])) {
772
+ consume(state, [...sourcePath, field]);
773
+ }
754
774
  }
755
- if (token) {
756
- credentials.token = token;
757
- consume(state, [...sourcePath, "token"]);
775
+ if (isObject(value.credentials)) {
776
+ for (const field of ["username", "password", "token", "apiKey"]) {
777
+ if (stringValue(value.credentials[field])) {
778
+ consume(state, [...sourcePath, "credentials", field]);
779
+ }
780
+ }
758
781
  }
759
- if (apiKey) {
760
- credentials.apiKey = apiKey;
761
- consume(state, [...sourcePath, "apiKey"]);
782
+ if (isObject(value.signature)) {
783
+ consume(state, [...sourcePath, "signature"]);
762
784
  }
763
- return Object.keys(credentials).length === 0 ? void 0 : credentials;
764
- }
765
- function mapMavenSignature(value, sourcePath, state) {
766
- if (!isObject(value)) return void 0;
767
- const keyId = stringValue(value.keyId);
768
- const password = stringValue(value.password);
769
- const secretKey = stringValue(value.secretKey);
770
- if (!keyId || !password || !secretKey) return void 0;
771
- consume(state, [...sourcePath, "keyId"]);
772
- consume(state, [...sourcePath, "password"]);
773
- consume(state, [...sourcePath, "secretKey"]);
774
- return { keyId, password, secretKey };
775
785
  }
776
786
  function mapReviewers(value, sourcePath, state) {
777
787
  if (Array.isArray(value)) {
@@ -800,7 +810,7 @@ function reviewerNames(value, expectedType, sourcePath, state) {
800
810
  });
801
811
  return names.length ? names : void 0;
802
812
  }
803
- function mapPublication(value, language, sourcePath, state, index) {
813
+ function mapPublication(value, rawOutput, language, sourcePath, state, index) {
804
814
  if (!isObject(value))
805
815
  fail(
806
816
  "FERN_PUBLICATION_INVALID",
@@ -816,13 +826,19 @@ function mapPublication(value, language, sourcePath, state, index) {
816
826
  const registry = publicationRegistry(type, language, [...sourcePath, "type"], index);
817
827
  const registryUrl = stringValue(nested.registryUrl);
818
828
  if (registryUrl) consume(state, [...nestedPath, "registryUrl"]);
819
- const credentials = mapInlineCredentials(nested, nestedPath, state);
829
+ consumeResolvedCredentials(nested, nestedPath, state);
830
+ const publish = sanitizePublishConfig(
831
+ compact({ registry, url: registryUrl }),
832
+ nested,
833
+ rawOutput,
834
+ state,
835
+ index
836
+ );
820
837
  if (registry === "maven") {
821
838
  const coordinate = stringValue(nested.coordinate);
822
- const signature = mapMavenSignature(nested.signature, [...nestedPath, "signature"], state);
823
839
  if (coordinate) consume(state, [...nestedPath, "coordinate"]);
824
840
  return {
825
- publish: compact({ registry, url: registryUrl, credentials, signature }),
841
+ publish,
826
842
  ...coordinate ? { package: mavenPackage(coordinate, [...nestedPath, "coordinate"], index) } : {}
827
843
  };
828
844
  }
@@ -831,15 +847,244 @@ function mapPublication(value, language, sourcePath, state, index) {
831
847
  if (packageName) consume(state, [...nestedPath, packageNameField]);
832
848
  const metadata = registry === "pypi" ? mapPypiMetadata(nested.pypiMetadata, nestedPath, state) : {};
833
849
  return {
834
- publish: compact({ registry, url: registryUrl, credentials }),
850
+ publish,
835
851
  ...packageName || Object.keys(metadata).length ? { package: { ...optional("packageName", packageName), ...metadata } } : {}
836
852
  };
837
853
  }
838
- function mapLegacyPublication(value, language, sourcePath, state, index) {
854
+ function sanitizePublishConfig(publish, resolvedPublication, rawOutput, state, index) {
855
+ const rawPublication = rawOutput?.location === publish.registry ? rawOutput : void 0;
856
+ const rawPath = ["group", "generators", index, "output"];
857
+ if (publish.registry === "npm" || publish.registry === "crates") {
858
+ const token = mapCredentialExpression(
859
+ rawPublication,
860
+ resolvedPublication,
861
+ "token",
862
+ rawPath,
863
+ state,
864
+ index
865
+ );
866
+ warnForUnexpectedCredentialFields(
867
+ rawPublication,
868
+ resolvedPublication,
869
+ ["token"],
870
+ rawPath,
871
+ state,
872
+ index
873
+ );
874
+ return compact({
875
+ registry: publish.registry,
876
+ url: publish.url,
877
+ releaseBranch: publish.releaseBranch,
878
+ tolerateRepublish: publish.tolerateRepublish,
879
+ token
880
+ });
881
+ }
882
+ if (publish.registry === "pypi") {
883
+ const { username, password } = mapPypiCredentialExpressions(
884
+ rawPublication,
885
+ resolvedPublication,
886
+ rawPath,
887
+ state,
888
+ index
889
+ );
890
+ warnForUnexpectedCredentialFields(
891
+ rawPublication,
892
+ resolvedPublication,
893
+ ["username", "password", "token"],
894
+ rawPath,
895
+ state,
896
+ index
897
+ );
898
+ return compact({
899
+ registry: publish.registry,
900
+ url: publish.url,
901
+ releaseBranch: publish.releaseBranch,
902
+ tolerateRepublish: publish.tolerateRepublish,
903
+ username,
904
+ password
905
+ });
906
+ }
907
+ if (publish.registry === "maven") {
908
+ const username = mapCredentialExpression(
909
+ rawPublication,
910
+ resolvedPublication,
911
+ "username",
912
+ rawPath,
913
+ state,
914
+ index
915
+ );
916
+ const password = mapCredentialExpression(
917
+ rawPublication,
918
+ resolvedPublication,
919
+ "password",
920
+ rawPath,
921
+ state,
922
+ index
923
+ );
924
+ const signature = mapMavenSignatureExpressions(
925
+ rawPublication?.signature,
926
+ resolvedPublication.signature,
927
+ [...rawPath, "signature"],
928
+ state,
929
+ index
930
+ );
931
+ warnForUnexpectedCredentialFields(
932
+ rawPublication,
933
+ resolvedPublication,
934
+ ["username", "password"],
935
+ rawPath,
936
+ state,
937
+ index,
938
+ true
939
+ );
940
+ return compact({
941
+ registry: publish.registry,
942
+ url: publish.url,
943
+ releaseBranch: publish.releaseBranch,
944
+ tolerateRepublish: publish.tolerateRepublish,
945
+ username,
946
+ password,
947
+ signature
948
+ });
949
+ }
950
+ warnForUnrepresentableCredentials(rawPublication, resolvedPublication, rawPath, state, index);
951
+ return compact({
952
+ registry: publish.registry,
953
+ url: publish.url,
954
+ releaseBranch: publish.releaseBranch,
955
+ tolerateRepublish: publish.tolerateRepublish
956
+ });
957
+ }
958
+ function mapLegacyPublication(value, rawOutput, language, sourcePath, state, index) {
839
959
  const registry = defaultRegistry(language, sourcePath, index);
840
960
  const overrides = isObject(value) ? value : {};
841
961
  const override = isObject(overrides[registry]) ? overrides[registry] : {};
842
- return mapPublication(override, language, [...sourcePath, registry], state, index);
962
+ return mapPublication(override, rawOutput, language, [...sourcePath, registry], state, index);
963
+ }
964
+ function mapCredentialExpression(rawPublication, resolvedPublication, field, rawPath, state, index) {
965
+ const rawValue = rawPublication?.[field];
966
+ if (isEnvironmentExpression(rawValue)) return rawValue;
967
+ if (rawValue !== void 0 || hasResolvedCredential(resolvedPublication, field)) {
968
+ addCredentialDiagnostic(
969
+ state,
970
+ [...rawPath, field],
971
+ ["targets", index, "output", "publish", field],
972
+ `Fern publishing ${field} is not an exact environment expression`
973
+ );
974
+ }
975
+ return void 0;
976
+ }
977
+ function mapPypiCredentialExpressions(rawPublication, resolvedPublication, rawPath, state, index) {
978
+ const rawToken = rawPublication?.token;
979
+ if (isEnvironmentExpression(rawToken)) {
980
+ return { username: "__token__", password: rawToken };
981
+ }
982
+ const resolvedUsesToken = resolvedCredentialValue(resolvedPublication, "username") === "__token__";
983
+ if (rawToken !== void 0 || resolvedUsesToken) {
984
+ addCredentialDiagnostic(
985
+ state,
986
+ [...rawPath, "token"],
987
+ ["targets", index, "output", "publish", "password"],
988
+ "Fern PyPI token is not an exact raw environment expression"
989
+ );
990
+ return {};
991
+ }
992
+ return {
993
+ ...optional(
994
+ "username",
995
+ mapCredentialExpression(
996
+ rawPublication,
997
+ resolvedPublication,
998
+ "username",
999
+ rawPath,
1000
+ state,
1001
+ index
1002
+ )
1003
+ ),
1004
+ ...optional(
1005
+ "password",
1006
+ mapCredentialExpression(
1007
+ rawPublication,
1008
+ resolvedPublication,
1009
+ "password",
1010
+ rawPath,
1011
+ state,
1012
+ index
1013
+ )
1014
+ )
1015
+ };
1016
+ }
1017
+ function mapMavenSignatureExpressions(rawValue, resolvedValue, rawPath, state, index) {
1018
+ if (isObject(rawValue)) {
1019
+ const yamlValues = [rawValue["key-id"], rawValue.password, rawValue["secret-key"]];
1020
+ const projectedValues = [rawValue.keyId, rawValue.password, rawValue.secretKey];
1021
+ const values = yamlValues.every(isEnvironmentExpression) ? yamlValues : projectedValues.every(isEnvironmentExpression) ? projectedValues : void 0;
1022
+ if (values) {
1023
+ const [keyId, password, secretKey] = values;
1024
+ return { keyId, password, secretKey };
1025
+ }
1026
+ }
1027
+ if (rawValue !== void 0 || isObject(resolvedValue)) {
1028
+ addCredentialDiagnostic(
1029
+ state,
1030
+ rawPath,
1031
+ ["targets", index, "output", "publish", "signature"],
1032
+ "Maven signing credentials are incomplete or not exact environment expressions"
1033
+ );
1034
+ }
1035
+ return void 0;
1036
+ }
1037
+ function warnForUnrepresentableCredentials(rawPublication, resolvedPublication, rawPath, state, index) {
1038
+ const rawHasCredential = ["username", "password", "token", "apiKey"].some(
1039
+ (field) => rawPublication?.[field] !== void 0
1040
+ ) || rawPublication?.signature !== void 0;
1041
+ if (rawHasCredential || hasAnyResolvedCredential(resolvedPublication)) {
1042
+ addCredentialDiagnostic(
1043
+ state,
1044
+ rawPath,
1045
+ ["targets", index, "output", "publish"],
1046
+ "This registry does not support credentials in public SDK Config v1"
1047
+ );
1048
+ }
1049
+ }
1050
+ function warnForUnexpectedCredentialFields(rawPublication, resolvedPublication, allowedFields, rawPath, state, index, allowSignature = false) {
1051
+ const credentialFields = ["username", "password", "token", "apiKey"];
1052
+ const unexpectedFields = credentialFields.filter(
1053
+ (field) => !allowedFields.includes(field) && (rawPublication?.[field] !== void 0 || hasResolvedCredential(resolvedPublication, field))
1054
+ );
1055
+ const hasUnexpectedSignature = !allowSignature && (rawPublication?.signature !== void 0 || resolvedPublication.signature !== void 0);
1056
+ if (unexpectedFields.length > 0 || hasUnexpectedSignature) {
1057
+ addCredentialDiagnostic(
1058
+ state,
1059
+ rawPath,
1060
+ ["targets", index, "output", "publish"],
1061
+ "Fern publishing credentials or signing material include fields unsupported by this registry"
1062
+ );
1063
+ }
1064
+ }
1065
+ function hasResolvedCredential(value, field) {
1066
+ return resolvedCredentialValue(value, field) !== void 0;
1067
+ }
1068
+ function resolvedCredentialValue(value, field) {
1069
+ return stringValue(value[field]) ?? (isObject(value.credentials) ? stringValue(value.credentials[field]) : void 0);
1070
+ }
1071
+ function hasAnyResolvedCredential(value) {
1072
+ return ["username", "password", "token", "apiKey"].some(
1073
+ (field) => hasResolvedCredential(value, field)
1074
+ ) || value.signature !== void 0;
1075
+ }
1076
+ function isEnvironmentExpression(value) {
1077
+ return typeof value === "string" && /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(value);
1078
+ }
1079
+ function addCredentialDiagnostic(state, path, sdkConfigPath, reason) {
1080
+ state.credentialDiagnostics?.push({
1081
+ code: "FERN_OUTPUT_CREDENTIAL_OMITTED",
1082
+ severity: "warning",
1083
+ path,
1084
+ reason,
1085
+ sdkConfigPath,
1086
+ suggestedAction: `Configure ${sdkConfigPath.join(".")} with an environment expression such as \${CREDENTIAL_ENV_VAR}.`
1087
+ });
843
1088
  }
844
1089
  function publicationRegistry(type, language, sourcePath, index) {
845
1090
  if (type === "postman") {
@@ -947,6 +1192,7 @@ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
947
1192
  return {
948
1193
  ...mapping,
949
1194
  unsupportedFields: [
1195
+ ...state.credentialDiagnostics ?? [],
950
1196
  ...hasCredentials ? [
951
1197
  {
952
1198
  code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
@@ -1176,12 +1422,6 @@ var sdkConfigV1PublishRegistrySchema = zod.z.enum([
1176
1422
  "go",
1177
1423
  "composer"
1178
1424
  ]);
1179
- var registryCredentialsSchema = zod.z.strictObject({
1180
- username: nonEmptyStringSchema.optional(),
1181
- password: nonEmptyStringSchema.optional(),
1182
- token: nonEmptyStringSchema.optional(),
1183
- apiKey: nonEmptyStringSchema.optional()
1184
- });
1185
1425
  var mavenSignatureSchema = zod.z.strictObject({
1186
1426
  keyId: nonEmptyStringSchema,
1187
1427
  password: nonEmptyStringSchema,
@@ -1189,23 +1429,35 @@ var mavenSignatureSchema = zod.z.strictObject({
1189
1429
  });
1190
1430
  var commonPublishShape = {
1191
1431
  url: nonEmptyStringSchema.optional(),
1192
- /** Raw registry credentials. These values can be sensitive and must be handled as secrets. */
1193
- credentials: registryCredentialsSchema.optional(),
1194
1432
  releaseBranch: nonEmptyStringSchema.optional(),
1195
1433
  tolerateRepublish: zod.z.boolean().optional()
1196
1434
  };
1197
1435
  var sdkConfigV1PublishConfigSchema = zod.z.discriminatedUnion("registry", [
1198
- zod.z.strictObject({ registry: zod.z.literal("npm"), ...commonPublishShape }),
1199
- zod.z.strictObject({ registry: zod.z.literal("pypi"), ...commonPublishShape }),
1436
+ zod.z.strictObject({
1437
+ registry: zod.z.literal("npm"),
1438
+ token: nonEmptyStringSchema.optional(),
1439
+ ...commonPublishShape
1440
+ }),
1441
+ zod.z.strictObject({
1442
+ registry: zod.z.literal("pypi"),
1443
+ username: nonEmptyStringSchema.optional(),
1444
+ password: nonEmptyStringSchema.optional(),
1445
+ ...commonPublishShape
1446
+ }),
1200
1447
  zod.z.strictObject({
1201
1448
  registry: zod.z.literal("maven"),
1202
- /** Raw Maven signing material. These values can be sensitive and must be handled as secrets. */
1449
+ username: nonEmptyStringSchema.optional(),
1450
+ password: nonEmptyStringSchema.optional(),
1203
1451
  signature: mavenSignatureSchema.optional(),
1204
1452
  ...commonPublishShape
1205
1453
  }),
1206
1454
  zod.z.strictObject({ registry: zod.z.literal("nuget"), ...commonPublishShape }),
1207
1455
  zod.z.strictObject({ registry: zod.z.literal("rubygems"), ...commonPublishShape }),
1208
- zod.z.strictObject({ registry: zod.z.literal("crates"), ...commonPublishShape }),
1456
+ zod.z.strictObject({
1457
+ registry: zod.z.literal("crates"),
1458
+ token: nonEmptyStringSchema.optional(),
1459
+ ...commonPublishShape
1460
+ }),
1209
1461
  zod.z.strictObject({ registry: zod.z.literal("go"), ...commonPublishShape }),
1210
1462
  zod.z.strictObject({ registry: zod.z.literal("composer"), ...commonPublishShape })
1211
1463
  ]);
@@ -1213,7 +1465,12 @@ var reviewersSchema = zod.z.strictObject({
1213
1465
  teams: zod.z.array(nonEmptyStringSchema).optional(),
1214
1466
  users: zod.z.array(nonEmptyStringSchema).optional()
1215
1467
  });
1216
- var githubCredentialsSchema = registryCredentialsSchema;
1468
+ var githubCredentialsSchema = zod.z.strictObject({
1469
+ username: nonEmptyStringSchema.optional(),
1470
+ password: nonEmptyStringSchema.optional(),
1471
+ token: nonEmptyStringSchema.optional(),
1472
+ apiKey: nonEmptyStringSchema.optional()
1473
+ });
1217
1474
  var githubOutputSchema = zod.z.strictObject({
1218
1475
  repository: nonEmptyStringSchema,
1219
1476
  host: nonEmptyStringSchema.optional(),
@@ -1730,7 +1987,7 @@ function mapFernConfigToSdkConfigV1(input) {
1730
1987
  const mapped = input.group.generators.map((generator, index) => {
1731
1988
  const language = languages[index];
1732
1989
  const invocation = mapInvocation(generator, language, activeLanguages, index);
1733
- const outputMapping = generator.output ? { output: generator.output, unsupportedFields: [] } : mapOutput(generator, language, index);
1990
+ const outputMapping = mapOutput(generator, language, index);
1734
1991
  return {
1735
1992
  generator,
1736
1993
  language,
@@ -1789,6 +2046,7 @@ function mapFernConfigToSdkConfigV1(input) {
1789
2046
  source: input.source,
1790
2047
  ...optional("sdkVersion", input.sdkVersion),
1791
2048
  ...optional("apiVersion", input.apiVersion),
2049
+ ...optional("replay", input.replay),
1792
2050
  ...optionalObject("api", api),
1793
2051
  ...optionalObject("client", clients.shared),
1794
2052
  ...optionalObject("docs", docs.shared),