clefbase 1.3.4 → 1.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-src/cli/api.js +25 -3
- package/dist/cli-src/cli/commands/deploy.js +177 -28
- package/dist/cli-src/cli/index.js +36 -8
- package/dist/cli.js +191 -41
- package/dist/hosting/index.d.ts +92 -6
- package/dist/hosting/index.d.ts.map +1 -1
- package/dist/hosting/index.js +67 -14
- package/dist/hosting/index.js.map +1 -1
- package/dist/react/StorageImage.d.ts +7 -58
- package/dist/react/StorageImage.d.ts.map +1 -1
- package/dist/react/StorageImage.js +12 -69
- package/dist/react/StorageImage.js.map +1 -1
- package/dist/storage/index.d.ts +21 -3
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +43 -13
- package/dist/storage/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli-src/cli/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Raw API calls used by the CLI.
|
|
3
|
+
* api.ts — Raw API calls used by the CLI.
|
|
4
4
|
* Written as plain fetch calls (not using HttpClient) so the CLI can be
|
|
5
5
|
* bundled independently and doesn't pull in the full SDK at runtime.
|
|
6
6
|
*/
|
|
@@ -41,6 +41,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
41
41
|
exports.CliApiError = void 0;
|
|
42
42
|
exports.listSites = listSites;
|
|
43
43
|
exports.createSite = createSite;
|
|
44
|
+
exports.deleteSite = deleteSite;
|
|
45
|
+
exports.getDnsStatus = getDnsStatus;
|
|
46
|
+
exports.reprovisionDns = reprovisionDns;
|
|
44
47
|
exports.createDeploy = createDeploy;
|
|
45
48
|
exports.uploadFileBatch = uploadFileBatch;
|
|
46
49
|
exports.finalizeDeploy = finalizeDeploy;
|
|
@@ -96,6 +99,27 @@ async function createSite(cfg, name, description) {
|
|
|
96
99
|
body: JSON.stringify({ name, description }),
|
|
97
100
|
});
|
|
98
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Delete a site.
|
|
104
|
+
*
|
|
105
|
+
* First call (confirm=false): returns { requiresConfirmation: true, dnsRecord?, message }
|
|
106
|
+
* Second call (confirm=true, deleteDns?): actually deletes
|
|
107
|
+
*/
|
|
108
|
+
async function deleteSite(cfg, siteId, opts = {}) {
|
|
109
|
+
const params = new URLSearchParams();
|
|
110
|
+
if (opts.confirm)
|
|
111
|
+
params.set("confirm", "true");
|
|
112
|
+
if (opts.deleteDns)
|
|
113
|
+
params.set("deleteDns", "true");
|
|
114
|
+
const qs = params.toString() ? `?${params}` : "";
|
|
115
|
+
return apiFetch(`${base(cfg)}/api/hosting/databases/${cfg.projectId}/sites/${siteId}${qs}`, { method: "DELETE", headers: adminHeaders(cfg) });
|
|
116
|
+
}
|
|
117
|
+
async function getDnsStatus(cfg, siteId) {
|
|
118
|
+
return apiFetch(`${base(cfg)}/api/hosting/databases/${cfg.projectId}/sites/${siteId}/dns`, { headers: adminHeaders(cfg) });
|
|
119
|
+
}
|
|
120
|
+
async function reprovisionDns(cfg, siteId) {
|
|
121
|
+
return apiFetch(`${base(cfg)}/api/hosting/databases/${cfg.projectId}/sites/${siteId}/dns/provision`, { method: "POST", headers: adminHeaders(cfg), body: JSON.stringify({}) });
|
|
122
|
+
}
|
|
99
123
|
async function createDeploy(cfg, siteId, entrypoint = "index.html") {
|
|
100
124
|
return apiFetch(`${base(cfg)}/api/hosting/databases/${cfg.projectId}/sites/${siteId}/deploys`, {
|
|
101
125
|
method: "POST",
|
|
@@ -108,7 +132,6 @@ async function uploadFileBatch(cfg, deployId, files) {
|
|
|
108
132
|
const url = `${base(cfg)}/api/hosting/databases/${cfg.projectId}/deploys/${deployId}/files/batch`;
|
|
109
133
|
let res;
|
|
110
134
|
if (typeof FormData !== "undefined") {
|
|
111
|
-
// Node 18+ native FormData: Buffer must be wrapped in Blob/File
|
|
112
135
|
const form = new FormData();
|
|
113
136
|
for (const f of files) {
|
|
114
137
|
const filename = f.path.split("/").pop() ?? f.path;
|
|
@@ -124,7 +147,6 @@ async function uploadFileBatch(cfg, deployId, files) {
|
|
|
124
147
|
});
|
|
125
148
|
}
|
|
126
149
|
else {
|
|
127
|
-
// Older Node: use form-data package which natively accepts Buffers
|
|
128
150
|
const mod = await Promise.resolve().then(() => __importStar(require("form-data")));
|
|
129
151
|
const FormDataLegacy = mod.default;
|
|
130
152
|
const form = new FormDataLegacy();
|
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.runDeploy = runDeploy;
|
|
7
7
|
exports.runHostingInit = runHostingInit;
|
|
8
8
|
exports.runStatus = runStatus;
|
|
9
|
+
exports.runDnsStatus = runDnsStatus;
|
|
10
|
+
exports.runDnsReprovision = runDnsReprovision;
|
|
9
11
|
const path_1 = __importDefault(require("path"));
|
|
10
12
|
const fs_1 = __importDefault(require("fs"));
|
|
11
13
|
const chalk_1 = __importDefault(require("chalk"));
|
|
@@ -65,6 +67,9 @@ function fmtBytes(n) {
|
|
|
65
67
|
return `${(n / 1024).toFixed(1)} KB`;
|
|
66
68
|
return `${(n / (1024 * 1024)).toFixed(2)} MB`;
|
|
67
69
|
}
|
|
70
|
+
function siteUrl(site) {
|
|
71
|
+
return site.customDomain ? `https://${site.customDomain}` : site.previewUrl;
|
|
72
|
+
}
|
|
68
73
|
// ─── deploy ───────────────────────────────────────────────────────────────────
|
|
69
74
|
async function runDeploy(opts) {
|
|
70
75
|
const cwd = opts.cwd ?? process.cwd();
|
|
@@ -75,18 +80,24 @@ async function runDeploy(opts) {
|
|
|
75
80
|
// ── Resolve / pick a site ─────────────────────────────────────────────────
|
|
76
81
|
let siteId = opts.site ?? cfg.hosting?.siteId ?? "";
|
|
77
82
|
let siteName = cfg.hosting?.siteName ?? "";
|
|
83
|
+
let previewUrl = "";
|
|
78
84
|
if (!siteId) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
siteName =
|
|
85
|
+
const site = await pickOrCreateSite(cfg);
|
|
86
|
+
siteId = site.id;
|
|
87
|
+
siteName = site.name;
|
|
88
|
+
previewUrl = site.previewUrl;
|
|
82
89
|
cfg.hosting = {
|
|
83
90
|
siteId,
|
|
84
91
|
siteName,
|
|
92
|
+
previewUrl,
|
|
85
93
|
distDir: cfg.hosting?.distDir ?? "dist",
|
|
86
94
|
entrypoint: cfg.hosting?.entrypoint ?? "index.html",
|
|
87
95
|
};
|
|
88
96
|
(0, config_1.saveConfig)(cfg, cwd);
|
|
89
97
|
}
|
|
98
|
+
else {
|
|
99
|
+
previewUrl = cfg.hosting?.previewUrl ?? "";
|
|
100
|
+
}
|
|
90
101
|
// ── Resolve dist dir ──────────────────────────────────────────────────────
|
|
91
102
|
const distDir = opts.dir ?? cfg.hosting?.distDir ?? await promptDistDir(cwd);
|
|
92
103
|
const absDir = path_1.default.isAbsolute(distDir) ? distDir : path_1.default.join(cwd, distDir);
|
|
@@ -111,9 +122,10 @@ async function runDeploy(opts) {
|
|
|
111
122
|
}
|
|
112
123
|
// ── Summary ───────────────────────────────────────────────────────────────
|
|
113
124
|
console.log();
|
|
114
|
-
console.log(` ${chalk_1.default.bold("Site:")}
|
|
115
|
-
console.log(` ${chalk_1.default.bold("
|
|
116
|
-
console.log(` ${chalk_1.default.bold("
|
|
125
|
+
console.log(` ${chalk_1.default.bold("Site:")} ${siteName} ${chalk_1.default.dim(siteId)}`);
|
|
126
|
+
console.log(` ${chalk_1.default.bold("Preview:")} ${chalk_1.default.cyan(previewUrl || "(set after deploy)")}`);
|
|
127
|
+
console.log(` ${chalk_1.default.bold("From:")} ${path_1.default.relative(cwd, absDir)}`);
|
|
128
|
+
console.log(` ${chalk_1.default.bold("Files:")} ${files.length} ${chalk_1.default.dim("(" + fmtBytes(totalBytes) + ")")}`);
|
|
117
129
|
console.log();
|
|
118
130
|
// ── Create deploy ─────────────────────────────────────────────────────────
|
|
119
131
|
const deploySpinner = (0, ora_1.default)("Creating deploy…").start();
|
|
@@ -165,10 +177,30 @@ async function runDeploy(opts) {
|
|
|
165
177
|
finSpinner.fail(`Finalize failed: ${err.message}`);
|
|
166
178
|
process.exit(1);
|
|
167
179
|
}
|
|
168
|
-
// ── Result
|
|
169
|
-
|
|
180
|
+
// ── Result — fetch the canonical URL from the live site record ────────────
|
|
181
|
+
// The previewUrl from the config may be stale (e.g. if the site was renamed)
|
|
182
|
+
// and a custom domain may have been added since init. Always fetch the live
|
|
183
|
+
// site record to get the correct canonical URL.
|
|
184
|
+
let canonicalUrl = previewUrl;
|
|
185
|
+
try {
|
|
186
|
+
// Fetch the current site record to get the canonical URL — it may differ
|
|
187
|
+
// from the config if the site was renamed or a custom domain was added.
|
|
188
|
+
const sites = await (0, api_1.listSites)(cfg);
|
|
189
|
+
const liveSite = sites.find(s => s.id === siteId);
|
|
190
|
+
if (liveSite) {
|
|
191
|
+
canonicalUrl = siteUrl(liveSite);
|
|
192
|
+
// Keep the config preview URL in sync for future deploys.
|
|
193
|
+
if (cfg.hosting && liveSite.previewUrl && cfg.hosting.previewUrl !== liveSite.previewUrl) {
|
|
194
|
+
cfg.hosting.previewUrl = liveSite.previewUrl;
|
|
195
|
+
(0, config_1.saveConfig)(cfg, cwd);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch { /* best-effort — fall back to stored previewUrl */ }
|
|
170
200
|
console.log();
|
|
171
|
-
|
|
201
|
+
if (canonicalUrl) {
|
|
202
|
+
console.log(chalk_1.default.green.bold(` ✓ ${canonicalUrl}`));
|
|
203
|
+
}
|
|
172
204
|
console.log();
|
|
173
205
|
}
|
|
174
206
|
// ─── hosting:init ─────────────────────────────────────────────────────────────
|
|
@@ -177,9 +209,7 @@ async function runHostingInit(cwd = process.cwd()) {
|
|
|
177
209
|
console.log();
|
|
178
210
|
console.log(chalk_1.default.bold.cyan(" Hosting Setup"));
|
|
179
211
|
console.log();
|
|
180
|
-
const
|
|
181
|
-
const sites = await (0, api_1.listSites)(cfg).catch(() => []);
|
|
182
|
-
const siteName = sites.find(s => s.id === siteId)?.name ?? siteId;
|
|
212
|
+
const site = await pickOrCreateSite(cfg);
|
|
183
213
|
const { distDir } = await inquirer_1.default.prompt([{
|
|
184
214
|
type: "input", name: "distDir",
|
|
185
215
|
message: "Build output directory",
|
|
@@ -192,10 +222,20 @@ async function runHostingInit(cwd = process.cwd()) {
|
|
|
192
222
|
default: cfg.hosting?.entrypoint ?? "index.html",
|
|
193
223
|
}]);
|
|
194
224
|
cfg.services.hosting = true;
|
|
195
|
-
cfg.hosting = {
|
|
225
|
+
cfg.hosting = {
|
|
226
|
+
siteId: site.id,
|
|
227
|
+
siteName: site.name,
|
|
228
|
+
previewUrl: site.previewUrl,
|
|
229
|
+
distDir: distDir.trim(),
|
|
230
|
+
entrypoint: entrypoint.trim(),
|
|
231
|
+
};
|
|
196
232
|
(0, config_1.saveConfig)(cfg, cwd);
|
|
197
233
|
console.log();
|
|
198
|
-
console.log(chalk_1.default.green(` ✓ Linked to "${
|
|
234
|
+
console.log(chalk_1.default.green(` ✓ Linked to "${site.name}"`));
|
|
235
|
+
console.log(chalk_1.default.dim(` Preview URL: ${site.previewUrl}`));
|
|
236
|
+
if (site.dnsWarning) {
|
|
237
|
+
console.log(chalk_1.default.yellow(` ⚠ ${site.dnsWarning}`));
|
|
238
|
+
}
|
|
199
239
|
console.log(chalk_1.default.dim(" Run `clefbase deploy` to go live."));
|
|
200
240
|
console.log();
|
|
201
241
|
}
|
|
@@ -218,15 +258,91 @@ async function runStatus(cwd = process.cwd()) {
|
|
|
218
258
|
else {
|
|
219
259
|
sp.succeed("Active deploy");
|
|
220
260
|
const d = active.deploy;
|
|
221
|
-
const url = `${cfg.serverUrl.replace(/\/+$/, "")}/hosted/${cfg.projectId}/${cfg.hosting.siteId}`;
|
|
222
261
|
console.log();
|
|
223
262
|
console.log(` ${chalk_1.default.bold("Site:")} ${cfg.hosting.siteName} ${chalk_1.default.dim(cfg.hosting.siteId)}`);
|
|
224
263
|
console.log(` ${chalk_1.default.bold("Deploy:")} ${chalk_1.default.dim(d.id)}`);
|
|
225
264
|
console.log(` ${chalk_1.default.bold("Status:")} ${chalk_1.default.green(d.status)}`);
|
|
226
265
|
console.log(` ${chalk_1.default.bold("Files:")} ${d.fileCount} ${chalk_1.default.dim(fmtBytes(d.totalBytes ?? 0))}`);
|
|
227
266
|
console.log(` ${chalk_1.default.bold("Deployed:")} ${new Date(d.finishedAt ?? d.createdAt).toLocaleString()}`);
|
|
228
|
-
|
|
267
|
+
if (cfg.hosting.previewUrl) {
|
|
268
|
+
console.log(` ${chalk_1.default.bold("Preview:")} ${chalk_1.default.cyan(cfg.hosting.previewUrl)}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
sp.fail(err.message);
|
|
274
|
+
}
|
|
275
|
+
console.log();
|
|
276
|
+
}
|
|
277
|
+
// ─── hosting:dns ──────────────────────────────────────────────────────────────
|
|
278
|
+
async function runDnsStatus(cwd = process.cwd()) {
|
|
279
|
+
const cfg = (0, config_1.requireConfig)(cwd);
|
|
280
|
+
console.log();
|
|
281
|
+
console.log(chalk_1.default.bold(" DNS Status"));
|
|
282
|
+
console.log();
|
|
283
|
+
if (!cfg.hosting?.siteId) {
|
|
284
|
+
console.log(chalk_1.default.yellow(" No site linked. Run `clefbase hosting:init` first.\n"));
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const sp = (0, ora_1.default)("Checking DNS records…").start();
|
|
288
|
+
try {
|
|
289
|
+
const dns = await (0, api_1.getDnsStatus)(cfg, cfg.hosting.siteId);
|
|
290
|
+
sp.succeed("DNS checked");
|
|
291
|
+
console.log();
|
|
292
|
+
// Preview subdomain
|
|
293
|
+
console.log(` ${chalk_1.default.bold("Preview subdomain:")}`);
|
|
294
|
+
console.log(` URL: ${chalk_1.default.cyan(dns.previewUrl)}`);
|
|
295
|
+
if (dns.preview.isCorrect) {
|
|
296
|
+
console.log(` DNS: ${chalk_1.default.green("✓ Correctly configured")}`);
|
|
297
|
+
}
|
|
298
|
+
else if (dns.preview.isConflict) {
|
|
299
|
+
console.log(` DNS: ${chalk_1.default.red("✗ Conflict — " + dns.preview.message)}`);
|
|
300
|
+
console.log(chalk_1.default.dim(" Run `clefbase hosting:dns:reprovision` to fix."));
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
console.log(` DNS: ${chalk_1.default.yellow("⚠ Not yet provisioned")}`);
|
|
304
|
+
console.log(chalk_1.default.dim(" Run `clefbase hosting:dns:reprovision` to create the record."));
|
|
229
305
|
}
|
|
306
|
+
// Custom domain
|
|
307
|
+
if (dns.customDomain) {
|
|
308
|
+
console.log();
|
|
309
|
+
console.log(` ${chalk_1.default.bold("Custom domain:")}`);
|
|
310
|
+
console.log(` Domain: ${dns.customDomain.domain}`);
|
|
311
|
+
if (dns.customDomain.cnameOk) {
|
|
312
|
+
console.log(` DNS: ${chalk_1.default.green("✓ CNAME correctly points to " + dns.customDomain.cnameTarget)}`);
|
|
313
|
+
}
|
|
314
|
+
else if (dns.customDomain.conflict) {
|
|
315
|
+
console.log(` DNS: ${chalk_1.default.red("✗ Conflict — existing record points to " + dns.customDomain.cnameTarget)}`);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
console.log(` DNS: ${chalk_1.default.yellow("⚠ CNAME not yet set")}`);
|
|
319
|
+
console.log(` Add: CNAME ${dns.customDomain.instructions.name} → ${dns.customDomain.instructions.content}`);
|
|
320
|
+
console.log(chalk_1.default.dim(` Note: ${dns.customDomain.instructions.note}`));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch (err) {
|
|
325
|
+
sp.fail(err.message);
|
|
326
|
+
}
|
|
327
|
+
console.log();
|
|
328
|
+
}
|
|
329
|
+
// ─── hosting:dns:reprovision ──────────────────────────────────────────────────
|
|
330
|
+
async function runDnsReprovision(cwd = process.cwd()) {
|
|
331
|
+
const cfg = (0, config_1.requireConfig)(cwd);
|
|
332
|
+
if (!cfg.hosting?.siteId) {
|
|
333
|
+
console.error(chalk_1.default.red("\n No site linked. Run `clefbase hosting:init` first.\n"));
|
|
334
|
+
process.exit(1);
|
|
335
|
+
}
|
|
336
|
+
const sp = (0, ora_1.default)(`Provisioning DNS for ${cfg.hosting.siteName}…`).start();
|
|
337
|
+
try {
|
|
338
|
+
const result = await (0, api_1.reprovisionDns)(cfg, cfg.hosting.siteId);
|
|
339
|
+
if (result.created) {
|
|
340
|
+
sp.succeed(chalk_1.default.green(`DNS record created: ${result.subdomain}`));
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
sp.succeed(chalk_1.default.dim(`DNS record already correct: ${result.subdomain}`));
|
|
344
|
+
}
|
|
345
|
+
console.log(chalk_1.default.cyan(` ${result.url}`));
|
|
230
346
|
}
|
|
231
347
|
catch (err) {
|
|
232
348
|
sp.fail(err.message);
|
|
@@ -234,6 +350,11 @@ async function runStatus(cwd = process.cwd()) {
|
|
|
234
350
|
console.log();
|
|
235
351
|
}
|
|
236
352
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
353
|
+
/**
|
|
354
|
+
* Interactive site picker / creator.
|
|
355
|
+
* Shows existing sites, allows creating a new one.
|
|
356
|
+
* On creation: enforces uniqueness, shows preview URL.
|
|
357
|
+
*/
|
|
237
358
|
async function pickOrCreateSite(cfg) {
|
|
238
359
|
const sp = (0, ora_1.default)("Fetching sites…").start();
|
|
239
360
|
let sites = [];
|
|
@@ -246,7 +367,10 @@ async function pickOrCreateSite(cfg) {
|
|
|
246
367
|
}
|
|
247
368
|
if (sites.length > 0) {
|
|
248
369
|
const choices = [
|
|
249
|
-
...sites.map(s => ({
|
|
370
|
+
...sites.map(s => ({
|
|
371
|
+
name: `${s.name} ${chalk_1.default.dim(s.previewUrl || s.id)}`,
|
|
372
|
+
value: s.id,
|
|
373
|
+
})),
|
|
250
374
|
{ name: chalk_1.default.cyan("+ Create a new site"), value: "__new__" },
|
|
251
375
|
];
|
|
252
376
|
const { chosen } = await inquirer_1.default.prompt([{
|
|
@@ -254,18 +378,43 @@ async function pickOrCreateSite(cfg) {
|
|
|
254
378
|
message: "Which site should receive this deploy?",
|
|
255
379
|
choices,
|
|
256
380
|
}]);
|
|
257
|
-
if (chosen !== "__new__")
|
|
258
|
-
return chosen;
|
|
381
|
+
if (chosen !== "__new__") {
|
|
382
|
+
return sites.find(s => s.id === chosen);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return createSiteInteractive(cfg);
|
|
386
|
+
}
|
|
387
|
+
/** Prompt for a new site name, handle conflict errors with retry. */
|
|
388
|
+
async function createSiteInteractive(cfg) {
|
|
389
|
+
while (true) {
|
|
390
|
+
const { name } = await inquirer_1.default.prompt([{
|
|
391
|
+
type: "input", name: "name",
|
|
392
|
+
message: "New site name (used as subdomain, e.g. my-app → my-app.preview.cleforyx.com)",
|
|
393
|
+
validate: (v) => v.trim().length >= 2 || "Must be at least 2 characters",
|
|
394
|
+
}]);
|
|
395
|
+
const s = (0, ora_1.default)(`Creating "${name.trim()}"…`).start();
|
|
396
|
+
try {
|
|
397
|
+
const site = await (0, api_1.createSite)(cfg, name.trim());
|
|
398
|
+
s.succeed(chalk_1.default.green(`Created "${site.name}" → ${chalk_1.default.cyan(site.previewUrl)}`));
|
|
399
|
+
if (site.dnsWarning) {
|
|
400
|
+
console.log(chalk_1.default.yellow(` ⚠ ${site.dnsWarning}`));
|
|
401
|
+
}
|
|
402
|
+
return site;
|
|
403
|
+
}
|
|
404
|
+
catch (err) {
|
|
405
|
+
const message = err.message;
|
|
406
|
+
// 409 conflict — name already taken
|
|
407
|
+
if (message.toLowerCase().includes("already exists") || message.includes("409")) {
|
|
408
|
+
s.fail(chalk_1.default.red(message));
|
|
409
|
+
console.log(chalk_1.default.dim(" Please choose a different name.\n"));
|
|
410
|
+
// Loop to prompt again
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
s.fail(message);
|
|
414
|
+
throw err;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
259
417
|
}
|
|
260
|
-
const { name } = await inquirer_1.default.prompt([{
|
|
261
|
-
type: "input", name: "name",
|
|
262
|
-
message: "New site name",
|
|
263
|
-
validate: (v) => v.trim().length > 0 || "Required",
|
|
264
|
-
}]);
|
|
265
|
-
const s = (0, ora_1.default)(`Creating "${name}"…`).start();
|
|
266
|
-
const site = await (0, api_1.createSite)(cfg, name.trim());
|
|
267
|
-
s.succeed(chalk_1.default.green(`Created "${site.name}" ${chalk_1.default.dim(site.id)}`));
|
|
268
|
-
return site.id;
|
|
269
418
|
}
|
|
270
419
|
async function promptDistDir(cwd) {
|
|
271
420
|
const { dir } = await inquirer_1.default.prompt([{
|
|
@@ -79,6 +79,32 @@ program
|
|
|
79
79
|
fatal(err);
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
|
+
// ─── hosting:dns ──────────────────────────────────────────────────────────────
|
|
83
|
+
program
|
|
84
|
+
.command("hosting:dns")
|
|
85
|
+
.alias("dns")
|
|
86
|
+
.description("Show DNS status for the linked site's preview and custom domains")
|
|
87
|
+
.action(async () => {
|
|
88
|
+
try {
|
|
89
|
+
await (0, deploy_1.runDnsStatus)();
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
fatal(err);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// ─── hosting:dns:reprovision ──────────────────────────────────────────────────
|
|
96
|
+
program
|
|
97
|
+
.command("hosting:dns:reprovision")
|
|
98
|
+
.alias("dns:reprovision")
|
|
99
|
+
.description("(Re-)provision the Cloudflare CNAME for the linked site")
|
|
100
|
+
.action(async () => {
|
|
101
|
+
try {
|
|
102
|
+
await (0, deploy_1.runDnsReprovision)();
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
fatal(err);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
82
108
|
// ─── info ─────────────────────────────────────────────────────────────────────
|
|
83
109
|
program
|
|
84
110
|
.command("info")
|
|
@@ -94,14 +120,16 @@ program
|
|
|
94
120
|
// ─── help footer ─────────────────────────────────────────────────────────────
|
|
95
121
|
program.addHelpText("after", `
|
|
96
122
|
${chalk_1.default.bold("Examples:")}
|
|
97
|
-
${chalk_1.default.cyan("clefbase init")}
|
|
98
|
-
${chalk_1.default.cyan("clefbase deploy")}
|
|
99
|
-
${chalk_1.default.cyan("clefbase deploy -d ./dist")}
|
|
100
|
-
${chalk_1.default.cyan("clefbase deploy -m \"v2 release\"")}
|
|
101
|
-
${chalk_1.default.cyan("clefbase hosting:init")}
|
|
102
|
-
${chalk_1.default.cyan("clefbase hosting:status")}
|
|
103
|
-
${chalk_1.default.cyan("clefbase hosting:sites")}
|
|
104
|
-
${chalk_1.default.cyan("clefbase
|
|
123
|
+
${chalk_1.default.cyan("clefbase init")} Set up a new project
|
|
124
|
+
${chalk_1.default.cyan("clefbase deploy")} Deploy your built site
|
|
125
|
+
${chalk_1.default.cyan("clefbase deploy -d ./dist")} Deploy from a specific directory
|
|
126
|
+
${chalk_1.default.cyan("clefbase deploy -m \"v2 release\"")} Deploy with a release note
|
|
127
|
+
${chalk_1.default.cyan("clefbase hosting:init")} Link or create a hosted site
|
|
128
|
+
${chalk_1.default.cyan("clefbase hosting:status")} Show current live deploy
|
|
129
|
+
${chalk_1.default.cyan("clefbase hosting:sites")} List all sites
|
|
130
|
+
${chalk_1.default.cyan("clefbase hosting:dns")} Show DNS status
|
|
131
|
+
${chalk_1.default.cyan("clefbase hosting:dns:reprovision")} Fix / create the preview CNAME
|
|
132
|
+
${chalk_1.default.cyan("clefbase info")} Show config & connection status
|
|
105
133
|
`);
|
|
106
134
|
program.parse(process.argv);
|
|
107
135
|
// ─── Helper ───────────────────────────────────────────────────────────────────
|