@postman/sdk-config 0.4.0 → 0.5.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.
package/dist/index.js CHANGED
@@ -28,6 +28,59 @@ var jsonValueSchema = z.lazy(
28
28
  ])
29
29
  );
30
30
  var jsonObjectSchema = z.record(z.string(), jsonValueSchema);
31
+ var hashAlgorithmSchema = z.enum(["sha1", "sha256", "sha384", "sha512"]);
32
+ var encodingSchema = z.enum(["base64", "hex"]);
33
+ var payloadComponentSchema = z.enum(["body", "timestamp", "notification-url", "message-id"]);
34
+ var payloadFormatSchema = z.strictObject({
35
+ components: z.array(payloadComponentSchema).min(1),
36
+ delimiter: z.string().optional(),
37
+ /**
38
+ * Set when the body is a form-encoded parameter map that must be canonicalized before signing:
39
+ * keys sorted, each key's values deduped and sorted, concatenated as key-value pairs.
40
+ */
41
+ bodySort: z.literal("alphabetical").optional()
42
+ });
43
+ var timestampSchema = z.strictObject({
44
+ header: nonEmptyStringSchema,
45
+ format: z.enum(["unix-seconds", "unix-millis", "iso8601"]).optional(),
46
+ /** Replay window in seconds. */
47
+ tolerance: z.number().positive().optional()
48
+ });
49
+ var bodyHashLocationSchema = z.discriminatedUnion("type", [
50
+ z.strictObject({
51
+ type: z.literal("query-parameter"),
52
+ name: nonEmptyStringSchema
53
+ })
54
+ ]);
55
+ var bodyHashBindingSchema = z.strictObject({
56
+ algorithm: hashAlgorithmSchema,
57
+ encoding: encodingSchema.optional(),
58
+ location: bodyHashLocationSchema
59
+ });
60
+ var urlNormalizationSchema = z.strictObject({
61
+ /** Try the URL with and without an explicit default port. */
62
+ portVariants: z.boolean().optional(),
63
+ /** Try the URL with the pre-RFC3986 query encoding (`+` for space, unescaped `*`). */
64
+ legacyQueryEncoding: z.boolean().optional()
65
+ }).refine(
66
+ ({ portVariants, legacyQueryEncoding }) => portVariants === true || legacyQueryEncoding === true,
67
+ { message: "url normalization must enable at least one variant" }
68
+ );
69
+ var webhookSignatureSchema = z.discriminatedUnion("type", [
70
+ z.strictObject({
71
+ type: z.literal("hmac"),
72
+ /** Request header carrying the signature. */
73
+ header: nonEmptyStringSchema,
74
+ algorithm: hashAlgorithmSchema.optional(),
75
+ encoding: encodingSchema.optional(),
76
+ /** Stripped from the header value before comparison, e.g. `sha256=`. */
77
+ signaturePrefix: z.string().optional(),
78
+ payloadFormat: payloadFormatSchema.optional(),
79
+ timestamp: timestampSchema.optional(),
80
+ bodyHashBinding: bodyHashBindingSchema.optional(),
81
+ urlNormalization: urlNormalizationSchema.optional()
82
+ })
83
+ ]);
31
84
 
32
85
  // src/sdk-config-domain/v1/api.ts
