vela 0.10.0 → 0.10.2
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/bin.js +299 -253
- package/dist/bin.js.map +4 -4
- package/package.json +1 -1
- package/templates/minimal/package.template.json +2 -2
- package/templates/minimal/src/routes/(public)/+page.svelte +28 -12
- package/templates/minimal/src/routes/(public)/root-layout.svelte +1 -0
- package/templates/minimal/src/routes/+error.svelte +11 -4
- package/templates/static/package.template.json +4 -3
- package/templates/static/src/hooks.server.ts +6 -22
- package/templates/static/src/routes/(public)/+page.svelte +30 -13
- package/templates/static/src/routes/(public)/root-layout.svelte +1 -0
- package/templates/static/src/routes/+error.svelte +11 -4
- package/templates/static/vite.config.ts +0 -12
package/dist/bin.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "vela",
|
|
10
|
-
version: "0.10.
|
|
10
|
+
version: "0.10.2",
|
|
11
11
|
type: "module",
|
|
12
12
|
description: "A CLI for creating and updating SvelteKit projects",
|
|
13
13
|
license: "MIT",
|
|
@@ -93,6 +93,13 @@ var package_default = {
|
|
|
93
93
|
]
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
+
// src/lib/argv.ts
|
|
97
|
+
function normalizeArgv(argv2) {
|
|
98
|
+
const separator = argv2.indexOf("--");
|
|
99
|
+
if (separator === -1) return argv2;
|
|
100
|
+
return [...argv2.slice(0, separator), ...argv2.slice(separator + 1)];
|
|
101
|
+
}
|
|
102
|
+
|
|
96
103
|
// src/lib/delegate.ts
|
|
97
104
|
import fs from "node:fs";
|
|
98
105
|
import path from "node:path";
|
|
@@ -140,18 +147,18 @@ function readLocalCli(pkgPath) {
|
|
|
140
147
|
function isRecord(value) {
|
|
141
148
|
return typeof value === "object" && value !== null;
|
|
142
149
|
}
|
|
143
|
-
function isDelegatable(
|
|
144
|
-
const first =
|
|
150
|
+
function isDelegatable(argv2) {
|
|
151
|
+
const first = argv2.find((arg) => !arg.startsWith("-"));
|
|
145
152
|
return first === void 0 || !NO_DELEGATE_COMMANDS.has(first);
|
|
146
153
|
}
|
|
147
154
|
function delegateToLocalCli(opts) {
|
|
148
155
|
const env = opts.env ?? process2.env;
|
|
149
156
|
if (env[NO_DELEGATE_ENV]) return null;
|
|
150
|
-
const
|
|
151
|
-
if (!isDelegatable(
|
|
157
|
+
const argv2 = opts.argv ?? process2.argv.slice(2);
|
|
158
|
+
if (!isDelegatable(argv2)) return null;
|
|
152
159
|
const local = findLocalCli(opts.cwd ?? process2.cwd(), opts.selfPath);
|
|
153
160
|
if (!local || local.version === opts.selfVersion) return null;
|
|
154
|
-
const result = spawnSync(process2.execPath, [local.binPath, ...
|
|
161
|
+
const result = spawnSync(process2.execPath, [local.binPath, ...argv2], {
|
|
155
162
|
stdio: "inherit",
|
|
156
163
|
env: { ...env, [NO_DELEGATE_ENV]: "1" }
|
|
157
164
|
});
|
|
@@ -279,6 +286,161 @@ function stubCommand(name, description, fullName) {
|
|
|
279
286
|
return cmd;
|
|
280
287
|
}
|
|
281
288
|
|
|
289
|
+
// src/lib/workspace.ts
|
|
290
|
+
import fs3 from "node:fs";
|
|
291
|
+
import path2 from "node:path";
|
|
292
|
+
import process3 from "node:process";
|
|
293
|
+
|
|
294
|
+
// src/lib/constants.ts
|
|
295
|
+
var DATA_DIR = "data";
|
|
296
|
+
var MIGRATIONS_DIR = "migrations";
|
|
297
|
+
var PUBLIC_DIR = "(public)";
|
|
298
|
+
var APP_DIR = "(app)";
|
|
299
|
+
var LEGAL_DIR = "(legal)";
|
|
300
|
+
var API_URL = "https://velastack.dev";
|
|
301
|
+
var FIXTURE_PREFIX = "vela";
|
|
302
|
+
|
|
303
|
+
// src/lib/package-json.ts
|
|
304
|
+
import fs2 from "node:fs";
|
|
305
|
+
var DEP_KINDS = ["dependencies", "devDependencies"];
|
|
306
|
+
function mergePackageJson(user, template) {
|
|
307
|
+
const merged = structuredClone(user);
|
|
308
|
+
const added = [];
|
|
309
|
+
const conflicts = [];
|
|
310
|
+
const replaced = [];
|
|
311
|
+
for (const kind of DEP_KINDS) {
|
|
312
|
+
const templateDeps = template[kind];
|
|
313
|
+
if (!templateDeps) continue;
|
|
314
|
+
const userDeps = merged[kind] ??= {};
|
|
315
|
+
const otherKind = kind === "dependencies" ? "devDependencies" : "dependencies";
|
|
316
|
+
const userOther = user[otherKind] ?? {};
|
|
317
|
+
for (const [name, templateValue] of Object.entries(templateDeps)) {
|
|
318
|
+
if (name in userDeps) {
|
|
319
|
+
if (userDeps[name] !== templateValue) {
|
|
320
|
+
conflicts.push({ kind, name, templateValue, userValue: userDeps[name] });
|
|
321
|
+
}
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
if (name in userOther) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
userDeps[name] = templateValue;
|
|
328
|
+
added.push({ kind, name, templateValue });
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const templateScripts = template.scripts;
|
|
332
|
+
if (templateScripts) {
|
|
333
|
+
const userScripts = merged.scripts ??= {};
|
|
334
|
+
for (const [name, templateValue] of Object.entries(templateScripts)) {
|
|
335
|
+
const existing = userScripts[name];
|
|
336
|
+
if (existing === void 0) {
|
|
337
|
+
userScripts[name] = templateValue;
|
|
338
|
+
added.push({ kind: "scripts", name, templateValue });
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (existing === templateValue) continue;
|
|
342
|
+
userScripts[name] = templateValue;
|
|
343
|
+
replaced.push({ kind: "scripts", name, templateValue, userValue: existing });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
for (const kind of DEP_KINDS) {
|
|
347
|
+
const deps = merged[kind];
|
|
348
|
+
if (deps) merged[kind] = sortKeys(deps);
|
|
349
|
+
}
|
|
350
|
+
return { merged, added, conflicts, replaced };
|
|
351
|
+
}
|
|
352
|
+
function readPackageJson(path36) {
|
|
353
|
+
return JSON.parse(fs2.readFileSync(path36, "utf8"));
|
|
354
|
+
}
|
|
355
|
+
var PACKAGE_NAME_PLACEHOLDER = /~TODO~/g;
|
|
356
|
+
var APP_NAME_PLACEHOLDER = /~APP_NAME~/g;
|
|
357
|
+
var CLI_VERSION_PLACEHOLDER = /~VELA_VERSION~/g;
|
|
358
|
+
function fillTemplatePlaceholders(raw, values) {
|
|
359
|
+
const packageName = toValidPackageName(values.appName);
|
|
360
|
+
const appName = escapeSingleQuoted(values.appName);
|
|
361
|
+
return raw.replace(PACKAGE_NAME_PLACEHOLDER, () => packageName).replace(APP_NAME_PLACEHOLDER, () => appName).replace(CLI_VERSION_PLACEHOLDER, () => values.cliVersion);
|
|
362
|
+
}
|
|
363
|
+
function escapeSingleQuoted(value) {
|
|
364
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
365
|
+
}
|
|
366
|
+
function readTemplatePackageJson(path36, values) {
|
|
367
|
+
const raw = fillTemplatePlaceholders(fs2.readFileSync(path36, "utf8"), values);
|
|
368
|
+
return JSON.parse(raw);
|
|
369
|
+
}
|
|
370
|
+
function writePackageJson(path36, pkg) {
|
|
371
|
+
fs2.writeFileSync(path36, JSON.stringify(pkg, null, " ") + "\n");
|
|
372
|
+
}
|
|
373
|
+
function toValidPackageName(name) {
|
|
374
|
+
return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9~.-]+/g, "-");
|
|
375
|
+
}
|
|
376
|
+
function sortKeys(obj) {
|
|
377
|
+
const sorted = {};
|
|
378
|
+
for (const key of Object.keys(obj).sort()) sorted[key] = obj[key];
|
|
379
|
+
return sorted;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/lib/workspace.ts
|
|
383
|
+
function findWorkspaceRoot(from = process3.cwd()) {
|
|
384
|
+
let currentDir = from;
|
|
385
|
+
while (currentDir !== path2.parse(currentDir).root) {
|
|
386
|
+
if (fs3.existsSync(path2.join(currentDir, "package.json"))) return currentDir;
|
|
387
|
+
currentDir = path2.dirname(currentDir);
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
function hasBackend(from = process3.cwd()) {
|
|
392
|
+
const root = findWorkspaceRoot(from);
|
|
393
|
+
return root !== null && fs3.existsSync(path2.join(root, DATA_DIR));
|
|
394
|
+
}
|
|
395
|
+
async function getWorkspace() {
|
|
396
|
+
const workspaceRootDir = findWorkspaceRoot();
|
|
397
|
+
if (!workspaceRootDir) {
|
|
398
|
+
throw new Error("Could not find workspace root (no package.json found)");
|
|
399
|
+
}
|
|
400
|
+
const routesDir = path2.join("src", "routes");
|
|
401
|
+
const fullRoutesPath = path2.join(workspaceRootDir, routesDir);
|
|
402
|
+
if (!fs3.existsSync(fullRoutesPath)) {
|
|
403
|
+
throw new Error("Could not find src/routes directory");
|
|
404
|
+
}
|
|
405
|
+
let publicRoutesDir = path2.join(routesDir, PUBLIC_DIR);
|
|
406
|
+
if (!fs3.existsSync(path2.join(workspaceRootDir, publicRoutesDir))) {
|
|
407
|
+
publicRoutesDir = routesDir;
|
|
408
|
+
}
|
|
409
|
+
let appRoutesDir;
|
|
410
|
+
const appRoutesPath = path2.join(fullRoutesPath, APP_DIR);
|
|
411
|
+
const isAppMode = fs3.existsSync(appRoutesPath);
|
|
412
|
+
if (isAppMode) appRoutesDir = path2.join(routesDir, APP_DIR);
|
|
413
|
+
const isPaymentsMode = fs3.existsSync(
|
|
414
|
+
path2.join(workspaceRootDir, routesDir, "webhooks", "stripe")
|
|
415
|
+
);
|
|
416
|
+
const features = detectFeatures(workspaceRootDir, { isAppMode, isPaymentsMode });
|
|
417
|
+
return {
|
|
418
|
+
workspaceRootDir,
|
|
419
|
+
routesDir,
|
|
420
|
+
publicRoutesDir,
|
|
421
|
+
appRoutesDir,
|
|
422
|
+
isAppMode,
|
|
423
|
+
isPaymentsMode,
|
|
424
|
+
features
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
function detectFeatures(root, { isAppMode, isPaymentsMode }) {
|
|
428
|
+
const has = (rel) => fs3.existsSync(path2.join(root, rel));
|
|
429
|
+
const pkg = readPackageJson(path2.join(root, "package.json"));
|
|
430
|
+
const hasDep = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
431
|
+
return {
|
|
432
|
+
auth: isAppMode,
|
|
433
|
+
api: has("src/routes/api"),
|
|
434
|
+
apiKeys: has("src/routes/api/api-keys") || has("src/routes/(app)/api-keys"),
|
|
435
|
+
backend: has(DATA_DIR),
|
|
436
|
+
i18n: has("src/lib/i18n") || has("messages"),
|
|
437
|
+
teams: has("src/routes/(app)/teams") || has("src/lib/teams"),
|
|
438
|
+
payments: isPaymentsMode,
|
|
439
|
+
blog: hasDep("mdsvex"),
|
|
440
|
+
contentNegotiation: hasDep("sveltekit-negotiate")
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
282
444
|
// src/commands/bless.ts
|
|
283
445
|
import fs12 from "node:fs";
|
|
284
446
|
import path11 from "node:path";
|
|
@@ -317,32 +479,32 @@ function toFlag(key) {
|
|
|
317
479
|
}
|
|
318
480
|
|
|
319
481
|
// src/lib/templates.ts
|
|
320
|
-
import
|
|
321
|
-
import
|
|
482
|
+
import fs4 from "node:fs";
|
|
483
|
+
import path3 from "node:path";
|
|
322
484
|
import { fileURLToPath } from "node:url";
|
|
323
485
|
var TEMPLATE_MANIFEST = "template.json";
|
|
324
486
|
var DEFAULT_TEMPLATE = "minimal";
|
|
325
487
|
var cached;
|
|
326
488
|
function templatesDir() {
|
|
327
|
-
let dir =
|
|
328
|
-
const { root } =
|
|
489
|
+
let dir = path3.dirname(fileURLToPath(import.meta.url));
|
|
490
|
+
const { root } = path3.parse(dir);
|
|
329
491
|
while (dir !== root) {
|
|
330
|
-
const candidate =
|
|
492
|
+
const candidate = path3.join(dir, "templates");
|
|
331
493
|
if (holdsManifest(candidate)) return candidate;
|
|
332
|
-
dir =
|
|
494
|
+
dir = path3.dirname(dir);
|
|
333
495
|
}
|
|
334
496
|
throw new Error("Could not locate the templates directory");
|
|
335
497
|
}
|
|
336
498
|
function holdsManifest(dir) {
|
|
337
|
-
if (!
|
|
338
|
-
return
|
|
339
|
-
(entry) => entry.isDirectory() &&
|
|
499
|
+
if (!fs4.existsSync(dir)) return false;
|
|
500
|
+
return fs4.readdirSync(dir, { withFileTypes: true }).some(
|
|
501
|
+
(entry) => entry.isDirectory() && fs4.existsSync(path3.join(dir, entry.name, TEMPLATE_MANIFEST))
|
|
340
502
|
);
|
|
341
503
|
}
|
|
342
504
|
function listProjectTemplates() {
|
|
343
505
|
if (cached) return cached;
|
|
344
506
|
const root = templatesDir();
|
|
345
|
-
cached =
|
|
507
|
+
cached = fs4.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => readManifest(root, entry.name)).filter((template) => template !== void 0).sort((a, b) => a.name.localeCompare(b.name));
|
|
346
508
|
return cached;
|
|
347
509
|
}
|
|
348
510
|
function projectTemplateNames(options = {}) {
|
|
@@ -356,11 +518,11 @@ function findProjectTemplate(name) {
|
|
|
356
518
|
return template;
|
|
357
519
|
}
|
|
358
520
|
function readManifest(root, name) {
|
|
359
|
-
const manifestPath =
|
|
360
|
-
if (!
|
|
521
|
+
const manifestPath = path3.join(root, name, TEMPLATE_MANIFEST);
|
|
522
|
+
if (!fs4.existsSync(manifestPath)) return void 0;
|
|
361
523
|
let parsed;
|
|
362
524
|
try {
|
|
363
|
-
parsed = JSON.parse(
|
|
525
|
+
parsed = JSON.parse(fs4.readFileSync(manifestPath, "utf8"));
|
|
364
526
|
} catch (e) {
|
|
365
527
|
throw new Error(
|
|
366
528
|
`Template ${name} has an unreadable ${TEMPLATE_MANIFEST}: ${e.message}`
|
|
@@ -376,14 +538,14 @@ function readManifest(root, name) {
|
|
|
376
538
|
name,
|
|
377
539
|
description: manifest.description,
|
|
378
540
|
backend: manifest.backend,
|
|
379
|
-
dir:
|
|
541
|
+
dir: path3.join(root, name)
|
|
380
542
|
};
|
|
381
543
|
}
|
|
382
544
|
|
|
383
545
|
// src/lib/package-manager.ts
|
|
384
|
-
import
|
|
385
|
-
import
|
|
386
|
-
import
|
|
546
|
+
import fs5 from "node:fs";
|
|
547
|
+
import path4 from "node:path";
|
|
548
|
+
import process4 from "node:process";
|
|
387
549
|
import { exec } from "tinyexec";
|
|
388
550
|
import { Option } from "commander";
|
|
389
551
|
import * as p2 from "@clack/prompts";
|
|
@@ -399,7 +561,7 @@ var installOption = new Option(
|
|
|
399
561
|
"installs dependencies with a specified package manager"
|
|
400
562
|
).choices(AGENT_NAMES);
|
|
401
563
|
function getUserAgent() {
|
|
402
|
-
const userAgent =
|
|
564
|
+
const userAgent = process4.env.npm_config_user_agent;
|
|
403
565
|
if (!userAgent) return void 0;
|
|
404
566
|
const pmSpec = userAgent.split(" ")[0];
|
|
405
567
|
const separatorPos = pmSpec.lastIndexOf("/");
|
|
@@ -409,7 +571,7 @@ function getUserAgent() {
|
|
|
409
571
|
async function packageManagerPrompt(cwd) {
|
|
410
572
|
const detected = await detect({ cwd });
|
|
411
573
|
const agent = detected?.name ?? getUserAgent();
|
|
412
|
-
if (!
|
|
574
|
+
if (!process4.stdout.isTTY) return agent;
|
|
413
575
|
const options = [
|
|
414
576
|
{ label: "None", value: void 0 },
|
|
415
577
|
...AGENT_NAMES.map((pm2) => ({ value: pm2, label: pm2 }))
|
|
@@ -421,14 +583,14 @@ async function packageManagerPrompt(cwd) {
|
|
|
421
583
|
});
|
|
422
584
|
if (p2.isCancel(pm)) {
|
|
423
585
|
p2.cancel("Operation cancelled.");
|
|
424
|
-
|
|
586
|
+
process4.exit(1);
|
|
425
587
|
}
|
|
426
588
|
return pm;
|
|
427
589
|
}
|
|
428
590
|
async function installDependencies(agent, cwd) {
|
|
429
591
|
const task = p2.taskLog({
|
|
430
592
|
title: `Installing dependencies with ${agent}...`,
|
|
431
|
-
limit: Math.ceil(
|
|
593
|
+
limit: Math.ceil(process4.stdout.rows / 2),
|
|
432
594
|
spacing: 0,
|
|
433
595
|
retainLog: true
|
|
434
596
|
});
|
|
@@ -445,14 +607,14 @@ async function installDependencies(agent, cwd) {
|
|
|
445
607
|
} catch {
|
|
446
608
|
task.error("Failed to install dependencies");
|
|
447
609
|
p2.cancel("Operation failed.");
|
|
448
|
-
|
|
610
|
+
process4.exit(2);
|
|
449
611
|
}
|
|
450
612
|
}
|
|
451
613
|
function addPnpmBuildDependencies(cwd, packageManager, allowedPackages) {
|
|
452
614
|
if (!packageManager || packageManager !== "pnpm") return;
|
|
453
|
-
const pkgPath =
|
|
454
|
-
if (!
|
|
455
|
-
const pkg = JSON.parse(
|
|
615
|
+
const pkgPath = path4.join(cwd, "package.json");
|
|
616
|
+
if (!fs5.existsSync(pkgPath)) return;
|
|
617
|
+
const pkg = JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
|
|
456
618
|
pkg.pnpm ??= {};
|
|
457
619
|
pkg.pnpm.onlyBuiltDependencies ??= [];
|
|
458
620
|
for (const name of allowedPackages) {
|
|
@@ -460,30 +622,19 @@ function addPnpmBuildDependencies(cwd, packageManager, allowedPackages) {
|
|
|
460
622
|
pkg.pnpm.onlyBuiltDependencies.push(name);
|
|
461
623
|
}
|
|
462
624
|
}
|
|
463
|
-
|
|
625
|
+
fs5.writeFileSync(pkgPath, JSON.stringify(pkg, null, " ") + "\n");
|
|
464
626
|
}
|
|
465
627
|
|
|
466
628
|
// src/lib/pocketbase.ts
|
|
467
|
-
import
|
|
629
|
+
import fs6 from "node:fs";
|
|
468
630
|
import net from "node:net";
|
|
469
|
-
import
|
|
470
|
-
import
|
|
631
|
+
import path5 from "node:path";
|
|
632
|
+
import process5 from "node:process";
|
|
471
633
|
import { spawn } from "node:child_process";
|
|
472
634
|
import PocketBase from "pocketbase";
|
|
473
635
|
import { detect as detect2 } from "package-manager-detector";
|
|
474
636
|
import { resolveCommand } from "package-manager-detector/commands";
|
|
475
637
|
import { x } from "tinyexec";
|
|
476
|
-
|
|
477
|
-
// src/lib/constants.ts
|
|
478
|
-
var DATA_DIR = "data";
|
|
479
|
-
var MIGRATIONS_DIR = "migrations";
|
|
480
|
-
var PUBLIC_DIR = "(public)";
|
|
481
|
-
var APP_DIR = "(app)";
|
|
482
|
-
var LEGAL_DIR = "(legal)";
|
|
483
|
-
var API_URL = "https://velastack.dev";
|
|
484
|
-
var FIXTURE_PREFIX = "vela";
|
|
485
|
-
|
|
486
|
-
// src/lib/pocketbase.ts
|
|
487
638
|
function findFreePort(host = "localhost") {
|
|
488
639
|
return new Promise((resolve, reject) => {
|
|
489
640
|
const server = net.createServer();
|
|
@@ -589,9 +740,9 @@ async function authWithRetries(pb, email3, password8, attempts = 3) {
|
|
|
589
740
|
}
|
|
590
741
|
}
|
|
591
742
|
function getPocketbaseMetadata(cwd) {
|
|
592
|
-
const metadataPath =
|
|
593
|
-
if (
|
|
594
|
-
return JSON.parse(
|
|
743
|
+
const metadataPath = path5.join(cwd, "node_modules", ".vite", "_pocketbase_metadata.json");
|
|
744
|
+
if (fs6.existsSync(metadataPath)) {
|
|
745
|
+
return JSON.parse(fs6.readFileSync(metadataPath, "utf8"));
|
|
595
746
|
}
|
|
596
747
|
return null;
|
|
597
748
|
}
|
|
@@ -604,12 +755,12 @@ async function execPackageBin(cwd, args, stdio = "pipe") {
|
|
|
604
755
|
return x(command, resolvedArgs, { nodeOptions: { cwd, stdio }, throwOnError: true });
|
|
605
756
|
}
|
|
606
757
|
async function withPocketbase(cwd, fn, creds) {
|
|
607
|
-
const dir =
|
|
608
|
-
const migrationsDir =
|
|
758
|
+
const dir = path5.join(cwd, DATA_DIR);
|
|
759
|
+
const migrationsDir = path5.join(cwd, MIGRATIONS_DIR);
|
|
609
760
|
const host = "localhost";
|
|
610
|
-
const email3 = creds?.email ??
|
|
611
|
-
const password8 = creds?.password ??
|
|
612
|
-
if (!
|
|
761
|
+
const email3 = creds?.email ?? process5.env.POCKETBASE_SUPERUSER_EMAIL;
|
|
762
|
+
const password8 = creds?.password ?? process5.env.POCKETBASE_SUPERUSER_PASSWORD;
|
|
763
|
+
if (!fs6.existsSync(dir)) {
|
|
613
764
|
throw new Error("PocketBase data directory does not exist");
|
|
614
765
|
}
|
|
615
766
|
const metadata = getPocketbaseMetadata(cwd);
|
|
@@ -634,10 +785,10 @@ async function withPocketbase(cwd, fn, creds) {
|
|
|
634
785
|
}
|
|
635
786
|
}
|
|
636
787
|
async function createSuperuser(cwd, email3, password8) {
|
|
637
|
-
const dir =
|
|
638
|
-
const migrationsDir =
|
|
639
|
-
|
|
640
|
-
|
|
788
|
+
const dir = path5.join(cwd, DATA_DIR);
|
|
789
|
+
const migrationsDir = path5.join(cwd, MIGRATIONS_DIR);
|
|
790
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
791
|
+
fs6.mkdirSync(migrationsDir, { recursive: true });
|
|
641
792
|
await execPackageBin(
|
|
642
793
|
cwd,
|
|
643
794
|
[
|
|
@@ -661,8 +812,8 @@ async function launchPocketbase(cwd, {
|
|
|
661
812
|
password: password8
|
|
662
813
|
}) {
|
|
663
814
|
const host = "localhost";
|
|
664
|
-
|
|
665
|
-
|
|
815
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
816
|
+
fs6.mkdirSync(migrationsDir, { recursive: true });
|
|
666
817
|
await execPackageBin(
|
|
667
818
|
cwd,
|
|
668
819
|
[
|
|
@@ -696,8 +847,8 @@ async function launchPocketbase(cwd, {
|
|
|
696
847
|
}
|
|
697
848
|
|
|
698
849
|
// src/lib/env.ts
|
|
699
|
-
import
|
|
700
|
-
import
|
|
850
|
+
import fs7 from "node:fs";
|
|
851
|
+
import path6 from "node:path";
|
|
701
852
|
function addEnvVar(content, key, value) {
|
|
702
853
|
if (content.includes(`${key}=`)) return content;
|
|
703
854
|
return appendLine(content, `${key}=${value}`);
|
|
@@ -712,99 +863,20 @@ function appendLine(existing, line) {
|
|
|
712
863
|
return withNewline + line + "\n";
|
|
713
864
|
}
|
|
714
865
|
function writeEnvFile(cwd, vars, comments = []) {
|
|
715
|
-
const envPath =
|
|
716
|
-
let content =
|
|
866
|
+
const envPath = path6.join(cwd, ".env");
|
|
867
|
+
let content = fs7.existsSync(envPath) ? fs7.readFileSync(envPath, "utf8") : "";
|
|
717
868
|
for (const comment of comments) content = addEnvComment(content, comment);
|
|
718
869
|
for (const [key, value] of Object.entries(vars)) content = addEnvVar(content, key, value);
|
|
719
|
-
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// src/lib/package-json.ts
|
|
723
|
-
import fs6 from "node:fs";
|
|
724
|
-
var DEP_KINDS = ["dependencies", "devDependencies"];
|
|
725
|
-
function mergePackageJson(user, template) {
|
|
726
|
-
const merged = structuredClone(user);
|
|
727
|
-
const added = [];
|
|
728
|
-
const conflicts = [];
|
|
729
|
-
const replaced = [];
|
|
730
|
-
for (const kind of DEP_KINDS) {
|
|
731
|
-
const templateDeps = template[kind];
|
|
732
|
-
if (!templateDeps) continue;
|
|
733
|
-
const userDeps = merged[kind] ??= {};
|
|
734
|
-
const otherKind = kind === "dependencies" ? "devDependencies" : "dependencies";
|
|
735
|
-
const userOther = user[otherKind] ?? {};
|
|
736
|
-
for (const [name, templateValue] of Object.entries(templateDeps)) {
|
|
737
|
-
if (name in userDeps) {
|
|
738
|
-
if (userDeps[name] !== templateValue) {
|
|
739
|
-
conflicts.push({ kind, name, templateValue, userValue: userDeps[name] });
|
|
740
|
-
}
|
|
741
|
-
continue;
|
|
742
|
-
}
|
|
743
|
-
if (name in userOther) {
|
|
744
|
-
continue;
|
|
745
|
-
}
|
|
746
|
-
userDeps[name] = templateValue;
|
|
747
|
-
added.push({ kind, name, templateValue });
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
const templateScripts = template.scripts;
|
|
751
|
-
if (templateScripts) {
|
|
752
|
-
const userScripts = merged.scripts ??= {};
|
|
753
|
-
for (const [name, templateValue] of Object.entries(templateScripts)) {
|
|
754
|
-
const existing = userScripts[name];
|
|
755
|
-
if (existing === void 0) {
|
|
756
|
-
userScripts[name] = templateValue;
|
|
757
|
-
added.push({ kind: "scripts", name, templateValue });
|
|
758
|
-
continue;
|
|
759
|
-
}
|
|
760
|
-
if (existing === templateValue) continue;
|
|
761
|
-
userScripts[name] = templateValue;
|
|
762
|
-
replaced.push({ kind: "scripts", name, templateValue, userValue: existing });
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
for (const kind of DEP_KINDS) {
|
|
766
|
-
const deps = merged[kind];
|
|
767
|
-
if (deps) merged[kind] = sortKeys(deps);
|
|
768
|
-
}
|
|
769
|
-
return { merged, added, conflicts, replaced };
|
|
770
|
-
}
|
|
771
|
-
function readPackageJson(path36) {
|
|
772
|
-
return JSON.parse(fs6.readFileSync(path36, "utf8"));
|
|
773
|
-
}
|
|
774
|
-
var PACKAGE_NAME_PLACEHOLDER = /~TODO~/g;
|
|
775
|
-
var APP_NAME_PLACEHOLDER = /~APP_NAME~/g;
|
|
776
|
-
var CLI_VERSION_PLACEHOLDER = /~VELA_VERSION~/g;
|
|
777
|
-
function fillTemplatePlaceholders(raw, values) {
|
|
778
|
-
const packageName = toValidPackageName(values.appName);
|
|
779
|
-
const appName = escapeSingleQuoted(values.appName);
|
|
780
|
-
return raw.replace(PACKAGE_NAME_PLACEHOLDER, () => packageName).replace(APP_NAME_PLACEHOLDER, () => appName).replace(CLI_VERSION_PLACEHOLDER, () => values.cliVersion);
|
|
781
|
-
}
|
|
782
|
-
function escapeSingleQuoted(value) {
|
|
783
|
-
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
784
|
-
}
|
|
785
|
-
function readTemplatePackageJson(path36, values) {
|
|
786
|
-
const raw = fillTemplatePlaceholders(fs6.readFileSync(path36, "utf8"), values);
|
|
787
|
-
return JSON.parse(raw);
|
|
788
|
-
}
|
|
789
|
-
function writePackageJson(path36, pkg) {
|
|
790
|
-
fs6.writeFileSync(path36, JSON.stringify(pkg, null, " ") + "\n");
|
|
791
|
-
}
|
|
792
|
-
function toValidPackageName(name) {
|
|
793
|
-
return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9~.-]+/g, "-");
|
|
794
|
-
}
|
|
795
|
-
function sortKeys(obj) {
|
|
796
|
-
const sorted = {};
|
|
797
|
-
for (const key of Object.keys(obj).sort()) sorted[key] = obj[key];
|
|
798
|
-
return sorted;
|
|
870
|
+
fs7.writeFileSync(envPath, content);
|
|
799
871
|
}
|
|
800
872
|
|
|
801
873
|
// src/lib/config-merge.ts
|
|
802
|
-
import
|
|
803
|
-
import
|
|
874
|
+
import fs9 from "node:fs";
|
|
875
|
+
import path8 from "node:path";
|
|
804
876
|
|
|
805
877
|
// src/lib/config-target.ts
|
|
806
|
-
import
|
|
807
|
-
import
|
|
878
|
+
import fs8 from "node:fs";
|
|
879
|
+
import path7 from "node:path";
|
|
808
880
|
import {
|
|
809
881
|
Project,
|
|
810
882
|
QuoteKind,
|
|
@@ -824,8 +896,8 @@ var SVELTE_CONFIG_CANDIDATES = [
|
|
|
824
896
|
];
|
|
825
897
|
function probeFirstExisting(root, candidates) {
|
|
826
898
|
for (const rel of candidates) {
|
|
827
|
-
const abs =
|
|
828
|
-
if (
|
|
899
|
+
const abs = path7.join(root, rel);
|
|
900
|
+
if (fs8.existsSync(abs)) return abs;
|
|
829
901
|
}
|
|
830
902
|
return null;
|
|
831
903
|
}
|
|
@@ -901,7 +973,7 @@ function mergeSvelteConfig(projectRoot) {
|
|
|
901
973
|
};
|
|
902
974
|
}
|
|
903
975
|
function mergeRunesIntoViteArg(vite, arg) {
|
|
904
|
-
const file =
|
|
976
|
+
const file = path8.basename(vite.filePath);
|
|
905
977
|
const compilerOptions = getOrCreateObjectLiteralProperty(arg, "compilerOptions", "{}");
|
|
906
978
|
if (!compilerOptions) {
|
|
907
979
|
return {
|
|
@@ -920,8 +992,8 @@ function mergeRunesIntoViteArg(vite, arg) {
|
|
|
920
992
|
return { applied: true, reason: "added runes compilerOption", file };
|
|
921
993
|
}
|
|
922
994
|
function mergeRunesIntoSvelteConfig(filePath) {
|
|
923
|
-
const file =
|
|
924
|
-
const original =
|
|
995
|
+
const file = path8.basename(filePath);
|
|
996
|
+
const original = fs9.readFileSync(filePath, "utf8");
|
|
925
997
|
if (/runes\s*:/m.test(original)) {
|
|
926
998
|
return { applied: false, reason: "runes already configured", file };
|
|
927
999
|
}
|
|
@@ -944,11 +1016,11 @@ function mergeRunesIntoSvelteConfig(filePath) {
|
|
|
944
1016
|
}
|
|
945
1017
|
const insertAt = anchor.index + anchor[0].length;
|
|
946
1018
|
const updated = original.slice(0, insertAt) + RUNES_SNIPPET + original.slice(insertAt);
|
|
947
|
-
|
|
1019
|
+
fs9.writeFileSync(filePath, updated);
|
|
948
1020
|
return { applied: true, reason: "added runes compilerOption", file };
|
|
949
1021
|
}
|
|
950
1022
|
function mergeViteConfig(filePath) {
|
|
951
|
-
if (!
|
|
1023
|
+
if (!fs9.existsSync(filePath)) {
|
|
952
1024
|
return {
|
|
953
1025
|
applied: false,
|
|
954
1026
|
reason: "vite.config.ts not found",
|
|
@@ -956,7 +1028,7 @@ function mergeViteConfig(filePath) {
|
|
|
956
1028
|
// then add tailwindcss() to the plugins array`
|
|
957
1029
|
};
|
|
958
1030
|
}
|
|
959
|
-
const original =
|
|
1031
|
+
const original = fs9.readFileSync(filePath, "utf8");
|
|
960
1032
|
if (original.includes("@tailwindcss/vite")) {
|
|
961
1033
|
return { applied: false, reason: "tailwindcss plugin already present" };
|
|
962
1034
|
}
|
|
@@ -975,14 +1047,14 @@ function mergeViteConfig(filePath) {
|
|
|
975
1047
|
const trailing = withImport.slice(insertAt);
|
|
976
1048
|
const prefix = /^\s*\]/.test(trailing) ? "tailwindcss()" : "tailwindcss(), ";
|
|
977
1049
|
const updated = withImport.slice(0, insertAt) + prefix + withImport.slice(insertAt);
|
|
978
|
-
|
|
1050
|
+
fs9.writeFileSync(filePath, updated);
|
|
979
1051
|
return { applied: true, reason: "added @tailwindcss/vite plugin" };
|
|
980
1052
|
}
|
|
981
1053
|
function mergeTsconfig(filePath) {
|
|
982
|
-
if (!
|
|
1054
|
+
if (!fs9.existsSync(filePath)) {
|
|
983
1055
|
return { applied: false, reason: "tsconfig.json not found" };
|
|
984
1056
|
}
|
|
985
|
-
const original =
|
|
1057
|
+
const original = fs9.readFileSync(filePath, "utf8");
|
|
986
1058
|
if (/rewriteRelativeImportExtensions/.test(original)) {
|
|
987
1059
|
return { applied: false, reason: "rewriteRelativeImportExtensions already set" };
|
|
988
1060
|
}
|
|
@@ -998,7 +1070,7 @@ function mergeTsconfig(filePath) {
|
|
|
998
1070
|
const indent = detectIndent(original, insertAt);
|
|
999
1071
|
const updated = original.slice(0, insertAt) + `
|
|
1000
1072
|
${indent}"rewriteRelativeImportExtensions": true,` + original.slice(insertAt);
|
|
1001
|
-
|
|
1073
|
+
fs9.writeFileSync(filePath, updated);
|
|
1002
1074
|
return { applied: true, reason: "added rewriteRelativeImportExtensions" };
|
|
1003
1075
|
}
|
|
1004
1076
|
var GITIGNORE_ENTRIES = [
|
|
@@ -1010,7 +1082,7 @@ var GITIGNORE_ENTRIES = [
|
|
|
1010
1082
|
"vite.config.ts.timestamp-*"
|
|
1011
1083
|
];
|
|
1012
1084
|
function mergeGitignore(filePath) {
|
|
1013
|
-
const existing =
|
|
1085
|
+
const existing = fs9.existsSync(filePath) ? fs9.readFileSync(filePath, "utf8") : "";
|
|
1014
1086
|
const lines = existing.split("\n").map((l) => l.trim());
|
|
1015
1087
|
const missing = GITIGNORE_ENTRIES.filter((entry) => !lines.includes(entry));
|
|
1016
1088
|
if (missing.length === 0) {
|
|
@@ -1019,7 +1091,7 @@ function mergeGitignore(filePath) {
|
|
|
1019
1091
|
const needsNewline = existing.length > 0 && !existing.endsWith("\n");
|
|
1020
1092
|
const appended = `${existing}${needsNewline ? "\n" : ""}${missing.join("\n")}
|
|
1021
1093
|
`;
|
|
1022
|
-
|
|
1094
|
+
fs9.writeFileSync(filePath, appended);
|
|
1023
1095
|
return { applied: true, reason: `added ${missing.length} gitignore entries` };
|
|
1024
1096
|
}
|
|
1025
1097
|
function addImport(source, importLine) {
|
|
@@ -1044,75 +1116,14 @@ function detectIndent(source, atOffset) {
|
|
|
1044
1116
|
}
|
|
1045
1117
|
|
|
1046
1118
|
// src/lib/scaffold-detect.ts
|
|
1047
|
-
import fs9 from "node:fs";
|
|
1048
|
-
import path8 from "node:path";
|
|
1049
|
-
var VANILLA_MARKER = "Welcome to SvelteKit";
|
|
1050
|
-
var PAGE_REL = path8.join("src", "routes", "+page.svelte");
|
|
1051
|
-
function isVanillaRoutes(cwd) {
|
|
1052
|
-
const pagePath = path8.join(cwd, PAGE_REL);
|
|
1053
|
-
if (!fs9.existsSync(pagePath)) return false;
|
|
1054
|
-
return fs9.readFileSync(pagePath, "utf8").includes(VANILLA_MARKER);
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
// src/lib/workspace.ts
|
|
1058
1119
|
import fs10 from "node:fs";
|
|
1059
1120
|
import path9 from "node:path";
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
workspaceRootDir = currentDir;
|
|
1067
|
-
break;
|
|
1068
|
-
}
|
|
1069
|
-
currentDir = path9.dirname(currentDir);
|
|
1070
|
-
}
|
|
1071
|
-
if (!workspaceRootDir) {
|
|
1072
|
-
throw new Error("Could not find workspace root (no package.json found)");
|
|
1073
|
-
}
|
|
1074
|
-
const routesDir = path9.join("src", "routes");
|
|
1075
|
-
const fullRoutesPath = path9.join(workspaceRootDir, routesDir);
|
|
1076
|
-
if (!fs10.existsSync(fullRoutesPath)) {
|
|
1077
|
-
throw new Error("Could not find src/routes directory");
|
|
1078
|
-
}
|
|
1079
|
-
let publicRoutesDir = path9.join(routesDir, PUBLIC_DIR);
|
|
1080
|
-
if (!fs10.existsSync(path9.join(workspaceRootDir, publicRoutesDir))) {
|
|
1081
|
-
publicRoutesDir = routesDir;
|
|
1082
|
-
}
|
|
1083
|
-
let appRoutesDir;
|
|
1084
|
-
const appRoutesPath = path9.join(fullRoutesPath, APP_DIR);
|
|
1085
|
-
const isAppMode = fs10.existsSync(appRoutesPath);
|
|
1086
|
-
if (isAppMode) appRoutesDir = path9.join(routesDir, APP_DIR);
|
|
1087
|
-
const isPaymentsMode = fs10.existsSync(
|
|
1088
|
-
path9.join(workspaceRootDir, routesDir, "webhooks", "stripe")
|
|
1089
|
-
);
|
|
1090
|
-
const features = detectFeatures(workspaceRootDir, { isAppMode, isPaymentsMode });
|
|
1091
|
-
return {
|
|
1092
|
-
workspaceRootDir,
|
|
1093
|
-
routesDir,
|
|
1094
|
-
publicRoutesDir,
|
|
1095
|
-
appRoutesDir,
|
|
1096
|
-
isAppMode,
|
|
1097
|
-
isPaymentsMode,
|
|
1098
|
-
features
|
|
1099
|
-
};
|
|
1100
|
-
}
|
|
1101
|
-
function detectFeatures(root, { isAppMode, isPaymentsMode }) {
|
|
1102
|
-
const has = (rel) => fs10.existsSync(path9.join(root, rel));
|
|
1103
|
-
const pkg = readPackageJson(path9.join(root, "package.json"));
|
|
1104
|
-
const hasDep = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
1105
|
-
return {
|
|
1106
|
-
auth: isAppMode,
|
|
1107
|
-
api: has("src/routes/api"),
|
|
1108
|
-
apiKeys: has("src/routes/api/api-keys") || has("src/routes/(app)/api-keys"),
|
|
1109
|
-
backend: has(DATA_DIR),
|
|
1110
|
-
i18n: has("src/lib/i18n") || has("messages"),
|
|
1111
|
-
teams: has("src/routes/(app)/teams") || has("src/lib/teams"),
|
|
1112
|
-
payments: isPaymentsMode,
|
|
1113
|
-
blog: hasDep("mdsvex"),
|
|
1114
|
-
contentNegotiation: hasDep("sveltekit-negotiate")
|
|
1115
|
-
};
|
|
1121
|
+
var VANILLA_MARKER = "Welcome to SvelteKit";
|
|
1122
|
+
var PAGE_REL = path9.join("src", "routes", "+page.svelte");
|
|
1123
|
+
function isVanillaRoutes(cwd) {
|
|
1124
|
+
const pagePath = path9.join(cwd, PAGE_REL);
|
|
1125
|
+
if (!fs10.existsSync(pagePath)) return false;
|
|
1126
|
+
return fs10.readFileSync(pagePath, "utf8").includes(VANILLA_MARKER);
|
|
1116
1127
|
}
|
|
1117
1128
|
|
|
1118
1129
|
// src/lib/result-report.ts
|
|
@@ -1677,7 +1688,7 @@ import { bySlug } from "@velastack/patterns";
|
|
|
1677
1688
|
function toRelative(root, filePath) {
|
|
1678
1689
|
return path13.isAbsolute(filePath) ? path13.relative(root, filePath) : filePath;
|
|
1679
1690
|
}
|
|
1680
|
-
async function runPattern(slug,
|
|
1691
|
+
async function runPattern(slug, argv2, input, report) {
|
|
1681
1692
|
const pattern = bySlug[slug];
|
|
1682
1693
|
if (!pattern) {
|
|
1683
1694
|
throw new Error(`Unknown pattern: ${slug}`);
|
|
@@ -1687,7 +1698,7 @@ async function runPattern(slug, argv, input, report) {
|
|
|
1687
1698
|
let result;
|
|
1688
1699
|
try {
|
|
1689
1700
|
result = await pattern.generate({
|
|
1690
|
-
argv,
|
|
1701
|
+
argv: argv2,
|
|
1691
1702
|
env: "runtime",
|
|
1692
1703
|
root: workspaceRootDir,
|
|
1693
1704
|
features,
|
|
@@ -1914,7 +1925,7 @@ function typeArg(field) {
|
|
|
1914
1925
|
return null;
|
|
1915
1926
|
}
|
|
1916
1927
|
function collectionSpecToArgv(spec) {
|
|
1917
|
-
const
|
|
1928
|
+
const argv2 = [spec.name];
|
|
1918
1929
|
for (const field of spec.fields) {
|
|
1919
1930
|
const type = typeArg(field);
|
|
1920
1931
|
if (type === null) {
|
|
@@ -1924,9 +1935,9 @@ function collectionSpecToArgv(spec) {
|
|
|
1924
1935
|
continue;
|
|
1925
1936
|
}
|
|
1926
1937
|
const required = field.required ? "!" : "";
|
|
1927
|
-
|
|
1938
|
+
argv2.push(`${field.name}:${type}${required}`);
|
|
1928
1939
|
}
|
|
1929
|
-
return
|
|
1940
|
+
return argv2;
|
|
1930
1941
|
}
|
|
1931
1942
|
|
|
1932
1943
|
// src/lib/ai-grid.ts
|
|
@@ -2079,7 +2090,7 @@ var form = new Command4("form").description("generate a form from a model").argu
|
|
|
2079
2090
|
"design the form with AI from a natural-language description (two stages: schema \u2192 layout)"
|
|
2080
2091
|
).allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
2081
2092
|
(model, fields, options) => runCommand(async () => {
|
|
2082
|
-
let
|
|
2093
|
+
let argv2;
|
|
2083
2094
|
let modelName;
|
|
2084
2095
|
let sidecarPath = null;
|
|
2085
2096
|
if (options.ai) {
|
|
@@ -2096,14 +2107,14 @@ var form = new Command4("form").description("generate a form from a model").argu
|
|
|
2096
2107
|
p11.cancel("Aborted before any files were written.");
|
|
2097
2108
|
return;
|
|
2098
2109
|
}
|
|
2099
|
-
|
|
2110
|
+
argv2 = specToArgv(stage.model);
|
|
2100
2111
|
modelName = stage.model.name;
|
|
2101
2112
|
sidecarPath = writeLayoutSidecar(stage.workspaceRootDir, modelName, layout);
|
|
2102
2113
|
} else {
|
|
2103
2114
|
if (!model) {
|
|
2104
2115
|
throw new Error("Missing required argument: model. Pass a model name or use --ai.");
|
|
2105
2116
|
}
|
|
2106
|
-
|
|
2117
|
+
argv2 = [model, ...fields];
|
|
2107
2118
|
modelName = model;
|
|
2108
2119
|
}
|
|
2109
2120
|
const slug = options.remote ? "generate-form-remote" : "generate-form";
|
|
@@ -2118,7 +2129,7 @@ var form = new Command4("form").description("generate a form from a model").argu
|
|
|
2118
2129
|
}
|
|
2119
2130
|
await runPattern(
|
|
2120
2131
|
slug,
|
|
2121
|
-
|
|
2132
|
+
argv2,
|
|
2122
2133
|
{ route: options.route },
|
|
2123
2134
|
{
|
|
2124
2135
|
summary: `Created ${modelName} form.`,
|
|
@@ -2138,7 +2149,7 @@ import { Command as Command5 } from "commander";
|
|
|
2138
2149
|
import * as p12 from "@clack/prompts";
|
|
2139
2150
|
var schema = new Command5("schema").description("generate a schema from a model").argument("[model]", "model name").argument("[fields...]", "field definitions").option("--ai <description>", "design the schema with AI from a natural-language description").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
2140
2151
|
(model, fields, options) => runCommand(async () => {
|
|
2141
|
-
let
|
|
2152
|
+
let argv2;
|
|
2142
2153
|
let modelName;
|
|
2143
2154
|
if (options.ai) {
|
|
2144
2155
|
if (model) {
|
|
@@ -2149,18 +2160,18 @@ var schema = new Command5("schema").description("generate a schema from a model"
|
|
|
2149
2160
|
p12.cancel("Aborted before any files were written.");
|
|
2150
2161
|
return;
|
|
2151
2162
|
}
|
|
2152
|
-
|
|
2163
|
+
argv2 = specToArgv(stage.model);
|
|
2153
2164
|
modelName = stage.model.name;
|
|
2154
2165
|
} else {
|
|
2155
2166
|
if (!model) {
|
|
2156
2167
|
throw new Error("Missing required argument: model. Pass a model name or use --ai.");
|
|
2157
2168
|
}
|
|
2158
|
-
|
|
2169
|
+
argv2 = [model, ...fields];
|
|
2159
2170
|
modelName = model;
|
|
2160
2171
|
}
|
|
2161
2172
|
await runPattern(
|
|
2162
2173
|
"generate-schema",
|
|
2163
|
-
|
|
2174
|
+
argv2,
|
|
2164
2175
|
{},
|
|
2165
2176
|
{
|
|
2166
2177
|
summary: `Created ${modelName} schema.`,
|
|
@@ -2215,7 +2226,7 @@ var scaffold = new Command7("scaffold").description("generate a full CRUD scaffo
|
|
|
2215
2226
|
"design the scaffold with AI from a natural-language description (two stages: schema \u2192 layout)"
|
|
2216
2227
|
).allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
2217
2228
|
(model, fields, options) => runCommand(async () => {
|
|
2218
|
-
let
|
|
2229
|
+
let argv2;
|
|
2219
2230
|
let modelName;
|
|
2220
2231
|
let sidecarPath = null;
|
|
2221
2232
|
if (options.ai) {
|
|
@@ -2232,14 +2243,14 @@ var scaffold = new Command7("scaffold").description("generate a full CRUD scaffo
|
|
|
2232
2243
|
p13.cancel("Aborted before any files were written.");
|
|
2233
2244
|
return;
|
|
2234
2245
|
}
|
|
2235
|
-
|
|
2246
|
+
argv2 = specToArgv(stage.model);
|
|
2236
2247
|
modelName = stage.model.name;
|
|
2237
2248
|
sidecarPath = writeLayoutSidecar(stage.workspaceRootDir, modelName, layout);
|
|
2238
2249
|
} else {
|
|
2239
2250
|
if (!model) {
|
|
2240
2251
|
throw new Error("Missing required argument: model. Pass a model name or use --ai.");
|
|
2241
2252
|
}
|
|
2242
|
-
|
|
2253
|
+
argv2 = [model, ...fields];
|
|
2243
2254
|
modelName = model;
|
|
2244
2255
|
}
|
|
2245
2256
|
const slug = options.remote ? "generate-scaffold-remote" : "generate-scaffold";
|
|
@@ -2255,7 +2266,7 @@ var scaffold = new Command7("scaffold").description("generate a full CRUD scaffo
|
|
|
2255
2266
|
}
|
|
2256
2267
|
await runPattern(
|
|
2257
2268
|
slug,
|
|
2258
|
-
|
|
2269
|
+
argv2,
|
|
2259
2270
|
{ route: options.route },
|
|
2260
2271
|
{
|
|
2261
2272
|
summary: `Created ${modelName} scaffold.`,
|
|
@@ -5605,17 +5616,25 @@ import fs27 from "node:fs";
|
|
|
5605
5616
|
import path29 from "node:path";
|
|
5606
5617
|
import process17 from "node:process";
|
|
5607
5618
|
import { performance } from "node:perf_hooks";
|
|
5608
|
-
import { Command as Command65 } from "commander";
|
|
5619
|
+
import { Command as Command65, InvalidArgumentError as InvalidArgumentError5 } from "commander";
|
|
5609
5620
|
import pc5 from "picocolors";
|
|
5610
5621
|
import PocketBase2 from "pocketbase";
|
|
5611
|
-
|
|
5622
|
+
function parsePort(value) {
|
|
5623
|
+
const port = Number(value);
|
|
5624
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
5625
|
+
throw new InvalidArgumentError5("must be a whole number between 1 and 65535.");
|
|
5626
|
+
}
|
|
5627
|
+
return port;
|
|
5628
|
+
}
|
|
5629
|
+
var dev = new Command65("dev").description("start the development server").option("--open [path]", "open the app in a browser once the server is ready").option("--host [host]", "expose the server on the network").option("--port <port>", "port to listen on", parsePort).option("--strictPort", "exit if the port is already in use instead of taking the next one").option("--cors", "enable CORS").option("--force", "re-bundle dependencies, ignoring the optimizer cache").configureHelp(helpConfig).action(async (options) => {
|
|
5612
5630
|
const cwd = process17.cwd();
|
|
5613
5631
|
const startTime = performance.now();
|
|
5614
5632
|
const { createServer, version } = await import("vite");
|
|
5615
5633
|
const viteMetadataDir = path29.join(cwd, "node_modules", ".vite");
|
|
5616
5634
|
const viteMetadataFile = path29.join(viteMetadataDir, "_pocketbase_metadata.json");
|
|
5617
5635
|
let pbProc;
|
|
5618
|
-
const
|
|
5636
|
+
const backend3 = hasBackend(cwd);
|
|
5637
|
+
const needsStart = backend3 && !process17.env.POCKETBASE_URL;
|
|
5619
5638
|
const cleanup = () => {
|
|
5620
5639
|
if (pbProc?.pid) pbProc.kill();
|
|
5621
5640
|
if (fs27.existsSync(viteMetadataFile)) fs27.rmSync(viteMetadataFile);
|
|
@@ -5641,8 +5660,19 @@ var dev = new Command65("dev").description("start the development server").confi
|
|
|
5641
5660
|
process17.exit(0);
|
|
5642
5661
|
});
|
|
5643
5662
|
}
|
|
5644
|
-
const
|
|
5663
|
+
const serverOptions = {};
|
|
5664
|
+
if (options.open !== void 0) serverOptions.open = options.open;
|
|
5665
|
+
if (options.host !== void 0) serverOptions.host = options.host;
|
|
5666
|
+
if (options.port !== void 0) serverOptions.port = options.port;
|
|
5667
|
+
if (options.cors !== void 0) serverOptions.cors = options.cors;
|
|
5668
|
+
if (options.strictPort !== void 0) serverOptions.strictPort = options.strictPort;
|
|
5669
|
+
const inlineConfig = {
|
|
5670
|
+
server: serverOptions
|
|
5671
|
+
};
|
|
5672
|
+
if (options.force !== void 0) inlineConfig.forceOptimizeDeps = options.force;
|
|
5673
|
+
const server = await createServer(inlineConfig);
|
|
5645
5674
|
server.httpServer?.on("listening", async () => {
|
|
5675
|
+
if (!backend3) return;
|
|
5646
5676
|
const { address, port: vitePort } = server.httpServer.address();
|
|
5647
5677
|
const viteHost = address === "::1" ? "localhost" : address;
|
|
5648
5678
|
await fs27.promises.mkdir(viteMetadataDir, { recursive: true });
|
|
@@ -5711,7 +5741,7 @@ var build = new Command66("build").description("build the app").configureHelp(he
|
|
|
5711
5741
|
process18.env.VITE_BUILD = "true";
|
|
5712
5742
|
const cwd = process18.cwd();
|
|
5713
5743
|
let pbProc;
|
|
5714
|
-
const needsStart = !process18.env.POCKETBASE_URL;
|
|
5744
|
+
const needsStart = hasBackend(cwd) && !process18.env.POCKETBASE_URL;
|
|
5715
5745
|
const cleanup = () => {
|
|
5716
5746
|
if (pbProc?.pid) pbProc.kill();
|
|
5717
5747
|
};
|
|
@@ -5755,7 +5785,7 @@ import { resolveCommand as resolveCommand6 } from "package-manager-detector/comm
|
|
|
5755
5785
|
var preview = new Command67("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
|
|
5756
5786
|
const cwd = process19.cwd();
|
|
5757
5787
|
let pbProc;
|
|
5758
|
-
const needsStart = !process19.env.POCKETBASE_URL;
|
|
5788
|
+
const needsStart = hasBackend(cwd) && !process19.env.POCKETBASE_URL;
|
|
5759
5789
|
const cleanup = () => {
|
|
5760
5790
|
if (pbProc?.pid) pbProc.kill();
|
|
5761
5791
|
};
|
|
@@ -6177,6 +6207,7 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
|
6177
6207
|
"generate schema",
|
|
6178
6208
|
"generate form"
|
|
6179
6209
|
]);
|
|
6210
|
+
var BACKEND_OPTIONAL_COMMANDS = /* @__PURE__ */ new Set(["dev", "build", "preview", "deploy"]);
|
|
6180
6211
|
var program = new Command73().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
|
|
6181
6212
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
6182
6213
|
if (isStub(actionCommand)) return;
|
|
@@ -6185,6 +6216,19 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
|
6185
6216
|
if (NO_BACKEND_COMMMANDS.has(path36)) return;
|
|
6186
6217
|
const top = path36.split(" ", 1)[0];
|
|
6187
6218
|
if (NO_BACKEND_COMMMANDS.has(top)) return;
|
|
6219
|
+
if (!hasBackend()) {
|
|
6220
|
+
if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
|
|
6221
|
+
p29.log.error(
|
|
6222
|
+
`${pc7.cyan(`vela ${path36}`)} needs a backend, and this project does not have one.
|
|
6223
|
+
|
|
6224
|
+
Static projects have no database to talk to.
|
|
6225
|
+
|
|
6226
|
+
To add a backend to this project, run ${pc7.cyan("vela bless")}.`
|
|
6227
|
+
);
|
|
6228
|
+
p29.log.message();
|
|
6229
|
+
p29.cancel("Operation failed.");
|
|
6230
|
+
process23.exit(1);
|
|
6231
|
+
}
|
|
6188
6232
|
if (!process23.env.POCKETBASE_SUPERUSER_EMAIL || !process23.env.POCKETBASE_SUPERUSER_PASSWORD) {
|
|
6189
6233
|
p29.log.error(
|
|
6190
6234
|
`PocketBase superuser credentials are required.
|
|
@@ -6240,12 +6284,14 @@ for (const command of [
|
|
|
6240
6284
|
}
|
|
6241
6285
|
|
|
6242
6286
|
// src/bin.ts
|
|
6287
|
+
var argv = normalizeArgv(process24.argv.slice(2));
|
|
6243
6288
|
var delegatedExitCode = delegateToLocalCli({
|
|
6289
|
+
argv,
|
|
6244
6290
|
selfPath: fileURLToPath2(import.meta.url),
|
|
6245
6291
|
selfVersion: package_default.version
|
|
6246
6292
|
});
|
|
6247
6293
|
if (delegatedExitCode !== null) {
|
|
6248
6294
|
process24.exit(delegatedExitCode);
|
|
6249
6295
|
}
|
|
6250
|
-
program.parse();
|
|
6296
|
+
program.parse(argv, { from: "user" });
|
|
6251
6297
|
//# sourceMappingURL=bin.js.map
|