@postman/sdk-config 0.9.0 → 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 +776 -44
- 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 +762 -45
- package/dist/index.js.map +1 -1
- package/dist/sdk-config/index.cjs +728 -44
- 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 +721 -45
- package/dist/sdk-config/index.js.map +1 -1
- package/dist/sdk-config/v1/index.cjs +728 -44
- 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 +721 -45
- 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/index.cjs
CHANGED
|
@@ -131,13 +131,21 @@ var oauthScopeSchema = zod.z.strictObject({
|
|
|
131
131
|
name: nonEmptyStringSchema.describe("The OAuth scope value requested from the provider."),
|
|
132
132
|
description: zod.z.string().optional().describe("A description of the OAuth scope included in generated SDK documentation.")
|
|
133
133
|
});
|
|
134
|
+
var publicClientIdSchema = nonEmptyStringSchema.refine((value) => value.trim() === value, {
|
|
135
|
+
message: "must not have leading or trailing whitespace"
|
|
136
|
+
}).refine((value) => !value.includes("${"), {
|
|
137
|
+
message: "must be a literal public client ID, not an environment expression"
|
|
138
|
+
});
|
|
134
139
|
var oauthFlowSchema = zod.z.discriminatedUnion("type", [
|
|
135
140
|
zod.z.strictObject({
|
|
136
141
|
type: zod.z.literal("authorization-code").describe("Uses the OAuth authorization code flow."),
|
|
137
142
|
authorizationUrl: nonEmptyStringSchema.describe("The URL used to authorize the client."),
|
|
138
143
|
tokenUrl: nonEmptyStringSchema.describe("The URL used to exchange a code for tokens."),
|
|
139
144
|
refreshUrl: nonEmptyStringSchema.optional().describe("The URL used to refresh access tokens."),
|
|
140
|
-
scopes: zod.z.array(oauthScopeSchema).optional().describe("The scopes supported by this flow.")
|
|
145
|
+
scopes: zod.z.array(oauthScopeSchema).optional().describe("The scopes supported by this flow."),
|
|
146
|
+
clientId: publicClientIdSchema.optional().describe(
|
|
147
|
+
"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."
|
|
148
|
+
)
|
|
141
149
|
}),
|
|
142
150
|
zod.z.strictObject({
|
|
143
151
|
type: zod.z.literal("client-credentials").describe("Uses the OAuth client credentials flow."),
|
|
@@ -453,8 +461,102 @@ var packageConfigSchema = zod.z.strictObject({
|
|
|
453
461
|
projectUrls: zod.z.array(projectUrlSchema).optional().describe("Labeled project links for package metadata."),
|
|
454
462
|
extraDependencies: zod.z.array(dependencySchema).optional().describe("Additional runtime dependencies added to the generated package."),
|
|
455
463
|
extraDevDependencies: zod.z.array(dependencySchema).optional().describe("Additional development dependencies added to the generated package."),
|
|
456
|
-
extraPeerDependencies: zod.z.array(dependencySchema).optional().describe("Additional peer dependencies added to the generated package.")
|
|
464
|
+
extraPeerDependencies: zod.z.array(dependencySchema).optional().describe("Additional peer dependencies added to the generated package."),
|
|
465
|
+
extraPeerDependenciesMeta: zod.z.record(nonEmptyStringSchema, jsonObjectSchema).optional().describe(
|
|
466
|
+
"npm peerDependenciesMeta entries keyed by peer dependency name, such as { optional: true }."
|
|
467
|
+
)
|
|
468
|
+
});
|
|
469
|
+
var GITHUB_ACTIONS_SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
470
|
+
var GITHUB_REPOSITORY_SLUG_PATTERN = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
|
|
471
|
+
var HOMEBREW_FORMULA_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
472
|
+
var githubActionsSecretNameSchema = zod.z.string({ error: "must be the name of a GitHub Actions secret" }).regex(GITHUB_ACTIONS_SECRET_NAME_PATTERN, {
|
|
473
|
+
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."
|
|
474
|
+
}).refine((value) => value !== "GITHUB_TOKEN", {
|
|
475
|
+
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."
|
|
476
|
+
});
|
|
477
|
+
var githubRepositorySlugSchema = zod.z.string({ error: 'must be a GitHub repository in "<owner>/<repo>" form' }).regex(GITHUB_REPOSITORY_SLUG_PATTERN, {
|
|
478
|
+
error: 'must be a GitHub repository in "<owner>/<repo>" form, for example "acme/homebrew-tap"'
|
|
479
|
+
});
|
|
480
|
+
var homebrewFormulaNameSchema = zod.z.string({ error: "must be a Homebrew formula name" }).regex(HOMEBREW_FORMULA_NAME_PATTERN, {
|
|
481
|
+
error: "must be a Homebrew formula name: start with a lowercase letter and contain only a-z, 0-9, or -"
|
|
482
|
+
});
|
|
483
|
+
var cliDistributionGithubAppSchema = zod.z.strictObject({
|
|
484
|
+
appIdSecretName: githubActionsSecretNameSchema.describe(
|
|
485
|
+
"The name of the GitHub Actions secret holding the GitHub App ID or client ID."
|
|
486
|
+
),
|
|
487
|
+
privateKeySecretName: githubActionsSecretNameSchema.describe(
|
|
488
|
+
"The name of the GitHub Actions secret holding the GitHub App private key in PEM form."
|
|
489
|
+
)
|
|
490
|
+
});
|
|
491
|
+
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.";
|
|
492
|
+
var cliDistributionHomebrewSchema = zod.z.strictObject({
|
|
493
|
+
tap: githubRepositorySlugSchema.describe(
|
|
494
|
+
'The Homebrew tap repository in "<owner>/<repo>" form that receives the formula.'
|
|
495
|
+
),
|
|
496
|
+
formula: homebrewFormulaNameSchema.optional().describe("The Homebrew formula name; the generator defaults it to the CLI binary name."),
|
|
497
|
+
tokenSecretName: githubActionsSecretNameSchema.optional().describe(channelTokenSecretNameDescription)
|
|
498
|
+
});
|
|
499
|
+
var cliDistributionScoopSchema = zod.z.strictObject({
|
|
500
|
+
bucket: githubRepositorySlugSchema.describe(
|
|
501
|
+
'The Scoop bucket repository in "<owner>/<repo>" form that receives the manifest.'
|
|
502
|
+
),
|
|
503
|
+
tokenSecretName: githubActionsSecretNameSchema.optional().describe(channelTokenSecretNameDescription)
|
|
504
|
+
});
|
|
505
|
+
var cliDistributionConfigSchema = zod.z.strictObject({
|
|
506
|
+
githubApp: cliDistributionGithubAppSchema.optional().describe(
|
|
507
|
+
"A GitHub App used to mint short-lived tokens for every channel without its own tokenSecretName."
|
|
508
|
+
),
|
|
509
|
+
homebrew: cliDistributionHomebrewSchema.optional().describe("Publishes a Homebrew formula to a tap repository on each tagged release."),
|
|
510
|
+
scoop: cliDistributionScoopSchema.optional().describe("Publishes a Scoop manifest to a bucket repository on each tagged release.")
|
|
511
|
+
}).superRefine((distribution, context) => {
|
|
512
|
+
if (distribution.homebrew !== void 0 || distribution.scoop !== void 0) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (distribution.githubApp !== void 0) {
|
|
516
|
+
context.addIssue({
|
|
517
|
+
code: "custom",
|
|
518
|
+
message: "githubApp requires at least one distribution channel: homebrew or scoop",
|
|
519
|
+
path: ["githubApp"]
|
|
520
|
+
});
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
context.addIssue({
|
|
524
|
+
code: "custom",
|
|
525
|
+
message: "distribution must configure at least one channel: homebrew or scoop"
|
|
526
|
+
});
|
|
457
527
|
});
|
|
528
|
+
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.';
|
|
529
|
+
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.';
|
|
530
|
+
var CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE = "CLI_DISTRIBUTION_NON_RELEASE_MODE";
|
|
531
|
+
var nonReleaseGithubModes = /* @__PURE__ */ new Set(["pull-request", "push", "commit"]);
|
|
532
|
+
function cliDistributionModeDiagnostic(output, outputPath) {
|
|
533
|
+
const mode = output?.github?.mode;
|
|
534
|
+
if (output?.distribution === void 0 || mode === void 0 || !nonReleaseGithubModes.has(mode)) {
|
|
535
|
+
return void 0;
|
|
536
|
+
}
|
|
537
|
+
return {
|
|
538
|
+
code: CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE,
|
|
539
|
+
severity: "warning",
|
|
540
|
+
path: [...outputPath, "github", "mode"],
|
|
541
|
+
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.`,
|
|
542
|
+
suggestedAction: 'Use mode "release" or "commit-and-release", or push a version tag after merging generated changes.'
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// src/sdk-config/v1/diagnostics.ts
|
|
547
|
+
function getSdkConfigV1Diagnostics(config) {
|
|
548
|
+
return config.targets.flatMap((target, targetIndex) => {
|
|
549
|
+
if (target.language !== "cli") {
|
|
550
|
+
return [];
|
|
551
|
+
}
|
|
552
|
+
const diagnostic = cliDistributionModeDiagnostic(target.output, [
|
|
553
|
+
"targets",
|
|
554
|
+
targetIndex,
|
|
555
|
+
"output"
|
|
556
|
+
]);
|
|
557
|
+
return diagnostic ? [diagnostic] : [];
|
|
558
|
+
});
|
|
559
|
+
}
|
|
458
560
|
var httpMethodSchema = zod.z.enum([
|
|
459
561
|
"GET",
|
|
460
562
|
"POST",
|
|
@@ -659,6 +761,17 @@ function stringValue(value) {
|
|
|
659
761
|
function stringArrayValue(value) {
|
|
660
762
|
return Array.isArray(value) && value.every((item) => typeof item === "string" && item.length > 0) ? value : void 0;
|
|
661
763
|
}
|
|
764
|
+
var canonicalLicenseTypes = {
|
|
765
|
+
mit: "MIT",
|
|
766
|
+
apache: "APACHE",
|
|
767
|
+
"apache-2.0": "APACHE",
|
|
768
|
+
"gpl-3.0": "GPL3",
|
|
769
|
+
"gpl-3.0-only": "GPL3",
|
|
770
|
+
unlicensed: "UNLICENSED"
|
|
771
|
+
};
|
|
772
|
+
function canonicalLicenseType(value) {
|
|
773
|
+
return canonicalLicenseTypes[value.trim().toLowerCase()];
|
|
774
|
+
}
|
|
662
775
|
function stableJson(value) {
|
|
663
776
|
return JSON.stringify(sortKeys(value));
|
|
664
777
|
}
|
|
@@ -669,6 +782,280 @@ function sortKeys(value) {
|
|
|
669
782
|
Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, sortKeys(child)])
|
|
670
783
|
);
|
|
671
784
|
}
|
|
785
|
+
var ALPHANUMERIC_PATTERN = /[A-Za-z0-9]/;
|
|
786
|
+
var ROOT_GROUP_PATTERN = /^[a-z][a-z0-9_-]*$/;
|
|
787
|
+
var KEBAB_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
788
|
+
var DOTTED_COMMAND_PATH_PATTERN = /^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/;
|
|
789
|
+
var FIELD_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;
|
|
790
|
+
var RESERVED_USER_AGENT_SUFFIX_FLAGS = /* @__PURE__ */ new Set([
|
|
791
|
+
"params",
|
|
792
|
+
"output",
|
|
793
|
+
"json",
|
|
794
|
+
"format",
|
|
795
|
+
"dry-run",
|
|
796
|
+
"base-url",
|
|
797
|
+
"page-all",
|
|
798
|
+
"page-limit",
|
|
799
|
+
"page-delay",
|
|
800
|
+
"no-pager",
|
|
801
|
+
"no-extract",
|
|
802
|
+
"no-retry",
|
|
803
|
+
"no-stream",
|
|
804
|
+
"quiet",
|
|
805
|
+
"query",
|
|
806
|
+
"help",
|
|
807
|
+
"debug",
|
|
808
|
+
"schema"
|
|
809
|
+
]);
|
|
810
|
+
var RESERVED_PROFILES_COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
811
|
+
"auth",
|
|
812
|
+
"completion",
|
|
813
|
+
"man",
|
|
814
|
+
"errors",
|
|
815
|
+
"generate-skills",
|
|
816
|
+
"help"
|
|
817
|
+
]);
|
|
818
|
+
var binaryNameSchema = nonEmptyStringSchema.regex(ALPHANUMERIC_PATTERN, {
|
|
819
|
+
message: "binaryName must contain at least one ASCII letter or digit"
|
|
820
|
+
});
|
|
821
|
+
var rootGroupSchema = zod.z.string().regex(ROOT_GROUP_PATTERN, {
|
|
822
|
+
message: "rootGroup must start with a lowercase letter and contain only lowercase letters, digits, hyphens, and underscores"
|
|
823
|
+
});
|
|
824
|
+
var userAgentSuffixFlagSchema = zod.z.string().superRefine((value, context) => {
|
|
825
|
+
if (value.startsWith("-")) {
|
|
826
|
+
context.addIssue({
|
|
827
|
+
code: "custom",
|
|
828
|
+
message: 'userAgentSuffixFlag must be the long flag name without the leading "--"'
|
|
829
|
+
});
|
|
830
|
+
} else if (!KEBAB_NAME_PATTERN.test(value)) {
|
|
831
|
+
context.addIssue({
|
|
832
|
+
code: "custom",
|
|
833
|
+
message: "userAgentSuffixFlag must start with a lowercase letter and contain only lowercase letters, digits, and hyphens"
|
|
834
|
+
});
|
|
835
|
+
} else if (RESERVED_USER_AGENT_SUFFIX_FLAGS.has(value)) {
|
|
836
|
+
context.addIssue({
|
|
837
|
+
code: "custom",
|
|
838
|
+
message: `userAgentSuffixFlag "${value}" collides with a built-in global flag`
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
var profilesCommandNameSchema = zod.z.string().superRefine((value, context) => {
|
|
843
|
+
if (!KEBAB_NAME_PATTERN.test(value)) {
|
|
844
|
+
context.addIssue({
|
|
845
|
+
code: "custom",
|
|
846
|
+
message: "profiles.commandName must start with a lowercase letter and contain only lowercase letters, digits, and hyphens"
|
|
847
|
+
});
|
|
848
|
+
} else if (RESERVED_PROFILES_COMMAND_NAMES.has(value)) {
|
|
849
|
+
context.addIssue({
|
|
850
|
+
code: "custom",
|
|
851
|
+
message: `profiles.commandName "${value}" collides with a built-in command group`
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
function dottedCommandPathSchema(field) {
|
|
856
|
+
return zod.z.string().regex(DOTTED_COMMAND_PATH_PATTERN, {
|
|
857
|
+
message: `${field} must be a dotted command path such as "iam.keys.create"`
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
function fieldNameMapSchema(field) {
|
|
861
|
+
const message = `${field} keys and values must be field names containing only [A-Za-z0-9_.-]`;
|
|
862
|
+
return zod.z.record(zod.z.string(), zod.z.string().regex(FIELD_NAME_PATTERN, { message })).superRefine((value, context) => {
|
|
863
|
+
for (const key of Object.keys(value)) {
|
|
864
|
+
if (!FIELD_NAME_PATTERN.test(key)) {
|
|
865
|
+
context.addIssue({ code: "custom", message, path: [key] });
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
var profilesProvisionOperationSchema = zod.z.strictObject({
|
|
871
|
+
operation: dottedCommandPathSchema("profiles.provisionOperation.operation").describe(
|
|
872
|
+
"The dotted command path of the operation that mints a profile credential."
|
|
873
|
+
),
|
|
874
|
+
credential: fieldNameMapSchema("profiles.provisionOperation.credential").refine((value) => Object.keys(value).length > 0, {
|
|
875
|
+
message: "profiles.provisionOperation.credential must map at least one credential field"
|
|
876
|
+
}).describe("Maps each stored credential field to the response field that supplies it."),
|
|
877
|
+
revokeParameters: fieldNameMapSchema("profiles.provisionOperation.revokeParameters").optional().describe("Maps each revoke-operation parameter to the response field that supplies it.")
|
|
878
|
+
});
|
|
879
|
+
var profilesConfigSchema = zod.z.strictObject({
|
|
880
|
+
enabled: zod.z.boolean().describe("Whether the CLI emits profile commands and the global --profile flag."),
|
|
881
|
+
commandName: profilesCommandNameSchema.optional().describe('The profile command group name. The generator defaults to "profiles".'),
|
|
882
|
+
revokeOperation: dottedCommandPathSchema("profiles.revokeOperation").optional().describe('The dotted command path called by "profiles remove --revoke".'),
|
|
883
|
+
provisionOperation: profilesProvisionOperationSchema.optional().describe('The operation called by "profiles create --provision" and its response mapping.')
|
|
884
|
+
});
|
|
885
|
+
var cliGenerationConfigSchema = zod.z.strictObject({
|
|
886
|
+
paginationParameters: zod.z.array(nonEmptyStringSchema).optional().describe("Request parameter names treated as pagination controls by the CLI."),
|
|
887
|
+
skills: zod.z.boolean().optional().describe("Whether the generated CLI includes skills that teach AI agents to invoke commands."),
|
|
888
|
+
binaryName: binaryNameSchema.optional().describe(
|
|
889
|
+
"The CLI executable name. The generator kebab-cases it and also uses it for the source directory and env-var prefix."
|
|
890
|
+
),
|
|
891
|
+
customCommands: zod.z.boolean().optional().describe("Whether hand-written command support is generated. The generator defaults to true."),
|
|
892
|
+
rootGroup: rootGroupSchema.optional().describe("A command group that every spec-derived command is nested under."),
|
|
893
|
+
profiles: profilesConfigSchema.optional().describe("Named profile command configuration."),
|
|
894
|
+
splitTypeCrates: zod.z.boolean().optional().describe("Whether generated types are split into one crate per API behind a facade crate."),
|
|
895
|
+
userAgentSuffixFlag: userAgentSuffixFlagSchema.optional().describe('The long flag name, without "--", that appends a product token to the User-Agent.')
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
// src/sdk-config/v1/fern-config-mapper-cli.ts
|
|
899
|
+
var CLI_GENERATION_FIELDS = [
|
|
900
|
+
"binaryName",
|
|
901
|
+
"customCommands",
|
|
902
|
+
"rootGroup",
|
|
903
|
+
"profiles",
|
|
904
|
+
"splitTypeCrates",
|
|
905
|
+
"userAgentSuffixFlag"
|
|
906
|
+
];
|
|
907
|
+
var PROFILES_FIELDS = ["enabled", "commandName", "revokeOperation"];
|
|
908
|
+
var PROVISION_OPERATION_FIELDS = ["operation", "credential", "revokeParameters"];
|
|
909
|
+
function mapCliGeneration(config, state, basePath, targetIndex) {
|
|
910
|
+
const generation = {};
|
|
911
|
+
for (const field of CLI_GENERATION_FIELDS) {
|
|
912
|
+
const raw = ownValue(config, field);
|
|
913
|
+
if (raw === void 0) continue;
|
|
914
|
+
const fieldPath = [...basePath, field];
|
|
915
|
+
const { value, consumedPaths } = field === "profiles" && isObject(raw) ? pickProfiles(raw, fieldPath) : { value: raw, consumedPaths: [fieldPath] };
|
|
916
|
+
const parsed = cliGenerationConfigSchema.shape[field].safeParse(value);
|
|
917
|
+
consumedPaths.forEach((path) => consume(state, path));
|
|
918
|
+
if (parsed.success) {
|
|
919
|
+
generation[field] = structuredClone(value);
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
const diagnostics = parsed.error.issues.map(
|
|
923
|
+
(issue) => invalidValueDiagnostic(field, fieldPath, issue.path, issue.message, targetIndex)
|
|
924
|
+
);
|
|
925
|
+
(state.valueDiagnostics ??= []).push(...diagnostics);
|
|
926
|
+
}
|
|
927
|
+
return generation;
|
|
928
|
+
}
|
|
929
|
+
function pickProfiles(profiles, path) {
|
|
930
|
+
const picked = pickKnown(profiles, PROFILES_FIELDS, path);
|
|
931
|
+
const provisionOperation = ownValue(profiles, "provisionOperation");
|
|
932
|
+
const provisionPath = [...path, "provisionOperation"];
|
|
933
|
+
if (isObject(provisionOperation)) {
|
|
934
|
+
const provision = pickKnown(provisionOperation, PROVISION_OPERATION_FIELDS, provisionPath);
|
|
935
|
+
picked.value.provisionOperation = provision.value;
|
|
936
|
+
picked.consumedPaths.push(...provision.consumedPaths);
|
|
937
|
+
} else if (provisionOperation !== void 0) {
|
|
938
|
+
picked.value.provisionOperation = provisionOperation;
|
|
939
|
+
picked.consumedPaths.push(provisionPath);
|
|
940
|
+
}
|
|
941
|
+
return { value: { enabled: false, ...picked.value }, consumedPaths: picked.consumedPaths };
|
|
942
|
+
}
|
|
943
|
+
function pickKnown(value, fields, path) {
|
|
944
|
+
const picked = {};
|
|
945
|
+
const consumedPaths = [];
|
|
946
|
+
for (const field of fields) {
|
|
947
|
+
const child = ownValue(value, field);
|
|
948
|
+
if (child === void 0) continue;
|
|
949
|
+
picked[field] = child;
|
|
950
|
+
consumedPaths.push([...path, field]);
|
|
951
|
+
}
|
|
952
|
+
return { value: picked, consumedPaths };
|
|
953
|
+
}
|
|
954
|
+
function ownValue(value, key) {
|
|
955
|
+
return Object.hasOwn(value, key) ? value[key] : void 0;
|
|
956
|
+
}
|
|
957
|
+
function invalidValueDiagnostic(field, fieldPath, issuePath, message, targetIndex) {
|
|
958
|
+
const relative = issuePath.map((part) => typeof part === "symbol" ? String(part) : part);
|
|
959
|
+
const sdkConfigField = ["targets", targetIndex, "generation", field];
|
|
960
|
+
return {
|
|
961
|
+
code: "FERN_CONFIG_VALUE_INVALID",
|
|
962
|
+
severity: "warning",
|
|
963
|
+
path: [...fieldPath, ...relative],
|
|
964
|
+
reason: `CLI setting ${field} was not migrated because SDK Config rejects it: ${message}`,
|
|
965
|
+
sdkConfigPath: [...sdkConfigField, ...relative],
|
|
966
|
+
suggestedAction: `Correct the value, then set ${sdkConfigField.join(".")} manually.`
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// src/sdk-config/v1/fern-config-mapper-cli-distribution.ts
|
|
971
|
+
var DISTRIBUTION_KEYS = {
|
|
972
|
+
githubApp: { appIdSecret: "appIdSecretName", privateKeySecret: "privateKeySecretName" },
|
|
973
|
+
homebrew: { tap: "tap", formula: "formula", tokenEnvironmentVariable: "tokenSecretName" },
|
|
974
|
+
scoop: { bucket: "bucket", tokenEnvironmentVariable: "tokenSecretName" }
|
|
975
|
+
};
|
|
976
|
+
function mapCliDistribution(config, state, basePath, targetIndex) {
|
|
977
|
+
if (!Object.hasOwn(config, "distribution")) return;
|
|
978
|
+
const raw = config.distribution;
|
|
979
|
+
const path = [...basePath, "distribution"];
|
|
980
|
+
const translated = isObject(raw) ? translateDistribution(raw, path) : { value: raw, consumedPaths: [path], legacyKeys: /* @__PURE__ */ new Map() };
|
|
981
|
+
const parsed = cliDistributionConfigSchema.safeParse(translated.value);
|
|
982
|
+
translated.consumedPaths.forEach((consumedPath) => consume(state, consumedPath));
|
|
983
|
+
if (parsed.success) {
|
|
984
|
+
state.cliDistribution = { value: parsed.data, path };
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
const diagnostics = parsed.error.issues.map(
|
|
988
|
+
(issue) => invalidDistributionDiagnostic(issue, path, translated.legacyKeys, targetIndex)
|
|
989
|
+
);
|
|
990
|
+
const reportedPaths = /* @__PURE__ */ new Set();
|
|
991
|
+
(state.valueDiagnostics ??= []).push(
|
|
992
|
+
...diagnostics.filter(({ path: diagnosticPath }) => {
|
|
993
|
+
const key = diagnosticPath.join(".");
|
|
994
|
+
if (reportedPaths.has(key)) return false;
|
|
995
|
+
reportedPaths.add(key);
|
|
996
|
+
return true;
|
|
997
|
+
})
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
function translateDistribution(distribution, path) {
|
|
1001
|
+
const value = {};
|
|
1002
|
+
const consumedPaths = [];
|
|
1003
|
+
const legacyKeys = /* @__PURE__ */ new Map();
|
|
1004
|
+
for (const [block, keys] of Object.entries(DISTRIBUTION_KEYS)) {
|
|
1005
|
+
if (!Object.hasOwn(distribution, block)) continue;
|
|
1006
|
+
const blockValue = distribution[block];
|
|
1007
|
+
const blockPath = [...path, block];
|
|
1008
|
+
if (!isObject(blockValue)) {
|
|
1009
|
+
value[block] = blockValue;
|
|
1010
|
+
consumedPaths.push(blockPath);
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
const translatedBlock = {};
|
|
1014
|
+
for (const [legacyKey, sdkConfigKey] of Object.entries(keys)) {
|
|
1015
|
+
if (!Object.hasOwn(blockValue, legacyKey)) continue;
|
|
1016
|
+
translatedBlock[sdkConfigKey] = blockValue[legacyKey];
|
|
1017
|
+
consumedPaths.push([...blockPath, legacyKey]);
|
|
1018
|
+
legacyKeys.set(`${block}.${sdkConfigKey}`, legacyKey);
|
|
1019
|
+
}
|
|
1020
|
+
value[block] = translatedBlock;
|
|
1021
|
+
}
|
|
1022
|
+
return { value, consumedPaths, legacyKeys };
|
|
1023
|
+
}
|
|
1024
|
+
function invalidDistributionDiagnostic(issue, path, legacyKeys, targetIndex) {
|
|
1025
|
+
const relative = issue.path.map((part) => typeof part === "symbol" ? String(part) : part);
|
|
1026
|
+
const [block, field] = relative;
|
|
1027
|
+
const legacyField = typeof block === "string" && typeof field === "string" ? legacyKeys.get(`${block}.${field}`) : void 0;
|
|
1028
|
+
const legacyRelative = typeof block === "string" && legacyField !== void 0 ? [block, legacyField] : relative;
|
|
1029
|
+
const sdkConfigField = ["targets", targetIndex, "output", "distribution"];
|
|
1030
|
+
return {
|
|
1031
|
+
code: "FERN_CONFIG_VALUE_INVALID",
|
|
1032
|
+
severity: "warning",
|
|
1033
|
+
path: [...path, ...legacyRelative],
|
|
1034
|
+
reason: `CLI distribution was not migrated because SDK Config rejects it: ${issue.message}`,
|
|
1035
|
+
sdkConfigPath: [...sdkConfigField, ...relative],
|
|
1036
|
+
suggestedAction: `Correct the value, then set ${sdkConfigField.join(".")} manually.`
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
function applyCliDistribution(output, pending, targetIndex) {
|
|
1040
|
+
if (pending === void 0) return { output, diagnostics: [] };
|
|
1041
|
+
if (output.delivery === "github") {
|
|
1042
|
+
return { output: { ...output, distribution: pending.value }, diagnostics: [] };
|
|
1043
|
+
}
|
|
1044
|
+
const outputPath = ["targets", targetIndex, "output"];
|
|
1045
|
+
return {
|
|
1046
|
+
output,
|
|
1047
|
+
diagnostics: [
|
|
1048
|
+
{
|
|
1049
|
+
code: "FERN_CLI_DISTRIBUTION_REQUIRES_GITHUB_OUTPUT",
|
|
1050
|
+
severity: "warning",
|
|
1051
|
+
path: pending.path,
|
|
1052
|
+
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`,
|
|
1053
|
+
sdkConfigPath: [...outputPath, "distribution"],
|
|
1054
|
+
suggestedAction: `Set ${outputPath.join(".")}.delivery to "github" for the CLI repository and add ${outputPath.join(".")}.distribution manually, or remove distribution.`
|
|
1055
|
+
}
|
|
1056
|
+
]
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
672
1059
|
|
|
673
1060
|
// src/sdk-config/v1/fern-config-mapper-output.ts
|
|
674
1061
|
function mapOutput(generator, language, index) {
|
|
@@ -677,8 +1064,19 @@ function mapOutput(generator, language, index) {
|
|
|
677
1064
|
const outputPath = ["group", "generators", index, "outputMode"];
|
|
678
1065
|
const state = { consumedPaths: /* @__PURE__ */ new Set(), credentialDiagnostics: [] };
|
|
679
1066
|
if (generator.output) {
|
|
1067
|
+
const downloadSnippets = mapDownloadSnippets(
|
|
1068
|
+
generator.outputMode,
|
|
1069
|
+
outputPath,
|
|
1070
|
+
state,
|
|
1071
|
+
language,
|
|
1072
|
+
index
|
|
1073
|
+
);
|
|
680
1074
|
return {
|
|
681
1075
|
output: sanitizeNormalizedOutput(generator.output, rawOutput, state, index),
|
|
1076
|
+
...optional(
|
|
1077
|
+
"docs",
|
|
1078
|
+
downloadSnippets === void 0 ? void 0 : { snippets: { enabled: downloadSnippets } }
|
|
1079
|
+
),
|
|
682
1080
|
unsupportedFields: state.credentialDiagnostics ?? []
|
|
683
1081
|
};
|
|
684
1082
|
}
|
|
@@ -694,7 +1092,8 @@ function mapOutput(generator, language, index) {
|
|
|
694
1092
|
generator.outputMode,
|
|
695
1093
|
outputPath,
|
|
696
1094
|
state,
|
|
697
|
-
index
|
|
1095
|
+
index,
|
|
1096
|
+
language
|
|
698
1097
|
);
|
|
699
1098
|
}
|
|
700
1099
|
if (!isObject(generator.outputMode) || typeof generator.outputMode.type !== "string") {
|
|
@@ -710,14 +1109,22 @@ function mapOutput(generator, language, index) {
|
|
|
710
1109
|
consume(state, [...outputPath, "type"]);
|
|
711
1110
|
switch (output.type) {
|
|
712
1111
|
case "downloadFiles":
|
|
713
|
-
return finishOutputMapping(
|
|
1112
|
+
return finishOutputMapping(
|
|
1113
|
+
{ output: { delivery: "zip" } },
|
|
1114
|
+
output,
|
|
1115
|
+
outputPath,
|
|
1116
|
+
state,
|
|
1117
|
+
index,
|
|
1118
|
+
language
|
|
1119
|
+
);
|
|
714
1120
|
case "github":
|
|
715
1121
|
return finishOutputMapping(
|
|
716
1122
|
githubOutput(output, output.publishInfo, rawOutput, language, outputPath, state, index),
|
|
717
1123
|
output,
|
|
718
1124
|
outputPath,
|
|
719
1125
|
state,
|
|
720
|
-
index
|
|
1126
|
+
index,
|
|
1127
|
+
language
|
|
721
1128
|
);
|
|
722
1129
|
case "githubV2": {
|
|
723
1130
|
if (!isObject(output.githubV2))
|
|
@@ -742,7 +1149,8 @@ function mapOutput(generator, language, index) {
|
|
|
742
1149
|
output,
|
|
743
1150
|
outputPath,
|
|
744
1151
|
state,
|
|
745
|
-
index
|
|
1152
|
+
index,
|
|
1153
|
+
language
|
|
746
1154
|
);
|
|
747
1155
|
}
|
|
748
1156
|
case "publishV2": {
|
|
@@ -762,7 +1170,8 @@ function mapOutput(generator, language, index) {
|
|
|
762
1170
|
output,
|
|
763
1171
|
outputPath,
|
|
764
1172
|
state,
|
|
765
|
-
index
|
|
1173
|
+
index,
|
|
1174
|
+
language
|
|
766
1175
|
);
|
|
767
1176
|
}
|
|
768
1177
|
case "publish": {
|
|
@@ -782,7 +1191,8 @@ function mapOutput(generator, language, index) {
|
|
|
782
1191
|
output,
|
|
783
1192
|
outputPath,
|
|
784
1193
|
state,
|
|
785
|
-
index
|
|
1194
|
+
index,
|
|
1195
|
+
language
|
|
786
1196
|
);
|
|
787
1197
|
}
|
|
788
1198
|
default:
|
|
@@ -856,11 +1266,10 @@ function githubOutput(value, publishInfo, rawOutput, language, sourcePath, state
|
|
|
856
1266
|
...optionalObject("package", { ...publication?.package, ...licensePackage })
|
|
857
1267
|
};
|
|
858
1268
|
}
|
|
859
|
-
var basicLicenseTypes = { mit: "MIT", apache: "APACHE" };
|
|
860
1269
|
function mapGithubLicense(value, sourcePath, state) {
|
|
861
1270
|
if (!isObject(value) || stringValue(value.type) !== "basic") return {};
|
|
862
1271
|
const id = stringValue(value.id);
|
|
863
|
-
const type = id ?
|
|
1272
|
+
const type = id ? canonicalLicenseType(id) : void 0;
|
|
864
1273
|
if (!type) return {};
|
|
865
1274
|
consume(state, [...sourcePath, "type"]);
|
|
866
1275
|
consume(state, [...sourcePath, "id"]);
|
|
@@ -1289,7 +1698,8 @@ function mapAuthors(value, sourcePath, state) {
|
|
|
1289
1698
|
});
|
|
1290
1699
|
return authors;
|
|
1291
1700
|
}
|
|
1292
|
-
function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
|
|
1701
|
+
function finishOutputMapping(mapping, outputMode, sourcePath, state, index, language) {
|
|
1702
|
+
const downloadSnippets = mapDownloadSnippets(outputMode, sourcePath, state, language, index);
|
|
1293
1703
|
for (const path of collectLeafPaths(outputMode, sourcePath)) {
|
|
1294
1704
|
if (path[path.length - 1] === "_visit") consume(state, path);
|
|
1295
1705
|
}
|
|
@@ -1297,6 +1707,10 @@ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
|
|
|
1297
1707
|
const hasCredentials = unsupported.some((diagnostic) => isCredentialPath(diagnostic.path));
|
|
1298
1708
|
return {
|
|
1299
1709
|
...mapping,
|
|
1710
|
+
...optional(
|
|
1711
|
+
"docs",
|
|
1712
|
+
downloadSnippets === void 0 ? void 0 : { snippets: { enabled: downloadSnippets } }
|
|
1713
|
+
),
|
|
1300
1714
|
unsupportedFields: [
|
|
1301
1715
|
...state.credentialDiagnostics ?? [],
|
|
1302
1716
|
...hasCredentials ? [
|
|
@@ -1316,6 +1730,45 @@ function finishOutputMapping(mapping, outputMode, sourcePath, state, index) {
|
|
|
1316
1730
|
]
|
|
1317
1731
|
};
|
|
1318
1732
|
}
|
|
1733
|
+
function mapDownloadSnippets(value, sourcePath, state, language, index) {
|
|
1734
|
+
if (!isObject(value)) return void 0;
|
|
1735
|
+
const candidates = [];
|
|
1736
|
+
switch (value.type) {
|
|
1737
|
+
case "downloadFiles":
|
|
1738
|
+
case "github":
|
|
1739
|
+
candidates.push({ value, path: sourcePath });
|
|
1740
|
+
break;
|
|
1741
|
+
case "githubV2":
|
|
1742
|
+
if (isObject(value.githubV2)) {
|
|
1743
|
+
candidates.push({ value: value.githubV2, path: [...sourcePath, "githubV2"] });
|
|
1744
|
+
}
|
|
1745
|
+
break;
|
|
1746
|
+
case "publishV2":
|
|
1747
|
+
if (isObject(value.publishV2)) {
|
|
1748
|
+
candidates.push({ value: value.publishV2, path: [...sourcePath, "publishV2"] });
|
|
1749
|
+
}
|
|
1750
|
+
break;
|
|
1751
|
+
case "publish":
|
|
1752
|
+
if (isObject(value.registryOverrides)) {
|
|
1753
|
+
const registry = defaultRegistry(language, [...sourcePath, "registryOverrides"], index);
|
|
1754
|
+
const override = value.registryOverrides[registry];
|
|
1755
|
+
if (isObject(override)) {
|
|
1756
|
+
candidates.push({
|
|
1757
|
+
value: override,
|
|
1758
|
+
path: [...sourcePath, "registryOverrides", registry]
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
break;
|
|
1763
|
+
}
|
|
1764
|
+
let enabled;
|
|
1765
|
+
for (const candidate of candidates) {
|
|
1766
|
+
if (typeof candidate.value.downloadSnippets !== "boolean") continue;
|
|
1767
|
+
consume(state, [...candidate.path, "downloadSnippets"]);
|
|
1768
|
+
enabled = enabled === true || candidate.value.downloadSnippets;
|
|
1769
|
+
}
|
|
1770
|
+
return enabled;
|
|
1771
|
+
}
|
|
1319
1772
|
function isCredentialPath(path) {
|
|
1320
1773
|
const fields = path.filter((part) => typeof part === "string");
|
|
1321
1774
|
const field = fields[fields.length - 1];
|
|
@@ -1383,6 +1836,114 @@ function outputDiagnostic(path, index) {
|
|
|
1383
1836
|
suggestedAction: resolvedGuidance?.suggestedAction ?? "Review this output setting and preserve it outside SDK Config when no equivalent exists."
|
|
1384
1837
|
};
|
|
1385
1838
|
}
|
|
1839
|
+
|
|
1840
|
+
// src/sdk-config/v1/package.ts
|
|
1841
|
+
var sdkConfigV1DependencySchema = dependencySchema;
|
|
1842
|
+
var sdkConfigV1PackageConfigSchema = packageConfigSchema;
|
|
1843
|
+
|
|
1844
|
+
// src/sdk-config/v1/fern-config-mapper-package.ts
|
|
1845
|
+
var emailSchema = zod.z.email();
|
|
1846
|
+
function mapCliPackageIdentity(identity, state, targetIndex) {
|
|
1847
|
+
mapIdentityField(identity, "homepage", stringValue, state);
|
|
1848
|
+
mapIdentityField(identity, "keywords", (value) => stringArrayValue(value)?.slice(), state);
|
|
1849
|
+
mapCargoAuthors(identity, state, targetIndex);
|
|
1850
|
+
mapIdentityField(identity, "license", licenseValue, state);
|
|
1851
|
+
}
|
|
1852
|
+
function mapIdentityField(identity, field, read, state) {
|
|
1853
|
+
const located = locate(identity.value, [field], identity.path);
|
|
1854
|
+
const value = located && read(located.value);
|
|
1855
|
+
if (located && value !== void 0) addPackageFallback(state, field, value, located.path);
|
|
1856
|
+
}
|
|
1857
|
+
function mapLicenseFallback(config, aliases, state, basePath) {
|
|
1858
|
+
const located = locate(config, aliases, basePath);
|
|
1859
|
+
const license = located && licenseValue(located.value);
|
|
1860
|
+
if (located && license) addPackageFallback(state, "license", license, located.path);
|
|
1861
|
+
}
|
|
1862
|
+
function resolveTargetPackage(targetPackage, fallbacks, generator, delivery, index) {
|
|
1863
|
+
const diagnostics = [];
|
|
1864
|
+
for (const fallback of fallbacks) {
|
|
1865
|
+
applyFallback(targetPackage, fallback, index, diagnostics);
|
|
1866
|
+
}
|
|
1867
|
+
if (delivery !== "github") {
|
|
1868
|
+
applyMetadataLicense(targetPackage, generator.raw, index, diagnostics);
|
|
1869
|
+
}
|
|
1870
|
+
return diagnostics;
|
|
1871
|
+
}
|
|
1872
|
+
function applyFallback(targetPackage, { field, value, path }, index, diagnostics) {
|
|
1873
|
+
const existing = targetPackage[field];
|
|
1874
|
+
if (existing === void 0) {
|
|
1875
|
+
targetPackage[field] = value;
|
|
1876
|
+
} else if (stableJson(existing) !== stableJson(value)) {
|
|
1877
|
+
diagnostics.push({
|
|
1878
|
+
code: "FERN_PACKAGE_VALUE_CONFLICT",
|
|
1879
|
+
severity: "warning",
|
|
1880
|
+
path,
|
|
1881
|
+
reason: `Fern value conflicts with the package.${field} already migrated for this target, which is kept`,
|
|
1882
|
+
sdkConfigPath: ["targets", index, "package", field],
|
|
1883
|
+
suggestedAction: `Choose the intended value and set targets.${index}.package.${field} manually.`
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
function applyMetadataLicense(targetPackage, raw, index, diagnostics) {
|
|
1888
|
+
const metadata = isObject(raw) && isObject(raw.metadata) ? raw.metadata : void 0;
|
|
1889
|
+
if (metadata?.license === void 0 || metadata.license === null) return;
|
|
1890
|
+
const path = ["group", "generators", index, "metadata", "license"];
|
|
1891
|
+
const license = licenseValue(metadata.license);
|
|
1892
|
+
if (license) {
|
|
1893
|
+
applyFallback(targetPackage, { field: "license", value: license, path }, index, diagnostics);
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1896
|
+
diagnostics.push({
|
|
1897
|
+
code: "FERN_CONFIG_FIELD_UNSUPPORTED",
|
|
1898
|
+
severity: "warning",
|
|
1899
|
+
path,
|
|
1900
|
+
reason: isObject(metadata.license) ? "A custom license file cannot be migrated automatically" : "metadata.license is not a license identifier",
|
|
1901
|
+
sdkConfigPath: ["targets", index, "package", "license"],
|
|
1902
|
+
suggestedAction: `Set targets.${index}.package.license manually.`
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
function mapCargoAuthors(identity, state, targetIndex) {
|
|
1906
|
+
const located = locate(identity.value, ["authors"], identity.path);
|
|
1907
|
+
const entries = located && stringArrayValue(located.value);
|
|
1908
|
+
if (!located || !entries) return;
|
|
1909
|
+
consume(state, located.path);
|
|
1910
|
+
const authors = entries.map(parseCargoAuthor);
|
|
1911
|
+
const parsed = sdkConfigV1PackageConfigSchema.shape.authors.safeParse(authors);
|
|
1912
|
+
const invalid = parsed.success ? [] : [...new Set(parsed.error.issues.map((issue) => issue.path[0]))].filter(
|
|
1913
|
+
(index) => typeof index === "number"
|
|
1914
|
+
);
|
|
1915
|
+
if (invalid.length === 0) {
|
|
1916
|
+
addPackageFallback(state, "authors", authors, located.path);
|
|
1917
|
+
return;
|
|
1918
|
+
}
|
|
1919
|
+
const authorsPath = ["targets", targetIndex, "package", "authors"];
|
|
1920
|
+
(state.valueDiagnostics ??= []).push(
|
|
1921
|
+
...invalid.map((entry) => ({
|
|
1922
|
+
code: "FERN_CONFIG_VALUE_INVALID",
|
|
1923
|
+
severity: "warning",
|
|
1924
|
+
path: [...located.path, entry],
|
|
1925
|
+
reason: 'CLI packageIdentity.authors was not migrated because this entry is not "Name" or "Name <email>" with a valid email',
|
|
1926
|
+
sdkConfigPath: authorsPath,
|
|
1927
|
+
suggestedAction: `Correct the entry, then set ${authorsPath.join(".")} manually.`
|
|
1928
|
+
}))
|
|
1929
|
+
);
|
|
1930
|
+
}
|
|
1931
|
+
function parseCargoAuthor(entry) {
|
|
1932
|
+
const trimmed = entry.trim();
|
|
1933
|
+
const match = /^(.*?)\s*<([^<>]*)>$/.exec(trimmed);
|
|
1934
|
+
if (!match) return { name: trimmed };
|
|
1935
|
+
const [, name = "", email = ""] = match;
|
|
1936
|
+
if (name !== "" && !emailSchema.safeParse(email).success) return { name: trimmed };
|
|
1937
|
+
return { name, email };
|
|
1938
|
+
}
|
|
1939
|
+
function licenseValue(value) {
|
|
1940
|
+
const license = stringValue(value)?.trim();
|
|
1941
|
+
return license ? { type: canonicalLicenseType(license) ?? license } : void 0;
|
|
1942
|
+
}
|
|
1943
|
+
function addPackageFallback(state, field, value, path) {
|
|
1944
|
+
consume(state, path);
|
|
1945
|
+
(state.packageFallbacks ??= []).push({ field, value, path });
|
|
1946
|
+
}
|
|
1386
1947
|
var OMIT = /* @__PURE__ */ Symbol("omit");
|
|
1387
1948
|
function inputJsonSchema(schema) {
|
|
1388
1949
|
return zod.z.toJSONSchema(schema, {
|
|
@@ -1652,7 +2213,16 @@ var sdkConfigV1PublishConfigSchema = zod.z.discriminatedUnion("registry", [
|
|
|
1652
2213
|
zod.z.strictObject({
|
|
1653
2214
|
registry: zod.z.literal("npm").describe("Publishes the package to an npm-compatible registry."),
|
|
1654
2215
|
token: nonEmptyStringSchema.optional().describe("The npm registry token, or an environment expression that resolves to it."),
|
|
2216
|
+
trustedPublishing: zod.z.boolean().optional().describe("Whether npm publication uses trusted publishing (OIDC) instead of a token."),
|
|
1655
2217
|
...commonPublishShape
|
|
2218
|
+
}).superRefine((publish, context) => {
|
|
2219
|
+
if (publish.trustedPublishing === true && publish.token !== void 0) {
|
|
2220
|
+
context.addIssue({
|
|
2221
|
+
code: "custom",
|
|
2222
|
+
message: "token must be omitted when trustedPublishing is true",
|
|
2223
|
+
path: ["token"]
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
1656
2226
|
}),
|
|
1657
2227
|
zod.z.strictObject({
|
|
1658
2228
|
registry: zod.z.literal("pypi").describe("Publishes the package to a PyPI-compatible registry."),
|
|
@@ -1730,10 +2300,29 @@ var sdkConfigV1OutputConfigSchema = zod.z.discriminatedUnion(
|
|
|
1730
2300
|
[filesOutputSchema, zipOutputSchema, githubDeliverySchema],
|
|
1731
2301
|
{ error: 'output.delivery must be one of "files", "zip", or "github"' }
|
|
1732
2302
|
);
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
2303
|
+
var cliDistributionShape = {
|
|
2304
|
+
distribution: cliDistributionConfigSchema.optional().describe(
|
|
2305
|
+
"CLI release channels published by the generated release workflow; credentials are GitHub Actions secret names."
|
|
2306
|
+
)
|
|
2307
|
+
};
|
|
2308
|
+
function rejectDistributionWithoutGithub(output, context) {
|
|
2309
|
+
if (output.distribution !== void 0) {
|
|
2310
|
+
context.addIssue({
|
|
2311
|
+
code: "custom",
|
|
2312
|
+
message: CLI_DISTRIBUTION_REQUIRES_GITHUB_DELIVERY_MESSAGE,
|
|
2313
|
+
path: ["distribution"]
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
var sdkConfigV1CliOutputConfigSchema = zod.z.discriminatedUnion(
|
|
2318
|
+
"delivery",
|
|
2319
|
+
[
|
|
2320
|
+
filesOutputSchema.extend(cliDistributionShape).superRefine(rejectDistributionWithoutGithub),
|
|
2321
|
+
zipOutputSchema.extend(cliDistributionShape).superRefine(rejectDistributionWithoutGithub),
|
|
2322
|
+
githubDeliverySchema.extend(cliDistributionShape)
|
|
2323
|
+
],
|
|
2324
|
+
{ error: 'output.delivery must be one of "files", "zip", or "github"' }
|
|
2325
|
+
);
|
|
1737
2326
|
var sdkConfigV1ReplayConfigSchema = zod.z.strictObject({
|
|
1738
2327
|
enabled: zod.z.boolean().describe("Whether regeneration reapplies customer-authored repository changes.")
|
|
1739
2328
|
});
|
|
@@ -1810,10 +2399,6 @@ var sdkConfigV1SourceConfigSchema = zod.z.strictObject({
|
|
|
1810
2399
|
seenIds.add(id);
|
|
1811
2400
|
});
|
|
1812
2401
|
});
|
|
1813
|
-
var cliGenerationConfigSchema = zod.z.strictObject({
|
|
1814
|
-
paginationParameters: zod.z.array(nonEmptyStringSchema).optional().describe("Request parameter names treated as pagination controls by the CLI."),
|
|
1815
|
-
skills: zod.z.boolean().optional().describe("Whether the generated CLI includes skills that teach AI agents to invoke commands.")
|
|
1816
|
-
});
|
|
1817
2402
|
var csharpGenerationConfigSchema = zod.z.strictObject({
|
|
1818
2403
|
useOptionalWrapper: zod.z.boolean().optional().describe("Whether optional values use an explicit Optional wrapper."),
|
|
1819
2404
|
simplifyObjectDictionaries: zod.z.boolean().optional().describe("Whether object schemas with arbitrary values use simplified dictionary types."),
|
|
@@ -2066,7 +2651,10 @@ var sdkConfigV1TargetSchema = zod.z.discriminatedUnion("language", [
|
|
|
2066
2651
|
zod.z.strictObject({
|
|
2067
2652
|
language: zod.z.literal("cli").describe("Generates a command-line interface."),
|
|
2068
2653
|
generation: sdkConfigV1GenerationConfigOverrideSchema.extend(cliGenerationConfigSchema.shape).optional().describe("Common and CLI-specific generation settings for this target."),
|
|
2069
|
-
...targetOverrideShape
|
|
2654
|
+
...targetOverrideShape,
|
|
2655
|
+
output: sdkConfigV1CliOutputConfigSchema.optional().describe(
|
|
2656
|
+
"Output configuration, including optional CLI distribution channels, that replaces the root output for this target."
|
|
2657
|
+
)
|
|
2070
2658
|
}),
|
|
2071
2659
|
zod.z.strictObject({
|
|
2072
2660
|
language: zod.z.literal("mcp").describe("Generates an MCP server."),
|
|
@@ -2083,7 +2671,7 @@ var sdkConfigV1TargetSchema = zod.z.discriminatedUnion("language", [
|
|
|
2083
2671
|
// src/sdk-config/v1/sdk-config-v1.ts
|
|
2084
2672
|
var SDK_CONFIG_V1_SCHEMA_VERSION = "sdk-config/v1";
|
|
2085
2673
|
var publishRegistryLanguages = {
|
|
2086
|
-
npm: ["typescript", "mcp"],
|
|
2674
|
+
npm: ["typescript", "mcp", "cli"],
|
|
2087
2675
|
pypi: ["python"],
|
|
2088
2676
|
maven: ["java", "kotlin"],
|
|
2089
2677
|
nuget: ["csharp"],
|
|
@@ -2160,6 +2748,13 @@ function validateTargetPublishing(target, targetIndex, globalPackage, globalOutp
|
|
|
2160
2748
|
});
|
|
2161
2749
|
return;
|
|
2162
2750
|
}
|
|
2751
|
+
if (target.language === "cli" && output.delivery !== "github") {
|
|
2752
|
+
context.addIssue({
|
|
2753
|
+
code: "custom",
|
|
2754
|
+
message: CLI_PUBLISH_REQUIRES_GITHUB_DELIVERY_MESSAGE,
|
|
2755
|
+
path: target.output ? ["targets", targetIndex, "output", "delivery"] : ["output", "delivery"]
|
|
2756
|
+
});
|
|
2757
|
+
}
|
|
2163
2758
|
validatePublishingIdentity(
|
|
2164
2759
|
{ ...globalPackage, ...target.package },
|
|
2165
2760
|
registry,
|
|
@@ -2251,11 +2846,12 @@ function mapFernConfigToSdkConfigV1(input) {
|
|
|
2251
2846
|
generator,
|
|
2252
2847
|
language,
|
|
2253
2848
|
invocation,
|
|
2254
|
-
...outputMapping
|
|
2849
|
+
...outputMapping,
|
|
2850
|
+
docs: { ...invocation.docs, ...outputMapping.docs }
|
|
2255
2851
|
};
|
|
2256
2852
|
});
|
|
2257
2853
|
const clients = partitionSharedBlock(mapped.map(({ invocation }) => invocation.client));
|
|
2258
|
-
const docs = partitionSharedBlock(mapped.map(({
|
|
2854
|
+
const docs = partitionSharedBlock(mapped.map(({ docs: docs2 }) => docs2));
|
|
2259
2855
|
const generations = partitionSharedBlock(mapped.map(({ invocation }) => invocation.generation));
|
|
2260
2856
|
const api = { ...input.api ?? {} };
|
|
2261
2857
|
delete api.audiences;
|
|
@@ -2271,16 +2867,28 @@ function mapFernConfigToSdkConfigV1(input) {
|
|
|
2271
2867
|
package: outputPackage,
|
|
2272
2868
|
generation: outputGeneration
|
|
2273
2869
|
}, index) => {
|
|
2870
|
+
const distribution = applyCliDistribution(output, invocation.cliDistribution, index);
|
|
2871
|
+
invocation.unsupportedFields.push(...distribution.diagnostics);
|
|
2274
2872
|
const target = {
|
|
2275
2873
|
language,
|
|
2276
|
-
output,
|
|
2874
|
+
output: distribution.output,
|
|
2277
2875
|
...optional("sdkName", generator.sdkName),
|
|
2278
2876
|
...optional("sdkVersion", generator.sdkVersion),
|
|
2279
2877
|
...optional("client", clients.targetOverrides[index]),
|
|
2280
2878
|
...optional("docs", docs.targetOverrides[index])
|
|
2281
2879
|
};
|
|
2282
|
-
|
|
2283
|
-
|
|
2880
|
+
const targetPackage = { ...invocation.package, ...outputPackage, ...generator.package };
|
|
2881
|
+
invocation.unsupportedFields.push(
|
|
2882
|
+
...resolveTargetPackage(
|
|
2883
|
+
targetPackage,
|
|
2884
|
+
invocation.packageFallbacks,
|
|
2885
|
+
generator,
|
|
2886
|
+
output.delivery,
|
|
2887
|
+
index
|
|
2888
|
+
)
|
|
2889
|
+
);
|
|
2890
|
+
if (Object.keys(targetPackage).length > 0 || outputPackage || generator.package) {
|
|
2891
|
+
target.package = targetPackage;
|
|
2284
2892
|
}
|
|
2285
2893
|
const targetGeneration = {
|
|
2286
2894
|
...generations.targetOverrides[index],
|
|
@@ -2462,10 +3070,14 @@ function mapInvocation(generator, language, activeLanguages, index) {
|
|
|
2462
3070
|
...optional("smartCasingDigitWordBoundary", smartCasingDigitWordBoundary)
|
|
2463
3071
|
};
|
|
2464
3072
|
}
|
|
2465
|
-
const targetGeneration = mapLanguageConfig(
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
3073
|
+
const targetGeneration = mapLanguageConfig(
|
|
3074
|
+
language,
|
|
3075
|
+
config,
|
|
3076
|
+
state,
|
|
3077
|
+
packageConfig,
|
|
3078
|
+
[...prefix, "config"],
|
|
3079
|
+
index
|
|
3080
|
+
);
|
|
2469
3081
|
mapPublishMetadata(generator.publishMetadata, packageConfig);
|
|
2470
3082
|
if (generator.keywords?.length) {
|
|
2471
3083
|
generation.reservedKeywords = [...generator.keywords];
|
|
@@ -2482,12 +3094,22 @@ function mapInvocation(generator, language, activeLanguages, index) {
|
|
|
2482
3094
|
}
|
|
2483
3095
|
const docs = mapReadme(generator.readme, language, activeLanguages, state, [...prefix, "readme"]);
|
|
2484
3096
|
const unsupportedFields = [
|
|
3097
|
+
...state.valueDiagnostics ?? [],
|
|
2485
3098
|
...collectUnsupported(config, [...prefix, "config"], state),
|
|
2486
3099
|
...settings ? collectUnsupported(settings, [...prefix, "settings"], state) : [],
|
|
2487
3100
|
...isObject(generator.readme) ? collectUnsupported(generator.readme, [...prefix, "readme"], state) : [],
|
|
2488
3101
|
...unsupportedResolvedFields(generator, index, apiWideIdempotency !== void 0)
|
|
2489
3102
|
];
|
|
2490
|
-
return {
|
|
3103
|
+
return {
|
|
3104
|
+
client,
|
|
3105
|
+
docs,
|
|
3106
|
+
generation,
|
|
3107
|
+
package: packageConfig,
|
|
3108
|
+
packageFallbacks: state.packageFallbacks ?? [],
|
|
3109
|
+
...optional("cliDistribution", state.cliDistribution),
|
|
3110
|
+
targetGeneration,
|
|
3111
|
+
unsupportedFields
|
|
3112
|
+
};
|
|
2491
3113
|
}
|
|
2492
3114
|
function unsupportedResolvedFields(generator, index, idempotencyMapped) {
|
|
2493
3115
|
const values = [
|
|
@@ -2677,6 +3299,7 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
|
|
|
2677
3299
|
const packagePath = takeString(config, ["packagePath"], state, basePath);
|
|
2678
3300
|
if (packagePath !== void 0) generation.layout = { packagePath };
|
|
2679
3301
|
mapDependencies(config, state, packageConfig, basePath);
|
|
3302
|
+
mapPeerDependenciesMeta(config, state, packageConfig, basePath);
|
|
2680
3303
|
}
|
|
2681
3304
|
function mapTypescriptStreams(config, state, basePath) {
|
|
2682
3305
|
const responseType = takeEnum(config, ["streamType"], ["wrapper", "web"], state, basePath);
|
|
@@ -2690,7 +3313,7 @@ function mapTypescriptStreams(config, state, basePath) {
|
|
|
2690
3313
|
if (responseType === void 0 && fileResponseType === void 0) return void 0;
|
|
2691
3314
|
return { enabled: true, ...compact({ responseType, fileResponseType }) };
|
|
2692
3315
|
}
|
|
2693
|
-
function mapLanguageConfig(language, config, state, packageConfig, basePath) {
|
|
3316
|
+
function mapLanguageConfig(language, config, state, packageConfig, basePath, targetIndex) {
|
|
2694
3317
|
switch (language) {
|
|
2695
3318
|
case "typescript":
|
|
2696
3319
|
return mapTypescript(config, state, packageConfig, basePath);
|
|
@@ -2717,7 +3340,7 @@ function mapLanguageConfig(language, config, state, packageConfig, basePath) {
|
|
|
2717
3340
|
case "swift":
|
|
2718
3341
|
return mapSwift(config, state, basePath);
|
|
2719
3342
|
case "cli":
|
|
2720
|
-
return mapCli(config, state, packageConfig, basePath);
|
|
3343
|
+
return mapCli(config, state, packageConfig, basePath, targetIndex);
|
|
2721
3344
|
case "terraform":
|
|
2722
3345
|
return mapTerraform(config, state, packageConfig, basePath);
|
|
2723
3346
|
}
|
|
@@ -2734,6 +3357,7 @@ function mapTypescript(config, state, packageConfig, basePath) {
|
|
|
2734
3357
|
const packageManagerAtIndex = packageJsonPackageManager ? packageJsonPackageManager.indexOf("@", packageJsonPackageManager.startsWith("@") ? 1 : 0) : -1;
|
|
2735
3358
|
const packageManagerVersionPart = packageManagerAtIndex >= 0 ? packageJsonPackageManager?.slice(packageManagerAtIndex + 1).split("+")[0] : void 0;
|
|
2736
3359
|
const packageManagerVersion = packageManagerVersionPart || void 0;
|
|
3360
|
+
if (packageJsonManifest) liftPackageJsonDependencies(packageJsonManifest, state, packageConfig);
|
|
2737
3361
|
const serdeLayer = takeBoolean(config, ["serdeLayer"], state, basePath);
|
|
2738
3362
|
const noSerdeLayer = takeBoolean(config, ["noSerdeLayer"], state, basePath);
|
|
2739
3363
|
const fetchSupport = takeEnum(config, ["fetchSupport"], ["native"], state, basePath);
|
|
@@ -2790,7 +3414,8 @@ function mapPython(config, state, packageConfig, basePath) {
|
|
|
2790
3414
|
});
|
|
2791
3415
|
}
|
|
2792
3416
|
function mapJvm(language, config, state, packageConfig, basePath) {
|
|
2793
|
-
const
|
|
3417
|
+
const namespaceAliases = language === "java" ? ["packagePrefix"] : ["packageName", "packagePrefix"];
|
|
3418
|
+
const namespace = takeString(config, namespaceAliases, state, basePath);
|
|
2794
3419
|
const groupId = takeString(config, ["group", "groupId"], state, basePath);
|
|
2795
3420
|
const artifactId = takeString(config, ["artifact", "artifactId"], state, basePath);
|
|
2796
3421
|
if (namespace !== void 0) packageConfig.namespace = namespace;
|
|
@@ -2902,6 +3527,7 @@ function mapRust(config, state, packageConfig, basePath) {
|
|
|
2902
3527
|
const description = takeString(config, ["packageDescription"], state, basePath);
|
|
2903
3528
|
const documentationUrl = takeString(config, ["packageDocumentation"], state, basePath);
|
|
2904
3529
|
Object.assign(packageConfig, compact({ packageName, repository, description, documentationUrl }));
|
|
3530
|
+
mapLicenseFallback(config, ["packageLicense"], state, basePath);
|
|
2905
3531
|
return compact({
|
|
2906
3532
|
dateTimeType: takeEnum(config, ["dateTimeType"], ["offset", "utc"], state, basePath),
|
|
2907
3533
|
capitalizeInitialisms: takeBoolean(config, ["capitalizeInitialisms"], state, basePath),
|
|
@@ -2915,7 +3541,7 @@ function mapSwift(config, state, basePath) {
|
|
|
2915
3541
|
nullableAsOptional: takeBoolean(config, ["nullableAsOptional"], state, basePath)
|
|
2916
3542
|
});
|
|
2917
3543
|
}
|
|
2918
|
-
function mapCli(config, state, packageConfig, basePath) {
|
|
3544
|
+
function mapCli(config, state, packageConfig, basePath, targetIndex) {
|
|
2919
3545
|
const identity = takeObject(config, ["packageIdentity"], state, basePath);
|
|
2920
3546
|
if (identity) {
|
|
2921
3547
|
Object.assign(
|
|
@@ -2926,10 +3552,13 @@ function mapCli(config, state, packageConfig, basePath) {
|
|
|
2926
3552
|
description: takeString(identity.value, ["description"], state, identity.path)
|
|
2927
3553
|
})
|
|
2928
3554
|
);
|
|
3555
|
+
mapCliPackageIdentity(identity, state, targetIndex);
|
|
2929
3556
|
}
|
|
3557
|
+
mapCliDistribution(config, state, basePath, targetIndex);
|
|
2930
3558
|
return compact({
|
|
2931
3559
|
paginationParameters: takeStringArray(config, ["paginationParameters"], state, basePath),
|
|
2932
|
-
skills: takeBoolean(config, ["skills"], state, basePath)
|
|
3560
|
+
skills: takeBoolean(config, ["skills"], state, basePath),
|
|
3561
|
+
...mapCliGeneration(config, state, basePath, targetIndex)
|
|
2933
3562
|
});
|
|
2934
3563
|
}
|
|
2935
3564
|
function mapTerraform(config, state, packageConfig, basePath) {
|
|
@@ -3013,6 +3642,48 @@ function mapDependencies(config, state, packageConfig, basePath) {
|
|
|
3013
3642
|
if (dependencies.length) packageConfig[field] = dependencies;
|
|
3014
3643
|
}
|
|
3015
3644
|
}
|
|
3645
|
+
function liftPackageJsonDependencies(manifest, state, packageConfig) {
|
|
3646
|
+
for (const [field, target] of [
|
|
3647
|
+
["dependencies", "extraDependencies"],
|
|
3648
|
+
["devDependencies", "extraDevDependencies"],
|
|
3649
|
+
["peerDependencies", "extraPeerDependencies"]
|
|
3650
|
+
]) {
|
|
3651
|
+
const located = takeObject(manifest.value, [field], state, manifest.path);
|
|
3652
|
+
if (!located) continue;
|
|
3653
|
+
const lifted = Object.entries(located.value).flatMap(
|
|
3654
|
+
([name, dependency]) => mapDependency(name, dependency, state, [...located.path, name])
|
|
3655
|
+
);
|
|
3656
|
+
if (lifted.length) packageConfig[target] = overrideByName(packageConfig[target] ?? [], lifted);
|
|
3657
|
+
}
|
|
3658
|
+
const meta = takeObject(manifest.value, ["peerDependenciesMeta"], state, manifest.path);
|
|
3659
|
+
if (!meta) return;
|
|
3660
|
+
const entries = peerDependenciesMetaEntries(meta, state);
|
|
3661
|
+
if (entries.length) {
|
|
3662
|
+
packageConfig.extraPeerDependenciesMeta = {
|
|
3663
|
+
...packageConfig.extraPeerDependenciesMeta,
|
|
3664
|
+
...Object.fromEntries(entries)
|
|
3665
|
+
};
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
function overrideByName(existing, overrides) {
|
|
3669
|
+
const byName = new Map(existing.map((dependency) => [dependency.name, dependency]));
|
|
3670
|
+
overrides.forEach((dependency) => byName.set(dependency.name, dependency));
|
|
3671
|
+
return [...byName.values()];
|
|
3672
|
+
}
|
|
3673
|
+
function mapPeerDependenciesMeta(config, state, packageConfig, basePath) {
|
|
3674
|
+
const located = takeObject(config, ["extraPeerDependenciesMeta"], state, basePath);
|
|
3675
|
+
if (!located) return;
|
|
3676
|
+
const entries = peerDependenciesMetaEntries(located, state);
|
|
3677
|
+
if (entries.length) packageConfig.extraPeerDependenciesMeta = Object.fromEntries(entries);
|
|
3678
|
+
}
|
|
3679
|
+
function peerDependenciesMetaEntries(located, state) {
|
|
3680
|
+
return Object.entries(located.value).flatMap(([name, value]) => {
|
|
3681
|
+
const parsed = jsonObjectSchema.safeParse(value);
|
|
3682
|
+
if (!parsed.success) return [];
|
|
3683
|
+
consume(state, [...located.path, name]);
|
|
3684
|
+
return [[name, parsed.data]];
|
|
3685
|
+
});
|
|
3686
|
+
}
|
|
3016
3687
|
function mapDependency(name, value, state, path) {
|
|
3017
3688
|
if (typeof value === "string" && value) {
|
|
3018
3689
|
consume(state, path);
|
|
@@ -3020,13 +3691,7 @@ function mapDependency(name, value, state, path) {
|
|
|
3020
3691
|
}
|
|
3021
3692
|
if (!isObject(value)) return [];
|
|
3022
3693
|
const version = takeString(value, ["version"], state, path);
|
|
3023
|
-
const
|
|
3024
|
-
const localPath = takeString(value, ["path"], state, path);
|
|
3025
|
-
const source = gitUrl ? {
|
|
3026
|
-
type: "git",
|
|
3027
|
-
url: gitUrl,
|
|
3028
|
-
...optional("ref", takeString(value, ["ref"], state, path))
|
|
3029
|
-
} : localPath ? { type: "path", path: localPath } : void 0;
|
|
3694
|
+
const source = takeDependencySource(value, state, path);
|
|
3030
3695
|
if (!version && !source) return [];
|
|
3031
3696
|
return [
|
|
3032
3697
|
{
|
|
@@ -3042,6 +3707,17 @@ function mapDependency(name, value, state, path) {
|
|
|
3042
3707
|
}
|
|
3043
3708
|
];
|
|
3044
3709
|
}
|
|
3710
|
+
function takeDependencySource(value, state, path) {
|
|
3711
|
+
const gitUrl = takeString(value, ["git"], state, path);
|
|
3712
|
+
if (gitUrl) {
|
|
3713
|
+
const ref = takeString(value, ["ref", "rev", "branch"], state, path);
|
|
3714
|
+
return { type: "git", url: gitUrl, ...optional("ref", ref) };
|
|
3715
|
+
}
|
|
3716
|
+
const localPath = takeString(value, ["path"], state, path);
|
|
3717
|
+
if (localPath) return { type: "path", path: localPath };
|
|
3718
|
+
const registry = takeString(value, ["registry"], state, path);
|
|
3719
|
+
return registry ? { type: "registry", registry } : void 0;
|
|
3720
|
+
}
|
|
3045
3721
|
function takeCustomSections(value, language, activeLanguages, state, basePath) {
|
|
3046
3722
|
const located = locate(value, ["customSections"], basePath);
|
|
3047
3723
|
if (!located || !Array.isArray(located.value)) return void 0;
|
|
@@ -3230,6 +3906,15 @@ var compatibilityConfigSchema = zod.z.strictObject({
|
|
|
3230
3906
|
legacyInput: legacyInputSchema.optional().describe("Original producer input retained only for migration debugging."),
|
|
3231
3907
|
unsupportedFields: zod.z.array(unsupportedFieldSchema).optional().describe("Legacy fields that could not be represented in normalized configuration.")
|
|
3232
3908
|
});
|
|
3909
|
+
|
|
3910
|
+
// src/sdk-config-ir/v1/diagnostics.ts
|
|
3911
|
+
function getSdkConfigIrV1Diagnostics(config) {
|
|
3912
|
+
if (config.target.language !== "cli") {
|
|
3913
|
+
return [];
|
|
3914
|
+
}
|
|
3915
|
+
const diagnostic = cliDistributionModeDiagnostic(config.output, ["output"]);
|
|
3916
|
+
return diagnostic ? [diagnostic] : [];
|
|
3917
|
+
}
|
|
3233
3918
|
var generationAssetSchema = zod.z.discriminatedUnion("type", [
|
|
3234
3919
|
zod.z.strictObject({
|
|
3235
3920
|
type: zod.z.literal("path").describe("Loads the generation asset from a relative path."),
|
|
@@ -3532,6 +4217,12 @@ var githubOutputSchema2 = zod.z.strictObject({
|
|
|
3532
4217
|
/** Automatically merge the GitHub publishing PR. Defaults to false. */
|
|
3533
4218
|
autoMerge: zod.z.boolean().default(false).describe("Whether the GitHub publisher automatically merges its pull request.")
|
|
3534
4219
|
});
|
|
4220
|
+
var distributionShape = {
|
|
4221
|
+
/** Valid only for `cli` targets with GitHub delivery; secret names only, never values. */
|
|
4222
|
+
distribution: cliDistributionConfigSchema.optional().describe(
|
|
4223
|
+
"CLI release channels published by the generated release workflow; credentials are GitHub Actions secret names."
|
|
4224
|
+
)
|
|
4225
|
+
};
|
|
3535
4226
|
var credentialResolutionShape = {
|
|
3536
4227
|
/** Where output credential references are resolved. */
|
|
3537
4228
|
credentialResolution: credentialResolutionSchema.default("refs-only").describe("Where output credential references are resolved.")
|
|
@@ -3540,18 +4231,21 @@ var filesOutputSchema2 = zod.z.strictObject({
|
|
|
3540
4231
|
delivery: zod.z.literal("files").describe("Writes the generated SDK to a directory."),
|
|
3541
4232
|
path: nonEmptyStringSchema.optional().describe("The destination directory for generated files."),
|
|
3542
4233
|
publish: publishConfigSchema.optional().describe("Optional package registry publication."),
|
|
4234
|
+
...distributionShape,
|
|
3543
4235
|
...credentialResolutionShape
|
|
3544
4236
|
});
|
|
3545
4237
|
var zipOutputSchema2 = zod.z.strictObject({
|
|
3546
4238
|
delivery: zod.z.literal("zip").describe("Packages the generated SDK as a ZIP archive."),
|
|
3547
4239
|
fileName: nonEmptyStringSchema.optional().describe("The generated ZIP archive file name."),
|
|
3548
4240
|
publish: publishConfigSchema.optional().describe("Optional package registry publication."),
|
|
4241
|
+
...distributionShape,
|
|
3549
4242
|
...credentialResolutionShape
|
|
3550
4243
|
});
|
|
3551
4244
|
var githubDeliverySchema2 = zod.z.strictObject({
|
|
3552
4245
|
delivery: zod.z.literal("github").describe("Delivers the generated SDK to GitHub."),
|
|
3553
4246
|
github: githubOutputSchema2.describe("GitHub repository delivery settings."),
|
|
3554
4247
|
publish: publishConfigSchema.optional().describe("Optional package registry publication."),
|
|
4248
|
+
...distributionShape,
|
|
3555
4249
|
...credentialResolutionShape
|
|
3556
4250
|
});
|
|
3557
4251
|
var outputConfigSchema = zod.z.discriminatedUnion(
|
|
@@ -3636,7 +4330,7 @@ var targetConfigSchema = zod.z.strictObject({
|
|
|
3636
4330
|
// src/sdk-config-ir/v1/sdk-config-ir-v1.ts
|
|
3637
4331
|
var SDK_CONFIG_IR_V1_SCHEMA_VERSION = "sdk-config-ir/v1";
|
|
3638
4332
|
var publishRegistryLanguages2 = {
|
|
3639
|
-
npm: ["typescript", "mcp"],
|
|
4333
|
+
npm: ["typescript", "mcp", "cli"],
|
|
3640
4334
|
pypi: ["python"],
|
|
3641
4335
|
maven: ["java", "kotlin"],
|
|
3642
4336
|
nuget: ["csharp"],
|
|
@@ -3691,6 +4385,28 @@ function validatePublishingIdentity2(packageConfig, registry, context) {
|
|
|
3691
4385
|
});
|
|
3692
4386
|
}
|
|
3693
4387
|
}
|
|
4388
|
+
function validateCliOutput(output, language, context) {
|
|
4389
|
+
if (output.distribution !== void 0 && language !== "cli") {
|
|
4390
|
+
context.addIssue({
|
|
4391
|
+
code: "custom",
|
|
4392
|
+
message: `output.distribution is supported only for target language "cli", not "${language}"`,
|
|
4393
|
+
path: ["output", "distribution"]
|
|
4394
|
+
});
|
|
4395
|
+
} else if (output.distribution !== void 0 && output.delivery !== "github") {
|
|
4396
|
+
context.addIssue({
|
|
4397
|
+
code: "custom",
|
|
4398
|
+
message: CLI_DISTRIBUTION_REQUIRES_GITHUB_DELIVERY_MESSAGE,
|
|
4399
|
+
path: ["output", "distribution"]
|
|
4400
|
+
});
|
|
4401
|
+
}
|
|
4402
|
+
if (language === "cli" && output.publish && output.delivery !== "github") {
|
|
4403
|
+
context.addIssue({
|
|
4404
|
+
code: "custom",
|
|
4405
|
+
message: CLI_PUBLISH_REQUIRES_GITHUB_DELIVERY_MESSAGE,
|
|
4406
|
+
path: ["output", "publish"]
|
|
4407
|
+
});
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
3694
4410
|
var sdkConfigIrV1Schema = zod.z.strictObject({
|
|
3695
4411
|
schemaVersion: zod.z.literal(SDK_CONFIG_IR_V1_SCHEMA_VERSION).describe("The version of the normalized SDK Config IR schema."),
|
|
3696
4412
|
source: sourceConfigSchema.describe("Materialized API descriptions consumed by generation."),
|
|
@@ -3752,6 +4468,7 @@ var sdkConfigIrV1Schema = zod.z.strictObject({
|
|
|
3752
4468
|
});
|
|
3753
4469
|
}
|
|
3754
4470
|
}
|
|
4471
|
+
validateCliOutput(output, target.language, context);
|
|
3755
4472
|
if (compatibility?.legacyInput) {
|
|
3756
4473
|
const expectedKind = target.sourceOrigin === "postman" ? "postman-build-parameters" : "fern-generator-invocation";
|
|
3757
4474
|
if (compatibility.legacyInput.kind !== expectedKind) {
|
|
@@ -3791,13 +4508,19 @@ function parseSdkConfigIrV1ForConsumption(value) {
|
|
|
3791
4508
|
return parseSdkConfigIrV1(stripUnknownProperties(value, sdkConfigIrV1InputJsonSchema));
|
|
3792
4509
|
}
|
|
3793
4510
|
|
|
4511
|
+
exports.CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE = CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE;
|
|
3794
4512
|
exports.FernConfigMappingError = FernConfigMappingError;
|
|
3795
4513
|
exports.SDK_CONFIG_IR_V1_SCHEMA_VERSION = SDK_CONFIG_IR_V1_SCHEMA_VERSION;
|
|
4514
|
+
exports.SDK_CONFIG_V1_CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE = CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE;
|
|
3796
4515
|
exports.SDK_CONFIG_V1_SCHEMA_VERSION = SDK_CONFIG_V1_SCHEMA_VERSION;
|
|
3797
4516
|
exports.apiConfigSchema = apiConfigSchema;
|
|
3798
4517
|
exports.apiImportSettingsSchema = apiImportSettingsSchema;
|
|
3799
4518
|
exports.authConfigSchema = authConfigSchema;
|
|
3800
4519
|
exports.authSchemeSchema = authSchemeSchema;
|
|
4520
|
+
exports.cliDistributionConfigSchema = cliDistributionConfigSchema;
|
|
4521
|
+
exports.cliDistributionGithubAppSchema = cliDistributionGithubAppSchema;
|
|
4522
|
+
exports.cliDistributionHomebrewSchema = cliDistributionHomebrewSchema;
|
|
4523
|
+
exports.cliDistributionScoopSchema = cliDistributionScoopSchema;
|
|
3801
4524
|
exports.cliGenerationConfigSchema = cliGenerationConfigSchema;
|
|
3802
4525
|
exports.clientConfigOverrideSchema = clientConfigOverrideSchema;
|
|
3803
4526
|
exports.clientConfigSchema = clientConfigSchema;
|
|
@@ -3809,6 +4532,9 @@ exports.dependencySchema = dependencySchema;
|
|
|
3809
4532
|
exports.docsConfigSchema = docsConfigSchema;
|
|
3810
4533
|
exports.exactSemverSchema = exactSemverSchema;
|
|
3811
4534
|
exports.generationConfigSchema = generationConfigSchema;
|
|
4535
|
+
exports.getSdkConfigIrV1Diagnostics = getSdkConfigIrV1Diagnostics;
|
|
4536
|
+
exports.getSdkConfigV1Diagnostics = getSdkConfigV1Diagnostics;
|
|
4537
|
+
exports.githubActionsSecretNameSchema = githubActionsSecretNameSchema;
|
|
3812
4538
|
exports.goGenerationConfigSchema = goGenerationConfigSchema;
|
|
3813
4539
|
exports.goModulePathSchema = goModulePathSchema;
|
|
3814
4540
|
exports.javaGenerationConfigSchema = javaGenerationConfigSchema;
|
|
@@ -3842,7 +4568,12 @@ exports.sdkConfigIrV1Schema = sdkConfigIrV1Schema;
|
|
|
3842
4568
|
exports.sdkConfigV1ApiConfigSchema = sdkConfigV1ApiConfigSchema;
|
|
3843
4569
|
exports.sdkConfigV1AuthConfigSchema = sdkConfigV1AuthConfigSchema;
|
|
3844
4570
|
exports.sdkConfigV1AuthSchemeSchema = sdkConfigV1AuthSchemeSchema;
|
|
4571
|
+
exports.sdkConfigV1CliDistributionConfigSchema = cliDistributionConfigSchema;
|
|
4572
|
+
exports.sdkConfigV1CliDistributionGithubAppSchema = cliDistributionGithubAppSchema;
|
|
4573
|
+
exports.sdkConfigV1CliDistributionHomebrewSchema = cliDistributionHomebrewSchema;
|
|
4574
|
+
exports.sdkConfigV1CliDistributionScoopSchema = cliDistributionScoopSchema;
|
|
3845
4575
|
exports.sdkConfigV1CliGenerationConfigSchema = cliGenerationConfigSchema;
|
|
4576
|
+
exports.sdkConfigV1CliOutputConfigSchema = sdkConfigV1CliOutputConfigSchema;
|
|
3846
4577
|
exports.sdkConfigV1ClientConfigOverrideSchema = sdkConfigV1ClientConfigOverrideSchema;
|
|
3847
4578
|
exports.sdkConfigV1ClientConfigSchema = sdkConfigV1ClientConfigSchema;
|
|
3848
4579
|
exports.sdkConfigV1ComposerPackageNameSchema = composerPackageNameSchema;
|
|
@@ -3852,6 +4583,7 @@ exports.sdkConfigV1DocsConfigSchema = sdkConfigV1DocsConfigSchema;
|
|
|
3852
4583
|
exports.sdkConfigV1ExactSemverSchema = exactSemverSchema;
|
|
3853
4584
|
exports.sdkConfigV1GenerationConfigOverrideSchema = sdkConfigV1GenerationConfigOverrideSchema;
|
|
3854
4585
|
exports.sdkConfigV1GenerationConfigSchema = sdkConfigV1GenerationConfigSchema;
|
|
4586
|
+
exports.sdkConfigV1GithubActionsSecretNameSchema = githubActionsSecretNameSchema;
|
|
3855
4587
|
exports.sdkConfigV1GoGenerationConfigSchema = goGenerationConfigSchema;
|
|
3856
4588
|
exports.sdkConfigV1GoModulePathSchema = goModulePathSchema;
|
|
3857
4589
|
exports.sdkConfigV1JavaGenerationConfigSchema = javaGenerationConfigSchema;
|