@fern-api/generator-cli 0.4.6 → 0.5.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/dist/api.cjs +115 -3
- package/dist/api.d.cts +41 -1
- package/dist/cli.cjs +115 -3
- package/package.json +1 -1
package/dist/api.cjs
CHANGED
|
@@ -6088,6 +6088,11 @@ var ClonedRepository = class _ClonedRepository {
|
|
|
6088
6088
|
this.clonePath = clonePath;
|
|
6089
6089
|
this.git = git;
|
|
6090
6090
|
}
|
|
6091
|
+
async setUserAndEmail({ name, email }) {
|
|
6092
|
+
await this.git.cwd(this.clonePath);
|
|
6093
|
+
await this.git.addConfig("user.name", name);
|
|
6094
|
+
await this.git.addConfig("user.email", email);
|
|
6095
|
+
}
|
|
6091
6096
|
static createAtPath(clonePath) {
|
|
6092
6097
|
return new _ClonedRepository({
|
|
6093
6098
|
clonePath,
|
|
@@ -6156,9 +6161,78 @@ var ClonedRepository = class _ClonedRepository {
|
|
|
6156
6161
|
await this.git.cwd(this.clonePath);
|
|
6157
6162
|
await this.git.pull("origin", branch);
|
|
6158
6163
|
}
|
|
6164
|
+
async pullWithMerge(branch) {
|
|
6165
|
+
await this.git.cwd(this.clonePath);
|
|
6166
|
+
await this.git.raw(["pull", "origin", branch, "--no-rebase"]);
|
|
6167
|
+
}
|
|
6159
6168
|
async push() {
|
|
6160
6169
|
await this.git.cwd(this.clonePath);
|
|
6161
|
-
await this.
|
|
6170
|
+
const currentBranch = await this.getCurrentBranch();
|
|
6171
|
+
try {
|
|
6172
|
+
await this.git.push();
|
|
6173
|
+
} catch (err) {
|
|
6174
|
+
const msg = String(err);
|
|
6175
|
+
const isNoUpstream = msg.includes("has no upstream branch") || msg.includes("no upstream branch");
|
|
6176
|
+
if (isNoUpstream) {
|
|
6177
|
+
await this.pushUpstream(currentBranch);
|
|
6178
|
+
return;
|
|
6179
|
+
}
|
|
6180
|
+
throw err;
|
|
6181
|
+
}
|
|
6182
|
+
}
|
|
6183
|
+
async pushWithMergingRemote() {
|
|
6184
|
+
await this.git.cwd(this.clonePath);
|
|
6185
|
+
const currentBranch = await this.getCurrentBranch();
|
|
6186
|
+
const isRemoteReject = (msg) => msg.includes("fetch first") || msg.includes("Updates were rejected") || msg.includes("non-fast-forward");
|
|
6187
|
+
const isDivergent = (msg) => msg.includes("divergent branches") || msg.includes("You have divergent branches");
|
|
6188
|
+
try {
|
|
6189
|
+
await this.push();
|
|
6190
|
+
} catch (err) {
|
|
6191
|
+
const errMsg = String(err);
|
|
6192
|
+
if (isRemoteReject(errMsg)) {
|
|
6193
|
+
try {
|
|
6194
|
+
await this.pull(currentBranch);
|
|
6195
|
+
await this.push();
|
|
6196
|
+
return;
|
|
6197
|
+
} catch (pullErr) {
|
|
6198
|
+
const pullMsg = String(pullErr);
|
|
6199
|
+
if (isDivergent(pullMsg)) {
|
|
6200
|
+
try {
|
|
6201
|
+
await this.pullWithMerge(currentBranch);
|
|
6202
|
+
await this.push();
|
|
6203
|
+
return;
|
|
6204
|
+
} catch (mergeErr) {
|
|
6205
|
+
throw err;
|
|
6206
|
+
}
|
|
6207
|
+
} else {
|
|
6208
|
+
throw err;
|
|
6209
|
+
}
|
|
6210
|
+
}
|
|
6211
|
+
} else {
|
|
6212
|
+
throw err;
|
|
6213
|
+
}
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
6216
|
+
async pushWithRebasingRemote() {
|
|
6217
|
+
await this.git.cwd(this.clonePath);
|
|
6218
|
+
const currentBranch = await this.getCurrentBranch();
|
|
6219
|
+
const isRemoteReject = (msg) => msg.includes("fetch first") || msg.includes("Updates were rejected") || msg.includes("non-fast-forward");
|
|
6220
|
+
try {
|
|
6221
|
+
await this.push();
|
|
6222
|
+
} catch (err) {
|
|
6223
|
+
const errMsg = String(err);
|
|
6224
|
+
if (isRemoteReject(errMsg)) {
|
|
6225
|
+
try {
|
|
6226
|
+
await this.git.raw(["pull", "origin", currentBranch, "--rebase"]);
|
|
6227
|
+
await this.push();
|
|
6228
|
+
return;
|
|
6229
|
+
} catch (pullErr) {
|
|
6230
|
+
throw new Error(`Push failed: ${errMsg}. Attempted to rebase but that also failed: ${String(pullErr)}`);
|
|
6231
|
+
}
|
|
6232
|
+
} else {
|
|
6233
|
+
throw err;
|
|
6234
|
+
}
|
|
6235
|
+
}
|
|
6162
6236
|
}
|
|
6163
6237
|
async isRemoteEmpty() {
|
|
6164
6238
|
await this.git.cwd(this.clonePath);
|
|
@@ -6177,6 +6251,18 @@ var ClonedRepository = class _ClonedRepository {
|
|
|
6177
6251
|
await this.git.checkoutLocalBranch(branch);
|
|
6178
6252
|
}
|
|
6179
6253
|
}
|
|
6254
|
+
async checkoutRemoteBranch(branch) {
|
|
6255
|
+
await this.git.cwd(this.clonePath);
|
|
6256
|
+
try {
|
|
6257
|
+
await this.git.checkout(branch);
|
|
6258
|
+
} catch (_error) {
|
|
6259
|
+
try {
|
|
6260
|
+
await this.git.checkout(["-b", branch, `origin/${branch}`]);
|
|
6261
|
+
} catch (_remoteError) {
|
|
6262
|
+
await this.git.checkoutLocalBranch(branch);
|
|
6263
|
+
}
|
|
6264
|
+
}
|
|
6265
|
+
}
|
|
6180
6266
|
async pushUpstream(branch) {
|
|
6181
6267
|
await this.git.cwd(this.clonePath);
|
|
6182
6268
|
await this.git.push("origin", branch, { "--set-upstream": null });
|
|
@@ -6781,7 +6867,8 @@ var import_fs = __toESM(require("fs"), 1);
|
|
|
6781
6867
|
var Writer = class {
|
|
6782
6868
|
async writeCodeBlock(language, content) {
|
|
6783
6869
|
await this.writeLine(`\`\`\`${language}`);
|
|
6784
|
-
|
|
6870
|
+
const normalizedContent = content.endsWith("\n") ? content : content + "\n";
|
|
6871
|
+
await this.write(normalizedContent);
|
|
6785
6872
|
await this.writeLine("```");
|
|
6786
6873
|
}
|
|
6787
6874
|
async writeLine(content) {
|
|
@@ -7124,7 +7211,23 @@ var ReadmeGenerator = class {
|
|
|
7124
7211
|
if (index > 0) {
|
|
7125
7212
|
await writer.writeLine();
|
|
7126
7213
|
}
|
|
7127
|
-
|
|
7214
|
+
if (typeof snippet === "string") {
|
|
7215
|
+
await writer.writeCodeBlock(this.readmeConfig.language.type, snippet);
|
|
7216
|
+
} else {
|
|
7217
|
+
switch (snippet.type) {
|
|
7218
|
+
case "markdown":
|
|
7219
|
+
await writer.writeLine(snippet.content);
|
|
7220
|
+
break;
|
|
7221
|
+
case "code":
|
|
7222
|
+
await writer.writeCodeBlock(
|
|
7223
|
+
snippet.language ?? this.readmeConfig.language.type,
|
|
7224
|
+
snippet.content
|
|
7225
|
+
);
|
|
7226
|
+
break;
|
|
7227
|
+
default:
|
|
7228
|
+
assertNever(snippet);
|
|
7229
|
+
}
|
|
7230
|
+
}
|
|
7128
7231
|
}
|
|
7129
7232
|
if (feature.addendum != null) {
|
|
7130
7233
|
await writer.writeLine(feature.addendum);
|
|
@@ -7160,6 +7263,15 @@ var ReadmeGenerator = class {
|
|
|
7160
7263
|
githubRepository: this.readmeConfig.remote.repoUrl,
|
|
7161
7264
|
installationToken: this.readmeConfig.remote.installationToken
|
|
7162
7265
|
});
|
|
7266
|
+
if (this.readmeConfig.remote.branch != null) {
|
|
7267
|
+
try {
|
|
7268
|
+
await clonedRepository.checkout(this.readmeConfig.remote.branch);
|
|
7269
|
+
} catch (error) {
|
|
7270
|
+
console.warn(
|
|
7271
|
+
`Failed to checkout branch ${this.readmeConfig.remote.branch}, using default branch instead`
|
|
7272
|
+
);
|
|
7273
|
+
}
|
|
7274
|
+
}
|
|
7163
7275
|
return await clonedRepository.getReadme();
|
|
7164
7276
|
}
|
|
7165
7277
|
return void 0;
|
package/dist/api.d.cts
CHANGED
|
@@ -158,6 +158,8 @@ interface GithubRemote {
|
|
|
158
158
|
repoUrl: string;
|
|
159
159
|
/** The token used to clone the GitHub repository. */
|
|
160
160
|
installationToken: string;
|
|
161
|
+
/** The branch to clone from. If not specified, the default branch will be used. */
|
|
162
|
+
branch?: string;
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
/**
|
|
@@ -168,7 +170,7 @@ interface GithubRemote {
|
|
|
168
170
|
* A single feature supported by a generator (e.g. PAGINATION).
|
|
169
171
|
*/
|
|
170
172
|
interface ReadmeFeature extends FeatureSpec {
|
|
171
|
-
snippets?:
|
|
173
|
+
snippets?: Snippet[];
|
|
172
174
|
/**
|
|
173
175
|
* If true, the feature block should be rendered even if we don't receive a snippet for it.
|
|
174
176
|
* This is useful for features that are always supported, but might not require a snippet
|
|
@@ -177,6 +179,44 @@ interface ReadmeFeature extends FeatureSpec {
|
|
|
177
179
|
snippetsAreOptional: boolean;
|
|
178
180
|
}
|
|
179
181
|
|
|
182
|
+
/**
|
|
183
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* A snippet that can be either a plain string (treated as code in the generator's language),
|
|
188
|
+
* markdown content, or a code block with optional language override.
|
|
189
|
+
* Plain strings are supported for backwards compatibility.
|
|
190
|
+
*/
|
|
191
|
+
type Snippet = string | MarkdownSnippet | CodeSnippet;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
195
|
+
*/
|
|
196
|
+
/**
|
|
197
|
+
* A markdown snippet that will be rendered as-is without code fences.
|
|
198
|
+
*/
|
|
199
|
+
interface MarkdownSnippet {
|
|
200
|
+
/** Discriminator field to identify this as a markdown snippet. */
|
|
201
|
+
type: "markdown";
|
|
202
|
+
content: string;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* This file was auto-generated by Fern from our API Definition.
|
|
207
|
+
*/
|
|
208
|
+
/**
|
|
209
|
+
* A code snippet that will be wrapped in a code fence with the specified language.
|
|
210
|
+
* If no language is specified, the generator's language will be used.
|
|
211
|
+
*/
|
|
212
|
+
interface CodeSnippet {
|
|
213
|
+
/** Discriminator field to identify this as a code snippet. */
|
|
214
|
+
type: "code";
|
|
215
|
+
content: string;
|
|
216
|
+
/** The language for the code fence. If not specified, the generator's language will be used. */
|
|
217
|
+
language?: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
180
220
|
/**
|
|
181
221
|
* This file was auto-generated by Fern from our API Definition.
|
|
182
222
|
*/
|
package/dist/cli.cjs
CHANGED
|
@@ -12227,6 +12227,11 @@ var ClonedRepository = class _ClonedRepository {
|
|
|
12227
12227
|
this.clonePath = clonePath;
|
|
12228
12228
|
this.git = git;
|
|
12229
12229
|
}
|
|
12230
|
+
async setUserAndEmail({ name, email }) {
|
|
12231
|
+
await this.git.cwd(this.clonePath);
|
|
12232
|
+
await this.git.addConfig("user.name", name);
|
|
12233
|
+
await this.git.addConfig("user.email", email);
|
|
12234
|
+
}
|
|
12230
12235
|
static createAtPath(clonePath) {
|
|
12231
12236
|
return new _ClonedRepository({
|
|
12232
12237
|
clonePath,
|
|
@@ -12295,9 +12300,78 @@ var ClonedRepository = class _ClonedRepository {
|
|
|
12295
12300
|
await this.git.cwd(this.clonePath);
|
|
12296
12301
|
await this.git.pull("origin", branch);
|
|
12297
12302
|
}
|
|
12303
|
+
async pullWithMerge(branch) {
|
|
12304
|
+
await this.git.cwd(this.clonePath);
|
|
12305
|
+
await this.git.raw(["pull", "origin", branch, "--no-rebase"]);
|
|
12306
|
+
}
|
|
12298
12307
|
async push() {
|
|
12299
12308
|
await this.git.cwd(this.clonePath);
|
|
12300
|
-
await this.
|
|
12309
|
+
const currentBranch = await this.getCurrentBranch();
|
|
12310
|
+
try {
|
|
12311
|
+
await this.git.push();
|
|
12312
|
+
} catch (err) {
|
|
12313
|
+
const msg = String(err);
|
|
12314
|
+
const isNoUpstream = msg.includes("has no upstream branch") || msg.includes("no upstream branch");
|
|
12315
|
+
if (isNoUpstream) {
|
|
12316
|
+
await this.pushUpstream(currentBranch);
|
|
12317
|
+
return;
|
|
12318
|
+
}
|
|
12319
|
+
throw err;
|
|
12320
|
+
}
|
|
12321
|
+
}
|
|
12322
|
+
async pushWithMergingRemote() {
|
|
12323
|
+
await this.git.cwd(this.clonePath);
|
|
12324
|
+
const currentBranch = await this.getCurrentBranch();
|
|
12325
|
+
const isRemoteReject = (msg) => msg.includes("fetch first") || msg.includes("Updates were rejected") || msg.includes("non-fast-forward");
|
|
12326
|
+
const isDivergent = (msg) => msg.includes("divergent branches") || msg.includes("You have divergent branches");
|
|
12327
|
+
try {
|
|
12328
|
+
await this.push();
|
|
12329
|
+
} catch (err) {
|
|
12330
|
+
const errMsg = String(err);
|
|
12331
|
+
if (isRemoteReject(errMsg)) {
|
|
12332
|
+
try {
|
|
12333
|
+
await this.pull(currentBranch);
|
|
12334
|
+
await this.push();
|
|
12335
|
+
return;
|
|
12336
|
+
} catch (pullErr) {
|
|
12337
|
+
const pullMsg = String(pullErr);
|
|
12338
|
+
if (isDivergent(pullMsg)) {
|
|
12339
|
+
try {
|
|
12340
|
+
await this.pullWithMerge(currentBranch);
|
|
12341
|
+
await this.push();
|
|
12342
|
+
return;
|
|
12343
|
+
} catch (mergeErr) {
|
|
12344
|
+
throw err;
|
|
12345
|
+
}
|
|
12346
|
+
} else {
|
|
12347
|
+
throw err;
|
|
12348
|
+
}
|
|
12349
|
+
}
|
|
12350
|
+
} else {
|
|
12351
|
+
throw err;
|
|
12352
|
+
}
|
|
12353
|
+
}
|
|
12354
|
+
}
|
|
12355
|
+
async pushWithRebasingRemote() {
|
|
12356
|
+
await this.git.cwd(this.clonePath);
|
|
12357
|
+
const currentBranch = await this.getCurrentBranch();
|
|
12358
|
+
const isRemoteReject = (msg) => msg.includes("fetch first") || msg.includes("Updates were rejected") || msg.includes("non-fast-forward");
|
|
12359
|
+
try {
|
|
12360
|
+
await this.push();
|
|
12361
|
+
} catch (err) {
|
|
12362
|
+
const errMsg = String(err);
|
|
12363
|
+
if (isRemoteReject(errMsg)) {
|
|
12364
|
+
try {
|
|
12365
|
+
await this.git.raw(["pull", "origin", currentBranch, "--rebase"]);
|
|
12366
|
+
await this.push();
|
|
12367
|
+
return;
|
|
12368
|
+
} catch (pullErr) {
|
|
12369
|
+
throw new Error(`Push failed: ${errMsg}. Attempted to rebase but that also failed: ${String(pullErr)}`);
|
|
12370
|
+
}
|
|
12371
|
+
} else {
|
|
12372
|
+
throw err;
|
|
12373
|
+
}
|
|
12374
|
+
}
|
|
12301
12375
|
}
|
|
12302
12376
|
async isRemoteEmpty() {
|
|
12303
12377
|
await this.git.cwd(this.clonePath);
|
|
@@ -12316,6 +12390,18 @@ var ClonedRepository = class _ClonedRepository {
|
|
|
12316
12390
|
await this.git.checkoutLocalBranch(branch);
|
|
12317
12391
|
}
|
|
12318
12392
|
}
|
|
12393
|
+
async checkoutRemoteBranch(branch) {
|
|
12394
|
+
await this.git.cwd(this.clonePath);
|
|
12395
|
+
try {
|
|
12396
|
+
await this.git.checkout(branch);
|
|
12397
|
+
} catch (_error) {
|
|
12398
|
+
try {
|
|
12399
|
+
await this.git.checkout(["-b", branch, `origin/${branch}`]);
|
|
12400
|
+
} catch (_remoteError) {
|
|
12401
|
+
await this.git.checkoutLocalBranch(branch);
|
|
12402
|
+
}
|
|
12403
|
+
}
|
|
12404
|
+
}
|
|
12319
12405
|
async pushUpstream(branch) {
|
|
12320
12406
|
await this.git.cwd(this.clonePath);
|
|
12321
12407
|
await this.git.push("origin", branch, { "--set-upstream": null });
|
|
@@ -12920,7 +13006,8 @@ var import_fs5 = __toESM(require("fs"), 1);
|
|
|
12920
13006
|
var Writer = class {
|
|
12921
13007
|
async writeCodeBlock(language, content) {
|
|
12922
13008
|
await this.writeLine(`\`\`\`${language}`);
|
|
12923
|
-
|
|
13009
|
+
const normalizedContent = content.endsWith("\n") ? content : content + "\n";
|
|
13010
|
+
await this.write(normalizedContent);
|
|
12924
13011
|
await this.writeLine("```");
|
|
12925
13012
|
}
|
|
12926
13013
|
async writeLine(content) {
|
|
@@ -13263,7 +13350,23 @@ var ReadmeGenerator = class {
|
|
|
13263
13350
|
if (index > 0) {
|
|
13264
13351
|
await writer.writeLine();
|
|
13265
13352
|
}
|
|
13266
|
-
|
|
13353
|
+
if (typeof snippet === "string") {
|
|
13354
|
+
await writer.writeCodeBlock(this.readmeConfig.language.type, snippet);
|
|
13355
|
+
} else {
|
|
13356
|
+
switch (snippet.type) {
|
|
13357
|
+
case "markdown":
|
|
13358
|
+
await writer.writeLine(snippet.content);
|
|
13359
|
+
break;
|
|
13360
|
+
case "code":
|
|
13361
|
+
await writer.writeCodeBlock(
|
|
13362
|
+
snippet.language ?? this.readmeConfig.language.type,
|
|
13363
|
+
snippet.content
|
|
13364
|
+
);
|
|
13365
|
+
break;
|
|
13366
|
+
default:
|
|
13367
|
+
assertNever(snippet);
|
|
13368
|
+
}
|
|
13369
|
+
}
|
|
13267
13370
|
}
|
|
13268
13371
|
if (feature.addendum != null) {
|
|
13269
13372
|
await writer.writeLine(feature.addendum);
|
|
@@ -13299,6 +13402,15 @@ var ReadmeGenerator = class {
|
|
|
13299
13402
|
githubRepository: this.readmeConfig.remote.repoUrl,
|
|
13300
13403
|
installationToken: this.readmeConfig.remote.installationToken
|
|
13301
13404
|
});
|
|
13405
|
+
if (this.readmeConfig.remote.branch != null) {
|
|
13406
|
+
try {
|
|
13407
|
+
await clonedRepository.checkout(this.readmeConfig.remote.branch);
|
|
13408
|
+
} catch (error) {
|
|
13409
|
+
console.warn(
|
|
13410
|
+
`Failed to checkout branch ${this.readmeConfig.remote.branch}, using default branch instead`
|
|
13411
|
+
);
|
|
13412
|
+
}
|
|
13413
|
+
}
|
|
13302
13414
|
return await clonedRepository.getReadme();
|
|
13303
13415
|
}
|
|
13304
13416
|
return void 0;
|