@ebay-dt/bonfire-cli 0.2.0-alpha.10 → 0.2.0-alpha.11
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 +16 -10
- package/dist/branch-prepare.d.ts +6 -3
- package/dist/branch-prepare.d.ts.map +1 -1
- package/dist/branch-prepare.js +67 -18
- package/dist/branch-prepare.js.map +1 -1
- package/dist/command.d.ts +5 -1
- package/dist/command.d.ts.map +1 -1
- package/dist/command.js +62 -12
- package/dist/command.js.map +1 -1
- package/dist/convert.d.ts.map +1 -1
- package/dist/convert.js +1 -1
- package/dist/convert.js.map +1 -1
- package/dist/release-versions.d.ts +1 -1
- package/dist/release-versions.d.ts.map +1 -1
- package/dist/release-versions.js +1 -1
- package/dist/release-versions.js.map +1 -1
- package/package.json +4 -4
- package/templates/instance/src/actions/prototypes.ts +8 -0
- package/templates/instance/src/actions/repository.ts +4 -0
- package/templates/instance/src/app/(system)/api/repository/preparation/retry/route.ts +3 -0
- package/templates/instance/src/app/layout.tsx +6 -0
- package/templates/instance/src/bonfire.ts +9 -1
package/README.md
CHANGED
|
@@ -80,15 +80,21 @@ machine state without changing it.
|
|
|
80
80
|
Before starting Next.js in development, run:
|
|
81
81
|
|
|
82
82
|
```sh
|
|
83
|
-
bonfire branch prepare --root <application-root> --hostname <hostname>
|
|
83
|
+
bonfire branch prepare --root <application-root> [--hostname <hostname>] [--default-hostname <hostname>]
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
The command loads environment values with Next-compatible precedence
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
86
|
+
The command loads environment values with Next-compatible precedence. Explicit
|
|
87
|
+
`--hostname` wins; generated development scripts use `--default-hostname` so
|
|
88
|
+
`BF_GITHUB_HOSTNAME` from `.env.local` is loaded before the fallback is used.
|
|
89
|
+
`BF_GIT_MODE=manual` disables Bonfire Git mutations and skips GitHub CLI and
|
|
90
|
+
branch preparation; managed mode is the default. Separately,
|
|
91
|
+
`BF_DISABLE_AUTO_BRANCH_SWITCH=true` skips automatic branch selection but does
|
|
92
|
+
not turn off managed commits and pushes. When enabled,
|
|
93
|
+
`BF_PROTOTYPE_BASE_BRANCH` overrides the default `main` primary branch, and
|
|
94
|
+
an available GitHub CLI identity is synchronized on their login branch through
|
|
95
|
+
`@ebay-dt/bonfire-node`. Missing GitHub CLI identity and classified repository
|
|
96
|
+
attention (for example dirty work, failed fetch, or missing primary) are
|
|
97
|
+
nonfatal and allow Next.js to start. Invalid configuration or unexpected
|
|
98
|
+
preparation failures still exit nonzero; no other branch is silently used.
|
|
99
|
+
The command never starts interactive authentication or prints identity,
|
|
100
|
+
credentials, paths, or raw Git output.
|
package/dist/branch-prepare.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { type GitHubCliClientLike, type PrototypeLifecycle } from "@ebay-dt/bonfire-node";
|
|
1
|
+
import { type DependencyInstaller, type GitHubCliClientLike, type PrototypeLifecycle } from "@ebay-dt/bonfire-node";
|
|
2
2
|
import type { BranchPrepareCommandOptions } from "./command.js";
|
|
3
3
|
export type CliEnvironmentLoader = (root: string) => Readonly<Record<string, string | undefined>>;
|
|
4
4
|
export type BranchPrepareDependencies = {
|
|
5
5
|
environment?: Readonly<Record<string, string | undefined>>;
|
|
6
6
|
loadEnvironment?: CliEnvironmentLoader;
|
|
7
7
|
githubCli?: GitHubCliClientLike;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
createGitHubCli?: (options: {
|
|
9
|
+
hostname: string;
|
|
10
|
+
}) => GitHubCliClientLike;
|
|
11
|
+
lifecycle?: Pick<PrototypeLifecycle, "prepareBranch" | "prepareDependencies">;
|
|
12
|
+
installDependencies?: DependencyInstaller;
|
|
10
13
|
};
|
|
11
14
|
export declare class BranchPrepareError extends Error {
|
|
12
15
|
constructor(message: string);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch-prepare.d.ts","sourceRoot":"","sources":["../src/branch-prepare.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"branch-prepare.d.ts","sourceRoot":"","sources":["../src/branch-prepare.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,MAAM,oBAAoB,GAAG,CACjC,IAAI,EAAE,MAAM,KACT,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAElD,MAAM,MAAM,yBAAyB,GAAG;IACtC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D,eAAe,CAAC,EAAE,oBAAoB,CAAC;IACvC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,mBAAmB,CAAC;IACzE,SAAS,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,GAAG,qBAAqB,CAAC,CAAC;IAC9E,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAMD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,2BAA2B,EACpC,YAAY,EAAE,yBAAyB,GACtC,OAAO,CAAC,MAAM,CAAC,CA0JjB","sourcesContent":["import nextEnv from \"@next/env\";\nimport {\n parseAutomaticBranchSwitchSetting,\n parseGitModeSetting,\n parseHostname,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n GitHubCliClient,\n GitHubCliError,\n LocalPrototypeLifecycle,\n type DependencyInstaller,\n type GitHubCliClientLike,\n type PrototypeLifecycle,\n} from \"@ebay-dt/bonfire-node\";\nimport { resolve } from \"node:path\";\nimport type { BranchPrepareCommandOptions } from \"./command.js\";\n\nexport type CliEnvironmentLoader = (\n root: string,\n) => Readonly<Record<string, string | undefined>>;\n\nexport type BranchPrepareDependencies = {\n environment?: Readonly<Record<string, string | undefined>>;\n loadEnvironment?: CliEnvironmentLoader;\n githubCli?: GitHubCliClientLike;\n createGitHubCli?: (options: { hostname: string }) => GitHubCliClientLike;\n lifecycle?: Pick<PrototypeLifecycle, \"prepareBranch\" | \"prepareDependencies\">;\n installDependencies?: DependencyInstaller;\n};\n\nexport class BranchPrepareError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BranchPrepareError\";\n }\n}\n\nfunction loadEnvironment(root: string) {\n return nextEnv.loadEnvConfig(root, true, undefined, false).combinedEnv;\n}\n\nexport async function runBranchPrepare(\n options: BranchPrepareCommandOptions,\n dependencies: BranchPrepareDependencies,\n): Promise<number> {\n const root = resolve(options.root);\n const environment =\n dependencies.environment ??\n dependencies.loadEnvironment?.(root) ??\n loadEnvironment(root);\n // This guard must precede marker reads, identity resolution, and all Git\n // collaborators. A direct production invocation must remain read-only even\n // when a previous development install left recovery state behind.\n if (environment.NODE_ENV === \"production\") {\n console.log(\"Branch preparation is disabled in production.\");\n return 0;\n }\n\n const mode = parseAutomaticBranchSwitchSetting(\n environment.BF_DISABLE_AUTO_BRANCH_SWITCH,\n );\n const gitMode = parseGitModeSetting(environment.BF_GIT_MODE);\n\n if (gitMode === \"manual\") {\n console.log(\"Git management is in manual mode.\");\n return 0;\n }\n\n if (mode === \"disabled\") {\n console.log(\"Automatic branch switching is disabled.\");\n return 0;\n }\n\n // Explicit --hostname wins. Generated scripts use --default-hostname so\n // Next-compatible .env.local loading can supply BF_GITHUB_HOSTNAME first.\n const hostname = parseHostname(\n options.hostname ??\n environment.BF_GITHUB_HOSTNAME ??\n options.defaultHostname,\n );\n const lifecycle =\n dependencies.lifecycle ??\n new LocalPrototypeLifecycle({\n repositoryRoot: root,\n prototypeRoot: options.prototypeRoot ?? environment.BF_PROTOTYPE_ROOT,\n remote: options.remote ?? environment.BF_GIT_REMOTE,\n primaryBranch:\n options.primaryBranch ?? environment.BF_PROTOTYPE_BASE_BRANCH,\n automaticBranchSwitch: mode,\n gitMode,\n installDependencies: dependencies.installDependencies,\n });\n const prepareDependencies = lifecycle.prepareDependencies;\n if (prepareDependencies !== undefined) {\n const pending = await prepareDependencies.call(\n lifecycle,\n [],\n dependencies.installDependencies,\n );\n if (!pending.ok) {\n throw new BranchPrepareError(\"Unable to prepare project dependencies.\");\n }\n if (pending.value.status === \"failed\") {\n throw new BranchPrepareError(\n \"Dependency preparation failed; the development server was not started.\",\n );\n }\n if (pending.value.status === \"prepared\") {\n console.log(\"Pending project dependencies prepared.\");\n }\n }\n\n const githubCli =\n dependencies.githubCli ??\n (dependencies.createGitHubCli?.({ hostname }) ??\n new GitHubCliClient({ hostname }));\n let identity;\n try {\n identity = await githubCli.getUser();\n } catch (error) {\n if (\n error instanceof GitHubCliError &&\n (error.reason === \"missing\" || error.reason === \"unauthenticated\")\n ) {\n console.log(\n \"Branch preparation deferred; GitHub CLI authentication is not available.\",\n );\n return 0;\n }\n throw new BranchPrepareError(\"Unable to resolve GitHub CLI identity.\");\n }\n\n const result = await lifecycle.prepareBranch(identity);\n if (!result.ok) {\n throw new BranchPrepareError(\n `Branch preparation failed with ${result.error.code}.`,\n );\n }\n\n if (result.value.status === \"deferred\") {\n console.log(\n `Branch preparation deferred; repository attention: ${result.value.reason}.`,\n );\n // A dirty/offline check that made no changes is safe to leave for the\n // existing environment. Never launch after a partially applied update.\n if (\n result.value.effects.changed ||\n result.value.effects.pushed ||\n result.value.effects.reconciledPaths.length > 0 ||\n (result.value.effects.platformPaths?.length ?? 0) > 0 ||\n (result.value.effects.dependencyPaths?.length ?? 0) > 0 ||\n result.value.effects.preparationRequired === true ||\n result.value.effects.restartRequired\n ) {\n throw new BranchPrepareError(\n \"Branch preparation was only partially completed; the development server was not started.\",\n );\n }\n return 0;\n }\n if (result.value.status === \"unsafe\") {\n throw new BranchPrepareError(\n `Branch preparation requires repository attention (${result.value.reason}); the development server was not started.`,\n );\n }\n if (result.value.status === \"disabled\") {\n console.log(\n \"Branch preparation skipped; synchronization is disabled by configuration.\",\n );\n return 0;\n }\n\n const dependencyPaths = result.value.effects.dependencyPaths ?? [];\n const managedPathChanged =\n dependencyPaths.length > 0 ||\n result.value.effects.preparationRequired === true;\n if (managedPathChanged) {\n console.log(\"Installing updated project dependencies...\");\n if (prepareDependencies !== undefined) {\n const preparation = await prepareDependencies.call(\n lifecycle,\n dependencyPaths,\n dependencies.installDependencies,\n );\n if (!preparation.ok || preparation.value.status === \"failed\") {\n throw new BranchPrepareError(\n \"Dependency preparation failed; the development server was not started.\",\n );\n }\n } else {\n throw new BranchPrepareError(\n \"This lifecycle does not support dependency preparation; the development server was not started.\",\n );\n }\n }\n\n console.log(\"Branch preparation complete.\");\n return 0;\n}\n"]}
|
package/dist/branch-prepare.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { execFile as execFileCallback } from "node:child_process";
|
|
2
|
-
import { promisify } from "node:util";
|
|
3
1
|
import nextEnv from "@next/env";
|
|
4
|
-
import {
|
|
2
|
+
import { parseAutomaticBranchSwitchSetting, parseGitModeSetting, parseHostname, } from "@ebay-dt/bonfire-core";
|
|
5
3
|
import { GitHubCliClient, GitHubCliError, LocalPrototypeLifecycle, } from "@ebay-dt/bonfire-node";
|
|
6
4
|
import { resolve } from "node:path";
|
|
7
|
-
const execFile = promisify(execFileCallback);
|
|
8
5
|
export class BranchPrepareError extends Error {
|
|
9
6
|
constructor(message) {
|
|
10
7
|
super(message);
|
|
@@ -19,9 +16,15 @@ export async function runBranchPrepare(options, dependencies) {
|
|
|
19
16
|
const environment = dependencies.environment ??
|
|
20
17
|
dependencies.loadEnvironment?.(root) ??
|
|
21
18
|
loadEnvironment(root);
|
|
19
|
+
// This guard must precede marker reads, identity resolution, and all Git
|
|
20
|
+
// collaborators. A direct production invocation must remain read-only even
|
|
21
|
+
// when a previous development install left recovery state behind.
|
|
22
|
+
if (environment.NODE_ENV === "production") {
|
|
23
|
+
console.log("Branch preparation is disabled in production.");
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
22
26
|
const mode = parseAutomaticBranchSwitchSetting(environment.BF_DISABLE_AUTO_BRANCH_SWITCH);
|
|
23
27
|
const gitMode = parseGitModeSetting(environment.BF_GIT_MODE);
|
|
24
|
-
const hostname = parseHostname(options.hostname);
|
|
25
28
|
if (gitMode === "manual") {
|
|
26
29
|
console.log("Git management is in manual mode.");
|
|
27
30
|
return 0;
|
|
@@ -30,7 +33,37 @@ export async function runBranchPrepare(options, dependencies) {
|
|
|
30
33
|
console.log("Automatic branch switching is disabled.");
|
|
31
34
|
return 0;
|
|
32
35
|
}
|
|
33
|
-
|
|
36
|
+
// Explicit --hostname wins. Generated scripts use --default-hostname so
|
|
37
|
+
// Next-compatible .env.local loading can supply BF_GITHUB_HOSTNAME first.
|
|
38
|
+
const hostname = parseHostname(options.hostname ??
|
|
39
|
+
environment.BF_GITHUB_HOSTNAME ??
|
|
40
|
+
options.defaultHostname);
|
|
41
|
+
const lifecycle = dependencies.lifecycle ??
|
|
42
|
+
new LocalPrototypeLifecycle({
|
|
43
|
+
repositoryRoot: root,
|
|
44
|
+
prototypeRoot: options.prototypeRoot ?? environment.BF_PROTOTYPE_ROOT,
|
|
45
|
+
remote: options.remote ?? environment.BF_GIT_REMOTE,
|
|
46
|
+
primaryBranch: options.primaryBranch ?? environment.BF_PROTOTYPE_BASE_BRANCH,
|
|
47
|
+
automaticBranchSwitch: mode,
|
|
48
|
+
gitMode,
|
|
49
|
+
installDependencies: dependencies.installDependencies,
|
|
50
|
+
});
|
|
51
|
+
const prepareDependencies = lifecycle.prepareDependencies;
|
|
52
|
+
if (prepareDependencies !== undefined) {
|
|
53
|
+
const pending = await prepareDependencies.call(lifecycle, [], dependencies.installDependencies);
|
|
54
|
+
if (!pending.ok) {
|
|
55
|
+
throw new BranchPrepareError("Unable to prepare project dependencies.");
|
|
56
|
+
}
|
|
57
|
+
if (pending.value.status === "failed") {
|
|
58
|
+
throw new BranchPrepareError("Dependency preparation failed; the development server was not started.");
|
|
59
|
+
}
|
|
60
|
+
if (pending.value.status === "prepared") {
|
|
61
|
+
console.log("Pending project dependencies prepared.");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const githubCli = dependencies.githubCli ??
|
|
65
|
+
(dependencies.createGitHubCli?.({ hostname }) ??
|
|
66
|
+
new GitHubCliClient({ hostname }));
|
|
34
67
|
let identity;
|
|
35
68
|
try {
|
|
36
69
|
identity = await githubCli.getUser();
|
|
@@ -43,30 +76,46 @@ export async function runBranchPrepare(options, dependencies) {
|
|
|
43
76
|
}
|
|
44
77
|
throw new BranchPrepareError("Unable to resolve GitHub CLI identity.");
|
|
45
78
|
}
|
|
46
|
-
const lifecycle = dependencies.lifecycle ??
|
|
47
|
-
new LocalPrototypeLifecycle({
|
|
48
|
-
repositoryRoot: root,
|
|
49
|
-
primaryBranch: environment.BF_PROTOTYPE_BASE_BRANCH,
|
|
50
|
-
automaticBranchSwitch: mode,
|
|
51
|
-
gitMode,
|
|
52
|
-
});
|
|
53
79
|
const result = await lifecycle.prepareBranch(identity);
|
|
54
80
|
if (!result.ok) {
|
|
55
81
|
throw new BranchPrepareError(`Branch preparation failed with ${result.error.code}.`);
|
|
56
82
|
}
|
|
57
83
|
if (result.value.status === "deferred") {
|
|
58
|
-
console.log(`Branch preparation deferred; repository attention: ${result.value.reason
|
|
84
|
+
console.log(`Branch preparation deferred; repository attention: ${result.value.reason}.`);
|
|
85
|
+
// A dirty/offline check that made no changes is safe to leave for the
|
|
86
|
+
// existing environment. Never launch after a partially applied update.
|
|
87
|
+
if (result.value.effects.changed ||
|
|
88
|
+
result.value.effects.pushed ||
|
|
89
|
+
result.value.effects.reconciledPaths.length > 0 ||
|
|
90
|
+
(result.value.effects.platformPaths?.length ?? 0) > 0 ||
|
|
91
|
+
(result.value.effects.dependencyPaths?.length ?? 0) > 0 ||
|
|
92
|
+
result.value.effects.preparationRequired === true ||
|
|
93
|
+
result.value.effects.restartRequired) {
|
|
94
|
+
throw new BranchPrepareError("Branch preparation was only partially completed; the development server was not started.");
|
|
95
|
+
}
|
|
59
96
|
return 0;
|
|
60
97
|
}
|
|
61
98
|
if (result.value.status === "unsafe") {
|
|
62
|
-
|
|
99
|
+
throw new BranchPrepareError(`Branch preparation requires repository attention (${result.value.reason}); the development server was not started.`);
|
|
100
|
+
}
|
|
101
|
+
if (result.value.status === "disabled") {
|
|
102
|
+
console.log("Branch preparation skipped; synchronization is disabled by configuration.");
|
|
63
103
|
return 0;
|
|
64
104
|
}
|
|
65
|
-
const
|
|
105
|
+
const dependencyPaths = result.value.effects.dependencyPaths ?? [];
|
|
106
|
+
const managedPathChanged = dependencyPaths.length > 0 ||
|
|
107
|
+
result.value.effects.preparationRequired === true;
|
|
66
108
|
if (managedPathChanged) {
|
|
67
109
|
console.log("Installing updated project dependencies...");
|
|
68
|
-
|
|
69
|
-
|
|
110
|
+
if (prepareDependencies !== undefined) {
|
|
111
|
+
const preparation = await prepareDependencies.call(lifecycle, dependencyPaths, dependencies.installDependencies);
|
|
112
|
+
if (!preparation.ok || preparation.value.status === "failed") {
|
|
113
|
+
throw new BranchPrepareError("Dependency preparation failed; the development server was not started.");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
throw new BranchPrepareError("This lifecycle does not support dependency preparation; the development server was not started.");
|
|
118
|
+
}
|
|
70
119
|
}
|
|
71
120
|
console.log("Branch preparation complete.");
|
|
72
121
|
return 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch-prepare.js","sourceRoot":"","sources":["../src/branch-prepare.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as execFileCallback } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport nextEnv from \"@next/env\";\nimport {\n MANAGED_REPOSITORY_PATHS,\n parseAutomaticBranchSwitchSetting,\n parseGitModeSetting,\n parseHostname,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n GitHubCliClient,\n GitHubCliError,\n LocalPrototypeLifecycle,\n type GitHubCliClientLike,\n type PrototypeLifecycle,\n} from \"@ebay-dt/bonfire-node\";\nimport { resolve } from \"node:path\";\nimport type { BranchPrepareCommandOptions } from \"./command.js\";\n\nconst execFile = promisify(execFileCallback);\n\nexport type CliEnvironmentLoader = (\n root: string,\n) => Readonly<Record<string, string | undefined>>;\n\nexport type BranchPrepareDependencies = {\n environment?: Readonly<Record<string, string | undefined>>;\n loadEnvironment?: CliEnvironmentLoader;\n githubCli?: GitHubCliClientLike;\n lifecycle?: Pick<PrototypeLifecycle, \"prepareBranch\">;\n installDependencies?: (root: string) => Promise<void>;\n};\n\nexport class BranchPrepareError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BranchPrepareError\";\n }\n}\n\nfunction loadEnvironment(root: string) {\n return nextEnv.loadEnvConfig(root, true, undefined, false).combinedEnv;\n}\n\nexport async function runBranchPrepare(\n options: BranchPrepareCommandOptions,\n dependencies: BranchPrepareDependencies,\n): Promise<number> {\n const root = resolve(options.root);\n const environment =\n dependencies.environment ??\n dependencies.loadEnvironment?.(root) ??\n loadEnvironment(root);\n const mode = parseAutomaticBranchSwitchSetting(\n environment.BF_DISABLE_AUTO_BRANCH_SWITCH,\n );\n const gitMode = parseGitModeSetting(environment.BF_GIT_MODE);\n const hostname = parseHostname(options.hostname);\n\n if (gitMode === \"manual\") {\n console.log(\"Git management is in manual mode.\");\n return 0;\n }\n\n if (mode === \"disabled\") {\n console.log(\"Automatic branch switching is disabled.\");\n return 0;\n }\n\n const githubCli = dependencies.githubCli ?? new GitHubCliClient({ hostname });\n let identity;\n try {\n identity = await githubCli.getUser();\n } catch (error) {\n if (\n error instanceof GitHubCliError &&\n (error.reason === \"missing\" || error.reason === \"unauthenticated\")\n ) {\n console.log(\n \"Branch preparation deferred; GitHub CLI authentication is not available.\",\n );\n return 0;\n }\n throw new BranchPrepareError(\"Unable to resolve GitHub CLI identity.\");\n }\n\n const lifecycle =\n dependencies.lifecycle ??\n new LocalPrototypeLifecycle({\n repositoryRoot: root,\n primaryBranch: environment.BF_PROTOTYPE_BASE_BRANCH,\n automaticBranchSwitch: mode,\n gitMode,\n });\n const result = await lifecycle.prepareBranch(identity);\n if (!result.ok) {\n throw new BranchPrepareError(\n `Branch preparation failed with ${result.error.code}.`,\n );\n }\n\n if (result.value.status === \"deferred\") {\n console.log(\n `Branch preparation deferred; repository attention: ${result.value.reason ?? \"unknown\"}.`,\n );\n return 0;\n }\n if (result.value.status === \"unsafe\") {\n console.log(\n `Branch preparation requires repository attention: ${result.value.reason ?? \"unknown\"}.`,\n );\n return 0;\n }\n\n const managedPathChanged = result.value.affectedPaths?.some((path) =>\n MANAGED_REPOSITORY_PATHS.some((managedPath) => managedPath === path),\n );\n if (managedPathChanged) {\n console.log(\"Installing updated project dependencies...\");\n await (dependencies.installDependencies?.(root) ??\n execFile(\"pnpm\", [\"install\"], { cwd: root }).then(() => undefined));\n }\n\n console.log(\"Branch preparation complete.\");\n return 0;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"branch-prepare.js","sourceRoot":"","sources":["../src/branch-prepare.ts"],"names":[],"mappings":"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","sourcesContent":["import nextEnv from \"@next/env\";\nimport {\n parseAutomaticBranchSwitchSetting,\n parseGitModeSetting,\n parseHostname,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n GitHubCliClient,\n GitHubCliError,\n LocalPrototypeLifecycle,\n type DependencyInstaller,\n type GitHubCliClientLike,\n type PrototypeLifecycle,\n} from \"@ebay-dt/bonfire-node\";\nimport { resolve } from \"node:path\";\nimport type { BranchPrepareCommandOptions } from \"./command.js\";\n\nexport type CliEnvironmentLoader = (\n root: string,\n) => Readonly<Record<string, string | undefined>>;\n\nexport type BranchPrepareDependencies = {\n environment?: Readonly<Record<string, string | undefined>>;\n loadEnvironment?: CliEnvironmentLoader;\n githubCli?: GitHubCliClientLike;\n createGitHubCli?: (options: { hostname: string }) => GitHubCliClientLike;\n lifecycle?: Pick<PrototypeLifecycle, \"prepareBranch\" | \"prepareDependencies\">;\n installDependencies?: DependencyInstaller;\n};\n\nexport class BranchPrepareError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BranchPrepareError\";\n }\n}\n\nfunction loadEnvironment(root: string) {\n return nextEnv.loadEnvConfig(root, true, undefined, false).combinedEnv;\n}\n\nexport async function runBranchPrepare(\n options: BranchPrepareCommandOptions,\n dependencies: BranchPrepareDependencies,\n): Promise<number> {\n const root = resolve(options.root);\n const environment =\n dependencies.environment ??\n dependencies.loadEnvironment?.(root) ??\n loadEnvironment(root);\n // This guard must precede marker reads, identity resolution, and all Git\n // collaborators. A direct production invocation must remain read-only even\n // when a previous development install left recovery state behind.\n if (environment.NODE_ENV === \"production\") {\n console.log(\"Branch preparation is disabled in production.\");\n return 0;\n }\n\n const mode = parseAutomaticBranchSwitchSetting(\n environment.BF_DISABLE_AUTO_BRANCH_SWITCH,\n );\n const gitMode = parseGitModeSetting(environment.BF_GIT_MODE);\n\n if (gitMode === \"manual\") {\n console.log(\"Git management is in manual mode.\");\n return 0;\n }\n\n if (mode === \"disabled\") {\n console.log(\"Automatic branch switching is disabled.\");\n return 0;\n }\n\n // Explicit --hostname wins. Generated scripts use --default-hostname so\n // Next-compatible .env.local loading can supply BF_GITHUB_HOSTNAME first.\n const hostname = parseHostname(\n options.hostname ??\n environment.BF_GITHUB_HOSTNAME ??\n options.defaultHostname,\n );\n const lifecycle =\n dependencies.lifecycle ??\n new LocalPrototypeLifecycle({\n repositoryRoot: root,\n prototypeRoot: options.prototypeRoot ?? environment.BF_PROTOTYPE_ROOT,\n remote: options.remote ?? environment.BF_GIT_REMOTE,\n primaryBranch:\n options.primaryBranch ?? environment.BF_PROTOTYPE_BASE_BRANCH,\n automaticBranchSwitch: mode,\n gitMode,\n installDependencies: dependencies.installDependencies,\n });\n const prepareDependencies = lifecycle.prepareDependencies;\n if (prepareDependencies !== undefined) {\n const pending = await prepareDependencies.call(\n lifecycle,\n [],\n dependencies.installDependencies,\n );\n if (!pending.ok) {\n throw new BranchPrepareError(\"Unable to prepare project dependencies.\");\n }\n if (pending.value.status === \"failed\") {\n throw new BranchPrepareError(\n \"Dependency preparation failed; the development server was not started.\",\n );\n }\n if (pending.value.status === \"prepared\") {\n console.log(\"Pending project dependencies prepared.\");\n }\n }\n\n const githubCli =\n dependencies.githubCli ??\n (dependencies.createGitHubCli?.({ hostname }) ??\n new GitHubCliClient({ hostname }));\n let identity;\n try {\n identity = await githubCli.getUser();\n } catch (error) {\n if (\n error instanceof GitHubCliError &&\n (error.reason === \"missing\" || error.reason === \"unauthenticated\")\n ) {\n console.log(\n \"Branch preparation deferred; GitHub CLI authentication is not available.\",\n );\n return 0;\n }\n throw new BranchPrepareError(\"Unable to resolve GitHub CLI identity.\");\n }\n\n const result = await lifecycle.prepareBranch(identity);\n if (!result.ok) {\n throw new BranchPrepareError(\n `Branch preparation failed with ${result.error.code}.`,\n );\n }\n\n if (result.value.status === \"deferred\") {\n console.log(\n `Branch preparation deferred; repository attention: ${result.value.reason}.`,\n );\n // A dirty/offline check that made no changes is safe to leave for the\n // existing environment. Never launch after a partially applied update.\n if (\n result.value.effects.changed ||\n result.value.effects.pushed ||\n result.value.effects.reconciledPaths.length > 0 ||\n (result.value.effects.platformPaths?.length ?? 0) > 0 ||\n (result.value.effects.dependencyPaths?.length ?? 0) > 0 ||\n result.value.effects.preparationRequired === true ||\n result.value.effects.restartRequired\n ) {\n throw new BranchPrepareError(\n \"Branch preparation was only partially completed; the development server was not started.\",\n );\n }\n return 0;\n }\n if (result.value.status === \"unsafe\") {\n throw new BranchPrepareError(\n `Branch preparation requires repository attention (${result.value.reason}); the development server was not started.`,\n );\n }\n if (result.value.status === \"disabled\") {\n console.log(\n \"Branch preparation skipped; synchronization is disabled by configuration.\",\n );\n return 0;\n }\n\n const dependencyPaths = result.value.effects.dependencyPaths ?? [];\n const managedPathChanged =\n dependencyPaths.length > 0 ||\n result.value.effects.preparationRequired === true;\n if (managedPathChanged) {\n console.log(\"Installing updated project dependencies...\");\n if (prepareDependencies !== undefined) {\n const preparation = await prepareDependencies.call(\n lifecycle,\n dependencyPaths,\n dependencies.installDependencies,\n );\n if (!preparation.ok || preparation.value.status === \"failed\") {\n throw new BranchPrepareError(\n \"Dependency preparation failed; the development server was not started.\",\n );\n }\n } else {\n throw new BranchPrepareError(\n \"This lifecycle does not support dependency preparation; the development server was not started.\",\n );\n }\n }\n\n console.log(\"Branch preparation complete.\");\n return 0;\n}\n"]}
|
package/dist/command.d.ts
CHANGED
|
@@ -9,7 +9,11 @@ export type PrepareCommandOptions = {
|
|
|
9
9
|
};
|
|
10
10
|
export type BranchPrepareCommandOptions = {
|
|
11
11
|
root: string;
|
|
12
|
-
hostname
|
|
12
|
+
hostname?: string;
|
|
13
|
+
defaultHostname?: string;
|
|
14
|
+
prototypeRoot?: string;
|
|
15
|
+
remote?: string;
|
|
16
|
+
primaryBranch?: string;
|
|
13
17
|
};
|
|
14
18
|
export type ContextCommandOptions = {
|
|
15
19
|
context: "sync";
|
package/dist/command.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAE3B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAEtB,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B;IACE,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEN,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5E,KAAK,iBAAiB,GAClB,qBAAqB,GACrB,2BAA2B,GAC3B,qBAAqB,GACrB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,eAAe,GAAG,yBAAyB,GAAG;IACxD,cAAc,CAAC,EAAE,CACf,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnC,mBAAmB,CAAC,EAAE,CACpB,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,yBAAyB,CAAC,CAAC;CACzC,CAAC;AAiPF,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CAUpE;AA+ED,wBAAsB,GAAG,CACvB,IAAI,GAAE,SAAS,MAAM,EAA0B,EAC/C,YAAY,GAAE,eAAoB,GACjC,OAAO,CAAC,MAAM,CAAC,CA4DjB","sourcesContent":["import {\n checkContext,\n checkContextInstallation,\n installContext,\n syncContext,\n type ContextInstallCheckResult,\n type ContextInstallResult,\n type ContextInstallOptions,\n type ContextSyncResult,\n} from \"@ebay-dt/bonfire-context\";\nimport { prepare, PrepareError } from \"./prepare.js\";\nimport {\n BranchPrepareError,\n runBranchPrepare,\n type BranchPrepareDependencies,\n} from \"./branch-prepare.js\";\nimport {\n convert,\n convertDefaults,\n defaultConvertOptions,\n humanizeAppId,\n type ConvertOptions,\n} from \"./convert.js\";\n\nexport class CliSyntaxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CliSyntaxError\";\n }\n}\n\nexport type PrepareCommandOptions = {\n root: string;\n};\n\nexport type BranchPrepareCommandOptions = {\n root: string;\n hostname: string;\n};\n\nexport type ContextCommandOptions =\n | {\n context: \"sync\";\n root: string;\n check: boolean;\n }\n | {\n context: \"install\";\n root: string;\n appId: string;\n check: boolean;\n };\n\nexport type ConvertCommandOptions = ConvertOptions & { command: \"convert\" };\n\ntype CliCommandOptions =\n | PrepareCommandOptions\n | BranchPrepareCommandOptions\n | ContextCommandOptions\n | ConvertCommandOptions;\n\nexport type CliDependencies = BranchPrepareDependencies & {\n contextInstall?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallResult>;\n contextInstallCheck?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallCheckResult>;\n};\n\nfunction parseRootOption(\n argv: readonly string[],\n start: number,\n): { root: string; nextIndex: number } {\n const value = argv[start + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --root option requires a value\");\n }\n return { root: value, nextIndex: start + 2 };\n}\n\nfunction parsePrepareArgs(argv: readonly string[]): PrepareCommandOptions {\n let root = process.cwd();\n let rootProvided = false;\n for (let index = 1; index < argv.length;) {\n if (argv[index] !== \"--root\") {\n throw new CliSyntaxError(`Unknown option: ${argv[index]}`);\n }\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n }\n return { root };\n}\n\nfunction parseContextArgs(argv: readonly string[]): ContextCommandOptions {\n const context = argv[1];\n if (context !== \"sync\" && context !== \"install\") {\n throw new CliSyntaxError(\n \"Usage: bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n\n let root = process.cwd();\n let appId: string | undefined;\n let check = false;\n let rootProvided = false;\n let appIdProvided = false;\n let checkProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--check\") {\n if (checkProvided) {\n throw new CliSyntaxError(\n \"The --check option may only be provided once\",\n );\n }\n check = true;\n checkProvided = true;\n index += 1;\n continue;\n }\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (option === \"--app-id\") {\n if (appIdProvided) {\n throw new CliSyntaxError(\n \"The --app-id option may only be provided once\",\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --app-id option requires a value\");\n }\n appId = value;\n appIdProvided = true;\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n if (context === \"install\") {\n if (appId === undefined) {\n throw new CliSyntaxError(\n \"Usage: bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n return { context, root, appId, check };\n }\n if (appId !== undefined) {\n throw new CliSyntaxError(\"The --app-id option is only valid for install\");\n }\n return { context, root, check };\n}\n\nfunction parseConvertArgs(argv: readonly string[]): ConvertCommandOptions {\n const defaults = defaultConvertOptions();\n let root: string | undefined;\n let appId: string | undefined;\n let name: string | undefined;\n let packageName = defaults.packageName;\n let hostname = convertDefaults.hostname;\n let port = convertDefaults.port;\n let deploymentEndpoint = convertDefaults.deploymentEndpoint;\n let withoutData = false;\n let dryRun = false;\n let skipInstall = false;\n const seen = new Set<string>();\n\n for (let index = 1; index < argv.length;) {\n const option = argv[index];\n if (!option) throw new CliSyntaxError(\"Missing convert option\");\n if (\n option === \"--without-data\" ||\n option === \"--dry-run\" ||\n option === \"--skip-install\"\n ) {\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n seen.add(option);\n if (option === \"--without-data\") withoutData = true;\n if (option === \"--dry-run\") dryRun = true;\n if (option === \"--skip-install\") skipInstall = true;\n index += 1;\n continue;\n }\n const setters: Record<string, (value: string) => void> = {\n \"--root\": (value) => {\n root = value;\n },\n \"--app-id\": (value) => {\n appId = value;\n },\n \"--name\": (value) => {\n name = value;\n },\n \"--package-name\": (value) => {\n packageName = value;\n },\n \"--hostname\": (value) => {\n hostname = value;\n },\n \"--deployment-endpoint\": (value) => {\n deploymentEndpoint = value;\n },\n \"--port\": (value) => {\n if (\n !/^\\d+$/u.test(value) ||\n Number(value) < 1 ||\n Number(value) > 65535\n ) {\n throw new CliSyntaxError(\n \"--port must be a number between 1 and 65535\",\n );\n }\n port = Number(value);\n },\n };\n const setter = setters[option];\n if (!setter) throw new CliSyntaxError(`Unknown option: ${option}`);\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\"))\n throw new CliSyntaxError(`${option} requires a value`);\n seen.add(option);\n setter(value);\n index += 2;\n }\n if (!root || !appId) {\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [--name <display-name>] [--hostname <hostname>] [--port <port>] [--without-data] [--dry-run] [--skip-install]\",\n );\n }\n return {\n command: \"convert\",\n root,\n appId,\n name: name ?? humanizeAppId(appId),\n packageName,\n hostname,\n port,\n deploymentEndpoint,\n withItemData: !withoutData,\n dryRun,\n skipInstall,\n };\n}\n\nfunction parseBranchPrepareArgs(\n argv: readonly string[],\n): BranchPrepareCommandOptions {\n let root = process.cwd();\n let hostname: string | undefined;\n let rootProvided = false;\n let hostnameProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (option === \"--hostname\") {\n if (hostnameProvided) {\n throw new CliSyntaxError(\n \"The --hostname option may only be provided once\",\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --hostname option requires a value\");\n }\n hostname = value;\n hostnameProvided = true;\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n if (hostname === undefined) {\n throw new CliSyntaxError(\n \"Usage: bonfire branch prepare --root <application-root> --hostname <hostname>\",\n );\n }\n return { root, hostname };\n}\n\nexport function parseArgs(argv: readonly string[]): CliCommandOptions {\n if (argv[0] === \"convert\") return parseConvertArgs(argv);\n if (argv[0] === \"context\") return parseContextArgs(argv);\n if (argv[0] === \"prepare\") return parsePrepareArgs(argv);\n if (argv[0] === \"branch\" && argv[1] === \"prepare\") {\n return parseBranchPrepareArgs(argv);\n }\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [options] | bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>] | bonfire prepare [--root <application-root>] | bonfire branch prepare --root <application-root> --hostname <hostname>\",\n );\n}\n\nfunction printContextIssues(result: {\n issues: readonly { kind: string; path: string }[];\n}) {\n for (const issue of result.issues) {\n console.error(`- ${issue.kind}: ${issue.path}`);\n }\n}\n\nfunction printContextSyncSummary(result: ContextSyncResult) {\n if (result.written.length > 0) {\n console.log(`Written: ${result.written.join(\", \")}`);\n }\n if (result.removed.length > 0) {\n console.log(`Removed: ${result.removed.join(\", \")}`);\n }\n}\n\nasync function runContextCommand(\n options: ContextCommandOptions,\n dependencies: CliDependencies,\n): Promise<number> {\n if (options.context === \"install\") {\n if (options.check) {\n const result = await (\n dependencies.contextInstallCheck ?? checkContextInstallation\n )({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n if (!result.ok) {\n console.error(\"Context install check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context install check passed.\");\n return 0;\n }\n const result = await (dependencies.contextInstall ?? installContext)({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n const skills = result.skills.map(\n (skill) => `${skill.name} (${skill.status})`,\n );\n const mcp = result.mcp.map((server) => `${server.name} (${server.status})`);\n console.log(\n skills.length > 0\n ? `Context skills: ${skills.join(\", \")}`\n : \"No context skills configured.\",\n );\n if (mcp.length > 0) console.log(`Context MCP: ${mcp.join(\", \")}`);\n console.log(\"Context install complete.\");\n return 0;\n }\n\n if (options.check) {\n const result = await checkContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context sync check passed.\");\n return 0;\n }\n\n const result = await syncContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync failed:\");\n printContextIssues(result);\n return 1;\n }\n printContextSyncSummary(result);\n console.log(\"Context sync complete.\");\n return 0;\n}\n\nexport async function run(\n argv: readonly string[] = process.argv.slice(2),\n dependencies: CliDependencies = {},\n): Promise<number> {\n const isBranchPrepare = argv[0] === \"branch\";\n const isContext = argv[0] === \"context\";\n const isConvert = argv[0] === \"convert\";\n try {\n const options = parseArgs(argv);\n if (\"context\" in options) {\n return await runContextCommand(options, dependencies);\n }\n if (isConvert && \"command\" in options) {\n await convert(options);\n return 0;\n }\n if (\"hostname\" in options) {\n return await runBranchPrepare(options, dependencies);\n }\n\n const result = await prepare(options);\n const descriptions = {\n environment: \"the process environment\",\n existing: \".env.local\",\n generated: \"a newly generated value in .env.local\",\n } as const;\n console.log(\n `Bonfire preparation complete; BF_SESSION_SECRET came from ${descriptions[result.source]}.`,\n );\n return 0;\n } catch (error) {\n if (error instanceof CliSyntaxError) {\n console.error(`bonfire: ${error.message}`);\n return 2;\n }\n if (isContext) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire context failed: ${message}`);\n return 1;\n }\n if (isBranchPrepare) {\n const message =\n error instanceof BranchPrepareError\n ? error.message\n : \"Unable to load branch preparation configuration.\";\n console.error(`bonfire branch prepare failed: ${message}`);\n return 1;\n }\n if (isConvert) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire convert failed: ${message}`);\n return 1;\n }\n\n const message =\n error instanceof PrepareError || error instanceof Error\n ? error.message\n : \"an unknown error occurred\";\n console.error(`bonfire prepare failed: ${message}`);\n return 1;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAE3B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,KAAK,yBAAyB,EAC/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAEtB,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B;IACE,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,GACD;IACE,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEN,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5E,KAAK,iBAAiB,GAClB,qBAAqB,GACrB,2BAA2B,GAC3B,qBAAqB,GACrB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,eAAe,GAAG,yBAAyB,GAAG;IACxD,cAAc,CAAC,EAAE,CACf,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnC,mBAAmB,CAAC,EAAE,CACpB,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,yBAAyB,CAAC,CAAC;CACzC,CAAC;AA6RF,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CAUpE;AA+ED,wBAAsB,GAAG,CACvB,IAAI,GAAE,SAAS,MAAM,EAA0B,EAC/C,YAAY,GAAE,eAAoB,GACjC,OAAO,CAAC,MAAM,CAAC,CA+DjB","sourcesContent":["import {\n checkContext,\n checkContextInstallation,\n installContext,\n syncContext,\n type ContextInstallCheckResult,\n type ContextInstallResult,\n type ContextInstallOptions,\n type ContextSyncResult,\n} from \"@ebay-dt/bonfire-context\";\nimport { prepare, PrepareError } from \"./prepare.js\";\nimport {\n BranchPrepareError,\n runBranchPrepare,\n type BranchPrepareDependencies,\n} from \"./branch-prepare.js\";\nimport {\n convert,\n convertDefaults,\n defaultConvertOptions,\n humanizeAppId,\n type ConvertOptions,\n} from \"./convert.js\";\n\nexport class CliSyntaxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CliSyntaxError\";\n }\n}\n\nexport type PrepareCommandOptions = {\n root: string;\n};\n\nexport type BranchPrepareCommandOptions = {\n root: string;\n hostname?: string;\n defaultHostname?: string;\n prototypeRoot?: string;\n remote?: string;\n primaryBranch?: string;\n};\n\nexport type ContextCommandOptions =\n | {\n context: \"sync\";\n root: string;\n check: boolean;\n }\n | {\n context: \"install\";\n root: string;\n appId: string;\n check: boolean;\n };\n\nexport type ConvertCommandOptions = ConvertOptions & { command: \"convert\" };\n\ntype CliCommandOptions =\n | PrepareCommandOptions\n | BranchPrepareCommandOptions\n | ContextCommandOptions\n | ConvertCommandOptions;\n\nexport type CliDependencies = BranchPrepareDependencies & {\n contextInstall?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallResult>;\n contextInstallCheck?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallCheckResult>;\n};\n\nfunction parseRootOption(\n argv: readonly string[],\n start: number,\n): { root: string; nextIndex: number } {\n const value = argv[start + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --root option requires a value\");\n }\n return { root: value, nextIndex: start + 2 };\n}\n\nfunction parsePrepareArgs(argv: readonly string[]): PrepareCommandOptions {\n let root = process.cwd();\n let rootProvided = false;\n for (let index = 1; index < argv.length;) {\n if (argv[index] !== \"--root\") {\n throw new CliSyntaxError(`Unknown option: ${argv[index]}`);\n }\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n }\n return { root };\n}\n\nfunction parseContextArgs(argv: readonly string[]): ContextCommandOptions {\n const context = argv[1];\n if (context !== \"sync\" && context !== \"install\") {\n throw new CliSyntaxError(\n \"Usage: bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n\n let root = process.cwd();\n let appId: string | undefined;\n let check = false;\n let rootProvided = false;\n let appIdProvided = false;\n let checkProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--check\") {\n if (checkProvided) {\n throw new CliSyntaxError(\n \"The --check option may only be provided once\",\n );\n }\n check = true;\n checkProvided = true;\n index += 1;\n continue;\n }\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (option === \"--app-id\") {\n if (appIdProvided) {\n throw new CliSyntaxError(\n \"The --app-id option may only be provided once\",\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --app-id option requires a value\");\n }\n appId = value;\n appIdProvided = true;\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n if (context === \"install\") {\n if (appId === undefined) {\n throw new CliSyntaxError(\n \"Usage: bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n return { context, root, appId, check };\n }\n if (appId !== undefined) {\n throw new CliSyntaxError(\"The --app-id option is only valid for install\");\n }\n return { context, root, check };\n}\n\nfunction parseConvertArgs(argv: readonly string[]): ConvertCommandOptions {\n const defaults = defaultConvertOptions();\n let root: string | undefined;\n let appId: string | undefined;\n let name: string | undefined;\n let packageName = defaults.packageName;\n let hostname = convertDefaults.hostname;\n let port = convertDefaults.port;\n let deploymentEndpoint = convertDefaults.deploymentEndpoint;\n let withoutData = false;\n let dryRun = false;\n let skipInstall = false;\n const seen = new Set<string>();\n\n for (let index = 1; index < argv.length;) {\n const option = argv[index];\n if (!option) throw new CliSyntaxError(\"Missing convert option\");\n if (\n option === \"--without-data\" ||\n option === \"--dry-run\" ||\n option === \"--skip-install\"\n ) {\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n seen.add(option);\n if (option === \"--without-data\") withoutData = true;\n if (option === \"--dry-run\") dryRun = true;\n if (option === \"--skip-install\") skipInstall = true;\n index += 1;\n continue;\n }\n const setters: Record<string, (value: string) => void> = {\n \"--root\": (value) => {\n root = value;\n },\n \"--app-id\": (value) => {\n appId = value;\n },\n \"--name\": (value) => {\n name = value;\n },\n \"--package-name\": (value) => {\n packageName = value;\n },\n \"--hostname\": (value) => {\n hostname = value;\n },\n \"--deployment-endpoint\": (value) => {\n deploymentEndpoint = value;\n },\n \"--port\": (value) => {\n if (\n !/^\\d+$/u.test(value) ||\n Number(value) < 1 ||\n Number(value) > 65535\n ) {\n throw new CliSyntaxError(\n \"--port must be a number between 1 and 65535\",\n );\n }\n port = Number(value);\n },\n };\n const setter = setters[option];\n if (!setter) throw new CliSyntaxError(`Unknown option: ${option}`);\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\"))\n throw new CliSyntaxError(`${option} requires a value`);\n seen.add(option);\n setter(value);\n index += 2;\n }\n if (!root || !appId) {\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [--name <display-name>] [--hostname <hostname>] [--port <port>] [--without-data] [--dry-run] [--skip-install]\",\n );\n }\n return {\n command: \"convert\",\n root,\n appId,\n name: name ?? humanizeAppId(appId),\n packageName,\n hostname,\n port,\n deploymentEndpoint,\n withItemData: !withoutData,\n dryRun,\n skipInstall,\n };\n}\n\nfunction parseBranchPrepareArgs(\n argv: readonly string[],\n): BranchPrepareCommandOptions {\n let root = process.cwd();\n let hostname: string | undefined;\n let defaultHostname: string | undefined;\n let prototypeRoot: string | undefined;\n let remote: string | undefined;\n let primaryBranch: string | undefined;\n let rootProvided = false;\n let hostnameProvided = false;\n let defaultHostnameProvided = false;\n let prototypeRootProvided = false;\n let remoteProvided = false;\n let primaryBranchProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (\n option === \"--prototype-root\" ||\n option === \"--remote\" ||\n option === \"--primary\"\n ) {\n const provided =\n option === \"--prototype-root\"\n ? prototypeRootProvided\n : option === \"--remote\"\n ? remoteProvided\n : primaryBranchProvided;\n if (provided) {\n throw new CliSyntaxError(`${option} may only be provided once`);\n }\n if (option === \"--prototype-root\") prototypeRootProvided = true;\n if (option === \"--remote\") remoteProvided = true;\n if (option === \"--primary\") primaryBranchProvided = true;\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(`${option} requires a value`);\n }\n if (option === \"--prototype-root\") prototypeRoot = value;\n if (option === \"--remote\") remote = value;\n if (option === \"--primary\") primaryBranch = value;\n index += 2;\n continue;\n }\n if (option === \"--hostname\" || option === \"--default-hostname\") {\n const isDefault = option === \"--default-hostname\";\n const provided = isDefault ? defaultHostnameProvided : hostnameProvided;\n if (provided) {\n throw new CliSyntaxError(\n `The ${option} option may only be provided once`,\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(`The ${option} option requires a value`);\n }\n if (isDefault) {\n defaultHostname = value;\n defaultHostnameProvided = true;\n } else {\n hostname = value;\n hostnameProvided = true;\n }\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n return {\n root,\n ...(hostname === undefined ? {} : { hostname }),\n ...(defaultHostname === undefined ? {} : { defaultHostname }),\n ...(prototypeRoot === undefined ? {} : { prototypeRoot }),\n ...(remote === undefined ? {} : { remote }),\n ...(primaryBranch === undefined ? {} : { primaryBranch }),\n };\n}\n\nexport function parseArgs(argv: readonly string[]): CliCommandOptions {\n if (argv[0] === \"convert\") return parseConvertArgs(argv);\n if (argv[0] === \"context\") return parseContextArgs(argv);\n if (argv[0] === \"prepare\") return parsePrepareArgs(argv);\n if (argv[0] === \"branch\" && argv[1] === \"prepare\") {\n return parseBranchPrepareArgs(argv);\n }\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [options] | bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>] | bonfire prepare [--root <application-root>] | bonfire branch prepare --root <application-root> [--hostname <hostname>] [--default-hostname <hostname>] [--prototype-root <root>] [--remote <name>] [--primary <branch>]\",\n );\n}\n\nfunction printContextIssues(result: {\n issues: readonly { kind: string; path: string }[];\n}) {\n for (const issue of result.issues) {\n console.error(`- ${issue.kind}: ${issue.path}`);\n }\n}\n\nfunction printContextSyncSummary(result: ContextSyncResult) {\n if (result.written.length > 0) {\n console.log(`Written: ${result.written.join(\", \")}`);\n }\n if (result.removed.length > 0) {\n console.log(`Removed: ${result.removed.join(\", \")}`);\n }\n}\n\nasync function runContextCommand(\n options: ContextCommandOptions,\n dependencies: CliDependencies,\n): Promise<number> {\n if (options.context === \"install\") {\n if (options.check) {\n const result = await (\n dependencies.contextInstallCheck ?? checkContextInstallation\n )({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n if (!result.ok) {\n console.error(\"Context install check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context install check passed.\");\n return 0;\n }\n const result = await (dependencies.contextInstall ?? installContext)({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n const skills = result.skills.map(\n (skill) => `${skill.name} (${skill.status})`,\n );\n const mcp = result.mcp.map((server) => `${server.name} (${server.status})`);\n console.log(\n skills.length > 0\n ? `Context skills: ${skills.join(\", \")}`\n : \"No context skills configured.\",\n );\n if (mcp.length > 0) console.log(`Context MCP: ${mcp.join(\", \")}`);\n console.log(\"Context install complete.\");\n return 0;\n }\n\n if (options.check) {\n const result = await checkContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context sync check passed.\");\n return 0;\n }\n\n const result = await syncContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync failed:\");\n printContextIssues(result);\n return 1;\n }\n printContextSyncSummary(result);\n console.log(\"Context sync complete.\");\n return 0;\n}\n\nexport async function run(\n argv: readonly string[] = process.argv.slice(2),\n dependencies: CliDependencies = {},\n): Promise<number> {\n const isBranchPrepare = argv[0] === \"branch\";\n const isContext = argv[0] === \"context\";\n const isConvert = argv[0] === \"convert\";\n try {\n const options = parseArgs(argv);\n if (\"context\" in options) {\n return await runContextCommand(options, dependencies);\n }\n if (isConvert && \"command\" in options) {\n await convert(options);\n return 0;\n }\n if (isBranchPrepare) {\n return await runBranchPrepare(\n options as BranchPrepareCommandOptions,\n dependencies,\n );\n }\n\n const result = await prepare(options as PrepareCommandOptions);\n const descriptions = {\n environment: \"the process environment\",\n existing: \".env.local\",\n generated: \"a newly generated value in .env.local\",\n } as const;\n console.log(\n `Bonfire preparation complete; BF_SESSION_SECRET came from ${descriptions[result.source]}.`,\n );\n return 0;\n } catch (error) {\n if (error instanceof CliSyntaxError) {\n console.error(`bonfire: ${error.message}`);\n return 2;\n }\n if (isContext) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire context failed: ${message}`);\n return 1;\n }\n if (isBranchPrepare) {\n const message =\n error instanceof BranchPrepareError\n ? error.message\n : \"Unable to load branch preparation configuration.\";\n console.error(`bonfire branch prepare failed: ${message}`);\n return 1;\n }\n if (isConvert) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire convert failed: ${message}`);\n return 1;\n }\n\n const message =\n error instanceof PrepareError || error instanceof Error\n ? error.message\n : \"an unknown error occurred\";\n console.error(`bonfire prepare failed: ${message}`);\n return 1;\n }\n}\n"]}
|
package/dist/command.js
CHANGED
|
@@ -182,8 +182,16 @@ function parseConvertArgs(argv) {
|
|
|
182
182
|
function parseBranchPrepareArgs(argv) {
|
|
183
183
|
let root = process.cwd();
|
|
184
184
|
let hostname;
|
|
185
|
+
let defaultHostname;
|
|
186
|
+
let prototypeRoot;
|
|
187
|
+
let remote;
|
|
188
|
+
let primaryBranch;
|
|
185
189
|
let rootProvided = false;
|
|
186
190
|
let hostnameProvided = false;
|
|
191
|
+
let defaultHostnameProvided = false;
|
|
192
|
+
let prototypeRootProvided = false;
|
|
193
|
+
let remoteProvided = false;
|
|
194
|
+
let primaryBranchProvided = false;
|
|
187
195
|
for (let index = 2; index < argv.length;) {
|
|
188
196
|
const option = argv[index];
|
|
189
197
|
if (option === "--root") {
|
|
@@ -196,25 +204,67 @@ function parseBranchPrepareArgs(argv) {
|
|
|
196
204
|
index = parsed.nextIndex;
|
|
197
205
|
continue;
|
|
198
206
|
}
|
|
199
|
-
if (option === "--
|
|
200
|
-
|
|
201
|
-
|
|
207
|
+
if (option === "--prototype-root" ||
|
|
208
|
+
option === "--remote" ||
|
|
209
|
+
option === "--primary") {
|
|
210
|
+
const provided = option === "--prototype-root"
|
|
211
|
+
? prototypeRootProvided
|
|
212
|
+
: option === "--remote"
|
|
213
|
+
? remoteProvided
|
|
214
|
+
: primaryBranchProvided;
|
|
215
|
+
if (provided) {
|
|
216
|
+
throw new CliSyntaxError(`${option} may only be provided once`);
|
|
217
|
+
}
|
|
218
|
+
if (option === "--prototype-root")
|
|
219
|
+
prototypeRootProvided = true;
|
|
220
|
+
if (option === "--remote")
|
|
221
|
+
remoteProvided = true;
|
|
222
|
+
if (option === "--primary")
|
|
223
|
+
primaryBranchProvided = true;
|
|
224
|
+
const value = argv[index + 1];
|
|
225
|
+
if (!value || value.startsWith("--")) {
|
|
226
|
+
throw new CliSyntaxError(`${option} requires a value`);
|
|
227
|
+
}
|
|
228
|
+
if (option === "--prototype-root")
|
|
229
|
+
prototypeRoot = value;
|
|
230
|
+
if (option === "--remote")
|
|
231
|
+
remote = value;
|
|
232
|
+
if (option === "--primary")
|
|
233
|
+
primaryBranch = value;
|
|
234
|
+
index += 2;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (option === "--hostname" || option === "--default-hostname") {
|
|
238
|
+
const isDefault = option === "--default-hostname";
|
|
239
|
+
const provided = isDefault ? defaultHostnameProvided : hostnameProvided;
|
|
240
|
+
if (provided) {
|
|
241
|
+
throw new CliSyntaxError(`The ${option} option may only be provided once`);
|
|
202
242
|
}
|
|
203
243
|
const value = argv[index + 1];
|
|
204
244
|
if (!value || value.startsWith("--")) {
|
|
205
|
-
throw new CliSyntaxError(
|
|
245
|
+
throw new CliSyntaxError(`The ${option} option requires a value`);
|
|
246
|
+
}
|
|
247
|
+
if (isDefault) {
|
|
248
|
+
defaultHostname = value;
|
|
249
|
+
defaultHostnameProvided = true;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
hostname = value;
|
|
253
|
+
hostnameProvided = true;
|
|
206
254
|
}
|
|
207
|
-
hostname = value;
|
|
208
|
-
hostnameProvided = true;
|
|
209
255
|
index += 2;
|
|
210
256
|
continue;
|
|
211
257
|
}
|
|
212
258
|
throw new CliSyntaxError(`Unknown option: ${option}`);
|
|
213
259
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
260
|
+
return {
|
|
261
|
+
root,
|
|
262
|
+
...(hostname === undefined ? {} : { hostname }),
|
|
263
|
+
...(defaultHostname === undefined ? {} : { defaultHostname }),
|
|
264
|
+
...(prototypeRoot === undefined ? {} : { prototypeRoot }),
|
|
265
|
+
...(remote === undefined ? {} : { remote }),
|
|
266
|
+
...(primaryBranch === undefined ? {} : { primaryBranch }),
|
|
267
|
+
};
|
|
218
268
|
}
|
|
219
269
|
export function parseArgs(argv) {
|
|
220
270
|
if (argv[0] === "convert")
|
|
@@ -226,7 +276,7 @@ export function parseArgs(argv) {
|
|
|
226
276
|
if (argv[0] === "branch" && argv[1] === "prepare") {
|
|
227
277
|
return parseBranchPrepareArgs(argv);
|
|
228
278
|
}
|
|
229
|
-
throw new CliSyntaxError("Usage: bonfire convert --root <next-app> --app-id <app-id> [options] | bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>] | bonfire prepare [--root <application-root>] | bonfire branch prepare --root <application-root> --hostname <hostname>");
|
|
279
|
+
throw new CliSyntaxError("Usage: bonfire convert --root <next-app> --app-id <app-id> [options] | bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>] | bonfire prepare [--root <application-root>] | bonfire branch prepare --root <application-root> [--hostname <hostname>] [--default-hostname <hostname>] [--prototype-root <root>] [--remote <name>] [--primary <branch>]");
|
|
230
280
|
}
|
|
231
281
|
function printContextIssues(result) {
|
|
232
282
|
for (const issue of result.issues) {
|
|
@@ -303,7 +353,7 @@ export async function run(argv = process.argv.slice(2), dependencies = {}) {
|
|
|
303
353
|
await convert(options);
|
|
304
354
|
return 0;
|
|
305
355
|
}
|
|
306
|
-
if (
|
|
356
|
+
if (isBranchPrepare) {
|
|
307
357
|
return await runBranchPrepare(options, dependencies);
|
|
308
358
|
}
|
|
309
359
|
const result = await prepare(options);
|
package/dist/command.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,cAAc,EACd,WAAW,GAKZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,aAAa,GAEd,MAAM,cAAc,CAAC;AAEtB,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAyCD,SAAS,eAAe,CACtB,IAAuB,EACvB,KAAa;IAEb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,cAAc,CAAC,oCAAoC,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAuB;IAC/C,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;QACzC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,cAAc,CAAC,mBAAmB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,IAAI,cAAc,CAAC,6CAA6C,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACnB,YAAY,GAAG,IAAI,CAAC;QACpB,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAuB;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAChD,MAAM,IAAI,cAAc,CACtB,6HAA6H,CAC9H,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,KAAyB,CAAC;IAC9B,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,IAAI,cAAc,CACtB,8CAA8C,CAC/C,CAAC;YACJ,CAAC;YACD,KAAK,GAAG,IAAI,CAAC;YACb,aAAa,GAAG,IAAI,CAAC;YACrB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,IAAI,cAAc,CAAC,6CAA6C,CAAC,CAAC;YAC1E,CAAC;YACD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC5C,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,YAAY,GAAG,IAAI,CAAC;YACpB,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;YACzB,SAAS;QACX,CAAC;QACD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,IAAI,cAAc,CACtB,+CAA+C,CAChD,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,cAAc,CAAC,sCAAsC,CAAC,CAAC;YACnE,CAAC;YACD,KAAK,GAAG,KAAK,CAAC;YACd,aAAa,GAAG,IAAI,CAAC;YACrB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QACD,MAAM,IAAI,cAAc,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,cAAc,CACtB,4EAA4E,CAC7E,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,cAAc,CAAC,+CAA+C,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAuB;IAC/C,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IACzC,IAAI,IAAwB,CAAC;IAC7B,IAAI,KAAyB,CAAC;IAC9B,IAAI,IAAwB,CAAC;IAC7B,IAAI,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;IACvC,IAAI,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC;IACxC,IAAI,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC;IAChC,IAAI,kBAAkB,GAAG,eAAe,CAAC,kBAAkB,CAAC;IAC5D,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,cAAc,CAAC,wBAAwB,CAAC,CAAC;QAChE,IACE,MAAM,KAAK,gBAAgB;YAC3B,MAAM,KAAK,WAAW;YACtB,MAAM,KAAK,gBAAgB,EAC3B,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;gBAClB,MAAM,IAAI,cAAc,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;YAClE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjB,IAAI,MAAM,KAAK,gBAAgB;gBAAE,WAAW,GAAG,IAAI,CAAC;YACpD,IAAI,MAAM,KAAK,WAAW;gBAAE,MAAM,GAAG,IAAI,CAAC;YAC1C,IAAI,MAAM,KAAK,gBAAgB;gBAAE,WAAW,GAAG,IAAI,CAAC;YACpD,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAA4C;YACvD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,IAAI,GAAG,KAAK,CAAC;YACf,CAAC;YACD,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,GAAG,KAAK,CAAC;YAChB,CAAC;YACD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,IAAI,GAAG,KAAK,CAAC;YACf,CAAC;YACD,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,WAAW,GAAG,KAAK,CAAC;YACtB,CAAC;YACD,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;gBACtB,QAAQ,GAAG,KAAK,CAAC;YACnB,CAAC;YACD,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjC,kBAAkB,GAAG,KAAK,CAAC;YAC7B,CAAC;YACD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,IACE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;oBACrB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;oBACjB,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,EACrB,CAAC;oBACD,MAAM,IAAI,cAAc,CACtB,6CAA6C,CAC9C,CAAC;gBACJ,CAAC;gBACD,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;SACF,CAAC;QACF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,cAAc,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAClB,MAAM,IAAI,cAAc,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;YAClC,MAAM,IAAI,cAAc,CAAC,GAAG,MAAM,mBAAmB,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjB,MAAM,CAAC,KAAK,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,cAAc,CACtB,0KAA0K,CAC3K,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,SAAS;QAClB,IAAI;QACJ,KAAK;QACL,IAAI,EAAE,IAAI,IAAI,aAAa,CAAC,KAAK,CAAC;QAClC,WAAW;QACX,QAAQ;QACR,IAAI;QACJ,kBAAkB;QAClB,YAAY,EAAE,CAAC,WAAW;QAC1B,MAAM;QACN,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAuB;IAEvB,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,QAA4B,CAAC;IACjC,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAE7B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,IAAI,cAAc,CAAC,6CAA6C,CAAC,CAAC;YAC1E,CAAC;YACD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC5C,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,YAAY,GAAG,IAAI,CAAC;YACpB,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;YACzB,SAAS;QACX,CAAC;QACD,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;YAC5B,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,IAAI,cAAc,CACtB,iDAAiD,CAClD,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,cAAc,CAAC,wCAAwC,CAAC,CAAC;YACrE,CAAC;YACD,QAAQ,GAAG,KAAK,CAAC;YACjB,gBAAgB,GAAG,IAAI,CAAC;YACxB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QACD,MAAM,IAAI,cAAc,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,cAAc,CACtB,+EAA+E,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAuB;IAC/C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAClD,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,IAAI,cAAc,CACtB,oTAAoT,CACrT,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,MAE3B;IACC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAyB;IACxD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,OAA8B,EAC9B,YAA6B;IAE7B,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,MAAM,CACnB,YAAY,CAAC,mBAAmB,IAAI,wBAAwB,CAC7D,CAAC;gBACA,cAAc,EAAE,OAAO,CAAC,IAAI;gBAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAC/C,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBAC3B,OAAO,CAAC,CAAC;YACX,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAC7C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,cAAc,IAAI,cAAc,CAAC,CAAC;YACnE,cAAc,EAAE,OAAO,CAAC,IAAI;YAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAC9B,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,GAAG,CAC7C,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,MAAM,GAAG,CAAC;YACf,CAAC,CAAC,mBAAmB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxC,CAAC,CAAC,+BAA+B,CACpC,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC5C,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,IAAI,GAAsB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAC/C,YAAY,GAAoB,EAAE;IAElC,MAAM,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;YACzB,OAAO,MAAM,iBAAiB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,SAAS,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;YACtC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACvB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,UAAU,IAAI,OAAO,EAAE,CAAC;YAC1B,OAAO,MAAM,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,YAAY,GAAG;YACnB,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,YAAY;YACtB,SAAS,EAAE,uCAAuC;SAC1C,CAAC;QACX,OAAO,CAAC,GAAG,CACT,6DAA6D,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAC5F,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,OAAO,GACX,KAAK,YAAY,kBAAkB;gBACjC,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,kDAAkD,CAAC;YACzD,OAAO,CAAC,KAAK,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,OAAO,GACX,KAAK,YAAY,YAAY,IAAI,KAAK,YAAY,KAAK;YACrD,CAAC,CAAC,KAAK,CAAC,OAAO;YACf,CAAC,CAAC,2BAA2B,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC","sourcesContent":["import {\n checkContext,\n checkContextInstallation,\n installContext,\n syncContext,\n type ContextInstallCheckResult,\n type ContextInstallResult,\n type ContextInstallOptions,\n type ContextSyncResult,\n} from \"@ebay-dt/bonfire-context\";\nimport { prepare, PrepareError } from \"./prepare.js\";\nimport {\n BranchPrepareError,\n runBranchPrepare,\n type BranchPrepareDependencies,\n} from \"./branch-prepare.js\";\nimport {\n convert,\n convertDefaults,\n defaultConvertOptions,\n humanizeAppId,\n type ConvertOptions,\n} from \"./convert.js\";\n\nexport class CliSyntaxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CliSyntaxError\";\n }\n}\n\nexport type PrepareCommandOptions = {\n root: string;\n};\n\nexport type BranchPrepareCommandOptions = {\n root: string;\n hostname: string;\n};\n\nexport type ContextCommandOptions =\n | {\n context: \"sync\";\n root: string;\n check: boolean;\n }\n | {\n context: \"install\";\n root: string;\n appId: string;\n check: boolean;\n };\n\nexport type ConvertCommandOptions = ConvertOptions & { command: \"convert\" };\n\ntype CliCommandOptions =\n | PrepareCommandOptions\n | BranchPrepareCommandOptions\n | ContextCommandOptions\n | ConvertCommandOptions;\n\nexport type CliDependencies = BranchPrepareDependencies & {\n contextInstall?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallResult>;\n contextInstallCheck?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallCheckResult>;\n};\n\nfunction parseRootOption(\n argv: readonly string[],\n start: number,\n): { root: string; nextIndex: number } {\n const value = argv[start + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --root option requires a value\");\n }\n return { root: value, nextIndex: start + 2 };\n}\n\nfunction parsePrepareArgs(argv: readonly string[]): PrepareCommandOptions {\n let root = process.cwd();\n let rootProvided = false;\n for (let index = 1; index < argv.length;) {\n if (argv[index] !== \"--root\") {\n throw new CliSyntaxError(`Unknown option: ${argv[index]}`);\n }\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n }\n return { root };\n}\n\nfunction parseContextArgs(argv: readonly string[]): ContextCommandOptions {\n const context = argv[1];\n if (context !== \"sync\" && context !== \"install\") {\n throw new CliSyntaxError(\n \"Usage: bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n\n let root = process.cwd();\n let appId: string | undefined;\n let check = false;\n let rootProvided = false;\n let appIdProvided = false;\n let checkProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--check\") {\n if (checkProvided) {\n throw new CliSyntaxError(\n \"The --check option may only be provided once\",\n );\n }\n check = true;\n checkProvided = true;\n index += 1;\n continue;\n }\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (option === \"--app-id\") {\n if (appIdProvided) {\n throw new CliSyntaxError(\n \"The --app-id option may only be provided once\",\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --app-id option requires a value\");\n }\n appId = value;\n appIdProvided = true;\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n if (context === \"install\") {\n if (appId === undefined) {\n throw new CliSyntaxError(\n \"Usage: bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n return { context, root, appId, check };\n }\n if (appId !== undefined) {\n throw new CliSyntaxError(\"The --app-id option is only valid for install\");\n }\n return { context, root, check };\n}\n\nfunction parseConvertArgs(argv: readonly string[]): ConvertCommandOptions {\n const defaults = defaultConvertOptions();\n let root: string | undefined;\n let appId: string | undefined;\n let name: string | undefined;\n let packageName = defaults.packageName;\n let hostname = convertDefaults.hostname;\n let port = convertDefaults.port;\n let deploymentEndpoint = convertDefaults.deploymentEndpoint;\n let withoutData = false;\n let dryRun = false;\n let skipInstall = false;\n const seen = new Set<string>();\n\n for (let index = 1; index < argv.length;) {\n const option = argv[index];\n if (!option) throw new CliSyntaxError(\"Missing convert option\");\n if (\n option === \"--without-data\" ||\n option === \"--dry-run\" ||\n option === \"--skip-install\"\n ) {\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n seen.add(option);\n if (option === \"--without-data\") withoutData = true;\n if (option === \"--dry-run\") dryRun = true;\n if (option === \"--skip-install\") skipInstall = true;\n index += 1;\n continue;\n }\n const setters: Record<string, (value: string) => void> = {\n \"--root\": (value) => {\n root = value;\n },\n \"--app-id\": (value) => {\n appId = value;\n },\n \"--name\": (value) => {\n name = value;\n },\n \"--package-name\": (value) => {\n packageName = value;\n },\n \"--hostname\": (value) => {\n hostname = value;\n },\n \"--deployment-endpoint\": (value) => {\n deploymentEndpoint = value;\n },\n \"--port\": (value) => {\n if (\n !/^\\d+$/u.test(value) ||\n Number(value) < 1 ||\n Number(value) > 65535\n ) {\n throw new CliSyntaxError(\n \"--port must be a number between 1 and 65535\",\n );\n }\n port = Number(value);\n },\n };\n const setter = setters[option];\n if (!setter) throw new CliSyntaxError(`Unknown option: ${option}`);\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\"))\n throw new CliSyntaxError(`${option} requires a value`);\n seen.add(option);\n setter(value);\n index += 2;\n }\n if (!root || !appId) {\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [--name <display-name>] [--hostname <hostname>] [--port <port>] [--without-data] [--dry-run] [--skip-install]\",\n );\n }\n return {\n command: \"convert\",\n root,\n appId,\n name: name ?? humanizeAppId(appId),\n packageName,\n hostname,\n port,\n deploymentEndpoint,\n withItemData: !withoutData,\n dryRun,\n skipInstall,\n };\n}\n\nfunction parseBranchPrepareArgs(\n argv: readonly string[],\n): BranchPrepareCommandOptions {\n let root = process.cwd();\n let hostname: string | undefined;\n let rootProvided = false;\n let hostnameProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (option === \"--hostname\") {\n if (hostnameProvided) {\n throw new CliSyntaxError(\n \"The --hostname option may only be provided once\",\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --hostname option requires a value\");\n }\n hostname = value;\n hostnameProvided = true;\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n if (hostname === undefined) {\n throw new CliSyntaxError(\n \"Usage: bonfire branch prepare --root <application-root> --hostname <hostname>\",\n );\n }\n return { root, hostname };\n}\n\nexport function parseArgs(argv: readonly string[]): CliCommandOptions {\n if (argv[0] === \"convert\") return parseConvertArgs(argv);\n if (argv[0] === \"context\") return parseContextArgs(argv);\n if (argv[0] === \"prepare\") return parsePrepareArgs(argv);\n if (argv[0] === \"branch\" && argv[1] === \"prepare\") {\n return parseBranchPrepareArgs(argv);\n }\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [options] | bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>] | bonfire prepare [--root <application-root>] | bonfire branch prepare --root <application-root> --hostname <hostname>\",\n );\n}\n\nfunction printContextIssues(result: {\n issues: readonly { kind: string; path: string }[];\n}) {\n for (const issue of result.issues) {\n console.error(`- ${issue.kind}: ${issue.path}`);\n }\n}\n\nfunction printContextSyncSummary(result: ContextSyncResult) {\n if (result.written.length > 0) {\n console.log(`Written: ${result.written.join(\", \")}`);\n }\n if (result.removed.length > 0) {\n console.log(`Removed: ${result.removed.join(\", \")}`);\n }\n}\n\nasync function runContextCommand(\n options: ContextCommandOptions,\n dependencies: CliDependencies,\n): Promise<number> {\n if (options.context === \"install\") {\n if (options.check) {\n const result = await (\n dependencies.contextInstallCheck ?? checkContextInstallation\n )({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n if (!result.ok) {\n console.error(\"Context install check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context install check passed.\");\n return 0;\n }\n const result = await (dependencies.contextInstall ?? installContext)({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n const skills = result.skills.map(\n (skill) => `${skill.name} (${skill.status})`,\n );\n const mcp = result.mcp.map((server) => `${server.name} (${server.status})`);\n console.log(\n skills.length > 0\n ? `Context skills: ${skills.join(\", \")}`\n : \"No context skills configured.\",\n );\n if (mcp.length > 0) console.log(`Context MCP: ${mcp.join(\", \")}`);\n console.log(\"Context install complete.\");\n return 0;\n }\n\n if (options.check) {\n const result = await checkContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context sync check passed.\");\n return 0;\n }\n\n const result = await syncContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync failed:\");\n printContextIssues(result);\n return 1;\n }\n printContextSyncSummary(result);\n console.log(\"Context sync complete.\");\n return 0;\n}\n\nexport async function run(\n argv: readonly string[] = process.argv.slice(2),\n dependencies: CliDependencies = {},\n): Promise<number> {\n const isBranchPrepare = argv[0] === \"branch\";\n const isContext = argv[0] === \"context\";\n const isConvert = argv[0] === \"convert\";\n try {\n const options = parseArgs(argv);\n if (\"context\" in options) {\n return await runContextCommand(options, dependencies);\n }\n if (isConvert && \"command\" in options) {\n await convert(options);\n return 0;\n }\n if (\"hostname\" in options) {\n return await runBranchPrepare(options, dependencies);\n }\n\n const result = await prepare(options);\n const descriptions = {\n environment: \"the process environment\",\n existing: \".env.local\",\n generated: \"a newly generated value in .env.local\",\n } as const;\n console.log(\n `Bonfire preparation complete; BF_SESSION_SECRET came from ${descriptions[result.source]}.`,\n );\n return 0;\n } catch (error) {\n if (error instanceof CliSyntaxError) {\n console.error(`bonfire: ${error.message}`);\n return 2;\n }\n if (isContext) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire context failed: ${message}`);\n return 1;\n }\n if (isBranchPrepare) {\n const message =\n error instanceof BranchPrepareError\n ? error.message\n : \"Unable to load branch preparation configuration.\";\n console.error(`bonfire branch prepare failed: ${message}`);\n return 1;\n }\n if (isConvert) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire convert failed: ${message}`);\n return 1;\n }\n\n const message =\n error instanceof PrepareError || error instanceof Error\n ? error.message\n : \"an unknown error occurred\";\n console.error(`bonfire prepare failed: ${message}`);\n return 1;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n checkContext,\n checkContextInstallation,\n installContext,\n syncContext,\n type ContextInstallCheckResult,\n type ContextInstallResult,\n type ContextInstallOptions,\n type ContextSyncResult,\n} from \"@ebay-dt/bonfire-context\";\nimport { prepare, PrepareError } from \"./prepare.js\";\nimport {\n BranchPrepareError,\n runBranchPrepare,\n type BranchPrepareDependencies,\n} from \"./branch-prepare.js\";\nimport {\n convert,\n convertDefaults,\n defaultConvertOptions,\n humanizeAppId,\n type ConvertOptions,\n} from \"./convert.js\";\n\nexport class CliSyntaxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CliSyntaxError\";\n }\n}\n\nexport type PrepareCommandOptions = {\n root: string;\n};\n\nexport type BranchPrepareCommandOptions = {\n root: string;\n hostname?: string;\n defaultHostname?: string;\n prototypeRoot?: string;\n remote?: string;\n primaryBranch?: string;\n};\n\nexport type ContextCommandOptions =\n | {\n context: \"sync\";\n root: string;\n check: boolean;\n }\n | {\n context: \"install\";\n root: string;\n appId: string;\n check: boolean;\n };\n\nexport type ConvertCommandOptions = ConvertOptions & { command: \"convert\" };\n\ntype CliCommandOptions =\n | PrepareCommandOptions\n | BranchPrepareCommandOptions\n | ContextCommandOptions\n | ConvertCommandOptions;\n\nexport type CliDependencies = BranchPrepareDependencies & {\n contextInstall?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallResult>;\n contextInstallCheck?: (\n options: ContextInstallOptions,\n ) => Promise<ContextInstallCheckResult>;\n};\n\nfunction parseRootOption(\n argv: readonly string[],\n start: number,\n): { root: string; nextIndex: number } {\n const value = argv[start + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --root option requires a value\");\n }\n return { root: value, nextIndex: start + 2 };\n}\n\nfunction parsePrepareArgs(argv: readonly string[]): PrepareCommandOptions {\n let root = process.cwd();\n let rootProvided = false;\n for (let index = 1; index < argv.length;) {\n if (argv[index] !== \"--root\") {\n throw new CliSyntaxError(`Unknown option: ${argv[index]}`);\n }\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n }\n return { root };\n}\n\nfunction parseContextArgs(argv: readonly string[]): ContextCommandOptions {\n const context = argv[1];\n if (context !== \"sync\" && context !== \"install\") {\n throw new CliSyntaxError(\n \"Usage: bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n\n let root = process.cwd();\n let appId: string | undefined;\n let check = false;\n let rootProvided = false;\n let appIdProvided = false;\n let checkProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--check\") {\n if (checkProvided) {\n throw new CliSyntaxError(\n \"The --check option may only be provided once\",\n );\n }\n check = true;\n checkProvided = true;\n index += 1;\n continue;\n }\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (option === \"--app-id\") {\n if (appIdProvided) {\n throw new CliSyntaxError(\n \"The --app-id option may only be provided once\",\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(\"The --app-id option requires a value\");\n }\n appId = value;\n appIdProvided = true;\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n if (context === \"install\") {\n if (appId === undefined) {\n throw new CliSyntaxError(\n \"Usage: bonfire context install [--check] --app-id <app-id> [--root <root>]\",\n );\n }\n return { context, root, appId, check };\n }\n if (appId !== undefined) {\n throw new CliSyntaxError(\"The --app-id option is only valid for install\");\n }\n return { context, root, check };\n}\n\nfunction parseConvertArgs(argv: readonly string[]): ConvertCommandOptions {\n const defaults = defaultConvertOptions();\n let root: string | undefined;\n let appId: string | undefined;\n let name: string | undefined;\n let packageName = defaults.packageName;\n let hostname = convertDefaults.hostname;\n let port = convertDefaults.port;\n let deploymentEndpoint = convertDefaults.deploymentEndpoint;\n let withoutData = false;\n let dryRun = false;\n let skipInstall = false;\n const seen = new Set<string>();\n\n for (let index = 1; index < argv.length;) {\n const option = argv[index];\n if (!option) throw new CliSyntaxError(\"Missing convert option\");\n if (\n option === \"--without-data\" ||\n option === \"--dry-run\" ||\n option === \"--skip-install\"\n ) {\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n seen.add(option);\n if (option === \"--without-data\") withoutData = true;\n if (option === \"--dry-run\") dryRun = true;\n if (option === \"--skip-install\") skipInstall = true;\n index += 1;\n continue;\n }\n const setters: Record<string, (value: string) => void> = {\n \"--root\": (value) => {\n root = value;\n },\n \"--app-id\": (value) => {\n appId = value;\n },\n \"--name\": (value) => {\n name = value;\n },\n \"--package-name\": (value) => {\n packageName = value;\n },\n \"--hostname\": (value) => {\n hostname = value;\n },\n \"--deployment-endpoint\": (value) => {\n deploymentEndpoint = value;\n },\n \"--port\": (value) => {\n if (\n !/^\\d+$/u.test(value) ||\n Number(value) < 1 ||\n Number(value) > 65535\n ) {\n throw new CliSyntaxError(\n \"--port must be a number between 1 and 65535\",\n );\n }\n port = Number(value);\n },\n };\n const setter = setters[option];\n if (!setter) throw new CliSyntaxError(`Unknown option: ${option}`);\n if (seen.has(option))\n throw new CliSyntaxError(`${option} may only be provided once`);\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\"))\n throw new CliSyntaxError(`${option} requires a value`);\n seen.add(option);\n setter(value);\n index += 2;\n }\n if (!root || !appId) {\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [--name <display-name>] [--hostname <hostname>] [--port <port>] [--without-data] [--dry-run] [--skip-install]\",\n );\n }\n return {\n command: \"convert\",\n root,\n appId,\n name: name ?? humanizeAppId(appId),\n packageName,\n hostname,\n port,\n deploymentEndpoint,\n withItemData: !withoutData,\n dryRun,\n skipInstall,\n };\n}\n\nfunction parseBranchPrepareArgs(\n argv: readonly string[],\n): BranchPrepareCommandOptions {\n let root = process.cwd();\n let hostname: string | undefined;\n let defaultHostname: string | undefined;\n let prototypeRoot: string | undefined;\n let remote: string | undefined;\n let primaryBranch: string | undefined;\n let rootProvided = false;\n let hostnameProvided = false;\n let defaultHostnameProvided = false;\n let prototypeRootProvided = false;\n let remoteProvided = false;\n let primaryBranchProvided = false;\n\n for (let index = 2; index < argv.length;) {\n const option = argv[index];\n if (option === \"--root\") {\n if (rootProvided) {\n throw new CliSyntaxError(\"The --root option may only be provided once\");\n }\n const parsed = parseRootOption(argv, index);\n root = parsed.root;\n rootProvided = true;\n index = parsed.nextIndex;\n continue;\n }\n if (\n option === \"--prototype-root\" ||\n option === \"--remote\" ||\n option === \"--primary\"\n ) {\n const provided =\n option === \"--prototype-root\"\n ? prototypeRootProvided\n : option === \"--remote\"\n ? remoteProvided\n : primaryBranchProvided;\n if (provided) {\n throw new CliSyntaxError(`${option} may only be provided once`);\n }\n if (option === \"--prototype-root\") prototypeRootProvided = true;\n if (option === \"--remote\") remoteProvided = true;\n if (option === \"--primary\") primaryBranchProvided = true;\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(`${option} requires a value`);\n }\n if (option === \"--prototype-root\") prototypeRoot = value;\n if (option === \"--remote\") remote = value;\n if (option === \"--primary\") primaryBranch = value;\n index += 2;\n continue;\n }\n if (option === \"--hostname\" || option === \"--default-hostname\") {\n const isDefault = option === \"--default-hostname\";\n const provided = isDefault ? defaultHostnameProvided : hostnameProvided;\n if (provided) {\n throw new CliSyntaxError(\n `The ${option} option may only be provided once`,\n );\n }\n const value = argv[index + 1];\n if (!value || value.startsWith(\"--\")) {\n throw new CliSyntaxError(`The ${option} option requires a value`);\n }\n if (isDefault) {\n defaultHostname = value;\n defaultHostnameProvided = true;\n } else {\n hostname = value;\n hostnameProvided = true;\n }\n index += 2;\n continue;\n }\n throw new CliSyntaxError(`Unknown option: ${option}`);\n }\n\n return {\n root,\n ...(hostname === undefined ? {} : { hostname }),\n ...(defaultHostname === undefined ? {} : { defaultHostname }),\n ...(prototypeRoot === undefined ? {} : { prototypeRoot }),\n ...(remote === undefined ? {} : { remote }),\n ...(primaryBranch === undefined ? {} : { primaryBranch }),\n };\n}\n\nexport function parseArgs(argv: readonly string[]): CliCommandOptions {\n if (argv[0] === \"convert\") return parseConvertArgs(argv);\n if (argv[0] === \"context\") return parseContextArgs(argv);\n if (argv[0] === \"prepare\") return parsePrepareArgs(argv);\n if (argv[0] === \"branch\" && argv[1] === \"prepare\") {\n return parseBranchPrepareArgs(argv);\n }\n throw new CliSyntaxError(\n \"Usage: bonfire convert --root <next-app> --app-id <app-id> [options] | bonfire context sync [--check] [--root <root>] | bonfire context install [--check] --app-id <app-id> [--root <root>] | bonfire prepare [--root <application-root>] | bonfire branch prepare --root <application-root> [--hostname <hostname>] [--default-hostname <hostname>] [--prototype-root <root>] [--remote <name>] [--primary <branch>]\",\n );\n}\n\nfunction printContextIssues(result: {\n issues: readonly { kind: string; path: string }[];\n}) {\n for (const issue of result.issues) {\n console.error(`- ${issue.kind}: ${issue.path}`);\n }\n}\n\nfunction printContextSyncSummary(result: ContextSyncResult) {\n if (result.written.length > 0) {\n console.log(`Written: ${result.written.join(\", \")}`);\n }\n if (result.removed.length > 0) {\n console.log(`Removed: ${result.removed.join(\", \")}`);\n }\n}\n\nasync function runContextCommand(\n options: ContextCommandOptions,\n dependencies: CliDependencies,\n): Promise<number> {\n if (options.context === \"install\") {\n if (options.check) {\n const result = await (\n dependencies.contextInstallCheck ?? checkContextInstallation\n )({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n if (!result.ok) {\n console.error(\"Context install check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context install check passed.\");\n return 0;\n }\n const result = await (dependencies.contextInstall ?? installContext)({\n repositoryRoot: options.root,\n appId: options.appId,\n });\n const skills = result.skills.map(\n (skill) => `${skill.name} (${skill.status})`,\n );\n const mcp = result.mcp.map((server) => `${server.name} (${server.status})`);\n console.log(\n skills.length > 0\n ? `Context skills: ${skills.join(\", \")}`\n : \"No context skills configured.\",\n );\n if (mcp.length > 0) console.log(`Context MCP: ${mcp.join(\", \")}`);\n console.log(\"Context install complete.\");\n return 0;\n }\n\n if (options.check) {\n const result = await checkContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync check failed:\");\n printContextIssues(result);\n return 1;\n }\n console.log(\"Context sync check passed.\");\n return 0;\n }\n\n const result = await syncContext({ repositoryRoot: options.root });\n if (!result.ok) {\n console.error(\"Context sync failed:\");\n printContextIssues(result);\n return 1;\n }\n printContextSyncSummary(result);\n console.log(\"Context sync complete.\");\n return 0;\n}\n\nexport async function run(\n argv: readonly string[] = process.argv.slice(2),\n dependencies: CliDependencies = {},\n): Promise<number> {\n const isBranchPrepare = argv[0] === \"branch\";\n const isContext = argv[0] === \"context\";\n const isConvert = argv[0] === \"convert\";\n try {\n const options = parseArgs(argv);\n if (\"context\" in options) {\n return await runContextCommand(options, dependencies);\n }\n if (isConvert && \"command\" in options) {\n await convert(options);\n return 0;\n }\n if (isBranchPrepare) {\n return await runBranchPrepare(\n options as BranchPrepareCommandOptions,\n dependencies,\n );\n }\n\n const result = await prepare(options as PrepareCommandOptions);\n const descriptions = {\n environment: \"the process environment\",\n existing: \".env.local\",\n generated: \"a newly generated value in .env.local\",\n } as const;\n console.log(\n `Bonfire preparation complete; BF_SESSION_SECRET came from ${descriptions[result.source]}.`,\n );\n return 0;\n } catch (error) {\n if (error instanceof CliSyntaxError) {\n console.error(`bonfire: ${error.message}`);\n return 2;\n }\n if (isContext) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire context failed: ${message}`);\n return 1;\n }\n if (isBranchPrepare) {\n const message =\n error instanceof BranchPrepareError\n ? error.message\n : \"Unable to load branch preparation configuration.\";\n console.error(`bonfire branch prepare failed: ${message}`);\n return 1;\n }\n if (isConvert) {\n const message =\n error instanceof Error ? error.message : \"an unknown error occurred\";\n console.error(`bonfire convert failed: ${message}`);\n return 1;\n }\n\n const message =\n error instanceof PrepareError || error instanceof Error\n ? error.message\n : \"an unknown error occurred\";\n console.error(`bonfire prepare failed: ${message}`);\n return 1;\n }\n}\n"]}
|
package/dist/convert.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC,CAAC;AAEH,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,aAAa,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,KAAK,cAAc,GAAG,QAAQ,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAClC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC,CAAC;AAEH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,UAS1C;AAED,qBAAa,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AA2cD,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAsPzB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBA0DpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,SAAgB,GAAG,cAAc,CAa1E;AAED,eAAO,MAAM,eAAe;;;;CAI3B,CAAC","sourcesContent":["import { execFile } from \"node:child_process\";\nimport {\n chmod,\n lstat,\n mkdir,\n readFile,\n readdir,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { fileURLToPath } from \"node:url\";\nimport { syncContext } from \"@ebay-dt/bonfire-context\";\nimport { BONFIRE_VERSION, PRESET_VERSION } from \"./release-versions.js\";\n\nconst execFileAsync = promisify(execFile);\nconst TEMPLATE_ROOT = fileURLToPath(\n new URL(\"../templates/instance/\", import.meta.url),\n);\nconst DEFAULT_HOSTNAME = \"github.corp.ebay.com\";\nconst DEFAULT_DEPLOYMENT_ENDPOINT =\n \"https://dtsvc.vip.qa.ebay.com/dt/v1/bonfire-deploy\";\nconst DEFAULT_PORT = 1995;\n\nexport type ConvertOptions = Readonly<{\n root: string;\n appId: string;\n name: string;\n packageName?: string;\n hostname: string;\n port: number;\n deploymentEndpoint: string;\n withItemData: boolean;\n dryRun: boolean;\n skipInstall: boolean;\n}>;\n\ntype PackageJson = {\n name?: unknown;\n scripts?: Record<string, unknown>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n engines?: Record<string, string>;\n packageManager?: unknown;\n [key: string]: unknown;\n};\n\ntype PlannedChange = Readonly<{\n kind: \"add\" | \"update\" | \"remove\";\n path: string;\n reason: string;\n}>;\n\ntype ConversionPlan = Readonly<{\n root: string;\n changes: readonly PlannedChange[];\n writes: ReadonlyMap<string, string>;\n removals: readonly string[];\n packageJson: PackageJson;\n}>;\n\nexport function humanizeAppId(appId: string) {\n return appId\n .replace(/([a-z0-9])([A-Z])/gu, \"$1 $2\")\n .replace(/[._-]+/gu, \" \")\n .trim()\n .split(/\\s+/u)\n .filter(Boolean)\n .map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)\n .join(\" \");\n}\n\nexport class ConvertError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConvertError\";\n }\n}\n\nfunction displayPath(root: string, path: string) {\n return relative(root, path) || \".\";\n}\n\nfunction parseVersion(value: unknown, label: string) {\n if (typeof value !== \"string\") {\n throw new ConvertError(`${label} must be declared in package.json`);\n }\n const match = value.match(/(\\d+)\\.(\\d+)\\.(\\d+)/u);\n if (!match) {\n throw new ConvertError(`${label} has an unsupported version: ${value}`);\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n };\n}\n\nfunction dependencyVersion(packageJson: PackageJson, name: string) {\n return (\n packageJson.dependencies?.[name] ?? packageJson.devDependencies?.[name]\n );\n}\n\nfunction validateStartingScaffold(packageJson: PackageJson) {\n const next = parseVersion(dependencyVersion(packageJson, \"next\"), \"next\");\n if (next.major !== 16 || next.minor < 2) {\n throw new ConvertError(\n `next must be 16.2 or newer within the 16.x line (found ${next.major}.${next.minor}.${next.patch})`,\n );\n }\n const react = parseVersion(dependencyVersion(packageJson, \"react\"), \"react\");\n if (react.major !== 19 || react.minor < 2) {\n throw new ConvertError(\n `react must be 19.2 or newer within the 19.x line (found ${react.major}.${react.minor}.${react.patch})`,\n );\n }\n if (!dependencyVersion(packageJson, \"typescript\")) {\n throw new ConvertError(\"typescript must be declared in package.json\");\n }\n\n if (Number(process.versions.node.split(\".\")[0]) < 24) {\n throw new ConvertError(\n \"Bonfire instance conversion requires Node.js 24 or newer\",\n );\n }\n return next;\n}\n\nasync function readJson(path: string) {\n try {\n return JSON.parse(await readFile(path, \"utf8\")) as PackageJson;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ConvertError(\n `${displayPath(dirname(path), path)} is not valid JSON`,\n );\n }\n throw error;\n }\n}\n\nasync function exists(path: string) {\n try {\n await lstat(path);\n return true;\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return false;\n }\n throw error;\n }\n}\n\nasync function fileContent(path: string) {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction addChange(\n changes: PlannedChange[],\n root: string,\n path: string,\n kind: PlannedChange[\"kind\"],\n reason: string,\n) {\n changes.push({ kind, path: displayPath(root, path), reason });\n}\n\nasync function planFile(\n root: string,\n path: string,\n content: string,\n reason: string,\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const existing = await fileContent(path);\n if (existing === undefined) {\n writes.set(path, content);\n addChange(changes, root, path, \"add\", reason);\n return;\n }\n if (existing === content) return;\n throw new ConvertError(\n `${displayPath(root, path)} already exists and differs from the Bonfire scaffold; resolve it before converting`,\n );\n}\n\nfunction looksLikeNextStarter(path: string, content: string) {\n if (path.endsWith(\"/page.tsx\")) {\n return /Create Next App|[Gg]et started|Looking for a starting point|create-next-app/u.test(\n content,\n );\n }\n if (path.endsWith(\"/layout.tsx\")) {\n return /next\\/font|Geist|Create Next App/u.test(content);\n }\n if (path.endsWith(\"/page.module.css\")) {\n return /\\.page|\\.main|\\.footer|\\.grid/u.test(content);\n }\n if (path.endsWith(\"/globals.css\")) {\n return /--background|--foreground|@import [\"']tailwindcss/u.test(content);\n }\n if (path.endsWith(\"/README.md\")) {\n return /bootstrapped with[\\s\\S]*create-next-app/u.test(content);\n }\n if (path.endsWith(\"/next.config.ts\")) {\n return /config options here/u.test(content);\n }\n return false;\n}\n\nfunction looksLikeStarterAsset(path: string, content: string) {\n const name = path.slice(path.lastIndexOf(\"/\") + 1);\n if (\n ![\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].includes(\n name,\n )\n ) {\n return false;\n }\n return /<svg[\\s\\S]*viewBox=/u.test(content);\n}\n\nasync function planRemoveStarter(\n root: string,\n path: string,\n reason: string,\n removals: string[],\n changes: PlannedChange[],\n) {\n const content = await fileContent(path);\n if (content === undefined) return;\n if (\n content.includes(\"@ebay-dt/bonfire-next\") ||\n content.includes(\"A Bonfire instance for creating\") ||\n content.includes(\"outputFileTracingIncludes\")\n ) {\n return;\n }\n if (\n !looksLikeNextStarter(path, content) &&\n !looksLikeStarterAsset(path, content)\n ) {\n throw new ConvertError(\n `${displayPath(root, path)} is customized; it will not be removed automatically`,\n );\n }\n removals.push(path);\n addChange(changes, root, path, \"remove\", reason);\n}\n\nfunction replaceIdentity(content: string, options: ConvertOptions) {\n return content\n .replaceAll(\"design-sandbox-next\", () => options.appId)\n .replaceAll(\"Design Sandbox\", () => options.name)\n .replaceAll(\"github.corp.ebay.com\", () => options.hostname)\n .replaceAll(DEFAULT_DEPLOYMENT_ENDPOINT, () => options.deploymentEndpoint);\n}\n\nfunction withoutItemGuidance(content: string) {\n const start = content.indexOf(\"### Data fetching\");\n const end = content.indexOf(\"### Viewport sizing\");\n if (start < 0 || end < 0 || end <= start) return content;\n return `${content.slice(0, start)}${content.slice(end)}`;\n}\n\nasync function templateFiles(options: ConvertOptions) {\n const files: Array<{ relativePath: string; content: string }> = [];\n async function visit(directory: string) {\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n const path = join(directory, entry.name);\n const relativePath = relative(TEMPLATE_ROOT, path);\n if (\n !options.withItemData &&\n (relativePath.startsWith(\"src/app/api/items/\") ||\n relativePath.startsWith(\"src/lib/items/\") ||\n relativePath === \"context/skills/item-data/SKILL.md\")\n ) {\n continue;\n }\n if (entry.isDirectory()) {\n await visit(path);\n } else if (entry.isFile()) {\n let content = await readFile(path, \"utf8\");\n content = replaceIdentity(content, options);\n if (!options.withItemData && relativePath === \"context/PROTOTYPE.md\") {\n content = withoutItemGuidance(content);\n }\n files.push({ relativePath, content });\n }\n }\n }\n await visit(TEMPLATE_ROOT);\n return files;\n}\n\nfunction starterReadme(options: ConvertOptions) {\n return `# ${options.name}\\n\\nA Bonfire instance for creating, editing, and sharing prototypes.\\n\\n## Development\\n\\nUse Node.js 24+, install dependencies with pnpm, then run:\\n\\n~~~sh\\npnpm dev\\n~~~\\n\\nThe development command prepares the Bonfire session secret and the local identity branch before starting Next.js on port ${options.port}.\\n\\nRun pnpm context:install once on a machine where agent tooling is desired.\\n`;\n}\n\nfunction addDependency(\n packageJson: PackageJson,\n section: \"dependencies\" | \"devDependencies\",\n name: string,\n version: string,\n) {\n const target = (packageJson[section] ??= {});\n const existing = target[name];\n if (existing !== undefined) {\n if (existing !== version && name.startsWith(\"@ebay-dt/bonfire-\")) {\n throw new ConvertError(\n `${name} is already declared as ${existing}; expected ${version}. Update it explicitly before converting`,\n );\n }\n return;\n }\n target[name] = version;\n}\n\nfunction addScript(\n packageJson: PackageJson,\n name: string,\n value: string,\n allowedExisting: readonly string[] = [],\n) {\n const scripts = (packageJson.scripts ??= {});\n const existing = scripts[name];\n if (existing !== undefined) {\n if (existing !== value && !allowedExisting.includes(String(existing))) {\n throw new ConvertError(\n `package.json script ${name} is customized (${String(existing)}); resolve it before converting`,\n );\n }\n scripts[name] = value;\n return;\n }\n scripts[name] = value;\n}\n\nfunction mergeLines(existing: string | undefined, required: readonly string[]) {\n let result = existing ?? \"\";\n for (const line of required) {\n if (result.split(/\\r?\\n/u).some((entry) => entry.trim() === line)) continue;\n if (result.length > 0 && !result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n return result;\n}\n\nfunction mergeWorkspace(existing: string | undefined) {\n let result = existing ?? \"\";\n if (!/^minimumReleaseAge:/mu.test(result)) {\n result = `# Bonfire publishes lockstep alpha packages that must be installable immediately.\\nminimumReleaseAge: 0\\n${result}`;\n } else if (!/^minimumReleaseAge:\\s*0\\s*$/mu.test(result)) {\n throw new ConvertError(\n \"pnpm-workspace.yaml has a conflicting minimumReleaseAge\",\n );\n }\n const required = [\n \" esbuild: true\",\n \" sharp: true\",\n \" unrs-resolver: true\",\n ];\n for (const line of required) {\n const key = line.trim().split(\":\")[0] ?? \"\";\n const match = result.match(new RegExp(`^\\\\s+${key}:\\\\s*(\\\\S+)\\\\s*$`, \"mu\"));\n if (match && match[1] !== \"true\") {\n // create-next-app currently writes these two false entries. They are\n // starter policy, not an instance decision, so normalize them to the\n // Bonfire installation policy.\n if (match[1] !== \"false\" || ![\"sharp\", \"unrs-resolver\"].includes(key)) {\n throw new ConvertError(\n `pnpm-workspace.yaml has a conflicting allowBuilds.${key} setting`,\n );\n }\n result = result.replace(\n new RegExp(`(^\\\\s+${key}:\\\\s*)false(\\\\s*$)`, \"mu\"),\n \"$1true$2\",\n );\n }\n if (!match) {\n if (!result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n }\n return result;\n}\n\nasync function planPackageJson(\n root: string,\n options: ConvertOptions,\n packageJson: PackageJson,\n nextVersion: { major: number; minor: number; patch: number },\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const packageName =\n options.packageName ??\n (typeof packageJson.name === \"string\" ? packageJson.name : options.appId);\n if (!/^[a-z0-9][a-z0-9._-]*$/u.test(packageName)) {\n throw new ConvertError(`package name is invalid: ${packageName}`);\n }\n packageJson.name = packageName;\n const engines = (packageJson.engines ??= {});\n if (\n engines.node !== undefined &&\n !/^(?:\\^|~|>=)?\\s*2[4-9]|[3-9]\\d/u.test(engines.node)\n ) {\n throw new ConvertError(\n \"package.json engines.node must allow Node.js 24 or newer\",\n );\n }\n engines.node = \">=24\";\n packageJson.packageManager ??= \"pnpm@11.25.0\";\n\n const dev = `bonfire prepare --root . && bonfire branch prepare --root . --hostname ${options.hostname} && next dev -p ${options.port}`;\n addScript(packageJson, \"dev\", dev, [\"next dev\"]);\n addScript(packageJson, \"context:sync\", \"bonfire context sync\");\n addScript(\n packageJson,\n \"context:install\",\n `bonfire context install --app-id ${options.appId}`,\n );\n addScript(\n packageJson,\n \"check\",\n \"tsc --noEmit --project tsconfig.check.json && pnpm context:sync --check\",\n );\n addScript(packageJson, \"format\", \"prettier --write .\");\n addScript(packageJson, \"build\", \"next build\", [\"next build\"]);\n addScript(packageJson, \"start\", \"next start\", [\"next start\"]);\n addScript(packageJson, \"lint\", \"eslint\", [\"eslint\", \"eslint .\"]);\n\n const nextExact = `${nextVersion.major}.${nextVersion.minor}.${nextVersion.patch}`;\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-context\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-core\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-next\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-preset-ebay\",\n PRESET_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-react\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"dependencies\", \"@ebay/ui-core-react\", \"9.13.0\");\n addDependency(packageJson, \"dependencies\", \"@evo-web/react\", \"0.4.4\");\n addDependency(\n packageJson,\n \"dependencies\",\n \"react-dom\",\n dependencyVersion(packageJson, \"react-dom\") ?? \"19.2.8\",\n );\n addDependency(packageJson, \"dependencies\", \"server-only\", \"^0.0.1\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"@ebay-dt/bonfire-cli\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"devDependencies\", \"@types/node\", \"^20\");\n addDependency(packageJson, \"devDependencies\", \"@types/react\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"@types/react-dom\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"eslint\", \"^9\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"eslint-config-next\",\n nextExact,\n );\n addDependency(packageJson, \"devDependencies\", \"prettier\", \"^3.9.5\");\n if (options.withItemData) {\n addDependency(\n packageJson,\n \"dependencies\",\n \"@tanstack/react-query\",\n \"^5.104.0\",\n );\n addDependency(packageJson, \"dependencies\", \"zod\", \"^4.4.3\");\n }\n\n const path = join(root, \"package.json\");\n const content = `${JSON.stringify(packageJson, null, 2)}\\n`;\n const existing = await readFile(path, \"utf8\");\n if (JSON.stringify(JSON.parse(existing)) !== JSON.stringify(packageJson)) {\n writes.set(path, content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"merge Bonfire scripts and dependencies\",\n );\n }\n}\n\nexport async function planConversion(\n options: ConvertOptions,\n): Promise<ConversionPlan> {\n const root = resolve(options.root);\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(options.appId)) {\n throw new ConvertError(\n \"app id must contain only letters, numbers, dots, underscores, and hyphens\",\n );\n }\n if (!options.name.trim())\n throw new ConvertError(\"display name must not be empty\");\n const packagePath = join(root, \"package.json\");\n const packageJson = await readJson(packagePath);\n const nextVersion = validateStartingScaffold(packageJson);\n if (!(await exists(join(root, \"src\", \"app\")))) {\n throw new ConvertError(\n \"the starting scaffold must use the src/app App Router\",\n );\n }\n\n const writes = new Map<string, string>();\n const changes: PlannedChange[] = [];\n const removals: string[] = [];\n\n const starterPaths = [\n join(root, \"src/app/layout.tsx\"),\n join(root, \"src/app/page.tsx\"),\n join(root, \"src/app/page.module.css\"),\n join(root, \"src/app/globals.css\"),\n join(root, \"next.config.ts\"),\n join(root, \"README.md\"),\n ...[\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].map(\n (name) => join(root, \"public\", name),\n ),\n ];\n for (const path of starterPaths) {\n await planRemoveStarter(\n root,\n path,\n \"remove unmodified create-next-app content\",\n removals,\n changes,\n );\n }\n const nextBuildDirectory = join(root, \".next\");\n if (await exists(nextBuildDirectory)) {\n removals.push(nextBuildDirectory);\n addChange(\n changes,\n root,\n nextBuildDirectory,\n \"remove\",\n \"clear generated Next.js output\",\n );\n }\n\n const resolvedOptions = { ...options, root };\n const templates = await templateFiles(resolvedOptions);\n for (const file of templates) {\n const path = join(root, file.relativePath);\n if (removals.includes(path)) {\n writes.set(path, file.content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"replace unmodified create-next-app content\",\n );\n continue;\n }\n await planFile(\n root,\n path,\n file.content,\n \"add Bonfire instance scaffold\",\n writes,\n changes,\n );\n }\n\n await planPackageJson(\n root,\n options,\n packageJson,\n nextVersion,\n writes,\n changes,\n );\n\n const tsconfigPath = join(root, \"tsconfig.json\");\n const existingTsconfig = await readFile(tsconfigPath, \"utf8\");\n const tsconfig = await readJson(tsconfigPath);\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<\n string,\n unknown\n >;\n tsconfig.compilerOptions = compilerOptions;\n const paths = compilerOptions[\"paths\"] as Record<string, unknown> | undefined;\n if (paths && JSON.stringify(paths[\"@/*\"]) !== JSON.stringify([\"./src/*\"])) {\n throw new ConvertError(\"tsconfig.json has a conflicting @/* path alias\");\n }\n compilerOptions[\"paths\"] = { ...(paths ?? {}), \"@/*\": [\"./src/*\"] };\n const nextTsconfig = `${JSON.stringify(tsconfig, null, 2)}\\n`;\n if (\n JSON.stringify(JSON.parse(existingTsconfig)) !== JSON.stringify(tsconfig)\n ) {\n writes.set(tsconfigPath, nextTsconfig);\n addChange(\n changes,\n root,\n tsconfigPath,\n \"update\",\n \"retain the Bonfire @/* source alias\",\n );\n }\n\n await planFile(\n root,\n join(root, \"tsconfig.check.json\"),\n '{\\n \"extends\": \"./tsconfig.json\",\\n \"exclude\": [\"node_modules\", \".next\"]\\n}\\n',\n \"add the clean TypeScript check project\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierrc\"),\n '{\\n \"semi\": false,\\n \"singleQuote\": true,\\n \"trailingComma\": \"es5\",\\n \"printWidth\": 80\\n}\\n',\n \"add Bonfire formatting conventions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierignore\"),\n \"# Generated and external files\\n.next/\\nnode_modules/\\npnpm-lock.yaml\\nsrc/app/(prototypes)/**/.claude/settings.json\\n\",\n \"add formatter exclusions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".env.local.example\"),\n \"# Bonfire generates this secret during `pnpm dev`.\\n# Do NOT manually modify or remove this variable.\\nBF_SESSION_SECRET=\\n\\n# Set exactly to lowercase `true` to skip automatic identity-branch preparation.\\nBF_DISABLE_AUTO_BRANCH_SWITCH=\\n\\n# Set to `managed` or `manual` for Bonfire Git management.\\nBF_GIT_MODE=\\n\",\n \"document Bonfire environment setup\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \"public/.gitkeep\"),\n \"\",\n \"retain an explicit public directory\",\n writes,\n changes,\n );\n\n const gitignorePath = join(root, \".gitignore\");\n const gitignore = await fileContent(gitignorePath);\n const mergedGitignore = mergeLines(gitignore, [\n \"# Bonfire local secrets\",\n \".env.local\",\n ]);\n if (mergedGitignore !== (gitignore ?? \"\")) {\n writes.set(gitignorePath, mergedGitignore);\n addChange(\n changes,\n root,\n gitignorePath,\n \"update\",\n \"ignore the generated local session secret\",\n );\n }\n\n const workspacePath = join(root, \"pnpm-workspace.yaml\");\n const workspace = await fileContent(workspacePath);\n const mergedWorkspace = mergeWorkspace(workspace);\n if (mergedWorkspace !== (workspace ?? \"\")) {\n writes.set(workspacePath, mergedWorkspace);\n addChange(\n changes,\n root,\n workspacePath,\n \"update\",\n \"retain the Bonfire pnpm installation policy\",\n );\n }\n const npmrcPath = join(root, \".npmrc\");\n const npmrc = await fileContent(npmrcPath);\n if (\n npmrc &&\n /@ebay-dt:\\s*registry=/u.test(npmrc) &&\n !npmrc.includes(\"@ebay-dt:registry=https://registry.npmjs.org/\")\n ) {\n throw new ConvertError(\".npmrc has a conflicting @ebay-dt registry\");\n }\n const mergedNpmrc = mergeLines(npmrc, [\n \"@ebay-dt:registry=https://registry.npmjs.org/\",\n ]);\n if (mergedNpmrc !== (npmrc ?? \"\")) {\n writes.set(npmrcPath, mergedNpmrc);\n addChange(\n changes,\n root,\n npmrcPath,\n \"update\",\n \"resolve Bonfire packages from public npm\",\n );\n }\n const nvmrcPath = join(root, \".nvmrc\");\n const nvmrc = await fileContent(nvmrcPath);\n if (nvmrc === undefined) {\n await planFile(\n root,\n nvmrcPath,\n \"24\\n\",\n \"select Node.js 24 or newer\",\n writes,\n changes,\n );\n }\n\n const readmePath = join(root, \"README.md\");\n if (removals.includes(readmePath)) {\n writes.set(readmePath, starterReadme(options));\n addChange(\n changes,\n root,\n readmePath,\n \"update\",\n \"replace unmodified create-next-app documentation\",\n );\n } else if (\n !writes.has(readmePath) &&\n (await fileContent(readmePath)) === undefined\n ) {\n await planFile(\n root,\n readmePath,\n starterReadme(options),\n \"add instance setup documentation\",\n writes,\n changes,\n );\n }\n\n return { root, changes, writes, removals, packageJson };\n}\n\nexport async function convert(options: ConvertOptions) {\n const plan = await planConversion(options);\n for (const change of plan.changes) {\n console.log(\n `${options.dryRun ? \"Would \" : \"\"}${change.kind} ${change.path} (${change.reason})`,\n );\n }\n if (options.dryRun) return;\n\n for (const path of plan.removals) {\n await rm(path, {\n force: true,\n recursive: path === join(plan.root, \".next\"),\n });\n }\n for (const [path, content] of plan.writes) {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, content);\n if (path.endsWith(\"context/hooks/block-env-reads.mjs\")) {\n await chmod(path, 0o755);\n }\n }\n\n if (!options.skipInstall) {\n console.log(\"Installing dependencies and updating pnpm-lock.yaml...\");\n await execFileAsync(\"pnpm\", [\"install\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n if (!options.skipInstall) {\n const formatPaths = [...plan.writes.keys()]\n .map((path) => displayPath(plan.root, path))\n .filter((path) => /\\.(?:json|mjs|md|ts|tsx|yaml|yml)$/u.test(path));\n if (formatPaths.length > 0) {\n await execFileAsync(\n \"pnpm\",\n [\"exec\", \"prettier\", \"--write\", ...formatPaths],\n {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n },\n );\n }\n await execFileAsync(\"pnpm\", [\"exec\", \"next\", \"typegen\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n const contextResult = await syncContext({ repositoryRoot: plan.root });\n if (contextResult.written.length > 0 || contextResult.removed.length > 0) {\n console.log(\n `Context synchronized (${contextResult.written.length} written, ${contextResult.removed.length} removed).`,\n );\n }\n console.log(\"Bonfire instance conversion complete.\");\n}\n\nexport function defaultConvertOptions(root = process.cwd()): ConvertOptions {\n const appId = \"bonfire-instance\";\n return {\n root,\n appId,\n name: \"Bonfire Instance\",\n hostname: DEFAULT_HOSTNAME,\n port: DEFAULT_PORT,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n withItemData: true,\n dryRun: false,\n skipInstall: false,\n };\n}\n\nexport const convertDefaults = {\n hostname: DEFAULT_HOSTNAME,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n port: DEFAULT_PORT,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC,CAAC;AAEH,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,aAAa,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,KAAK,cAAc,GAAG,QAAQ,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAClC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC,CAAC;AAEH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,UAS1C;AAED,qBAAa,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AA2cD,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAsPzB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,iBA0DpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,SAAgB,GAAG,cAAc,CAa1E;AAED,eAAO,MAAM,eAAe;;;;CAI3B,CAAC","sourcesContent":["import { execFile } from \"node:child_process\";\nimport {\n chmod,\n lstat,\n mkdir,\n readFile,\n readdir,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { fileURLToPath } from \"node:url\";\nimport { syncContext } from \"@ebay-dt/bonfire-context\";\nimport { BONFIRE_VERSION, PRESET_VERSION } from \"./release-versions.js\";\n\nconst execFileAsync = promisify(execFile);\nconst TEMPLATE_ROOT = fileURLToPath(\n new URL(\"../templates/instance/\", import.meta.url),\n);\nconst DEFAULT_HOSTNAME = \"github.corp.ebay.com\";\nconst DEFAULT_DEPLOYMENT_ENDPOINT =\n \"https://dtsvc.vip.qa.ebay.com/dt/v1/bonfire-deploy\";\nconst DEFAULT_PORT = 1995;\n\nexport type ConvertOptions = Readonly<{\n root: string;\n appId: string;\n name: string;\n packageName?: string;\n hostname: string;\n port: number;\n deploymentEndpoint: string;\n withItemData: boolean;\n dryRun: boolean;\n skipInstall: boolean;\n}>;\n\ntype PackageJson = {\n name?: unknown;\n scripts?: Record<string, unknown>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n engines?: Record<string, string>;\n packageManager?: unknown;\n [key: string]: unknown;\n};\n\ntype PlannedChange = Readonly<{\n kind: \"add\" | \"update\" | \"remove\";\n path: string;\n reason: string;\n}>;\n\ntype ConversionPlan = Readonly<{\n root: string;\n changes: readonly PlannedChange[];\n writes: ReadonlyMap<string, string>;\n removals: readonly string[];\n packageJson: PackageJson;\n}>;\n\nexport function humanizeAppId(appId: string) {\n return appId\n .replace(/([a-z0-9])([A-Z])/gu, \"$1 $2\")\n .replace(/[._-]+/gu, \" \")\n .trim()\n .split(/\\s+/u)\n .filter(Boolean)\n .map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)\n .join(\" \");\n}\n\nexport class ConvertError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConvertError\";\n }\n}\n\nfunction displayPath(root: string, path: string) {\n return relative(root, path) || \".\";\n}\n\nfunction parseVersion(value: unknown, label: string) {\n if (typeof value !== \"string\") {\n throw new ConvertError(`${label} must be declared in package.json`);\n }\n const match = value.match(/(\\d+)\\.(\\d+)\\.(\\d+)/u);\n if (!match) {\n throw new ConvertError(`${label} has an unsupported version: ${value}`);\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n };\n}\n\nfunction dependencyVersion(packageJson: PackageJson, name: string) {\n return (\n packageJson.dependencies?.[name] ?? packageJson.devDependencies?.[name]\n );\n}\n\nfunction validateStartingScaffold(packageJson: PackageJson) {\n const next = parseVersion(dependencyVersion(packageJson, \"next\"), \"next\");\n if (next.major !== 16 || next.minor < 2) {\n throw new ConvertError(\n `next must be 16.2 or newer within the 16.x line (found ${next.major}.${next.minor}.${next.patch})`,\n );\n }\n const react = parseVersion(dependencyVersion(packageJson, \"react\"), \"react\");\n if (react.major !== 19 || react.minor < 2) {\n throw new ConvertError(\n `react must be 19.2 or newer within the 19.x line (found ${react.major}.${react.minor}.${react.patch})`,\n );\n }\n if (!dependencyVersion(packageJson, \"typescript\")) {\n throw new ConvertError(\"typescript must be declared in package.json\");\n }\n\n if (Number(process.versions.node.split(\".\")[0]) < 24) {\n throw new ConvertError(\n \"Bonfire instance conversion requires Node.js 24 or newer\",\n );\n }\n return next;\n}\n\nasync function readJson(path: string) {\n try {\n return JSON.parse(await readFile(path, \"utf8\")) as PackageJson;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ConvertError(\n `${displayPath(dirname(path), path)} is not valid JSON`,\n );\n }\n throw error;\n }\n}\n\nasync function exists(path: string) {\n try {\n await lstat(path);\n return true;\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return false;\n }\n throw error;\n }\n}\n\nasync function fileContent(path: string) {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction addChange(\n changes: PlannedChange[],\n root: string,\n path: string,\n kind: PlannedChange[\"kind\"],\n reason: string,\n) {\n changes.push({ kind, path: displayPath(root, path), reason });\n}\n\nasync function planFile(\n root: string,\n path: string,\n content: string,\n reason: string,\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const existing = await fileContent(path);\n if (existing === undefined) {\n writes.set(path, content);\n addChange(changes, root, path, \"add\", reason);\n return;\n }\n if (existing === content) return;\n throw new ConvertError(\n `${displayPath(root, path)} already exists and differs from the Bonfire scaffold; resolve it before converting`,\n );\n}\n\nfunction looksLikeNextStarter(path: string, content: string) {\n if (path.endsWith(\"/page.tsx\")) {\n return /Create Next App|[Gg]et started|Looking for a starting point|create-next-app/u.test(\n content,\n );\n }\n if (path.endsWith(\"/layout.tsx\")) {\n return /next\\/font|Geist|Create Next App/u.test(content);\n }\n if (path.endsWith(\"/page.module.css\")) {\n return /\\.page|\\.main|\\.footer|\\.grid/u.test(content);\n }\n if (path.endsWith(\"/globals.css\")) {\n return /--background|--foreground|@import [\"']tailwindcss/u.test(content);\n }\n if (path.endsWith(\"/README.md\")) {\n return /bootstrapped with[\\s\\S]*create-next-app/u.test(content);\n }\n if (path.endsWith(\"/next.config.ts\")) {\n return /config options here/u.test(content);\n }\n return false;\n}\n\nfunction looksLikeStarterAsset(path: string, content: string) {\n const name = path.slice(path.lastIndexOf(\"/\") + 1);\n if (\n ![\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].includes(\n name,\n )\n ) {\n return false;\n }\n return /<svg[\\s\\S]*viewBox=/u.test(content);\n}\n\nasync function planRemoveStarter(\n root: string,\n path: string,\n reason: string,\n removals: string[],\n changes: PlannedChange[],\n) {\n const content = await fileContent(path);\n if (content === undefined) return;\n if (\n content.includes(\"@ebay-dt/bonfire-next\") ||\n content.includes(\"A Bonfire instance for creating\") ||\n content.includes(\"outputFileTracingIncludes\")\n ) {\n return;\n }\n if (\n !looksLikeNextStarter(path, content) &&\n !looksLikeStarterAsset(path, content)\n ) {\n throw new ConvertError(\n `${displayPath(root, path)} is customized; it will not be removed automatically`,\n );\n }\n removals.push(path);\n addChange(changes, root, path, \"remove\", reason);\n}\n\nfunction replaceIdentity(content: string, options: ConvertOptions) {\n return content\n .replaceAll(\"design-sandbox-next\", () => options.appId)\n .replaceAll(\"Design Sandbox\", () => options.name)\n .replaceAll(\"github.corp.ebay.com\", () => options.hostname)\n .replaceAll(DEFAULT_DEPLOYMENT_ENDPOINT, () => options.deploymentEndpoint);\n}\n\nfunction withoutItemGuidance(content: string) {\n const start = content.indexOf(\"### Data fetching\");\n const end = content.indexOf(\"### Viewport sizing\");\n if (start < 0 || end < 0 || end <= start) return content;\n return `${content.slice(0, start)}${content.slice(end)}`;\n}\n\nasync function templateFiles(options: ConvertOptions) {\n const files: Array<{ relativePath: string; content: string }> = [];\n async function visit(directory: string) {\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n const path = join(directory, entry.name);\n const relativePath = relative(TEMPLATE_ROOT, path);\n if (\n !options.withItemData &&\n (relativePath.startsWith(\"src/app/api/items/\") ||\n relativePath.startsWith(\"src/lib/items/\") ||\n relativePath === \"context/skills/item-data/SKILL.md\")\n ) {\n continue;\n }\n if (entry.isDirectory()) {\n await visit(path);\n } else if (entry.isFile()) {\n let content = await readFile(path, \"utf8\");\n content = replaceIdentity(content, options);\n if (!options.withItemData && relativePath === \"context/PROTOTYPE.md\") {\n content = withoutItemGuidance(content);\n }\n files.push({ relativePath, content });\n }\n }\n }\n await visit(TEMPLATE_ROOT);\n return files;\n}\n\nfunction starterReadme(options: ConvertOptions) {\n return `# ${options.name}\\n\\nA Bonfire instance for creating, editing, and sharing prototypes.\\n\\n## Development\\n\\nUse Node.js 24+, install dependencies with pnpm, then run:\\n\\n~~~sh\\npnpm dev\\n~~~\\n\\nThe development command prepares the Bonfire session secret and the local identity branch before starting Next.js on port ${options.port}.\\n\\nRun pnpm context:install once on a machine where agent tooling is desired.\\n`;\n}\n\nfunction addDependency(\n packageJson: PackageJson,\n section: \"dependencies\" | \"devDependencies\",\n name: string,\n version: string,\n) {\n const target = (packageJson[section] ??= {});\n const existing = target[name];\n if (existing !== undefined) {\n if (existing !== version && name.startsWith(\"@ebay-dt/bonfire-\")) {\n throw new ConvertError(\n `${name} is already declared as ${existing}; expected ${version}. Update it explicitly before converting`,\n );\n }\n return;\n }\n target[name] = version;\n}\n\nfunction addScript(\n packageJson: PackageJson,\n name: string,\n value: string,\n allowedExisting: readonly string[] = [],\n) {\n const scripts = (packageJson.scripts ??= {});\n const existing = scripts[name];\n if (existing !== undefined) {\n if (existing !== value && !allowedExisting.includes(String(existing))) {\n throw new ConvertError(\n `package.json script ${name} is customized (${String(existing)}); resolve it before converting`,\n );\n }\n scripts[name] = value;\n return;\n }\n scripts[name] = value;\n}\n\nfunction mergeLines(existing: string | undefined, required: readonly string[]) {\n let result = existing ?? \"\";\n for (const line of required) {\n if (result.split(/\\r?\\n/u).some((entry) => entry.trim() === line)) continue;\n if (result.length > 0 && !result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n return result;\n}\n\nfunction mergeWorkspace(existing: string | undefined) {\n let result = existing ?? \"\";\n if (!/^minimumReleaseAge:/mu.test(result)) {\n result = `# Bonfire publishes lockstep alpha packages that must be installable immediately.\\nminimumReleaseAge: 0\\n${result}`;\n } else if (!/^minimumReleaseAge:\\s*0\\s*$/mu.test(result)) {\n throw new ConvertError(\n \"pnpm-workspace.yaml has a conflicting minimumReleaseAge\",\n );\n }\n const required = [\n \" esbuild: true\",\n \" sharp: true\",\n \" unrs-resolver: true\",\n ];\n for (const line of required) {\n const key = line.trim().split(\":\")[0] ?? \"\";\n const match = result.match(new RegExp(`^\\\\s+${key}:\\\\s*(\\\\S+)\\\\s*$`, \"mu\"));\n if (match && match[1] !== \"true\") {\n // create-next-app currently writes these two false entries. They are\n // starter policy, not an instance decision, so normalize them to the\n // Bonfire installation policy.\n if (match[1] !== \"false\" || ![\"sharp\", \"unrs-resolver\"].includes(key)) {\n throw new ConvertError(\n `pnpm-workspace.yaml has a conflicting allowBuilds.${key} setting`,\n );\n }\n result = result.replace(\n new RegExp(`(^\\\\s+${key}:\\\\s*)false(\\\\s*$)`, \"mu\"),\n \"$1true$2\",\n );\n }\n if (!match) {\n if (!result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n }\n return result;\n}\n\nasync function planPackageJson(\n root: string,\n options: ConvertOptions,\n packageJson: PackageJson,\n nextVersion: { major: number; minor: number; patch: number },\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const packageName =\n options.packageName ??\n (typeof packageJson.name === \"string\" ? packageJson.name : options.appId);\n if (!/^[a-z0-9][a-z0-9._-]*$/u.test(packageName)) {\n throw new ConvertError(`package name is invalid: ${packageName}`);\n }\n packageJson.name = packageName;\n const engines = (packageJson.engines ??= {});\n if (\n engines.node !== undefined &&\n !/^(?:\\^|~|>=)?\\s*2[4-9]|[3-9]\\d/u.test(engines.node)\n ) {\n throw new ConvertError(\n \"package.json engines.node must allow Node.js 24 or newer\",\n );\n }\n engines.node = \">=24\";\n packageJson.packageManager ??= \"pnpm@11.25.0\";\n\n const dev = `bonfire prepare --root . && bonfire branch prepare --root . --default-hostname \"${options.hostname}\" && next dev -p ${options.port}`;\n addScript(packageJson, \"dev\", dev, [\"next dev\"]);\n addScript(packageJson, \"context:sync\", \"bonfire context sync\");\n addScript(\n packageJson,\n \"context:install\",\n `bonfire context install --app-id ${options.appId}`,\n );\n addScript(\n packageJson,\n \"check\",\n \"tsc --noEmit --project tsconfig.check.json && pnpm context:sync --check\",\n );\n addScript(packageJson, \"format\", \"prettier --write .\");\n addScript(packageJson, \"build\", \"next build\", [\"next build\"]);\n addScript(packageJson, \"start\", \"next start\", [\"next start\"]);\n addScript(packageJson, \"lint\", \"eslint\", [\"eslint\", \"eslint .\"]);\n\n const nextExact = `${nextVersion.major}.${nextVersion.minor}.${nextVersion.patch}`;\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-context\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-core\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-next\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-preset-ebay\",\n PRESET_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-react\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"dependencies\", \"@ebay/ui-core-react\", \"9.13.0\");\n addDependency(packageJson, \"dependencies\", \"@evo-web/react\", \"0.4.4\");\n addDependency(\n packageJson,\n \"dependencies\",\n \"react-dom\",\n dependencyVersion(packageJson, \"react-dom\") ?? \"19.2.8\",\n );\n addDependency(packageJson, \"dependencies\", \"server-only\", \"^0.0.1\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"@ebay-dt/bonfire-cli\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"devDependencies\", \"@types/node\", \"^20\");\n addDependency(packageJson, \"devDependencies\", \"@types/react\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"@types/react-dom\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"eslint\", \"^9\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"eslint-config-next\",\n nextExact,\n );\n addDependency(packageJson, \"devDependencies\", \"prettier\", \"^3.9.5\");\n if (options.withItemData) {\n addDependency(\n packageJson,\n \"dependencies\",\n \"@tanstack/react-query\",\n \"^5.104.0\",\n );\n addDependency(packageJson, \"dependencies\", \"zod\", \"^4.4.3\");\n }\n\n const path = join(root, \"package.json\");\n const content = `${JSON.stringify(packageJson, null, 2)}\\n`;\n const existing = await readFile(path, \"utf8\");\n if (JSON.stringify(JSON.parse(existing)) !== JSON.stringify(packageJson)) {\n writes.set(path, content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"merge Bonfire scripts and dependencies\",\n );\n }\n}\n\nexport async function planConversion(\n options: ConvertOptions,\n): Promise<ConversionPlan> {\n const root = resolve(options.root);\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(options.appId)) {\n throw new ConvertError(\n \"app id must contain only letters, numbers, dots, underscores, and hyphens\",\n );\n }\n if (!options.name.trim())\n throw new ConvertError(\"display name must not be empty\");\n const packagePath = join(root, \"package.json\");\n const packageJson = await readJson(packagePath);\n const nextVersion = validateStartingScaffold(packageJson);\n if (!(await exists(join(root, \"src\", \"app\")))) {\n throw new ConvertError(\n \"the starting scaffold must use the src/app App Router\",\n );\n }\n\n const writes = new Map<string, string>();\n const changes: PlannedChange[] = [];\n const removals: string[] = [];\n\n const starterPaths = [\n join(root, \"src/app/layout.tsx\"),\n join(root, \"src/app/page.tsx\"),\n join(root, \"src/app/page.module.css\"),\n join(root, \"src/app/globals.css\"),\n join(root, \"next.config.ts\"),\n join(root, \"README.md\"),\n ...[\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].map(\n (name) => join(root, \"public\", name),\n ),\n ];\n for (const path of starterPaths) {\n await planRemoveStarter(\n root,\n path,\n \"remove unmodified create-next-app content\",\n removals,\n changes,\n );\n }\n const nextBuildDirectory = join(root, \".next\");\n if (await exists(nextBuildDirectory)) {\n removals.push(nextBuildDirectory);\n addChange(\n changes,\n root,\n nextBuildDirectory,\n \"remove\",\n \"clear generated Next.js output\",\n );\n }\n\n const resolvedOptions = { ...options, root };\n const templates = await templateFiles(resolvedOptions);\n for (const file of templates) {\n const path = join(root, file.relativePath);\n if (removals.includes(path)) {\n writes.set(path, file.content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"replace unmodified create-next-app content\",\n );\n continue;\n }\n await planFile(\n root,\n path,\n file.content,\n \"add Bonfire instance scaffold\",\n writes,\n changes,\n );\n }\n\n await planPackageJson(\n root,\n options,\n packageJson,\n nextVersion,\n writes,\n changes,\n );\n\n const tsconfigPath = join(root, \"tsconfig.json\");\n const existingTsconfig = await readFile(tsconfigPath, \"utf8\");\n const tsconfig = await readJson(tsconfigPath);\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<\n string,\n unknown\n >;\n tsconfig.compilerOptions = compilerOptions;\n const paths = compilerOptions[\"paths\"] as Record<string, unknown> | undefined;\n if (paths && JSON.stringify(paths[\"@/*\"]) !== JSON.stringify([\"./src/*\"])) {\n throw new ConvertError(\"tsconfig.json has a conflicting @/* path alias\");\n }\n compilerOptions[\"paths\"] = { ...(paths ?? {}), \"@/*\": [\"./src/*\"] };\n const nextTsconfig = `${JSON.stringify(tsconfig, null, 2)}\\n`;\n if (\n JSON.stringify(JSON.parse(existingTsconfig)) !== JSON.stringify(tsconfig)\n ) {\n writes.set(tsconfigPath, nextTsconfig);\n addChange(\n changes,\n root,\n tsconfigPath,\n \"update\",\n \"retain the Bonfire @/* source alias\",\n );\n }\n\n await planFile(\n root,\n join(root, \"tsconfig.check.json\"),\n '{\\n \"extends\": \"./tsconfig.json\",\\n \"exclude\": [\"node_modules\", \".next\"]\\n}\\n',\n \"add the clean TypeScript check project\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierrc\"),\n '{\\n \"semi\": false,\\n \"singleQuote\": true,\\n \"trailingComma\": \"es5\",\\n \"printWidth\": 80\\n}\\n',\n \"add Bonfire formatting conventions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierignore\"),\n \"# Generated and external files\\n.next/\\nnode_modules/\\npnpm-lock.yaml\\nsrc/app/(prototypes)/**/.claude/settings.json\\n\",\n \"add formatter exclusions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".env.local.example\"),\n \"# Bonfire generates this secret during `pnpm dev`.\\n# Do NOT manually modify or remove this variable.\\nBF_SESSION_SECRET=\\n\\n# Set exactly to lowercase `true` to skip automatic identity-branch preparation.\\nBF_DISABLE_AUTO_BRANCH_SWITCH=\\n\\n# Set to `managed` or `manual` for Bonfire Git management.\\nBF_GIT_MODE=\\n\",\n \"document Bonfire environment setup\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \"public/.gitkeep\"),\n \"\",\n \"retain an explicit public directory\",\n writes,\n changes,\n );\n\n const gitignorePath = join(root, \".gitignore\");\n const gitignore = await fileContent(gitignorePath);\n const mergedGitignore = mergeLines(gitignore, [\n \"# Bonfire local secrets\",\n \".env.local\",\n ]);\n if (mergedGitignore !== (gitignore ?? \"\")) {\n writes.set(gitignorePath, mergedGitignore);\n addChange(\n changes,\n root,\n gitignorePath,\n \"update\",\n \"ignore the generated local session secret\",\n );\n }\n\n const workspacePath = join(root, \"pnpm-workspace.yaml\");\n const workspace = await fileContent(workspacePath);\n const mergedWorkspace = mergeWorkspace(workspace);\n if (mergedWorkspace !== (workspace ?? \"\")) {\n writes.set(workspacePath, mergedWorkspace);\n addChange(\n changes,\n root,\n workspacePath,\n \"update\",\n \"retain the Bonfire pnpm installation policy\",\n );\n }\n const npmrcPath = join(root, \".npmrc\");\n const npmrc = await fileContent(npmrcPath);\n if (\n npmrc &&\n /@ebay-dt:\\s*registry=/u.test(npmrc) &&\n !npmrc.includes(\"@ebay-dt:registry=https://registry.npmjs.org/\")\n ) {\n throw new ConvertError(\".npmrc has a conflicting @ebay-dt registry\");\n }\n const mergedNpmrc = mergeLines(npmrc, [\n \"@ebay-dt:registry=https://registry.npmjs.org/\",\n ]);\n if (mergedNpmrc !== (npmrc ?? \"\")) {\n writes.set(npmrcPath, mergedNpmrc);\n addChange(\n changes,\n root,\n npmrcPath,\n \"update\",\n \"resolve Bonfire packages from public npm\",\n );\n }\n const nvmrcPath = join(root, \".nvmrc\");\n const nvmrc = await fileContent(nvmrcPath);\n if (nvmrc === undefined) {\n await planFile(\n root,\n nvmrcPath,\n \"24\\n\",\n \"select Node.js 24 or newer\",\n writes,\n changes,\n );\n }\n\n const readmePath = join(root, \"README.md\");\n if (removals.includes(readmePath)) {\n writes.set(readmePath, starterReadme(options));\n addChange(\n changes,\n root,\n readmePath,\n \"update\",\n \"replace unmodified create-next-app documentation\",\n );\n } else if (\n !writes.has(readmePath) &&\n (await fileContent(readmePath)) === undefined\n ) {\n await planFile(\n root,\n readmePath,\n starterReadme(options),\n \"add instance setup documentation\",\n writes,\n changes,\n );\n }\n\n return { root, changes, writes, removals, packageJson };\n}\n\nexport async function convert(options: ConvertOptions) {\n const plan = await planConversion(options);\n for (const change of plan.changes) {\n console.log(\n `${options.dryRun ? \"Would \" : \"\"}${change.kind} ${change.path} (${change.reason})`,\n );\n }\n if (options.dryRun) return;\n\n for (const path of plan.removals) {\n await rm(path, {\n force: true,\n recursive: path === join(plan.root, \".next\"),\n });\n }\n for (const [path, content] of plan.writes) {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, content);\n if (path.endsWith(\"context/hooks/block-env-reads.mjs\")) {\n await chmod(path, 0o755);\n }\n }\n\n if (!options.skipInstall) {\n console.log(\"Installing dependencies and updating pnpm-lock.yaml...\");\n await execFileAsync(\"pnpm\", [\"install\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n if (!options.skipInstall) {\n const formatPaths = [...plan.writes.keys()]\n .map((path) => displayPath(plan.root, path))\n .filter((path) => /\\.(?:json|mjs|md|ts|tsx|yaml|yml)$/u.test(path));\n if (formatPaths.length > 0) {\n await execFileAsync(\n \"pnpm\",\n [\"exec\", \"prettier\", \"--write\", ...formatPaths],\n {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n },\n );\n }\n await execFileAsync(\"pnpm\", [\"exec\", \"next\", \"typegen\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n const contextResult = await syncContext({ repositoryRoot: plan.root });\n if (contextResult.written.length > 0 || contextResult.removed.length > 0) {\n console.log(\n `Context synchronized (${contextResult.written.length} written, ${contextResult.removed.length} removed).`,\n );\n }\n console.log(\"Bonfire instance conversion complete.\");\n}\n\nexport function defaultConvertOptions(root = process.cwd()): ConvertOptions {\n const appId = \"bonfire-instance\";\n return {\n root,\n appId,\n name: \"Bonfire Instance\",\n hostname: DEFAULT_HOSTNAME,\n port: DEFAULT_PORT,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n withItemData: true,\n dryRun: false,\n skipInstall: false,\n };\n}\n\nexport const convertDefaults = {\n hostname: DEFAULT_HOSTNAME,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n port: DEFAULT_PORT,\n};\n"]}
|
package/dist/convert.js
CHANGED
|
@@ -288,7 +288,7 @@ async function planPackageJson(root, options, packageJson, nextVersion, writes,
|
|
|
288
288
|
}
|
|
289
289
|
engines.node = ">=24";
|
|
290
290
|
packageJson.packageManager ??= "pnpm@11.25.0";
|
|
291
|
-
const dev = `bonfire prepare --root . && bonfire branch prepare --root . --hostname ${options.hostname} && next dev -p ${options.port}`;
|
|
291
|
+
const dev = `bonfire prepare --root . && bonfire branch prepare --root . --default-hostname "${options.hostname}" && next dev -p ${options.port}`;
|
|
292
292
|
addScript(packageJson, "dev", dev, ["next dev"]);
|
|
293
293
|
addScript(packageJson, "context:sync", "bonfire context sync");
|
|
294
294
|
addScript(packageJson, "context:install", `bonfire context install --app-id ${options.appId}`);
|
package/dist/convert.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport {\n chmod,\n lstat,\n mkdir,\n readFile,\n readdir,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { fileURLToPath } from \"node:url\";\nimport { syncContext } from \"@ebay-dt/bonfire-context\";\nimport { BONFIRE_VERSION, PRESET_VERSION } from \"./release-versions.js\";\n\nconst execFileAsync = promisify(execFile);\nconst TEMPLATE_ROOT = fileURLToPath(\n new URL(\"../templates/instance/\", import.meta.url),\n);\nconst DEFAULT_HOSTNAME = \"github.corp.ebay.com\";\nconst DEFAULT_DEPLOYMENT_ENDPOINT =\n \"https://dtsvc.vip.qa.ebay.com/dt/v1/bonfire-deploy\";\nconst DEFAULT_PORT = 1995;\n\nexport type ConvertOptions = Readonly<{\n root: string;\n appId: string;\n name: string;\n packageName?: string;\n hostname: string;\n port: number;\n deploymentEndpoint: string;\n withItemData: boolean;\n dryRun: boolean;\n skipInstall: boolean;\n}>;\n\ntype PackageJson = {\n name?: unknown;\n scripts?: Record<string, unknown>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n engines?: Record<string, string>;\n packageManager?: unknown;\n [key: string]: unknown;\n};\n\ntype PlannedChange = Readonly<{\n kind: \"add\" | \"update\" | \"remove\";\n path: string;\n reason: string;\n}>;\n\ntype ConversionPlan = Readonly<{\n root: string;\n changes: readonly PlannedChange[];\n writes: ReadonlyMap<string, string>;\n removals: readonly string[];\n packageJson: PackageJson;\n}>;\n\nexport function humanizeAppId(appId: string) {\n return appId\n .replace(/([a-z0-9])([A-Z])/gu, \"$1 $2\")\n .replace(/[._-]+/gu, \" \")\n .trim()\n .split(/\\s+/u)\n .filter(Boolean)\n .map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)\n .join(\" \");\n}\n\nexport class ConvertError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConvertError\";\n }\n}\n\nfunction displayPath(root: string, path: string) {\n return relative(root, path) || \".\";\n}\n\nfunction parseVersion(value: unknown, label: string) {\n if (typeof value !== \"string\") {\n throw new ConvertError(`${label} must be declared in package.json`);\n }\n const match = value.match(/(\\d+)\\.(\\d+)\\.(\\d+)/u);\n if (!match) {\n throw new ConvertError(`${label} has an unsupported version: ${value}`);\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n };\n}\n\nfunction dependencyVersion(packageJson: PackageJson, name: string) {\n return (\n packageJson.dependencies?.[name] ?? packageJson.devDependencies?.[name]\n );\n}\n\nfunction validateStartingScaffold(packageJson: PackageJson) {\n const next = parseVersion(dependencyVersion(packageJson, \"next\"), \"next\");\n if (next.major !== 16 || next.minor < 2) {\n throw new ConvertError(\n `next must be 16.2 or newer within the 16.x line (found ${next.major}.${next.minor}.${next.patch})`,\n );\n }\n const react = parseVersion(dependencyVersion(packageJson, \"react\"), \"react\");\n if (react.major !== 19 || react.minor < 2) {\n throw new ConvertError(\n `react must be 19.2 or newer within the 19.x line (found ${react.major}.${react.minor}.${react.patch})`,\n );\n }\n if (!dependencyVersion(packageJson, \"typescript\")) {\n throw new ConvertError(\"typescript must be declared in package.json\");\n }\n\n if (Number(process.versions.node.split(\".\")[0]) < 24) {\n throw new ConvertError(\n \"Bonfire instance conversion requires Node.js 24 or newer\",\n );\n }\n return next;\n}\n\nasync function readJson(path: string) {\n try {\n return JSON.parse(await readFile(path, \"utf8\")) as PackageJson;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ConvertError(\n `${displayPath(dirname(path), path)} is not valid JSON`,\n );\n }\n throw error;\n }\n}\n\nasync function exists(path: string) {\n try {\n await lstat(path);\n return true;\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return false;\n }\n throw error;\n }\n}\n\nasync function fileContent(path: string) {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction addChange(\n changes: PlannedChange[],\n root: string,\n path: string,\n kind: PlannedChange[\"kind\"],\n reason: string,\n) {\n changes.push({ kind, path: displayPath(root, path), reason });\n}\n\nasync function planFile(\n root: string,\n path: string,\n content: string,\n reason: string,\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const existing = await fileContent(path);\n if (existing === undefined) {\n writes.set(path, content);\n addChange(changes, root, path, \"add\", reason);\n return;\n }\n if (existing === content) return;\n throw new ConvertError(\n `${displayPath(root, path)} already exists and differs from the Bonfire scaffold; resolve it before converting`,\n );\n}\n\nfunction looksLikeNextStarter(path: string, content: string) {\n if (path.endsWith(\"/page.tsx\")) {\n return /Create Next App|[Gg]et started|Looking for a starting point|create-next-app/u.test(\n content,\n );\n }\n if (path.endsWith(\"/layout.tsx\")) {\n return /next\\/font|Geist|Create Next App/u.test(content);\n }\n if (path.endsWith(\"/page.module.css\")) {\n return /\\.page|\\.main|\\.footer|\\.grid/u.test(content);\n }\n if (path.endsWith(\"/globals.css\")) {\n return /--background|--foreground|@import [\"']tailwindcss/u.test(content);\n }\n if (path.endsWith(\"/README.md\")) {\n return /bootstrapped with[\\s\\S]*create-next-app/u.test(content);\n }\n if (path.endsWith(\"/next.config.ts\")) {\n return /config options here/u.test(content);\n }\n return false;\n}\n\nfunction looksLikeStarterAsset(path: string, content: string) {\n const name = path.slice(path.lastIndexOf(\"/\") + 1);\n if (\n ![\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].includes(\n name,\n )\n ) {\n return false;\n }\n return /<svg[\\s\\S]*viewBox=/u.test(content);\n}\n\nasync function planRemoveStarter(\n root: string,\n path: string,\n reason: string,\n removals: string[],\n changes: PlannedChange[],\n) {\n const content = await fileContent(path);\n if (content === undefined) return;\n if (\n content.includes(\"@ebay-dt/bonfire-next\") ||\n content.includes(\"A Bonfire instance for creating\") ||\n content.includes(\"outputFileTracingIncludes\")\n ) {\n return;\n }\n if (\n !looksLikeNextStarter(path, content) &&\n !looksLikeStarterAsset(path, content)\n ) {\n throw new ConvertError(\n `${displayPath(root, path)} is customized; it will not be removed automatically`,\n );\n }\n removals.push(path);\n addChange(changes, root, path, \"remove\", reason);\n}\n\nfunction replaceIdentity(content: string, options: ConvertOptions) {\n return content\n .replaceAll(\"design-sandbox-next\", () => options.appId)\n .replaceAll(\"Design Sandbox\", () => options.name)\n .replaceAll(\"github.corp.ebay.com\", () => options.hostname)\n .replaceAll(DEFAULT_DEPLOYMENT_ENDPOINT, () => options.deploymentEndpoint);\n}\n\nfunction withoutItemGuidance(content: string) {\n const start = content.indexOf(\"### Data fetching\");\n const end = content.indexOf(\"### Viewport sizing\");\n if (start < 0 || end < 0 || end <= start) return content;\n return `${content.slice(0, start)}${content.slice(end)}`;\n}\n\nasync function templateFiles(options: ConvertOptions) {\n const files: Array<{ relativePath: string; content: string }> = [];\n async function visit(directory: string) {\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n const path = join(directory, entry.name);\n const relativePath = relative(TEMPLATE_ROOT, path);\n if (\n !options.withItemData &&\n (relativePath.startsWith(\"src/app/api/items/\") ||\n relativePath.startsWith(\"src/lib/items/\") ||\n relativePath === \"context/skills/item-data/SKILL.md\")\n ) {\n continue;\n }\n if (entry.isDirectory()) {\n await visit(path);\n } else if (entry.isFile()) {\n let content = await readFile(path, \"utf8\");\n content = replaceIdentity(content, options);\n if (!options.withItemData && relativePath === \"context/PROTOTYPE.md\") {\n content = withoutItemGuidance(content);\n }\n files.push({ relativePath, content });\n }\n }\n }\n await visit(TEMPLATE_ROOT);\n return files;\n}\n\nfunction starterReadme(options: ConvertOptions) {\n return `# ${options.name}\\n\\nA Bonfire instance for creating, editing, and sharing prototypes.\\n\\n## Development\\n\\nUse Node.js 24+, install dependencies with pnpm, then run:\\n\\n~~~sh\\npnpm dev\\n~~~\\n\\nThe development command prepares the Bonfire session secret and the local identity branch before starting Next.js on port ${options.port}.\\n\\nRun pnpm context:install once on a machine where agent tooling is desired.\\n`;\n}\n\nfunction addDependency(\n packageJson: PackageJson,\n section: \"dependencies\" | \"devDependencies\",\n name: string,\n version: string,\n) {\n const target = (packageJson[section] ??= {});\n const existing = target[name];\n if (existing !== undefined) {\n if (existing !== version && name.startsWith(\"@ebay-dt/bonfire-\")) {\n throw new ConvertError(\n `${name} is already declared as ${existing}; expected ${version}. Update it explicitly before converting`,\n );\n }\n return;\n }\n target[name] = version;\n}\n\nfunction addScript(\n packageJson: PackageJson,\n name: string,\n value: string,\n allowedExisting: readonly string[] = [],\n) {\n const scripts = (packageJson.scripts ??= {});\n const existing = scripts[name];\n if (existing !== undefined) {\n if (existing !== value && !allowedExisting.includes(String(existing))) {\n throw new ConvertError(\n `package.json script ${name} is customized (${String(existing)}); resolve it before converting`,\n );\n }\n scripts[name] = value;\n return;\n }\n scripts[name] = value;\n}\n\nfunction mergeLines(existing: string | undefined, required: readonly string[]) {\n let result = existing ?? \"\";\n for (const line of required) {\n if (result.split(/\\r?\\n/u).some((entry) => entry.trim() === line)) continue;\n if (result.length > 0 && !result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n return result;\n}\n\nfunction mergeWorkspace(existing: string | undefined) {\n let result = existing ?? \"\";\n if (!/^minimumReleaseAge:/mu.test(result)) {\n result = `# Bonfire publishes lockstep alpha packages that must be installable immediately.\\nminimumReleaseAge: 0\\n${result}`;\n } else if (!/^minimumReleaseAge:\\s*0\\s*$/mu.test(result)) {\n throw new ConvertError(\n \"pnpm-workspace.yaml has a conflicting minimumReleaseAge\",\n );\n }\n const required = [\n \" esbuild: true\",\n \" sharp: true\",\n \" unrs-resolver: true\",\n ];\n for (const line of required) {\n const key = line.trim().split(\":\")[0] ?? \"\";\n const match = result.match(new RegExp(`^\\\\s+${key}:\\\\s*(\\\\S+)\\\\s*$`, \"mu\"));\n if (match && match[1] !== \"true\") {\n // create-next-app currently writes these two false entries. They are\n // starter policy, not an instance decision, so normalize them to the\n // Bonfire installation policy.\n if (match[1] !== \"false\" || ![\"sharp\", \"unrs-resolver\"].includes(key)) {\n throw new ConvertError(\n `pnpm-workspace.yaml has a conflicting allowBuilds.${key} setting`,\n );\n }\n result = result.replace(\n new RegExp(`(^\\\\s+${key}:\\\\s*)false(\\\\s*$)`, \"mu\"),\n \"$1true$2\",\n );\n }\n if (!match) {\n if (!result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n }\n return result;\n}\n\nasync function planPackageJson(\n root: string,\n options: ConvertOptions,\n packageJson: PackageJson,\n nextVersion: { major: number; minor: number; patch: number },\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const packageName =\n options.packageName ??\n (typeof packageJson.name === \"string\" ? packageJson.name : options.appId);\n if (!/^[a-z0-9][a-z0-9._-]*$/u.test(packageName)) {\n throw new ConvertError(`package name is invalid: ${packageName}`);\n }\n packageJson.name = packageName;\n const engines = (packageJson.engines ??= {});\n if (\n engines.node !== undefined &&\n !/^(?:\\^|~|>=)?\\s*2[4-9]|[3-9]\\d/u.test(engines.node)\n ) {\n throw new ConvertError(\n \"package.json engines.node must allow Node.js 24 or newer\",\n );\n }\n engines.node = \">=24\";\n packageJson.packageManager ??= \"pnpm@11.25.0\";\n\n const dev = `bonfire prepare --root . && bonfire branch prepare --root . --hostname ${options.hostname} && next dev -p ${options.port}`;\n addScript(packageJson, \"dev\", dev, [\"next dev\"]);\n addScript(packageJson, \"context:sync\", \"bonfire context sync\");\n addScript(\n packageJson,\n \"context:install\",\n `bonfire context install --app-id ${options.appId}`,\n );\n addScript(\n packageJson,\n \"check\",\n \"tsc --noEmit --project tsconfig.check.json && pnpm context:sync --check\",\n );\n addScript(packageJson, \"format\", \"prettier --write .\");\n addScript(packageJson, \"build\", \"next build\", [\"next build\"]);\n addScript(packageJson, \"start\", \"next start\", [\"next start\"]);\n addScript(packageJson, \"lint\", \"eslint\", [\"eslint\", \"eslint .\"]);\n\n const nextExact = `${nextVersion.major}.${nextVersion.minor}.${nextVersion.patch}`;\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-context\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-core\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-next\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-preset-ebay\",\n PRESET_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-react\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"dependencies\", \"@ebay/ui-core-react\", \"9.13.0\");\n addDependency(packageJson, \"dependencies\", \"@evo-web/react\", \"0.4.4\");\n addDependency(\n packageJson,\n \"dependencies\",\n \"react-dom\",\n dependencyVersion(packageJson, \"react-dom\") ?? \"19.2.8\",\n );\n addDependency(packageJson, \"dependencies\", \"server-only\", \"^0.0.1\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"@ebay-dt/bonfire-cli\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"devDependencies\", \"@types/node\", \"^20\");\n addDependency(packageJson, \"devDependencies\", \"@types/react\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"@types/react-dom\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"eslint\", \"^9\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"eslint-config-next\",\n nextExact,\n );\n addDependency(packageJson, \"devDependencies\", \"prettier\", \"^3.9.5\");\n if (options.withItemData) {\n addDependency(\n packageJson,\n \"dependencies\",\n \"@tanstack/react-query\",\n \"^5.104.0\",\n );\n addDependency(packageJson, \"dependencies\", \"zod\", \"^4.4.3\");\n }\n\n const path = join(root, \"package.json\");\n const content = `${JSON.stringify(packageJson, null, 2)}\\n`;\n const existing = await readFile(path, \"utf8\");\n if (JSON.stringify(JSON.parse(existing)) !== JSON.stringify(packageJson)) {\n writes.set(path, content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"merge Bonfire scripts and dependencies\",\n );\n }\n}\n\nexport async function planConversion(\n options: ConvertOptions,\n): Promise<ConversionPlan> {\n const root = resolve(options.root);\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(options.appId)) {\n throw new ConvertError(\n \"app id must contain only letters, numbers, dots, underscores, and hyphens\",\n );\n }\n if (!options.name.trim())\n throw new ConvertError(\"display name must not be empty\");\n const packagePath = join(root, \"package.json\");\n const packageJson = await readJson(packagePath);\n const nextVersion = validateStartingScaffold(packageJson);\n if (!(await exists(join(root, \"src\", \"app\")))) {\n throw new ConvertError(\n \"the starting scaffold must use the src/app App Router\",\n );\n }\n\n const writes = new Map<string, string>();\n const changes: PlannedChange[] = [];\n const removals: string[] = [];\n\n const starterPaths = [\n join(root, \"src/app/layout.tsx\"),\n join(root, \"src/app/page.tsx\"),\n join(root, \"src/app/page.module.css\"),\n join(root, \"src/app/globals.css\"),\n join(root, \"next.config.ts\"),\n join(root, \"README.md\"),\n ...[\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].map(\n (name) => join(root, \"public\", name),\n ),\n ];\n for (const path of starterPaths) {\n await planRemoveStarter(\n root,\n path,\n \"remove unmodified create-next-app content\",\n removals,\n changes,\n );\n }\n const nextBuildDirectory = join(root, \".next\");\n if (await exists(nextBuildDirectory)) {\n removals.push(nextBuildDirectory);\n addChange(\n changes,\n root,\n nextBuildDirectory,\n \"remove\",\n \"clear generated Next.js output\",\n );\n }\n\n const resolvedOptions = { ...options, root };\n const templates = await templateFiles(resolvedOptions);\n for (const file of templates) {\n const path = join(root, file.relativePath);\n if (removals.includes(path)) {\n writes.set(path, file.content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"replace unmodified create-next-app content\",\n );\n continue;\n }\n await planFile(\n root,\n path,\n file.content,\n \"add Bonfire instance scaffold\",\n writes,\n changes,\n );\n }\n\n await planPackageJson(\n root,\n options,\n packageJson,\n nextVersion,\n writes,\n changes,\n );\n\n const tsconfigPath = join(root, \"tsconfig.json\");\n const existingTsconfig = await readFile(tsconfigPath, \"utf8\");\n const tsconfig = await readJson(tsconfigPath);\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<\n string,\n unknown\n >;\n tsconfig.compilerOptions = compilerOptions;\n const paths = compilerOptions[\"paths\"] as Record<string, unknown> | undefined;\n if (paths && JSON.stringify(paths[\"@/*\"]) !== JSON.stringify([\"./src/*\"])) {\n throw new ConvertError(\"tsconfig.json has a conflicting @/* path alias\");\n }\n compilerOptions[\"paths\"] = { ...(paths ?? {}), \"@/*\": [\"./src/*\"] };\n const nextTsconfig = `${JSON.stringify(tsconfig, null, 2)}\\n`;\n if (\n JSON.stringify(JSON.parse(existingTsconfig)) !== JSON.stringify(tsconfig)\n ) {\n writes.set(tsconfigPath, nextTsconfig);\n addChange(\n changes,\n root,\n tsconfigPath,\n \"update\",\n \"retain the Bonfire @/* source alias\",\n );\n }\n\n await planFile(\n root,\n join(root, \"tsconfig.check.json\"),\n '{\\n \"extends\": \"./tsconfig.json\",\\n \"exclude\": [\"node_modules\", \".next\"]\\n}\\n',\n \"add the clean TypeScript check project\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierrc\"),\n '{\\n \"semi\": false,\\n \"singleQuote\": true,\\n \"trailingComma\": \"es5\",\\n \"printWidth\": 80\\n}\\n',\n \"add Bonfire formatting conventions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierignore\"),\n \"# Generated and external files\\n.next/\\nnode_modules/\\npnpm-lock.yaml\\nsrc/app/(prototypes)/**/.claude/settings.json\\n\",\n \"add formatter exclusions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".env.local.example\"),\n \"# Bonfire generates this secret during `pnpm dev`.\\n# Do NOT manually modify or remove this variable.\\nBF_SESSION_SECRET=\\n\\n# Set exactly to lowercase `true` to skip automatic identity-branch preparation.\\nBF_DISABLE_AUTO_BRANCH_SWITCH=\\n\\n# Set to `managed` or `manual` for Bonfire Git management.\\nBF_GIT_MODE=\\n\",\n \"document Bonfire environment setup\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \"public/.gitkeep\"),\n \"\",\n \"retain an explicit public directory\",\n writes,\n changes,\n );\n\n const gitignorePath = join(root, \".gitignore\");\n const gitignore = await fileContent(gitignorePath);\n const mergedGitignore = mergeLines(gitignore, [\n \"# Bonfire local secrets\",\n \".env.local\",\n ]);\n if (mergedGitignore !== (gitignore ?? \"\")) {\n writes.set(gitignorePath, mergedGitignore);\n addChange(\n changes,\n root,\n gitignorePath,\n \"update\",\n \"ignore the generated local session secret\",\n );\n }\n\n const workspacePath = join(root, \"pnpm-workspace.yaml\");\n const workspace = await fileContent(workspacePath);\n const mergedWorkspace = mergeWorkspace(workspace);\n if (mergedWorkspace !== (workspace ?? \"\")) {\n writes.set(workspacePath, mergedWorkspace);\n addChange(\n changes,\n root,\n workspacePath,\n \"update\",\n \"retain the Bonfire pnpm installation policy\",\n );\n }\n const npmrcPath = join(root, \".npmrc\");\n const npmrc = await fileContent(npmrcPath);\n if (\n npmrc &&\n /@ebay-dt:\\s*registry=/u.test(npmrc) &&\n !npmrc.includes(\"@ebay-dt:registry=https://registry.npmjs.org/\")\n ) {\n throw new ConvertError(\".npmrc has a conflicting @ebay-dt registry\");\n }\n const mergedNpmrc = mergeLines(npmrc, [\n \"@ebay-dt:registry=https://registry.npmjs.org/\",\n ]);\n if (mergedNpmrc !== (npmrc ?? \"\")) {\n writes.set(npmrcPath, mergedNpmrc);\n addChange(\n changes,\n root,\n npmrcPath,\n \"update\",\n \"resolve Bonfire packages from public npm\",\n );\n }\n const nvmrcPath = join(root, \".nvmrc\");\n const nvmrc = await fileContent(nvmrcPath);\n if (nvmrc === undefined) {\n await planFile(\n root,\n nvmrcPath,\n \"24\\n\",\n \"select Node.js 24 or newer\",\n writes,\n changes,\n );\n }\n\n const readmePath = join(root, \"README.md\");\n if (removals.includes(readmePath)) {\n writes.set(readmePath, starterReadme(options));\n addChange(\n changes,\n root,\n readmePath,\n \"update\",\n \"replace unmodified create-next-app documentation\",\n );\n } else if (\n !writes.has(readmePath) &&\n (await fileContent(readmePath)) === undefined\n ) {\n await planFile(\n root,\n readmePath,\n starterReadme(options),\n \"add instance setup documentation\",\n writes,\n changes,\n );\n }\n\n return { root, changes, writes, removals, packageJson };\n}\n\nexport async function convert(options: ConvertOptions) {\n const plan = await planConversion(options);\n for (const change of plan.changes) {\n console.log(\n `${options.dryRun ? \"Would \" : \"\"}${change.kind} ${change.path} (${change.reason})`,\n );\n }\n if (options.dryRun) return;\n\n for (const path of plan.removals) {\n await rm(path, {\n force: true,\n recursive: path === join(plan.root, \".next\"),\n });\n }\n for (const [path, content] of plan.writes) {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, content);\n if (path.endsWith(\"context/hooks/block-env-reads.mjs\")) {\n await chmod(path, 0o755);\n }\n }\n\n if (!options.skipInstall) {\n console.log(\"Installing dependencies and updating pnpm-lock.yaml...\");\n await execFileAsync(\"pnpm\", [\"install\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n if (!options.skipInstall) {\n const formatPaths = [...plan.writes.keys()]\n .map((path) => displayPath(plan.root, path))\n .filter((path) => /\\.(?:json|mjs|md|ts|tsx|yaml|yml)$/u.test(path));\n if (formatPaths.length > 0) {\n await execFileAsync(\n \"pnpm\",\n [\"exec\", \"prettier\", \"--write\", ...formatPaths],\n {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n },\n );\n }\n await execFileAsync(\"pnpm\", [\"exec\", \"next\", \"typegen\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n const contextResult = await syncContext({ repositoryRoot: plan.root });\n if (contextResult.written.length > 0 || contextResult.removed.length > 0) {\n console.log(\n `Context synchronized (${contextResult.written.length} written, ${contextResult.removed.length} removed).`,\n );\n }\n console.log(\"Bonfire instance conversion complete.\");\n}\n\nexport function defaultConvertOptions(root = process.cwd()): ConvertOptions {\n const appId = \"bonfire-instance\";\n return {\n root,\n appId,\n name: \"Bonfire Instance\",\n hostname: DEFAULT_HOSTNAME,\n port: DEFAULT_PORT,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n withItemData: true,\n dryRun: false,\n skipInstall: false,\n };\n}\n\nexport const convertDefaults = {\n hostname: DEFAULT_HOSTNAME,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n port: DEFAULT_PORT,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport {\n chmod,\n lstat,\n mkdir,\n readFile,\n readdir,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { fileURLToPath } from \"node:url\";\nimport { syncContext } from \"@ebay-dt/bonfire-context\";\nimport { BONFIRE_VERSION, PRESET_VERSION } from \"./release-versions.js\";\n\nconst execFileAsync = promisify(execFile);\nconst TEMPLATE_ROOT = fileURLToPath(\n new URL(\"../templates/instance/\", import.meta.url),\n);\nconst DEFAULT_HOSTNAME = \"github.corp.ebay.com\";\nconst DEFAULT_DEPLOYMENT_ENDPOINT =\n \"https://dtsvc.vip.qa.ebay.com/dt/v1/bonfire-deploy\";\nconst DEFAULT_PORT = 1995;\n\nexport type ConvertOptions = Readonly<{\n root: string;\n appId: string;\n name: string;\n packageName?: string;\n hostname: string;\n port: number;\n deploymentEndpoint: string;\n withItemData: boolean;\n dryRun: boolean;\n skipInstall: boolean;\n}>;\n\ntype PackageJson = {\n name?: unknown;\n scripts?: Record<string, unknown>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n engines?: Record<string, string>;\n packageManager?: unknown;\n [key: string]: unknown;\n};\n\ntype PlannedChange = Readonly<{\n kind: \"add\" | \"update\" | \"remove\";\n path: string;\n reason: string;\n}>;\n\ntype ConversionPlan = Readonly<{\n root: string;\n changes: readonly PlannedChange[];\n writes: ReadonlyMap<string, string>;\n removals: readonly string[];\n packageJson: PackageJson;\n}>;\n\nexport function humanizeAppId(appId: string) {\n return appId\n .replace(/([a-z0-9])([A-Z])/gu, \"$1 $2\")\n .replace(/[._-]+/gu, \" \")\n .trim()\n .split(/\\s+/u)\n .filter(Boolean)\n .map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)\n .join(\" \");\n}\n\nexport class ConvertError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConvertError\";\n }\n}\n\nfunction displayPath(root: string, path: string) {\n return relative(root, path) || \".\";\n}\n\nfunction parseVersion(value: unknown, label: string) {\n if (typeof value !== \"string\") {\n throw new ConvertError(`${label} must be declared in package.json`);\n }\n const match = value.match(/(\\d+)\\.(\\d+)\\.(\\d+)/u);\n if (!match) {\n throw new ConvertError(`${label} has an unsupported version: ${value}`);\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n };\n}\n\nfunction dependencyVersion(packageJson: PackageJson, name: string) {\n return (\n packageJson.dependencies?.[name] ?? packageJson.devDependencies?.[name]\n );\n}\n\nfunction validateStartingScaffold(packageJson: PackageJson) {\n const next = parseVersion(dependencyVersion(packageJson, \"next\"), \"next\");\n if (next.major !== 16 || next.minor < 2) {\n throw new ConvertError(\n `next must be 16.2 or newer within the 16.x line (found ${next.major}.${next.minor}.${next.patch})`,\n );\n }\n const react = parseVersion(dependencyVersion(packageJson, \"react\"), \"react\");\n if (react.major !== 19 || react.minor < 2) {\n throw new ConvertError(\n `react must be 19.2 or newer within the 19.x line (found ${react.major}.${react.minor}.${react.patch})`,\n );\n }\n if (!dependencyVersion(packageJson, \"typescript\")) {\n throw new ConvertError(\"typescript must be declared in package.json\");\n }\n\n if (Number(process.versions.node.split(\".\")[0]) < 24) {\n throw new ConvertError(\n \"Bonfire instance conversion requires Node.js 24 or newer\",\n );\n }\n return next;\n}\n\nasync function readJson(path: string) {\n try {\n return JSON.parse(await readFile(path, \"utf8\")) as PackageJson;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ConvertError(\n `${displayPath(dirname(path), path)} is not valid JSON`,\n );\n }\n throw error;\n }\n}\n\nasync function exists(path: string) {\n try {\n await lstat(path);\n return true;\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return false;\n }\n throw error;\n }\n}\n\nasync function fileContent(path: string) {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if (\n error !== null &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction addChange(\n changes: PlannedChange[],\n root: string,\n path: string,\n kind: PlannedChange[\"kind\"],\n reason: string,\n) {\n changes.push({ kind, path: displayPath(root, path), reason });\n}\n\nasync function planFile(\n root: string,\n path: string,\n content: string,\n reason: string,\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const existing = await fileContent(path);\n if (existing === undefined) {\n writes.set(path, content);\n addChange(changes, root, path, \"add\", reason);\n return;\n }\n if (existing === content) return;\n throw new ConvertError(\n `${displayPath(root, path)} already exists and differs from the Bonfire scaffold; resolve it before converting`,\n );\n}\n\nfunction looksLikeNextStarter(path: string, content: string) {\n if (path.endsWith(\"/page.tsx\")) {\n return /Create Next App|[Gg]et started|Looking for a starting point|create-next-app/u.test(\n content,\n );\n }\n if (path.endsWith(\"/layout.tsx\")) {\n return /next\\/font|Geist|Create Next App/u.test(content);\n }\n if (path.endsWith(\"/page.module.css\")) {\n return /\\.page|\\.main|\\.footer|\\.grid/u.test(content);\n }\n if (path.endsWith(\"/globals.css\")) {\n return /--background|--foreground|@import [\"']tailwindcss/u.test(content);\n }\n if (path.endsWith(\"/README.md\")) {\n return /bootstrapped with[\\s\\S]*create-next-app/u.test(content);\n }\n if (path.endsWith(\"/next.config.ts\")) {\n return /config options here/u.test(content);\n }\n return false;\n}\n\nfunction looksLikeStarterAsset(path: string, content: string) {\n const name = path.slice(path.lastIndexOf(\"/\") + 1);\n if (\n ![\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].includes(\n name,\n )\n ) {\n return false;\n }\n return /<svg[\\s\\S]*viewBox=/u.test(content);\n}\n\nasync function planRemoveStarter(\n root: string,\n path: string,\n reason: string,\n removals: string[],\n changes: PlannedChange[],\n) {\n const content = await fileContent(path);\n if (content === undefined) return;\n if (\n content.includes(\"@ebay-dt/bonfire-next\") ||\n content.includes(\"A Bonfire instance for creating\") ||\n content.includes(\"outputFileTracingIncludes\")\n ) {\n return;\n }\n if (\n !looksLikeNextStarter(path, content) &&\n !looksLikeStarterAsset(path, content)\n ) {\n throw new ConvertError(\n `${displayPath(root, path)} is customized; it will not be removed automatically`,\n );\n }\n removals.push(path);\n addChange(changes, root, path, \"remove\", reason);\n}\n\nfunction replaceIdentity(content: string, options: ConvertOptions) {\n return content\n .replaceAll(\"design-sandbox-next\", () => options.appId)\n .replaceAll(\"Design Sandbox\", () => options.name)\n .replaceAll(\"github.corp.ebay.com\", () => options.hostname)\n .replaceAll(DEFAULT_DEPLOYMENT_ENDPOINT, () => options.deploymentEndpoint);\n}\n\nfunction withoutItemGuidance(content: string) {\n const start = content.indexOf(\"### Data fetching\");\n const end = content.indexOf(\"### Viewport sizing\");\n if (start < 0 || end < 0 || end <= start) return content;\n return `${content.slice(0, start)}${content.slice(end)}`;\n}\n\nasync function templateFiles(options: ConvertOptions) {\n const files: Array<{ relativePath: string; content: string }> = [];\n async function visit(directory: string) {\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n const path = join(directory, entry.name);\n const relativePath = relative(TEMPLATE_ROOT, path);\n if (\n !options.withItemData &&\n (relativePath.startsWith(\"src/app/api/items/\") ||\n relativePath.startsWith(\"src/lib/items/\") ||\n relativePath === \"context/skills/item-data/SKILL.md\")\n ) {\n continue;\n }\n if (entry.isDirectory()) {\n await visit(path);\n } else if (entry.isFile()) {\n let content = await readFile(path, \"utf8\");\n content = replaceIdentity(content, options);\n if (!options.withItemData && relativePath === \"context/PROTOTYPE.md\") {\n content = withoutItemGuidance(content);\n }\n files.push({ relativePath, content });\n }\n }\n }\n await visit(TEMPLATE_ROOT);\n return files;\n}\n\nfunction starterReadme(options: ConvertOptions) {\n return `# ${options.name}\\n\\nA Bonfire instance for creating, editing, and sharing prototypes.\\n\\n## Development\\n\\nUse Node.js 24+, install dependencies with pnpm, then run:\\n\\n~~~sh\\npnpm dev\\n~~~\\n\\nThe development command prepares the Bonfire session secret and the local identity branch before starting Next.js on port ${options.port}.\\n\\nRun pnpm context:install once on a machine where agent tooling is desired.\\n`;\n}\n\nfunction addDependency(\n packageJson: PackageJson,\n section: \"dependencies\" | \"devDependencies\",\n name: string,\n version: string,\n) {\n const target = (packageJson[section] ??= {});\n const existing = target[name];\n if (existing !== undefined) {\n if (existing !== version && name.startsWith(\"@ebay-dt/bonfire-\")) {\n throw new ConvertError(\n `${name} is already declared as ${existing}; expected ${version}. Update it explicitly before converting`,\n );\n }\n return;\n }\n target[name] = version;\n}\n\nfunction addScript(\n packageJson: PackageJson,\n name: string,\n value: string,\n allowedExisting: readonly string[] = [],\n) {\n const scripts = (packageJson.scripts ??= {});\n const existing = scripts[name];\n if (existing !== undefined) {\n if (existing !== value && !allowedExisting.includes(String(existing))) {\n throw new ConvertError(\n `package.json script ${name} is customized (${String(existing)}); resolve it before converting`,\n );\n }\n scripts[name] = value;\n return;\n }\n scripts[name] = value;\n}\n\nfunction mergeLines(existing: string | undefined, required: readonly string[]) {\n let result = existing ?? \"\";\n for (const line of required) {\n if (result.split(/\\r?\\n/u).some((entry) => entry.trim() === line)) continue;\n if (result.length > 0 && !result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n return result;\n}\n\nfunction mergeWorkspace(existing: string | undefined) {\n let result = existing ?? \"\";\n if (!/^minimumReleaseAge:/mu.test(result)) {\n result = `# Bonfire publishes lockstep alpha packages that must be installable immediately.\\nminimumReleaseAge: 0\\n${result}`;\n } else if (!/^minimumReleaseAge:\\s*0\\s*$/mu.test(result)) {\n throw new ConvertError(\n \"pnpm-workspace.yaml has a conflicting minimumReleaseAge\",\n );\n }\n const required = [\n \" esbuild: true\",\n \" sharp: true\",\n \" unrs-resolver: true\",\n ];\n for (const line of required) {\n const key = line.trim().split(\":\")[0] ?? \"\";\n const match = result.match(new RegExp(`^\\\\s+${key}:\\\\s*(\\\\S+)\\\\s*$`, \"mu\"));\n if (match && match[1] !== \"true\") {\n // create-next-app currently writes these two false entries. They are\n // starter policy, not an instance decision, so normalize them to the\n // Bonfire installation policy.\n if (match[1] !== \"false\" || ![\"sharp\", \"unrs-resolver\"].includes(key)) {\n throw new ConvertError(\n `pnpm-workspace.yaml has a conflicting allowBuilds.${key} setting`,\n );\n }\n result = result.replace(\n new RegExp(`(^\\\\s+${key}:\\\\s*)false(\\\\s*$)`, \"mu\"),\n \"$1true$2\",\n );\n }\n if (!match) {\n if (!result.endsWith(\"\\n\")) result += \"\\n\";\n result += `${line}\\n`;\n }\n }\n return result;\n}\n\nasync function planPackageJson(\n root: string,\n options: ConvertOptions,\n packageJson: PackageJson,\n nextVersion: { major: number; minor: number; patch: number },\n writes: Map<string, string>,\n changes: PlannedChange[],\n) {\n const packageName =\n options.packageName ??\n (typeof packageJson.name === \"string\" ? packageJson.name : options.appId);\n if (!/^[a-z0-9][a-z0-9._-]*$/u.test(packageName)) {\n throw new ConvertError(`package name is invalid: ${packageName}`);\n }\n packageJson.name = packageName;\n const engines = (packageJson.engines ??= {});\n if (\n engines.node !== undefined &&\n !/^(?:\\^|~|>=)?\\s*2[4-9]|[3-9]\\d/u.test(engines.node)\n ) {\n throw new ConvertError(\n \"package.json engines.node must allow Node.js 24 or newer\",\n );\n }\n engines.node = \">=24\";\n packageJson.packageManager ??= \"pnpm@11.25.0\";\n\n const dev = `bonfire prepare --root . && bonfire branch prepare --root . --default-hostname \"${options.hostname}\" && next dev -p ${options.port}`;\n addScript(packageJson, \"dev\", dev, [\"next dev\"]);\n addScript(packageJson, \"context:sync\", \"bonfire context sync\");\n addScript(\n packageJson,\n \"context:install\",\n `bonfire context install --app-id ${options.appId}`,\n );\n addScript(\n packageJson,\n \"check\",\n \"tsc --noEmit --project tsconfig.check.json && pnpm context:sync --check\",\n );\n addScript(packageJson, \"format\", \"prettier --write .\");\n addScript(packageJson, \"build\", \"next build\", [\"next build\"]);\n addScript(packageJson, \"start\", \"next start\", [\"next start\"]);\n addScript(packageJson, \"lint\", \"eslint\", [\"eslint\", \"eslint .\"]);\n\n const nextExact = `${nextVersion.major}.${nextVersion.minor}.${nextVersion.patch}`;\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-context\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-core\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-next\",\n BONFIRE_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-preset-ebay\",\n PRESET_VERSION,\n );\n addDependency(\n packageJson,\n \"dependencies\",\n \"@ebay-dt/bonfire-react\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"dependencies\", \"@ebay/ui-core-react\", \"9.13.0\");\n addDependency(packageJson, \"dependencies\", \"@evo-web/react\", \"0.4.4\");\n addDependency(\n packageJson,\n \"dependencies\",\n \"react-dom\",\n dependencyVersion(packageJson, \"react-dom\") ?? \"19.2.8\",\n );\n addDependency(packageJson, \"dependencies\", \"server-only\", \"^0.0.1\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"@ebay-dt/bonfire-cli\",\n BONFIRE_VERSION,\n );\n addDependency(packageJson, \"devDependencies\", \"@types/node\", \"^20\");\n addDependency(packageJson, \"devDependencies\", \"@types/react\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"@types/react-dom\", \"^19\");\n addDependency(packageJson, \"devDependencies\", \"eslint\", \"^9\");\n addDependency(\n packageJson,\n \"devDependencies\",\n \"eslint-config-next\",\n nextExact,\n );\n addDependency(packageJson, \"devDependencies\", \"prettier\", \"^3.9.5\");\n if (options.withItemData) {\n addDependency(\n packageJson,\n \"dependencies\",\n \"@tanstack/react-query\",\n \"^5.104.0\",\n );\n addDependency(packageJson, \"dependencies\", \"zod\", \"^4.4.3\");\n }\n\n const path = join(root, \"package.json\");\n const content = `${JSON.stringify(packageJson, null, 2)}\\n`;\n const existing = await readFile(path, \"utf8\");\n if (JSON.stringify(JSON.parse(existing)) !== JSON.stringify(packageJson)) {\n writes.set(path, content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"merge Bonfire scripts and dependencies\",\n );\n }\n}\n\nexport async function planConversion(\n options: ConvertOptions,\n): Promise<ConversionPlan> {\n const root = resolve(options.root);\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(options.appId)) {\n throw new ConvertError(\n \"app id must contain only letters, numbers, dots, underscores, and hyphens\",\n );\n }\n if (!options.name.trim())\n throw new ConvertError(\"display name must not be empty\");\n const packagePath = join(root, \"package.json\");\n const packageJson = await readJson(packagePath);\n const nextVersion = validateStartingScaffold(packageJson);\n if (!(await exists(join(root, \"src\", \"app\")))) {\n throw new ConvertError(\n \"the starting scaffold must use the src/app App Router\",\n );\n }\n\n const writes = new Map<string, string>();\n const changes: PlannedChange[] = [];\n const removals: string[] = [];\n\n const starterPaths = [\n join(root, \"src/app/layout.tsx\"),\n join(root, \"src/app/page.tsx\"),\n join(root, \"src/app/page.module.css\"),\n join(root, \"src/app/globals.css\"),\n join(root, \"next.config.ts\"),\n join(root, \"README.md\"),\n ...[\"file.svg\", \"globe.svg\", \"next.svg\", \"vercel.svg\", \"window.svg\"].map(\n (name) => join(root, \"public\", name),\n ),\n ];\n for (const path of starterPaths) {\n await planRemoveStarter(\n root,\n path,\n \"remove unmodified create-next-app content\",\n removals,\n changes,\n );\n }\n const nextBuildDirectory = join(root, \".next\");\n if (await exists(nextBuildDirectory)) {\n removals.push(nextBuildDirectory);\n addChange(\n changes,\n root,\n nextBuildDirectory,\n \"remove\",\n \"clear generated Next.js output\",\n );\n }\n\n const resolvedOptions = { ...options, root };\n const templates = await templateFiles(resolvedOptions);\n for (const file of templates) {\n const path = join(root, file.relativePath);\n if (removals.includes(path)) {\n writes.set(path, file.content);\n addChange(\n changes,\n root,\n path,\n \"update\",\n \"replace unmodified create-next-app content\",\n );\n continue;\n }\n await planFile(\n root,\n path,\n file.content,\n \"add Bonfire instance scaffold\",\n writes,\n changes,\n );\n }\n\n await planPackageJson(\n root,\n options,\n packageJson,\n nextVersion,\n writes,\n changes,\n );\n\n const tsconfigPath = join(root, \"tsconfig.json\");\n const existingTsconfig = await readFile(tsconfigPath, \"utf8\");\n const tsconfig = await readJson(tsconfigPath);\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<\n string,\n unknown\n >;\n tsconfig.compilerOptions = compilerOptions;\n const paths = compilerOptions[\"paths\"] as Record<string, unknown> | undefined;\n if (paths && JSON.stringify(paths[\"@/*\"]) !== JSON.stringify([\"./src/*\"])) {\n throw new ConvertError(\"tsconfig.json has a conflicting @/* path alias\");\n }\n compilerOptions[\"paths\"] = { ...(paths ?? {}), \"@/*\": [\"./src/*\"] };\n const nextTsconfig = `${JSON.stringify(tsconfig, null, 2)}\\n`;\n if (\n JSON.stringify(JSON.parse(existingTsconfig)) !== JSON.stringify(tsconfig)\n ) {\n writes.set(tsconfigPath, nextTsconfig);\n addChange(\n changes,\n root,\n tsconfigPath,\n \"update\",\n \"retain the Bonfire @/* source alias\",\n );\n }\n\n await planFile(\n root,\n join(root, \"tsconfig.check.json\"),\n '{\\n \"extends\": \"./tsconfig.json\",\\n \"exclude\": [\"node_modules\", \".next\"]\\n}\\n',\n \"add the clean TypeScript check project\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierrc\"),\n '{\\n \"semi\": false,\\n \"singleQuote\": true,\\n \"trailingComma\": \"es5\",\\n \"printWidth\": 80\\n}\\n',\n \"add Bonfire formatting conventions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".prettierignore\"),\n \"# Generated and external files\\n.next/\\nnode_modules/\\npnpm-lock.yaml\\nsrc/app/(prototypes)/**/.claude/settings.json\\n\",\n \"add formatter exclusions\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \".env.local.example\"),\n \"# Bonfire generates this secret during `pnpm dev`.\\n# Do NOT manually modify or remove this variable.\\nBF_SESSION_SECRET=\\n\\n# Set exactly to lowercase `true` to skip automatic identity-branch preparation.\\nBF_DISABLE_AUTO_BRANCH_SWITCH=\\n\\n# Set to `managed` or `manual` for Bonfire Git management.\\nBF_GIT_MODE=\\n\",\n \"document Bonfire environment setup\",\n writes,\n changes,\n );\n await planFile(\n root,\n join(root, \"public/.gitkeep\"),\n \"\",\n \"retain an explicit public directory\",\n writes,\n changes,\n );\n\n const gitignorePath = join(root, \".gitignore\");\n const gitignore = await fileContent(gitignorePath);\n const mergedGitignore = mergeLines(gitignore, [\n \"# Bonfire local secrets\",\n \".env.local\",\n ]);\n if (mergedGitignore !== (gitignore ?? \"\")) {\n writes.set(gitignorePath, mergedGitignore);\n addChange(\n changes,\n root,\n gitignorePath,\n \"update\",\n \"ignore the generated local session secret\",\n );\n }\n\n const workspacePath = join(root, \"pnpm-workspace.yaml\");\n const workspace = await fileContent(workspacePath);\n const mergedWorkspace = mergeWorkspace(workspace);\n if (mergedWorkspace !== (workspace ?? \"\")) {\n writes.set(workspacePath, mergedWorkspace);\n addChange(\n changes,\n root,\n workspacePath,\n \"update\",\n \"retain the Bonfire pnpm installation policy\",\n );\n }\n const npmrcPath = join(root, \".npmrc\");\n const npmrc = await fileContent(npmrcPath);\n if (\n npmrc &&\n /@ebay-dt:\\s*registry=/u.test(npmrc) &&\n !npmrc.includes(\"@ebay-dt:registry=https://registry.npmjs.org/\")\n ) {\n throw new ConvertError(\".npmrc has a conflicting @ebay-dt registry\");\n }\n const mergedNpmrc = mergeLines(npmrc, [\n \"@ebay-dt:registry=https://registry.npmjs.org/\",\n ]);\n if (mergedNpmrc !== (npmrc ?? \"\")) {\n writes.set(npmrcPath, mergedNpmrc);\n addChange(\n changes,\n root,\n npmrcPath,\n \"update\",\n \"resolve Bonfire packages from public npm\",\n );\n }\n const nvmrcPath = join(root, \".nvmrc\");\n const nvmrc = await fileContent(nvmrcPath);\n if (nvmrc === undefined) {\n await planFile(\n root,\n nvmrcPath,\n \"24\\n\",\n \"select Node.js 24 or newer\",\n writes,\n changes,\n );\n }\n\n const readmePath = join(root, \"README.md\");\n if (removals.includes(readmePath)) {\n writes.set(readmePath, starterReadme(options));\n addChange(\n changes,\n root,\n readmePath,\n \"update\",\n \"replace unmodified create-next-app documentation\",\n );\n } else if (\n !writes.has(readmePath) &&\n (await fileContent(readmePath)) === undefined\n ) {\n await planFile(\n root,\n readmePath,\n starterReadme(options),\n \"add instance setup documentation\",\n writes,\n changes,\n );\n }\n\n return { root, changes, writes, removals, packageJson };\n}\n\nexport async function convert(options: ConvertOptions) {\n const plan = await planConversion(options);\n for (const change of plan.changes) {\n console.log(\n `${options.dryRun ? \"Would \" : \"\"}${change.kind} ${change.path} (${change.reason})`,\n );\n }\n if (options.dryRun) return;\n\n for (const path of plan.removals) {\n await rm(path, {\n force: true,\n recursive: path === join(plan.root, \".next\"),\n });\n }\n for (const [path, content] of plan.writes) {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, content);\n if (path.endsWith(\"context/hooks/block-env-reads.mjs\")) {\n await chmod(path, 0o755);\n }\n }\n\n if (!options.skipInstall) {\n console.log(\"Installing dependencies and updating pnpm-lock.yaml...\");\n await execFileAsync(\"pnpm\", [\"install\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n if (!options.skipInstall) {\n const formatPaths = [...plan.writes.keys()]\n .map((path) => displayPath(plan.root, path))\n .filter((path) => /\\.(?:json|mjs|md|ts|tsx|yaml|yml)$/u.test(path));\n if (formatPaths.length > 0) {\n await execFileAsync(\n \"pnpm\",\n [\"exec\", \"prettier\", \"--write\", ...formatPaths],\n {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n },\n );\n }\n await execFileAsync(\"pnpm\", [\"exec\", \"next\", \"typegen\"], {\n cwd: plan.root,\n maxBuffer: 10 * 1024 * 1024,\n });\n }\n\n const contextResult = await syncContext({ repositoryRoot: plan.root });\n if (contextResult.written.length > 0 || contextResult.removed.length > 0) {\n console.log(\n `Context synchronized (${contextResult.written.length} written, ${contextResult.removed.length} removed).`,\n );\n }\n console.log(\"Bonfire instance conversion complete.\");\n}\n\nexport function defaultConvertOptions(root = process.cwd()): ConvertOptions {\n const appId = \"bonfire-instance\";\n return {\n root,\n appId,\n name: \"Bonfire Instance\",\n hostname: DEFAULT_HOSTNAME,\n port: DEFAULT_PORT,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n withItemData: true,\n dryRun: false,\n skipInstall: false,\n };\n}\n\nexport const convertDefaults = {\n hostname: DEFAULT_HOSTNAME,\n deploymentEndpoint: DEFAULT_DEPLOYMENT_ENDPOINT,\n port: DEFAULT_PORT,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-versions.d.ts","sourceRoot":"","sources":["../src/release-versions.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAChD,eAAO,MAAM,cAAc,UAAU,CAAC","sourcesContent":["// Generated by scripts/generate-release-versions.mjs during the package build.\nexport const BONFIRE_VERSION = \"0.2.0-alpha.
|
|
1
|
+
{"version":3,"file":"release-versions.d.ts","sourceRoot":"","sources":["../src/release-versions.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAChD,eAAO,MAAM,cAAc,UAAU,CAAC","sourcesContent":["// Generated by scripts/generate-release-versions.mjs during the package build.\nexport const BONFIRE_VERSION = \"0.2.0-alpha.11\";\nexport const PRESET_VERSION = \"0.1.0\";\n"]}
|
package/dist/release-versions.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-versions.js","sourceRoot":"","sources":["../src/release-versions.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAChD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC","sourcesContent":["// Generated by scripts/generate-release-versions.mjs during the package build.\nexport const BONFIRE_VERSION = \"0.2.0-alpha.
|
|
1
|
+
{"version":3,"file":"release-versions.js","sourceRoot":"","sources":["../src/release-versions.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAChD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC","sourcesContent":["// Generated by scripts/generate-release-versions.mjs during the package build.\nexport const BONFIRE_VERSION = \"0.2.0-alpha.11\";\nexport const PRESET_VERSION = \"0.1.0\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ebay-dt/bonfire-cli",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.11",
|
|
4
4
|
"description": "The Bonfire command-line tool.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ebay-dt/bonfire-context": "0.2.0-alpha.
|
|
34
|
+
"@ebay-dt/bonfire-context": "0.2.0-alpha.11",
|
|
35
35
|
"@next/env": "16.3.4",
|
|
36
|
-
"@ebay-dt/bonfire-core": "0.2.0-alpha.
|
|
37
|
-
"@ebay-dt/bonfire-node": "0.2.0-alpha.
|
|
36
|
+
"@ebay-dt/bonfire-core": "0.2.0-alpha.11",
|
|
37
|
+
"@ebay-dt/bonfire-node": "0.2.0-alpha.11"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@repo/eslint-config": "0.0.0",
|
|
@@ -39,3 +39,11 @@ export async function deployPrototype(input: PrototypeCommandInput) {
|
|
|
39
39
|
export async function retryPublishPrototype(input: PrototypeCommandInput) {
|
|
40
40
|
return bonfire.prototypes.actions.retryPublish!(input);
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
export async function getPendingPrototypeRecovery() {
|
|
44
|
+
return bonfire.prototypes.actions.getPendingRecovery();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function retryPendingPrototypePublication(recoveryId: string) {
|
|
48
|
+
return bonfire.prototypes.actions.retryPendingPublication(recoveryId);
|
|
49
|
+
}
|
|
@@ -18,6 +18,10 @@ export async function retryRepositoryUpdate() {
|
|
|
18
18
|
return bonfire.prototypes.repository.retry();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export async function retryRepositoryPreparation() {
|
|
22
|
+
return bonfire.prototypes.repository.retryPreparation!();
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
export async function saveRepositoryPrototype(ref: {
|
|
22
26
|
login: string;
|
|
23
27
|
slug: string;
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
duplicatePrototype,
|
|
10
10
|
editPrototype,
|
|
11
11
|
deployPrototype,
|
|
12
|
+
getPendingPrototypeRecovery,
|
|
13
|
+
retryPendingPrototypePublication,
|
|
12
14
|
retryPublishPrototype,
|
|
13
15
|
savePrototype,
|
|
14
16
|
} from "@/actions/prototypes";
|
|
@@ -17,6 +19,7 @@ import {
|
|
|
17
19
|
checkRepository,
|
|
18
20
|
getRepositorySummary,
|
|
19
21
|
retryRepositoryUpdate,
|
|
22
|
+
retryRepositoryPreparation,
|
|
20
23
|
saveRepositoryPrototype,
|
|
21
24
|
discardRepositoryPrototype,
|
|
22
25
|
} from "@/actions/repository";
|
|
@@ -51,6 +54,7 @@ export default async function RootLayout({
|
|
|
51
54
|
check: checkRepository,
|
|
52
55
|
applyUpdates: applyRepositoryUpdates,
|
|
53
56
|
retry: retryRepositoryUpdate,
|
|
57
|
+
retryPreparation: retryRepositoryPreparation,
|
|
54
58
|
save: saveRepositoryPrototype,
|
|
55
59
|
discard: discardRepositoryPrototype,
|
|
56
60
|
}}
|
|
@@ -61,6 +65,8 @@ export default async function RootLayout({
|
|
|
61
65
|
delete: deletePrototype,
|
|
62
66
|
save: savePrototype,
|
|
63
67
|
discard: discardPrototype,
|
|
68
|
+
getPendingRecovery: getPendingPrototypeRecovery,
|
|
69
|
+
retryPendingPublication: retryPendingPrototypePublication,
|
|
64
70
|
...(lifecycleEnabled
|
|
65
71
|
? {
|
|
66
72
|
deploy: deployPrototype,
|
|
@@ -12,9 +12,17 @@ const deploymentProvider = createDeploymentProvider({
|
|
|
12
12
|
export const bonfire = createBonfireNext({
|
|
13
13
|
appId: "design-sandbox-next",
|
|
14
14
|
name: "Design Sandbox",
|
|
15
|
-
auth: {
|
|
15
|
+
auth: {
|
|
16
|
+
github: {
|
|
17
|
+
// BF_GITHUB_HOSTNAME is loaded by Next from .env.local before this config.
|
|
18
|
+
hostname: process.env.BF_GITHUB_HOSTNAME ?? "github.corp.ebay.com",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
16
21
|
themes,
|
|
17
22
|
repositoryRoot: process.cwd(),
|
|
23
|
+
prototypeRoot: process.env.BF_PROTOTYPE_ROOT,
|
|
24
|
+
remote: process.env.BF_GIT_REMOTE,
|
|
25
|
+
gitMode: process.env.BF_GIT_MODE as "managed" | "manual" | undefined,
|
|
18
26
|
primaryBranch: process.env.BF_PROTOTYPE_BASE_BRANCH,
|
|
19
27
|
sessionSecret: process.env.BF_SESSION_SECRET,
|
|
20
28
|
disableAutoBranchSwitch: process.env.BF_DISABLE_AUTO_BRANCH_SWITCH,
|