33
86
  var authVariableSchema = z.strictObject({
@@ -186,13 +239,19 @@ var apiConfigSchema = z.strictObject({
186
239
  * Absent means all audiences. A present empty array selects no tagged audience: untagged nodes
187
240
  * remain included, while every audience-tagged node is excluded.
188
241
  */
189
- audiences: z.array(nonEmptyStringSchema).optional()
242
+ audiences: z.array(nonEmptyStringSchema).optional(),
243
+ /**
244
+ * How the API signs the webhooks it sends, enabling a generated verification helper. API-wide, and
245
+ * independent of whether any webhook is modeled — see {@link webhookSignatureSchema}.
246
+ */
247
+ webhookSignature: webhookSignatureSchema.optional()
190
248
  });
191
249
 
192
250
  // src/sdk-config/v1/api.ts
193
251
  var sdkConfigV1AuthSchemeSchema = authSchemeSchema;
194
252
  var sdkConfigV1AuthConfigSchema = authConfigSchema;
195
253
  var sdkConfigV1ApiConfigSchema = apiConfigSchema;
254
+ var sdkConfigV1WebhookSignatureSchema = webhookSignatureSchema;
196
255
  var retryOverrideShape = {
197
256
  enabled: z.boolean().optional(),
198
257
  maxAttempts: z.number().int().min(1).optional(),
@@ -575,7 +634,13 @@ function mapOutput(generator, language, index) {
575
634
  const raw = isObject(generator.raw) ? generator.raw : void 0;
576
635
  const rawOutput = raw && isObject(raw.output) ? raw.output : void 0;
577
636
  const outputPath = ["group", "generators", index, "outputMode"];
578
- const state = { consumedPaths: /* @__PURE__ */ new Set() };
637
+ const state = { consumedPaths: /* @__PURE__ */ new Set(), credentialDiagnostics: [] };
638
+ if (generator.output) {
639
+ return {
640
+ output: sanitizeNormalizedOutput(generator.output, rawOutput, state, index),
641
+ unsupportedFields: state.credentialDiagnostics ?? []
642
+ };
643
+ }
579
644
  if (rawOutput?.location === "local-file-system") {
580
645
  if (isObject(generator.outputMode)) consume(state, [...outputPath, "type"]);
581
646
  return finishOutputMapping(
@@ -607,7 +672,7 @@ function mapOutput(generator, language, index) {
607
672
  return finishOutputMapping({ output: { delivery: "zip" } }, output, outputPath, state, index);
608
673
  case "github":
609
674
  return finishOutputMapping(
610
- githubOutput(output, output.publishInfo, language, outputPath, state, index),
675
+ githubOutput(output, output.publishInfo, rawOutput, language, outputPath, state, index),
611
676
  output,
612
677
  outputPath,
613
678
  state,
@@ -627,6 +692,7 @@ function mapOutput(generator, language, index) {
627
692
  githubOutput(
628
693
  output.githubV2,
629
694
  output.githubV2.publishInfo,
695
+ rawOutput,
630
696
  language,
631
697
  githubPath,
632
698
  state,
@@ -641,6 +707,7 @@ function mapOutput(generator, language, index) {
641
707
  case "publishV2": {
642
708
  const publication = mapPublication(
643
709
  output.publishV2,
710
+ rawOutput,
644
711
  language,
645
712
  [...outputPath, "publishV2"],
646
713
  state,
@@ -660,6 +727,7 @@ function mapOutput(generator, language, index) {
660
727
  case "publish": {
661
728
  const publication = mapLegacyPublication(
662
729
  output.registryOverrides,
730
+ rawOutput,
663
731
  language,
664
732
  [...outputPath, "registryOverrides"],
665
733
  state,
@@ -686,7 +754,22 @@ function mapOutput(generator, language, index) {
686
754
  );
687
755
  }
688
756
  }
689
- function githubOutput(value, publishInfo, language, sourcePath, state, index) {
757
+ function sanitizeNormalizedOutput(output, rawOutput, state, index) {
758
+ const publish = output.publish ? sanitizePublishConfig(output.publish, output.publish, rawOutput, state, index) : void 0;
759
+ const publishShape = publish ? { publish } : {};
760
+ if (output.delivery !== "github") return { ...output, ...publishShape };
761
+ const { credentials, ...github } = output.github;
762
+ if (credentials) {
763
+ addCredentialDiagnostic(
764
+ state,
765
+ ["group", "generators", index, "output", "github", "credentials"],
766
+ ["targets", index, "output", "github", "credentials"],
767
+ "Normalized GitHub credentials have no raw environment-expression provenance"
768
+ );
769
+ }
770
+ return { ...output, github, ...publishShape };
771
+ }
772
+ function githubOutput(value, publishInfo, rawOutput, language, sourcePath, state, index) {
690
773
  const owner = stringValue(value.owner);
691
774
  const repo = stringValue(value.repo);
692
775
  if (!owner || !repo)
@@ -699,14 +782,22 @@ function githubOutput(value, publishInfo, language, sourcePath, state, index) {
699
782
  );
700
783
  consume(state, [...sourcePath, "owner"]);
701
784
  consume(state, [...sourcePath, "repo"]);
702
- const publication = publishInfo ? mapPublication(publishInfo, language, [...sourcePath, "publishInfo"], state, index) : void 0;
785
+ const publication = publishInfo ? mapPublication(publishInfo, rawOutput, language, [...sourcePath, "publishInfo"], state, index) : void 0;
703
786
  const type = stringValue(value.type);
704
787
  const reviewers = mapReviewers(value.reviewers, [...sourcePath, "reviewers"], state);
705
788
  if (type) consume(state, [...sourcePath, "type"]);
706
789
  if (typeof value.makePr === "boolean") consume(state, [...sourcePath, "makePr"]);
707
790
  if (stringValue(value.host)) consume(state, [...sourcePath, "host"]);
708
791
  if (stringValue(value.branch)) consume(state, [...sourcePath, "branch"]);
709
- const credentials = mapCredentials(value.credentials, [...sourcePath, "credentials"], state);
792
+ consumeCredentialObject(value.credentials, [...sourcePath, "credentials"], state);
793
+ if (isObject(value.credentials)) {
794
+ addCredentialDiagnostic(
795
+ state,
796
+ [...sourcePath, "credentials"],
797
+ ["targets", index, "output", "github", "credentials"],
798
+ "GitHub credentials cannot be traced safely to raw environment expressions"
799
+ );
800
+ }
710
801
  return {
711
802
  output: {
712
803
  delivery: "github",
@@ -715,57 +806,35 @@ function githubOutput(value, publishInfo, language, sourcePath, state, index) {
715
806
  ...optional("host", stringValue(value.host)),
716
807
  ...optional("branch", stringValue(value.branch)),
717
808
  mode: value.makePr === true || type === "pullRequest" ? "pull-request" : type === "push" ? "push" : "release",
718
- ...optional("reviewers", reviewers),
719
- ...optional("credentials", credentials)
809
+ ...optional("reviewers", reviewers)
720
810
  },
721
811
  ...publication ? { publish: publication.publish } : {}
722
812
  },
723
813
  ...optional("package", publication?.package)
724
814
  };
725
815
  }
726
- function mapCredentials(value, sourcePath, state) {
727
- if (!isObject(value)) return void 0;
728
- return credentialsFromObject(value, sourcePath, state);
729
- }
730
- function mapInlineCredentials(value, sourcePath, state) {
731
- const credentials = mapCredentials(value.credentials, [...sourcePath, "credentials"], state);
732
- if (credentials) return credentials;
733
- return credentialsFromObject(value, sourcePath, state);
734
- }
735
- function credentialsFromObject(value, sourcePath, state) {
736
- const credentials = {};
737
- const username = stringValue(value.username);
738
- const password = stringValue(value.password);
739
- const token = stringValue(value.token);
740
- const apiKey = stringValue(value.apiKey);
741
- if (username) {
742
- credentials.username = username;
743
- consume(state, [...sourcePath, "username"]);
744
- }
745
- if (password) {
746
- credentials.password = password;
747
- consume(state, [...sourcePath, "password"]);
748
- }
749
- if (token) {
750
- credentials.token = token;
751
- consume(state, [...sourcePath, "token"]);
752
- }
753
- if (apiKey) {
754
- credentials.apiKey = apiKey;
755
- consume(state, [...sourcePath, "apiKey"]);
756
- }
757
- return Object.keys(credentials).length === 0 ? void 0 : credentials;
758
- }
759
- function mapMavenSignature(value, sourcePath, state) {
760
- if (!isObject(value)) return void 0;
761
- const keyId = stringValue(value.keyId);
762
- const password = stringValue(value.password);
763
- const secretKey = stringValue(value.secretKey);
764
- if (!keyId || !password || !secretKey) return void 0;
765
- consume(state, [...sourcePath, "keyId"]);
766
- consume(state, [...sourcePath, "password"]);
767
- consume(state, [...sourcePath, "secretKey"]);
768
- return { keyId, password, secretKey };
816
+ function consumeCredentialObject(value, sourcePath, state) {
817
+ if (!isObject(value)) return;
818
+ for (const field of ["username", "password", "token", "apiKey"]) {
819
+ if (stringValue(value[field])) consume(state, [...sourcePath, field]);
820
+ }
821
+ }
822
+ function consumeResolvedCredentials(value, sourcePath, state) {
823
+ for (const field of ["username", "password", "token", "apiKey"]) {
824
+ if (stringValue(value[field])) {
825
+ consume(state, [...sourcePath, field]);
826
+ }
827
+ }
828
+ if (isObject(value.credentials)) {
829
+ for (const field of ["username", "password", "token", "apiKey"]) {
830
+ if (stringValue(value.credentials[field])) {
831
+ consume(state, [...sourcePath, "credentials", field]);
832
+ }
833
+ }
834
+ }
835
+ if (isObject(value.signature)) {
836
+ consume(state, [...sourcePath, "signature"]);
837
+ }
769
838
  }
770
839
  function mapReviewers(value, sourcePath, state) {
771
840
  if (Array.isArray(value)) {
@@ -794,7 +863,7 @@ function reviewerNames(value, expectedType, sourcePath, state) {
794
863
  });
795
864
  return names.length ? names : void 0;
796
865
  }
797
- function mapPublication(value, language, sourcePath, state, index) {
866
+ function mapPublication(value, rawOutput, language, sourcePath, state, index) {
798
867
  if (!isObject(value))
799
868
  fail(
800
869
  "FERN_PUBLICATION_INVALID",
@@ -810,13 +879,19 @@ function mapPublication(value, language, sourcePath, state, index) {
810
879
  const registry = publicationRegistry(type, language, [...sourcePath, "type"], index);
811
880
  const registryUrl = stringValue(nested.registryUrl);
812
881
  if (registryUrl) consume(state, [...nestedPath, "registryUrl"]);
813
- const credentials = mapInlineCredentials(nested, nestedPath, state);
882
+ consumeResolvedCredentials(nested, nestedPath, state);
883
+ const publish = sanitizePublishConfig(
884
+ compact({ registry, url: registryUrl }),
885
+ nested,
886
+ rawOutput,
887
+ state,
888
+ index
889
+ );
814
890
  if (registry === "maven") {
815
891
  const coordinate = stringValue(nested.coordinate);
816
- const signature = mapMavenSignature(nested.signature, [...nestedPath, "signature"], state);
817
892
  if (coordinate) consume(state, [...nestedPath, "coordinate"]);
818
893
  return {
819
- publish: compact({ registry, url: registryUrl, credentials, signature }),
894
+ publish,
820
895
  ...coordinate ? { package: mavenPackage(coordinate, [...nestedPath, "coordinate"], index) } : {}
821
896
  };
822
897
  }
@@ -825,15 +900,244 @@ function mapPublication(value, language, sourcePath, state, index) {
825
900
  if (packageName) consume(state, [...nestedPath, packageNameField]);
826
901
  const metadata = registry === "pypi" ? mapPypiMetadata(nested.pypiMetadata, nestedPath, state) : {};
827
902
  return {
828
- publish: compact({ registry, url: registryUrl, credentials }),
903
+ publish,
829
904
  ...packageName || Object.keys(metadata).length ? { package: { ...optional("packageName", packageName), ...metadata } } : {}
830
905
  };
831
906
  }
832
- function mapLegacyPublication(value, language, sourcePath, state, index) {
907
+ function sanitizePublishConfig(publish, resolvedPublication, rawOutput, state, index) {
908
+ const rawPublication = rawOutput?.location === publish.registry ? rawOutput : void 0;
909
+ const rawPath = ["group", "generators", index, "output"];
910
+ if (publish.registry === "npm" || publish.registry === "crates") {
911
+ const token = mapCredentialExpression(
912
+ rawPublication,
913
+ resolvedPublication,
914
+ "token",
915
+ rawPath,
916
+ state,
917
+ index
918
+ );
919
+ warnForUnexpectedCredentialFields(
920
+ rawPublication,
921
+ resolvedPublication,
922
+ ["token"],
923
+ rawPath,
924
+ state,
925
+ index
926
+ );
927
+ return compact({
928
+ registry: publish.registry,
929
+ url: publish.url,
930
+ releaseBranch: publish.releaseBranch,
931
+ tolerateRepublish: publish.tolerateRepublish,
932
+ token
933
+ });
934
+ }
935
+ if (publish.registry === "pypi") {
936
+ const { username, password } = mapPypiCredentialExpressions(
937
+ rawPublication,
938
+ resolvedPublication,
939
+ rawPath,
940
+ state,
941
+ index
942
+ );
943
+ warnForUnexpectedCredentialFields(
944
+ rawPublication,
945
+ resolvedPublication,
946
+ ["username", "password", "token"],
947
+ rawPath,
948
+ state,
949
+ index
950
+ );
951
+ return compact({
952
+ registry: publish.registry,
953
+ url: publish.url,
954
+ releaseBranch: publish.releaseBranch,
955
+ tolerateRepublish: publish.tolerateRepublish,
956
+ username,
957
+ password
958
+ });
959
+ }
960
+ if (publish.registry === "maven") {
961
+ const username = mapCredentialExpression(
962
+ rawPublication,
963
+ resolvedPublication,
964
+ "username",
965
+ rawPath,
966
+ state,
967
+ index
968
+ );
969
+ const password = mapCredentialExpression(
970
+ rawPublication,
971
+ resolvedPublication,
972
+ "password",
973
+ rawPath,
974
+ state,
975
+ index
976
+ );
977
+ const signature = mapMavenSignatureExpressions(
978
+ rawPublication?.signature,
979
+ resolvedPublication.signature,
980
+ [...rawPath, "signature"],
981
+ state,
982
+ index
983
+ );
984
+ warnForUnexpectedCredentialFields(
985
+ rawPublication,
986
+ resolvedPublication,
987
+ ["username", "password"],
988
+ rawPath,
989
+ state,
990
+ index,
991
+ true
992
+ );
993
+ return compact({
994
+ registry: publish.registry,
995
+ url: publish.url,
996
+ releaseBranch: publish.releaseBranch,
997
+ tolerateRepublish: publish.tolerateRepublish,
998
+ username,
999
+ password,
1000
+ signature
1001
+ });
1002
+ }
1003
+ warnForUnrepresentableCredentials(rawPublication, resolvedPublication, rawPath, state, index);
1004
+ return compact({
1005
+ registry: publish.registry,
1006
+ url: publish.url,
1007
+ releaseBranch: publish.releaseBranch,
1008
+ tolerateRepublish: publish.tolerateRepublish
1009
+ });
1010
+ }
1011
+ function mapLegacyPublication(value, rawOutput, language, sourcePath, state, index) {
833
1012
  const registry = defaultRegistry(language, sourcePath, index);
834
1013
  const overrides = isObject(value) ? value : {};
835
1014
  const override = isObject(overrides[registry]) ? overrides[registry] : {};
836
- return mapPublication(override, language, [...sourcePath, registry], state, index);
1015
+ return mapPublication(override, rawOutput, language, [...sourcePath, registry], state, index);
1016
+ }
1017
+ function mapCredentialExpression(rawPublication, resolvedPublication, field, rawPath, state, index) {
1018
+ const rawValue = rawPublication?.[field];
1019
+ if (isEnvironmentExpression(rawValue)) return rawValue;
1020
+ if (rawValue !== void 0 || hasResolvedCredential(resolvedPublication, field)) {
1021
+ addCredentialDiagnostic(
1022
+ state,
1023
+ [...rawPath, field],
1024
+ ["targets", index, "output", "publish", field],
1025
+ `Fern publishing ${field} is not an exact environment expression`
1026
+ );
1027
+ }
1028
+ return void 0;
1029
+ }
1030
+ function mapPypiCredentialExpressions(rawPublication, resolvedPublication, rawPath, state, index) {
1031
+ const rawToken = rawPublication?.token;
1032
+ if (isEnvironmentExpression(rawToken)) {
1033
+ return { username: "__token__", password: rawToken };
1034
+ }
1035
+ const resolvedUsesToken = resolvedCredentialValue(resolvedPublication, "username") === "__token__";
1036
+ if (rawToken !== void 0 || resolvedUsesToken) {
1037
+ addCredentialDiagnostic(
1038
+ state,
1039
+ [...rawPath, "token"],
1040
+ ["targets", index, "output", "publish", "password"],
1041
+ "Fern PyPI token is not an exact raw environment expression"
1042
+ );
1043
+ return {};
1044
+ }
1045
+ return {
1046
+ ...optional(
1047
+ "username",
1048
+ mapCredentialExpression(
1049
+ rawPublication,
1050
+ resolvedPublication,
1051
+ "username",
1052
+ rawPath,
1053
+ state,
1054
+ index
1055
+ )
1056
+ ),
1057
+ ...optional(
1058
+ "password",
1059
+ mapCredentialExpression(
1060
+ rawPublication,
1061
+ resolvedPublication,
1062
+ "password",
1063
+ rawPath,
1064
+ state,
1065
+ index
1066
+ )
1067
+ )
1068
+ };
1069
+ }
1070
+ function mapMavenSignatureExpressions(rawValue, resolvedValue, rawPath, state, index) {
1071
+ if (isObject(rawValue)) {
1072
+ const yamlValues = [rawValue["key-id"], rawValue.password, rawValue["secret-key"]];
1073
+ const projectedValues = [rawValue.keyId, rawValue.password, rawValue.secretKey];
1074
+ const values = yamlValues.every(isEnvironmentExpression) ? yamlValues : projectedValues.every(isEnvironmentExpression) ? projectedValues : void 0;
1075
+ if (values) {
1076
+ const [keyId, password, secretKey] = values;
1077
+ return { keyId, password, secretKey };
1078
+ }
1079
+ }
1080
+ if (rawValue !== void 0 || isObject(resolvedValue)) {
1081
+ addCredentialDiagnostic(
1082
+ state,
1083
+ rawPath,
1084
+ ["targets", index, "output", "publish", "signature"],
1085
+ "Maven signing credentials are incomplete or not exact environment expressions"
1086
+ );
1087
+ }
1088
+ return void 0;
1089
+ }
1090
+ function warnForUnrepresentableCredentials(rawPublication, resolvedPublication, rawPath, state, index) {
1091
+ const rawHasCredential = ["username", "password", "token", "apiKey"].some(
1092
+ (field) => rawPublication?.[field] !== void 0
1093
+ ) || rawPublication?.signature !== void 0;
1094
+ if (rawHasCredential || hasAnyResolvedCredential(resolvedPublication)) {
1095
+ addCredentialDiagnostic(
1096
+ state,
1097
+ rawPath,
1098
+ ["targets", index, "output", "publish"],
1099
+ "This registry does not support credentials in public SDK Config v1"
1100
+ );
1101
+ }
1102
+ }
1103
+ function warnForUnexpectedCredentialFields(rawPublication, resolvedPublication, allowedFields, rawPath, state, index, allowSignature = false) {
1104
+ const credentialFields = ["username", "password", "token", "apiKey"];
1105
+ const unexpectedFields = credentialFields.filter(
1106
+ (field) => !allowedFields.includes(field) && (rawPublication?.[field] !== void 0 || hasResolvedCredential(resolvedPublication, field))
1107
+ );
1108
+ const hasUnexpectedSignature = !allowSignature && (rawPublication?.signature !== void 0 || resolvedPublication.signature !== void 0);
1109
+ if (unexpectedFields.length > 0 || hasUnexpectedSignature) {
1110
+ addCredentialDiagnostic(
1111
+ state,
1112
+ rawPath,
1113
+ ["targets", index, "output", "publish"],
1114
+ "Fern publishing credentials or signing material include fields unsupported by this registry"
1115
+ );
1116
+ }
1117
+ }
1118
+ function hasResolvedCredential(value, field) {
1119
+ return resolvedCredentialValue(value, field) !== void 0;
1120
+ }
1121
+ function resolvedCredentialValue(value, field) {
1122
+ return stringValue(value[field]) ?? (isObject(value.credentials) ? stringValue(value.credentials[field]) : void 0);
1123
+ }
1124
+ function hasAnyResolvedCredential(value) {
1125
+ return ["username", "password", "token", "apiKey"].some(
1126
+ (field) => hasResolvedCredential(value, field)
1127
+ ) || value.signature !== void 0;
1128
+ }
1129
+ function isEnvironmentExpression(value) {
1130
+ return typeof value === "string" && /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(value);
1131
+ }
1132
+ function addCredentialDiagnostic(state, path, sdkConfigPath, reason) {
1133
+ state.credentialDiagnostics?.push({
1134
+ code: "FERN_OUTPUT_CREDENTIAL_OMITTED",
1135
+ severity: "warning",
1136
+ path,
1137
+ reason,
1138
+ sdkConfigPath,
1139
+ suggestedAction: `Configure ${sdkConfigPath.join(".")} with an environment expression such as \${CREDENTIAL_ENV_VAR}.`
1140
+ });
837
1141
  }
838
1142
  function publicationRegistry(type, language, sourcePath, index) {
839
1143
  if (type === "postman") {
@@ -941,6 +1245,7 @@ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
941
1245
  return {
942
1246
  ...mapping,
943
1247
  unsupportedFields: [
1248
+ ...state.credentialDiagnostics ?? [],
944
1249
  ...hasCredentials ? [
945
1250
  {
946
1251
  code: "FERN_OUTPUT_CREDENTIAL_UNSUPPORTED",
@@ -1170,12 +1475,6 @@ var sdkConfigV1PublishRegistrySchema = z.enum([
1170
1475
  "go",
1171
1476
  "composer"
1172
1477
  ]);
1173
- var registryCredentialsSchema = z.strictObject({
1174
- username: nonEmptyStringSchema.optional(),
1175
- password: nonEmptyStringSchema.optional(),
1176
- token: nonEmptyStringSchema.optional(),
1177
- apiKey: nonEmptyStringSchema.optional()
1178
- });
1179
1478
  var mavenSignatureSchema = z.strictObject({
1180
1479
  keyId: nonEmptyStringSchema,
1181
1480
  password: nonEmptyStringSchema,
@@ -1183,23 +1482,35 @@ var mavenSignatureSchema = z.strictObject({
1183
1482
  });
1184
1483
  var commonPublishShape = {
1185
1484
  url: nonEmptyStringSchema.optional(),
1186
- /** Raw registry credentials. These values can be sensitive and must be handled as secrets. */
1187
- credentials: registryCredentialsSchema.optional(),
1188
1485
  releaseBranch: nonEmptyStringSchema.optional(),
1189
1486
  tolerateRepublish: z.boolean().optional()
1190
1487
  };
1191
1488
  var sdkConfigV1PublishConfigSchema = z.discriminatedUnion("registry", [
1192
- z.strictObject({ registry: z.literal("npm"), ...commonPublishShape }),
1193
- z.strictObject({ registry: z.literal("pypi"), ...commonPublishShape }),
1489
+ z.strictObject({
1490
+ registry: z.literal("npm"),
1491
+ token: nonEmptyStringSchema.optional(),
1492
+ ...commonPublishShape
1493
+ }),
1494
+ z.strictObject({
1495
+ registry: z.literal("pypi"),
1496
+ username: nonEmptyStringSchema.optional(),
1497
+ password: nonEmptyStringSchema.optional(),
1498
+ ...commonPublishShape
1499
+ }),
1194
1500
  z.strictObject({
1195
1501
  registry: z.literal("maven"),
1196
- /** Raw Maven signing material. These values can be sensitive and must be handled as secrets. */
1502
+ username: nonEmptyStringSchema.optional(),
1503
+ password: nonEmptyStringSchema.optional(),
1197
1504
  signature: mavenSignatureSchema.optional(),
1198
1505
  ...commonPublishShape
1199
1506
  }),
1200
1507
  z.strictObject({ registry: z.literal("nuget"), ...commonPublishShape }),
1201
1508
  z.strictObject({ registry: z.literal("rubygems"), ...commonPublishShape }),
1202
- z.strictObject({ registry: z.literal("crates"), ...commonPublishShape }),
1509
+ z.strictObject({
1510
+ registry: z.literal("crates"),
1511
+ token: nonEmptyStringSchema.optional(),
1512
+ ...commonPublishShape
1513
+ }),
1203
1514
  z.strictObject({ registry: z.literal("go"), ...commonPublishShape }),
1204
1515
  z.strictObject({ registry: z.literal("composer"), ...commonPublishShape })
1205
1516
  ]);
@@ -1207,7 +1518,12 @@ var reviewersSchema = z.strictObject({
1207
1518
  teams: z.array(nonEmptyStringSchema).optional(),
1208
1519
  users: z.array(nonEmptyStringSchema).optional()
1209
1520
  });
1210
- var githubCredentialsSchema = registryCredentialsSchema;
1521
+ var githubCredentialsSchema = z.strictObject({
1522
+ username: nonEmptyStringSchema.optional(),
1523
+ password: nonEmptyStringSchema.optional(),
1524
+ token: nonEmptyStringSchema.optional(),
1525
+ apiKey: nonEmptyStringSchema.optional()
1526
+ });
1211
1527
  var githubOutputSchema = z.strictObject({
1212
1528
  repository: nonEmptyStringSchema,
1213
1529
  host: nonEmptyStringSchema.optional(),
@@ -1724,7 +2040,7 @@ function mapFernConfigToSdkConfigV1(input) {
1724
2040
  const mapped = input.group.generators.map((generator, index) => {
1725
2041
  const language = languages[index];
1726
2042
  const invocation = mapInvocation(generator, language, activeLanguages, index);
1727
- const outputMapping = generator.output ? { output: generator.output, unsupportedFields: [] } : mapOutput(generator, language, index);
2043
+ const outputMapping = mapOutput(generator, language, index);
1728
2044
  return {
1729
2045
  generator,
1730
2046
  language,
@@ -1783,6 +2099,7 @@ function mapFernConfigToSdkConfigV1(input) {
1783
2099
  source: input.source,
1784
2100
  ...optional("sdkVersion", input.sdkVersion),
1785
2101
  ...optional("apiVersion", input.apiVersion),
2102
+ ...optional("replay", input.replay),
1786
2103
  ...optionalObject("api", api),
1787
2104
  ...optionalObject("client", clients.shared),
1788
2105
  ...optionalObject("docs", docs.shared),
@@ -2113,7 +2430,7 @@ function mapLanguageConfig(language, config, state, packageConfig, basePath) {
2113
2430
  case "rust":
2114
2431
  return mapRust(config, state, packageConfig, basePath);
2115
2432
  case "swift":
2116
- return compact({ moduleName: takeString(config, ["moduleName"], state, basePath) });
2433
+ return mapSwift(config, state, basePath);
2117
2434
  case "cli":
2118
2435
  return mapCli(config, state, packageConfig, basePath);
2119
2436
  case "terraform":
@@ -2280,6 +2597,12 @@ function mapRust(config, state, packageConfig, basePath) {
2280
2597
  defaultFeatures: takeStringArray(config, ["defaultFeatures"], state, basePath)
2281
2598
  });
2282
2599
  }
2600
+ function mapSwift(config, state, basePath) {
2601
+ return compact({
2602
+ moduleName: takeString(config, ["moduleName"], state, basePath),
2603
+ nullableAsOptional: takeBoolean(config, ["nullableAsOptional"], state, basePath)
2604
+ });
2605
+ }
2283
2606
  function mapCli(config, state, packageConfig, basePath) {
2284
2607
  const identity = takeObject(config, ["packageIdentity"], state, basePath);
2285
2608
  if (identity) {
@@ -2715,7 +3038,7 @@ var credentialResolutionSchema = z.enum([
2715
3038
  "resolved-by-orchestrator",
2716
3039
  "resolved-by-fiddle"
2717
3040
  ]);
2718
- var registryCredentialsSchema2 = z.strictObject({
3041
+ var registryCredentialsSchema = z.strictObject({
2719
3042
  username: nonEmptyStringSchema.optional(),
2720
3043
  password: nonEmptyStringSchema.optional(),
2721
3044
  token: nonEmptyStringSchema.optional(),
@@ -2726,7 +3049,7 @@ var commonPublishShape2 = {
2726
3049
  /** Reference to registry publishing credentials. */
2727
3050
  credentialsRef: nonEmptyStringSchema.optional(),
2728
3051
  /** Raw registry credentials. These values can be sensitive and must be handled as secrets. */
2729
- credentials: registryCredentialsSchema2.optional(),
3052
+ credentials: registryCredentialsSchema.optional(),
2730
3053
  /**
2731
3054
  * Registry-specific package version override. If omitted, the external publisher/orchestrator may
2732
3055
  * fall back to target.sdkVersion.
@@ -2831,7 +3154,7 @@ var githubOutputSchema2 = z.strictObject({
2831
3154
  /** Reference to GitHub credentials. */
2832
3155
  credentialsRef: nonEmptyStringSchema.optional(),
2833
3156
  /** Raw GitHub credentials. These values can be sensitive and must be handled as secrets. */
2834
- credentials: registryCredentialsSchema2.optional(),
3157
+ credentials: registryCredentialsSchema.optional(),
2835
3158
  privateRepository: z.boolean().optional(),
2836
3159
  /** GitHub license block scoped to repository delivery. */
2837
3160
  license: githubLicenseSchema.optional(),
@@ -3071,6 +3394,6 @@ function parseSdkConfigIrV1(value) {
3071
3394
  return sdkConfigIrV1Schema.parse(value);
3072
3395
  }
3073
3396
 
3074
- export { FernConfigMappingError, SDK_CONFIG_IR_V1_SCHEMA_VERSION, SDK_CONFIG_V1_SCHEMA_VERSION, apiConfigSchema, apiImportSettingsSchema, authConfigSchema, authSchemeSchema, cliGenerationConfigSchema, clientConfigOverrideSchema, clientConfigSchema, clientRetryOverrideSchema, compatibilityConfigSchema, composerPackageNameSchema, csharpGenerationConfigSchema, dependencySchema, docsConfigSchema, exactSemverSchema, generationConfigSchema, goGenerationConfigSchema, goModulePathSchema, javaGenerationConfigSchema, jsonObjectSchema, jsonValueSchema, kotlinGenerationConfigSchema, languageGenerationConfigSchema, legacyInputSchema, mapFernConfigToSdkConfigV1, mcpAvailabilityStatuses, mcpGenerationConfigSchema, nonEmptyStringSchema, outputConfigSchema, packageConfigSchema, parseSdkConfigIrV1, parseSdkConfigV1, phpGenerationConfigSchema, publishConfigSchema, publishRegistrySchema, pythonGenerationConfigSchema, readmeCustomSectionSchema, readmeEndpointSchema, relativePathSchema, replayConfigSchema, rubyGenerationConfigSchema, rustGenerationConfigSchema, sdkConfigIrV1Schema, sdkConfigV1ApiConfigSchema, sdkConfigV1AuthConfigSchema, sdkConfigV1AuthSchemeSchema, cliGenerationConfigSchema as sdkConfigV1CliGenerationConfigSchema, sdkConfigV1ClientConfigOverrideSchema, sdkConfigV1ClientConfigSchema, composerPackageNameSchema as sdkConfigV1ComposerPackageNameSchema, csharpGenerationConfigSchema as sdkConfigV1CsharpGenerationConfigSchema, sdkConfigV1DependencySchema, sdkConfigV1DocsConfigSchema, exactSemverSchema as sdkConfigV1ExactSemverSchema, sdkConfigV1GenerationConfigOverrideSchema, sdkConfigV1GenerationConfigSchema, goGenerationConfigSchema as sdkConfigV1GoGenerationConfigSchema, goModulePathSchema as sdkConfigV1GoModulePathSchema, javaGenerationConfigSchema as sdkConfigV1JavaGenerationConfigSchema, kotlinGenerationConfigSchema as sdkConfigV1KotlinGenerationConfigSchema, mcpGenerationConfigSchema as sdkConfigV1McpGenerationConfigSchema, nonEmptyStringSchema as sdkConfigV1NonEmptyStringSchema, sdkConfigV1OutputConfigSchema, sdkConfigV1PackageConfigSchema, phpGenerationConfigSchema as sdkConfigV1PhpGenerationConfigSchema, sdkConfigV1PublishConfigSchema, sdkConfigV1PublishRegistrySchema, pythonGenerationConfigSchema as sdkConfigV1PythonGenerationConfigSchema, sdkConfigV1ReadmeCustomSectionSchema, sdkConfigV1ReadmeEndpointSchema, relativePathSchema as sdkConfigV1RelativePathSchema, sdkConfigV1ReplayConfigSchema, rubyGenerationConfigSchema as sdkConfigV1RubyGenerationConfigSchema, rustGenerationConfigSchema as sdkConfigV1RustGenerationConfigSchema, sdkConfigV1Schema, sdkConfigV1SourceConfigSchema, sdkConfigV1SourceSpecSchema, swiftGenerationConfigSchema as sdkConfigV1SwiftGenerationConfigSchema, sdkConfigV1TargetSchema, terraformGenerationConfigSchema as sdkConfigV1TerraformGenerationConfigSchema, typescriptGenerationConfigSchema as sdkConfigV1TypescriptGenerationConfigSchema, sourceConfigSchema, sourceSpecConfigSchema, sourceSpecTypeSchema, splitSdkConfigV1TargetGeneration, swiftGenerationConfigSchema, targetConfigSchema, targetLanguageSchema, terraformGenerationConfigSchema, typescriptGenerationConfigSchema, unsupportedFieldSchema, validateSdkConfigV1 };
3397
+ export { FernConfigMappingError, SDK_CONFIG_IR_V1_SCHEMA_VERSION, SDK_CONFIG_V1_SCHEMA_VERSION, apiConfigSchema, apiImportSettingsSchema, authConfigSchema, authSchemeSchema, cliGenerationConfigSchema, clientConfigOverrideSchema, clientConfigSchema, clientRetryOverrideSchema, compatibilityConfigSchema, composerPackageNameSchema, csharpGenerationConfigSchema, dependencySchema, docsConfigSchema, exactSemverSchema, generationConfigSchema, goGenerationConfigSchema, goModulePathSchema, javaGenerationConfigSchema, jsonObjectSchema, jsonValueSchema, kotlinGenerationConfigSchema, languageGenerationConfigSchema, legacyInputSchema, mapFernConfigToSdkConfigV1, mcpAvailabilityStatuses, mcpGenerationConfigSchema, nonEmptyStringSchema, outputConfigSchema, packageConfigSchema, parseSdkConfigIrV1, parseSdkConfigV1, phpGenerationConfigSchema, publishConfigSchema, publishRegistrySchema, pythonGenerationConfigSchema, readmeCustomSectionSchema, readmeEndpointSchema, relativePathSchema, replayConfigSchema, rubyGenerationConfigSchema, rustGenerationConfigSchema, sdkConfigIrV1Schema, sdkConfigV1ApiConfigSchema, sdkConfigV1AuthConfigSchema, sdkConfigV1AuthSchemeSchema, cliGenerationConfigSchema as sdkConfigV1CliGenerationConfigSchema, sdkConfigV1ClientConfigOverrideSchema, sdkConfigV1ClientConfigSchema, composerPackageNameSchema as sdkConfigV1ComposerPackageNameSchema, csharpGenerationConfigSchema as sdkConfigV1CsharpGenerationConfigSchema, sdkConfigV1DependencySchema, sdkConfigV1DocsConfigSchema, exactSemverSchema as sdkConfigV1ExactSemverSchema, sdkConfigV1GenerationConfigOverrideSchema, sdkConfigV1GenerationConfigSchema, goGenerationConfigSchema as sdkConfigV1GoGenerationConfigSchema, goModulePathSchema as sdkConfigV1GoModulePathSchema, javaGenerationConfigSchema as sdkConfigV1JavaGenerationConfigSchema, kotlinGenerationConfigSchema as sdkConfigV1KotlinGenerationConfigSchema, mcpGenerationConfigSchema as sdkConfigV1McpGenerationConfigSchema, nonEmptyStringSchema as sdkConfigV1NonEmptyStringSchema, sdkConfigV1OutputConfigSchema, sdkConfigV1PackageConfigSchema, phpGenerationConfigSchema as sdkConfigV1PhpGenerationConfigSchema, sdkConfigV1PublishConfigSchema, sdkConfigV1PublishRegistrySchema, pythonGenerationConfigSchema as sdkConfigV1PythonGenerationConfigSchema, sdkConfigV1ReadmeCustomSectionSchema, sdkConfigV1ReadmeEndpointSchema, relativePathSchema as sdkConfigV1RelativePathSchema, sdkConfigV1ReplayConfigSchema, rubyGenerationConfigSchema as sdkConfigV1RubyGenerationConfigSchema, rustGenerationConfigSchema as sdkConfigV1RustGenerationConfigSchema, sdkConfigV1Schema, sdkConfigV1SourceConfigSchema, sdkConfigV1SourceSpecSchema, swiftGenerationConfigSchema as sdkConfigV1SwiftGenerationConfigSchema, sdkConfigV1TargetSchema, terraformGenerationConfigSchema as sdkConfigV1TerraformGenerationConfigSchema, typescriptGenerationConfigSchema as sdkConfigV1TypescriptGenerationConfigSchema, sdkConfigV1WebhookSignatureSchema, sourceConfigSchema, sourceSpecConfigSchema, sourceSpecTypeSchema, splitSdkConfigV1TargetGeneration, swiftGenerationConfigSchema, targetConfigSchema, targetLanguageSchema, terraformGenerationConfigSchema, typescriptGenerationConfigSchema, unsupportedFieldSchema, validateSdkConfigV1, webhookSignatureSchema };
3075
3398
  //# sourceMappingURL=index.js.map
3076
3399
  //# sourceMappingURL=index.js.map