create-riebeckite 0.0.14 → 0.0.16
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 +28 -0
- package/README_ja.md +25 -1
- package/dist/src/arguments.d.ts +13 -0
- package/dist/src/index.d.ts +1 -10
- package/dist/src/index.js +318 -45
- package/dist/src/interactive.d.ts +26 -0
- package/dist/src/package-manager.d.ts +13 -0
- package/dist/src/publish.d.ts +11 -0
- package/dist/src/run-commands.d.ts +2 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -6,6 +6,15 @@ Create a new Riebeckite site from an official starter preset.
|
|
|
6
6
|
|
|
7
7
|
## Usage
|
|
8
8
|
|
|
9
|
+
Interactive (recommended): run without arguments and answer the prompts for
|
|
10
|
+
the project name, preset, content source, and deployment.
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npx create-riebeckite
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Passing any argument keeps the command non-interactive:
|
|
17
|
+
|
|
9
18
|
```sh
|
|
10
19
|
npx create-riebeckite my-site
|
|
11
20
|
cd my-site
|
|
@@ -13,6 +22,23 @@ npm install
|
|
|
13
22
|
npm exec riebeckite build
|
|
14
23
|
```
|
|
15
24
|
|
|
25
|
+
## Choices
|
|
26
|
+
|
|
27
|
+
The prompts ask, in order:
|
|
28
|
+
|
|
29
|
+
| Prompt | Options | Recommendation |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| Project name | the folder to create (empty input uses the default name) | any name, e.g. `my-site` |
|
|
32
|
+
| Preset | `starter`, `minimal`, `showcase`, `empty` | `starter` for most sites |
|
|
33
|
+
| Content source | `This project`, `Separate GitHub repository` | `This project` to start |
|
|
34
|
+
| Deployment | `GitHub Actions + Cloudflare Workers`, `Not now` | `Not now` for local development |
|
|
35
|
+
|
|
36
|
+
`Separate GitHub repository` also asks for the content and site repositories,
|
|
37
|
+
and GitHub Actions deployment is then configured for you. That setup is covered
|
|
38
|
+
in the [content repository guide](../../docs/en/docs/guides/content-repositories.md).
|
|
39
|
+
Deployment can be added later, described in
|
|
40
|
+
[Deployment](../../docs/en/docs/getting-started/deployment.md).
|
|
41
|
+
|
|
16
42
|
## Options
|
|
17
43
|
|
|
18
44
|
| Option | Description |
|
|
@@ -31,6 +57,8 @@ For example, scaffold the complete feature tour:
|
|
|
31
57
|
npx create-riebeckite my-site --preset showcase
|
|
32
58
|
```
|
|
33
59
|
|
|
60
|
+
## External content repository
|
|
61
|
+
|
|
34
62
|
To use a separate content repository and deploy after its `main` branch is
|
|
35
63
|
pushed, generate the common workflow once (the preset does not affect it):
|
|
36
64
|
|
package/README_ja.md
CHANGED
|
@@ -7,6 +7,15 @@ CLI ツールです。
|
|
|
7
7
|
|
|
8
8
|
## 使い方
|
|
9
9
|
|
|
10
|
+
対話モード(推奨): 引数なしで実行すると、プロジェクト名・preset・
|
|
11
|
+
コンテンツの格納場所・デプロイについて順に確認します。
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npx create-riebeckite
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
引数を 1 つでも渡すと、従来どおり非対話で動作します。
|
|
18
|
+
|
|
10
19
|
```sh
|
|
11
20
|
npx create-riebeckite my-site
|
|
12
21
|
cd my-site
|
|
@@ -14,6 +23,19 @@ npm install
|
|
|
14
23
|
npm exec riebeckite build
|
|
15
24
|
```
|
|
16
25
|
|
|
26
|
+
## Choices
|
|
27
|
+
|
|
28
|
+
対話式の CLI は、次の順に確認します。
|
|
29
|
+
|
|
30
|
+
| 質問 | 選択肢 | 推奨 |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| Project name | 作るフォルダ名(空なら既定の名前) | 任意。例: `my-site` |
|
|
33
|
+
| Preset | `starter`、`minimal`、`showcase`、`empty` | 大半のサイトは `starter` |
|
|
34
|
+
| Content source | `This project`、`Separate GitHub repository` | 最初は `This project` |
|
|
35
|
+
| デプロイ設定 | `GitHub Actions + Cloudflare Workers`、`Not now` | 手元で試すなら `Not now` |
|
|
36
|
+
|
|
37
|
+
`Separate GitHub repository` を選ぶと content と site のリポジトリ名も入力し、GitHub Actions のデプロイ設定が自動で構成されます。この構成は[content repository ガイド](../../docs/ja/docs/guides/content-repositories.md)に、デプロイの追加方法は [Deployment](../../docs/ja/docs/getting-started/deployment.md) にあります。
|
|
38
|
+
|
|
17
39
|
## オプション
|
|
18
40
|
|
|
19
41
|
| オプション | 説明 |
|
|
@@ -32,6 +54,8 @@ npm exec riebeckite build
|
|
|
32
54
|
npx create-riebeckite my-site --preset showcase
|
|
33
55
|
```
|
|
34
56
|
|
|
57
|
+
## External content repository
|
|
58
|
+
|
|
35
59
|
別の記事リポジトリを使い、その `main` への push でデプロイする場合は、共通の
|
|
36
60
|
workflow を一度だけ生成します。preset による違いはありません。
|
|
37
61
|
|
|
@@ -63,7 +87,7 @@ npx create-riebeckite --list-presets
|
|
|
63
87
|
| --- | --- |
|
|
64
88
|
| `starter` | 大半のサイトにおすすめ |
|
|
65
89
|
| `minimal` | 最小限の設定で作る Markdown サイト |
|
|
66
|
-
| `showcase` |
|
|
90
|
+
| `showcase` | 描画例とローカルの fixture で Riebeckite の機能と Plugin を確認する構成 |
|
|
67
91
|
| `empty` | 独自構成のための空のシェル |
|
|
68
92
|
|
|
69
93
|
各 preset の説明は次のとおりです(`--list-presets` で表示される内容と同じです)。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ScaffoldPresetName } from "@riebeckite/honox";
|
|
2
|
+
export type CreateRiebeckiteOptions = {
|
|
3
|
+
readonly directory: string;
|
|
4
|
+
readonly force: boolean;
|
|
5
|
+
readonly preset: ScaffoldPresetName;
|
|
6
|
+
readonly listPresets: boolean;
|
|
7
|
+
readonly githubActions: boolean;
|
|
8
|
+
readonly cloudflareWorkers: boolean;
|
|
9
|
+
readonly contentRepository?: string;
|
|
10
|
+
readonly siteRepository?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function parseArguments(arguments_: readonly string[]): CreateRiebeckiteOptions;
|
|
13
|
+
export declare function printPresets(): void;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export type CreateRiebeckiteOptions = {
|
|
3
|
-
readonly directory: string;
|
|
4
|
-
readonly force: boolean;
|
|
5
|
-
readonly preset: ScaffoldPresetName;
|
|
6
|
-
readonly listPresets: boolean;
|
|
7
|
-
readonly githubActions: boolean;
|
|
8
|
-
readonly contentRepository?: string;
|
|
9
|
-
readonly siteRepository?: string;
|
|
10
|
-
};
|
|
1
|
+
export type { CreateRiebeckiteOptions } from "./arguments.js";
|
|
11
2
|
export declare function runCreateRiebeckite(arguments_: readonly string[]): Promise<void>;
|
package/dist/src/index.js
CHANGED
|
@@ -2,54 +2,16 @@
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import {
|
|
4
4
|
formatScaffoldNextSteps,
|
|
5
|
-
isScaffoldPresetName,
|
|
6
|
-
SCAFFOLD_PRESET_NAMES,
|
|
7
5
|
ScaffoldSiteError,
|
|
8
|
-
scaffoldPresets,
|
|
9
6
|
scaffoldRiebeckiteSite
|
|
10
7
|
} from "@riebeckite/honox";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (options.listPresets) {
|
|
21
|
-
printPresets();
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
const targetDirectory = path.resolve(process.cwd(), options.directory);
|
|
25
|
-
try {
|
|
26
|
-
const result = await scaffoldRiebeckiteSite({
|
|
27
|
-
targetDirectory,
|
|
28
|
-
overwrite: options.force,
|
|
29
|
-
preset: options.preset,
|
|
30
|
-
githubActions: options.githubActions,
|
|
31
|
-
contentRepository: options.contentRepository,
|
|
32
|
-
siteRepository: options.siteRepository
|
|
33
|
-
});
|
|
34
|
-
const relative = path.relative(process.cwd(), result.targetDirectory) || ".";
|
|
35
|
-
console.log(`Created a ${options.preset} Riebeckite site in ${relative}`);
|
|
36
|
-
console.log("");
|
|
37
|
-
console.log(formatScaffoldNextSteps(relative));
|
|
38
|
-
if (options.contentRepository !== void 0) {
|
|
39
|
-
console.log("");
|
|
40
|
-
console.log(
|
|
41
|
-
"Copy github/notify-site.yml to the content repository as .github/workflows/notify-site.yml."
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
} catch (error) {
|
|
45
|
-
if (error instanceof ScaffoldSiteError) {
|
|
46
|
-
console.error(error.message);
|
|
47
|
-
process.exitCode = 1;
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
throw error;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
8
|
+
|
|
9
|
+
// src/arguments.ts
|
|
10
|
+
import {
|
|
11
|
+
isScaffoldPresetName,
|
|
12
|
+
SCAFFOLD_PRESET_NAMES,
|
|
13
|
+
scaffoldPresets
|
|
14
|
+
} from "@riebeckite/honox";
|
|
53
15
|
function parseArguments(arguments_) {
|
|
54
16
|
let directory;
|
|
55
17
|
let force = false;
|
|
@@ -109,6 +71,7 @@ function parseArguments(arguments_) {
|
|
|
109
71
|
preset: preset ?? "starter",
|
|
110
72
|
listPresets,
|
|
111
73
|
githubActions,
|
|
74
|
+
cloudflareWorkers: false,
|
|
112
75
|
contentRepository,
|
|
113
76
|
siteRepository
|
|
114
77
|
};
|
|
@@ -120,6 +83,316 @@ function printPresets() {
|
|
|
120
83
|
console.log(` ${name}: ${scaffoldPresets[name].description}`);
|
|
121
84
|
}
|
|
122
85
|
}
|
|
86
|
+
|
|
87
|
+
// src/interactive.ts
|
|
88
|
+
import { isCancel, log, select, text } from "@clack/prompts";
|
|
89
|
+
import {
|
|
90
|
+
SCAFFOLD_PRESET_NAMES as SCAFFOLD_PRESET_NAMES2,
|
|
91
|
+
scaffoldPresets as scaffoldPresets2
|
|
92
|
+
} from "@riebeckite/honox";
|
|
93
|
+
var DEFAULT_DIRECTORY = "my-riebeckite-site";
|
|
94
|
+
var DEFAULT_INTERACTIVE_DEPLOYMENT = "none";
|
|
95
|
+
function interactiveAnswersToOptions(answers) {
|
|
96
|
+
const external = answers.contentSource === "external";
|
|
97
|
+
return {
|
|
98
|
+
directory: answers.directory,
|
|
99
|
+
force: false,
|
|
100
|
+
preset: answers.preset,
|
|
101
|
+
listPresets: false,
|
|
102
|
+
githubActions: external || answers.deployment === "github-actions",
|
|
103
|
+
cloudflareWorkers: !external && answers.deployment === "cloudflare",
|
|
104
|
+
contentRepository: external ? answers.contentRepository : void 0,
|
|
105
|
+
siteRepository: external ? answers.siteRepository : void 0
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async function promptInteractiveAnswers() {
|
|
109
|
+
const projectInput = await text({
|
|
110
|
+
message: "Project name",
|
|
111
|
+
placeholder: DEFAULT_DIRECTORY,
|
|
112
|
+
defaultValue: DEFAULT_DIRECTORY
|
|
113
|
+
});
|
|
114
|
+
if (isCancel(projectInput)) return null;
|
|
115
|
+
const directory = projectInput.trim() || DEFAULT_DIRECTORY;
|
|
116
|
+
const preset = await select({
|
|
117
|
+
message: "Choose a preset",
|
|
118
|
+
initialValue: "starter",
|
|
119
|
+
options: SCAFFOLD_PRESET_NAMES2.map((name) => ({
|
|
120
|
+
value: name,
|
|
121
|
+
label: capitalize(name),
|
|
122
|
+
hint: scaffoldPresets2[name].description
|
|
123
|
+
}))
|
|
124
|
+
});
|
|
125
|
+
if (isCancel(preset)) return null;
|
|
126
|
+
const contentSource = await select({
|
|
127
|
+
message: "Where will you write content?",
|
|
128
|
+
initialValue: "local",
|
|
129
|
+
options: [
|
|
130
|
+
{ value: "local", label: "This project" },
|
|
131
|
+
{ value: "external", label: "Separate GitHub repository" }
|
|
132
|
+
]
|
|
133
|
+
});
|
|
134
|
+
if (isCancel(contentSource)) return null;
|
|
135
|
+
let answers;
|
|
136
|
+
if (contentSource === "external") {
|
|
137
|
+
log.info(
|
|
138
|
+
"Separate repositories use GitHub Actions so content updates can trigger site deployments."
|
|
139
|
+
);
|
|
140
|
+
const contentRepository = await text({
|
|
141
|
+
message: "Content repository",
|
|
142
|
+
placeholder: "OWNER/notes"
|
|
143
|
+
});
|
|
144
|
+
if (isCancel(contentRepository)) return null;
|
|
145
|
+
const siteRepository = await text({
|
|
146
|
+
message: "Site repository",
|
|
147
|
+
placeholder: "OWNER/site"
|
|
148
|
+
});
|
|
149
|
+
if (isCancel(siteRepository)) return null;
|
|
150
|
+
answers = {
|
|
151
|
+
directory,
|
|
152
|
+
preset,
|
|
153
|
+
contentSource,
|
|
154
|
+
deployment: "github-actions",
|
|
155
|
+
contentRepository: contentRepository.trim(),
|
|
156
|
+
siteRepository: siteRepository.trim()
|
|
157
|
+
};
|
|
158
|
+
} else {
|
|
159
|
+
const deployment = await select({
|
|
160
|
+
message: "Set up deployment?",
|
|
161
|
+
initialValue: DEFAULT_INTERACTIVE_DEPLOYMENT,
|
|
162
|
+
options: [
|
|
163
|
+
{
|
|
164
|
+
value: "cloudflare",
|
|
165
|
+
label: "Cloudflare Workers",
|
|
166
|
+
hint: "Publish from this machine"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
value: "github-actions",
|
|
170
|
+
label: "GitHub Actions",
|
|
171
|
+
hint: "Deploy on every push"
|
|
172
|
+
},
|
|
173
|
+
{ value: "none", label: "Not now" }
|
|
174
|
+
]
|
|
175
|
+
});
|
|
176
|
+
if (isCancel(deployment)) return null;
|
|
177
|
+
answers = { directory, preset, contentSource, deployment };
|
|
178
|
+
}
|
|
179
|
+
log.step("Creating Riebeckite site...");
|
|
180
|
+
return answers;
|
|
181
|
+
}
|
|
182
|
+
async function promptDeployNow() {
|
|
183
|
+
const answer = await select({
|
|
184
|
+
message: "Deploy now?",
|
|
185
|
+
initialValue: "yes",
|
|
186
|
+
options: [
|
|
187
|
+
{ value: "yes", label: "Yes" },
|
|
188
|
+
{ value: "later", label: "Later" }
|
|
189
|
+
]
|
|
190
|
+
});
|
|
191
|
+
if (isCancel(answer)) return false;
|
|
192
|
+
return answer === "yes";
|
|
193
|
+
}
|
|
194
|
+
function capitalize(value) {
|
|
195
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// src/package-manager.ts
|
|
199
|
+
import { PACKAGE_MANAGER } from "@riebeckite/honox";
|
|
200
|
+
function packageManagerCommands(name = PACKAGE_MANAGER) {
|
|
201
|
+
if (name === "pnpm") {
|
|
202
|
+
return {
|
|
203
|
+
name,
|
|
204
|
+
install: { command: "pnpm", args: ["install"], label: "pnpm install" },
|
|
205
|
+
build: { command: "pnpm", args: ["build"], label: "pnpm build" },
|
|
206
|
+
deploy: {
|
|
207
|
+
command: "pnpm",
|
|
208
|
+
args: ["exec", "riebeckite", "deploy"],
|
|
209
|
+
label: "pnpm exec riebeckite deploy"
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
name: "npm",
|
|
215
|
+
install: { command: "npm", args: ["install"], label: "npm install" },
|
|
216
|
+
build: { command: "npm", args: ["run", "build"], label: "npm run build" },
|
|
217
|
+
deploy: {
|
|
218
|
+
command: "npm",
|
|
219
|
+
args: ["exec", "riebeckite", "deploy"],
|
|
220
|
+
label: "npm exec riebeckite deploy"
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/publish.ts
|
|
226
|
+
var DeploymentFailure = class extends Error {
|
|
227
|
+
phase;
|
|
228
|
+
constructor(phase, message) {
|
|
229
|
+
super(message);
|
|
230
|
+
this.name = "DeploymentFailure";
|
|
231
|
+
this.phase = phase;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
async function installDependencies(directory, commands, run) {
|
|
235
|
+
await runCommand("install", commands.install, directory, run);
|
|
236
|
+
}
|
|
237
|
+
async function buildAndDeploy(directory, commands, run) {
|
|
238
|
+
await runCommand("build", commands.build, directory, run);
|
|
239
|
+
await runCommand("deploy", commands.deploy, directory, run);
|
|
240
|
+
}
|
|
241
|
+
function formatCloudflareNextSteps(relativeDirectory, commands) {
|
|
242
|
+
const lines = ["Next steps:"];
|
|
243
|
+
if (relativeDirectory !== ".") {
|
|
244
|
+
lines.push(` cd ${relativeDirectory}`);
|
|
245
|
+
}
|
|
246
|
+
lines.push(` ${commands.build.label}`);
|
|
247
|
+
lines.push(` ${commands.deploy.label}`);
|
|
248
|
+
return lines.join("\n");
|
|
249
|
+
}
|
|
250
|
+
function formatDeploymentFailure(relativeDirectory, commands, failure) {
|
|
251
|
+
const lines = [
|
|
252
|
+
"Project created successfully.",
|
|
253
|
+
deploymentFailureSummary(failure.phase),
|
|
254
|
+
failure.message,
|
|
255
|
+
"You can retry with:"
|
|
256
|
+
];
|
|
257
|
+
if (relativeDirectory !== ".") {
|
|
258
|
+
lines.push(` cd ${relativeDirectory}`);
|
|
259
|
+
}
|
|
260
|
+
if (failure.phase === "install") {
|
|
261
|
+
lines.push(` ${commands.install.label}`);
|
|
262
|
+
}
|
|
263
|
+
lines.push(` ${commands.build.label}`);
|
|
264
|
+
lines.push(` ${commands.deploy.label}`);
|
|
265
|
+
return lines.join("\n");
|
|
266
|
+
}
|
|
267
|
+
function deploymentFailureSummary(phase) {
|
|
268
|
+
if (phase === "install") return "Installing dependencies failed.";
|
|
269
|
+
if (phase === "build") return "Build failed.";
|
|
270
|
+
return "Deployment failed.";
|
|
271
|
+
}
|
|
272
|
+
async function runCommand(phase, command, directory, run) {
|
|
273
|
+
let exitCode;
|
|
274
|
+
try {
|
|
275
|
+
exitCode = await run(command.command, command.args, directory);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
throw new DeploymentFailure(
|
|
278
|
+
phase,
|
|
279
|
+
error instanceof Error ? error.message : String(error)
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
if (exitCode !== 0) {
|
|
283
|
+
throw new DeploymentFailure(
|
|
284
|
+
phase,
|
|
285
|
+
`${command.label} exited with code ${exitCode}.`
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/run-commands.ts
|
|
291
|
+
import { spawn } from "node:child_process";
|
|
292
|
+
function spawnCommand(command, args, cwd) {
|
|
293
|
+
return new Promise((resolve, reject) => {
|
|
294
|
+
const child = spawn(command, [...args], {
|
|
295
|
+
cwd,
|
|
296
|
+
stdio: "inherit",
|
|
297
|
+
shell: process.platform === "win32"
|
|
298
|
+
});
|
|
299
|
+
child.on("error", reject);
|
|
300
|
+
child.on("exit", (code) => resolve(code ?? 1));
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/index.ts
|
|
305
|
+
async function runCreateRiebeckite(arguments_) {
|
|
306
|
+
const resolved = await resolveOptions(arguments_);
|
|
307
|
+
if (resolved === null) return;
|
|
308
|
+
const { options, interactive } = resolved;
|
|
309
|
+
if (options.listPresets) {
|
|
310
|
+
printPresets();
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const targetDirectory = path.resolve(process.cwd(), options.directory);
|
|
314
|
+
let result;
|
|
315
|
+
try {
|
|
316
|
+
result = await scaffoldRiebeckiteSite({
|
|
317
|
+
targetDirectory,
|
|
318
|
+
overwrite: options.force,
|
|
319
|
+
preset: options.preset,
|
|
320
|
+
githubActions: options.githubActions,
|
|
321
|
+
cloudflareWorkers: options.cloudflareWorkers,
|
|
322
|
+
contentRepository: options.contentRepository,
|
|
323
|
+
siteRepository: options.siteRepository
|
|
324
|
+
});
|
|
325
|
+
} catch (error) {
|
|
326
|
+
if (error instanceof ScaffoldSiteError) {
|
|
327
|
+
console.error(error.message);
|
|
328
|
+
process.exitCode = 1;
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
throw error;
|
|
332
|
+
}
|
|
333
|
+
const relative = path.relative(process.cwd(), result.targetDirectory) || ".";
|
|
334
|
+
console.log(`Created a ${options.preset} Riebeckite site in ${relative}`);
|
|
335
|
+
console.log("");
|
|
336
|
+
if (interactive && options.cloudflareWorkers) {
|
|
337
|
+
await publishCloudflareSite(targetDirectory, relative);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
printScaffoldNextSteps(options, result, relative);
|
|
341
|
+
}
|
|
342
|
+
async function resolveOptions(arguments_) {
|
|
343
|
+
if (arguments_.length === 0) {
|
|
344
|
+
const answers = await promptInteractiveAnswers();
|
|
345
|
+
if (answers === null) {
|
|
346
|
+
console.log("Operation cancelled.");
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
return { options: interactiveAnswersToOptions(answers), interactive: true };
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
return { options: parseArguments(arguments_), interactive: false };
|
|
353
|
+
} catch (error) {
|
|
354
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
355
|
+
process.exitCode = 1;
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function printScaffoldNextSteps(options, result, relative) {
|
|
360
|
+
const externalContent = options.contentRepository !== void 0;
|
|
361
|
+
const editFile = !externalContent && result.files.includes("content/index.md") ? "content/index.md" : void 0;
|
|
362
|
+
console.log(formatScaffoldNextSteps(relative, { editFile, externalContent }));
|
|
363
|
+
}
|
|
364
|
+
async function publishCloudflareSite(targetDirectory, relative) {
|
|
365
|
+
const commands = packageManagerCommands();
|
|
366
|
+
console.log(`Installing dependencies with ${commands.name}...`);
|
|
367
|
+
try {
|
|
368
|
+
await installDependencies(targetDirectory, commands, spawnCommand);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
if (!(error instanceof DeploymentFailure)) throw error;
|
|
371
|
+
reportDeploymentFailure(error, relative);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const deployNow = await promptDeployNow();
|
|
375
|
+
if (!deployNow) {
|
|
376
|
+
console.log("");
|
|
377
|
+
console.log(formatCloudflareNextSteps(relative, commands));
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
await buildAndDeploy(targetDirectory, commands, spawnCommand);
|
|
382
|
+
} catch (error) {
|
|
383
|
+
if (!(error instanceof DeploymentFailure)) throw error;
|
|
384
|
+
reportDeploymentFailure(error, relative);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
console.log("");
|
|
388
|
+
console.log("Deployment complete.");
|
|
389
|
+
}
|
|
390
|
+
function reportDeploymentFailure(error, relative) {
|
|
391
|
+
const commands = packageManagerCommands();
|
|
392
|
+
console.error("");
|
|
393
|
+
console.error(formatDeploymentFailure(relative, commands, error));
|
|
394
|
+
process.exitCode = 1;
|
|
395
|
+
}
|
|
123
396
|
export {
|
|
124
397
|
runCreateRiebeckite
|
|
125
398
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ScaffoldPresetName } from "@riebeckite/honox";
|
|
2
|
+
import type { CreateRiebeckiteOptions } from "./arguments.js";
|
|
3
|
+
export declare const DEFAULT_INTERACTIVE_DEPLOYMENT: InteractiveDeployment;
|
|
4
|
+
export type InteractiveContentSource = "local" | "external";
|
|
5
|
+
export type InteractiveDeployment = "cloudflare" | "github-actions" | "none";
|
|
6
|
+
export type InteractiveAnswers = {
|
|
7
|
+
readonly directory: string;
|
|
8
|
+
readonly preset: ScaffoldPresetName;
|
|
9
|
+
readonly contentSource: InteractiveContentSource;
|
|
10
|
+
readonly deployment: InteractiveDeployment;
|
|
11
|
+
readonly contentRepository?: string;
|
|
12
|
+
readonly siteRepository?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Map interactive answers onto the same options object the non-interactive
|
|
16
|
+
* flags produce. A separate content repository always deploys through GitHub
|
|
17
|
+
* Actions, so the answered deployment never wins in that combination.
|
|
18
|
+
*/
|
|
19
|
+
export declare function interactiveAnswersToOptions(answers: InteractiveAnswers): CreateRiebeckiteOptions;
|
|
20
|
+
/**
|
|
21
|
+
* Run the prompt flow. Returns `null` when the user cancels, so the caller can
|
|
22
|
+
* exit without a stack trace. Repository values are only trimmed here; their
|
|
23
|
+
* `owner/repository` shape is validated by the existing scaffold.
|
|
24
|
+
*/
|
|
25
|
+
export declare function promptInteractiveAnswers(): Promise<InteractiveAnswers | null>;
|
|
26
|
+
export declare function promptDeployNow(): Promise<boolean>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type PackageManagerName = "npm" | "pnpm";
|
|
2
|
+
export type PackageManagerCommand = {
|
|
3
|
+
readonly command: string;
|
|
4
|
+
readonly args: readonly string[];
|
|
5
|
+
readonly label: string;
|
|
6
|
+
};
|
|
7
|
+
export type PackageManagerCommands = {
|
|
8
|
+
readonly name: PackageManagerName;
|
|
9
|
+
readonly install: PackageManagerCommand;
|
|
10
|
+
readonly build: PackageManagerCommand;
|
|
11
|
+
readonly deploy: PackageManagerCommand;
|
|
12
|
+
};
|
|
13
|
+
export declare function packageManagerCommands(name?: PackageManagerName): PackageManagerCommands;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PackageManagerCommands } from "./package-manager.js";
|
|
2
|
+
import type { CommandRunner } from "./run-commands.js";
|
|
3
|
+
export type DeploymentPhase = "install" | "build" | "deploy";
|
|
4
|
+
export declare class DeploymentFailure extends Error {
|
|
5
|
+
readonly phase: DeploymentPhase;
|
|
6
|
+
constructor(phase: DeploymentPhase, message: string);
|
|
7
|
+
}
|
|
8
|
+
export declare function installDependencies(directory: string, commands: PackageManagerCommands, run: CommandRunner): Promise<void>;
|
|
9
|
+
export declare function buildAndDeploy(directory: string, commands: PackageManagerCommands, run: CommandRunner): Promise<void>;
|
|
10
|
+
export declare function formatCloudflareNextSteps(relativeDirectory: string, commands: PackageManagerCommands): string;
|
|
11
|
+
export declare function formatDeploymentFailure(relativeDirectory: string, commands: PackageManagerCommands, failure: DeploymentFailure): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-riebeckite",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@
|
|
30
|
+
"@clack/prompts": "^1.8.1",
|
|
31
|
+
"@riebeckite/honox": "0.0.16"
|
|
31
32
|
},
|
|
32
33
|
"repository": {
|
|
33
34
|
"type": "git",
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
},
|
|
51
52
|
"sideEffects": false,
|
|
52
53
|
"scripts": {
|
|
53
|
-
"build": "node ../../scripts/build_package.mjs"
|
|
54
|
+
"build": "node ../../scripts/build_package.mjs",
|
|
55
|
+
"test": "node --import tsx --test \"test/*.test.ts\""
|
|
54
56
|
}
|
|
55
57
|
}
|