@fern-api/generator-cli 0.9.51 → 0.9.53
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/cli.js +124 -4
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -22214,7 +22214,7 @@ var init_diff3 = __esm({
|
|
|
22214
22214
|
}
|
|
22215
22215
|
});
|
|
22216
22216
|
|
|
22217
|
-
// ../../node_modules/.pnpm/@fern-api+replay@0.19.
|
|
22217
|
+
// ../../node_modules/.pnpm/@fern-api+replay@0.19.2/node_modules/@fern-api/replay/dist/index.js
|
|
22218
22218
|
var dist_exports = {};
|
|
22219
22219
|
__export(dist_exports, {
|
|
22220
22220
|
CREDENTIAL_PATTERNS: () => CREDENTIAL_PATTERNS,
|
|
@@ -24295,7 +24295,7 @@ function status(outputDir) {
|
|
|
24295
24295
|
}
|
|
24296
24296
|
var import_promises4, import_os, import_path7, import_fs6, import_path8, import_yaml, import_crypto, import_path9, import_promises5, import_os2, import_path10, import_promises6, import_path11, import_promises7, import_path12, import_fs7, import_promises8, import_path13, import_fs8, import_path14, import_promises9, import_os3, import_path15, import_child_process3, import_crypto2, import_fs9, import_path16, import_yaml2, import_crypto3, import_fs10, import_path17, import_fs11, import_promises10, import_path18, __defProp3, __getOwnPropNames3, __esm3, __export3, GitClient_exports, GitClient, init_GitClient, HybridReconstruction_exports, init_HybridReconstruction, PatchApplyTheirs_exports, init_PatchApplyTheirs, CREDENTIAL_PATTERNS, SENSITIVE_FILE_PATTERNS, FERN_BOT_NAME, FERN_BOT_EMAIL, FERN_BOT_LOGIN, FERN_SUPPORT_NAMES, LOCKFILE_HEADER, LockfileNotFoundError, LockfileManager, BINARY_EXTENSIONS, INFRASTRUCTURE_FILES, ReplayDetector, MergeAccumulator, CONFLICT_OPENER, CONFLICT_SEPARATOR, CONFLICT_CLOSER, AUTOVERSION_PLACEHOLDERS, VERSION_TOKEN, VERSION_MASK, ReplayApplicator, ReplayCommitter, FileOwnership, FirstGenerationFlow, SkipApplicationFlow, NoPatchesFlow, NormalRegenerationFlow, ReplayService, FernignoreMigrator, REPLAY_FERNIGNORE_ENTRIES, GITATTRIBUTES_ENTRIES, EMPTY_RESULT;
|
|
24297
24297
|
var init_dist3 = __esm({
|
|
24298
|
-
"../../node_modules/.pnpm/@fern-api+replay@0.19.
|
|
24298
|
+
"../../node_modules/.pnpm/@fern-api+replay@0.19.2/node_modules/@fern-api/replay/dist/index.js"() {
|
|
24299
24299
|
"use strict";
|
|
24300
24300
|
init_esm4();
|
|
24301
24301
|
import_promises4 = require("fs/promises");
|
|
@@ -26248,7 +26248,9 @@ Patches absorbed by generator (${buckets.absorbed.length}):`;
|
|
|
26248
26248
|
}
|
|
26249
26249
|
async prepare(options) {
|
|
26250
26250
|
const preLock = this.service.lockManager.read();
|
|
26251
|
-
const previousGenerationSha =
|
|
26251
|
+
const previousGenerationSha = await this.service.resolveReachablePreviousGeneration(
|
|
26252
|
+
preLock.current_generation ?? null
|
|
26253
|
+
);
|
|
26252
26254
|
let { patches: newPatches, revertedPatchIds } = await this.service.detector.detectNewPatches();
|
|
26253
26255
|
const detectorWarnings = [...this.service.detector.warnings];
|
|
26254
26256
|
const detectorDegraded = [...this.service.detector.degradedReasons];
|
|
@@ -26384,7 +26386,9 @@ Patches absorbed by generator (${buckets.absorbed.length}):`;
|
|
|
26384
26386
|
}
|
|
26385
26387
|
async prepare(options) {
|
|
26386
26388
|
const preLock = this.service.lockManager.read();
|
|
26387
|
-
const previousGenerationSha =
|
|
26389
|
+
const previousGenerationSha = await this.service.resolveReachablePreviousGeneration(
|
|
26390
|
+
preLock.current_generation ?? null
|
|
26391
|
+
);
|
|
26388
26392
|
if (options?.dryRun) {
|
|
26389
26393
|
const existingPatches2 = this.service.lockManager.getPatches();
|
|
26390
26394
|
const { patches: newPatches2, revertedPatchIds: dryRunReverted } = await this.service.detector.detectNewPatches();
|
|
@@ -26613,6 +26617,37 @@ Patches absorbed by generator (${buckets.absorbed.length}):`;
|
|
|
26613
26617
|
this.committer = new ReplayCommitter(git, outputDir);
|
|
26614
26618
|
this.fileOwnership = new FileOwnership(git);
|
|
26615
26619
|
}
|
|
26620
|
+
/**
|
|
26621
|
+
* Resolve the previous-generation SHA to export on
|
|
26622
|
+
* `ReplayPreparation.previousGenerationSha`.
|
|
26623
|
+
*
|
|
26624
|
+
* `current_generation` is the SHA of a LOCALLY-created `[fern-generated]` commit.
|
|
26625
|
+
* generator-cli's signed-commit push (`pushSignedCommit`) recreates that commit under a
|
|
26626
|
+
* new remote SHA, and a squash-merge collapses it away, so the recorded value can be
|
|
26627
|
+
* unreachable in a later clone (org "Natural": autoVersion then diffed against a phantom
|
|
26628
|
+
* baseline and silently reported NO_CHANGE — or, pre-a38bbc6, shipped
|
|
26629
|
+
* `0.0.0-fern-placeholder`). Consumers (generator-cli's autoVersion) diff against this
|
|
26630
|
+
* baseline, so it MUST resolve to a real commit.
|
|
26631
|
+
*
|
|
26632
|
+
* Prefer the recorded SHA while it still resolves — the healthy case, and the pristine
|
|
26633
|
+
* prior `[fern-generated]` tree. Otherwise re-anchor on the most recent reachable
|
|
26634
|
+
* generation boundary in first-parent history: the SAME value the detector already
|
|
26635
|
+
* derives for its own scan boundary (`findPreviousGenerationFromHistory`, whose
|
|
26636
|
+
* `isGenerationBoundary` matches squash-merge subjects like `SDK Generation (#N)`). Fall
|
|
26637
|
+
* back to the recorded SHA only when no boundary is reachable at all — no worse than the
|
|
26638
|
+
* prior behavior. ADR 0002 (generator-cli) allows replay to expose this reconciled value;
|
|
26639
|
+
* the consumer stays independently resilient.
|
|
26640
|
+
*
|
|
26641
|
+
* MUST be called before the new `[fern-generated]` commit is created, while HEAD is still
|
|
26642
|
+
* the pre-generation (customer) state, so the walk anchors on the PREVIOUS generation.
|
|
26643
|
+
*/
|
|
26644
|
+
async resolveReachablePreviousGeneration(recordedSha) {
|
|
26645
|
+
if (recordedSha != null && await this.git.commitExists(recordedSha)) {
|
|
26646
|
+
return recordedSha;
|
|
26647
|
+
}
|
|
26648
|
+
const derived = await this.detector.findPreviousGenerationFromHistory();
|
|
26649
|
+
return derived ?? recordedSha;
|
|
26650
|
+
}
|
|
26616
26651
|
/**
|
|
26617
26652
|
* Phase 1 of the two-phase replay flow. Runs preGenerationRebase (when applicable),
|
|
26618
26653
|
* detects new patches, and creates the `[fern-generated]` commit. Leaves HEAD at
|
|
@@ -41127,6 +41162,7 @@ var AutoVersioningService = class _AutoVersioningService {
|
|
|
41127
41162
|
}
|
|
41128
41163
|
}
|
|
41129
41164
|
let processedContent = this.removeGoModulePathSuffixPairs(contentLines);
|
|
41165
|
+
processedContent = this.removeGoExplicitFieldBitConstantPairs(processedContent);
|
|
41130
41166
|
processedContent = this.removeVersionChangePairs(processedContent, mappedMagicVersion);
|
|
41131
41167
|
processedContent = this.removeRemainingMagicVersionLines(processedContent, mappedMagicVersion);
|
|
41132
41168
|
let hasChanges = false;
|
|
@@ -41331,6 +41367,90 @@ var AutoVersioningService = class _AutoVersioningService {
|
|
|
41331
41367
|
hasSuffix: suffixPattern.test(content)
|
|
41332
41368
|
};
|
|
41333
41369
|
}
|
|
41370
|
+
/**
|
|
41371
|
+
* Removes Go `explicitFields` bit-constant reindexing churn from a diff section.
|
|
41372
|
+
*
|
|
41373
|
+
* The Go SDK tracks which optional fields were explicitly set via a per-struct `big.Int`
|
|
41374
|
+
* bitmask. For each struct property it generates a private constant whose value is a single
|
|
41375
|
+
* bit at the property's positional index, e.g.
|
|
41376
|
+
*
|
|
41377
|
+
* var (
|
|
41378
|
+
* entityFieldGeoShape = big.NewInt(1 << 3)
|
|
41379
|
+
* entityFieldGeoDetails = big.NewInt(1 << 4)
|
|
41380
|
+
* )
|
|
41381
|
+
*
|
|
41382
|
+
* Inserting a new field earlier in the struct shifts every following constant's bit index by
|
|
41383
|
+
* one, producing a deletion/addition pair per field that differs only by the integer:
|
|
41384
|
+
*
|
|
41385
|
+
* - entityFieldGeoShape = big.NewInt(1 << 3)
|
|
41386
|
+
* + entityFieldGeoShape = big.NewInt(1 << 4)
|
|
41387
|
+
*
|
|
41388
|
+
* This is a purely mechanical artifact of the field addition: the bit is assigned and read
|
|
41389
|
+
* within the same generated version (the wire format is name-based JSON, not bit position),
|
|
41390
|
+
* so shifting it is not observable to consumers. Left in the diff, the AI analyzer reads the
|
|
41391
|
+
* shifted bit positions as a serialization-compatibility break and misclassifies an additive
|
|
41392
|
+
* change as a spurious MAJOR bump. The genuinely new field, its own new bit constant, and its
|
|
41393
|
+
* setter are all pure additions with no matching deletion, so they survive this pass and the
|
|
41394
|
+
* AI still sees (and correctly classifies) the field addition as MINOR.
|
|
41395
|
+
*/
|
|
41396
|
+
removeGoExplicitFieldBitConstantPairs(lines) {
|
|
41397
|
+
const additions = [];
|
|
41398
|
+
for (let index = 0; index < lines.length; index++) {
|
|
41399
|
+
const line = lines[index];
|
|
41400
|
+
if (line == null || !this.isAdditionLine(line)) {
|
|
41401
|
+
continue;
|
|
41402
|
+
}
|
|
41403
|
+
const info = this.analyzeGoBitConstantLine(line);
|
|
41404
|
+
if (info != null) {
|
|
41405
|
+
additions.push({ index, normalized: info.normalized });
|
|
41406
|
+
}
|
|
41407
|
+
}
|
|
41408
|
+
const removed = /* @__PURE__ */ new Set();
|
|
41409
|
+
const usedAdditions = /* @__PURE__ */ new Set();
|
|
41410
|
+
for (let index = 0; index < lines.length; index++) {
|
|
41411
|
+
const line = lines[index];
|
|
41412
|
+
if (line == null || !this.isDeletionLine(line)) {
|
|
41413
|
+
continue;
|
|
41414
|
+
}
|
|
41415
|
+
const info = this.analyzeGoBitConstantLine(line);
|
|
41416
|
+
if (info == null) {
|
|
41417
|
+
continue;
|
|
41418
|
+
}
|
|
41419
|
+
const match2 = additions.find(
|
|
41420
|
+
(addition) => !usedAdditions.has(addition.index) && addition.normalized === info.normalized
|
|
41421
|
+
);
|
|
41422
|
+
if (match2 != null) {
|
|
41423
|
+
usedAdditions.add(match2.index);
|
|
41424
|
+
removed.add(index);
|
|
41425
|
+
removed.add(match2.index);
|
|
41426
|
+
}
|
|
41427
|
+
}
|
|
41428
|
+
if (removed.size === 0) {
|
|
41429
|
+
return lines;
|
|
41430
|
+
}
|
|
41431
|
+
return lines.filter((_2, index) => !removed.has(index));
|
|
41432
|
+
}
|
|
41433
|
+
/**
|
|
41434
|
+
* If a diff line (with its leading +/- stripped) is a generated Go `explicitFields`
|
|
41435
|
+
* bit constant — `<name> = big.NewInt(1 << N)` or the >=63 form
|
|
41436
|
+
* `<name> = big.NewInt(0).Lsh(big.NewInt(1), N)` — returns a normalized key with the bit
|
|
41437
|
+
* index removed so a deletion and its reindexed addition compare equal. Requiring the exact
|
|
41438
|
+
* `big.NewInt` bit-shift shape keeps this from matching ordinary integer assignments.
|
|
41439
|
+
*/
|
|
41440
|
+
analyzeGoBitConstantLine(line) {
|
|
41441
|
+
const content = line.substring(1);
|
|
41442
|
+
const shiftMatch = content.match(/^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=\s*big\.NewInt\(1\s*<<\s*\d+\)\s*$/);
|
|
41443
|
+
if (shiftMatch?.[2] != null) {
|
|
41444
|
+
return { normalized: `${shiftMatch[2]}=big.NewInt(1<<#)` };
|
|
41445
|
+
}
|
|
41446
|
+
const lshMatch = content.match(
|
|
41447
|
+
/^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=\s*big\.NewInt\(0\)\.Lsh\(big\.NewInt\(1\),\s*\d+\)\s*$/
|
|
41448
|
+
);
|
|
41449
|
+
if (lshMatch?.[2] != null) {
|
|
41450
|
+
return { normalized: `${lshMatch[2]}=big.NewInt(0).Lsh(big.NewInt(1),#)` };
|
|
41451
|
+
}
|
|
41452
|
+
return void 0;
|
|
41453
|
+
}
|
|
41334
41454
|
/**
|
|
41335
41455
|
* Gets the latest semantic version from git tags in the given repository.
|
|
41336
41456
|
* Used as a fallback when the magic version is not embedded in any generated file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fern-api/generator-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.53",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/fern-api/fern.git",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@boundaryml/baml": "^0.219.0",
|
|
26
|
-
"@fern-api/replay": "0.19.
|
|
26
|
+
"@fern-api/replay": "0.19.2",
|
|
27
27
|
"@octokit/rest": "^22.0.1",
|
|
28
28
|
"es-toolkit": "^1.45.1",
|
|
29
29
|
"semver": "^7.6.3",
|