@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 +10 -5
- package/dist/index.cjs +342 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +341 -75
- package/dist/index.js.map +1 -1
- package/dist/sdk-config/index.cjs +330 -67
- package/dist/sdk-config/index.cjs.map +1 -1
- package/dist/sdk-config/index.d.cts +1 -1
- package/dist/sdk-config/index.d.ts +1 -1
- package/dist/sdk-config/index.js +330 -68
- package/dist/sdk-config/index.js.map +1 -1
- package/dist/sdk-config/v1/index.cjs +330 -67
- package/dist/sdk-config/v1/index.cjs.map +1 -1
- package/dist/sdk-config/v1/index.d.cts +533 -4128
- package/dist/sdk-config/v1/index.d.ts +533 -4128
- package/dist/sdk-config/v1/index.js +330 -68
- package/dist/sdk-config/v1/index.js.map +1 -1
- package/dist/sdk-config-ir/index.cjs +5 -0
- package/dist/sdk-config-ir/index.cjs.map +1 -1
- package/dist/sdk-config-ir/index.d.cts +1 -1
- package/dist/sdk-config-ir/index.d.ts +1 -1
- package/dist/sdk-config-ir/index.js +5 -1
- package/dist/sdk-config-ir/index.js.map +1 -1
- package/dist/sdk-config-ir/v1/index.cjs +5 -0
- package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
- package/dist/sdk-config-ir/v1/index.d.cts +10 -1
- package/dist/sdk-config-ir/v1/index.d.ts +10 -1
- package/dist/sdk-config-ir/v1/index.js +5 -1
- package/dist/sdk-config-ir/v1/index.js.map +1 -1
- package/package.json +1 -1
- package/src/sdk-config/v1/README.md +12 -4
- package/src/sdk-config-ir/v1/README.md +3 -1
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.
|
|
75
|
-
|
|
76
|
-
`
|
|
77
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
733
|
-
if (!isObject(value)) return
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
if (
|
|
752
|
-
|
|
753
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
850
|
+
publish,
|
|
835
851
|
...packageName || Object.keys(metadata).length ? { package: { ...optional("packageName", packageName), ...metadata } } : {}
|
|
836
852
|
};
|
|
837
853
|
}
|
|
838
|
-
function
|
|
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({
|
|
1199
|
-
|
|
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
|
-
|
|
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({
|
|
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 =
|
|
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 =
|
|
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
|
|
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:
|
|
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:
|
|
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;
|