@contentrail/cli 0.2.2 → 0.2.3
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 +36 -28
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +223 -140
- package/dist/cli.js.map +1 -1
- package/dist/commands/connect.d.ts +3 -0
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +37 -8
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +81 -16
- package/dist/commands/init.js.map +1 -1
- package/dist/install/plan.d.ts +8 -0
- package/dist/install/plan.d.ts.map +1 -0
- package/dist/install/plan.js +29 -0
- package/dist/install/plan.js.map +1 -0
- package/dist/install/run.d.ts +5 -0
- package/dist/install/run.d.ts.map +1 -0
- package/dist/install/run.js +80 -0
- package/dist/install/run.js.map +1 -0
- package/dist/interactive/clack-host.d.ts +3 -0
- package/dist/interactive/clack-host.d.ts.map +1 -0
- package/dist/interactive/clack-host.js +47 -0
- package/dist/interactive/clack-host.js.map +1 -0
- package/dist/interactive/connect-wizard.d.ts +17 -0
- package/dist/interactive/connect-wizard.d.ts.map +1 -0
- package/dist/interactive/connect-wizard.js +41 -0
- package/dist/interactive/connect-wizard.js.map +1 -0
- package/dist/interactive/init-wizard.d.ts +12 -0
- package/dist/interactive/init-wizard.d.ts.map +1 -0
- package/dist/interactive/init-wizard.js +73 -0
- package/dist/interactive/init-wizard.js.map +1 -0
- package/dist/interactive/is-interactive.d.ts +9 -0
- package/dist/interactive/is-interactive.d.ts.map +1 -0
- package/dist/interactive/is-interactive.js +19 -0
- package/dist/interactive/is-interactive.js.map +1 -0
- package/dist/interactive/menu.d.ts +4 -0
- package/dist/interactive/menu.d.ts.map +1 -0
- package/dist/interactive/menu.js +50 -0
- package/dist/interactive/menu.js.map +1 -0
- package/dist/interactive/types.d.ts +34 -0
- package/dist/interactive/types.d.ts.map +1 -0
- package/dist/interactive/types.js +2 -0
- package/dist/interactive/types.js.map +1 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
# `@contentrail/cli`
|
|
2
2
|
|
|
3
|
-
Node.js CLI for ContentRail local development (ADR 020).
|
|
3
|
+
Node.js CLI for ContentRail local development (ADR 020 / ADR 029).
|
|
4
4
|
|
|
5
5
|
Requires **Node.js ≥ 22**. Init works on any static site (`framework: "static"`).
|
|
6
6
|
Astro and Vite have extra helpers (Astro **7.3.8**, Vite **8.3.5**;
|
|
7
7
|
`@contentrail/astro` needs Node ≥ **22.12**).
|
|
8
8
|
|
|
9
|
-
## Install
|
|
10
|
-
|
|
11
|
-
### Monorepo
|
|
9
|
+
## Install (one package)
|
|
12
10
|
|
|
13
11
|
```sh
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
pnpm exec contentrail --help
|
|
12
|
+
npm i -D @contentrail/cli
|
|
13
|
+
npx contentrail
|
|
17
14
|
```
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
On a TTY, `contentrail` opens an interactive menu: Setup, Connect, Doctor,
|
|
17
|
+
Status, Deploy. Setup scaffolds files and can install the other `@contentrail/*`
|
|
18
|
+
packages for your framework. You still configure Git + Cloudflare (tokens stay
|
|
19
|
+
in env / the dashboard — never in `contentrail.config.json`).
|
|
20
|
+
|
|
21
|
+
Non-interactive / CI: pass commands and `-y` / `--yes`. Use `init --install` to
|
|
22
|
+
add packages without prompts.
|
|
23
|
+
|
|
24
|
+
### Monorepo
|
|
20
25
|
|
|
21
26
|
```sh
|
|
22
|
-
pnpm
|
|
27
|
+
pnpm install
|
|
28
|
+
pnpm --filter @contentrail/cli build
|
|
23
29
|
pnpm exec contentrail --help
|
|
24
30
|
```
|
|
25
31
|
|
|
@@ -28,18 +34,21 @@ schemas use Zod **`^4.6.7`** via `@contentrail/core`.
|
|
|
28
34
|
|
|
29
35
|
## Commands
|
|
30
36
|
|
|
31
|
-
| Command | Purpose
|
|
32
|
-
| --------------------------- |
|
|
33
|
-
| `contentrail
|
|
34
|
-
| `contentrail
|
|
35
|
-
| `contentrail
|
|
36
|
-
| `contentrail
|
|
37
|
-
| `contentrail
|
|
38
|
-
| `contentrail
|
|
39
|
-
| `contentrail
|
|
40
|
-
| `contentrail
|
|
41
|
-
| `contentrail
|
|
42
|
-
| `contentrail
|
|
37
|
+
| Command | Purpose |
|
|
38
|
+
| --------------------------- | --------------------------------------------------------------------------- |
|
|
39
|
+
| `contentrail` | Interactive control panel (TTY) |
|
|
40
|
+
| `contentrail init` | Scaffold config + optional `--install` of ContentRail packages |
|
|
41
|
+
| `contentrail validate` | Validate config + local JSON content |
|
|
42
|
+
| `contentrail build` | Validate, then run `package.json` build script |
|
|
43
|
+
| `contentrail doctor` | Diagnose setup (no secret values printed) |
|
|
44
|
+
| `contentrail status` | Summarize local readiness |
|
|
45
|
+
| `contentrail dev` | Run `package.json` `dev` |
|
|
46
|
+
| `contentrail import` | CSV → validated JSON for a registered collection |
|
|
47
|
+
| `contentrail publish` | POST local JSON to `publishApiUrl` (env token) |
|
|
48
|
+
| `contentrail connect` | GitHub origin + Cloudflare Pages project (interactive or `--confirm --yes`) |
|
|
49
|
+
| `contentrail deploy` | Build and deploy to Pages |
|
|
50
|
+
| `contentrail deploy status` | Pages deployment status (`CF_API_TOKEN`) |
|
|
51
|
+
| `contentrail pages setup` | Alias for connect |
|
|
43
52
|
|
|
44
53
|
`rollback` is API-only. `publish` never sends GitHub tokens (ADR 020). See `docs/CONFIGURATION.md`.
|
|
45
54
|
|
|
@@ -71,13 +80,12 @@ schemas use Zod **`^4.6.7`** via `@contentrail/core`.
|
|
|
71
80
|
|
|
72
81
|
## Typical workflow
|
|
73
82
|
|
|
74
|
-
1. Create an Astro, Vite,
|
|
75
|
-
2.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
6. Framework `dev` / `contentrail build`
|
|
83
|
+
1. Create an Astro, Vite, Next.js, or static site.
|
|
84
|
+
2. `npm i -D @contentrail/cli` then `npx contentrail` → **Setup** (installs the rest).
|
|
85
|
+
3. Export `CF_API_TOKEN` (never commit it) → **Connect** for Pages.
|
|
86
|
+
4. Edit collections / JSON under `content/` (or use `/admin`).
|
|
87
|
+
5. `npx contentrail validate` / `doctor`
|
|
88
|
+
6. Framework `dev` / `contentrail build` / **Deploy**
|
|
81
89
|
7. For `/admin`, add `@contentrail/editor` + `preact@^10.26.0` (`docs/ADMIN.md`)
|
|
82
90
|
8. `contentrail doctor` when something fails
|
|
83
91
|
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExitCode } from "./exit-codes.js";
|
|
2
|
+
import type { InstallDepsFn, PromptHost } from "./interactive/types.js";
|
|
2
3
|
export interface RunCliOptions {
|
|
3
4
|
readonly cwd?: string;
|
|
4
5
|
readonly stdout?: NodeJS.WritableStream;
|
|
@@ -6,6 +7,10 @@ export interface RunCliOptions {
|
|
|
6
7
|
readonly env?: NodeJS.ProcessEnv;
|
|
7
8
|
readonly fetchImpl?: typeof fetch;
|
|
8
9
|
readonly gitRemoteUrl?: string;
|
|
10
|
+
/** Force interactive UI on/off (tests). Default: TTY + non-CI detection. */
|
|
11
|
+
readonly interactive?: boolean;
|
|
12
|
+
readonly prompts?: PromptHost;
|
|
13
|
+
readonly installDeps?: InstallDepsFn;
|
|
9
14
|
}
|
|
10
15
|
export declare function runCli(argv: readonly string[], options?: RunCliOptions): Promise<ExitCode>;
|
|
11
16
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAI3C,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA8IxE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACxC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;CACtC;AAED,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,QAAQ,CAAC,CAyFnB"}
|
package/dist/cli.js
CHANGED
|
@@ -12,16 +12,25 @@ import { runStatus } from "./commands/status.js";
|
|
|
12
12
|
import { runValidate } from "./commands/validate.js";
|
|
13
13
|
import { loadProject } from "./config/load.js";
|
|
14
14
|
import { ExitCode } from "./exit-codes.js";
|
|
15
|
+
import { createClackPromptHost } from "./interactive/clack-host.js";
|
|
16
|
+
import { canUseInteractiveUi } from "./interactive/is-interactive.js";
|
|
17
|
+
import { runMainMenu } from "./interactive/menu.js";
|
|
18
|
+
import { createPackageInstallRunner } from "./install/run.js";
|
|
15
19
|
import { createLogger } from "./util/print.js";
|
|
16
20
|
import { findProjectRoot } from "./util/paths.js";
|
|
17
21
|
const VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
18
|
-
const HELP = `ContentRail CLI —
|
|
22
|
+
const HELP = `ContentRail CLI — developer control panel for your static site
|
|
19
23
|
|
|
20
24
|
Usage:
|
|
25
|
+
contentrail Interactive menu (TTY)
|
|
21
26
|
contentrail <command> [options]
|
|
22
27
|
|
|
28
|
+
Install once:
|
|
29
|
+
npm i -D @contentrail/cli
|
|
30
|
+
npx contentrail
|
|
31
|
+
|
|
23
32
|
Commands:
|
|
24
|
-
init Add ContentRail
|
|
33
|
+
init Add ContentRail + optionally install packages for this site
|
|
25
34
|
validate Validate configuration and local JSON content
|
|
26
35
|
build Validate then run the project build script
|
|
27
36
|
doctor Diagnose common setup problems
|
|
@@ -43,12 +52,13 @@ Global options:
|
|
|
43
52
|
init options:
|
|
44
53
|
--framework <astro|vite|next|static> Force framework (default: auto-detect)
|
|
45
54
|
--force Overwrite existing generated files
|
|
55
|
+
--install Install ContentRail packages with the project package manager
|
|
46
56
|
--no-editor Skip contentrail.editor.json
|
|
47
57
|
--no-functions Skip Pages Functions templates
|
|
48
|
-
-y, --yes Non-interactive; accept defaults
|
|
58
|
+
-y, --yes Non-interactive; accept defaults (skips prompts)
|
|
49
59
|
|
|
50
60
|
connect / deploy:
|
|
51
|
-
--confirm --yes Required to create or change Pages projects
|
|
61
|
+
--confirm --yes Required to create or change Pages projects (non-interactive)
|
|
52
62
|
--account-id --project Cloudflare account and Pages project name
|
|
53
63
|
--skip-build Deploy without running the site build
|
|
54
64
|
|
|
@@ -66,7 +76,7 @@ deploy status options:
|
|
|
66
76
|
--project <pages-project-name>
|
|
67
77
|
|
|
68
78
|
pages setup options:
|
|
69
|
-
--confirm Required before any Cloudflare mutation
|
|
79
|
+
--confirm Required before any Cloudflare mutation
|
|
70
80
|
-y, --yes Non-interactive confirmation
|
|
71
81
|
|
|
72
82
|
Exit codes:
|
|
@@ -78,13 +88,16 @@ Exit codes:
|
|
|
78
88
|
Notes:
|
|
79
89
|
rollback is not a CLI command. Use the authenticated Worker/Pages API.
|
|
80
90
|
CLI publish never sends GitHub tokens; it uses CONTENTRAIL_PUBLISH_TOKEN.
|
|
91
|
+
Secrets never go in contentrail.config.json.
|
|
81
92
|
`;
|
|
82
93
|
function printCommandHelp(command) {
|
|
83
94
|
switch (command) {
|
|
84
95
|
case "init":
|
|
85
|
-
return `Usage: contentrail init [--framework astro|vite|static] [--force] [--
|
|
96
|
+
return `Usage: contentrail init [--framework astro|vite|next|static] [--force] [--install] [--no-editor] [--no-functions] [--dry-run] [-y]
|
|
86
97
|
|
|
87
98
|
Creates contentrail.config.json, a sample collection module, and sample JSON.
|
|
99
|
+
With --install (or interactive Setup), installs the ContentRail packages this
|
|
100
|
+
site needs so you only add @contentrail/cli yourself.
|
|
88
101
|
Works on Next.js, React, vanilla, Astro, and Vite sites. Does not generate the public site.
|
|
89
102
|
Never overwrites existing files unless --force is set.`;
|
|
90
103
|
case "validate":
|
|
@@ -138,141 +151,192 @@ Prints the Cloudflare automation capability map. Does not mutate production.`;
|
|
|
138
151
|
export async function runCli(argv, options) {
|
|
139
152
|
const log = createLogger(options?.stdout, options?.stderr);
|
|
140
153
|
const baseCwd = options?.cwd ?? process.cwd();
|
|
154
|
+
const env = options?.env ?? process.env;
|
|
155
|
+
const prompts = options?.prompts ?? createClackPromptHost();
|
|
156
|
+
const installDeps = options?.installDeps ?? createPackageInstallRunner({ env });
|
|
141
157
|
try {
|
|
142
158
|
const { command, subcommand, flags, cwd } = parseArgv(argv, baseCwd);
|
|
159
|
+
const interactive = options?.interactive ??
|
|
160
|
+
(canUseInteractiveUi(env) && !flags.yes && !flags.help && !flags.version);
|
|
143
161
|
if (flags.version) {
|
|
144
162
|
log.info(VERSION);
|
|
145
163
|
return ExitCode.Success;
|
|
146
164
|
}
|
|
147
|
-
if (
|
|
148
|
-
log.info(command !== undefined
|
|
149
|
-
? printCommandHelp(command)
|
|
150
|
-
: HELP);
|
|
165
|
+
if (flags.help) {
|
|
166
|
+
log.info(command !== undefined ? printCommandHelp(command) : HELP);
|
|
151
167
|
return ExitCode.Success;
|
|
152
168
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
framework !== "static" &&
|
|
162
|
-
framework !== "next") {
|
|
163
|
-
log.error('--framework must be "astro", "vite", "next", or "static".');
|
|
164
|
-
return ExitCode.Usage;
|
|
165
|
-
}
|
|
166
|
-
return runInit({
|
|
167
|
-
projectRoot,
|
|
168
|
-
...(framework !== undefined ? { framework } : {}),
|
|
169
|
-
force: flags.force,
|
|
170
|
-
withEditor: flags.withEditor,
|
|
171
|
-
withFunctions: flags.withFunctions,
|
|
172
|
-
dryRun: flags.dryRun,
|
|
173
|
-
yes: flags.yes,
|
|
174
|
-
}, log);
|
|
169
|
+
if (command === "help") {
|
|
170
|
+
log.info(HELP);
|
|
171
|
+
return ExitCode.Success;
|
|
172
|
+
}
|
|
173
|
+
if (command === undefined) {
|
|
174
|
+
if (!interactive) {
|
|
175
|
+
log.info(HELP);
|
|
176
|
+
return ExitCode.Success;
|
|
175
177
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return
|
|
178
|
+
const action = await runMainMenu(prompts, log);
|
|
179
|
+
if (action === "cancelled" || action === "exit") {
|
|
180
|
+
return ExitCode.Success;
|
|
179
181
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return
|
|
182
|
+
if (action === "help") {
|
|
183
|
+
log.info(HELP);
|
|
184
|
+
return ExitCode.Success;
|
|
183
185
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
186
|
+
return await dispatchCommand(action, {
|
|
187
|
+
projectRoot: findProjectRoot(cwd),
|
|
188
|
+
flags: {
|
|
189
|
+
...flags,
|
|
190
|
+
yes: false,
|
|
191
|
+
},
|
|
192
|
+
env,
|
|
193
|
+
log,
|
|
194
|
+
interactive: true,
|
|
195
|
+
prompts,
|
|
196
|
+
installDeps,
|
|
197
|
+
...(options !== undefined ? { options } : {}),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
const projectRoot = findProjectRoot(cwd);
|
|
201
|
+
return await dispatchCommand(command, {
|
|
202
|
+
projectRoot,
|
|
203
|
+
...(subcommand !== undefined ? { subcommand } : {}),
|
|
204
|
+
flags,
|
|
205
|
+
env,
|
|
206
|
+
log,
|
|
207
|
+
interactive: interactive && !flags.yes,
|
|
208
|
+
prompts,
|
|
209
|
+
installDeps,
|
|
210
|
+
...(options !== undefined ? { options } : {}),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
215
|
+
log.error(message);
|
|
216
|
+
if (/Unknown option|Unexpected argument|requires a directory|--framework requires/i.test(message)) {
|
|
217
|
+
return ExitCode.Usage;
|
|
218
|
+
}
|
|
219
|
+
if (/contentrail\.config\.json|Invalid contentrail|collections module|escapes the project/i.test(message)) {
|
|
220
|
+
return ExitCode.Config;
|
|
221
|
+
}
|
|
222
|
+
return ExitCode.Failure;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async function dispatchCommand(command, ctx) {
|
|
226
|
+
const { projectRoot, subcommand, flags, env, log, interactive, prompts, installDeps, options, } = ctx;
|
|
227
|
+
switch (command) {
|
|
228
|
+
case "setup":
|
|
229
|
+
case "init": {
|
|
230
|
+
const framework = flags.framework;
|
|
231
|
+
if (framework !== undefined &&
|
|
232
|
+
framework !== "astro" &&
|
|
233
|
+
framework !== "vite" &&
|
|
234
|
+
framework !== "static" &&
|
|
235
|
+
framework !== "next") {
|
|
236
|
+
log.error('--framework must be "astro", "vite", "next", or "static".');
|
|
237
|
+
return ExitCode.Usage;
|
|
202
238
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
239
|
+
const useWizard = interactive && (command === "setup" || !flags.yes);
|
|
240
|
+
return runInit({
|
|
241
|
+
projectRoot,
|
|
242
|
+
...(framework !== undefined ? { framework } : {}),
|
|
243
|
+
force: flags.force,
|
|
244
|
+
...(useWizard && !flags.editorFlagSet
|
|
245
|
+
? {}
|
|
246
|
+
: { withEditor: flags.withEditor }),
|
|
247
|
+
...(useWizard && !flags.functionsFlagSet
|
|
248
|
+
? {}
|
|
249
|
+
: { withFunctions: flags.withFunctions }),
|
|
250
|
+
dryRun: flags.dryRun,
|
|
251
|
+
yes: flags.yes,
|
|
252
|
+
install: flags.install,
|
|
253
|
+
interactive: useWizard,
|
|
254
|
+
prompts,
|
|
255
|
+
installDeps,
|
|
256
|
+
}, log);
|
|
257
|
+
}
|
|
258
|
+
case "validate": {
|
|
259
|
+
const project = await loadProject(projectRoot);
|
|
260
|
+
return (await runValidate(project, log)).code;
|
|
261
|
+
}
|
|
262
|
+
case "build": {
|
|
263
|
+
const project = await loadProject(projectRoot);
|
|
264
|
+
return runBuild(project, log);
|
|
265
|
+
}
|
|
266
|
+
case "doctor":
|
|
267
|
+
return runDoctor(projectRoot, log);
|
|
268
|
+
case "status":
|
|
269
|
+
return runStatus(projectRoot, log);
|
|
270
|
+
case "dev":
|
|
271
|
+
return runDev(projectRoot, log);
|
|
272
|
+
case "import": {
|
|
273
|
+
if (flags.collection === undefined || flags.file === undefined) {
|
|
274
|
+
log.error("import requires --collection and --file.");
|
|
275
|
+
return ExitCode.Usage;
|
|
224
276
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
277
|
+
return runImport({
|
|
278
|
+
projectRoot,
|
|
279
|
+
collection: flags.collection,
|
|
280
|
+
file: flags.file,
|
|
281
|
+
dryRun: flags.dryRun,
|
|
282
|
+
force: flags.force,
|
|
283
|
+
}, log);
|
|
284
|
+
}
|
|
285
|
+
case "publish": {
|
|
286
|
+
if (flags.collection === undefined) {
|
|
287
|
+
log.error("publish requires --collection.");
|
|
288
|
+
return ExitCode.Usage;
|
|
289
|
+
}
|
|
290
|
+
return runPublish({
|
|
291
|
+
projectRoot,
|
|
292
|
+
collection: flags.collection,
|
|
293
|
+
dryRun: flags.dryRun,
|
|
294
|
+
env,
|
|
295
|
+
...(flags.expectedVersion !== undefined
|
|
296
|
+
? {
|
|
297
|
+
expectedVersion: flags.expectedVersion === "null"
|
|
298
|
+
? null
|
|
299
|
+
: flags.expectedVersion,
|
|
300
|
+
}
|
|
301
|
+
: {}),
|
|
302
|
+
...(options?.fetchImpl !== undefined
|
|
303
|
+
? { fetchImpl: options.fetchImpl }
|
|
304
|
+
: {}),
|
|
305
|
+
}, log);
|
|
306
|
+
}
|
|
307
|
+
case "connect":
|
|
308
|
+
case "pages": {
|
|
309
|
+
if (command === "pages" && subcommand !== "setup") {
|
|
310
|
+
log.error("Use `contentrail pages setup` or `contentrail connect`.");
|
|
311
|
+
return ExitCode.Usage;
|
|
250
312
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
313
|
+
return runConnect({
|
|
314
|
+
projectRoot,
|
|
315
|
+
dryRun: flags.dryRun,
|
|
316
|
+
confirm: flags.confirm,
|
|
317
|
+
yes: flags.yes,
|
|
318
|
+
env,
|
|
319
|
+
interactive,
|
|
320
|
+
prompts,
|
|
321
|
+
...(flags.accountId !== undefined
|
|
322
|
+
? { accountId: flags.accountId }
|
|
323
|
+
: {}),
|
|
324
|
+
...(flags.project !== undefined
|
|
325
|
+
? { projectName: flags.project }
|
|
326
|
+
: {}),
|
|
327
|
+
...(options?.fetchImpl !== undefined
|
|
328
|
+
? { fetchImpl: options.fetchImpl }
|
|
329
|
+
: {}),
|
|
330
|
+
...(options?.gitRemoteUrl !== undefined
|
|
331
|
+
? { gitRemoteUrl: options.gitRemoteUrl }
|
|
332
|
+
: {}),
|
|
333
|
+
}, log);
|
|
334
|
+
}
|
|
335
|
+
case "deploy": {
|
|
336
|
+
if (subcommand === "status") {
|
|
337
|
+
return runDeployStatus({
|
|
272
338
|
projectRoot,
|
|
273
339
|
env,
|
|
274
|
-
skipBuild: flags.skipBuild,
|
|
275
|
-
dryRun: flags.dryRun,
|
|
276
340
|
...(flags.accountId !== undefined
|
|
277
341
|
? { accountId: flags.accountId }
|
|
278
342
|
: {}),
|
|
@@ -284,24 +348,32 @@ export async function runCli(argv, options) {
|
|
|
284
348
|
: {}),
|
|
285
349
|
}, log);
|
|
286
350
|
}
|
|
287
|
-
|
|
288
|
-
log.error(
|
|
289
|
-
return ExitCode.Usage;
|
|
290
|
-
default:
|
|
291
|
-
log.error(`Unknown command "${command}". Run contentrail --help.`);
|
|
351
|
+
if (subcommand !== undefined) {
|
|
352
|
+
log.error("Use `contentrail deploy` or `contentrail deploy status`.");
|
|
292
353
|
return ExitCode.Usage;
|
|
354
|
+
}
|
|
355
|
+
return runDeploy({
|
|
356
|
+
projectRoot,
|
|
357
|
+
env,
|
|
358
|
+
skipBuild: flags.skipBuild,
|
|
359
|
+
dryRun: flags.dryRun,
|
|
360
|
+
...(flags.accountId !== undefined
|
|
361
|
+
? { accountId: flags.accountId }
|
|
362
|
+
: {}),
|
|
363
|
+
...(flags.project !== undefined
|
|
364
|
+
? { projectName: flags.project }
|
|
365
|
+
: {}),
|
|
366
|
+
...(options?.fetchImpl !== undefined
|
|
367
|
+
? { fetchImpl: options.fetchImpl }
|
|
368
|
+
: {}),
|
|
369
|
+
}, log);
|
|
293
370
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
371
|
+
case "rollback":
|
|
372
|
+
log.error('Command "rollback" is not implemented in the CLI. Use the authenticated Worker or Pages API.');
|
|
373
|
+
return ExitCode.Usage;
|
|
374
|
+
default:
|
|
375
|
+
log.error(`Unknown command "${command}". Run contentrail --help.`);
|
|
299
376
|
return ExitCode.Usage;
|
|
300
|
-
}
|
|
301
|
-
if (/contentrail\.config\.json|Invalid contentrail|collections module|escapes the project/i.test(message)) {
|
|
302
|
-
return ExitCode.Config;
|
|
303
|
-
}
|
|
304
|
-
return ExitCode.Failure;
|
|
305
377
|
}
|
|
306
378
|
}
|
|
307
379
|
function parseArgv(argv, baseCwd) {
|
|
@@ -314,10 +386,13 @@ function parseArgv(argv, baseCwd) {
|
|
|
314
386
|
force: false,
|
|
315
387
|
withEditor: true,
|
|
316
388
|
withFunctions: true,
|
|
389
|
+
editorFlagSet: false,
|
|
390
|
+
functionsFlagSet: false,
|
|
317
391
|
yes: false,
|
|
318
392
|
dryRun: false,
|
|
319
393
|
confirm: false,
|
|
320
394
|
skipBuild: false,
|
|
395
|
+
install: false,
|
|
321
396
|
};
|
|
322
397
|
const take = (index, flag) => {
|
|
323
398
|
const value = argv[index];
|
|
@@ -340,20 +415,28 @@ function parseArgv(argv, baseCwd) {
|
|
|
340
415
|
flags.force = true;
|
|
341
416
|
continue;
|
|
342
417
|
}
|
|
418
|
+
if (arg === "--install") {
|
|
419
|
+
flags.install = true;
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
343
422
|
if (arg === "--with-editor") {
|
|
344
423
|
flags.withEditor = true;
|
|
424
|
+
flags.editorFlagSet = true;
|
|
345
425
|
continue;
|
|
346
426
|
}
|
|
347
427
|
if (arg === "--with-functions") {
|
|
348
428
|
flags.withFunctions = true;
|
|
429
|
+
flags.functionsFlagSet = true;
|
|
349
430
|
continue;
|
|
350
431
|
}
|
|
351
432
|
if (arg === "--no-editor") {
|
|
352
433
|
flags.withEditor = false;
|
|
434
|
+
flags.editorFlagSet = true;
|
|
353
435
|
continue;
|
|
354
436
|
}
|
|
355
437
|
if (arg === "--no-functions") {
|
|
356
438
|
flags.withFunctions = false;
|
|
439
|
+
flags.functionsFlagSet = true;
|
|
357
440
|
continue;
|
|
358
441
|
}
|
|
359
442
|
if (arg === "--skip-build") {
|