@fern-api/generator-cli 0.9.34 → 0.9.36
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/dist/api.js +1 -1
- package/dist/cli.js +84 -17
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -8179,7 +8179,7 @@ function expandFernignorePatterns(fernignoreContent, candidatePaths) {
|
|
|
8179
8179
|
}
|
|
8180
8180
|
function matches(candidate, pattern) {
|
|
8181
8181
|
const normalized = pattern.endsWith("/") ? pattern.slice(0, -1) : pattern;
|
|
8182
|
-
if (minimatch(candidate, normalized, { dot: true })) {
|
|
8182
|
+
if (minimatch(candidate, normalized, { dot: true, nonegate: true })) {
|
|
8183
8183
|
return true;
|
|
8184
8184
|
}
|
|
8185
8185
|
return candidate === normalized || candidate.startsWith(normalized + "/");
|
package/dist/cli.js
CHANGED
|
@@ -3822,9 +3822,9 @@ var init_esm3 = __esm({
|
|
|
3822
3822
|
}
|
|
3823
3823
|
});
|
|
3824
3824
|
|
|
3825
|
-
// ../../node_modules/.pnpm/tmp@0.2.
|
|
3825
|
+
// ../../node_modules/.pnpm/tmp@0.2.6/node_modules/tmp/lib/tmp.js
|
|
3826
3826
|
var require_tmp = __commonJS({
|
|
3827
|
-
"../../node_modules/.pnpm/tmp@0.2.
|
|
3827
|
+
"../../node_modules/.pnpm/tmp@0.2.6/node_modules/tmp/lib/tmp.js"(exports2, module2) {
|
|
3828
3828
|
"use strict";
|
|
3829
3829
|
var fs3 = require("fs");
|
|
3830
3830
|
var os = require("os");
|
|
@@ -4075,13 +4075,20 @@ var require_tmp = __commonJS({
|
|
|
4075
4075
|
].join("");
|
|
4076
4076
|
return path5.join(tmpDir, opts.dir, name);
|
|
4077
4077
|
}
|
|
4078
|
+
function _assertPath(path6) {
|
|
4079
|
+
if (path6.includes("..")) {
|
|
4080
|
+
throw new Error("Relative value not allowed");
|
|
4081
|
+
}
|
|
4082
|
+
return path6;
|
|
4083
|
+
}
|
|
4078
4084
|
function _assertOptionsBase(options) {
|
|
4079
4085
|
if (!_isUndefined(options.name)) {
|
|
4080
4086
|
const name = options.name;
|
|
4081
4087
|
if (path5.isAbsolute(name)) throw new Error(`name option must not contain an absolute path, found "${name}".`);
|
|
4082
4088
|
const basename2 = path5.basename(name);
|
|
4083
|
-
if (basename2 === ".." || basename2 === "." || basename2 !== name)
|
|
4089
|
+
if (basename2 === ".." || basename2 === "." || basename2 !== name) {
|
|
4084
4090
|
throw new Error(`name option must not contain a path, found "${name}".`);
|
|
4091
|
+
}
|
|
4085
4092
|
}
|
|
4086
4093
|
if (!_isUndefined(options.template) && !options.template.match(TEMPLATE_PATTERN)) {
|
|
4087
4094
|
throw new Error(`Invalid template, found "${options.template}".`);
|
|
@@ -4094,15 +4101,16 @@ var require_tmp = __commonJS({
|
|
|
4094
4101
|
options.detachDescriptor = !!options.detachDescriptor;
|
|
4095
4102
|
options.discardDescriptor = !!options.discardDescriptor;
|
|
4096
4103
|
options.unsafeCleanup = !!options.unsafeCleanup;
|
|
4097
|
-
options.prefix = _isUndefined(options.prefix) ? "" : options.prefix;
|
|
4098
|
-
options.postfix = _isUndefined(options.postfix) ? "" : options.postfix;
|
|
4104
|
+
options.prefix = _isUndefined(options.prefix) ? "" : _assertPath(options.prefix);
|
|
4105
|
+
options.postfix = _isUndefined(options.postfix) ? "" : _assertPath(options.postfix);
|
|
4106
|
+
options.template = _isUndefined(options.template) ? void 0 : _assertPath(options.template);
|
|
4099
4107
|
}
|
|
4100
4108
|
function _getRelativePath(option, name, tmpDir, cb) {
|
|
4101
4109
|
if (_isUndefined(name)) return cb(null);
|
|
4102
4110
|
_resolvePath(name, tmpDir, function(err, resolvedPath) {
|
|
4103
4111
|
if (err) return cb(err);
|
|
4104
4112
|
const relativePath = path5.relative(tmpDir, resolvedPath);
|
|
4105
|
-
if (
|
|
4113
|
+
if (relativePath.startsWith("..") || path5.isAbsolute(relativePath)) {
|
|
4106
4114
|
return cb(new Error(`${option} option must be relative to "${tmpDir}", found "${relativePath}".`));
|
|
4107
4115
|
}
|
|
4108
4116
|
cb(null, relativePath);
|
|
@@ -4112,7 +4120,7 @@ var require_tmp = __commonJS({
|
|
|
4112
4120
|
if (_isUndefined(name)) return;
|
|
4113
4121
|
const resolvedPath = _resolvePathSync(name, tmpDir);
|
|
4114
4122
|
const relativePath = path5.relative(tmpDir, resolvedPath);
|
|
4115
|
-
if (
|
|
4123
|
+
if (relativePath.startsWith("..") || path5.isAbsolute(relativePath)) {
|
|
4116
4124
|
throw new Error(`${option} option must be relative to "${tmpDir}", found "${relativePath}".`);
|
|
4117
4125
|
}
|
|
4118
4126
|
return relativePath;
|
|
@@ -32026,7 +32034,7 @@ function expandFernignorePatterns(fernignoreContent, candidatePaths) {
|
|
|
32026
32034
|
}
|
|
32027
32035
|
function matches(candidate, pattern) {
|
|
32028
32036
|
const normalized = pattern.endsWith("/") ? pattern.slice(0, -1) : pattern;
|
|
32029
|
-
if (minimatch(candidate, normalized, { dot: true })) {
|
|
32037
|
+
if (minimatch(candidate, normalized, { dot: true, nonegate: true })) {
|
|
32030
32038
|
return true;
|
|
32031
32039
|
}
|
|
32032
32040
|
return candidate === normalized || candidate.startsWith(normalized + "/");
|
|
@@ -41278,17 +41286,21 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
41278
41286
|
analysis: { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") }
|
|
41279
41287
|
});
|
|
41280
41288
|
}
|
|
41281
|
-
const chunks = service.chunkDiff(cleanedDiff, MAX_AI_DIFF_BYTES);
|
|
41282
|
-
const cappedChunks = chunks.slice(0, MAX_CHUNKS);
|
|
41283
|
-
const skippedChunks = chunks.length - cappedChunks.length;
|
|
41284
|
-
if (chunks.length > 1) {
|
|
41285
|
-
this.logger.info(
|
|
41286
|
-
`AutoVersionStep: split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
|
|
41287
|
-
);
|
|
41288
|
-
}
|
|
41289
41289
|
let analysis;
|
|
41290
41290
|
try {
|
|
41291
|
-
|
|
41291
|
+
if (this.config.ai == null && this.config.fernToken != null) {
|
|
41292
|
+
analysis = await this.analyzeViaFaiService(cleanedDiff, language, previousVersion);
|
|
41293
|
+
} else {
|
|
41294
|
+
const chunks = service.chunkDiff(cleanedDiff, MAX_AI_DIFF_BYTES);
|
|
41295
|
+
const cappedChunks = chunks.slice(0, MAX_CHUNKS);
|
|
41296
|
+
const skippedChunks = chunks.length - cappedChunks.length;
|
|
41297
|
+
if (chunks.length > 1) {
|
|
41298
|
+
this.logger.info(
|
|
41299
|
+
`AutoVersionStep: split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
|
|
41300
|
+
);
|
|
41301
|
+
}
|
|
41302
|
+
analysis = cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion);
|
|
41303
|
+
}
|
|
41292
41304
|
} catch (error) {
|
|
41293
41305
|
this.logger.warn(`AutoVersionStep: FAI analysis failed (${String(error)}); falling back to PATCH bump.`);
|
|
41294
41306
|
analysis = { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
|
|
@@ -41568,6 +41580,47 @@ ${newBlock}${remainder}`;
|
|
|
41568
41580
|
};
|
|
41569
41581
|
}
|
|
41570
41582
|
}
|
|
41583
|
+
/**
|
|
41584
|
+
* Calls the hosted FAI service (`/sdks/analyze-commit-diff`) with the fern token.
|
|
41585
|
+
* Used when no BAML `ai` config is supplied (remote generation via fiddle). FAI
|
|
41586
|
+
* handles chunking, parallelism, and retries server-side. Returns null on
|
|
41587
|
+
* NO_CHANGE; throws on transport/HTTP errors so the caller's PATCH fallback applies.
|
|
41588
|
+
*/
|
|
41589
|
+
async analyzeViaFaiService(cleanedDiff, language, previousVersion) {
|
|
41590
|
+
const baseUrl = this.config.faiBaseUrl ?? "https://fai.buildwithfern.com";
|
|
41591
|
+
const response = await fetch(`${baseUrl}/sdks/analyze-commit-diff`, {
|
|
41592
|
+
method: "POST",
|
|
41593
|
+
headers: {
|
|
41594
|
+
Authorization: `Bearer ${this.config.fernToken}`,
|
|
41595
|
+
"Content-Type": "application/json"
|
|
41596
|
+
},
|
|
41597
|
+
body: JSON.stringify({
|
|
41598
|
+
diff: cleanedDiff,
|
|
41599
|
+
language,
|
|
41600
|
+
previous_version: previousVersion,
|
|
41601
|
+
prior_changelog: this.config.priorChangelog ?? void 0,
|
|
41602
|
+
spec_commit_message: this.config.specCommitMessage ?? void 0
|
|
41603
|
+
})
|
|
41604
|
+
});
|
|
41605
|
+
if (!response.ok) {
|
|
41606
|
+
const body = await response.text().catch(() => "");
|
|
41607
|
+
throw new Error(`FAI analyze-commit-diff failed with status ${response.status}: ${body.slice(0, 500)}`);
|
|
41608
|
+
}
|
|
41609
|
+
const parsed = await response.json();
|
|
41610
|
+
if (!isFaiAnalyzeResponse(parsed)) {
|
|
41611
|
+
throw new Error("FAI analyze-commit-diff returned an unexpected response shape");
|
|
41612
|
+
}
|
|
41613
|
+
if (parsed.version_bump === "NO_CHANGE") {
|
|
41614
|
+
return null;
|
|
41615
|
+
}
|
|
41616
|
+
return {
|
|
41617
|
+
versionBump: parsed.version_bump,
|
|
41618
|
+
message: this.brandMessage(parsed.message),
|
|
41619
|
+
changelogEntry: nonEmpty(parsed.changelog_entry),
|
|
41620
|
+
prDescription: nonEmpty(parsed.pr_description),
|
|
41621
|
+
versionBumpReason: nonEmpty(parsed.version_bump_reason)
|
|
41622
|
+
};
|
|
41623
|
+
}
|
|
41571
41624
|
/**
|
|
41572
41625
|
* Dynamically imports @fern-api/cli-ai only when autoversion actually needs to
|
|
41573
41626
|
* call FAI. The package is ESM-only with extensionless internal imports, so
|
|
@@ -41609,6 +41662,20 @@ ${newBlock}${remainder}`;
|
|
|
41609
41662
|
return adapter;
|
|
41610
41663
|
}
|
|
41611
41664
|
};
|
|
41665
|
+
var FAI_VERSION_BUMPS = ["MAJOR", "MINOR", "PATCH", "NO_CHANGE"];
|
|
41666
|
+
function isFaiAnalyzeResponse(value) {
|
|
41667
|
+
if (typeof value !== "object" || value == null) {
|
|
41668
|
+
return false;
|
|
41669
|
+
}
|
|
41670
|
+
const candidate = value;
|
|
41671
|
+
return typeof candidate.message === "string" && typeof candidate.version_bump === "string" && FAI_VERSION_BUMPS.includes(candidate.version_bump) && isStringOrAbsent(candidate.changelog_entry) && isStringOrAbsent(candidate.pr_description) && isStringOrAbsent(candidate.version_bump_reason);
|
|
41672
|
+
}
|
|
41673
|
+
function isStringOrAbsent(value) {
|
|
41674
|
+
return value == null || typeof value === "string";
|
|
41675
|
+
}
|
|
41676
|
+
function nonEmpty(value) {
|
|
41677
|
+
return value != null && value.trim().length > 0 ? value : void 0;
|
|
41678
|
+
}
|
|
41612
41679
|
|
|
41613
41680
|
// src/pipeline/steps/GenerationCommitStep.ts
|
|
41614
41681
|
var import_child_process5 = require("child_process");
|