@postman/sdk-config 0.11.0 → 0.13.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 +18 -6
- package/dist/index.cjs +372 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +372 -24
- package/dist/index.js.map +1 -1
- package/dist/sdk-config/index.cjs +370 -23
- package/dist/sdk-config/index.cjs.map +1 -1
- package/dist/sdk-config/index.d.cts +1 -1
- package/dist/sdk-config/index.d.ts +1 -1
- package/dist/sdk-config/index.js +370 -23
- package/dist/sdk-config/index.js.map +1 -1
- package/dist/sdk-config/v1/index.cjs +370 -23
- package/dist/sdk-config/v1/index.cjs.map +1 -1
- package/dist/sdk-config/v1/index.d.cts +632 -31
- package/dist/sdk-config/v1/index.d.ts +632 -31
- package/dist/sdk-config/v1/index.js +370 -23
- package/dist/sdk-config/v1/index.js.map +1 -1
- package/dist/sdk-config-ir/index.cjs +57 -6
- package/dist/sdk-config-ir/index.cjs.map +1 -1
- package/dist/sdk-config-ir/index.d.cts +1 -1
- package/dist/sdk-config-ir/index.d.ts +1 -1
- package/dist/sdk-config-ir/index.js +57 -6
- package/dist/sdk-config-ir/index.js.map +1 -1
- package/dist/sdk-config-ir/v1/index.cjs +57 -6
- package/dist/sdk-config-ir/v1/index.cjs.map +1 -1
- package/dist/sdk-config-ir/v1/index.d.cts +211 -4
- package/dist/sdk-config-ir/v1/index.d.ts +211 -4
- package/dist/sdk-config-ir/v1/index.js +57 -6
- package/dist/sdk-config-ir/v1/index.js.map +1 -1
- package/dist/{typescript-CsAa1VSy.d.cts → typescript-BFRxjAah.d.cts} +65 -0
- package/dist/{typescript-CsAa1VSy.d.ts → typescript-BFRxjAah.d.ts} +65 -0
- package/package.json +1 -1
- package/src/sdk-config/v1/README.md +32 -11
- package/src/sdk-config-ir/v1/README.md +115 -60
|
@@ -432,6 +432,12 @@ var dependencySchema = z.strictObject({
|
|
|
432
432
|
}).refine(({ source, version }) => source !== void 0 || version !== void 0, {
|
|
433
433
|
message: "dependency must define a version or a source"
|
|
434
434
|
});
|
|
435
|
+
var bugsSchema = z.strictObject({
|
|
436
|
+
url: nonEmptyStringSchema.optional().describe("The issue tracker URL."),
|
|
437
|
+
email: nonEmptyStringSchema.optional().describe("The address for reporting issues.")
|
|
438
|
+
}).refine(({ url, email }) => url !== void 0 || email !== void 0, {
|
|
439
|
+
message: "bugs must define a url or an email"
|
|
440
|
+
});
|
|
435
441
|
var projectUrlSchema = z.strictObject({
|
|
436
442
|
label: nonEmptyStringSchema.describe("The label displayed for the project link."),
|
|
437
443
|
url: nonEmptyStringSchema.describe("The project link URL.")
|
|
@@ -446,6 +452,7 @@ var packageConfigSchema = z.strictObject({
|
|
|
446
452
|
description: z.string().optional().describe("The package description used in generated metadata."),
|
|
447
453
|
repository: nonEmptyStringSchema.optional().describe("The source repository for the generated SDK."),
|
|
448
454
|
homepage: nonEmptyStringSchema.optional().describe("The package homepage URL."),
|
|
455
|
+
bugs: bugsSchema.optional().describe("Where issues with the package are reported."),
|
|
449
456
|
documentationUrl: nonEmptyStringSchema.optional().describe("The package documentation URL."),
|
|
450
457
|
authors: z.array(authorSchema).optional().describe("Authors credited in package metadata."),
|
|
451
458
|
developers: z.array(developerSchema).optional().describe("Developers credited in package metadata."),
|
|
@@ -501,7 +508,10 @@ var cliDistributionConfigSchema = z.strictObject({
|
|
|
501
508
|
"A GitHub App used to mint short-lived tokens for every channel without its own tokenSecretName."
|
|
502
509
|
),
|
|
503
510
|
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.")
|
|
511
|
+
scoop: cliDistributionScoopSchema.optional().describe("Publishes a Scoop manifest to a bucket repository on each tagged release."),
|
|
512
|
+
githubAttestations: z.union([z.literal("auto"), z.boolean()], { error: 'must be "auto", true, or false' }).optional().describe(
|
|
513
|
+
'Whether the generated release workflow attests build provenance. "auto" (the generator default) attests only on public repositories; true always attests, for private repositories on GitHub Enterprise Cloud; false omits the attestation step and its permissions.'
|
|
514
|
+
)
|
|
505
515
|
}).superRefine((distribution, context) => {
|
|
506
516
|
if (distribution.homebrew !== void 0 || distribution.scoop !== void 0) {
|
|
507
517
|
return;
|
|
@@ -514,6 +524,9 @@ var cliDistributionConfigSchema = z.strictObject({
|
|
|
514
524
|
});
|
|
515
525
|
return;
|
|
516
526
|
}
|
|
527
|
+
if (distribution.githubAttestations !== void 0) {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
517
530
|
context.addIssue({
|
|
518
531
|
code: "custom",
|
|
519
532
|
message: "distribution must configure at least one channel: homebrew or scoop"
|
|
@@ -525,14 +538,17 @@ var CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE = "CLI_DISTRIBUTION_NON_RELEASE_MODE"
|
|
|
525
538
|
var nonReleaseGithubModes = /* @__PURE__ */ new Set(["pull-request", "push", "commit"]);
|
|
526
539
|
function cliDistributionModeDiagnostic(output, outputPath) {
|
|
527
540
|
const mode = output?.github?.mode;
|
|
528
|
-
|
|
541
|
+
const distribution = output?.distribution;
|
|
542
|
+
if (distribution === void 0 || mode === void 0 || !nonReleaseGithubModes.has(mode)) {
|
|
529
543
|
return void 0;
|
|
530
544
|
}
|
|
545
|
+
const hasChannel = distribution.homebrew !== void 0 || distribution.scoop !== void 0;
|
|
546
|
+
const consequence = hasChannel ? "Homebrew and Scoop publish only after a semantic-version tag is pushed to the repository." : "the release workflow, including its githubAttestations setting, runs only after a semantic-version tag is pushed to the repository.";
|
|
531
547
|
return {
|
|
532
548
|
code: CLI_DISTRIBUTION_NON_RELEASE_MODE_CODE,
|
|
533
549
|
severity: "warning",
|
|
534
550
|
path: [...outputPath, "github", "mode"],
|
|
535
|
-
reason: `GitHub mode "${mode}" does not create a release tag, so
|
|
551
|
+
reason: `GitHub mode "${mode}" does not create a release tag, so ${consequence}`,
|
|
536
552
|
suggestedAction: 'Use mode "release" or "commit-and-release", or push a version tag after merging generated changes.'
|
|
537
553
|
};
|
|
538
554
|
}
|
|
@@ -967,6 +983,7 @@ var DISTRIBUTION_KEYS = {
|
|
|
967
983
|
homebrew: { tap: "tap", formula: "formula", tokenEnvironmentVariable: "tokenSecretName" },
|
|
968
984
|
scoop: { bucket: "bucket", tokenEnvironmentVariable: "tokenSecretName" }
|
|
969
985
|
};
|
|
986
|
+
var DISTRIBUTION_SCALAR_KEYS = ["githubAttestations"];
|
|
970
987
|
function mapCliDistribution(config, state, basePath, targetIndex) {
|
|
971
988
|
if (!Object.hasOwn(config, "distribution")) return;
|
|
972
989
|
const raw = config.distribution;
|
|
@@ -1013,6 +1030,11 @@ function translateDistribution(distribution, path) {
|
|
|
1013
1030
|
}
|
|
1014
1031
|
value[block] = translatedBlock;
|
|
1015
1032
|
}
|
|
1033
|
+
for (const key of DISTRIBUTION_SCALAR_KEYS) {
|
|
1034
|
+
if (!Object.hasOwn(distribution, key)) continue;
|
|
1035
|
+
value[key] = distribution[key];
|
|
1036
|
+
consumedPaths.push([...path, key]);
|
|
1037
|
+
}
|
|
1016
1038
|
return { value, consumedPaths, legacyKeys };
|
|
1017
1039
|
}
|
|
1018
1040
|
function invalidDistributionDiagnostic(issue, path, legacyKeys, targetIndex) {
|
|
@@ -1152,6 +1174,7 @@ function mapOutput(generator, language, index) {
|
|
|
1152
1174
|
output.publishV2,
|
|
1153
1175
|
rawOutput,
|
|
1154
1176
|
language,
|
|
1177
|
+
"zip",
|
|
1155
1178
|
[...outputPath, "publishV2"],
|
|
1156
1179
|
state,
|
|
1157
1180
|
index
|
|
@@ -1173,6 +1196,7 @@ function mapOutput(generator, language, index) {
|
|
|
1173
1196
|
output.registryOverrides,
|
|
1174
1197
|
rawOutput,
|
|
1175
1198
|
language,
|
|
1199
|
+
"zip",
|
|
1176
1200
|
[...outputPath, "registryOverrides"],
|
|
1177
1201
|
state,
|
|
1178
1202
|
index
|
|
@@ -1200,7 +1224,14 @@ function mapOutput(generator, language, index) {
|
|
|
1200
1224
|
}
|
|
1201
1225
|
}
|
|
1202
1226
|
function sanitizeNormalizedOutput(output, rawOutput, state, index) {
|
|
1203
|
-
const publish = output.publish ? sanitizePublishConfig(
|
|
1227
|
+
const publish = output.publish ? sanitizePublishConfig(
|
|
1228
|
+
output.publish,
|
|
1229
|
+
output.publish,
|
|
1230
|
+
rawOutput,
|
|
1231
|
+
output.delivery,
|
|
1232
|
+
state,
|
|
1233
|
+
index
|
|
1234
|
+
) : void 0;
|
|
1204
1235
|
const publishShape = publish ? { publish } : {};
|
|
1205
1236
|
if (output.delivery !== "github") return { ...output, ...publishShape };
|
|
1206
1237
|
const { credentials, ...github } = output.github;
|
|
@@ -1227,12 +1258,21 @@ function githubOutput(value, publishInfo, rawOutput, language, sourcePath, state
|
|
|
1227
1258
|
);
|
|
1228
1259
|
consume(state, [...sourcePath, "owner"]);
|
|
1229
1260
|
consume(state, [...sourcePath, "repo"]);
|
|
1230
|
-
const publication = publishInfo ? mapPublication(
|
|
1261
|
+
const publication = publishInfo ? mapPublication(
|
|
1262
|
+
publishInfo,
|
|
1263
|
+
rawOutput,
|
|
1264
|
+
language,
|
|
1265
|
+
"github",
|
|
1266
|
+
[...sourcePath, "publishInfo"],
|
|
1267
|
+
state,
|
|
1268
|
+
index
|
|
1269
|
+
) : void 0;
|
|
1231
1270
|
const type = stringValue(value.type);
|
|
1232
1271
|
const licensePackage = mapGithubLicense(value.license, [...sourcePath, "license"], state);
|
|
1233
1272
|
const reviewers = mapReviewers(value.reviewers, [...sourcePath, "reviewers"], state);
|
|
1234
1273
|
if (type) consume(state, [...sourcePath, "type"]);
|
|
1235
1274
|
if (typeof value.makePr === "boolean") consume(state, [...sourcePath, "makePr"]);
|
|
1275
|
+
if (value.workflows === true) consume(state, [...sourcePath, "workflows"]);
|
|
1236
1276
|
if (stringValue(value.host)) consume(state, [...sourcePath, "host"]);
|
|
1237
1277
|
if (stringValue(value.branch)) consume(state, [...sourcePath, "branch"]);
|
|
1238
1278
|
consumeCredentialObject(value.credentials, [...sourcePath, "credentials"], state);
|
|
@@ -1319,7 +1359,7 @@ function reviewerNames(value, expectedType, sourcePath, state) {
|
|
|
1319
1359
|
});
|
|
1320
1360
|
return names.length ? names : void 0;
|
|
1321
1361
|
}
|
|
1322
|
-
function mapPublication(value, rawOutput, language, sourcePath, state, index) {
|
|
1362
|
+
function mapPublication(value, rawOutput, language, delivery, sourcePath, state, index) {
|
|
1323
1363
|
if (!isObject(value))
|
|
1324
1364
|
fail(
|
|
1325
1365
|
"FERN_PUBLICATION_INVALID",
|
|
@@ -1340,6 +1380,7 @@ function mapPublication(value, rawOutput, language, sourcePath, state, index) {
|
|
|
1340
1380
|
compact({ registry, url: registryUrl }),
|
|
1341
1381
|
nested,
|
|
1342
1382
|
rawOutput,
|
|
1383
|
+
delivery,
|
|
1343
1384
|
state,
|
|
1344
1385
|
index
|
|
1345
1386
|
);
|
|
@@ -1360,7 +1401,7 @@ function mapPublication(value, rawOutput, language, sourcePath, state, index) {
|
|
|
1360
1401
|
...packageName || Object.keys(metadata).length ? { package: { ...optional("packageName", packageName), ...metadata } } : {}
|
|
1361
1402
|
};
|
|
1362
1403
|
}
|
|
1363
|
-
function sanitizePublishConfig(publish, resolvedPublication, rawOutput, state, index) {
|
|
1404
|
+
function sanitizePublishConfig(publish, resolvedPublication, rawOutput, delivery, state, index) {
|
|
1364
1405
|
const rawPublication = rawOutput?.location === publish.registry ? rawOutput : void 0;
|
|
1365
1406
|
const rawPath = ["group", "generators", index, "output"];
|
|
1366
1407
|
if (publish.registry === "npm" || publish.registry === "crates") {
|
|
@@ -1456,6 +1497,33 @@ function sanitizePublishConfig(publish, resolvedPublication, rawOutput, state, i
|
|
|
1456
1497
|
signature
|
|
1457
1498
|
});
|
|
1458
1499
|
}
|
|
1500
|
+
if (publish.registry === "nuget" || publish.registry === "rubygems") {
|
|
1501
|
+
const apiKey = mapApiKeyExpression(
|
|
1502
|
+
publish.registry,
|
|
1503
|
+
rawPublication,
|
|
1504
|
+
resolvedPublication,
|
|
1505
|
+
rawPath,
|
|
1506
|
+
state,
|
|
1507
|
+
index,
|
|
1508
|
+
fernDefaultApiKey(publish.registry, rawOutput, delivery)
|
|
1509
|
+
);
|
|
1510
|
+
warnForUnexpectedCredentialFields(
|
|
1511
|
+
rawPublication,
|
|
1512
|
+
resolvedPublication,
|
|
1513
|
+
["apiKey"],
|
|
1514
|
+
rawPath,
|
|
1515
|
+
state,
|
|
1516
|
+
index
|
|
1517
|
+
);
|
|
1518
|
+
return compact({
|
|
1519
|
+
registry: publish.registry,
|
|
1520
|
+
url: publish.url,
|
|
1521
|
+
releaseBranch: publish.releaseBranch,
|
|
1522
|
+
tolerateRepublish: publish.tolerateRepublish,
|
|
1523
|
+
apiKey,
|
|
1524
|
+
trustedPublishing: usesTrustedPublishing(rawPublication) || void 0
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1459
1527
|
warnForUnrepresentableCredentials(rawPublication, resolvedPublication, rawPath, state, index);
|
|
1460
1528
|
return compact({
|
|
1461
1529
|
registry: publish.registry,
|
|
@@ -1464,11 +1532,19 @@ function sanitizePublishConfig(publish, resolvedPublication, rawOutput, state, i
|
|
|
1464
1532
|
tolerateRepublish: publish.tolerateRepublish
|
|
1465
1533
|
});
|
|
1466
1534
|
}
|
|
1467
|
-
function mapLegacyPublication(value, rawOutput, language, sourcePath, state, index) {
|
|
1535
|
+
function mapLegacyPublication(value, rawOutput, language, delivery, sourcePath, state, index) {
|
|
1468
1536
|
const registry = defaultRegistry(language, sourcePath, index);
|
|
1469
1537
|
const overrides = isObject(value) ? value : {};
|
|
1470
1538
|
const override = isObject(overrides[registry]) ? overrides[registry] : {};
|
|
1471
|
-
return mapPublication(
|
|
1539
|
+
return mapPublication(
|
|
1540
|
+
override,
|
|
1541
|
+
rawOutput,
|
|
1542
|
+
language,
|
|
1543
|
+
delivery,
|
|
1544
|
+
[...sourcePath, registry],
|
|
1545
|
+
state,
|
|
1546
|
+
index
|
|
1547
|
+
);
|
|
1472
1548
|
}
|
|
1473
1549
|
function mapCredentialExpression(rawPublication, resolvedPublication, field, rawPath, state, index) {
|
|
1474
1550
|
const rawValue = rawPublication?.[field];
|
|
@@ -1483,6 +1559,45 @@ function mapCredentialExpression(rawPublication, resolvedPublication, field, raw
|
|
|
1483
1559
|
}
|
|
1484
1560
|
return void 0;
|
|
1485
1561
|
}
|
|
1562
|
+
var TRUSTED_PUBLISHING_VALUES = /* @__PURE__ */ new Set(["OIDC", "<USE_OIDC>"]);
|
|
1563
|
+
function rawApiKeyValue(raw) {
|
|
1564
|
+
return raw?.apiKey ?? raw?.["api-key"];
|
|
1565
|
+
}
|
|
1566
|
+
function usesTrustedPublishing(rawPublication) {
|
|
1567
|
+
const rawValue = rawApiKeyValue(rawPublication);
|
|
1568
|
+
return typeof rawValue === "string" && TRUSTED_PUBLISHING_VALUES.has(rawValue);
|
|
1569
|
+
}
|
|
1570
|
+
function mapApiKeyExpression(registry, rawPublication, resolvedPublication, rawPath, state, index, defaultSecretName) {
|
|
1571
|
+
const rawValue = rawApiKeyValue(rawPublication);
|
|
1572
|
+
if (isEnvironmentExpression(rawValue)) return rawValue;
|
|
1573
|
+
if (usesTrustedPublishing(rawPublication)) return void 0;
|
|
1574
|
+
if (defaultSecretName !== void 0) return defaultSecretName;
|
|
1575
|
+
if (rawValue === void 0 && !hasResolvedCredential(resolvedPublication, "apiKey")) {
|
|
1576
|
+
return void 0;
|
|
1577
|
+
}
|
|
1578
|
+
addCredentialDiagnostic(
|
|
1579
|
+
state,
|
|
1580
|
+
[...rawPath, "apiKey"],
|
|
1581
|
+
["targets", index, "output", "publish", "apiKey"],
|
|
1582
|
+
apiKeyOmissionReason(registry)
|
|
1583
|
+
);
|
|
1584
|
+
return void 0;
|
|
1585
|
+
}
|
|
1586
|
+
function apiKeyOmissionReason(registry) {
|
|
1587
|
+
const label = registry === "nuget" ? "NuGet" : "RubyGems";
|
|
1588
|
+
return `Fern ${label} apiKey is not an exact environment expression naming a secret`;
|
|
1589
|
+
}
|
|
1590
|
+
var FERN_DEFAULT_NUGET_API_KEY = "${NUGET_API_TOKEN}";
|
|
1591
|
+
function fernDefaultApiKey(registry, rawOutput, delivery) {
|
|
1592
|
+
if (registry !== "nuget" || delivery !== "github" || rawOutput?.location !== "nuget") {
|
|
1593
|
+
return void 0;
|
|
1594
|
+
}
|
|
1595
|
+
const rawApiKey = rawApiKeyValue(rawOutput);
|
|
1596
|
+
if (typeof rawApiKey === "string" && TRUSTED_PUBLISHING_VALUES.has(rawApiKey)) {
|
|
1597
|
+
return void 0;
|
|
1598
|
+
}
|
|
1599
|
+
return FERN_DEFAULT_NUGET_API_KEY;
|
|
1600
|
+
}
|
|
1486
1601
|
function mapPypiCredentialExpressions(rawPublication, resolvedPublication, rawPath, state, index) {
|
|
1487
1602
|
const rawToken = rawPublication?.token;
|
|
1488
1603
|
if (isEnvironmentExpression(rawToken)) {
|
|
@@ -2186,6 +2301,29 @@ var mavenSignatureSchema = z.strictObject({
|
|
|
2186
2301
|
"The armored secret key, or an environment expression that resolves to it."
|
|
2187
2302
|
)
|
|
2188
2303
|
});
|
|
2304
|
+
function apiKeySecretSchema(registry, example) {
|
|
2305
|
+
return nonEmptyStringSchema.regex(
|
|
2306
|
+
/^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/,
|
|
2307
|
+
`${registry} apiKey must be an environment expression naming a secret, such as ${example}`
|
|
2308
|
+
);
|
|
2309
|
+
}
|
|
2310
|
+
function apiKeySecretDescription(registry, example) {
|
|
2311
|
+
return `An environment expression naming the repository secret that the generated release workflow reads the ${registry} API key from, such as ${example}. This is a secret name, never the key itself.`;
|
|
2312
|
+
}
|
|
2313
|
+
function trustedPublishingSchema(registry) {
|
|
2314
|
+
return z.boolean().optional().describe(
|
|
2315
|
+
`Whether ${registry} publication uses trusted publishing (OIDC) instead of an API key secret.`
|
|
2316
|
+
);
|
|
2317
|
+
}
|
|
2318
|
+
function refineApiKeyAgainstTrustedPublishing(publish, context) {
|
|
2319
|
+
if (publish.trustedPublishing === true && publish.apiKey !== void 0) {
|
|
2320
|
+
context.addIssue({
|
|
2321
|
+
code: "custom",
|
|
2322
|
+
message: "apiKey must be omitted when trustedPublishing is true",
|
|
2323
|
+
path: ["apiKey"]
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2189
2327
|
var commonPublishShape = {
|
|
2190
2328
|
url: nonEmptyStringSchema.optional().describe("A custom package registry URL."),
|
|
2191
2329
|
releaseBranch: nonEmptyStringSchema.optional().describe("The branch used by generated package release workflows."),
|
|
@@ -2221,12 +2359,16 @@ var sdkConfigV1PublishConfigSchema = z.discriminatedUnion("registry", [
|
|
|
2221
2359
|
}),
|
|
2222
2360
|
z.strictObject({
|
|
2223
2361
|
registry: z.literal("nuget").describe("Publishes the package to a NuGet-compatible registry."),
|
|
2362
|
+
apiKey: apiKeySecretSchema("NuGet", "${NUGET_API_KEY}").optional().describe(apiKeySecretDescription("NuGet", "${NUGET_API_KEY}")),
|
|
2363
|
+
trustedPublishing: trustedPublishingSchema("NuGet"),
|
|
2224
2364
|
...commonPublishShape
|
|
2225
|
-
}),
|
|
2365
|
+
}).superRefine(refineApiKeyAgainstTrustedPublishing),
|
|
2226
2366
|
z.strictObject({
|
|
2227
2367
|
registry: z.literal("rubygems").describe("Publishes the package to a RubyGems-compatible registry."),
|
|
2368
|
+
apiKey: apiKeySecretSchema("RubyGems", "${RUBYGEMS_API_KEY}").optional().describe(apiKeySecretDescription("RubyGems", "${RUBYGEMS_API_KEY}")),
|
|
2369
|
+
trustedPublishing: trustedPublishingSchema("RubyGems"),
|
|
2228
2370
|
...commonPublishShape
|
|
2229
|
-
}),
|
|
2371
|
+
}).superRefine(refineApiKeyAgainstTrustedPublishing),
|
|
2230
2372
|
z.strictObject({
|
|
2231
2373
|
registry: z.literal("crates").describe("Publishes the crate to a Cargo-compatible registry."),
|
|
2232
2374
|
token: nonEmptyStringSchema.optional().describe("The Cargo registry token, or an environment expression that resolves to it."),
|
|
@@ -2284,7 +2426,7 @@ var sdkConfigV1OutputConfigSchema = z.discriminatedUnion(
|
|
|
2284
2426
|
);
|
|
2285
2427
|
var cliDistributionShape = {
|
|
2286
2428
|
distribution: cliDistributionConfigSchema.optional().describe(
|
|
2287
|
-
"CLI release channels
|
|
2429
|
+
"CLI release channels and build attestation settings for the generated release workflow; credentials are GitHub Actions secret names."
|
|
2288
2430
|
)
|
|
2289
2431
|
};
|
|
2290
2432
|
function rejectDistributionWithoutGithub(output, context) {
|
|
@@ -2330,6 +2472,9 @@ var apiImportSettingsSchema = z.strictObject({
|
|
|
2330
2472
|
discriminatedUnionV2: z.boolean().optional().describe("Whether oneOf and anyOf schemas use the newer discriminator inference rules."),
|
|
2331
2473
|
undiscriminatedUnionsWithLiterals: z.boolean().optional().describe("Whether literal-bearing unions remain undiscriminated during import."),
|
|
2332
2474
|
inlineAllOfSchemas: z.boolean().optional().describe("Whether schemas composed with allOf are inlined when possible."),
|
|
2475
|
+
inferDiscriminatedUnionBaseProperties: z.boolean().optional().describe(
|
|
2476
|
+
"Whether properties every discriminated-union variant shares are lifted onto the union."
|
|
2477
|
+
),
|
|
2333
2478
|
resolveSchemaCollisions: z.boolean().optional().describe("Whether colliding imported schema names are resolved automatically."),
|
|
2334
2479
|
asyncApiMessageNaming: z.enum(["v1", "v2"]).optional().describe("The naming strategy used for messages imported from AsyncAPI."),
|
|
2335
2480
|
defaultIntegerFormat: z.enum(["int32", "int64", "uint32", "uint64"]).optional().describe("The integer format used when a schema does not declare one.")
|
|
@@ -2428,7 +2573,7 @@ var packageScriptSchema = z.strictObject({
|
|
|
2428
2573
|
command: nonEmptyStringSchema.describe("The command executed by the package script.")
|
|
2429
2574
|
});
|
|
2430
2575
|
var httpClientSchema = z.strictObject({
|
|
2431
|
-
name: z.enum(["axios", "fetch"]).describe("The HTTP client used by generated TypeScript code.")
|
|
2576
|
+
name: z.enum(["axios", "fetch", "node-fetch"]).describe("The HTTP client used by generated TypeScript code.")
|
|
2432
2577
|
});
|
|
2433
2578
|
var typescriptGenerationConfigSchema = z.strictObject({
|
|
2434
2579
|
typescriptVersion: nonEmptyStringSchema.optional().describe("The TypeScript version used by the generated project."),
|
|
@@ -2444,6 +2589,37 @@ var typescriptGenerationConfigSchema = z.strictObject({
|
|
|
2444
2589
|
/** Name of the top-level namespace export emitted by Fern-compatible TypeScript SDKs. */
|
|
2445
2590
|
namespaceExportName: nonEmptyStringSchema.optional().describe("The top-level namespace export name."),
|
|
2446
2591
|
consolidateTypeFiles: z.boolean().optional().describe("Whether generated types are consolidated into fewer source files."),
|
|
2592
|
+
formDataSupport: z.enum(["Node16", "Node18"]).optional().describe(
|
|
2593
|
+
"The multipart form-data implementation: Node16 uses the form-data packages, Node18 uses the platform FormData."
|
|
2594
|
+
),
|
|
2595
|
+
allowExtraFields: z.boolean().optional().describe(
|
|
2596
|
+
"Whether response parsing keeps unrecognized object keys and accepts unrecognized union members and enum values."
|
|
2597
|
+
),
|
|
2598
|
+
generateSubpackageExports: z.boolean().optional().describe(
|
|
2599
|
+
"Whether the package manifest exports each subpackage client as its own entry point."
|
|
2600
|
+
),
|
|
2601
|
+
exportAllRequestsAtRoot: z.boolean().optional().describe("Whether every request type is also exported from the package root."),
|
|
2602
|
+
generateEndpointMetadata: z.boolean().optional().describe("Whether generated clients expose metadata for each endpoint."),
|
|
2603
|
+
outputEsm: z.boolean().optional().describe(
|
|
2604
|
+
"Whether the package is marked as an ES module while still shipping its CommonJS build."
|
|
2605
|
+
),
|
|
2606
|
+
neverThrowErrors: z.boolean().optional().describe(
|
|
2607
|
+
"Whether client methods return a wrapped response instead of throwing on a non-2xx status."
|
|
2608
|
+
),
|
|
2609
|
+
includeOtherInUnionTypes: z.boolean().optional().describe("Whether union types gain a member for variants the SDK does not recognize."),
|
|
2610
|
+
includeUtilsOnUnionMembers: z.boolean().optional().describe("Whether helper utilities are generated on each member of a union type."),
|
|
2611
|
+
omitFernHeaders: z.boolean().optional().describe("Whether requests omit the SDK identification headers and the User-Agent header."),
|
|
2612
|
+
linter: z.enum(["biome", "oxlint", "none"]).optional().describe("The linter configured in the generated project."),
|
|
2613
|
+
formatter: z.enum(["prettier", "biome", "oxfmt", "none"]).optional().describe("The formatter configured in the generated project."),
|
|
2614
|
+
exports: jsonObjectSchema.optional().describe(
|
|
2615
|
+
"package.json exports entries, keyed by subpath, applied over the generated exports. Each subpath replaces the generated one."
|
|
2616
|
+
),
|
|
2617
|
+
files: z.array(nonEmptyStringSchema).optional().describe("package.json files entries, listed ahead of the generated ones."),
|
|
2618
|
+
engines: z.record(nonEmptyStringSchema, nonEmptyStringSchema).optional().describe("package.json engines version ranges, keyed by engine name such as node."),
|
|
2619
|
+
lintStaged: z.record(nonEmptyStringSchema, z.array(nonEmptyStringSchema).min(1)).optional().describe("lint-staged commands to run, keyed by file glob."),
|
|
2620
|
+
browser: z.record(nonEmptyStringSchema, z.union([z.boolean(), nonEmptyStringSchema])).optional().describe(
|
|
2621
|
+
"package.json browser field: a module or file is excluded (false) or replaced by another path."
|
|
2622
|
+
),
|
|
2447
2623
|
allowCustomFetcher: z.boolean().optional().describe("Whether callers can supply a custom fetch implementation."),
|
|
2448
2624
|
useBrandedStringAliases: z.boolean().optional().describe("Whether string aliases are emitted as distinct branded types."),
|
|
2449
2625
|
useLegacyExports: z.boolean().optional().describe("Whether the package emits the legacy export layout."),
|
|
@@ -2517,7 +2693,7 @@ var pythonGenerationConfigSchema = z.strictObject({
|
|
|
2517
2693
|
additionalInitExports: z.array(additionalInitExportSchema).optional().describe("Additional names re-exported from the package initializer.")
|
|
2518
2694
|
});
|
|
2519
2695
|
var rubyGenerationConfigSchema = z.strictObject({
|
|
2520
|
-
requirePaths: z.array(nonEmptyStringSchema).optional().describe("
|
|
2696
|
+
requirePaths: z.array(nonEmptyStringSchema).optional().describe("Files the generated entry file loads with `require`.")
|
|
2521
2697
|
});
|
|
2522
2698
|
var rustGenerationConfigSchema = z.strictObject({
|
|
2523
2699
|
/**
|
|
@@ -2859,16 +3035,21 @@ function mapFernConfigToSdkConfigV1(input) {
|
|
|
2859
3035
|
...optional("client", clients.targetOverrides[index]),
|
|
2860
3036
|
...optional("docs", docs.targetOverrides[index])
|
|
2861
3037
|
};
|
|
2862
|
-
const
|
|
3038
|
+
const mappedPackage = { ...invocation.package, ...outputPackage, ...generator.package };
|
|
2863
3039
|
invocation.unsupportedFields.push(
|
|
2864
3040
|
...resolveTargetPackage(
|
|
2865
|
-
|
|
3041
|
+
mappedPackage,
|
|
2866
3042
|
invocation.packageFallbacks,
|
|
2867
3043
|
generator,
|
|
2868
3044
|
output.delivery,
|
|
2869
3045
|
index
|
|
2870
3046
|
)
|
|
2871
3047
|
);
|
|
3048
|
+
const targetPackage = withRustCratesPublishDefaults(mappedPackage, {
|
|
3049
|
+
language,
|
|
3050
|
+
output,
|
|
3051
|
+
generator
|
|
3052
|
+
});
|
|
2872
3053
|
if (Object.keys(targetPackage).length > 0 || outputPackage || generator.package) {
|
|
2873
3054
|
target.package = targetPackage;
|
|
2874
3055
|
}
|
|
@@ -2937,6 +3118,21 @@ function mapFernConfigToSdkConfigV1(input) {
|
|
|
2937
3118
|
])
|
|
2938
3119
|
};
|
|
2939
3120
|
}
|
|
3121
|
+
function withRustCratesPublishDefaults(packageConfig, { language, output, generator }) {
|
|
3122
|
+
if (language !== "rust" || !("publish" in output) || output.publish?.registry !== "crates") {
|
|
3123
|
+
return packageConfig;
|
|
3124
|
+
}
|
|
3125
|
+
const { packageName } = packageConfig;
|
|
3126
|
+
return {
|
|
3127
|
+
...packageName ? { description: `Rust SDK for ${packageName} generated by Fern` } : {},
|
|
3128
|
+
...usesCustomLicenseFile(generator) ? {} : { license: { type: "MIT" } },
|
|
3129
|
+
...packageConfig
|
|
3130
|
+
};
|
|
3131
|
+
}
|
|
3132
|
+
function usesCustomLicenseFile({ config, raw }) {
|
|
3133
|
+
const metadata = isObject(raw) && isObject(raw.metadata) ? raw.metadata : void 0;
|
|
3134
|
+
return isObject(config) && typeof config.packageLicenseFile === "string" || isObject(metadata?.license);
|
|
3135
|
+
}
|
|
2940
3136
|
function resolveLanguage(generator, index) {
|
|
2941
3137
|
const language = generator.sdkLanguage ?? generatorLanguages[generator.name];
|
|
2942
3138
|
if (!language || !isFernLanguage(language)) {
|
|
@@ -3075,6 +3271,13 @@ function mapInvocation(generator, language, activeLanguages, index) {
|
|
|
3075
3271
|
}
|
|
3076
3272
|
}
|
|
3077
3273
|
const docs = mapReadme(generator.readme, language, activeLanguages, state, [...prefix, "readme"]);
|
|
3274
|
+
if (language === "typescript") {
|
|
3275
|
+
const includeApiReference = takeBoolean(config, ["includeApiReference"], state, [
|
|
3276
|
+
...prefix,
|
|
3277
|
+
"config"
|
|
3278
|
+
]);
|
|
3279
|
+
if (includeApiReference !== void 0) docs.includeApiReference = includeApiReference;
|
|
3280
|
+
}
|
|
3078
3281
|
const unsupportedFields = [
|
|
3079
3282
|
...state.valueDiagnostics ?? [],
|
|
3080
3283
|
...collectUnsupported(config, [...prefix, "config"], state),
|
|
@@ -3221,7 +3424,12 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
|
|
|
3221
3424
|
}
|
|
3222
3425
|
const pythonClient = language === "python" ? takeObject(config, ["client"], state, basePath) : void 0;
|
|
3223
3426
|
const typescriptNaming = language === "typescript" || language === "mcp" ? takeObject(config, ["naming"], state, basePath) : void 0;
|
|
3224
|
-
const directClientName = takeString(
|
|
3427
|
+
const directClientName = takeString(
|
|
3428
|
+
config,
|
|
3429
|
+
language === "ruby" ? ["clientName"] : ["clientName", "clientClassName"],
|
|
3430
|
+
state,
|
|
3431
|
+
basePath
|
|
3432
|
+
);
|
|
3225
3433
|
const nestedClientName = pythonClient ? takeString(pythonClient.value, ["className"], state, pythonClient.path) : typescriptNaming ? takeString(typescriptNaming.value, ["client"], state, typescriptNaming.path) : language === "ruby" ? (
|
|
3226
3434
|
// Fern's Ruby generator renames the root client class (`Auth0::Management`) with it.
|
|
3227
3435
|
takeString(config, ["clientModuleName"], state, basePath)
|
|
@@ -3255,7 +3463,13 @@ function mapCommonConfig(language, config, state, client, generation, packageCon
|
|
|
3255
3463
|
});
|
|
3256
3464
|
if (Object.keys(naming).length) generation.naming = naming;
|
|
3257
3465
|
const wireTests = takeBoolean(config, ["enableWireTests", "generateWireTests"], state, basePath);
|
|
3258
|
-
|
|
3466
|
+
const wireTestsFallback = language === "typescript" ? takeBoolean(config, ["wireTestsFallbackToAutoGeneratedErrorExamples"], state, basePath) : void 0;
|
|
3467
|
+
if (wireTests !== void 0 || wireTestsFallback !== void 0) {
|
|
3468
|
+
generation.wireTests = { enabled: wireTests ?? true };
|
|
3469
|
+
if (wireTestsFallback !== void 0) {
|
|
3470
|
+
generation.wireTests.fallbackToGeneratedErrorExamples = wireTestsFallback;
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3259
3473
|
const webSockets = takeBoolean(
|
|
3260
3474
|
config,
|
|
3261
3475
|
["generateWebSocketClients", "shouldGenerateWebsocketClients", "enableWebsockets"],
|
|
@@ -3298,10 +3512,10 @@ function mapTypescriptStreams(config, state, basePath) {
|
|
|
3298
3512
|
function mapLanguageConfig(language, config, state, packageConfig, basePath, targetIndex) {
|
|
3299
3513
|
switch (language) {
|
|
3300
3514
|
case "typescript":
|
|
3301
|
-
return mapTypescript(config, state, packageConfig, basePath);
|
|
3515
|
+
return mapTypescript(config, state, packageConfig, basePath, true);
|
|
3302
3516
|
case "mcp":
|
|
3303
3517
|
return {
|
|
3304
|
-
...mapTypescript(config, state, packageConfig, basePath),
|
|
3518
|
+
...mapTypescript(config, state, packageConfig, basePath, false),
|
|
3305
3519
|
...mapMcp(config, state, basePath)
|
|
3306
3520
|
};
|
|
3307
3521
|
case "python":
|
|
@@ -3327,7 +3541,7 @@ function mapLanguageConfig(language, config, state, packageConfig, basePath, tar
|
|
|
3327
3541
|
return mapTerraform(config, state, packageConfig, basePath);
|
|
3328
3542
|
}
|
|
3329
3543
|
}
|
|
3330
|
-
function mapTypescript(config, state, packageConfig, basePath) {
|
|
3544
|
+
function mapTypescript(config, state, packageConfig, basePath, sdkTarget) {
|
|
3331
3545
|
const packageJsonManifest = mapPackageManifest(
|
|
3332
3546
|
config,
|
|
3333
3547
|
["packageJson"],
|
|
@@ -3340,18 +3554,74 @@ function mapTypescript(config, state, packageConfig, basePath) {
|
|
|
3340
3554
|
const packageManagerVersionPart = packageManagerAtIndex >= 0 ? packageJsonPackageManager?.slice(packageManagerAtIndex + 1).split("+")[0] : void 0;
|
|
3341
3555
|
const packageManagerVersion = packageManagerVersionPart || void 0;
|
|
3342
3556
|
if (packageJsonManifest) liftPackageJsonDependencies(packageJsonManifest, state, packageConfig);
|
|
3557
|
+
const manifestOptions = sdkTarget && packageJsonManifest ? mapPackageManifestOptions(packageJsonManifest, state, packageConfig) : {};
|
|
3343
3558
|
const serdeLayer = takeBoolean(config, ["serdeLayer"], state, basePath);
|
|
3344
3559
|
const noSerdeLayer = takeBoolean(config, ["noSerdeLayer"], state, basePath);
|
|
3345
|
-
const fetchSupport = takeEnum(
|
|
3560
|
+
const fetchSupport = takeEnum(
|
|
3561
|
+
config,
|
|
3562
|
+
["fetchSupport"],
|
|
3563
|
+
sdkTarget ? ["native", "node-fetch"] : ["native"],
|
|
3564
|
+
state,
|
|
3565
|
+
basePath
|
|
3566
|
+
);
|
|
3346
3567
|
const namingObject = takeObject(config, ["naming"], state, basePath);
|
|
3347
3568
|
const nestedNamespace = namingObject ? takeString(namingObject.value, ["namespace"], state, namingObject.path) : void 0;
|
|
3569
|
+
const sdkOnlyOptions = sdkTarget ? {
|
|
3570
|
+
formDataSupport: takeEnum(
|
|
3571
|
+
config,
|
|
3572
|
+
["formDataSupport"],
|
|
3573
|
+
["Node16", "Node18"],
|
|
3574
|
+
state,
|
|
3575
|
+
basePath
|
|
3576
|
+
),
|
|
3577
|
+
allowExtraFields: takeBoolean(config, ["allowExtraFields"], state, basePath),
|
|
3578
|
+
generateSubpackageExports: takeBoolean(
|
|
3579
|
+
config,
|
|
3580
|
+
["generateSubpackageExports"],
|
|
3581
|
+
state,
|
|
3582
|
+
basePath
|
|
3583
|
+
),
|
|
3584
|
+
exportAllRequestsAtRoot: takeBoolean(config, ["exportAllRequestsAtRoot"], state, basePath),
|
|
3585
|
+
generateEndpointMetadata: takeBoolean(
|
|
3586
|
+
config,
|
|
3587
|
+
["generateEndpointMetadata"],
|
|
3588
|
+
state,
|
|
3589
|
+
basePath
|
|
3590
|
+
),
|
|
3591
|
+
outputEsm: takeBoolean(config, ["outputEsm"], state, basePath),
|
|
3592
|
+
neverThrowErrors: takeBoolean(config, ["neverThrowErrors"], state, basePath),
|
|
3593
|
+
includeOtherInUnionTypes: takeBoolean(
|
|
3594
|
+
config,
|
|
3595
|
+
["includeOtherInUnionTypes"],
|
|
3596
|
+
state,
|
|
3597
|
+
basePath
|
|
3598
|
+
),
|
|
3599
|
+
includeUtilsOnUnionMembers: takeBoolean(
|
|
3600
|
+
config,
|
|
3601
|
+
["includeUtilsOnUnionMembers"],
|
|
3602
|
+
state,
|
|
3603
|
+
basePath
|
|
3604
|
+
),
|
|
3605
|
+
omitFernHeaders: takeBoolean(config, ["omitFernHeaders"], state, basePath),
|
|
3606
|
+
linter: takeEnum(config, ["linter"], ["biome", "oxlint", "none"], state, basePath),
|
|
3607
|
+
formatter: takeEnum(
|
|
3608
|
+
config,
|
|
3609
|
+
["formatter"],
|
|
3610
|
+
["prettier", "biome", "oxfmt", "none"],
|
|
3611
|
+
state,
|
|
3612
|
+
basePath
|
|
3613
|
+
)
|
|
3614
|
+
} : {};
|
|
3348
3615
|
return compact({
|
|
3616
|
+
...sdkOnlyOptions,
|
|
3617
|
+
// Only the manifest writes these keys; nothing in sdkOnlyOptions or below shares a name.
|
|
3618
|
+
...manifestOptions,
|
|
3349
3619
|
typescriptVersion: takeString(config, ["typescriptVersion"], state, basePath),
|
|
3350
3620
|
zodVersion: takeString(config, ["zodVersion"], state, basePath),
|
|
3351
3621
|
packageManager: takeEnum(config, ["packageManager"], ["pnpm", "yarn"], state, basePath),
|
|
3352
3622
|
packageManagerVersion,
|
|
3353
3623
|
testFramework: takeEnum(config, ["testFramework"], ["jest", "vitest"], state, basePath),
|
|
3354
|
-
httpClient: fetchSupport ===
|
|
3624
|
+
httpClient: fetchSupport === void 0 ? void 0 : { name: fetchSupport === "native" ? "fetch" : "node-fetch" },
|
|
3355
3625
|
bundle: takeBoolean(config, ["bundle"], state, basePath),
|
|
3356
3626
|
exportClassDefault: takeBoolean(config, ["exportClassDefault"], state, basePath),
|
|
3357
3627
|
namespaceExportName: takeString(config, ["namespaceExportName", "namespaceExport"], state, basePath) ?? nestedNamespace,
|
|
@@ -3748,6 +4018,83 @@ function mapPackageManifest(config, aliases, state, packageConfig, basePath) {
|
|
|
3748
4018
|
);
|
|
3749
4019
|
return manifest;
|
|
3750
4020
|
}
|
|
4021
|
+
function mapPackageManifestOptions(manifest, state, packageConfig) {
|
|
4022
|
+
const bugs = takeManifestBugs(manifest, state);
|
|
4023
|
+
if (bugs) packageConfig.bugs = bugs;
|
|
4024
|
+
const repository = takeManifestRepository(manifest, state);
|
|
4025
|
+
if (repository !== void 0 && packageConfig.repository === void 0) {
|
|
4026
|
+
packageConfig.repository = repository;
|
|
4027
|
+
}
|
|
4028
|
+
const exports = takeObject(manifest.value, ["exports"], state, manifest.path);
|
|
4029
|
+
if (exports) consume(state, exports.path);
|
|
4030
|
+
return compact({
|
|
4031
|
+
exports: exports?.value,
|
|
4032
|
+
scripts: takeManifestScripts(manifest, state),
|
|
4033
|
+
files: takeStringArray(manifest.value, ["files"], state, manifest.path),
|
|
4034
|
+
engines: takeManifestStringRecord(manifest, "engines", state),
|
|
4035
|
+
lintStaged: takeManifestLintStaged(manifest, state),
|
|
4036
|
+
browser: takeManifestBrowser(manifest, state)
|
|
4037
|
+
});
|
|
4038
|
+
}
|
|
4039
|
+
function takeManifestBugs(manifest, state) {
|
|
4040
|
+
const text = takeString(manifest.value, ["bugs"], state, manifest.path);
|
|
4041
|
+
if (text !== void 0) return { url: text };
|
|
4042
|
+
const located = takeObject(manifest.value, ["bugs"], state, manifest.path);
|
|
4043
|
+
if (!located) return void 0;
|
|
4044
|
+
const url = takeString(located.value, ["url"], state, located.path);
|
|
4045
|
+
const email = takeString(located.value, ["email"], state, located.path);
|
|
4046
|
+
return url === void 0 && email === void 0 ? void 0 : compact({ url, email });
|
|
4047
|
+
}
|
|
4048
|
+
function takeManifestRepository(manifest, state) {
|
|
4049
|
+
const text = takeString(manifest.value, ["repository"], state, manifest.path);
|
|
4050
|
+
if (text !== void 0) return text;
|
|
4051
|
+
const located = takeObject(manifest.value, ["repository"], state, manifest.path);
|
|
4052
|
+
if (!located) return void 0;
|
|
4053
|
+
const url = takeString(located.value, ["url"], state, located.path);
|
|
4054
|
+
if (url !== void 0) void takeEnum(located.value, ["type"], ["git"], state, located.path);
|
|
4055
|
+
return url;
|
|
4056
|
+
}
|
|
4057
|
+
function takeManifestScripts(manifest, state) {
|
|
4058
|
+
const located = takeObject(manifest.value, ["scripts"], state, manifest.path);
|
|
4059
|
+
if (!located) return void 0;
|
|
4060
|
+
const scripts = Object.entries(located.value).flatMap(([name, command]) => {
|
|
4061
|
+
if (typeof command !== "string" || !command) return [];
|
|
4062
|
+
consume(state, [...located.path, name]);
|
|
4063
|
+
return [{ name, command }];
|
|
4064
|
+
});
|
|
4065
|
+
return scripts.length ? scripts : void 0;
|
|
4066
|
+
}
|
|
4067
|
+
function takeManifestStringRecord(manifest, key, state) {
|
|
4068
|
+
const located = takeObject(manifest.value, [key], state, manifest.path);
|
|
4069
|
+
if (!located) return void 0;
|
|
4070
|
+
const entries = Object.entries(located.value).flatMap(([name, value]) => {
|
|
4071
|
+
if (typeof value !== "string" || !value) return [];
|
|
4072
|
+
consume(state, [...located.path, name]);
|
|
4073
|
+
return [[name, value]];
|
|
4074
|
+
});
|
|
4075
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
4076
|
+
}
|
|
4077
|
+
function takeManifestLintStaged(manifest, state) {
|
|
4078
|
+
const located = takeObject(manifest.value, ["lint-staged"], state, manifest.path);
|
|
4079
|
+
if (!located) return void 0;
|
|
4080
|
+
const entries = Object.entries(located.value).flatMap(([glob, commands]) => {
|
|
4081
|
+
const list = typeof commands === "string" ? [commands] : stringArrayValue(commands);
|
|
4082
|
+
if (!list?.length || list.some((command) => !command)) return [];
|
|
4083
|
+
consume(state, [...located.path, glob]);
|
|
4084
|
+
return [[glob, list]];
|
|
4085
|
+
});
|
|
4086
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
4087
|
+
}
|
|
4088
|
+
function takeManifestBrowser(manifest, state) {
|
|
4089
|
+
const located = takeObject(manifest.value, ["browser"], state, manifest.path);
|
|
4090
|
+
if (!located) return void 0;
|
|
4091
|
+
const entries = Object.entries(located.value).flatMap(([name, value]) => {
|
|
4092
|
+
if (typeof value !== "boolean" && (typeof value !== "string" || !value)) return [];
|
|
4093
|
+
consume(state, [...located.path, name]);
|
|
4094
|
+
return [[name, value]];
|
|
4095
|
+
});
|
|
4096
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
4097
|
+
}
|
|
3751
4098
|
function takeManifestAuthors(manifest, state) {
|
|
3752
4099
|
const located = locate(manifest.value, ["authors"], manifest.path);
|
|
3753
4100
|
if (!located || !Array.isArray(located.value)) return [];
|