@postman/sdk-config 0.3.5 → 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.
package/README.md CHANGED
@@ -39,6 +39,7 @@ const input: SdkConfigV1Input = {
39
39
  },
40
40
  client: { timeoutMs: 30_000 },
41
41
  output: { delivery: 'zip', fileName: 'example-typescript.zip' },
42
+ replay: { enabled: false },
42
43
  docs: { includeApiReference: true },
43
44
  generation: { includeWatermark: true },
44
45
  targets: [
@@ -59,7 +60,8 @@ Use `parseSdkConfigV1` when entering the runtime boundary and materializing the
59
60
  defaults. For validation without throwing, use the exported schema:
60
61
 
61
62
  Empty top-level `api`, `client`, `package`, `docs`, and `generation` blocks may be omitted from the
62
- customer document. Runtime parsing materializes those blocks and their versioned defaults.
63
+ customer document. Runtime parsing materializes those blocks and their versioned defaults. The
64
+ optional top-level `replay` block is preserved only when authored.
63
65
 
64
66
  ```ts
65
67
  import { sdkConfigV1Schema } from '@postman/sdk-config/sdk-config/v1';
@@ -71,10 +73,13 @@ if (!result.success) {
71
73
  ```
72
74
 
73
75
  SDK Config objects are strict. Unknown fields, duplicate language targets, incompatible package
74
- publication settings, and non-exact generator versions are rejected. Publishing credentials and
75
- signing material may be provided under `output.publish.credentials`, Maven
76
- `output.publish.signature`, or `output.github.credentials`; these fields can contain raw secrets and
77
- must be handled accordingly by clients and servers.
76
+ publication settings, and non-exact generator versions are rejected. npm and crates use
77
+ `output.publish.token`, PyPI and Maven use flat `username` and `password` fields, and Maven may also
78
+ use a complete `signature` object. Configure these fields with environment expressions such as
79
+ `${NPM_TOKEN}` rather than literal credentials. Clients must resolve and transport credentials using
80
+ a dedicated secret channel and remove them from generation payloads, logs, and stored artifacts.
81
+ Fern migration preserves a credential only when the raw `generators.yml` value is exactly an
82
+ environment expression; normalized, resolved, or literal values are omitted with a warning.
78
83
 
79
84
  `SdkConfigV1` accepts customer-facing local source paths and HTTP(S) source URLs, but not
80
85
  server-owned signed URLs or artifact metadata. See the
package/dist/index.cjs CHANGED
@@ -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"]);
750
- }
751
- if (password) {
752
- credentials.password = password;
753
- consume(state, [...sourcePath, "password"]);
754
- }
755
- if (token) {
756
- credentials.token = token;
757
- consume(state, [...sourcePath, "token"]);
758
- }
759
- if (apiKey) {
760
- credentials.apiKey = apiKey;
761
- consume(state, [...sourcePath, "apiKey"]);
762
- }
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 };
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]);
767
+ }
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
+ }
774
+ }
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
+ }
781
+ }
782
+ if (isObject(value.signature)) {
783
+ consume(state, [...sourcePath, "signature"]);
784
+ }
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(),
@@ -1248,6 +1505,9 @@ var sdkConfigV1OutputConfigSchema = zod.z.discriminatedUnion(
1248
1505
  // src/sdk-config/v1/package.ts
1249
1506
  var sdkConfigV1DependencySchema = dependencySchema;
1250
1507
  var sdkConfigV1PackageConfigSchema = packageConfigSchema;
1508
+ var sdkConfigV1ReplayConfigSchema = zod.z.strictObject({
1509
+ enabled: zod.z.boolean()
1510
+ });
1251
1511
  var apiImportSettingsSchema = zod.z.strictObject({
1252
1512
  respectNullableSchemas: zod.z.boolean().optional(),
1253
1513
  titleAsSchemaName: zod.z.boolean().optional(),
@@ -1664,6 +1924,7 @@ var sdkConfigV1Schema = zod.z.strictObject({
1664
1924
  client: sdkConfigV1ClientConfigSchema.prefault({}),
1665
1925
  package: sdkConfigV1PackageConfigSchema.prefault({}),
1666
1926
  output: sdkConfigV1OutputConfigSchema.optional(),
1927
+ replay: sdkConfigV1ReplayConfigSchema.optional(),
1667
1928
  docs: sdkConfigV1DocsConfigSchema.prefault({}),
1668
1929
  generation: sdkConfigV1GenerationConfigSchema.prefault({}),
1669
1930
  targets: zod.z.array(sdkConfigV1TargetSchema).min(1)
@@ -1726,7 +1987,7 @@ function mapFernConfigToSdkConfigV1(input) {
1726
1987
  const mapped = input.group.generators.map((generator, index) => {
1727
1988
  const language = languages[index];
1728
1989
  const invocation = mapInvocation(generator, language, activeLanguages, index);
1729
- const outputMapping = generator.output ? { output: generator.output, unsupportedFields: [] } : mapOutput(generator, language, index);
1990
+ const outputMapping = mapOutput(generator, language, index);
1730
1991
  return {
1731
1992
  generator,
1732
1993
  language,
@@ -1785,6 +2046,7 @@ function mapFernConfigToSdkConfigV1(input) {
1785
2046
  source: input.source,
1786
2047
  ...optional("sdkVersion", input.sdkVersion),
1787
2048
  ...optional("apiVersion", input.apiVersion),
2049
+ ...optional("replay", input.replay),
1788
2050
  ...optionalObject("api", api),
1789
2051
  ...optionalObject("client", clients.shared),
1790
2052
  ...optionalObject("docs", docs.shared),
@@ -2717,7 +2979,7 @@ var credentialResolutionSchema = zod.z.enum([
2717
2979
  "resolved-by-orchestrator",
2718
2980
  "resolved-by-fiddle"
2719
2981
  ]);
2720
- var registryCredentialsSchema2 = zod.z.strictObject({
2982
+ var registryCredentialsSchema = zod.z.strictObject({
2721
2983
  username: nonEmptyStringSchema.optional(),
2722
2984
  password: nonEmptyStringSchema.optional(),
2723
2985
  token: nonEmptyStringSchema.optional(),
@@ -2728,7 +2990,7 @@ var commonPublishShape2 = {
2728
2990
  /** Reference to registry publishing credentials. */
2729
2991
  credentialsRef: nonEmptyStringSchema.optional(),
2730
2992
  /** Raw registry credentials. These values can be sensitive and must be handled as secrets. */
2731
- credentials: registryCredentialsSchema2.optional(),
2993
+ credentials: registryCredentialsSchema.optional(),
2732
2994
  /**
2733
2995
  * Registry-specific package version override. If omitted, the external publisher/orchestrator may
2734
2996
  * fall back to target.sdkVersion.
@@ -2833,7 +3095,7 @@ var githubOutputSchema2 = zod.z.strictObject({
2833
3095
  /** Reference to GitHub credentials. */
2834
3096
  credentialsRef: nonEmptyStringSchema.optional(),
2835
3097
  /** Raw GitHub credentials. These values can be sensitive and must be handled as secrets. */
2836
- credentials: registryCredentialsSchema2.optional(),
3098
+ credentials: registryCredentialsSchema.optional(),
2837
3099
  privateRepository: zod.z.boolean().optional(),
2838
3100
  /** GitHub license block scoped to repository delivery. */
2839
3101
  license: githubLicenseSchema.optional(),
@@ -2875,6 +3137,9 @@ var outputConfigSchema = zod.z.discriminatedUnion(
2875
3137
  error: 'output.delivery must be one of "files", "zip", or "github"'
2876
3138
  }
2877
3139
  );
3140
+ var replayConfigSchema = zod.z.strictObject({
3141
+ enabled: zod.z.boolean()
3142
+ });
2878
3143
  var sourceSpecConfigSchema = zod.z.strictObject({
2879
3144
  id: nonEmptyStringSchema.optional(),
2880
3145
  name: nonEmptyStringSchema.optional(),
@@ -3006,6 +3271,7 @@ var sdkConfigIrV1Schema = zod.z.strictObject({
3006
3271
  client: clientConfigSchema,
3007
3272
  package: packageConfigSchema,
3008
3273
  output: outputConfigSchema,
3274
+ replay: replayConfigSchema.optional(),
3009
3275
  docs: docsConfigSchema,
3010
3276
  generation: generationConfigSchema,
3011
3277
  compatibility: compatibilityConfigSchema.optional()
@@ -3110,6 +3376,7 @@ exports.pythonGenerationConfigSchema = pythonGenerationConfigSchema;
3110
3376
  exports.readmeCustomSectionSchema = readmeCustomSectionSchema;
3111
3377
  exports.readmeEndpointSchema = readmeEndpointSchema;
3112
3378
  exports.relativePathSchema = relativePathSchema;
3379
+ exports.replayConfigSchema = replayConfigSchema;
3113
3380
  exports.rubyGenerationConfigSchema = rubyGenerationConfigSchema;
3114
3381
  exports.rustGenerationConfigSchema = rustGenerationConfigSchema;
3115
3382
  exports.sdkConfigIrV1Schema = sdkConfigIrV1Schema;
@@ -3141,6 +3408,7 @@ exports.sdkConfigV1PythonGenerationConfigSchema = pythonGenerationConfigSchema;
3141
3408
  exports.sdkConfigV1ReadmeCustomSectionSchema = sdkConfigV1ReadmeCustomSectionSchema;
3142
3409
  exports.sdkConfigV1ReadmeEndpointSchema = sdkConfigV1ReadmeEndpointSchema;
3143
3410
  exports.sdkConfigV1RelativePathSchema = relativePathSchema;
3411
+ exports.sdkConfigV1ReplayConfigSchema = sdkConfigV1ReplayConfigSchema;
3144
3412
  exports.sdkConfigV1RubyGenerationConfigSchema = rubyGenerationConfigSchema;
3145
3413
  exports.sdkConfigV1RustGenerationConfigSchema = rustGenerationConfigSchema;
3146
3414
  exports.sdkConfigV1Schema = sdkConfigV1Schema;