@postman/sdk-config 0.10.1 → 0.11.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/README.md +6 -0
- package/dist/index.cjs +697 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +683 -35
- package/dist/index.js.map +1 -1
- package/dist/sdk-config/index.cjs +649 -34
- package/dist/sdk-config/index.cjs.map +1 -1
- package/dist/sdk-config/index.d.cts +2 -2
- package/dist/sdk-config/index.d.ts +2 -2
- package/dist/sdk-config/index.js +642 -35
- package/dist/sdk-config/index.js.map +1 -1
- package/dist/sdk-config/v1/index.cjs +649 -34
- package/dist/sdk-config/v1/index.cjs.map +1 -1
- package/dist/sdk-config/v1/index.d.cts +2858 -2377
- package/dist/sdk-config/v1/index.d.ts +2858 -2377
- package/dist/sdk-config/v1/index.js +642 -35
- package/dist/sdk-config/v1/index.js.map +1 -1
- package/dist/sdk-config-ir/index.cjs +247 -4
- package/dist/sdk-config-ir/index.cjs.map +1 -1
- package/dist/sdk-config-ir/index.d.cts +2 -2
- package/dist/sdk-config-ir/index.d.ts +2 -2
- package/dist/sdk-config-ir/index.js +241 -5
- package/dist/sdk-config-ir/index.js.map +1 -1
- package/dist/sdk-config-ir/v1/index.cjs +247 -4
- package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
- package/dist/sdk-config-ir/v1/index.d.cts +3109 -2960
- package/dist/sdk-config-ir/v1/index.d.ts +3109 -2960
- package/dist/sdk-config-ir/v1/index.js +241 -5
- package/dist/sdk-config-ir/v1/index.js.map +1 -1
- package/dist/{typescript-Chge0X4f.d.cts → typescript-CsAa1VSy.d.cts} +81 -1
- package/dist/{typescript-Chge0X4f.d.ts → typescript-CsAa1VSy.d.ts} +81 -1
- package/package.json +1 -1
- package/src/sdk-config/v1/README.md +183 -1
- package/src/sdk-config-ir/v1/README.md +29 -1
package/dist/sdk-config/index.js
CHANGED
|
@@ -27,7 +27,7 @@ var jsonValueSchema = z.lazy(
|
|
|
27
27
|
z.record(z.string(), jsonValueSchema)
|
|
28
28
|
])
|
|
29
29
|
);
|
|
30
|
-
z.record(z.string(), jsonValueSchema);
|
|
30
|
+
var jsonObjectSchema = z.record(z.string(), jsonValueSchema);
|
|
31
31
|
var hashAlgorithmSchema = z.enum(["sha1", "sha256", "sha384", "sha512"]);
|
|
32
32
|
var encodingSchema = z.enum(["base64", "hex"]);
|
|
33
33
|
var payloadComponentSchema = z.enum(["body", "timestamp", "notification-url", "message-id"]);
|
|
@@ -125,13 +125,21 @@ var oauthScopeSchema = z.strictObject({
|
|
|
125
125
|
name: nonEmptyStringSchema.describe("The OAuth scope value requested from the provider."),
|
|
126
126
|
description: z.string().optional().describe("A description of the OAuth scope included in generated SDK documentation.")
|
|
127
127
|
});
|
|
128
|
+
var publicClientIdSchema = nonEmptyStringSchema.refine((value) => value.trim() === value, {
|
|
129
|
+
message: "must not have leading or trailing whitespace"
|
|
130
|
+
}).refine((value) => !value.includes("${"), {
|
|
131
|
+
message: "must be a literal public client ID, not an environment expression"
|
|
132
|
+
});
|
|
128
133
|
var oauthFlowSchema = z.discriminatedUnion("type", [
|
|
129
134
|
z.strictObject({
|
|
130
135
|
type: z.literal("authorization-code").describe("Uses the OAuth authorization code flow."),
|
|
131
136
|
authorizationUrl: nonEmptyStringSchema.describe("The URL used to authorize the client."),
|
|
132
137
|
tokenUrl: nonEmptyStringSchema.describe("The URL used to exchange a code for tokens."),
|
|
133
138
|
refreshUrl: nonEmptyStringSchema.optional().describe("The URL used to refresh access tokens."),
|
|
134
|
-
scopes: z.array(oauthScopeSchema).optional().describe("The scopes supported by this flow.")
|
|
139
|
+
scopes: z.array(oauthScopeSchema).optional().describe("The scopes supported by this flow."),
|
|
140
|
+
clientId: publicClientIdSchema.optional().describe(
|
|
141
|
+
"The public, non-secret OAuth client ID that generated interactive login flows, such as CLI browser login with PKCE, send to the authorization and token endpoints. It is embedded verbatim in generated code, so it must never be a client secret."
|
|
142
|
+
)
|
|
135
143
|
}),
|
|
136
144
|
z.strictObject({
|
|
137
145
|
type: z.literal("client-credentials").describe("Uses the OAuth client credentials flow."),
|
|
@@ -447,8 +455,102 @@ var packageConfigSchema = z.strictObject({
|
|
|
447
455
|
projectUrls: z.array(projectUrlSchema).optional().describe("Labeled project links for package metadata."),
|
|
448
456
|
extraDependencies: z.array(dependencySchema).optional().describe("Additional runtime dependencies added to the generated package."),
|
|
449
457
|
extraDevDependencies: z.array(dependencySchema).optional().describe("Additional development dependencies added to the generated package."),
|
|
450
|
-
extraPeerDependencies: z.array(dependencySchema).optional().describe("Additional peer dependencies added to the generated package.")
|
|
458
|
+
extraPeerDependencies: z.array(dependencySchema).optional().describe("Additional peer dependencies added to the generated package."),
|
|
459
|
+
extraPeerDependenciesMeta: z.record(nonEmptyStringSchema, jsonObjectSchema).optional().describe(
|
|
460
|
+
"npm peerDependenciesMeta entries keyed by peer dependency name, such as { optional: true }."
|
|
461
|
+
)
|
|
462
|
+
});
|
|
463
|
+
var GITHUB_ACTIONS_SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
464
|
+
var GITHUB_REPOSITORY_SLUG_PATTERN = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
|
|
465
|
+
var HOMEBREW_FORMULA_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
466
|
+
var githubActionsSecretNameSchema = z.string({ error: "must be the name of a GitHub Actions secret" }).regex(GITHUB_ACTIONS_SECRET_NAME_PATTERN, {
|
|
467
|
+
error: "must be the name of a GitHub Actions secret: start with an uppercase letter and contain only A-Z, 0-9, or _. Secret values and ${...} expressions are not accepted."
|
|
468
|
+
}).refine((value) => value !== "GITHUB_TOKEN", {
|
|
469
|
+
error: "GITHUB_TOKEN cannot be used: it is the workflow's built-in token, scoped to the generated repository. Store the credential under a different secret name."
|
|
470
|
+
});
|
|
471
|
+
var githubRepositorySlugSchema = z.string({ error: 'must be a GitHub repository in "<owner>/<repo>" form' }).regex(GITHUB_REPOSITORY_SLUG_PATTERN, {
|
|
472
|
+
error: 'must be a GitHub repository in "<owner>/<repo>" form, for example "acme/homebrew-tap"'
|
|
473
|
+
});
|
|
474
|
+
var homebrewFormulaNameSchema = z.string({ error: "must be a Homebrew formula name" }).regex(HOMEBREW_FORMULA_NAME_PATTERN, {
|
|
475
|
+
error: "must be a Homebrew formula name: start with a lowercase letter and contain only a-z, 0-9, or -"
|
|
451
476
|
});
|
|
477
|
+
var cliDistributionGithubAppSchema = z.strictObject({
|
|
478
|
+
appIdSecretName: githubActionsSecretNameSchema.describe(
|
|
479
|
+
"The name of the GitHub Actions secret holding the GitHub App ID or client ID."
|
|
480
|
+
),
|
|
481
|
+
privateKeySecretName: githubActionsSecretNameSchema.describe(
|
|
482
|
+
"The name of the GitHub Actions secret holding the GitHub App private key in PEM form."
|
|
483
|
+
)
|
|
484
|
+
});
|
|
485
|
+
var channelTokenSecretNameDescription = "The name of the GitHub Actions secret holding a token with write access to the channel repository. Takes precedence over githubApp for this channel.";
|
|
486
|
+
var cliDistributionHomebrewSchema = z.strictObject({
|
|
487
|
+
tap: githubRepositorySlugSchema.describe(
|
|
488
|
+
'The Homebrew tap repository in "<owner>/<repo>" form that receives the formula.'
|
|
489
|
+
),
|
|
490
|
+
formula: homebrewFormulaNameSchema.optional().describe("The Homebrew formula name; the generator defaults it to the CLI binary name."),
|
|
491
|
+
tokenSecretName: githubActionsSecretNameSchema.optional().describe(channelTokenSecretNameDescription)
|
|
492
|
+
});
|
|
493
|
+
var cliDistributionScoopSchema = z.strictObject({
|
|
494
|
+
bucket: githubRepositorySlugSchema.describe(
|
|
495
|
+
'The Scoop bucket repository in "<owner>/<repo>" form that receives the manifest.'
|
|
496
|
+
),
|
|
497
|
+
tokenSecretName: githubActionsSecretNameSchema.optional().describe(channelTokenSecretNameDescription)
|
|
498
|
+
});
|
|
499
|
+
var cliDistributionConfigSchema = z.strictObject({
|
|
500
|
+
githubApp: cliDistributionGithubAppSchema.optional().describe(
|
|
501
|
+
"A GitHub App used to mint short-lived tokens for every channel without its own tokenSecretName."
|
|
502
|
+
),
|
|
503
|
+
homebrew: cliDistributionHomebrewSchema.optional().describe("Publishes a Homebrew formula to a tap repository on each tagged release."),
|
|
504
|
+
scoop: cliDistributionScoopSchema.optional().describe("Publishes a Scoop manifest to a bucket repository on each tagged release.")
|
|
505
|
+
}).superRefine((distribution, context) => {
|
|
506
|
+
if (distribution.homebrew !== void 0 || distribution.scoop !== void 0) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
if (distribution.githubApp !== void 0) {
|
|
510
|
+
context.addIssue({
|
|
511
|
+
code: "custom",
|
|
512
|
+
message: "githubApp requires at least one distribution channel: homebrew or scoop",
|
|
513
|
+
path: ["githubApp"]
|
|
514
|
+
});
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
context.addIssue({
|
|
518
|
+
code: "custom",
|
|
519
|
+
message: "distribution must configure at least one channel: homebrew or scoop"
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
var CLI_DISTRIBUTION_REQUIRES_GITHUB_DELIVERY_MESSAGE = 'distribution requires output.delivery "github": Homebrew and Scoop publish from a tagged GitHub Release produced by the generated release workflow. Set delivery to "github" or remove distribution.';
|
|
523
|
+
var CLI_PUBLISH_REQUIRES_GITHUB_DELIVERY_MESSAGE = 'package publication for target language "cli" requires output.delivery "github": the CLI generator publishes npm packages only from its generated GitHub workflow.';
|
|
524
|
+
var CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE = "CLI_DISTRIBUTION_NON_RELEASE_MODE";
|
|
525
|
+
var nonReleaseGithubModes = /* @__PURE__ */ new Set(["pull-request", "push", "commit"]);
|
|
526
|
+
function cliDistributionModeDiagnostic(output, outputPath) {
|
|
527
|
+
const mode = output?.github?.mode;
|
|
528
|
+
if (output?.distribution === void 0 || mode === void 0 || !nonReleaseGithubModes.has(mode)) {
|
|
529
|
+
return void 0;
|
|
530
|
+
}
|
|
531
|
+
return {
|
|
532
|
+
code: CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE,
|
|
533
|
+
severity: "warning",
|
|
534
|
+
path: [...outputPath, "github", "mode"],
|
|
535
|
+
reason: `GitHub mode "${mode}" does not create a release tag, so Homebrew and Scoop publish only after a semantic-version tag is pushed to the repository.`,
|
|
536
|
+
suggestedAction: 'Use mode "release" or "commit-and-release", or push a version tag after merging generated changes.'
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// src/sdk-config/v1/diagnostics.ts
|
|
541
|
+
function getSdkConfigV1Diagnostics(config) {
|
|
542
|
+
return config.targets.flatMap((target, targetIndex) => {
|
|
543
|
+
if (target.language !== "cli") {
|
|
544
|
+
return [];
|
|
545
|
+
}
|
|
546
|
+
const diagnostic = cliDistributionModeDiagnostic(target.output, [
|
|
547
|
+
"targets",
|
|
548
|
+
targetIndex,
|
|
549
|
+
"output"
|
|
550
|
+
]);
|
|
551
|
+
return diagnostic ? [diagnostic] : [];
|
|
552
|
+
});
|
|
553
|
+
}
|
|
452
554
|
var httpMethodSchema = z.enum([
|
|
453
555
|
"GET",
|
|
454
556
|
"POST",
|
|
@@ -653,6 +755,17 @@ function stringValue(value) {
|
|
|
653
755
|
function stringArrayValue(value) {
|
|
654
756
|
return Array.isArray(value) && value.every((item) => typeof item === "string" && item.length > 0) ? value : void 0;
|
|
655
757
|
}
|
|
758
|
+
var canonicalLicenseTypes = {
|
|
759
|
+
mit: "MIT",
|
|
760
|
+
apache: "APACHE",
|
|
761
|
+
"apache-2.0": "APACHE",
|
|
762
|
+
"gpl-3.0": "GPL3",
|
|
763
|
+
"gpl-3.0-only": "GPL3",
|
|
764
|
+
unlicensed: "UNLICENSED"
|
|
765
|
+
};
|
|
766
|
+
function canonicalLicenseType(value) {
|
|
767
|
+
return canonicalLicenseTypes[value.trim().toLowerCase()];
|
|
768
|
+
}
|
|
656
769
|
function stableJson(value) {
|
|
657
770
|
return JSON.stringify(sortKeys(value));
|
|
658
771
|
}
|
|
@@ -663,6 +776,280 @@ function sortKeys(value) {
|
|
|
663
776
|
Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, sortKeys(child)])
|
|
664
777
|
);
|
|
665
778
|
}
|
|
779
|
+
var ALPHANUMERIC_PATTERN = /[A-Za-z0-9]/;
|
|
780
|
+
var ROOT_GROUP_PATTERN = /^[a-z][a-z0-9_-]*$/;
|
|
781
|
+
var KEBAB_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
782
|
+
var DOTTED_COMMAND_PATH_PATTERN = /^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;
|
|
783
|
+
var FIELD_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;
|
|
784
|
+
var RESERVED_USER_AGENT_SUFFIX_FLAGS = /* @__PURE__ */ new Set([
|
|
785
|
+
"params",
|
|
786
|
+
"output",
|
|
787
|
+
"json",
|
|
788
|
+
"format",
|
|
789
|
+
"dry-run",
|
|
790
|
+
"base-url",
|
|
791
|
+
"page-all",
|
|
792
|
+
"page-limit",
|
|
793
|
+
"page-delay",
|
|
794
|
+
"no-pager",
|
|
795
|
+
"no-extract",
|
|
796
|
+
"no-retry",
|
|
797
|
+
"no-stream",
|
|
798
|
+
"quiet",
|
|
799
|
+
"query",
|
|
800
|
+
"help",
|
|
801
|
+
"debug",
|
|
802
|
+
"schema"
|
|
803
|
+
]);
|
|
804
|
+
var RESERVED_PROFILES_COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
805
|
+
"auth",
|
|
806
|
+
"completion",
|
|
807
|
+
"man",
|
|
808
|
+
"errors",
|
|
809
|
+
"generate-skills",
|
|
810
|
+
"help"
|
|
811
|
+
]);
|
|
812
|
+
var binaryNameSchema = nonEmptyStringSchema.regex(ALPHANUMERIC_PATTERN, {
|
|
813
|
+
message: "binaryName must contain at least one ASCII letter or digit"
|
|
814
|
+
});
|
|
815
|
+
var rootGroupSchema = z.string().regex(ROOT_GROUP_PATTERN, {
|
|
816
|
+
message: "rootGroup must start with a lowercase letter and contain only lowercase letters, digits, hyphens, and underscores"
|
|
817
|
+
});
|
|
818
|
+
var userAgentSuffixFlagSchema = z.string().superRefine((value, context) => {
|
|
819
|
+
if (value.startsWith("-")) {
|
|
820
|
+
context.addIssue({
|
|
821
|
+
code: "custom",
|
|
822
|
+
message: 'userAgentSuffixFlag must be the long flag name without the leading "--"'
|
|
823
|
+
});
|
|
824
|
+
} else if (!KEBAB_NAME_PATTERN.test(value)) {
|
|
825
|
+
context.addIssue({
|
|
826
|
+
code: "custom",
|
|
827
|
+
message: "userAgentSuffixFlag must start with a lowercase letter and contain only lowercase letters, digits, and hyphens"
|
|
828
|
+
});
|
|
829
|
+
} else if (RESERVED_USER_AGENT_SUFFIX_FLAGS.has(value)) {
|
|
830
|
+
context.addIssue({
|
|
831
|
+
code: "custom",
|
|
832
|
+
message: `userAgentSuffixFlag "${value}" collides with a built-in global flag`
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
var profilesCommandNameSchema = z.string().superRefine((value, context) => {
|
|
837
|
+
if (!KEBAB_NAME_PATTERN.test(value)) {
|
|
838
|
+
context.addIssue({
|
|
839
|
+
code: "custom",
|
|
840
|
+
message: "profiles.commandName must start with a lowercase letter and contain only lowercase letters, digits, and hyphens"
|
|
841
|
+
});
|
|
842
|
+
} else if (RESERVED_PROFILES_COMMAND_NAMES.has(value)) {
|
|
843
|
+
context.addIssue({
|
|
844
|
+
code: "custom",
|
|
845
|
+
message: `profiles.commandName "${value}" collides with a built-in command group`
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
function dottedCommandPathSchema(field) {
|
|
850
|
+
return z.string().regex(DOTTED_COMMAND_PATH_PATTERN, {
|
|
851
|
+
message: `${field} must be a dotted command path such as "iam.keys.create"`
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
function fieldNameMapSchema(field) {
|
|
855
|
+
const message = `${field} keys and values must be field names containing only [A-Za-z0-9_.-]`;
|
|
856
|
+
return z.record(z.string(), z.string().regex(FIELD_NAME_PATTERN, { message })).superRefine((value, context) => {
|
|
857
|
+
for (const key of Object.keys(value)) {
|
|
858
|
+
if (!FIELD_NAME_PATTERN.test(key)) {
|
|
859
|
+
context.addIssue({ code: "custom", message, path: [key] });
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
var profilesProvisionOperationSchema = z.strictObject({
|
|
865
|
+
operation: dottedCommandPathSchema("profiles.provisionOperation.operation").describe(
|
|
866
|
+
"The dotted command path of the operation that mints a profile credential."
|
|
867
|
+
),
|
|
868
|
+
credential: fieldNameMapSchema("profiles.provisionOperation.credential").refine((value) => Object.keys(value).length > 0, {
|
|
869
|
+
message: "profiles.provisionOperation.credential must map at least one credential field"
|
|
870
|
+
}).describe("Maps each stored credential field to the response field that supplies it."),
|
|
871
|
+
revokeParameters: fieldNameMapSchema("profiles.provisionOperation.revokeParameters").optional().describe("Maps each revoke-operation parameter to the response field that supplies it.")
|
|
872
|
+
});
|
|
873
|
+
var profilesConfigSchema = z.strictObject({
|
|
874
|
+
enabled: z.boolean().describe("Whether the CLI emits profile commands and the global --profile flag."),
|
|
875
|
+
commandName: profilesCommandNameSchema.optional().describe('The profile command group name. The generator defaults to "profiles".'),
|
|
876
|
+
revokeOperation: dottedCommandPathSchema("profiles.revokeOperation").optional().describe('The dotted command path called by "profiles remove --revoke".'),
|
|
877
|
+
provisionOperation: profilesProvisionOperationSchema.optional().describe('The operation called by "profiles create --provision" and its response mapping.')
|
|
878
|
+
});
|
|
879
|
+
var cliGenerationConfigSchema = z.strictObject({
|
|
880
|
+
paginationParameters: z.array(nonEmptyStringSchema).optional().describe("Request parameter names treated as pagination controls by the CLI."),
|
|
881
|
+
skills: z.boolean().optional().describe("Whether the generated CLI includes skills that teach AI agents to invoke commands."),
|
|
882
|
+
binaryName: binaryNameSchema.optional().describe(
|
|
883
|
+
"The CLI executable name. The generator kebab-cases it and also uses it for the source directory and env-var prefix."
|
|
884
|
+
),
|
|
885
|
+
customCommands: z.boolean().optional().describe("Whether hand-written command support is generated. The generator defaults to true."),
|
|
886
|
+
rootGroup: rootGroupSchema.optional().describe("A command group that every spec-derived command is nested under."),
|
|
887
|
+
profiles: profilesConfigSchema.optional().describe("Named profile command configuration."),
|
|
888
|
+
splitTypeCrates: z.boolean().optional().describe("Whether generated types are split into one crate per API behind a facade crate."),
|
|
889
|
+
userAgentSuffixFlag: userAgentSuffixFlagSchema.optional().describe('The long flag name, without "--", that appends a product token to the User-Agent.')
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
// src/sdk-config/v1/fern-config-mapper-cli.ts
|
|
893
|
+
var CLI_GENERATION_FIELDS = [
|
|
894
|
+
"binaryName",
|
|
895
|
+
"customCommands",
|
|
896
|
+
"rootGroup",
|
|
897
|
+
"profiles",
|
|
898
|
+
"splitTypeCrates",
|
|
899
|
+
"userAgentSuffixFlag"
|
|
900
|
+
];
|
|
901
|
+
var PROFILES_FIELDS = ["enabled", "commandName", "revokeOperation"];
|
|
902
|
+
var PROVISION_OPERATION_FIELDS = ["operation", "credential", "revokeParameters"];
|
|
903
|
+
function mapCliGeneration(config, state, basePath, targetIndex) {
|
|
904
|
+
const generation = {};
|
|
905
|
+
for (const field of CLI_GENERATION_FIELDS) {
|
|
906
|
+
const raw = ownValue(config, field);
|
|
907
|
+
if (raw === void 0) continue;
|
|
908
|
+
const fieldPath = [...basePath, field];
|
|
909
|
+
const { value, consumedPaths } = field === "profiles" && isObject(raw) ? pickProfiles(raw, fieldPath) : { value: raw, consumedPaths: [fieldPath] };
|
|
910
|
+
const parsed = cliGenerationConfigSchema.shape[field].safeParse(value);
|
|
911
|
+
consumedPaths.forEach((path) => consume(state, path));
|
|
912
|
+
if (parsed.success) {
|
|
913
|
+
generation[field] = structuredClone(value);
|
|
914
|
+
continue;
|
|
915
|
+
}
|
|
916
|
+
const diagnostics = parsed.error.issues.map(
|
|
917
|
+
(issue) => invalidValueDiagnostic(field, fieldPath, issue.path, issue.message, targetIndex)
|
|
918
|
+
);
|
|
919
|
+
(state.valueDiagnostics ??= []).push(...diagnostics);
|
|
920
|
+
}
|
|
921
|
+
return generation;
|
|
922
|
+
}
|
|
923
|
+
function pickProfiles(profiles, path) {
|
|
924
|
+
const picked = pickKnown(profiles, PROFILES_FIELDS, path);
|
|
925
|
+
const provisionOperation = ownValue(profiles, "provisionOperation");
|
|
926
|
+
const provisionPath = [...path, "provisionOperation"];
|
|
927
|
+
if (isObject(provisionOperation)) {
|
|
928
|
+
const provision = pickKnown(provisionOperation, PROVISION_OPERATION_FIELDS, provisionPath);
|
|
929
|
+
picked.value.provisionOperation = provision.value;
|
|
930
|
+
picked.consumedPaths.push(...provision.consumedPaths);
|
|
931
|
+
} else if (provisionOperation !== void 0) {
|
|
932
|
+
picked.value.provisionOperation = provisionOperation;
|
|
933
|
+
picked.consumedPaths.push(provisionPath);
|
|
934
|
+
}
|
|
935
|
+
return { value: { enabled: false, ...picked.value }, consumedPaths: picked.consumedPaths };
|
|
936
|
+
}
|
|
937
|
+
function pickKnown(value, fields, path) {
|
|
938
|
+
const picked = {};
|
|
939
|
+
const consumedPaths = [];
|
|
940
|
+
for (const field of fields) {
|
|
941
|
+
const child = ownValue(value, field);
|
|
942
|
+
if (child === void 0) continue;
|
|
943
|
+
picked[field] = child;
|
|
944
|
+
consumedPaths.push([...path, field]);
|
|
945
|
+
}
|
|
946
|
+
return { value: picked, consumedPaths };
|
|
947
|
+
}
|
|
948
|
+
function ownValue(value, key) {
|
|
949
|
+
return Object.hasOwn(value, key) ? value[key] : void 0;
|
|
950
|
+
}
|
|
951
|
+
function invalidValueDiagnostic(field, fieldPath, issuePath, message, targetIndex) {
|
|
952
|
+
const relative = issuePath.map((part) => typeof part === "symbol" ? String(part) : part);
|
|
953
|
+
const sdkConfigField = ["targets", targetIndex, "generation", field];
|
|
954
|
+
return {
|
|
955
|
+
code: "FERN_CONFIG_VALUE_INVALID",
|
|
956
|
+
severity: "warning",
|
|
957
|
+
path: [...fieldPath, ...relative],
|
|
958
|
+
reason: `CLI setting ${field} was not migrated because SDK Config rejects it: ${message}`,
|
|
959
|
+
sdkConfigPath: [...sdkConfigField, ...relative],
|
|
960
|
+
suggestedAction: `Correct the value, then set ${sdkConfigField.join(".")} manually.`
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// src/sdk-config/v1/fern-config-mapper-cli-distribution.ts
|
|
965
|
+
var DISTRIBUTION_KEYS = {
|
|
966
|
+
githubApp: { appIdSecret: "appIdSecretName", privateKeySecret: "privateKeySecretName" },
|
|
967
|
+
homebrew: { tap: "tap", formula: "formula", tokenEnvironmentVariable: "tokenSecretName" },
|
|
968
|
+
scoop: { bucket: "bucket", tokenEnvironmentVariable: "tokenSecretName" }
|
|
969
|
+
};
|
|
970
|
+
function mapCliDistribution(config, state, basePath, targetIndex) {
|
|
971
|
+
if (!Object.hasOwn(config, "distribution")) return;
|
|
972
|
+
const raw = config.distribution;
|
|
973
|
+
const path = [...basePath, "distribution"];
|
|
974
|
+
const translated = isObject(raw) ? translateDistribution(raw, path) : { value: raw, consumedPaths: [path], legacyKeys: /* @__PURE__ */ new Map() };
|
|
975
|
+
const parsed = cliDistributionConfigSchema.safeParse(translated.value);
|
|
976
|
+
translated.consumedPaths.forEach((consumedPath) => consume(state, consumedPath));
|
|
977
|
+
if (parsed.success) {
|
|
978
|
+
state.cliDistribution = { value: parsed.data, path };
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
const diagnostics = parsed.error.issues.map(
|
|
982
|
+
(issue) => invalidDistributionDiagnostic(issue, path, translated.legacyKeys, targetIndex)
|
|
983
|
+
);
|
|
984
|
+
const reportedPaths = /* @__PURE__ */ new Set();
|
|
985
|
+
(state.valueDiagnostics ??= []).push(
|
|
986
|
+
...diagnostics.filter(({ path: diagnosticPath }) => {
|
|
987
|
+
const key = diagnosticPath.join(".");
|
|
988
|
+
if (reportedPaths.has(key)) return false;
|
|
989
|
+
reportedPaths.add(key);
|
|
990
|
+
return true;
|
|
991
|
+
})
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
function translateDistribution(distribution, path) {
|
|
995
|
+
const value = {};
|
|
996
|
+
const consumedPaths = [];
|
|
997
|
+
const legacyKeys = /* @__PURE__ */ new Map();
|
|
998
|
+
for (const [block, keys] of Object.entries(DISTRIBUTION_KEYS)) {
|
|
999
|
+
if (!Object.hasOwn(distribution, block)) continue;
|
|
1000
|
+
const blockValue = distribution[block];
|
|
1001
|
+
const blockPath = [...path, block];
|
|
1002
|
+
if (!isObject(blockValue)) {
|
|
1003
|
+
value[block] = blockValue;
|
|
1004
|
+
consumedPaths.push(blockPath);
|
|
1005
|
+
continue;
|
|
1006
|
+
}
|
|
1007
|
+
const translatedBlock = {};
|
|
1008
|
+
for (const [legacyKey, sdkConfigKey] of Object.entries(keys)) {
|
|
1009
|
+
if (!Object.hasOwn(blockValue, legacyKey)) continue;
|
|
1010
|
+
translatedBlock[sdkConfigKey] = blockValue[legacyKey];
|
|
1011
|
+
consumedPaths.push([...blockPath, legacyKey]);
|
|
1012
|
+
legacyKeys.set(`${block}.${sdkConfigKey}`, legacyKey);
|
|
1013
|
+
}
|
|
1014
|
+
value[block] = translatedBlock;
|
|
1015
|
+
}
|
|
1016
|
+
return { value, consumedPaths, legacyKeys };
|
|
1017
|
+
}
|
|
1018
|
+
function invalidDistributionDiagnostic(issue, path, legacyKeys, targetIndex) {
|
|
1019
|
+
const relative = issue.path.map((part) => typeof part === "symbol" ? String(part) : part);
|
|
1020
|
+
const [block, field] = relative;
|
|
1021
|
+
const legacyField = typeof block === "string" && typeof field === "string" ? legacyKeys.get(`${block}.${field}`) : void 0;
|
|
1022
|
+
const legacyRelative = typeof block === "string" && legacyField !== void 0 ? [block, legacyField] : relative;
|
|
1023
|
+
const sdkConfigField = ["targets", targetIndex, "output", "distribution"];
|
|
1024
|
+
return {
|
|
1025
|
+
code: "FERN_CONFIG_VALUE_INVALID",
|
|
1026
|
+
severity: "warning",
|
|
1027
|
+
path: [...path, ...legacyRelative],
|
|
1028
|
+
reason: `CLI distribution was not migrated because SDK Config rejects it: ${issue.message}`,
|
|
1029
|
+
sdkConfigPath: [...sdkConfigField, ...relative],
|
|
1030
|
+
suggestedAction: `Correct the value, then set ${sdkConfigField.join(".")} manually.`
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
function applyCliDistribution(output, pending, targetIndex) {
|
|
1034
|
+
if (pending === void 0) return { output, diagnostics: [] };
|
|
1035
|
+
if (output.delivery === "github") {
|
|
1036
|
+
return { output: { ...output, distribution: pending.value }, diagnostics: [] };
|
|
1037
|
+
}
|
|
1038
|
+
const outputPath = ["targets", targetIndex, "output"];
|
|
1039
|
+
return {
|
|
1040
|
+
output,
|
|
1041
|
+
diagnostics: [
|
|
1042
|
+
{
|
|
1043
|
+
code: "FERN_CLI_DISTRIBUTION_REQUIRES_GITHUB_OUTPUT",
|
|
1044
|
+
severity: "warning",
|
|
1045
|
+
path: pending.path,
|
|
1046
|
+
reason: `The CLI generator ignores distribution for "${output.delivery}" output, and SDK Config accepts distribution only with output.delivery "github", so it was not migrated`,
|
|
1047
|
+
sdkConfigPath: [...outputPath, "distribution"],
|
|
1048
|
+
suggestedAction: `Set ${outputPath.join(".")}.delivery to "github" for the CLI repository and add ${outputPath.join(".")}.distribution manually, or remove distribution.`
|
|
1049
|
+
}
|
|
1050
|
+
]
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
666
1053
|
|
|
667
1054
|
// src/sdk-config/v1/fern-config-mapper-output.ts
|
|
668
1055
|
function mapOutput(generator, language, index) {
|
|
@@ -873,11 +1260,10 @@ function githubOutput(value, publishInfo, rawOutput, language, sourcePath, state
|
|
|
873
1260
|
...optionalObject("package", { ...publication?.package, ...licensePackage })
|
|
874
1261
|
};
|
|
875
1262
|
}
|
|
876
|
-
var basicLicenseTypes = { mit: "MIT", apache: "APACHE" };
|
|
877
1263
|
function mapGithubLicense(value, sourcePath, state) {
|
|
878
1264
|
if (!isObject(value) || stringValue(value.type) !== "basic") return {};
|
|
879
1265
|
const id = stringValue(value.id);
|
|
880
|
-
const type = id ?
|
|
1266
|
+
const type = id ? canonicalLicenseType(id) : void 0;
|
|
881
1267
|
if (!type) return {};
|
|
882
1268
|
consume(state, [...sourcePath, "type"]);
|
|
883
1269
|
consume(state, [...sourcePath, "id"]);
|
|
@@ -1444,6 +1830,114 @@ function outputDiagnostic(path, index) {
|
|
|
1444
1830
|
suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
|
|
1445
1831
|
};
|
|
1446
1832
|
}
|
|
1833
|
+
|
|
1834
|
+
// src/sdk-config/v1/package.ts
|
|
1835
|
+
var sdkConfigV1DependencySchema = dependencySchema;
|
|
1836
|
+
var sdkConfigV1PackageConfigSchema = packageConfigSchema;
|
|
1837
|
+
|
|
1838
|
+
// src/sdk-config/v1/fern-config-mapper-package.ts
|
|
1839
|
+
var emailSchema = z.email();
|
|
1840
|
+
function mapCliPackageIdentity(identity, state, targetIndex) {
|
|
1841
|
+
mapIdentityField(identity, "homepage", stringValue, state);
|
|
1842
|
+
mapIdentityField(identity, "keywords", (value) => stringArrayValue(value)?.slice(), state);
|
|
1843
|
+
mapCargoAuthors(identity, state, targetIndex);
|
|
1844
|
+
mapIdentityField(identity, "license", licenseValue, state);
|
|
1845
|
+
}
|
|
1846
|
+
function mapIdentityField(identity, field, read, state) {
|
|
1847
|
+
const located = locate(identity.value, [field], identity.path);
|
|
1848
|
+
const value = located && read(located.value);
|
|
1849
|
+
if (located && value !== void 0) addPackageFallback(state, field, value, located.path);
|
|
1850
|
+
}
|
|
1851
|
+
function mapLicenseFallback(config, aliases, state, basePath) {
|
|
1852
|
+
const located = locate(config, aliases, basePath);
|
|
1853
|
+
const license = located && licenseValue(located.value);
|
|
1854
|
+
if (located && license) addPackageFallback(state, "license", license, located.path);
|
|
1855
|
+
}
|
|
1856
|
+
function resolveTargetPackage(targetPackage, fallbacks, generator, delivery, index) {
|
|
1857
|
+
const diagnostics = [];
|
|
1858
|
+
for (const fallback of fallbacks) {
|
|
1859
|
+
applyFallback(targetPackage, fallback, index, diagnostics);
|
|
1860
|
+
}
|
|
1861
|
+
if (delivery !== "github") {
|
|
1862
|
+
applyMetadataLicense(targetPackage, generator.raw, index, diagnostics);
|
|
1863
|
+
}
|
|
1864
|
+
return diagnostics;
|
|
1865
|
+
}
|
|
1866
|
+
function applyFallback(targetPackage, { field, value, path }, index, diagnostics) {
|
|
1867
|
+
const existing = targetPackage[field];
|
|
1868
|
+
if (existing === void 0) {
|
|
1869
|
+
targetPackage[field] = value;
|
|
1870
|
+
} else if (stableJson(existing) !== stableJson(value)) {
|
|
1871
|
+
diagnostics.push({
|
|
1872
|
+
code: "FERN_PACKAGE_VALUE_CONFLICT",
|
|
1873
|
+
severity: "warning",
|
|
1874
|
+
path,
|
|
1875
|
+
reason: `Fern value conflicts with the package.${field} already migrated for this target, which is kept`,
|
|
1876
|
+
sdkConfigPath: ["targets", index, "package", field],
|
|
1877
|
+
suggestedAction: `Choose the intended value and set targets.${index}.package.${field} manually.`
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
function applyMetadataLicense(targetPackage, raw, index, diagnostics) {
|
|
1882
|
+
const metadata = isObject(raw) && isObject(raw.metadata) ? raw.metadata : void 0;
|
|
1883
|
+
if (metadata?.license === void 0 || metadata.license === null) return;
|
|
1884
|
+
const path = ["group", "generators", index, "metadata", "license"];
|
|
1885
|
+
const license = licenseValue(metadata.license);
|
|
1886
|
+
if (license) {
|
|
1887
|
+
applyFallback(targetPackage, { field: "license", value: license, path }, index, diagnostics);
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
diagnostics.push({
|
|
1891
|
+
code: "FERN_CONFIG_FIELD_UNSUPPORTED",
|
|
1892
|
+
severity: "warning",
|
|
1893
|
+
path,
|
|
1894
|
+
reason: isObject(metadata.license) ? "A custom license file cannot be migrated automatically" : "metadata.license is not a license identifier",
|
|
1895
|
+
sdkConfigPath: ["targets", index, "package", "license"],
|
|
1896
|
+
suggestedAction: `Set targets.${index}.package.license manually.`
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
function mapCargoAuthors(identity, state, targetIndex) {
|
|
1900
|
+
const located = locate(identity.value, ["authors"], identity.path);
|
|
1901
|
+
const entries = located && stringArrayValue(located.value);
|
|
1902
|
+
if (!located || !entries) return;
|
|
1903
|
+
consume(state, located.path);
|
|
1904
|
+
const authors = entries.map(parseCargoAuthor);
|
|
1905
|
+
const parsed = sdkConfigV1PackageConfigSchema.shape.authors.safeParse(authors);
|
|
1906
|
+
const invalid = parsed.success ? [] : [...new Set(parsed.error.issues.map((issue) => issue.path[0]))].filter(
|
|
1907
|
+
(index) => typeof index === "number"
|
|
1908
|
+
);
|
|
1909
|
+
if (invalid.length === 0) {
|
|
1910
|
+
addPackageFallback(state, "authors", authors, located.path);
|
|
1911
|
+
return;
|
|
1912
|
+
}
|
|
1913
|
+
const authorsPath = ["targets", targetIndex, "package", "authors"];
|
|
1914
|
+
(state.valueDiagnostics ??= []).push(
|
|
1915
|
+
...invalid.map((entry) => ({
|
|
1916
|
+
code: "FERN_CONFIG_VALUE_INVALID",
|
|
1917
|
+
severity: "warning",
|
|
1918
|
+
path: [...located.path, entry],
|
|
1919
|
+
reason: 'CLI packageIdentity.authors was not migrated because this entry is not "Name" or "Name <email>" with a valid email',
|
|
1920
|
+
sdkConfigPath: authorsPath,
|
|
1921
|
+
suggestedAction: `Correct the entry, then set ${authorsPath.join(".")} manually.`
|
|
1922
|
+
}))
|
|
1923
|
+
);
|
|
1924
|
+
}
|
|
1925
|
+
function parseCargoAuthor(entry) {
|
|
1926
|
+
const trimmed = entry.trim();
|
|
1927
|
+
const match = /^(.*?)\s*<([^<>]*)>$/.exec(trimmed);
|
|
1928
|
+
if (!match) return { name: trimmed };
|
|
1929
|
+
const [, name = "", email = ""] = match;
|
|
1930
|
+
if (name !== "" && !emailSchema.safeParse(email).success) return { name: trimmed };
|
|
1931
|
+
return { name, email };
|
|
1932
|
+
}
|
|
1933
|
+
function licenseValue(value) {
|
|
1934
|
+
const license = stringValue(value)?.trim();
|
|
1935
|
+
return license ? { type: canonicalLicenseType(license) ?? license } : void 0;
|
|
1936
|
+
}
|
|
1937
|
+
function addPackageFallback(state, field, value, path) {
|
|
1938
|
+
consume(state, path);
|
|
1939
|
+
(state.packageFallbacks ??= []).push({ field, value, path });
|
|
1940
|
+
}
|
|
1447
1941
|
var OMIT = /* @__PURE__ */ Symbol("omit");
|
|
1448
1942
|
function inputJsonSchema(schema) {
|
|
1449
1943
|
return z.toJSONSchema(schema, {
|
|
@@ -1701,7 +2195,16 @@ var sdkConfigV1PublishConfigSchema = z.discriminatedUnion("registry", [
|
|
|
1701
2195
|
z.strictObject({
|
|
1702
2196
|
registry: z.literal("npm").describe("Publishes the package to an npm-compatible registry."),
|
|
1703
2197
|
token: nonEmptyStringSchema.optional().describe("The npm registry token, or an environment expression that resolves to it."),
|
|
2198
|
+
trustedPublishing: z.boolean().optional().describe("Whether npm publication uses trusted publishing (OIDC) instead of a token."),
|
|
1704
2199
|
...commonPublishShape
|
|
2200
|
+
}).superRefine((publish, context) => {
|
|
2201
|
+
if (publish.trustedPublishing === true && publish.token !== void 0) {
|
|
2202
|
+
context.addIssue({
|
|
2203
|
+
code: "custom",
|
|
2204
|
+
message: "token must be omitted when trustedPublishing is true",
|
|
2205
|
+
path: ["token"]
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
1705
2208
|
}),
|
|
1706
2209
|
z.strictObject({
|
|
1707
2210
|
registry: z.literal("pypi").describe("Publishes the package to a PyPI-compatible registry."),
|
|
@@ -1779,10 +2282,29 @@ var sdkConfigV1OutputConfigSchema = z.discriminatedUnion(
|
|
|
1779
2282
|
[filesOutputSchema, zipOutputSchema, githubDeliverySchema],
|
|
1780
2283
|
{ error: 'output.delivery must be one of "files", "zip", or "github"' }
|
|
1781
2284
|
);
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
2285
|
+
var cliDistributionShape = {
|
|
2286
|
+
distribution: cliDistributionConfigSchema.optional().describe(
|
|
2287
|
+
"CLI release channels published by the generated release workflow; credentials are GitHub Actions secret names."
|
|
2288
|
+
)
|
|
2289
|
+
};
|
|
2290
|
+
function rejectDistributionWithoutGithub(output, context) {
|
|
2291
|
+
if (output.distribution !== void 0) {
|
|
2292
|
+
context.addIssue({
|
|
2293
|
+
code: "custom",
|
|
2294
|
+
message: CLI_DISTRIBUTION_REQUIRES_GITHUB_DELIVERY_MESSAGE,
|
|
2295
|
+
path: ["distribution"]
|
|
2296
|
+
});
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
var sdkConfigV1CliOutputConfigSchema = z.discriminatedUnion(
|
|
2300
|
+
"delivery",
|
|
2301
|
+
[
|
|
2302
|
+
filesOutputSchema.extend(cliDistributionShape).superRefine(rejectDistributionWithoutGithub),
|
|
2303
|
+
zipOutputSchema.extend(cliDistributionShape).superRefine(rejectDistributionWithoutGithub),
|
|
2304
|
+
githubDeliverySchema.extend(cliDistributionShape)
|
|
2305
|
+
],
|
|
2306
|
+
{ error: 'output.delivery must be one of "files", "zip", or "github"' }
|
|
2307
|
+
);
|
|
1786
2308
|
var sdkConfigV1ReplayConfigSchema = z.strictObject({
|
|
1787
2309
|
enabled: z.boolean().describe("Whether regeneration reapplies customer-authored repository changes.")
|
|
1788
2310
|
});
|
|
@@ -1859,10 +2381,6 @@ var sdkConfigV1SourceConfigSchema = z.strictObject({
|
|
|
1859
2381
|
seenIds.add(id);
|
|
1860
2382
|
});
|
|
1861
2383
|
});
|
|
1862
|
-
var cliGenerationConfigSchema = z.strictObject({
|
|
1863
|
-
paginationParameters: z.array(nonEmptyStringSchema).optional().describe("Request parameter names treated as pagination controls by the CLI."),
|
|
1864
|
-
skills: z.boolean().optional().describe("Whether the generated CLI includes skills that teach AI agents to invoke commands.")
|
|
1865
|
-
});
|
|
1866
2384
|
var csharpGenerationConfigSchema = z.strictObject({
|
|
1867
2385
|
useOptionalWrapper: z.boolean().optional().describe("Whether optional values use an explicit Optional wrapper."),
|
|
1868
2386
|
simplifyObjectDictionaries: z.boolean().optional().describe("Whether object schemas with arbitrary values use simplified dictionary types."),
|
|
@@ -2115,7 +2633,10 @@ var sdkConfigV1TargetSchema = z.discriminatedUnion("language", [
|
|
|
2115
2633
|
z.strictObject({
|
|
2116
2634
|
language: z.literal("cli").describe("Generates a command-line interface."),
|
|
2117
2635
|
generation: sdkConfigV1GenerationConfigOverrideSchema.extend(cliGenerationConfigSchema.shape).optional().describe("Common and CLI-specific generation settings for this target."),
|
|
2118
|
-
...targetOverrideShape
|
|
2636
|
+
...targetOverrideShape,
|
|
2637
|
+
output: sdkConfigV1CliOutputConfigSchema.optional().describe(
|
|
2638
|
+
"Output configuration, including optional CLI distribution channels, that replaces the root output for this target."
|
|
2639
|
+
)
|
|
2119
2640
|
}),
|
|
2120
2641
|
z.strictObject({
|
|
2121
2642
|
language: z.literal("mcp").describe("Generates an MCP server."),
|
|
@@ -2132,7 +2653,7 @@ var sdkConfigV1TargetSchema = z.discriminatedUnion("language", [
|
|
|
2132
2653
|
// src/sdk-config/v1/sdk-config-v1.ts
|
|
2133
2654
|
var SDK_CONFIG_V1_SCHEMA_VERSION = "sdk-config/v1";
|
|
2134
2655
|
var publishRegistryLanguages = {
|
|
2135
|
-
npm: ["typescript", "mcp"],
|
|
2656
|
+
npm: ["typescript", "mcp", "cli"],
|
|
2136
2657
|
pypi: ["python"],
|
|
2137
2658
|
maven: ["java", "kotlin"],
|
|
2138
2659
|
nuget: ["csharp"],
|
|
@@ -2209,6 +2730,13 @@ function validateTargetPublishing(target, targetIndex, globalPackage, globalOutp
|
|
|
2209
2730
|
});
|
|
2210
2731
|
return;
|
|
2211
2732
|
}
|
|
2733
|
+
if (target.language === "cli" && output.delivery !== "github") {
|
|
2734
|
+
context.addIssue({
|
|
2735
|
+
code: "custom",
|
|
2736
|
+
message: CLI_PUBLISH_REQUIRES_GITHUB_DELIVERY_MESSAGE,
|
|
2737
|
+
path: target.output ? ["targets", targetIndex, "output", "delivery"] : ["output", "delivery"]
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2212
2740
|
validatePublishingIdentity(
|
|
2213
2741
|
{ ...globalPackage, ...target.package },
|
|
2214
2742
|
registry,
|
|
@@ -2321,16 +2849,28 @@ function mapFernConfigToSdkConfigV1(input) {
|
|
|
2321
2849
|
package: outputPackage,
|
|
2322
2850
|
generation: outputGeneration
|
|
2323
2851
|
}, index) => {
|
|
2852
|
+
const distribution = applyCliDistribution(output, invocation.cliDistribution, index);
|
|
2853
|
+
invocation.unsupportedFields.push(...distribution.diagnostics);
|
|
2324
2854
|
const target = {
|
|
2325
2855
|
language,
|
|
2326
|
-
output,
|
|
2856
|
+
output: distribution.output,
|
|
2327
2857
|
...optional("sdkName", generator.sdkName),
|
|
2328
2858
|
...optional("sdkVersion", generator.sdkVersion),
|
|
2329
2859
|
...optional("client", clients.targetOverrides[index]),
|
|
2330
2860
|
...optional("docs", docs.targetOverrides[index])
|
|
2331
2861
|
};
|
|
2332
|
-
|
|
2333
|
-
|
|
2862
|
+
const targetPackage = { ...invocation.package, ...outputPackage, ...generator.package };
|
|
2863
|
+
invocation.unsupportedFields.push(
|
|
2864
|
+
...resolveTargetPackage(
|
|
2865
|
+
targetPackage,
|
|
2866
|
+
invocation.packageFallbacks,
|
|
2867
|
+
generator,
|
|
2868
|
+
output.delivery,
|
|
2869
|
+
index
|
|
2870
|
+
)
|
|
2871
|
+
);
|
|
2872
|
+
if (Object.keys(targetPackage).length > 0 || outputPackage || generator.package) {
|
|
2873
|
+
target.package = targetPackage;
|
|
2334
2874
|
}
|
|
2335
2875
|
const targetGeneration = {
|
|
2336
2876
|
...generations.targetOverrides[index],
|
|
@@ -2512,10 +3052,14 @@ function mapInvocation(generator, language, activeLanguages, index) {
|
|
|
2512
3052
|
...optional("smartCasingDigitWordBoundary", smartCasingDigitWordBoundary)
|
|
2513
3053
|
};
|
|
2514
3054
|
}
|
|
2515
|
-
const targetGeneration = mapLanguageConfig(
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
3055
|
+
const targetGeneration = mapLanguageConfig(
|
|
3056
|
+
language,
|
|
3057
|
+
config,
|
|
3058
|
+
state,
|
|
3059
|
+
packageConfig,
|
|
3060
|
+
[...prefix, "config"],
|
|
3061
|
+
index
|
|
3062
|
+
);
|
|
2519
3063
|
mapPublishMetadata(generator.publishMetadata, packageConfig);
|
|
2520
3064
|
if (generator.keywords?.length) {
|
|
2521
3065
|
generation.reservedKeywords = [...generator.keywords];
|
|
@@ -2532,12 +3076,22 @@ function mapInvocation(generator, language, activeLanguages, index) {
|
|
|
2532
3076
|
}
|
|
2533
3077
|
const docs = mapReadme(generator.readme, language, activeLanguages, state, [...prefix, "readme"]);
|
|
2534
3078
|
const unsupportedFields = [
|
|
3079
|
+
...state.valueDiagnostics ?? [],
|
|
2535
3080
|
...collectUnsupported(config, [...prefix, "config"], state),
|
|
2536
3081
|
...settings ? collectUnsupported(settings, [...prefix, "settings"], state) : [],
|
|
2537
3082
|
...isObject(generator.readme) ? collectUnsupported(generator.readme, [...prefix, "readme"], state) : [],
|
|
2538
3083
|
...unsupportedResolvedFields(generator, index, apiWideIdempotency !== void 0)
|
|
2539
3084
|
];
|
|
2540
|
-
return {
|
|
3085
|
+
return {
|
|
3086
|
+
client,
|
|
3087
|
+
docs,
|
|
3088
|
+
generation,
|
|
3089
|
+
package: packageConfig,
|
|
3090
|
+
packageFallbacks: state.packageFallbacks ?? [],
|
|
3091
|
+
...optional("cliDistribution", state.cliDistribution),
|
|
3092
|
+
targetGeneration,
|
|
3093
|
+
unsupportedFields
|
|
3094
|
+
};
|
|
2541
3095
|
}
|
|
2542
3096
|
function unsupportedResolvedFields(generator, index, idempotencyMapped) {
|
|
2543
3097
|
const values = [
|
|
@@ -2727,6 +3281,7 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
|
|
|
2727
3281
|
const packagePath = takeString(config, ["packagePath"], state, basePath);
|
|
2728
3282
|
if (packagePath !== void 0) generation.layout = { packagePath };
|
|
2729
3283
|
mapDependencies(config, state, packageConfig, basePath);
|
|
3284
|
+
mapPeerDependenciesMeta(config, state, packageConfig, basePath);
|
|
2730
3285
|
}
|
|
2731
3286
|
function mapTypescriptStreams(config, state, basePath) {
|
|
2732
3287
|
const responseType = takeEnum(config, ["streamType"], ["wrapper", "web"], state, basePath);
|
|
@@ -2740,7 +3295,7 @@ function mapTypescriptStreams(config, state, basePath) {
|
|
|
2740
3295
|
if (responseType === void 0 && fileResponseType === void 0) return void 0;
|
|
2741
3296
|
return { enabled: true, ...compact({ responseType, fileResponseType }) };
|
|
2742
3297
|
}
|
|
2743
|
-
function mapLanguageConfig(language, config, state, packageConfig, basePath) {
|
|
3298
|
+
function mapLanguageConfig(language, config, state, packageConfig, basePath, targetIndex) {
|
|
2744
3299
|
switch (language) {
|
|
2745
3300
|
case "typescript":
|
|
2746
3301
|
return mapTypescript(config, state, packageConfig, basePath);
|
|
@@ -2767,7 +3322,7 @@ function mapLanguageConfig(language, config, state, packageConfig, basePath) {
|
|
|
2767
3322
|
case "swift":
|
|
2768
3323
|
return mapSwift(config, state, basePath);
|
|
2769
3324
|
case "cli":
|
|
2770
|
-
return mapCli(config, state, packageConfig, basePath);
|
|
3325
|
+
return mapCli(config, state, packageConfig, basePath, targetIndex);
|
|
2771
3326
|
case "terraform":
|
|
2772
3327
|
return mapTerraform(config, state, packageConfig, basePath);
|
|
2773
3328
|
}
|
|
@@ -2784,6 +3339,7 @@ function mapTypescript(config, state, packageConfig, basePath) {
|
|
|
2784
3339
|
const packageManagerAtIndex = packageJsonPackageManager ? packageJsonPackageManager.indexOf("@", packageJsonPackageManager.startsWith("@") ? 1 : 0) : -1;
|
|
2785
3340
|
const packageManagerVersionPart = packageManagerAtIndex >= 0 ? packageJsonPackageManager?.slice(packageManagerAtIndex + 1).split("+")[0] : void 0;
|
|
2786
3341
|
const packageManagerVersion = packageManagerVersionPart || void 0;
|
|
3342
|
+
if (packageJsonManifest) liftPackageJsonDependencies(packageJsonManifest, state, packageConfig);
|
|
2787
3343
|
const serdeLayer = takeBoolean(config, ["serdeLayer"], state, basePath);
|
|
2788
3344
|
const noSerdeLayer = takeBoolean(config, ["noSerdeLayer"], state, basePath);
|
|
2789
3345
|
const fetchSupport = takeEnum(config, ["fetchSupport"], ["native"], state, basePath);
|
|
@@ -2953,6 +3509,7 @@ function mapRust(config, state, packageConfig, basePath) {
|
|
|
2953
3509
|
const description = takeString(config, ["packageDescription"], state, basePath);
|
|
2954
3510
|
const documentationUrl = takeString(config, ["packageDocumentation"], state, basePath);
|
|
2955
3511
|
Object.assign(packageConfig, compact({ packageName, repository, description, documentationUrl }));
|
|
3512
|
+
mapLicenseFallback(config, ["packageLicense"], state, basePath);
|
|
2956
3513
|
return compact({
|
|
2957
3514
|
dateTimeType: takeEnum(config, ["dateTimeType"], ["offset", "utc"], state, basePath),
|
|
2958
3515
|
capitalizeInitialisms: takeBoolean(config, ["capitalizeInitialisms"], state, basePath),
|
|
@@ -2966,7 +3523,7 @@ function mapSwift(config, state, basePath) {
|
|
|
2966
3523
|
nullableAsOptional: takeBoolean(config, ["nullableAsOptional"], state, basePath)
|
|
2967
3524
|
});
|
|
2968
3525
|
}
|
|
2969
|
-
function mapCli(config, state, packageConfig, basePath) {
|
|
3526
|
+
function mapCli(config, state, packageConfig, basePath, targetIndex) {
|
|
2970
3527
|
const identity = takeObject(config, ["packageIdentity"], state, basePath);
|
|
2971
3528
|
if (identity) {
|
|
2972
3529
|
Object.assign(
|
|
@@ -2977,10 +3534,13 @@ function mapCli(config, state, packageConfig, basePath) {
|
|
|
2977
3534
|
description: takeString(identity.value, ["description"], state, identity.path)
|
|
2978
3535
|
})
|
|
2979
3536
|
);
|
|
3537
|
+
mapCliPackageIdentity(identity, state, targetIndex);
|
|
2980
3538
|
}
|
|
3539
|
+
mapCliDistribution(config, state, basePath, targetIndex);
|
|
2981
3540
|
return compact({
|
|
2982
3541
|
paginationParameters: takeStringArray(config, ["paginationParameters"], state, basePath),
|
|
2983
|
-
skills: takeBoolean(config, ["skills"], state, basePath)
|
|
3542
|
+
skills: takeBoolean(config, ["skills"], state, basePath),
|
|
3543
|
+
...mapCliGeneration(config, state, basePath, targetIndex)
|
|
2984
3544
|
});
|
|
2985
3545
|
}
|
|
2986
3546
|
function mapTerraform(config, state, packageConfig, basePath) {
|
|
@@ -3064,6 +3624,48 @@ function mapDependencies(config, state, packageConfig, basePath) {
|
|
|
3064
3624
|
if (dependencies.length) packageConfig[field] = dependencies;
|
|
3065
3625
|
}
|
|
3066
3626
|
}
|
|
3627
|
+
function liftPackageJsonDependencies(manifest, state, packageConfig) {
|
|
3628
|
+
for (const [field, target] of [
|
|
3629
|
+
["dependencies", "extraDependencies"],
|
|
3630
|
+
["devDependencies", "extraDevDependencies"],
|
|
3631
|
+
["peerDependencies", "extraPeerDependencies"]
|
|
3632
|
+
]) {
|
|
3633
|
+
const located = takeObject(manifest.value, [field], state, manifest.path);
|
|
3634
|
+
if (!located) continue;
|
|
3635
|
+
const lifted = Object.entries(located.value).flatMap(
|
|
3636
|
+
([name, dependency]) => mapDependency(name, dependency, state, [...located.path, name])
|
|
3637
|
+
);
|
|
3638
|
+
if (lifted.length) packageConfig[target] = overrideByName(packageConfig[target] ?? [], lifted);
|
|
3639
|
+
}
|
|
3640
|
+
const meta = takeObject(manifest.value, ["peerDependenciesMeta"], state, manifest.path);
|
|
3641
|
+
if (!meta) return;
|
|
3642
|
+
const entries = peerDependenciesMetaEntries(meta, state);
|
|
3643
|
+
if (entries.length) {
|
|
3644
|
+
packageConfig.extraPeerDependenciesMeta = {
|
|
3645
|
+
...packageConfig.extraPeerDependenciesMeta,
|
|
3646
|
+
...Object.fromEntries(entries)
|
|
3647
|
+
};
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
function overrideByName(existing, overrides) {
|
|
3651
|
+
const byName = new Map(existing.map((dependency) => [dependency.name, dependency]));
|
|
3652
|
+
overrides.forEach((dependency) => byName.set(dependency.name, dependency));
|
|
3653
|
+
return [...byName.values()];
|
|
3654
|
+
}
|
|
3655
|
+
function mapPeerDependenciesMeta(config, state, packageConfig, basePath) {
|
|
3656
|
+
const located = takeObject(config, ["extraPeerDependenciesMeta"], state, basePath);
|
|
3657
|
+
if (!located) return;
|
|
3658
|
+
const entries = peerDependenciesMetaEntries(located, state);
|
|
3659
|
+
if (entries.length) packageConfig.extraPeerDependenciesMeta = Object.fromEntries(entries);
|
|
3660
|
+
}
|
|
3661
|
+
function peerDependenciesMetaEntries(located, state) {
|
|
3662
|
+
return Object.entries(located.value).flatMap(([name, value]) => {
|
|
3663
|
+
const parsed = jsonObjectSchema.safeParse(value);
|
|
3664
|
+
if (!parsed.success) return [];
|
|
3665
|
+
consume(state, [...located.path, name]);
|
|
3666
|
+
return [[name, parsed.data]];
|
|
3667
|
+
});
|
|
3668
|
+
}
|
|
3067
3669
|
function mapDependency(name, value, state, path) {
|
|
3068
3670
|
if (typeof value === "string" && value) {
|
|
3069
3671
|
consume(state, path);
|
|
@@ -3071,13 +3673,7 @@ function mapDependency(name, value, state, path) {
|
|
|
3071
3673
|
}
|
|
3072
3674
|
if (!isObject(value)) return [];
|
|
3073
3675
|
const version = takeString(value, ["version"], state, path);
|
|
3074
|
-
const
|
|
3075
|
-
const localPath = takeString(value, ["path"], state, path);
|
|
3076
|
-
const source = gitUrl ? {
|
|
3077
|
-
type: "git",
|
|
3078
|
-
url: gitUrl,
|
|
3079
|
-
...optional("ref", takeString(value, ["ref"], state, path))
|
|
3080
|
-
} : localPath ? { type: "path", path: localPath } : void 0;
|
|
3676
|
+
const source = takeDependencySource(value, state, path);
|
|
3081
3677
|
if (!version && !source) return [];
|
|
3082
3678
|
return [
|
|
3083
3679
|
{
|
|
@@ -3093,6 +3689,17 @@ function mapDependency(name, value, state, path) {
|
|
|
3093
3689
|
}
|
|
3094
3690
|
];
|
|
3095
3691
|
}
|
|
3692
|
+
function takeDependencySource(value, state, path) {
|
|
3693
|
+
const gitUrl = takeString(value, ["git"], state, path);
|
|
3694
|
+
if (gitUrl) {
|
|
3695
|
+
const ref = takeString(value, ["ref", "rev", "branch"], state, path);
|
|
3696
|
+
return { type: "git", url: gitUrl, ...optional("ref", ref) };
|
|
3697
|
+
}
|
|
3698
|
+
const localPath = takeString(value, ["path"], state, path);
|
|
3699
|
+
if (localPath) return { type: "path", path: localPath };
|
|
3700
|
+
const registry = takeString(value, ["registry"], state, path);
|
|
3701
|
+
return registry ? { type: "registry", registry } : void 0;
|
|
3702
|
+
}
|
|
3096
3703
|
function takeCustomSections(value, language, activeLanguages, state, basePath) {
|
|
3097
3704
|
const located = locate(value, ["customSections"], basePath);
|
|
3098
3705
|
if (!located || !Array.isArray(located.value)) return void 0;
|
|
@@ -3251,6 +3858,6 @@ function takeToolsets(value, aliases, state, basePath) {
|
|
|
3251
3858
|
return Object.fromEntries(entries.filter((entry) => entry !== void 0));
|
|
3252
3859
|
}
|
|
3253
3860
|
|
|
3254
|
-
export { FernConfigMappingError, SDK_CONFIG_V1_SCHEMA_VERSION, mapFernConfigToSdkConfigV1, parseSdkConfigV1, parseSdkConfigV1ForConsumption, 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, splitSdkConfigV1TargetGeneration, validateSdkConfigV1 };
|
|
3861
|
+
export { FernConfigMappingError, CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE as SDK_CONFIG_V1_CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE, SDK_CONFIG_V1_SCHEMA_VERSION, getSdkConfigV1Diagnostics, mapFernConfigToSdkConfigV1, parseSdkConfigV1, parseSdkConfigV1ForConsumption, sdkConfigV1ApiConfigSchema, sdkConfigV1AuthConfigSchema, sdkConfigV1AuthSchemeSchema, cliDistributionConfigSchema as sdkConfigV1CliDistributionConfigSchema, cliDistributionGithubAppSchema as sdkConfigV1CliDistributionGithubAppSchema, cliDistributionHomebrewSchema as sdkConfigV1CliDistributionHomebrewSchema, cliDistributionScoopSchema as sdkConfigV1CliDistributionScoopSchema, cliGenerationConfigSchema as sdkConfigV1CliGenerationConfigSchema, sdkConfigV1CliOutputConfigSchema, sdkConfigV1ClientConfigOverrideSchema, sdkConfigV1ClientConfigSchema, composerPackageNameSchema as sdkConfigV1ComposerPackageNameSchema, csharpGenerationConfigSchema as sdkConfigV1CsharpGenerationConfigSchema, sdkConfigV1DependencySchema, sdkConfigV1DocsConfigSchema, exactSemverSchema as sdkConfigV1ExactSemverSchema, sdkConfigV1GenerationConfigOverrideSchema, sdkConfigV1GenerationConfigSchema, githubActionsSecretNameSchema as sdkConfigV1GithubActionsSecretNameSchema, 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, splitSdkConfigV1TargetGeneration, validateSdkConfigV1 };
|
|
3255
3862
|
//# sourceMappingURL=index.js.map
|
|
3256
3863
|
//# sourceMappingURL=index.js.map
|