vela 0.15.0-next.1 → 0.15.0
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 +938 -753
- package/dist/bin.js.map +4 -4
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -21,7 +21,7 @@ import pc45 from "picocolors";
|
|
|
21
21
|
// package.json
|
|
22
22
|
var package_default = {
|
|
23
23
|
name: "vela",
|
|
24
|
-
version: "0.15.0
|
|
24
|
+
version: "0.15.0",
|
|
25
25
|
type: "module",
|
|
26
26
|
description: "A CLI for creating and updating SvelteKit projects",
|
|
27
27
|
license: "MIT",
|
|
@@ -298,8 +298,8 @@ function dropTemplateAdapters(user, template) {
|
|
|
298
298
|
}
|
|
299
299
|
return copy;
|
|
300
300
|
}
|
|
301
|
-
function readPackageJson(
|
|
302
|
-
return JSON.parse(fs2.readFileSync(
|
|
301
|
+
function readPackageJson(path62) {
|
|
302
|
+
return JSON.parse(fs2.readFileSync(path62, "utf8"));
|
|
303
303
|
}
|
|
304
304
|
var PACKAGE_NAME_PLACEHOLDER = /~TODO~/g;
|
|
305
305
|
var APP_NAME_PLACEHOLDER = /~APP_NAME~/g;
|
|
@@ -328,12 +328,12 @@ function jsString(value) {
|
|
|
328
328
|
const quote2 = count("'") > count('"') ? '"' : "'";
|
|
329
329
|
return `${quote2}${escapeFor(quote2, value)}${quote2}`;
|
|
330
330
|
}
|
|
331
|
-
function readTemplatePackageJson(
|
|
332
|
-
const raw = fillTemplatePlaceholders(fs2.readFileSync(
|
|
331
|
+
function readTemplatePackageJson(path62, values) {
|
|
332
|
+
const raw = fillTemplatePlaceholders(fs2.readFileSync(path62, "utf8"), values);
|
|
333
333
|
return JSON.parse(raw);
|
|
334
334
|
}
|
|
335
|
-
function writePackageJson(
|
|
336
|
-
fs2.writeFileSync(
|
|
335
|
+
function writePackageJson(path62, pkg) {
|
|
336
|
+
fs2.writeFileSync(path62, JSON.stringify(pkg, null, " ") + "\n");
|
|
337
337
|
}
|
|
338
338
|
function toValidPackageName(name) {
|
|
339
339
|
return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9~.-]+/g, "-");
|
|
@@ -1603,20 +1603,20 @@ var SITE_FILE = path10.join("src", "lib", "site.ts");
|
|
|
1603
1603
|
async function readSite(root) {
|
|
1604
1604
|
const file = path10.join(root, SITE_FILE);
|
|
1605
1605
|
if (!fs12.existsSync(file)) return null;
|
|
1606
|
-
const { Project: Project4, Node:
|
|
1606
|
+
const { Project: Project4, Node: Node4 } = await import("ts-morph");
|
|
1607
1607
|
const project = new Project4({ useInMemoryFileSystem: true });
|
|
1608
1608
|
const source = project.createSourceFile("site.ts", fs12.readFileSync(file, "utf8"));
|
|
1609
1609
|
let object6 = source.getVariableDeclaration("site")?.getInitializer();
|
|
1610
|
-
while (object6 && (
|
|
1610
|
+
while (object6 && (Node4.isAsExpression(object6) || Node4.isSatisfiesExpression(object6))) {
|
|
1611
1611
|
object6 = object6.getExpression();
|
|
1612
1612
|
}
|
|
1613
|
-
if (!object6 || !
|
|
1613
|
+
if (!object6 || !Node4.isObjectLiteralExpression(object6)) return null;
|
|
1614
1614
|
const info = {};
|
|
1615
1615
|
for (const key of ["name", "url"]) {
|
|
1616
1616
|
const property = object6.getProperty(key);
|
|
1617
|
-
if (!property || !
|
|
1617
|
+
if (!property || !Node4.isPropertyAssignment(property)) continue;
|
|
1618
1618
|
const value = property.getInitializer();
|
|
1619
|
-
if (
|
|
1619
|
+
if (Node4.isStringLiteral(value) || Node4.isNoSubstitutionTemplateLiteral(value)) {
|
|
1620
1620
|
const text19 = value.getLiteralValue().trim();
|
|
1621
1621
|
if (text19) info[key] = text19;
|
|
1622
1622
|
}
|
|
@@ -2872,13 +2872,13 @@ function printNextSteps(projectPath, packageManager2) {
|
|
|
2872
2872
|
}
|
|
2873
2873
|
|
|
2874
2874
|
// src/commands/create.ts
|
|
2875
|
-
import
|
|
2876
|
-
import
|
|
2875
|
+
import fs29 from "node:fs";
|
|
2876
|
+
import path27 from "node:path";
|
|
2877
2877
|
import process13 from "node:process";
|
|
2878
2878
|
import * as v5 from "valibot";
|
|
2879
2879
|
import { Command as Command3 } from "commander";
|
|
2880
2880
|
import * as p10 from "@clack/prompts";
|
|
2881
|
-
import { detect as
|
|
2881
|
+
import { detect as detect5, resolveCommand as resolveCommand3 } from "package-manager-detector";
|
|
2882
2882
|
|
|
2883
2883
|
// src/lib/providers.ts
|
|
2884
2884
|
import process9 from "node:process";
|
|
@@ -3311,17 +3311,17 @@ function extractApiKey(cookie) {
|
|
|
3311
3311
|
}
|
|
3312
3312
|
|
|
3313
3313
|
// src/lib/kit3-migrate.ts
|
|
3314
|
-
import
|
|
3315
|
-
import
|
|
3314
|
+
import fs27 from "node:fs";
|
|
3315
|
+
import path25 from "node:path";
|
|
3316
3316
|
import process12 from "node:process";
|
|
3317
3317
|
import { execFileSync, spawn as spawn2 } from "node:child_process";
|
|
3318
3318
|
import { createRequire as createRequire2 } from "node:module";
|
|
3319
3319
|
import * as p9 from "@clack/prompts";
|
|
3320
3320
|
import { x as x2 } from "tinyexec";
|
|
3321
|
-
import { detect as
|
|
3321
|
+
import { detect as detect4 } from "package-manager-detector";
|
|
3322
3322
|
import {
|
|
3323
|
-
ADAPTER_NODE,
|
|
3324
|
-
ADAPTER_STATIC,
|
|
3323
|
+
ADAPTER_NODE as ADAPTER_NODE2,
|
|
3324
|
+
ADAPTER_STATIC as ADAPTER_STATIC2,
|
|
3325
3325
|
ensurePackageOverrides,
|
|
3326
3326
|
FLASH,
|
|
3327
3327
|
SUPERFORMS_VERSION,
|
|
@@ -3330,9 +3330,371 @@ import {
|
|
|
3330
3330
|
VELASTACK_POCKETBASE
|
|
3331
3331
|
} from "@velastack/patterns";
|
|
3332
3332
|
|
|
3333
|
-
// src/lib/
|
|
3333
|
+
// src/lib/adapter.ts
|
|
3334
3334
|
import fs20 from "node:fs";
|
|
3335
3335
|
import path18 from "node:path";
|
|
3336
|
+
import {
|
|
3337
|
+
SyntaxKind as SyntaxKind3
|
|
3338
|
+
} from "ts-morph";
|
|
3339
|
+
import { detect as detect3 } from "package-manager-detector";
|
|
3340
|
+
var ADAPTER_NODE = "@sveltejs/adapter-node";
|
|
3341
|
+
var ADAPTER_AUTO = "@sveltejs/adapter-auto";
|
|
3342
|
+
var ADAPTER_STATIC = "@sveltejs/adapter-static";
|
|
3343
|
+
var ADAPTER_NODE_RANGE = "^6.0.0";
|
|
3344
|
+
var ADAPTER_SNIPPET = `import adapter from '${ADAPTER_NODE}';
|
|
3345
|
+
|
|
3346
|
+
// ...
|
|
3347
|
+
adapter: adapter()`;
|
|
3348
|
+
var AdapterError = class extends Error {
|
|
3349
|
+
constructor(message, snippet = ADAPTER_SNIPPET) {
|
|
3350
|
+
super(message);
|
|
3351
|
+
this.snippet = snippet;
|
|
3352
|
+
this.name = "AdapterError";
|
|
3353
|
+
}
|
|
3354
|
+
snippet;
|
|
3355
|
+
};
|
|
3356
|
+
function resolveKitTarget(root) {
|
|
3357
|
+
const svelteConfig = findSvelteConfig(root);
|
|
3358
|
+
if (svelteConfig) {
|
|
3359
|
+
throw new AdapterError(
|
|
3360
|
+
`${path18.basename(svelteConfig)} found: this looks like a SvelteKit 2 project, and
|
|
3361
|
+
SvelteKit 3 reads its config only from sveltekit({...}) in vite.config.
|
|
3362
|
+
|
|
3363
|
+
Migrate it first:`,
|
|
3364
|
+
KIT3_MIGRATE_COMMAND
|
|
3365
|
+
);
|
|
3366
|
+
}
|
|
3367
|
+
const vite = inspectViteSveltekit(root);
|
|
3368
|
+
if (vite?.inlineArg) {
|
|
3369
|
+
return {
|
|
3370
|
+
sourceFile: vite.sourceFile,
|
|
3371
|
+
filePath: vite.filePath,
|
|
3372
|
+
kit: vite.inlineArg,
|
|
3373
|
+
created: false,
|
|
3374
|
+
originalText: vite.sourceFile.getFullText()
|
|
3375
|
+
};
|
|
3376
|
+
}
|
|
3377
|
+
if (vite?.sveltekitCall) {
|
|
3378
|
+
const name = path18.basename(vite.filePath);
|
|
3379
|
+
if (vite.nonObjectArg) {
|
|
3380
|
+
throw new AdapterError(`${name} passes sveltekit() something other than an object literal.`);
|
|
3381
|
+
}
|
|
3382
|
+
const originalText = vite.sourceFile.getFullText();
|
|
3383
|
+
const kit = createSveltekitArg(vite);
|
|
3384
|
+
if (!kit)
|
|
3385
|
+
throw new AdapterError(`${name} has a sveltekit() call vela cannot add an argument to.`);
|
|
3386
|
+
return {
|
|
3387
|
+
sourceFile: vite.sourceFile,
|
|
3388
|
+
filePath: vite.filePath,
|
|
3389
|
+
kit,
|
|
3390
|
+
created: true,
|
|
3391
|
+
originalText
|
|
3392
|
+
};
|
|
3393
|
+
}
|
|
3394
|
+
throw new AdapterError(`No vite.config with a sveltekit() plugin found in ${root}.`);
|
|
3395
|
+
}
|
|
3396
|
+
function classify(specifier) {
|
|
3397
|
+
if (specifier === ADAPTER_NODE) return "node";
|
|
3398
|
+
if (specifier === ADAPTER_AUTO) return "auto";
|
|
3399
|
+
if (specifier === ADAPTER_STATIC) return "static";
|
|
3400
|
+
return "other";
|
|
3401
|
+
}
|
|
3402
|
+
function importOf(sourceFile, identifier) {
|
|
3403
|
+
return sourceFile.getImportDeclarations().find((decl) => decl.getDefaultImport()?.getText() === identifier);
|
|
3404
|
+
}
|
|
3405
|
+
function inspectAdapter(target) {
|
|
3406
|
+
const base2 = { file: target.filePath };
|
|
3407
|
+
const prop = target.kit.getProperty("adapter");
|
|
3408
|
+
if (!prop) return { info: { ...base2, kind: "none" } };
|
|
3409
|
+
if (prop.getKind() !== SyntaxKind3.PropertyAssignment) {
|
|
3410
|
+
return { info: { ...base2, kind: "other" } };
|
|
3411
|
+
}
|
|
3412
|
+
const init = prop.asKindOrThrow(SyntaxKind3.PropertyAssignment).getInitializer();
|
|
3413
|
+
if (!init || init.getKind() !== SyntaxKind3.CallExpression) {
|
|
3414
|
+
return { info: { ...base2, kind: "other" } };
|
|
3415
|
+
}
|
|
3416
|
+
const callee = init.asKindOrThrow(SyntaxKind3.CallExpression).getExpression();
|
|
3417
|
+
if (callee.getKind() !== SyntaxKind3.Identifier) {
|
|
3418
|
+
return { info: { ...base2, kind: "other" } };
|
|
3419
|
+
}
|
|
3420
|
+
const importDecl = importOf(target.sourceFile, callee.getText());
|
|
3421
|
+
if (!importDecl) return { info: { ...base2, kind: "other" } };
|
|
3422
|
+
const specifier = importDecl.getModuleSpecifierValue();
|
|
3423
|
+
return { info: { ...base2, kind: classify(specifier), specifier }, importDecl };
|
|
3424
|
+
}
|
|
3425
|
+
function detectAdapter(root) {
|
|
3426
|
+
return inspectAdapter(resolveKitTarget(root)).info;
|
|
3427
|
+
}
|
|
3428
|
+
async function ensureNodeAdapter(root, { install: install2 = true } = {}) {
|
|
3429
|
+
const target = resolveKitTarget(root);
|
|
3430
|
+
const { info, importDecl } = inspectAdapter(target);
|
|
3431
|
+
const name = path18.basename(target.filePath);
|
|
3432
|
+
const outcome = {
|
|
3433
|
+
previous: info.kind,
|
|
3434
|
+
removedDeps: [],
|
|
3435
|
+
packageJsonChanged: false
|
|
3436
|
+
};
|
|
3437
|
+
switch (info.kind) {
|
|
3438
|
+
case "node":
|
|
3439
|
+
break;
|
|
3440
|
+
case "static":
|
|
3441
|
+
throw new AdapterError(
|
|
3442
|
+
`This project builds a static site with ${ADAPTER_STATIC} (${name}).
|
|
3443
|
+
|
|
3444
|
+
vela deploy runs the app as a Node server, which needs ${ADAPTER_NODE}. Switch
|
|
3445
|
+
the adapter to deploy it here, or host the static output elsewhere.`
|
|
3446
|
+
);
|
|
3447
|
+
case "other":
|
|
3448
|
+
throw new AdapterError(
|
|
3449
|
+
`This project's adapter${info.specifier ? ` (${info.specifier})` : ""} in ${name} is not one
|
|
3450
|
+
vela will change for you.
|
|
3451
|
+
|
|
3452
|
+
vela deploy runs the app as a Node server, which needs ${ADAPTER_NODE}:`
|
|
3453
|
+
);
|
|
3454
|
+
case "auto":
|
|
3455
|
+
switchImport(target, importDecl);
|
|
3456
|
+
outcome.configFile = name;
|
|
3457
|
+
break;
|
|
3458
|
+
case "none":
|
|
3459
|
+
addAdapter(target);
|
|
3460
|
+
outcome.configFile = name;
|
|
3461
|
+
break;
|
|
3462
|
+
}
|
|
3463
|
+
if (outcome.configFile) saveTarget(target);
|
|
3464
|
+
const pkgPath = path18.join(root, "package.json");
|
|
3465
|
+
if (fs20.existsSync(pkgPath)) {
|
|
3466
|
+
const pkg = readPackageJson(pkgPath);
|
|
3467
|
+
const { changed, removed } = adoptNodeAdapter(pkg);
|
|
3468
|
+
if (changed) {
|
|
3469
|
+
writePackageJson(pkgPath, pkg);
|
|
3470
|
+
outcome.packageJsonChanged = true;
|
|
3471
|
+
outcome.removedDeps = removed;
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
if (outcome.packageJsonChanged && install2) {
|
|
3475
|
+
outcome.installedWith = await installAdapterDependencies(root);
|
|
3476
|
+
}
|
|
3477
|
+
return outcome;
|
|
3478
|
+
}
|
|
3479
|
+
async function installAdapterDependencies(root) {
|
|
3480
|
+
const agent = await packageManager(root);
|
|
3481
|
+
if (!isInstalled(agent)) {
|
|
3482
|
+
throw new AdapterError(
|
|
3483
|
+
`${agent} is not installed, so ${ADAPTER_NODE} couldn't be installed.
|
|
3484
|
+
|
|
3485
|
+
The config and package.json are already updated: install ${agent}, run \`${agent} install\`, then deploy again.`,
|
|
3486
|
+
""
|
|
3487
|
+
);
|
|
3488
|
+
}
|
|
3489
|
+
const ok = await installDependencies(agent, root, { exitOnFailure: false });
|
|
3490
|
+
if (!ok) {
|
|
3491
|
+
throw new AdapterError(
|
|
3492
|
+
`Installing ${ADAPTER_NODE} with ${agent} failed.
|
|
3493
|
+
|
|
3494
|
+
The config and package.json are already updated: run \`${agent} install\`, then deploy again.`,
|
|
3495
|
+
""
|
|
3496
|
+
);
|
|
3497
|
+
}
|
|
3498
|
+
return agent;
|
|
3499
|
+
}
|
|
3500
|
+
function switchImport(target, importDecl) {
|
|
3501
|
+
importDecl.setModuleSpecifier(ADAPTER_NODE);
|
|
3502
|
+
const prop = target.kit.getPropertyOrThrow("adapter").asKindOrThrow(SyntaxKind3.PropertyAssignment);
|
|
3503
|
+
const call = prop.getInitializerIfKindOrThrow(SyntaxKind3.CallExpression);
|
|
3504
|
+
for (let i = call.getArguments().length - 1; i >= 0; i--) call.removeArgument(i);
|
|
3505
|
+
dropAdapterAutoComments(target);
|
|
3506
|
+
}
|
|
3507
|
+
var ADAPTER_AUTO_COMMENT = /adapter-auto|svelte\.dev\/docs\/kit\/adapters|switch out the adapter/;
|
|
3508
|
+
function dropAdapterAutoComments(target) {
|
|
3509
|
+
const prop = target.kit.getPropertyOrThrow("adapter");
|
|
3510
|
+
const ranges = prop.getLeadingCommentRanges();
|
|
3511
|
+
if (ranges.length === 0 || !ranges.every((r) => ADAPTER_AUTO_COMMENT.test(r.getText()))) return;
|
|
3512
|
+
const fullStart = prop.getFullStart();
|
|
3513
|
+
const start = prop.getStart();
|
|
3514
|
+
const trivia = target.sourceFile.getFullText().slice(fullStart, start);
|
|
3515
|
+
const lastNewline = trivia.lastIndexOf("\n");
|
|
3516
|
+
if (lastNewline === -1) return;
|
|
3517
|
+
const indent = trivia.slice(lastNewline + 1);
|
|
3518
|
+
target.sourceFile.replaceText([fullStart, start], `
|
|
3519
|
+
${indent}`);
|
|
3520
|
+
}
|
|
3521
|
+
function addAdapter(target) {
|
|
3522
|
+
const taken = importOf(target.sourceFile, "adapter") ?? target.sourceFile.getVariableDeclaration("adapter");
|
|
3523
|
+
if (taken) {
|
|
3524
|
+
throw new AdapterError(
|
|
3525
|
+
`${path18.basename(target.filePath)} already binds the name \`adapter\` to something that is not the SvelteKit adapter.`
|
|
3526
|
+
);
|
|
3527
|
+
}
|
|
3528
|
+
target.sourceFile.addImportDeclaration({
|
|
3529
|
+
defaultImport: "adapter",
|
|
3530
|
+
moduleSpecifier: ADAPTER_NODE
|
|
3531
|
+
});
|
|
3532
|
+
target.kit.addPropertyAssignment({ name: "adapter", initializer: "adapter()" });
|
|
3533
|
+
}
|
|
3534
|
+
function saveTarget(target) {
|
|
3535
|
+
if (target.created) formatLikeSource(target.sourceFile);
|
|
3536
|
+
if (target.sourceFile.getFullText() === target.originalText) return;
|
|
3537
|
+
target.sourceFile.saveSync();
|
|
3538
|
+
}
|
|
3539
|
+
function adoptNodeAdapter(pkg) {
|
|
3540
|
+
const removed = [];
|
|
3541
|
+
let changed = false;
|
|
3542
|
+
for (const kind of ["dependencies", "devDependencies"]) {
|
|
3543
|
+
const deps = pkg[kind];
|
|
3544
|
+
if (deps && ADAPTER_AUTO in deps) {
|
|
3545
|
+
delete deps[ADAPTER_AUTO];
|
|
3546
|
+
removed.push(ADAPTER_AUTO);
|
|
3547
|
+
changed = true;
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
if (!pkg.dependencies?.[ADAPTER_NODE] && !pkg.devDependencies?.[ADAPTER_NODE]) {
|
|
3551
|
+
pkg.devDependencies = sortKeys({ ...pkg.devDependencies, [ADAPTER_NODE]: ADAPTER_NODE_RANGE });
|
|
3552
|
+
changed = true;
|
|
3553
|
+
}
|
|
3554
|
+
return { changed, removed: [...new Set(removed)] };
|
|
3555
|
+
}
|
|
3556
|
+
function lockfileFor(agent) {
|
|
3557
|
+
switch (agent) {
|
|
3558
|
+
case "pnpm":
|
|
3559
|
+
return "pnpm-lock.yaml";
|
|
3560
|
+
case "yarn":
|
|
3561
|
+
return "yarn.lock";
|
|
3562
|
+
case "bun":
|
|
3563
|
+
return "bun.lock";
|
|
3564
|
+
case "deno":
|
|
3565
|
+
return "deno.lock";
|
|
3566
|
+
default:
|
|
3567
|
+
return "package-lock.json";
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
async function packageManager(root) {
|
|
3571
|
+
return (await detect3({ cwd: root }))?.name ?? getUserAgent() ?? "npm";
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
// src/lib/ssr-external.ts
|
|
3575
|
+
import fs21 from "node:fs";
|
|
3576
|
+
import path19 from "node:path";
|
|
3577
|
+
import { isBuiltin } from "node:module";
|
|
3578
|
+
import { Node as Node2, SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
3579
|
+
function packageNameOf(specifier) {
|
|
3580
|
+
const parts = specifier.split("/");
|
|
3581
|
+
return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
|
|
3582
|
+
}
|
|
3583
|
+
function unwrap2(expr) {
|
|
3584
|
+
let current = expr;
|
|
3585
|
+
for (let i = 0; current && i < 10; i++) {
|
|
3586
|
+
if (Node2.isParenthesizedExpression(current) || Node2.isAsExpression(current)) {
|
|
3587
|
+
current = current.getExpression();
|
|
3588
|
+
} else if (Node2.isSatisfiesExpression(current)) {
|
|
3589
|
+
current = current.getExpression();
|
|
3590
|
+
} else if (Node2.isCallExpression(current) && current.getExpression().getText() === "defineConfig") {
|
|
3591
|
+
current = current.getArguments()[0];
|
|
3592
|
+
} else if (Node2.isIdentifier(current)) {
|
|
3593
|
+
const decl = current.getSourceFile().getVariableDeclaration(current.getText())?.getInitializer();
|
|
3594
|
+
if (!decl) return current;
|
|
3595
|
+
current = decl;
|
|
3596
|
+
} else {
|
|
3597
|
+
return current;
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
return current;
|
|
3601
|
+
}
|
|
3602
|
+
function exportedConfig(expr) {
|
|
3603
|
+
const value = unwrap2(expr);
|
|
3604
|
+
if (!value) return "it has no default export";
|
|
3605
|
+
if (Node2.isObjectLiteralExpression(value)) return value;
|
|
3606
|
+
if (Node2.isArrowFunction(value) || Node2.isFunctionExpression(value)) {
|
|
3607
|
+
return "its config is a function";
|
|
3608
|
+
}
|
|
3609
|
+
return "its default export is not an object literal";
|
|
3610
|
+
}
|
|
3611
|
+
function ssrExternalNotInDependencies(root) {
|
|
3612
|
+
let vite;
|
|
3613
|
+
try {
|
|
3614
|
+
vite = inspectViteSveltekit(root);
|
|
3615
|
+
} catch (err) {
|
|
3616
|
+
return { kind: "unknown", file: "vite.config", reason: err.message };
|
|
3617
|
+
}
|
|
3618
|
+
if (!vite) return { kind: "none" };
|
|
3619
|
+
const file = path19.basename(vite.filePath);
|
|
3620
|
+
const unknown2 = (reason) => ({ kind: "unknown", file, reason });
|
|
3621
|
+
try {
|
|
3622
|
+
const assignment = vite.sourceFile.getExportAssignment((d) => !d.isExportEquals());
|
|
3623
|
+
const config = exportedConfig(assignment?.getExpression());
|
|
3624
|
+
if (typeof config === "string") return unknown2(config);
|
|
3625
|
+
const ssrProp = config.getProperty("ssr");
|
|
3626
|
+
if (!ssrProp) return { kind: "none" };
|
|
3627
|
+
if (!Node2.isPropertyAssignment(ssrProp)) return unknown2("`ssr` is not a plain property");
|
|
3628
|
+
const ssr = unwrap2(ssrProp.getInitializer());
|
|
3629
|
+
if (!ssr || !Node2.isObjectLiteralExpression(ssr)) {
|
|
3630
|
+
return unknown2("`ssr` is not an object literal");
|
|
3631
|
+
}
|
|
3632
|
+
const externalProp = ssr.getProperty("external");
|
|
3633
|
+
if (!externalProp) return { kind: "none" };
|
|
3634
|
+
if (!Node2.isPropertyAssignment(externalProp)) {
|
|
3635
|
+
return unknown2("`ssr.external` is not a plain property");
|
|
3636
|
+
}
|
|
3637
|
+
const external = unwrap2(externalProp.getInitializer());
|
|
3638
|
+
if (!external) return unknown2("`ssr.external` has no value");
|
|
3639
|
+
if (external.getKind() === SyntaxKind4.TrueKeyword) return { kind: "all", file };
|
|
3640
|
+
if (!Node2.isArrayLiteralExpression(external)) {
|
|
3641
|
+
return unknown2("`ssr.external` is not an array literal");
|
|
3642
|
+
}
|
|
3643
|
+
const entries = [];
|
|
3644
|
+
for (const element of external.getElements()) {
|
|
3645
|
+
if (Node2.isStringLiteral(element) || Node2.isNoSubstitutionTemplateLiteral(element)) {
|
|
3646
|
+
entries.push(element.getLiteralValue());
|
|
3647
|
+
} else {
|
|
3648
|
+
return unknown2(`\`ssr.external\` has an entry that is not a string: ${element.getText()}`);
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
const pkgPath = path19.join(root, "package.json");
|
|
3652
|
+
const pkg = fs21.existsSync(pkgPath) ? readPackageJson(pkgPath) : {};
|
|
3653
|
+
const missing = entries.filter((entry) => !isBuiltin(entry)).map(packageNameOf).filter((name) => !pkg.dependencies?.[name] && pkg.devDependencies?.[name] !== void 0);
|
|
3654
|
+
return { kind: "list", file, entries, missing: [...new Set(missing)] };
|
|
3655
|
+
} catch (err) {
|
|
3656
|
+
return unknown2(err.message);
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
function moveToDependencies(pkg, names) {
|
|
3660
|
+
const moved = [];
|
|
3661
|
+
for (const name of names) {
|
|
3662
|
+
const range = pkg.devDependencies?.[name];
|
|
3663
|
+
if (range === void 0 || pkg.dependencies?.[name] !== void 0) continue;
|
|
3664
|
+
pkg.dependencies = sortKeys({ ...pkg.dependencies, [name]: range });
|
|
3665
|
+
delete pkg.devDependencies[name];
|
|
3666
|
+
moved.push(name);
|
|
3667
|
+
}
|
|
3668
|
+
return moved;
|
|
3669
|
+
}
|
|
3670
|
+
function moveSsrExternalsToDependencies(root, names) {
|
|
3671
|
+
const pkgPath = path19.join(root, "package.json");
|
|
3672
|
+
const pkg = readPackageJson(pkgPath);
|
|
3673
|
+
const moved = moveToDependencies(pkg, names);
|
|
3674
|
+
if (moved.length > 0) writePackageJson(pkgPath, pkg);
|
|
3675
|
+
return moved;
|
|
3676
|
+
}
|
|
3677
|
+
function ssrExternalProblem(check2) {
|
|
3678
|
+
if (check2.kind !== "list" || check2.missing.length === 0) return null;
|
|
3679
|
+
const names = check2.missing.join(", ");
|
|
3680
|
+
const one = check2.missing.length === 1;
|
|
3681
|
+
return `${check2.file} lists ${names} in ssr.external, but ${one ? "it is a devDependency" : "they are devDependencies"}.
|
|
3682
|
+
adapter-node 6 builds the server in one Vite pass and leaves ssr.external imports
|
|
3683
|
+
unbundled, and the server installs production dependencies only, so every page that
|
|
3684
|
+
imports ${one ? "it" : "one"} fails with ERR_MODULE_NOT_FOUND.
|
|
3685
|
+
|
|
3686
|
+
Move ${one ? "it" : "them"} to dependencies, or drop ${one ? "it" : "them"} from ssr.external.`;
|
|
3687
|
+
}
|
|
3688
|
+
function ssrExternalAllNotice(check2) {
|
|
3689
|
+
if (check2.kind !== "all") return null;
|
|
3690
|
+
return `${check2.file} sets ssr.external: true, which adapter-node 6 overrides: it bundles the
|
|
3691
|
+
whole server, dependencies included. Drop it, or list only the packages that must stay
|
|
3692
|
+
external (each in dependencies).`;
|
|
3693
|
+
}
|
|
3694
|
+
|
|
3695
|
+
// src/lib/kit-peers.ts
|
|
3696
|
+
import fs22 from "node:fs";
|
|
3697
|
+
import path20 from "node:path";
|
|
3336
3698
|
import { execFile } from "node:child_process";
|
|
3337
3699
|
var LOOKUP_TIMEOUT_MS = 15e3;
|
|
3338
3700
|
var CONCURRENCY = 8;
|
|
@@ -3368,7 +3730,7 @@ function newest(data) {
|
|
|
3368
3730
|
function installed(root, name) {
|
|
3369
3731
|
try {
|
|
3370
3732
|
const data = JSON.parse(
|
|
3371
|
-
|
|
3733
|
+
fs22.readFileSync(path20.join(root, "node_modules", name, "package.json"), "utf8")
|
|
3372
3734
|
);
|
|
3373
3735
|
return typeof data.version === "string" ? data : null;
|
|
3374
3736
|
} catch {
|
|
@@ -3426,14 +3788,14 @@ async function findKit2Peers(root, pkg, skip, lookup = npmViewLookup) {
|
|
|
3426
3788
|
}
|
|
3427
3789
|
|
|
3428
3790
|
// src/lib/locales-alias.ts
|
|
3429
|
-
import
|
|
3430
|
-
import
|
|
3431
|
-
import { Node as
|
|
3791
|
+
import fs23 from "node:fs";
|
|
3792
|
+
import path21 from "node:path";
|
|
3793
|
+
import { Node as Node3, SyntaxKind as SyntaxKind5 } from "ts-morph";
|
|
3432
3794
|
import { ensurePackageImports } from "@velastack/patterns";
|
|
3433
3795
|
var LOCALES_IMPORTS = { "#locales/*": "./src/locales/*" };
|
|
3434
3796
|
var LOCALES_DIR = "src/locales";
|
|
3435
3797
|
function keyName(node) {
|
|
3436
|
-
if (!
|
|
3798
|
+
if (!Node3.isPropertyAssignment(node)) return void 0;
|
|
3437
3799
|
return node.getNameNode().getText().replace(/^['"`]|['"`]$/g, "");
|
|
3438
3800
|
}
|
|
3439
3801
|
function localesProperty(alias) {
|
|
@@ -3441,8 +3803,8 @@ function localesProperty(alias) {
|
|
|
3441
3803
|
}
|
|
3442
3804
|
function localesSpecifier(root, rest) {
|
|
3443
3805
|
if (/\.(?:js|mjs|cjs|json)$/.test(rest)) return `#locales/${rest}`;
|
|
3444
|
-
const dir =
|
|
3445
|
-
const exists = (name) =>
|
|
3806
|
+
const dir = path21.join(root, LOCALES_DIR);
|
|
3807
|
+
const exists = (name) => fs23.existsSync(path21.join(dir, name));
|
|
3446
3808
|
if (!exists(`${rest}.js`) && (exists(`${rest}.svelte.js`) || exists(`${rest}.svelte.ts`))) {
|
|
3447
3809
|
return `#locales/${rest}.svelte.js`;
|
|
3448
3810
|
}
|
|
@@ -3462,11 +3824,11 @@ async function migrateLocalesAlias(root) {
|
|
|
3462
3824
|
const outcome = { changed: false, details: [], warnings: [] };
|
|
3463
3825
|
const vite = inspectViteSveltekit(root);
|
|
3464
3826
|
const aliasProp = vite?.inlineArg?.getProperty("alias");
|
|
3465
|
-
if (!vite || !aliasProp || !
|
|
3466
|
-
const alias = aliasProp.getInitializerIfKind(
|
|
3827
|
+
if (!vite || !aliasProp || !Node3.isPropertyAssignment(aliasProp)) return outcome;
|
|
3828
|
+
const alias = aliasProp.getInitializerIfKind(SyntaxKind5.ObjectLiteralExpression);
|
|
3467
3829
|
const entry = alias && localesProperty(alias);
|
|
3468
|
-
if (!alias || !entry || !
|
|
3469
|
-
const target = entry.getInitializerIfKind(
|
|
3830
|
+
if (!alias || !entry || !Node3.isPropertyAssignment(entry)) return outcome;
|
|
3831
|
+
const target = entry.getInitializerIfKind(SyntaxKind5.StringLiteral)?.getLiteralValue();
|
|
3470
3832
|
const normalized = target?.replace(/^\.\//, "").replace(/\/$/, "");
|
|
3471
3833
|
if (normalized !== LOCALES_DIR) return outcome;
|
|
3472
3834
|
const imports = await ensurePackageImports(root, LOCALES_IMPORTS);
|
|
@@ -3480,41 +3842,41 @@ async function migrateLocalesAlias(root) {
|
|
|
3480
3842
|
outcome.changed = true;
|
|
3481
3843
|
outcome.details.push("package.json imports #locales/*");
|
|
3482
3844
|
}
|
|
3483
|
-
const files = [...sourceFiles(
|
|
3845
|
+
const files = [...sourceFiles(path21.join(root, "src")), ...sourceFiles(path21.join(root, "test"))];
|
|
3484
3846
|
let rewritten = 0;
|
|
3485
3847
|
for (const file of files) {
|
|
3486
|
-
const source =
|
|
3848
|
+
const source = fs23.readFileSync(file, "utf8");
|
|
3487
3849
|
if (!source.includes("$locales/")) continue;
|
|
3488
3850
|
const { code: code2, changes } = rewriteLocalesSource(root, source);
|
|
3489
3851
|
if (code2 === source) continue;
|
|
3490
|
-
|
|
3852
|
+
fs23.writeFileSync(file, code2);
|
|
3491
3853
|
rewritten += changes.length;
|
|
3492
|
-
outcome.details.push(`${
|
|
3854
|
+
outcome.details.push(`${path21.relative(root, file)}: ${[...new Set(changes)].join(", ")}`);
|
|
3493
3855
|
}
|
|
3494
3856
|
entry.remove();
|
|
3495
3857
|
if (alias.getProperties().length === 0) aliasProp.remove();
|
|
3496
3858
|
vite.sourceFile.saveSync();
|
|
3497
3859
|
outcome.changed = true;
|
|
3498
3860
|
outcome.details.push(
|
|
3499
|
-
`${
|
|
3861
|
+
`${path21.basename(vite.filePath)}: removed alias.$locales${rewritten ? ` (${rewritten} specifier${rewritten === 1 ? "" : "s"} now #locales)` : ""}`
|
|
3500
3862
|
);
|
|
3501
3863
|
return outcome;
|
|
3502
3864
|
}
|
|
3503
3865
|
|
|
3504
3866
|
// src/lib/params-native.ts
|
|
3505
|
-
import
|
|
3506
|
-
import
|
|
3867
|
+
import fs24 from "node:fs";
|
|
3868
|
+
import path22 from "node:path";
|
|
3507
3869
|
import { Project as Project3, QuoteKind as QuoteKind2 } from "ts-morph";
|
|
3508
3870
|
var PARAMS_FILES = ["src/params.ts", "src/params.js"];
|
|
3509
3871
|
var PARAMS_DIR = "src/params";
|
|
3510
3872
|
var IMPORT_SPECIFIERS = /import\s+(type\s+)?([^'";]*?)\s*from\s*(['"])([^'"]+)\3/g;
|
|
3511
3873
|
function captureParamTypeImports(root) {
|
|
3512
3874
|
const names = /* @__PURE__ */ new Set();
|
|
3513
|
-
const dir =
|
|
3514
|
-
if (!
|
|
3515
|
-
for (const entry of
|
|
3875
|
+
const dir = path22.join(root, PARAMS_DIR);
|
|
3876
|
+
if (!fs24.existsSync(dir)) return names;
|
|
3877
|
+
for (const entry of fs24.readdirSync(dir)) {
|
|
3516
3878
|
if (!/\.(ts|js)$/.test(entry)) continue;
|
|
3517
|
-
const source =
|
|
3879
|
+
const source = fs24.readFileSync(path22.join(dir, entry), "utf8");
|
|
3518
3880
|
for (const match of source.matchAll(IMPORT_SPECIFIERS)) {
|
|
3519
3881
|
const clause = match[2];
|
|
3520
3882
|
const braces = clause.match(/\{([^}]*)\}/)?.[1];
|
|
@@ -3533,18 +3895,18 @@ function captureParamTypeImports(root) {
|
|
|
3533
3895
|
function resolveLocal(root, fromDir, spec) {
|
|
3534
3896
|
let base2;
|
|
3535
3897
|
if (spec.startsWith("#lib/") || spec.startsWith("$lib/")) {
|
|
3536
|
-
base2 =
|
|
3898
|
+
base2 = path22.join(root, "src", "lib", spec.slice(5));
|
|
3537
3899
|
} else if (spec.startsWith("./") || spec.startsWith("../")) {
|
|
3538
|
-
base2 =
|
|
3900
|
+
base2 = path22.resolve(fromDir, spec);
|
|
3539
3901
|
} else {
|
|
3540
3902
|
return null;
|
|
3541
3903
|
}
|
|
3542
3904
|
const stem = base2.replace(/\.js$/, "");
|
|
3543
|
-
const candidates = /\.js$/.test(base2) ? [base2, `${stem}.ts`] : [base2, `${base2}.ts`, `${base2}.js`,
|
|
3544
|
-
return candidates.find((c) =>
|
|
3905
|
+
const candidates = /\.js$/.test(base2) ? [base2, `${stem}.ts`] : [base2, `${base2}.ts`, `${base2}.js`, path22.join(base2, "index.ts"), path22.join(base2, "index.js")];
|
|
3906
|
+
return candidates.find((c) => fs24.existsSync(c) && fs24.statSync(c).isFile()) ?? null;
|
|
3545
3907
|
}
|
|
3546
3908
|
function declaresTypeOnly(file, name) {
|
|
3547
|
-
const source =
|
|
3909
|
+
const source = fs24.readFileSync(file, "utf8");
|
|
3548
3910
|
const n = name.replace(/[$]/g, "\\$");
|
|
3549
3911
|
const asValue = new RegExp(
|
|
3550
3912
|
String.raw`\bexport\s+(?:declare\s+)?(?:const|let|var|function|class|enum|async\s+function)\s+${n}\b|\bexport\s*\{[^}]*\b${n}\b`
|
|
@@ -3555,20 +3917,20 @@ function declaresTypeOnly(file, name) {
|
|
|
3555
3917
|
).test(source);
|
|
3556
3918
|
}
|
|
3557
3919
|
function relativeSpecifier(root, target) {
|
|
3558
|
-
const rel =
|
|
3920
|
+
const rel = path22.relative(path22.join(root, "src"), target).split(path22.sep).join("/");
|
|
3559
3921
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
3560
3922
|
}
|
|
3561
3923
|
function fixParamsImports(root, typeNames = /* @__PURE__ */ new Set()) {
|
|
3562
|
-
const rel = PARAMS_FILES.find((f) =>
|
|
3924
|
+
const rel = PARAMS_FILES.find((f) => fs24.existsSync(path22.join(root, f)));
|
|
3563
3925
|
if (!rel) return { changes: [], viteOnly: [] };
|
|
3564
|
-
const file =
|
|
3926
|
+
const file = path22.join(root, rel);
|
|
3565
3927
|
const outcome = { file: rel, changes: [], viteOnly: [] };
|
|
3566
3928
|
const project = new Project3({
|
|
3567
3929
|
compilerOptions: { allowJs: true },
|
|
3568
3930
|
manipulationSettings: { quoteKind: QuoteKind2.Single }
|
|
3569
3931
|
});
|
|
3570
3932
|
const sourceFile = project.addSourceFileAtPath(file);
|
|
3571
|
-
const srcDir =
|
|
3933
|
+
const srcDir = path22.join(root, "src");
|
|
3572
3934
|
const loaded = [];
|
|
3573
3935
|
for (const decl of sourceFile.getImportDeclarations()) {
|
|
3574
3936
|
const spec = decl.getModuleSpecifierValue();
|
|
@@ -3577,7 +3939,7 @@ function fixParamsImports(root, typeNames = /* @__PURE__ */ new Set()) {
|
|
|
3577
3939
|
if (!decl.isTypeOnly()) restoreTypes(decl, target, typeNames, outcome);
|
|
3578
3940
|
if (decl.isTypeOnly()) continue;
|
|
3579
3941
|
loaded.push(target);
|
|
3580
|
-
const nodeResolves = spec.startsWith("#lib/") && /\.js$/.test(spec) ?
|
|
3942
|
+
const nodeResolves = spec.startsWith("#lib/") && /\.js$/.test(spec) ? fs24.existsSync(path22.join(root, "src", "lib", spec.slice(5))) : spec.startsWith(".") && path22.resolve(srcDir, spec) === target;
|
|
3581
3943
|
if (nodeResolves) continue;
|
|
3582
3944
|
const next = relativeSpecifier(root, target);
|
|
3583
3945
|
decl.setModuleSpecifier(next);
|
|
@@ -3609,10 +3971,10 @@ function viteOnlyImports(root, start) {
|
|
|
3609
3971
|
const seen = /* @__PURE__ */ new Set();
|
|
3610
3972
|
const queue = [...start];
|
|
3611
3973
|
for (let file = queue.shift(); file; file = queue.shift()) {
|
|
3612
|
-
if (seen.has(file) || !file.startsWith(
|
|
3974
|
+
if (seen.has(file) || !file.startsWith(path22.join(root, "src"))) continue;
|
|
3613
3975
|
seen.add(file);
|
|
3614
|
-
const source =
|
|
3615
|
-
const rel =
|
|
3976
|
+
const source = fs24.readFileSync(file, "utf8");
|
|
3977
|
+
const rel = path22.relative(root, file).split(path22.sep).join("/");
|
|
3616
3978
|
for (const match of source.matchAll(IMPORT_SPECIFIERS)) {
|
|
3617
3979
|
const clause = match[2];
|
|
3618
3980
|
const spec = match[4];
|
|
@@ -3622,12 +3984,12 @@ function viteOnlyImports(root, start) {
|
|
|
3622
3984
|
found.push(`${rel}: ${spec}`);
|
|
3623
3985
|
continue;
|
|
3624
3986
|
}
|
|
3625
|
-
const target = resolveLocal(root,
|
|
3987
|
+
const target = resolveLocal(root, path22.dirname(file), spec);
|
|
3626
3988
|
if (spec.startsWith("#lib/")) {
|
|
3627
|
-
if (!
|
|
3989
|
+
if (!fs24.existsSync(path22.join(root, "src", "lib", spec.slice(5)))) {
|
|
3628
3990
|
found.push(`${rel}: ${spec}`);
|
|
3629
3991
|
}
|
|
3630
|
-
} else if (spec.startsWith(".") && target &&
|
|
3992
|
+
} else if (spec.startsWith(".") && target && path22.resolve(path22.dirname(file), spec) !== target) {
|
|
3631
3993
|
found.push(`${rel}: ${spec}`);
|
|
3632
3994
|
}
|
|
3633
3995
|
if (target) queue.push(target);
|
|
@@ -3637,15 +3999,15 @@ function viteOnlyImports(root, start) {
|
|
|
3637
3999
|
}
|
|
3638
4000
|
|
|
3639
4001
|
// src/lib/lib-rewrite.ts
|
|
3640
|
-
import
|
|
3641
|
-
import
|
|
4002
|
+
import fs25 from "node:fs";
|
|
4003
|
+
import path23 from "node:path";
|
|
3642
4004
|
import { libSpecifier } from "@velastack/patterns";
|
|
3643
4005
|
var KEPT_EXTENSIONS = /\.(svelte|svg|svx|css|json)$/;
|
|
3644
4006
|
var MODULE_EXTENSIONS = [".ts", ".js", ".mts", ".mjs"];
|
|
3645
4007
|
function resolveLibPath(root, rel) {
|
|
3646
|
-
const lib =
|
|
3647
|
-
const isFile = (p73) =>
|
|
3648
|
-
const isDir = (p73) =>
|
|
4008
|
+
const lib = path23.join(root, "src", "lib");
|
|
4009
|
+
const isFile = (p73) => fs25.existsSync(path23.join(lib, p73)) && fs25.statSync(path23.join(lib, p73)).isFile();
|
|
4010
|
+
const isDir = (p73) => fs25.existsSync(path23.join(lib, p73)) && fs25.statSync(path23.join(lib, p73)).isDirectory();
|
|
3649
4011
|
if (rel === "") return "";
|
|
3650
4012
|
if (KEPT_EXTENSIONS.test(rel)) {
|
|
3651
4013
|
if (isFile(rel)) return rel;
|
|
@@ -3685,40 +4047,40 @@ function rewriteLibSpecifiers(root, source) {
|
|
|
3685
4047
|
}
|
|
3686
4048
|
function filesOutsideSrc(root) {
|
|
3687
4049
|
const files = [];
|
|
3688
|
-
const test =
|
|
3689
|
-
if (
|
|
3690
|
-
for (const rel of
|
|
4050
|
+
const test = path23.join(root, "test");
|
|
4051
|
+
if (fs25.existsSync(test)) {
|
|
4052
|
+
for (const rel of fs25.globSync("**/*.{ts,js,mts,mjs,svelte}", {
|
|
3691
4053
|
cwd: test,
|
|
3692
4054
|
exclude: (name) => name === "node_modules"
|
|
3693
4055
|
})) {
|
|
3694
|
-
files.push(
|
|
4056
|
+
files.push(path23.join(test, rel));
|
|
3695
4057
|
}
|
|
3696
4058
|
}
|
|
3697
|
-
for (const entry of
|
|
4059
|
+
for (const entry of fs25.readdirSync(root, { withFileTypes: true })) {
|
|
3698
4060
|
if (entry.isFile() && /\.(ts|js|mts|mjs|cts|cjs)$/.test(entry.name) && !entry.name.endsWith(".d.ts")) {
|
|
3699
|
-
files.push(
|
|
4061
|
+
files.push(path23.join(root, entry.name));
|
|
3700
4062
|
}
|
|
3701
4063
|
}
|
|
3702
|
-
return files.filter((f) =>
|
|
4064
|
+
return files.filter((f) => fs25.statSync(f).isFile()).sort();
|
|
3703
4065
|
}
|
|
3704
4066
|
function rewriteLibOutsideSrc(root) {
|
|
3705
4067
|
const result = { rewritten: [], unresolved: [] };
|
|
3706
4068
|
for (const file of filesOutsideSrc(root)) {
|
|
3707
|
-
const source =
|
|
4069
|
+
const source = fs25.readFileSync(file, "utf8");
|
|
3708
4070
|
if (!source.includes("$lib")) continue;
|
|
3709
|
-
const rel =
|
|
4071
|
+
const rel = path23.relative(root, file);
|
|
3710
4072
|
const { code: code2, changes, unresolved } = rewriteLibSpecifiers(root, source);
|
|
3711
4073
|
result.unresolved.push(...unresolved.map((spec) => `${rel}: ${spec}`));
|
|
3712
4074
|
if (code2 === source) continue;
|
|
3713
|
-
|
|
4075
|
+
fs25.writeFileSync(file, code2);
|
|
3714
4076
|
result.rewritten.push({ file: rel, changes });
|
|
3715
4077
|
}
|
|
3716
4078
|
return result;
|
|
3717
4079
|
}
|
|
3718
4080
|
function rewriteComponentsJsonAliases(root) {
|
|
3719
|
-
const file =
|
|
3720
|
-
if (!
|
|
3721
|
-
const source =
|
|
4081
|
+
const file = path23.join(root, "components.json");
|
|
4082
|
+
if (!fs25.existsSync(file)) return null;
|
|
4083
|
+
const source = fs25.readFileSync(file, "utf8");
|
|
3722
4084
|
let data;
|
|
3723
4085
|
try {
|
|
3724
4086
|
data = JSON.parse(source);
|
|
@@ -3736,13 +4098,13 @@ function rewriteComponentsJsonAliases(root) {
|
|
|
3736
4098
|
changes.push(`${value} \u2192 ${next}`);
|
|
3737
4099
|
}
|
|
3738
4100
|
if (code2 === source) return null;
|
|
3739
|
-
|
|
4101
|
+
fs25.writeFileSync(file, code2);
|
|
3740
4102
|
return { file: "components.json", changes };
|
|
3741
4103
|
}
|
|
3742
4104
|
|
|
3743
4105
|
// src/lib/kit3-rewrites.ts
|
|
3744
|
-
import
|
|
3745
|
-
import
|
|
4106
|
+
import fs26 from "node:fs";
|
|
4107
|
+
import path24 from "node:path";
|
|
3746
4108
|
var MIGRATION_TASK_MARKER = "@migration-task";
|
|
3747
4109
|
var NAVIGATION_IMPORT = /import\s*\{([^}]*)\}\s*from\s*['"]\$app\/navigation['"]\s*;?/g;
|
|
3748
4110
|
function navigationBindings(source) {
|
|
@@ -4128,15 +4490,15 @@ function rewriteKit3Source(file, source) {
|
|
|
4128
4490
|
}
|
|
4129
4491
|
function rewriteKit3Code(root) {
|
|
4130
4492
|
const results = [];
|
|
4131
|
-
const files = [...sourceFiles(
|
|
4493
|
+
const files = [...sourceFiles(path24.join(root, "src")), ...sourceFiles(path24.join(root, "test"))];
|
|
4132
4494
|
for (const file of files) {
|
|
4133
|
-
const source =
|
|
4495
|
+
const source = fs26.readFileSync(file, "utf8");
|
|
4134
4496
|
if (!/\$app\/navigation|\$app\/environment|\$env\/|new\s+URL\(\s*\$?page\.url\s*\)/.test(source))
|
|
4135
4497
|
continue;
|
|
4136
|
-
const rel =
|
|
4498
|
+
const rel = path24.relative(root, file);
|
|
4137
4499
|
const { code: code2, changes, tasks } = rewriteKit3Source(rel, source);
|
|
4138
4500
|
if (code2 === source) continue;
|
|
4139
|
-
|
|
4501
|
+
fs26.writeFileSync(file, code2);
|
|
4140
4502
|
results.push({ file: rel, changes, tasks });
|
|
4141
4503
|
}
|
|
4142
4504
|
return results;
|
|
@@ -4182,13 +4544,13 @@ function rewriteVelaEnvDefaultsSource(source) {
|
|
|
4182
4544
|
}
|
|
4183
4545
|
function rewriteVelaEnvDefaults(root) {
|
|
4184
4546
|
const results = [];
|
|
4185
|
-
for (const file of sourceFiles(
|
|
4186
|
-
const source =
|
|
4547
|
+
for (const file of sourceFiles(path24.join(root, "src"))) {
|
|
4548
|
+
const source = fs26.readFileSync(file, "utf8");
|
|
4187
4549
|
if (!source.includes("$app/env/") || !source.includes("??")) continue;
|
|
4188
4550
|
const { code: code2, changes } = rewriteVelaEnvDefaultsSource(source);
|
|
4189
4551
|
if (code2 === source) continue;
|
|
4190
|
-
|
|
4191
|
-
results.push({ file:
|
|
4552
|
+
fs26.writeFileSync(file, code2);
|
|
4553
|
+
results.push({ file: path24.relative(root, file), changes, tasks: [] });
|
|
4192
4554
|
}
|
|
4193
4555
|
return results;
|
|
4194
4556
|
}
|
|
@@ -4255,6 +4617,7 @@ async function runKit3Migration(root, options = {}) {
|
|
|
4255
4617
|
codeFixup(root),
|
|
4256
4618
|
tsconfigFixup(root),
|
|
4257
4619
|
packageFixup(root, cliVersion),
|
|
4620
|
+
ssrExternalFixup(root),
|
|
4258
4621
|
await peersFixup(root, options.peerLookup),
|
|
4259
4622
|
lockfileFixup(root)
|
|
4260
4623
|
];
|
|
@@ -4269,10 +4632,10 @@ async function runKit3Migration(root, options = {}) {
|
|
|
4269
4632
|
if (installed2) formatted = await formatChanged(root, dirtyBefore);
|
|
4270
4633
|
}
|
|
4271
4634
|
const found = [...collectFollowUps(root, sv), ...fixups.flatMap((f) => f.followUps ?? [])];
|
|
4272
|
-
if (!sv.ran) found.unshift(...
|
|
4635
|
+
if (!sv.ran) found.unshift(...previousFollowUps(root, SV_FAILURE_ITEM));
|
|
4273
4636
|
const followUps = [...new Set(found)];
|
|
4274
4637
|
const genericFollowUps = depRange(
|
|
4275
|
-
readJson(
|
|
4638
|
+
readJson(path25.join(root, "package.json")).data,
|
|
4276
4639
|
"@sveltejs/adapter-node"
|
|
4277
4640
|
) ? [
|
|
4278
4641
|
"Servers need Node 22.17 or later: run `vela provision` on each before the first SvelteKit 3 deploy."
|
|
@@ -4288,9 +4651,9 @@ async function preflight(root, options) {
|
|
|
4288
4651
|
`SvelteKit 3 needs Node ${NODE_FLOOR} or later; this is Node ${options.nodeVersion ?? process12.versions.node}.`
|
|
4289
4652
|
);
|
|
4290
4653
|
}
|
|
4291
|
-
const pkgPath =
|
|
4292
|
-
if (!
|
|
4293
|
-
const project = JSON.parse(
|
|
4654
|
+
const pkgPath = path25.join(root, "package.json");
|
|
4655
|
+
if (!fs27.existsSync(pkgPath)) throw new Kit3MigrationError(`No package.json found in ${root}.`);
|
|
4656
|
+
const project = JSON.parse(fs27.readFileSync(pkgPath, "utf8"));
|
|
4294
4657
|
if (!project.devDependencies?.["@sveltejs/kit"]) {
|
|
4295
4658
|
throw new Kit3MigrationError(
|
|
4296
4659
|
project.dependencies?.["@sveltejs/kit"] ? "@sveltejs/kit is in dependencies; sv migrates it only from devDependencies. Move it there and run this again." : `@sveltejs/kit is not a devDependency in ${pkgPath}: this does not look like a SvelteKit project.`
|
|
@@ -4347,14 +4710,14 @@ function clearOutputDirs(root, log55) {
|
|
|
4347
4710
|
const cleared = [];
|
|
4348
4711
|
const inGit = spawnSync("git", ["rev-parse", "--is-inside-work-tree"], root) !== null;
|
|
4349
4712
|
const walk2 = (dir, depth) => {
|
|
4350
|
-
for (const entry of
|
|
4713
|
+
for (const entry of fs27.readdirSync(dir, { withFileTypes: true })) {
|
|
4351
4714
|
if (!entry.isDirectory() || entry.name === "node_modules" || entry.name === ".git") continue;
|
|
4352
|
-
const full =
|
|
4353
|
-
const rel =
|
|
4715
|
+
const full = path25.join(dir, entry.name);
|
|
4716
|
+
const rel = path25.relative(root, full);
|
|
4354
4717
|
if (OUTPUT_DIRS.has(entry.name)) {
|
|
4355
4718
|
const ignored = inGit ? spawnSync("git", ["check-ignore", "-q", rel], root) !== null : entry.name === ".svelte-kit";
|
|
4356
4719
|
if (ignored) {
|
|
4357
|
-
|
|
4720
|
+
fs27.rmSync(full, { recursive: true, force: true });
|
|
4358
4721
|
cleared.push(rel);
|
|
4359
4722
|
} else if (entry.name !== ".svelte-kit") {
|
|
4360
4723
|
log55.warn(
|
|
@@ -4373,18 +4736,18 @@ function clearOutputDirs(root, log55) {
|
|
|
4373
4736
|
}
|
|
4374
4737
|
function svBin() {
|
|
4375
4738
|
const entry = require_.resolve("sv");
|
|
4376
|
-
let dir =
|
|
4377
|
-
while (dir !==
|
|
4378
|
-
const manifest =
|
|
4379
|
-
if (
|
|
4380
|
-
const data = JSON.parse(
|
|
4739
|
+
let dir = path25.dirname(entry);
|
|
4740
|
+
while (dir !== path25.dirname(dir)) {
|
|
4741
|
+
const manifest = path25.join(dir, "package.json");
|
|
4742
|
+
if (fs27.existsSync(manifest)) {
|
|
4743
|
+
const data = JSON.parse(fs27.readFileSync(manifest, "utf8"));
|
|
4381
4744
|
if (data.name === "sv") {
|
|
4382
4745
|
const bin = typeof data.bin === "string" ? data.bin : data.bin?.sv;
|
|
4383
4746
|
if (!bin) throw new Kit3MigrationError("The installed sv package has no bin.");
|
|
4384
|
-
return
|
|
4747
|
+
return path25.join(dir, bin);
|
|
4385
4748
|
}
|
|
4386
4749
|
}
|
|
4387
|
-
dir =
|
|
4750
|
+
dir = path25.dirname(dir);
|
|
4388
4751
|
}
|
|
4389
4752
|
throw new Kit3MigrationError("Could not find the sv package vela depends on. Reinstall vela.");
|
|
4390
4753
|
}
|
|
@@ -4534,7 +4897,7 @@ async function envFixup(root) {
|
|
|
4534
4897
|
}
|
|
4535
4898
|
function libFixup(root, skippedBySv) {
|
|
4536
4899
|
const f = fixup("#lib");
|
|
4537
|
-
const pkgPath =
|
|
4900
|
+
const pkgPath = path25.join(root, "package.json");
|
|
4538
4901
|
const { data, indent } = readJson(pkgPath);
|
|
4539
4902
|
if (ensureLibImports(data)) {
|
|
4540
4903
|
writeJson(pkgPath, data, indent);
|
|
@@ -4547,14 +4910,14 @@ function libFixup(root, skippedBySv) {
|
|
|
4547
4910
|
f.details.push(`components.json aliases ${components.changes.join(", ")}`);
|
|
4548
4911
|
}
|
|
4549
4912
|
for (const rel of skippedBySv) {
|
|
4550
|
-
const file =
|
|
4551
|
-
if (!
|
|
4552
|
-
const source =
|
|
4913
|
+
const file = path25.join(root, rel);
|
|
4914
|
+
if (!fs27.existsSync(file)) continue;
|
|
4915
|
+
const source = fs27.readFileSync(file, "utf8");
|
|
4553
4916
|
const { code: code2, changes, unresolved } = rewriteLibSpecifiers(root, source);
|
|
4554
4917
|
for (const u of unresolved)
|
|
4555
4918
|
f.warnings.push(`${rel}: ${u} names nothing under src/lib; change it by hand`);
|
|
4556
4919
|
if (code2 === source) continue;
|
|
4557
|
-
|
|
4920
|
+
fs27.writeFileSync(file, code2);
|
|
4558
4921
|
f.changed = true;
|
|
4559
4922
|
f.details.push(`${rel} (skipped by sv): ${changes.join(", ")}`);
|
|
4560
4923
|
}
|
|
@@ -4622,8 +4985,8 @@ function splitSpec(spec) {
|
|
|
4622
4985
|
}
|
|
4623
4986
|
var FLOORS = [
|
|
4624
4987
|
["@sveltejs/kit", "^3.0.0"],
|
|
4625
|
-
splitSpec(
|
|
4626
|
-
splitSpec(
|
|
4988
|
+
splitSpec(ADAPTER_NODE2),
|
|
4989
|
+
splitSpec(ADAPTER_STATIC2),
|
|
4627
4990
|
["@sveltejs/adapter-auto", "^8.0.0"],
|
|
4628
4991
|
["@sveltejs/package", "^3.0.0"],
|
|
4629
4992
|
["@sveltejs/vite-plugin-svelte", "^7.3.1"],
|
|
@@ -4647,7 +5010,7 @@ var EXACT_PINS = [
|
|
|
4647
5010
|
var ENGINES_FLOOR = ">=22.17";
|
|
4648
5011
|
function packageFixup(root, cliVersion) {
|
|
4649
5012
|
const f = fixup("package.json");
|
|
4650
|
-
const pkgPath =
|
|
5013
|
+
const pkgPath = path25.join(root, "package.json");
|
|
4651
5014
|
const { data, indent } = readJson(pkgPath);
|
|
4652
5015
|
const changed = [];
|
|
4653
5016
|
for (const [name, range] of [...FLOORS, ["vela", `^${cliVersion}`]]) {
|
|
@@ -4693,13 +5056,40 @@ function packageFixup(root, cliVersion) {
|
|
|
4693
5056
|
}
|
|
4694
5057
|
return f;
|
|
4695
5058
|
}
|
|
5059
|
+
function ssrExternalFixup(root) {
|
|
5060
|
+
const f = fixup("ssr.external");
|
|
5061
|
+
f.followUps = previousFollowUps(root, SSR_EXTERNAL_ITEM);
|
|
5062
|
+
let adapter;
|
|
5063
|
+
try {
|
|
5064
|
+
adapter = detectAdapter(root);
|
|
5065
|
+
} catch {
|
|
5066
|
+
return f;
|
|
5067
|
+
}
|
|
5068
|
+
if (adapter.kind !== "node") return f;
|
|
5069
|
+
const check2 = ssrExternalNotInDependencies(root);
|
|
5070
|
+
if (check2.kind === "list" && check2.missing.length > 0) {
|
|
5071
|
+
const moved = moveSsrExternalsToDependencies(root, check2.missing);
|
|
5072
|
+
if (moved.length > 0) {
|
|
5073
|
+
f.changed = true;
|
|
5074
|
+
f.details.push(`moved ${moved.join(", ")} from devDependencies to dependencies`);
|
|
5075
|
+
f.followUps.push(
|
|
5076
|
+
`${code(check2.file)}: moved ${moved.map(code).join(", ")} from devDependencies to dependencies because \`ssr.external\` lists ${moved.length === 1 ? "it" : "them"}. adapter-node 6 builds the server in one Vite pass and no longer bundles \`ssr.external\` imports, and the server installs production dependencies only. Keep ${moved.length === 1 ? "it" : "them"} in dependencies, or drop ${moved.length === 1 ? "it" : "them"} from \`ssr.external\` to have ${moved.length === 1 ? "it" : "them"} bundled.`
|
|
5077
|
+
);
|
|
5078
|
+
}
|
|
5079
|
+
} else if (check2.kind === "all") {
|
|
5080
|
+
f.followUps.push(
|
|
5081
|
+
`${code(check2.file)}: \`ssr.external: true\` does nothing under adapter-node 6, which bundles the whole server, dependencies included. Drop it, or list only the packages that must stay external, each in dependencies.`
|
|
5082
|
+
);
|
|
5083
|
+
}
|
|
5084
|
+
return f;
|
|
5085
|
+
}
|
|
4696
5086
|
function bumpedHere(name) {
|
|
4697
5087
|
return name === "vela" || name.startsWith("@sveltejs/") || name.startsWith("@velastack/") || name.startsWith("@types/") || FLOORS.some(([floor]) => floor === name) || EXACT_PINS.some(([pin]) => pin === name);
|
|
4698
5088
|
}
|
|
4699
5089
|
async function peersFixup(root, lookup) {
|
|
4700
5090
|
const f = fixup("SvelteKit 2 peers");
|
|
4701
5091
|
f.followUps = [];
|
|
4702
|
-
const data = readJson(
|
|
5092
|
+
const data = readJson(path25.join(root, "package.json")).data;
|
|
4703
5093
|
const kit = depRange(data, "@sveltejs/kit") ?? "^3.0.0";
|
|
4704
5094
|
const overrides = data.overrides ?? {};
|
|
4705
5095
|
const overridden = (name) => {
|
|
@@ -4733,7 +5123,7 @@ async function peersFixup(root, lookup) {
|
|
|
4733
5123
|
...Object.keys(data.dependencies ?? {}),
|
|
4734
5124
|
...Object.keys(data.devDependencies ?? {})
|
|
4735
5125
|
].filter((name, i, all) => all.indexOf(name) === i);
|
|
4736
|
-
const after = readJson(
|
|
5126
|
+
const after = readJson(path25.join(root, "package.json")).data.overrides ?? {};
|
|
4737
5127
|
for (const name of names) {
|
|
4738
5128
|
const entry = after[name];
|
|
4739
5129
|
if (bumpedHere(name) || typeof entry !== "object" || entry === null) continue;
|
|
@@ -4755,10 +5145,10 @@ function depRange(data, name) {
|
|
|
4755
5145
|
var STALE_LOCK_ENTRY = /(^|\/)node_modules\/(@sveltejs\/[^/]+|sveltekit-superforms|sveltekit-flash-message|formsnap|@velastack\/[^/]+|sveltekit-negotiate)$/;
|
|
4756
5146
|
function lockfileFixup(root) {
|
|
4757
5147
|
const f = fixup("package-lock.json");
|
|
4758
|
-
const lockPath =
|
|
4759
|
-
if (!
|
|
5148
|
+
const lockPath = path25.join(root, "package-lock.json");
|
|
5149
|
+
if (!fs27.existsSync(lockPath)) {
|
|
4760
5150
|
for (const other of ["pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"]) {
|
|
4761
|
-
if (
|
|
5151
|
+
if (fs27.existsSync(path25.join(root, other))) {
|
|
4762
5152
|
f.warnings.push(
|
|
4763
5153
|
`${other} still pins SvelteKit 2 packages; if the install fails, update @sveltejs/* with your package manager`
|
|
4764
5154
|
);
|
|
@@ -4768,7 +5158,7 @@ function lockfileFixup(root) {
|
|
|
4768
5158
|
}
|
|
4769
5159
|
const { data, indent } = readJson(lockPath);
|
|
4770
5160
|
const packages = data.packages;
|
|
4771
|
-
const project = readJson(
|
|
5161
|
+
const project = readJson(path25.join(root, "package.json")).data;
|
|
4772
5162
|
const lockedKit = packages?.["node_modules/@sveltejs/kit"]?.version;
|
|
4773
5163
|
const kit2Lock = lockedKit !== void 0 && (minVersion(lockedKit)?.major ?? 0) < 3;
|
|
4774
5164
|
const removed = [];
|
|
@@ -4800,19 +5190,19 @@ function belowFloor(project, key, entry) {
|
|
|
4800
5190
|
return Boolean(floor && locked && compareVersions(locked, floor) < 0);
|
|
4801
5191
|
}
|
|
4802
5192
|
function readJson(file) {
|
|
4803
|
-
const text19 =
|
|
5193
|
+
const text19 = fs27.readFileSync(file, "utf8");
|
|
4804
5194
|
return {
|
|
4805
5195
|
data: JSON.parse(text19),
|
|
4806
5196
|
indent: text19.match(/^[{[]\s*\n([\t ]+)/)?.[1] ?? " "
|
|
4807
5197
|
};
|
|
4808
5198
|
}
|
|
4809
5199
|
function writeJson(file, data, indent) {
|
|
4810
|
-
|
|
5200
|
+
fs27.writeFileSync(file, `${JSON.stringify(data, null, indent)}
|
|
4811
5201
|
`);
|
|
4812
5202
|
}
|
|
4813
5203
|
function collectFollowUps(root, sv) {
|
|
4814
5204
|
const items = [];
|
|
4815
|
-
const files = [...sourceFiles(
|
|
5205
|
+
const files = [...sourceFiles(path25.join(root, "src")), ...sourceFiles(path25.join(root, "test"))];
|
|
4816
5206
|
for (const spread of sv.dropped) {
|
|
4817
5207
|
items.push(
|
|
4818
5208
|
`${code(spread.file)}: sv dropped ${code(spread.text)} when it moved the config into \`sveltekit({...})\` (it skips spread properties). Add it back there if it is still needed.`
|
|
@@ -4830,8 +5220,8 @@ function collectFollowUps(root, sv) {
|
|
|
4830
5220
|
}
|
|
4831
5221
|
}
|
|
4832
5222
|
for (const file of files) {
|
|
4833
|
-
const source =
|
|
4834
|
-
const rel =
|
|
5223
|
+
const source = fs27.readFileSync(file, "utf8");
|
|
5224
|
+
const rel = path25.relative(root, file).split(path25.sep).join("/");
|
|
4835
5225
|
const lines = source.split("\n");
|
|
4836
5226
|
const locals = envImports(source).filter((i) => !i.local.includes(".")).map((i) => i.local);
|
|
4837
5227
|
if (locals.length > 0) {
|
|
@@ -4859,9 +5249,9 @@ function collectFollowUps(root, sv) {
|
|
|
4859
5249
|
}
|
|
4860
5250
|
});
|
|
4861
5251
|
}
|
|
4862
|
-
for (const file of textFiles(
|
|
4863
|
-
const rel =
|
|
4864
|
-
const source =
|
|
5252
|
+
for (const file of textFiles(path25.join(root, "src"))) {
|
|
5253
|
+
const rel = path25.relative(root, file).split(path25.sep).join("/");
|
|
5254
|
+
const source = fs27.readFileSync(file, "utf8");
|
|
4865
5255
|
if (!source.includes("svelte.config.js")) continue;
|
|
4866
5256
|
source.split("\n").forEach((line, i) => {
|
|
4867
5257
|
if (!line.includes("svelte.config.js")) return;
|
|
@@ -4874,7 +5264,7 @@ function collectFollowUps(root, sv) {
|
|
|
4874
5264
|
const vite = inspectViteSveltekit(root);
|
|
4875
5265
|
if (vite?.inlineArg) {
|
|
4876
5266
|
const config = vite.inlineArg.getText();
|
|
4877
|
-
const rel =
|
|
5267
|
+
const rel = path25.basename(vite.filePath);
|
|
4878
5268
|
if (/\borigin\s*:\s*['"`]/.test(config)) {
|
|
4879
5269
|
items.push(
|
|
4880
5270
|
`\`${rel}\`: \`paths.origin\` is a literal. It is baked into the build, so every host serving this app gets that origin; leave it unset for a multi-host deploy (vela sets it from VELA_ORIGIN on single-host deploys).`
|
|
@@ -4890,24 +5280,25 @@ function collectFollowUps(root, sv) {
|
|
|
4890
5280
|
}
|
|
4891
5281
|
var BINARY_EXTENSIONS = /\.(?:png|jpe?g|gif|webp|avif|ico|bmp|tiff?|woff2?|ttf|otf|eot|pdf|zip|gz|tgz|mp[34]|webm|mov|wav|ogg|wasm|db|sqlite3?)$/i;
|
|
4892
5282
|
function textFiles(dir) {
|
|
4893
|
-
if (!
|
|
4894
|
-
return
|
|
5283
|
+
if (!fs27.existsSync(dir)) return [];
|
|
5284
|
+
return fs27.globSync("**/*", {
|
|
4895
5285
|
cwd: dir,
|
|
4896
5286
|
exclude: (name) => name === "node_modules" || name === ".svelte-kit"
|
|
4897
|
-
}).filter((rel) => !BINARY_EXTENSIONS.test(rel)).map((rel) =>
|
|
4898
|
-
const stat =
|
|
5287
|
+
}).filter((rel) => !BINARY_EXTENSIONS.test(rel)).map((rel) => path25.join(dir, rel)).filter((file) => {
|
|
5288
|
+
const stat = fs27.statSync(file);
|
|
4899
5289
|
return stat.isFile() && stat.size < 2e6;
|
|
4900
5290
|
});
|
|
4901
5291
|
}
|
|
4902
5292
|
var SV_FAILURE_ITEM = /sv's `[^`]+` task (could not parse it|failed)|: sv dropped `/;
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
5293
|
+
var SSR_EXTERNAL_ITEM = /: moved .+ from devDependencies to dependencies because `ssr\.external` lists /;
|
|
5294
|
+
function previousFollowUps(root, pattern) {
|
|
5295
|
+
const file = path25.join(root, MIGRATION_TASKS_FILE);
|
|
5296
|
+
if (!fs27.existsSync(file)) return [];
|
|
5297
|
+
const content = fs27.readFileSync(file, "utf8");
|
|
4907
5298
|
const start = content.indexOf(FOLLOW_UPS_HEADING);
|
|
4908
5299
|
if (start === -1) return [];
|
|
4909
5300
|
const end = content.indexOf("\n## ", start + FOLLOW_UPS_HEADING.length);
|
|
4910
|
-
return content.slice(start, end === -1 ? void 0 : end).split("\n").filter((line) => line.startsWith("- [") &&
|
|
5301
|
+
return content.slice(start, end === -1 ? void 0 : end).split("\n").filter((line) => line.startsWith("- [") && pattern.test(line)).map((line) => line.replace(/^- \[[ x]\] /, ""));
|
|
4911
5302
|
}
|
|
4912
5303
|
function code(text19) {
|
|
4913
5304
|
const fence = text19.includes("`") ? "``" : "`";
|
|
@@ -4918,11 +5309,11 @@ function escape(text19) {
|
|
|
4918
5309
|
return text19.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4919
5310
|
}
|
|
4920
5311
|
function writeFollowUps(root, items, generic) {
|
|
4921
|
-
const file =
|
|
4922
|
-
const exists =
|
|
5312
|
+
const file = path25.join(root, MIGRATION_TASKS_FILE);
|
|
5313
|
+
const exists = fs27.existsSync(file);
|
|
4923
5314
|
const all = [...items, ...generic];
|
|
4924
5315
|
if (!exists && items.length === 0) return;
|
|
4925
|
-
const original = exists ?
|
|
5316
|
+
const original = exists ? fs27.readFileSync(file, "utf8") : "# SvelteKit 3 migration tasks\n";
|
|
4926
5317
|
let content = original;
|
|
4927
5318
|
const start = content.indexOf(FOLLOW_UPS_HEADING);
|
|
4928
5319
|
if (start !== -1) {
|
|
@@ -4944,17 +5335,17 @@ function writeFollowUps(root, items, generic) {
|
|
|
4944
5335
|
${body}` : `${content.slice(0, final)}${body}
|
|
4945
5336
|
${content.slice(final)}`;
|
|
4946
5337
|
}
|
|
4947
|
-
if (content !== original)
|
|
5338
|
+
if (content !== original) fs27.writeFileSync(file, content);
|
|
4948
5339
|
}
|
|
4949
5340
|
function summarizeMigrationTasks(root) {
|
|
4950
|
-
const file =
|
|
5341
|
+
const file = path25.join(root, MIGRATION_TASKS_FILE);
|
|
4951
5342
|
const markerComments = countMarkers(root);
|
|
4952
|
-
if (!
|
|
5343
|
+
if (!fs27.existsSync(file))
|
|
4953
5344
|
return markerComments > 0 ? { sections: [], filesToReview: 0, markerComments } : null;
|
|
4954
5345
|
const sections = [];
|
|
4955
5346
|
let current = null;
|
|
4956
5347
|
let inFiles = false;
|
|
4957
|
-
for (const line of
|
|
5348
|
+
for (const line of fs27.readFileSync(file, "utf8").split("\n")) {
|
|
4958
5349
|
if (line.startsWith("## ")) {
|
|
4959
5350
|
current = null;
|
|
4960
5351
|
inFiles = false;
|
|
@@ -4974,33 +5365,33 @@ function summarizeMigrationTasks(root) {
|
|
|
4974
5365
|
}
|
|
4975
5366
|
function countMarkers(root) {
|
|
4976
5367
|
let count = 0;
|
|
4977
|
-
const files = [...sourceFiles(
|
|
4978
|
-
for (const entry of
|
|
5368
|
+
const files = [...sourceFiles(path25.join(root, "src")), ...sourceFiles(path25.join(root, "test"))];
|
|
5369
|
+
for (const entry of fs27.readdirSync(root, { withFileTypes: true })) {
|
|
4979
5370
|
if (entry.isFile() && /\.(ts|js|mts|mjs)$/.test(entry.name))
|
|
4980
|
-
files.push(
|
|
5371
|
+
files.push(path25.join(root, entry.name));
|
|
4981
5372
|
}
|
|
4982
5373
|
for (const file of files) {
|
|
4983
|
-
count +=
|
|
5374
|
+
count += fs27.readFileSync(file, "utf8").split(MIGRATION_TASK_MARKER).length - 1;
|
|
4984
5375
|
}
|
|
4985
5376
|
return count;
|
|
4986
5377
|
}
|
|
4987
5378
|
async function install(root) {
|
|
4988
|
-
const agent = (await
|
|
5379
|
+
const agent = (await detect4({ cwd: root }))?.name ?? "npm";
|
|
4989
5380
|
return installDependencies(agent, root, { exitOnFailure: false });
|
|
4990
5381
|
}
|
|
4991
5382
|
async function formatProject(root) {
|
|
4992
|
-
const bin =
|
|
4993
|
-
if (!
|
|
5383
|
+
const bin = path25.join(root, "node_modules", ".bin", "prettier");
|
|
5384
|
+
if (!fs27.existsSync(bin)) return;
|
|
4994
5385
|
await x2(bin, ["--write", "--ignore-unknown", "."], {
|
|
4995
5386
|
nodeOptions: { cwd: root, stdio: "ignore" }
|
|
4996
5387
|
});
|
|
4997
5388
|
}
|
|
4998
5389
|
async function formatChanged(root, dirtyBefore) {
|
|
4999
|
-
const bin =
|
|
5390
|
+
const bin = path25.join(root, "node_modules", ".bin", "prettier");
|
|
5000
5391
|
const changed = gitDirty(root);
|
|
5001
|
-
if (!changed || !
|
|
5392
|
+
if (!changed || !fs27.existsSync(bin)) return [];
|
|
5002
5393
|
const files = changed.filter(
|
|
5003
|
-
(f) => !dirtyBefore.has(f) &&
|
|
5394
|
+
(f) => !dirtyBefore.has(f) && fs27.existsSync(path25.join(root, f)) && fs27.statSync(path25.join(root, f)).isFile()
|
|
5004
5395
|
);
|
|
5005
5396
|
if (files.length === 0) return [];
|
|
5006
5397
|
const result = await x2(bin, ["--write", "--ignore-unknown", ...files], {
|
|
@@ -5010,8 +5401,8 @@ async function formatChanged(root, dirtyBefore) {
|
|
|
5010
5401
|
}
|
|
5011
5402
|
|
|
5012
5403
|
// src/lib/kit3-template-support.ts
|
|
5013
|
-
import
|
|
5014
|
-
import
|
|
5404
|
+
import fs28 from "node:fs";
|
|
5405
|
+
import path26 from "node:path";
|
|
5015
5406
|
var CMS = "@velastack/cms";
|
|
5016
5407
|
var REPEATER_REMOVED_IN = { major: 0, minor: 5, patch: 0, prerelease: [] };
|
|
5017
5408
|
var SOURCE_FILE = /\.(svelte|svx|md|[cm]?[jt]s)$/;
|
|
@@ -5038,11 +5429,11 @@ Pick another template, or create the SvelteKit 2 version with
|
|
|
5038
5429
|
}
|
|
5039
5430
|
function cmsRange(dir) {
|
|
5040
5431
|
for (const file of ["package.template.json", "package.json"]) {
|
|
5041
|
-
const pkgPath =
|
|
5042
|
-
if (!
|
|
5432
|
+
const pkgPath = path26.join(dir, file);
|
|
5433
|
+
if (!fs28.existsSync(pkgPath)) continue;
|
|
5043
5434
|
let pkg;
|
|
5044
5435
|
try {
|
|
5045
|
-
pkg = JSON.parse(
|
|
5436
|
+
pkg = JSON.parse(fs28.readFileSync(pkgPath, "utf8"));
|
|
5046
5437
|
} catch {
|
|
5047
5438
|
return void 0;
|
|
5048
5439
|
}
|
|
@@ -5051,15 +5442,15 @@ function cmsRange(dir) {
|
|
|
5051
5442
|
return void 0;
|
|
5052
5443
|
}
|
|
5053
5444
|
function findRepeaterImport(dir) {
|
|
5054
|
-
const src =
|
|
5055
|
-
if (!
|
|
5056
|
-
const entries =
|
|
5445
|
+
const src = path26.join(dir, "src");
|
|
5446
|
+
if (!fs28.existsSync(src)) return void 0;
|
|
5447
|
+
const entries = fs28.readdirSync(src, { recursive: true, withFileTypes: true });
|
|
5057
5448
|
for (const entry of entries) {
|
|
5058
5449
|
if (!entry.isFile() || !SOURCE_FILE.test(entry.name)) continue;
|
|
5059
|
-
const file =
|
|
5060
|
-
const text19 =
|
|
5450
|
+
const file = path26.join(entry.parentPath, entry.name);
|
|
5451
|
+
const text19 = fs28.readFileSync(file, "utf8");
|
|
5061
5452
|
if (text19.includes("CmsRepeater") && REPEATER_IMPORT.test(text19)) {
|
|
5062
|
-
return
|
|
5453
|
+
return path26.relative(dir, file);
|
|
5063
5454
|
}
|
|
5064
5455
|
}
|
|
5065
5456
|
return void 0;
|
|
@@ -5119,8 +5510,8 @@ var create = new Command3("create").description("scaffold a new velastack projec
|
|
|
5119
5510
|
const listing = await listAllTemplates();
|
|
5120
5511
|
const options = parseOptions(optionsSchema2(listing), rawOpts);
|
|
5121
5512
|
const { directory, packageManager: packageManager2, installed: installed2, migrated, name, template, link: link2 } = await createProject2(projectPath, options, listing);
|
|
5122
|
-
const relative =
|
|
5123
|
-
const pm = packageManager2 ?? (await
|
|
5513
|
+
const relative = path27.relative(process13.cwd(), directory);
|
|
5514
|
+
const pm = packageManager2 ?? (await detect5({ cwd: directory }))?.name ?? getUserAgent() ?? "npm";
|
|
5124
5515
|
const nextSteps = [];
|
|
5125
5516
|
if (relative !== "") {
|
|
5126
5517
|
const hasSpaces = relative.includes(" ");
|
|
@@ -5181,7 +5572,7 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
5181
5572
|
resolved.cleanup();
|
|
5182
5573
|
}
|
|
5183
5574
|
const { directory: projectPath, name, credentials, link: link2 } = scaffolded;
|
|
5184
|
-
if (!
|
|
5575
|
+
if (!fs29.existsSync(path27.join(projectPath, "package.json"))) {
|
|
5185
5576
|
throw new Error(`Template ${template.name} is missing package.template.json`);
|
|
5186
5577
|
}
|
|
5187
5578
|
if (link2.linked) {
|
|
@@ -5240,7 +5631,7 @@ async function resolveCreatableTemplate(template) {
|
|
|
5240
5631
|
async function scaffoldProject(cwdArg, options, template, resolved, onCancel2) {
|
|
5241
5632
|
let directory;
|
|
5242
5633
|
if (cwdArg) {
|
|
5243
|
-
directory =
|
|
5634
|
+
directory = path27.resolve(cwdArg);
|
|
5244
5635
|
} else {
|
|
5245
5636
|
const answer = await p10.text({
|
|
5246
5637
|
message: "Where would you like your project to be created?",
|
|
@@ -5248,16 +5639,16 @@ async function scaffoldProject(cwdArg, options, template, resolved, onCancel2) {
|
|
|
5248
5639
|
defaultValue: "./"
|
|
5249
5640
|
});
|
|
5250
5641
|
if (p10.isCancel(answer)) onCancel2();
|
|
5251
|
-
directory =
|
|
5642
|
+
directory = path27.resolve(answer);
|
|
5252
5643
|
}
|
|
5253
|
-
if (
|
|
5644
|
+
if (fs29.existsSync(directory) && fs29.readdirSync(directory).filter((f) => !f.startsWith(".git")).length > 0) {
|
|
5254
5645
|
const force = await p10.confirm({
|
|
5255
5646
|
message: "Directory not empty. Continue?",
|
|
5256
5647
|
initialValue: false
|
|
5257
5648
|
});
|
|
5258
5649
|
if (p10.isCancel(force) || !force) onCancel2();
|
|
5259
5650
|
}
|
|
5260
|
-
const dirName =
|
|
5651
|
+
const dirName = path27.basename(directory);
|
|
5261
5652
|
const { name } = await p10.group(
|
|
5262
5653
|
{
|
|
5263
5654
|
name: () => {
|
|
@@ -5291,7 +5682,7 @@ async function migrateKit2Template(projectPath, templateName2) {
|
|
|
5291
5682
|
try {
|
|
5292
5683
|
result = await runKit3Migration(projectPath, { gitCheck: false, install: false, quiet: true });
|
|
5293
5684
|
} catch (e) {
|
|
5294
|
-
const relative =
|
|
5685
|
+
const relative = path27.relative(process13.cwd(), projectPath) || ".";
|
|
5295
5686
|
throw new Error(
|
|
5296
5687
|
`Could not migrate template ${templateName2} to SvelteKit 3: ${e.message}
|
|
5297
5688
|
|
|
@@ -5302,11 +5693,11 @@ The project is in ${projectPath}. Finish the migration by hand with
|
|
|
5302
5693
|
);
|
|
5303
5694
|
}
|
|
5304
5695
|
const tasks = result.tasks;
|
|
5305
|
-
const tasksFile =
|
|
5306
|
-
if (
|
|
5307
|
-
|
|
5696
|
+
const tasksFile = path27.join(projectPath, MIGRATION_TASKS_FILE);
|
|
5697
|
+
if (fs29.existsSync(tasksFile) && !tasks?.filesToReview && result.followUps.length === 0) {
|
|
5698
|
+
fs29.rmSync(tasksFile);
|
|
5308
5699
|
}
|
|
5309
|
-
const left =
|
|
5700
|
+
const left = fs29.existsSync(tasksFile);
|
|
5310
5701
|
p10.log.success(
|
|
5311
5702
|
`Migrated to SvelteKit 3${left ? `; ${MIGRATION_TASKS_FILE} lists what to check by hand` : ""}.`
|
|
5312
5703
|
);
|
|
@@ -5400,7 +5791,7 @@ ${FREE_CMS_HINT}.`, "CMS");
|
|
|
5400
5791
|
}
|
|
5401
5792
|
function hasScript(directory, name) {
|
|
5402
5793
|
try {
|
|
5403
|
-
const pkg = JSON.parse(
|
|
5794
|
+
const pkg = JSON.parse(fs29.readFileSync(path27.join(directory, "package.json"), "utf8"));
|
|
5404
5795
|
return typeof pkg.scripts?.[name] === "string";
|
|
5405
5796
|
} catch {
|
|
5406
5797
|
return false;
|
|
@@ -5415,7 +5806,7 @@ import { Command as Command4 } from "commander";
|
|
|
5415
5806
|
import * as p16 from "@clack/prompts";
|
|
5416
5807
|
|
|
5417
5808
|
// src/lib/pattern-runner.ts
|
|
5418
|
-
import
|
|
5809
|
+
import path28 from "node:path";
|
|
5419
5810
|
import * as p11 from "@clack/prompts";
|
|
5420
5811
|
import { bySlug as bySlug2 } from "@velastack/patterns";
|
|
5421
5812
|
|
|
@@ -5434,7 +5825,7 @@ Then run this again.`
|
|
|
5434
5825
|
|
|
5435
5826
|
// src/lib/pattern-runner.ts
|
|
5436
5827
|
function toRelative(root, filePath) {
|
|
5437
|
-
return
|
|
5828
|
+
return path28.isAbsolute(filePath) ? path28.relative(root, filePath) : filePath;
|
|
5438
5829
|
}
|
|
5439
5830
|
var isSuccess = (f) => (f.status ?? "success") === "success";
|
|
5440
5831
|
async function runPattern(slug2, argv, input, report4, after) {
|
|
@@ -5516,10 +5907,10 @@ async function runPattern(slug2, argv, input, report4, after) {
|
|
|
5516
5907
|
}
|
|
5517
5908
|
|
|
5518
5909
|
// src/lib/form-ui.ts
|
|
5519
|
-
import
|
|
5910
|
+
import path29 from "node:path";
|
|
5520
5911
|
var UIS = ["shadcn", "plain"];
|
|
5521
5912
|
function detectFormInput(root) {
|
|
5522
|
-
const pkg = readPackageJson(
|
|
5913
|
+
const pkg = readPackageJson(path29.join(root, "package.json"));
|
|
5523
5914
|
const hasDep = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
5524
5915
|
return {
|
|
5525
5916
|
flash: hasDep("sveltekit-flash-message"),
|
|
@@ -5541,8 +5932,8 @@ function resolveFormInput(root, detectedUi, requested) {
|
|
|
5541
5932
|
}
|
|
5542
5933
|
|
|
5543
5934
|
// src/lib/ai-flow.ts
|
|
5544
|
-
import
|
|
5545
|
-
import
|
|
5935
|
+
import fs30 from "node:fs";
|
|
5936
|
+
import path30 from "node:path";
|
|
5546
5937
|
import * as p15 from "@clack/prompts";
|
|
5547
5938
|
import pc4 from "picocolors";
|
|
5548
5939
|
|
|
@@ -5817,15 +6208,15 @@ function specToArgv(spec) {
|
|
|
5817
6208
|
return collectionSpecToArgv(spec);
|
|
5818
6209
|
}
|
|
5819
6210
|
function writeLayoutSidecar(workspaceRootDir, modelName, layout) {
|
|
5820
|
-
const dir =
|
|
6211
|
+
const dir = path30.join(
|
|
5821
6212
|
workspaceRootDir,
|
|
5822
6213
|
hasBackend(workspaceRootDir) ? DATA_DIR : ".vela",
|
|
5823
6214
|
"ai-form-layouts"
|
|
5824
6215
|
);
|
|
5825
|
-
|
|
5826
|
-
const file =
|
|
5827
|
-
|
|
5828
|
-
return
|
|
6216
|
+
fs30.mkdirSync(dir, { recursive: true });
|
|
6217
|
+
const file = path30.join(dir, `${modelName}.json`);
|
|
6218
|
+
fs30.writeFileSync(file, JSON.stringify(layout, null, 2) + "\n");
|
|
6219
|
+
return path30.relative(workspaceRootDir, file);
|
|
5829
6220
|
}
|
|
5830
6221
|
|
|
5831
6222
|
// src/commands/generate/form.ts
|
|
@@ -6547,8 +6938,8 @@ import * as p21 from "@clack/prompts";
|
|
|
6547
6938
|
import pc6 from "picocolors";
|
|
6548
6939
|
|
|
6549
6940
|
// src/lib/deploy-config.ts
|
|
6550
|
-
import
|
|
6551
|
-
import
|
|
6941
|
+
import fs31 from "node:fs";
|
|
6942
|
+
import path31 from "node:path";
|
|
6552
6943
|
import crypto from "node:crypto";
|
|
6553
6944
|
import { pathToFileURL } from "node:url";
|
|
6554
6945
|
var CONFIG_BASENAMES = [
|
|
@@ -6559,8 +6950,8 @@ var CONFIG_BASENAMES = [
|
|
|
6559
6950
|
];
|
|
6560
6951
|
function findConfigFile(workspaceRootDir) {
|
|
6561
6952
|
for (const name of CONFIG_BASENAMES) {
|
|
6562
|
-
const file =
|
|
6563
|
-
if (
|
|
6953
|
+
const file = path31.join(workspaceRootDir, name);
|
|
6954
|
+
if (fs31.existsSync(file)) return file;
|
|
6564
6955
|
}
|
|
6565
6956
|
return null;
|
|
6566
6957
|
}
|
|
@@ -6568,49 +6959,49 @@ async function loadDeployConfig(workspaceRootDir) {
|
|
|
6568
6959
|
const file = findConfigFile(workspaceRootDir);
|
|
6569
6960
|
if (!file) return {};
|
|
6570
6961
|
if (file.endsWith(".json")) {
|
|
6571
|
-
return JSON.parse(
|
|
6962
|
+
return JSON.parse(fs31.readFileSync(file, "utf8"));
|
|
6572
6963
|
}
|
|
6573
6964
|
const url = file.endsWith(".ts") ? await transpileToTemp(file) : pathToFileURL(file).href;
|
|
6574
6965
|
try {
|
|
6575
6966
|
const mod = await import(url);
|
|
6576
6967
|
const config = mod.default;
|
|
6577
6968
|
if (!config || typeof config !== "object") {
|
|
6578
|
-
throw new Error(`${
|
|
6969
|
+
throw new Error(`${path31.basename(file)} must export a config object as its default export.`);
|
|
6579
6970
|
}
|
|
6580
6971
|
return config;
|
|
6581
6972
|
} finally {
|
|
6582
|
-
if (url !== pathToFileURL(file).href)
|
|
6973
|
+
if (url !== pathToFileURL(file).href) fs31.rmSync(new URL(url), { force: true });
|
|
6583
6974
|
}
|
|
6584
6975
|
}
|
|
6585
6976
|
async function transpileToTemp(file) {
|
|
6586
6977
|
const { ts: ts2 } = await import("ts-morph");
|
|
6587
|
-
const source =
|
|
6978
|
+
const source = fs31.readFileSync(file, "utf8");
|
|
6588
6979
|
const { outputText } = ts2.transpileModule(source, {
|
|
6589
6980
|
compilerOptions: { module: ts2.ModuleKind.ESNext, target: ts2.ScriptTarget.ES2022 }
|
|
6590
6981
|
});
|
|
6591
|
-
const temp =
|
|
6592
|
-
|
|
6982
|
+
const temp = path31.join(
|
|
6983
|
+
path31.dirname(file),
|
|
6593
6984
|
`.velastack.config.${crypto.randomBytes(4).toString("hex")}.mjs`
|
|
6594
6985
|
);
|
|
6595
|
-
|
|
6986
|
+
fs31.writeFileSync(temp, outputText);
|
|
6596
6987
|
return pathToFileURL(temp).href;
|
|
6597
6988
|
}
|
|
6598
6989
|
function projectFilePath(workspaceRootDir) {
|
|
6599
|
-
return
|
|
6990
|
+
return path31.join(workspaceRootDir, ".vela", "project.json");
|
|
6600
6991
|
}
|
|
6601
6992
|
function readProjectFile(workspaceRootDir) {
|
|
6602
6993
|
const file = projectFilePath(workspaceRootDir);
|
|
6603
|
-
if (!
|
|
6994
|
+
if (!fs31.existsSync(file)) return {};
|
|
6604
6995
|
try {
|
|
6605
|
-
return JSON.parse(
|
|
6996
|
+
return JSON.parse(fs31.readFileSync(file, "utf8"));
|
|
6606
6997
|
} catch {
|
|
6607
6998
|
return {};
|
|
6608
6999
|
}
|
|
6609
7000
|
}
|
|
6610
7001
|
function writeProjectFile(workspaceRootDir, data) {
|
|
6611
7002
|
const file = projectFilePath(workspaceRootDir);
|
|
6612
|
-
|
|
6613
|
-
|
|
7003
|
+
fs31.mkdirSync(path31.dirname(file), { recursive: true });
|
|
7004
|
+
fs31.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
6614
7005
|
}
|
|
6615
7006
|
function resolveAppIdentity(workspaceRootDir, config = {}) {
|
|
6616
7007
|
const project = readProjectFile(workspaceRootDir);
|
|
@@ -6635,11 +7026,11 @@ function readAppIdentity(workspaceRootDir, config = {}) {
|
|
|
6635
7026
|
}
|
|
6636
7027
|
function defaultProjectName(workspaceRootDir) {
|
|
6637
7028
|
try {
|
|
6638
|
-
const pkg = readPackageJson(
|
|
7029
|
+
const pkg = readPackageJson(path31.join(workspaceRootDir, "package.json"));
|
|
6639
7030
|
if (typeof pkg.name === "string" && pkg.name.trim()) return pkg.name.trim();
|
|
6640
7031
|
} catch {
|
|
6641
7032
|
}
|
|
6642
|
-
return
|
|
7033
|
+
return path31.basename(workspaceRootDir);
|
|
6643
7034
|
}
|
|
6644
7035
|
function slug(value) {
|
|
6645
7036
|
return value.toLowerCase().replace(/^@/, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "app";
|
|
@@ -6710,15 +7101,15 @@ function randomSuffix() {
|
|
|
6710
7101
|
}
|
|
6711
7102
|
|
|
6712
7103
|
// src/lib/artifact.ts
|
|
6713
|
-
import
|
|
6714
|
-
import
|
|
6715
|
-
import { detect as
|
|
7104
|
+
import fs33 from "node:fs";
|
|
7105
|
+
import path33 from "node:path";
|
|
7106
|
+
import { detect as detect6 } from "package-manager-detector";
|
|
6716
7107
|
import { resolveCommand as resolveCommand4 } from "package-manager-detector/commands";
|
|
6717
7108
|
|
|
6718
7109
|
// src/lib/ssh.ts
|
|
6719
|
-
import
|
|
7110
|
+
import fs32 from "node:fs";
|
|
6720
7111
|
import os4 from "node:os";
|
|
6721
|
-
import
|
|
7112
|
+
import path32 from "node:path";
|
|
6722
7113
|
import crypto3 from "node:crypto";
|
|
6723
7114
|
import process16 from "node:process";
|
|
6724
7115
|
import { spawn as spawn3 } from "node:child_process";
|
|
@@ -6761,9 +7152,9 @@ var SshSession = class {
|
|
|
6761
7152
|
}
|
|
6762
7153
|
async open() {
|
|
6763
7154
|
if (this.controlPath) return;
|
|
6764
|
-
const dir =
|
|
6765
|
-
|
|
6766
|
-
const socket =
|
|
7155
|
+
const dir = path32.join(os4.tmpdir(), "vela-ssh");
|
|
7156
|
+
fs32.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
7157
|
+
const socket = path32.join(dir, `${crypto3.randomBytes(6).toString("hex")}.sock`);
|
|
6767
7158
|
this.controlPath = socket;
|
|
6768
7159
|
const args = [
|
|
6769
7160
|
...this.sshArgs(),
|
|
@@ -7034,7 +7425,7 @@ async function runBuild(cwd, buildCommand, env2) {
|
|
|
7034
7425
|
throw new BuildError(`\`${buildCommand}\` exited ${result2.exitCode}.`);
|
|
7035
7426
|
return;
|
|
7036
7427
|
}
|
|
7037
|
-
const pm = (await
|
|
7428
|
+
const pm = (await detect6({ cwd }))?.name ?? "npm";
|
|
7038
7429
|
const resolved = resolveCommand4(pm, "run", ["build"]);
|
|
7039
7430
|
if (!resolved) throw new BuildError(`Could not work out how to run a build with ${pm}.`);
|
|
7040
7431
|
const result = await spawnCapture(resolved.command, resolved.args, {
|
|
@@ -7053,11 +7444,11 @@ function collectArtifact(cwd, config = {}) {
|
|
|
7053
7444
|
const outputDir = config.outputDir ?? DEFAULT_OUTPUT_DIR;
|
|
7054
7445
|
const entries = [];
|
|
7055
7446
|
const add2 = (rel, remoteDir = "") => {
|
|
7056
|
-
const localPath =
|
|
7057
|
-
if (
|
|
7447
|
+
const localPath = path33.join(cwd, rel);
|
|
7448
|
+
if (fs33.existsSync(localPath)) entries.push({ localPath, remoteDir });
|
|
7058
7449
|
};
|
|
7059
|
-
const buildPath =
|
|
7060
|
-
if (!
|
|
7450
|
+
const buildPath = path33.join(cwd, outputDir);
|
|
7451
|
+
if (!fs33.existsSync(path33.join(buildPath, "index.js"))) {
|
|
7061
7452
|
throw new BuildError(
|
|
7062
7453
|
`No ${outputDir}/index.js to deploy.
|
|
7063
7454
|
|
|
@@ -7071,19 +7462,19 @@ matches where it writes), then deploy again.`
|
|
|
7071
7462
|
for (const lockfile of [NPM_LOCKFILE, ...FOREIGN_LOCKFILES]) add2(lockfile);
|
|
7072
7463
|
add2(".npmrc");
|
|
7073
7464
|
add2(MIGRATIONS_DIR);
|
|
7074
|
-
const hooks =
|
|
7075
|
-
if (
|
|
7465
|
+
const hooks = path33.join(cwd, DATA_DIR, "hooks");
|
|
7466
|
+
if (fs33.existsSync(hooks)) entries.push({ localPath: hooks, remoteDir: "hooks" });
|
|
7076
7467
|
for (const extra of config.include ?? []) add2(extra);
|
|
7077
7468
|
return entries;
|
|
7078
7469
|
}
|
|
7079
7470
|
var NPM_LOCKFILE = "package-lock.json";
|
|
7080
7471
|
var FOREIGN_LOCKFILES = ["pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"];
|
|
7081
7472
|
function hasLockfile(cwd) {
|
|
7082
|
-
return
|
|
7473
|
+
return fs33.existsSync(path33.join(cwd, NPM_LOCKFILE));
|
|
7083
7474
|
}
|
|
7084
7475
|
function foreignLockfile(cwd) {
|
|
7085
7476
|
if (hasLockfile(cwd)) return void 0;
|
|
7086
|
-
return FOREIGN_LOCKFILES.find((name) =>
|
|
7477
|
+
return FOREIGN_LOCKFILES.find((name) => fs33.existsSync(path33.join(cwd, name)));
|
|
7087
7478
|
}
|
|
7088
7479
|
async function gitSha(cwd) {
|
|
7089
7480
|
const result = await spawnCapture("git", ["rev-parse", "HEAD"], { cwd });
|
|
@@ -7122,8 +7513,8 @@ function sshOptionsFrom(options) {
|
|
|
7122
7513
|
|
|
7123
7514
|
// src/lib/remote.ts
|
|
7124
7515
|
import crypto4 from "node:crypto";
|
|
7125
|
-
import
|
|
7126
|
-
import
|
|
7516
|
+
import fs34 from "node:fs";
|
|
7517
|
+
import path34 from "node:path";
|
|
7127
7518
|
import process17 from "node:process";
|
|
7128
7519
|
var VELA_ROOT = "/var/lib/vela";
|
|
7129
7520
|
var VELA_ETC = "/etc/vela";
|
|
@@ -7136,19 +7527,19 @@ function instanceHasBackend(state) {
|
|
|
7136
7527
|
return state.backend ?? Boolean(state.pbPort);
|
|
7137
7528
|
}
|
|
7138
7529
|
function serverTemplatesDir() {
|
|
7139
|
-
return
|
|
7530
|
+
return path34.join(templatesDir(), "server");
|
|
7140
7531
|
}
|
|
7141
7532
|
var DIGEST_LENGTH = 12;
|
|
7142
7533
|
function serverScriptsDigest(dir = serverTemplatesDir()) {
|
|
7143
7534
|
const hash = crypto4.createHash("sha256");
|
|
7144
7535
|
for (const file of listFiles(dir).sort()) {
|
|
7145
|
-
hash.update(file).update("\0").update(
|
|
7536
|
+
hash.update(file).update("\0").update(fs34.readFileSync(path34.join(dir, file))).update("\0");
|
|
7146
7537
|
}
|
|
7147
7538
|
return hash.digest("hex").slice(0, DIGEST_LENGTH);
|
|
7148
7539
|
}
|
|
7149
7540
|
function listFiles(root, prefix = "") {
|
|
7150
7541
|
const files = [];
|
|
7151
|
-
for (const entry of
|
|
7542
|
+
for (const entry of fs34.readdirSync(path34.join(root, prefix), { withFileTypes: true })) {
|
|
7152
7543
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
7153
7544
|
if (entry.isDirectory()) files.push(...listFiles(root, rel));
|
|
7154
7545
|
else if (entry.isFile()) files.push(rel);
|
|
@@ -7267,7 +7658,7 @@ var remotePaths = {
|
|
|
7267
7658
|
};
|
|
7268
7659
|
|
|
7269
7660
|
// src/lib/remote-env.ts
|
|
7270
|
-
import
|
|
7661
|
+
import fs35 from "node:fs";
|
|
7271
7662
|
import dotenv from "dotenv";
|
|
7272
7663
|
var KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
7273
7664
|
function isValidKey(key) {
|
|
@@ -7315,7 +7706,7 @@ function quote(value) {
|
|
|
7315
7706
|
return `"${escaped}"`;
|
|
7316
7707
|
}
|
|
7317
7708
|
function readLocalEnvFile(file) {
|
|
7318
|
-
const parsed = dotenv.parse(
|
|
7709
|
+
const parsed = dotenv.parse(fs35.readFileSync(file));
|
|
7319
7710
|
const result = {};
|
|
7320
7711
|
for (const [key, value] of Object.entries(parsed)) {
|
|
7321
7712
|
if (isValidKey(key)) result[key] = value;
|
|
@@ -7641,17 +8032,17 @@ function envFilePath(workspaceRootDir) {
|
|
|
7641
8032
|
import pc8 from "picocolors";
|
|
7642
8033
|
|
|
7643
8034
|
// src/lib/local-env.ts
|
|
7644
|
-
import
|
|
8035
|
+
import fs36 from "node:fs";
|
|
7645
8036
|
import * as p22 from "@clack/prompts";
|
|
7646
8037
|
import pc7 from "picocolors";
|
|
7647
8038
|
function readLocalEnv(envFile) {
|
|
7648
|
-
if (!
|
|
8039
|
+
if (!fs36.existsSync(envFile)) return {};
|
|
7649
8040
|
return readLocalEnvFile(envFile);
|
|
7650
8041
|
}
|
|
7651
8042
|
function editLocalEnv(envFile, edit) {
|
|
7652
|
-
const before =
|
|
8043
|
+
const before = fs36.existsSync(envFile) ? fs36.readFileSync(envFile, "utf8") : "";
|
|
7653
8044
|
const after = edit(before);
|
|
7654
|
-
if (after !== before)
|
|
8045
|
+
if (after !== before) fs36.writeFileSync(envFile, after);
|
|
7655
8046
|
}
|
|
7656
8047
|
function setLocalEnv(envFile, key, value) {
|
|
7657
8048
|
editLocalEnv(envFile, (content) => upsertEnvVar(content, key, value));
|
|
@@ -7788,8 +8179,8 @@ Set ${pc8.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc8.cyan("POCKETBASE_SUPERUS
|
|
|
7788
8179
|
}
|
|
7789
8180
|
|
|
7790
8181
|
// src/lib/s3-settings.ts
|
|
7791
|
-
import
|
|
7792
|
-
import
|
|
8182
|
+
import fs37 from "node:fs";
|
|
8183
|
+
import path35 from "node:path";
|
|
7793
8184
|
var VIRTUAL_HOSTED = [/\.amazonaws\.com$/i, /\.r2\.cloudflarestorage\.com$/i];
|
|
7794
8185
|
function defaultForcePathStyle(endpoint) {
|
|
7795
8186
|
let host;
|
|
@@ -7827,18 +8218,18 @@ async function hasLocalUploads(session, instance, workspaceRootDir) {
|
|
|
7827
8218
|
});
|
|
7828
8219
|
return result.stdout.trim().length > 0;
|
|
7829
8220
|
}
|
|
7830
|
-
return hasFile(
|
|
8221
|
+
return hasFile(path35.join(workspaceRootDir, DATA_DIR, "storage"));
|
|
7831
8222
|
}
|
|
7832
8223
|
function hasFile(dir) {
|
|
7833
8224
|
let entries;
|
|
7834
8225
|
try {
|
|
7835
|
-
entries =
|
|
8226
|
+
entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
7836
8227
|
} catch {
|
|
7837
8228
|
return false;
|
|
7838
8229
|
}
|
|
7839
8230
|
for (const entry of entries) {
|
|
7840
8231
|
if (entry.isFile()) return true;
|
|
7841
|
-
if (entry.isDirectory() && hasFile(
|
|
8232
|
+
if (entry.isDirectory() && hasFile(path35.join(dir, entry.name))) return true;
|
|
7842
8233
|
}
|
|
7843
8234
|
return false;
|
|
7844
8235
|
}
|
|
@@ -7893,367 +8284,124 @@ async function guardExistingUploads(ctx, options) {
|
|
|
7893
8284
|
if (options.force) return;
|
|
7894
8285
|
if (!await hasLocalUploads(ctx.session, ctx.instance, ctx.workspaceRootDir)) return;
|
|
7895
8286
|
const from = ctx.session ? `${remotePaths.storage(ctx.instance)}/` : "data/storage/";
|
|
7896
|
-
throw new Error(
|
|
7897
|
-
`${ctx.targetName} already has uploaded files on disk.
|
|
7898
|
-
|
|
7899
|
-
Turning on S3 changes where PocketBase reads from; it does not move anything,
|
|
7900
|
-
so every one of those files would stop resolving.
|
|
7901
|
-
|
|
7902
|
-
The layout is the same on both sides, so copying them across is a plain sync:
|
|
7903
|
-
|
|
7904
|
-
${pc9.cyan(`rclone copy ${from} <remote>:<bucket>/`)}
|
|
7905
|
-
|
|
7906
|
-
Do that first, then re-run with ${pc9.cyan("--force")}.`
|
|
7907
|
-
);
|
|
7908
|
-
}
|
|
7909
|
-
async function promptConfig(options, existing) {
|
|
7910
|
-
const endpoint = options.endpoint ?? await text9("S3 endpoint URL", existing.endpoint || "https://s3.amazonaws.com");
|
|
7911
|
-
const bucket = options.bucket ?? await text9("S3 bucket name", existing.bucket);
|
|
7912
|
-
const region = options.region ?? await text9("S3 region", existing.region || "us-east-1");
|
|
7913
|
-
const accessKey = options.accessKey ?? await text9("S3 access key", existing.accessKey);
|
|
7914
|
-
const secret = options.secret ?? process19.env.VELA_S3_SECRET ?? await password6("S3 secret key");
|
|
7915
|
-
const forcePathStyle = options.forcePathStyle ?? await confirm4(
|
|
7916
|
-
"Address the bucket in the path? (MinIO, Ceph and most self-hosted gateways need this)",
|
|
7917
|
-
defaultForcePathStyle(endpoint)
|
|
7918
|
-
);
|
|
7919
|
-
return { endpoint, bucket, region, accessKey, secret, forcePathStyle };
|
|
7920
|
-
}
|
|
7921
|
-
async function text9(message, initialValue = "") {
|
|
7922
|
-
const value = await p23.text({
|
|
7923
|
-
message,
|
|
7924
|
-
initialValue,
|
|
7925
|
-
validate: (input) => input?.trim() ? void 0 : `${message} is required`
|
|
7926
|
-
});
|
|
7927
|
-
if (p23.isCancel(value)) {
|
|
7928
|
-
p23.cancel("Operation cancelled.");
|
|
7929
|
-
process19.exit(0);
|
|
7930
|
-
}
|
|
7931
|
-
return value.trim();
|
|
7932
|
-
}
|
|
7933
|
-
async function password6(message) {
|
|
7934
|
-
const value = await p23.password({
|
|
7935
|
-
message,
|
|
7936
|
-
validate: (input) => input ? void 0 : `${message} is required`
|
|
7937
|
-
});
|
|
7938
|
-
if (p23.isCancel(value)) {
|
|
7939
|
-
p23.cancel("Operation cancelled.");
|
|
7940
|
-
process19.exit(0);
|
|
7941
|
-
}
|
|
7942
|
-
return value;
|
|
7943
|
-
}
|
|
7944
|
-
async function confirm4(message, initialValue) {
|
|
7945
|
-
const value = await p23.confirm({ message, initialValue });
|
|
7946
|
-
if (p23.isCancel(value)) {
|
|
7947
|
-
p23.cancel("Operation cancelled.");
|
|
7948
|
-
process19.exit(0);
|
|
7949
|
-
}
|
|
7950
|
-
return value;
|
|
7951
|
-
}
|
|
7952
|
-
|
|
7953
|
-
// src/commands/enable/smtp.ts
|
|
7954
|
-
import process20 from "node:process";
|
|
7955
|
-
import { Command as Command23 } from "commander";
|
|
7956
|
-
import * as p24 from "@clack/prompts";
|
|
7957
|
-
var smtp = new Command23("smtp").description("configure SMTP for transactional email").configureHelp(helpConfig).action(
|
|
7958
|
-
() => runCommand(async () => {
|
|
7959
|
-
const { workspaceRootDir } = await getWorkspace();
|
|
7960
|
-
const config = await p24.group(
|
|
7961
|
-
{
|
|
7962
|
-
host: () => p24.text({
|
|
7963
|
-
message: "SMTP host",
|
|
7964
|
-
placeholder: "smtp.example.com",
|
|
7965
|
-
validate: (v12) => v12 ? void 0 : "Host is required"
|
|
7966
|
-
}),
|
|
7967
|
-
port: () => p24.text({
|
|
7968
|
-
message: "SMTP port",
|
|
7969
|
-
initialValue: "587",
|
|
7970
|
-
validate: (v12) => {
|
|
7971
|
-
if (!v12) return "Port is required";
|
|
7972
|
-
const n = Number(v12);
|
|
7973
|
-
if (!Number.isInteger(n) || n <= 0 || n > 65535) return "Invalid port";
|
|
7974
|
-
return void 0;
|
|
7975
|
-
}
|
|
7976
|
-
}),
|
|
7977
|
-
username: () => p24.text({ message: "SMTP username" }),
|
|
7978
|
-
password: () => p24.password({ message: "SMTP password" })
|
|
7979
|
-
},
|
|
7980
|
-
{
|
|
7981
|
-
onCancel: () => {
|
|
7982
|
-
p24.cancel("Operation cancelled.");
|
|
7983
|
-
process20.exit(0);
|
|
7984
|
-
}
|
|
7985
|
-
}
|
|
7986
|
-
);
|
|
7987
|
-
await withPocketbase(workspaceRootDir, async (pb) => {
|
|
7988
|
-
await pb.settings.update({
|
|
7989
|
-
smtp: {
|
|
7990
|
-
enabled: true,
|
|
7991
|
-
host: config.host,
|
|
7992
|
-
port: parseInt(config.port, 10),
|
|
7993
|
-
username: config.username ?? "",
|
|
7994
|
-
password: config.password ?? ""
|
|
7995
|
-
}
|
|
7996
|
-
});
|
|
7997
|
-
});
|
|
7998
|
-
reportResult({
|
|
7999
|
-
summary: "Enabled SMTP for transactional email.",
|
|
8000
|
-
nextSteps: [
|
|
8001
|
-
"PocketBase will now send auth/verification email via your SMTP server.",
|
|
8002
|
-
"Send a test email from the PocketBase admin UI (Settings \u2192 Mail settings).",
|
|
8003
|
-
"Run `vela disable smtp` to revert to the built-in fallback sender."
|
|
8004
|
-
]
|
|
8005
|
-
});
|
|
8006
|
-
}, "Failed to enable SMTP.")
|
|
8007
|
-
);
|
|
8008
|
-
|
|
8009
|
-
// src/commands/enable/cms.ts
|
|
8010
|
-
import process21 from "node:process";
|
|
8011
|
-
import { Command as Command24 } from "commander";
|
|
8012
|
-
import * as p25 from "@clack/prompts";
|
|
8013
|
-
import pc10 from "picocolors";
|
|
8014
|
-
|
|
8015
|
-
// src/lib/adapter.ts
|
|
8016
|
-
import fs36 from "node:fs";
|
|
8017
|
-
import path34 from "node:path";
|
|
8018
|
-
import {
|
|
8019
|
-
SyntaxKind as SyntaxKind4
|
|
8020
|
-
} from "ts-morph";
|
|
8021
|
-
import { detect as detect6 } from "package-manager-detector";
|
|
8022
|
-
var ADAPTER_NODE2 = "@sveltejs/adapter-node";
|
|
8023
|
-
var ADAPTER_AUTO = "@sveltejs/adapter-auto";
|
|
8024
|
-
var ADAPTER_STATIC2 = "@sveltejs/adapter-static";
|
|
8025
|
-
var ADAPTER_NODE_RANGE = "^6.0.0";
|
|
8026
|
-
var ADAPTER_SNIPPET = `import adapter from '${ADAPTER_NODE2}';
|
|
8027
|
-
|
|
8028
|
-
// ...
|
|
8029
|
-
adapter: adapter()`;
|
|
8030
|
-
var AdapterError = class extends Error {
|
|
8031
|
-
constructor(message, snippet = ADAPTER_SNIPPET) {
|
|
8032
|
-
super(message);
|
|
8033
|
-
this.snippet = snippet;
|
|
8034
|
-
this.name = "AdapterError";
|
|
8035
|
-
}
|
|
8036
|
-
snippet;
|
|
8037
|
-
};
|
|
8038
|
-
function resolveKitTarget(root) {
|
|
8039
|
-
const svelteConfig = findSvelteConfig(root);
|
|
8040
|
-
if (svelteConfig) {
|
|
8041
|
-
throw new AdapterError(
|
|
8042
|
-
`${path34.basename(svelteConfig)} found: this looks like a SvelteKit 2 project, and
|
|
8043
|
-
SvelteKit 3 reads its config only from sveltekit({...}) in vite.config.
|
|
8044
|
-
|
|
8045
|
-
Migrate it first:`,
|
|
8046
|
-
KIT3_MIGRATE_COMMAND
|
|
8047
|
-
);
|
|
8048
|
-
}
|
|
8049
|
-
const vite = inspectViteSveltekit(root);
|
|
8050
|
-
if (vite?.inlineArg) {
|
|
8051
|
-
return {
|
|
8052
|
-
sourceFile: vite.sourceFile,
|
|
8053
|
-
filePath: vite.filePath,
|
|
8054
|
-
kit: vite.inlineArg,
|
|
8055
|
-
created: false,
|
|
8056
|
-
originalText: vite.sourceFile.getFullText()
|
|
8057
|
-
};
|
|
8058
|
-
}
|
|
8059
|
-
if (vite?.sveltekitCall) {
|
|
8060
|
-
const name = path34.basename(vite.filePath);
|
|
8061
|
-
if (vite.nonObjectArg) {
|
|
8062
|
-
throw new AdapterError(`${name} passes sveltekit() something other than an object literal.`);
|
|
8063
|
-
}
|
|
8064
|
-
const originalText = vite.sourceFile.getFullText();
|
|
8065
|
-
const kit = createSveltekitArg(vite);
|
|
8066
|
-
if (!kit)
|
|
8067
|
-
throw new AdapterError(`${name} has a sveltekit() call vela cannot add an argument to.`);
|
|
8068
|
-
return {
|
|
8069
|
-
sourceFile: vite.sourceFile,
|
|
8070
|
-
filePath: vite.filePath,
|
|
8071
|
-
kit,
|
|
8072
|
-
created: true,
|
|
8073
|
-
originalText
|
|
8074
|
-
};
|
|
8075
|
-
}
|
|
8076
|
-
throw new AdapterError(`No vite.config with a sveltekit() plugin found in ${root}.`);
|
|
8077
|
-
}
|
|
8078
|
-
function classify(specifier) {
|
|
8079
|
-
if (specifier === ADAPTER_NODE2) return "node";
|
|
8080
|
-
if (specifier === ADAPTER_AUTO) return "auto";
|
|
8081
|
-
if (specifier === ADAPTER_STATIC2) return "static";
|
|
8082
|
-
return "other";
|
|
8083
|
-
}
|
|
8084
|
-
function importOf(sourceFile, identifier) {
|
|
8085
|
-
return sourceFile.getImportDeclarations().find((decl) => decl.getDefaultImport()?.getText() === identifier);
|
|
8086
|
-
}
|
|
8087
|
-
function inspectAdapter(target) {
|
|
8088
|
-
const base2 = { file: target.filePath };
|
|
8089
|
-
const prop = target.kit.getProperty("adapter");
|
|
8090
|
-
if (!prop) return { info: { ...base2, kind: "none" } };
|
|
8091
|
-
if (prop.getKind() !== SyntaxKind4.PropertyAssignment) {
|
|
8092
|
-
return { info: { ...base2, kind: "other" } };
|
|
8093
|
-
}
|
|
8094
|
-
const init = prop.asKindOrThrow(SyntaxKind4.PropertyAssignment).getInitializer();
|
|
8095
|
-
if (!init || init.getKind() !== SyntaxKind4.CallExpression) {
|
|
8096
|
-
return { info: { ...base2, kind: "other" } };
|
|
8097
|
-
}
|
|
8098
|
-
const callee = init.asKindOrThrow(SyntaxKind4.CallExpression).getExpression();
|
|
8099
|
-
if (callee.getKind() !== SyntaxKind4.Identifier) {
|
|
8100
|
-
return { info: { ...base2, kind: "other" } };
|
|
8101
|
-
}
|
|
8102
|
-
const importDecl = importOf(target.sourceFile, callee.getText());
|
|
8103
|
-
if (!importDecl) return { info: { ...base2, kind: "other" } };
|
|
8104
|
-
const specifier = importDecl.getModuleSpecifierValue();
|
|
8105
|
-
return { info: { ...base2, kind: classify(specifier), specifier }, importDecl };
|
|
8106
|
-
}
|
|
8107
|
-
function detectAdapter(root) {
|
|
8108
|
-
return inspectAdapter(resolveKitTarget(root)).info;
|
|
8109
|
-
}
|
|
8110
|
-
async function ensureNodeAdapter(root, { install: install2 = true } = {}) {
|
|
8111
|
-
const target = resolveKitTarget(root);
|
|
8112
|
-
const { info, importDecl } = inspectAdapter(target);
|
|
8113
|
-
const name = path34.basename(target.filePath);
|
|
8114
|
-
const outcome = {
|
|
8115
|
-
previous: info.kind,
|
|
8116
|
-
removedDeps: [],
|
|
8117
|
-
packageJsonChanged: false
|
|
8118
|
-
};
|
|
8119
|
-
switch (info.kind) {
|
|
8120
|
-
case "node":
|
|
8121
|
-
break;
|
|
8122
|
-
case "static":
|
|
8123
|
-
throw new AdapterError(
|
|
8124
|
-
`This project builds a static site with ${ADAPTER_STATIC2} (${name}).
|
|
8125
|
-
|
|
8126
|
-
vela deploy runs the app as a Node server, which needs ${ADAPTER_NODE2}. Switch
|
|
8127
|
-
the adapter to deploy it here, or host the static output elsewhere.`
|
|
8128
|
-
);
|
|
8129
|
-
case "other":
|
|
8130
|
-
throw new AdapterError(
|
|
8131
|
-
`This project's adapter${info.specifier ? ` (${info.specifier})` : ""} in ${name} is not one
|
|
8132
|
-
vela will change for you.
|
|
8133
|
-
|
|
8134
|
-
vela deploy runs the app as a Node server, which needs ${ADAPTER_NODE2}:`
|
|
8135
|
-
);
|
|
8136
|
-
case "auto":
|
|
8137
|
-
switchImport(target, importDecl);
|
|
8138
|
-
outcome.configFile = name;
|
|
8139
|
-
break;
|
|
8140
|
-
case "none":
|
|
8141
|
-
addAdapter(target);
|
|
8142
|
-
outcome.configFile = name;
|
|
8143
|
-
break;
|
|
8144
|
-
}
|
|
8145
|
-
if (outcome.configFile) saveTarget(target);
|
|
8146
|
-
const pkgPath = path34.join(root, "package.json");
|
|
8147
|
-
if (fs36.existsSync(pkgPath)) {
|
|
8148
|
-
const pkg = readPackageJson(pkgPath);
|
|
8149
|
-
const { changed, removed } = adoptNodeAdapter(pkg);
|
|
8150
|
-
if (changed) {
|
|
8151
|
-
writePackageJson(pkgPath, pkg);
|
|
8152
|
-
outcome.packageJsonChanged = true;
|
|
8153
|
-
outcome.removedDeps = removed;
|
|
8154
|
-
}
|
|
8155
|
-
}
|
|
8156
|
-
if (outcome.packageJsonChanged && install2) {
|
|
8157
|
-
outcome.installedWith = await installAdapterDependencies(root);
|
|
8158
|
-
}
|
|
8159
|
-
return outcome;
|
|
8160
|
-
}
|
|
8161
|
-
async function installAdapterDependencies(root) {
|
|
8162
|
-
const agent = await packageManager(root);
|
|
8163
|
-
if (!isInstalled(agent)) {
|
|
8164
|
-
throw new AdapterError(
|
|
8165
|
-
`${agent} is not installed, so ${ADAPTER_NODE2} couldn't be installed.
|
|
8166
|
-
|
|
8167
|
-
The config and package.json are already updated: install ${agent}, run \`${agent} install\`, then deploy again.`,
|
|
8168
|
-
""
|
|
8169
|
-
);
|
|
8170
|
-
}
|
|
8171
|
-
const ok = await installDependencies(agent, root, { exitOnFailure: false });
|
|
8172
|
-
if (!ok) {
|
|
8173
|
-
throw new AdapterError(
|
|
8174
|
-
`Installing ${ADAPTER_NODE2} with ${agent} failed.
|
|
8175
|
-
|
|
8176
|
-
The config and package.json are already updated: run \`${agent} install\`, then deploy again.`,
|
|
8177
|
-
""
|
|
8178
|
-
);
|
|
8179
|
-
}
|
|
8180
|
-
return agent;
|
|
8181
|
-
}
|
|
8182
|
-
function switchImport(target, importDecl) {
|
|
8183
|
-
importDecl.setModuleSpecifier(ADAPTER_NODE2);
|
|
8184
|
-
const prop = target.kit.getPropertyOrThrow("adapter").asKindOrThrow(SyntaxKind4.PropertyAssignment);
|
|
8185
|
-
const call = prop.getInitializerIfKindOrThrow(SyntaxKind4.CallExpression);
|
|
8186
|
-
for (let i = call.getArguments().length - 1; i >= 0; i--) call.removeArgument(i);
|
|
8187
|
-
dropAdapterAutoComments(target);
|
|
8188
|
-
}
|
|
8189
|
-
var ADAPTER_AUTO_COMMENT = /adapter-auto|svelte\.dev\/docs\/kit\/adapters|switch out the adapter/;
|
|
8190
|
-
function dropAdapterAutoComments(target) {
|
|
8191
|
-
const prop = target.kit.getPropertyOrThrow("adapter");
|
|
8192
|
-
const ranges = prop.getLeadingCommentRanges();
|
|
8193
|
-
if (ranges.length === 0 || !ranges.every((r) => ADAPTER_AUTO_COMMENT.test(r.getText()))) return;
|
|
8194
|
-
const fullStart = prop.getFullStart();
|
|
8195
|
-
const start = prop.getStart();
|
|
8196
|
-
const trivia = target.sourceFile.getFullText().slice(fullStart, start);
|
|
8197
|
-
const lastNewline = trivia.lastIndexOf("\n");
|
|
8198
|
-
if (lastNewline === -1) return;
|
|
8199
|
-
const indent = trivia.slice(lastNewline + 1);
|
|
8200
|
-
target.sourceFile.replaceText([fullStart, start], `
|
|
8201
|
-
${indent}`);
|
|
8202
|
-
}
|
|
8203
|
-
function addAdapter(target) {
|
|
8204
|
-
const taken = importOf(target.sourceFile, "adapter") ?? target.sourceFile.getVariableDeclaration("adapter");
|
|
8205
|
-
if (taken) {
|
|
8206
|
-
throw new AdapterError(
|
|
8207
|
-
`${path34.basename(target.filePath)} already binds the name \`adapter\` to something that is not the SvelteKit adapter.`
|
|
8208
|
-
);
|
|
8209
|
-
}
|
|
8210
|
-
target.sourceFile.addImportDeclaration({
|
|
8211
|
-
defaultImport: "adapter",
|
|
8212
|
-
moduleSpecifier: ADAPTER_NODE2
|
|
8213
|
-
});
|
|
8214
|
-
target.kit.addPropertyAssignment({ name: "adapter", initializer: "adapter()" });
|
|
8287
|
+
throw new Error(
|
|
8288
|
+
`${ctx.targetName} already has uploaded files on disk.
|
|
8289
|
+
|
|
8290
|
+
Turning on S3 changes where PocketBase reads from; it does not move anything,
|
|
8291
|
+
so every one of those files would stop resolving.
|
|
8292
|
+
|
|
8293
|
+
The layout is the same on both sides, so copying them across is a plain sync:
|
|
8294
|
+
|
|
8295
|
+
${pc9.cyan(`rclone copy ${from} <remote>:<bucket>/`)}
|
|
8296
|
+
|
|
8297
|
+
Do that first, then re-run with ${pc9.cyan("--force")}.`
|
|
8298
|
+
);
|
|
8215
8299
|
}
|
|
8216
|
-
function
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8300
|
+
async function promptConfig(options, existing) {
|
|
8301
|
+
const endpoint = options.endpoint ?? await text9("S3 endpoint URL", existing.endpoint || "https://s3.amazonaws.com");
|
|
8302
|
+
const bucket = options.bucket ?? await text9("S3 bucket name", existing.bucket);
|
|
8303
|
+
const region = options.region ?? await text9("S3 region", existing.region || "us-east-1");
|
|
8304
|
+
const accessKey = options.accessKey ?? await text9("S3 access key", existing.accessKey);
|
|
8305
|
+
const secret = options.secret ?? process19.env.VELA_S3_SECRET ?? await password6("S3 secret key");
|
|
8306
|
+
const forcePathStyle = options.forcePathStyle ?? await confirm4(
|
|
8307
|
+
"Address the bucket in the path? (MinIO, Ceph and most self-hosted gateways need this)",
|
|
8308
|
+
defaultForcePathStyle(endpoint)
|
|
8309
|
+
);
|
|
8310
|
+
return { endpoint, bucket, region, accessKey, secret, forcePathStyle };
|
|
8220
8311
|
}
|
|
8221
|
-
function
|
|
8222
|
-
const
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
}
|
|
8231
|
-
}
|
|
8232
|
-
if (!pkg.dependencies?.[ADAPTER_NODE2] && !pkg.devDependencies?.[ADAPTER_NODE2]) {
|
|
8233
|
-
pkg.devDependencies = sortKeys({ ...pkg.devDependencies, [ADAPTER_NODE2]: ADAPTER_NODE_RANGE });
|
|
8234
|
-
changed = true;
|
|
8312
|
+
async function text9(message, initialValue = "") {
|
|
8313
|
+
const value = await p23.text({
|
|
8314
|
+
message,
|
|
8315
|
+
initialValue,
|
|
8316
|
+
validate: (input) => input?.trim() ? void 0 : `${message} is required`
|
|
8317
|
+
});
|
|
8318
|
+
if (p23.isCancel(value)) {
|
|
8319
|
+
p23.cancel("Operation cancelled.");
|
|
8320
|
+
process19.exit(0);
|
|
8235
8321
|
}
|
|
8236
|
-
return
|
|
8322
|
+
return value.trim();
|
|
8237
8323
|
}
|
|
8238
|
-
function
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
case "deno":
|
|
8247
|
-
return "deno.lock";
|
|
8248
|
-
default:
|
|
8249
|
-
return "package-lock.json";
|
|
8324
|
+
async function password6(message) {
|
|
8325
|
+
const value = await p23.password({
|
|
8326
|
+
message,
|
|
8327
|
+
validate: (input) => input ? void 0 : `${message} is required`
|
|
8328
|
+
});
|
|
8329
|
+
if (p23.isCancel(value)) {
|
|
8330
|
+
p23.cancel("Operation cancelled.");
|
|
8331
|
+
process19.exit(0);
|
|
8250
8332
|
}
|
|
8333
|
+
return value;
|
|
8251
8334
|
}
|
|
8252
|
-
async function
|
|
8253
|
-
|
|
8335
|
+
async function confirm4(message, initialValue) {
|
|
8336
|
+
const value = await p23.confirm({ message, initialValue });
|
|
8337
|
+
if (p23.isCancel(value)) {
|
|
8338
|
+
p23.cancel("Operation cancelled.");
|
|
8339
|
+
process19.exit(0);
|
|
8340
|
+
}
|
|
8341
|
+
return value;
|
|
8254
8342
|
}
|
|
8255
8343
|
|
|
8344
|
+
// src/commands/enable/smtp.ts
|
|
8345
|
+
import process20 from "node:process";
|
|
8346
|
+
import { Command as Command23 } from "commander";
|
|
8347
|
+
import * as p24 from "@clack/prompts";
|
|
8348
|
+
var smtp = new Command23("smtp").description("configure SMTP for transactional email").configureHelp(helpConfig).action(
|
|
8349
|
+
() => runCommand(async () => {
|
|
8350
|
+
const { workspaceRootDir } = await getWorkspace();
|
|
8351
|
+
const config = await p24.group(
|
|
8352
|
+
{
|
|
8353
|
+
host: () => p24.text({
|
|
8354
|
+
message: "SMTP host",
|
|
8355
|
+
placeholder: "smtp.example.com",
|
|
8356
|
+
validate: (v12) => v12 ? void 0 : "Host is required"
|
|
8357
|
+
}),
|
|
8358
|
+
port: () => p24.text({
|
|
8359
|
+
message: "SMTP port",
|
|
8360
|
+
initialValue: "587",
|
|
8361
|
+
validate: (v12) => {
|
|
8362
|
+
if (!v12) return "Port is required";
|
|
8363
|
+
const n = Number(v12);
|
|
8364
|
+
if (!Number.isInteger(n) || n <= 0 || n > 65535) return "Invalid port";
|
|
8365
|
+
return void 0;
|
|
8366
|
+
}
|
|
8367
|
+
}),
|
|
8368
|
+
username: () => p24.text({ message: "SMTP username" }),
|
|
8369
|
+
password: () => p24.password({ message: "SMTP password" })
|
|
8370
|
+
},
|
|
8371
|
+
{
|
|
8372
|
+
onCancel: () => {
|
|
8373
|
+
p24.cancel("Operation cancelled.");
|
|
8374
|
+
process20.exit(0);
|
|
8375
|
+
}
|
|
8376
|
+
}
|
|
8377
|
+
);
|
|
8378
|
+
await withPocketbase(workspaceRootDir, async (pb) => {
|
|
8379
|
+
await pb.settings.update({
|
|
8380
|
+
smtp: {
|
|
8381
|
+
enabled: true,
|
|
8382
|
+
host: config.host,
|
|
8383
|
+
port: parseInt(config.port, 10),
|
|
8384
|
+
username: config.username ?? "",
|
|
8385
|
+
password: config.password ?? ""
|
|
8386
|
+
}
|
|
8387
|
+
});
|
|
8388
|
+
});
|
|
8389
|
+
reportResult({
|
|
8390
|
+
summary: "Enabled SMTP for transactional email.",
|
|
8391
|
+
nextSteps: [
|
|
8392
|
+
"PocketBase will now send auth/verification email via your SMTP server.",
|
|
8393
|
+
"Send a test email from the PocketBase admin UI (Settings \u2192 Mail settings).",
|
|
8394
|
+
"Run `vela disable smtp` to revert to the built-in fallback sender."
|
|
8395
|
+
]
|
|
8396
|
+
});
|
|
8397
|
+
}, "Failed to enable SMTP.")
|
|
8398
|
+
);
|
|
8399
|
+
|
|
8256
8400
|
// src/commands/enable/cms.ts
|
|
8401
|
+
import process21 from "node:process";
|
|
8402
|
+
import { Command as Command24 } from "commander";
|
|
8403
|
+
import * as p25 from "@clack/prompts";
|
|
8404
|
+
import pc10 from "picocolors";
|
|
8257
8405
|
function resolveCmsBackend(facts) {
|
|
8258
8406
|
if (facts.endpoint) return { kind: "hosted", endpoint: facts.endpoint, from: "flag" };
|
|
8259
8407
|
if (facts.backend || facts.adapter === "node") return { kind: "self-hosted" };
|
|
@@ -9433,14 +9581,14 @@ var ui = new Command55("ui").description("generate ui components").configureHelp
|
|
|
9433
9581
|
import { Command as Command58 } from "commander";
|
|
9434
9582
|
|
|
9435
9583
|
// src/commands/legal/terms.ts
|
|
9436
|
-
import
|
|
9584
|
+
import path37 from "node:path";
|
|
9437
9585
|
import { Command as Command56 } from "commander";
|
|
9438
9586
|
import * as p38 from "@clack/prompts";
|
|
9439
9587
|
|
|
9440
9588
|
// src/commands/legal/shared.ts
|
|
9441
9589
|
import process26 from "node:process";
|
|
9442
|
-
import
|
|
9443
|
-
import
|
|
9590
|
+
import fs38 from "node:fs";
|
|
9591
|
+
import path36 from "node:path";
|
|
9444
9592
|
import * as p37 from "@clack/prompts";
|
|
9445
9593
|
function siteFields(site) {
|
|
9446
9594
|
const url = site?.url && !isLocalUrl(site.url) ? site.url : void 0;
|
|
@@ -9722,16 +9870,16 @@ function writeLegalPage(root, dir, page) {
|
|
|
9722
9870
|
|
|
9723
9871
|
${html}`;
|
|
9724
9872
|
}
|
|
9725
|
-
const pagePath =
|
|
9726
|
-
|
|
9727
|
-
|
|
9873
|
+
const pagePath = path36.join(root, dir, "+page.svelte");
|
|
9874
|
+
fs38.mkdirSync(path36.dirname(pagePath), { recursive: true });
|
|
9875
|
+
fs38.writeFileSync(pagePath, html);
|
|
9728
9876
|
const written = [pagePath];
|
|
9729
9877
|
if (metaTags) {
|
|
9730
|
-
const loaderPath =
|
|
9731
|
-
|
|
9878
|
+
const loaderPath = path36.join(root, dir, "+page.ts");
|
|
9879
|
+
fs38.writeFileSync(loaderPath, pageMetaTagsLoader(page.title, page.description));
|
|
9732
9880
|
written.push(loaderPath);
|
|
9733
9881
|
}
|
|
9734
|
-
return written.map((file) =>
|
|
9882
|
+
return written.map((file) => path36.relative(root, file));
|
|
9735
9883
|
}
|
|
9736
9884
|
|
|
9737
9885
|
// src/commands/legal/terms.ts
|
|
@@ -10128,7 +10276,7 @@ async function termsAction() {
|
|
|
10128
10276
|
});
|
|
10129
10277
|
const [relativeTermsPage, ...rest] = writeLegalPage(
|
|
10130
10278
|
workspaceRootDir,
|
|
10131
|
-
|
|
10279
|
+
path37.join(publicRoutesDir, LEGAL_DIR, "terms"),
|
|
10132
10280
|
{
|
|
10133
10281
|
html,
|
|
10134
10282
|
title: "Terms of Service",
|
|
@@ -10148,7 +10296,7 @@ async function termsAction() {
|
|
|
10148
10296
|
var terms = new Command56("terms").description("generate placeholder terms and conditions").configureHelp(helpConfig).action(() => runCommand(termsAction, "Failed to generate terms and conditions."));
|
|
10149
10297
|
|
|
10150
10298
|
// src/commands/legal/privacy.ts
|
|
10151
|
-
import
|
|
10299
|
+
import path38 from "node:path";
|
|
10152
10300
|
import { Command as Command57 } from "commander";
|
|
10153
10301
|
import * as p39 from "@clack/prompts";
|
|
10154
10302
|
var mapLabels = {
|
|
@@ -10864,7 +11012,7 @@ async function privacyAction() {
|
|
|
10864
11012
|
});
|
|
10865
11013
|
const [relativePrivacyPage, ...rest] = writeLegalPage(
|
|
10866
11014
|
workspaceRootDir,
|
|
10867
|
-
|
|
11015
|
+
path38.join(publicRoutesDir, LEGAL_DIR, "privacy"),
|
|
10868
11016
|
{
|
|
10869
11017
|
html,
|
|
10870
11018
|
title: "Privacy Policy",
|
|
@@ -10893,8 +11041,8 @@ import { Command as Command64 } from "commander";
|
|
|
10893
11041
|
import { Command as Command59 } from "commander";
|
|
10894
11042
|
|
|
10895
11043
|
// src/lib/data.ts
|
|
10896
|
-
import
|
|
10897
|
-
import
|
|
11044
|
+
import fs39 from "node:fs";
|
|
11045
|
+
import path39 from "node:path";
|
|
10898
11046
|
import { ClientResponseError } from "pocketbase";
|
|
10899
11047
|
|
|
10900
11048
|
// src/lib/collections.ts
|
|
@@ -10931,14 +11079,14 @@ function dependencyOrder(collections2, startingCollectionId) {
|
|
|
10931
11079
|
|
|
10932
11080
|
// src/lib/data.ts
|
|
10933
11081
|
function dataDir(cwd, kind) {
|
|
10934
|
-
return
|
|
11082
|
+
return path39.join(cwd, DATA_DIR, kind);
|
|
10935
11083
|
}
|
|
10936
11084
|
function getDataFiles(cwd, kind) {
|
|
10937
11085
|
const dir = dataDir(cwd, kind);
|
|
10938
|
-
if (!
|
|
10939
|
-
return
|
|
11086
|
+
if (!fs39.existsSync(dir)) return [];
|
|
11087
|
+
return fs39.readdirSync(dir).filter((file) => file.endsWith(".json")).sort((a, b) => a.localeCompare(b)).map((file) => ({
|
|
10940
11088
|
collectionName: file.replace(/\.json$/i, "").replace(/^\d+[-_]?/, ""),
|
|
10941
|
-
filePath:
|
|
11089
|
+
filePath: path39.join(dir, file)
|
|
10942
11090
|
}));
|
|
10943
11091
|
}
|
|
10944
11092
|
function getSeedFiles(cwd) {
|
|
@@ -10948,7 +11096,7 @@ function getFixtureFiles(cwd) {
|
|
|
10948
11096
|
return getDataFiles(cwd, "fixtures");
|
|
10949
11097
|
}
|
|
10950
11098
|
function readRecords(filePath) {
|
|
10951
|
-
return JSON.parse(
|
|
11099
|
+
return JSON.parse(fs39.readFileSync(filePath, "utf8"));
|
|
10952
11100
|
}
|
|
10953
11101
|
function readSeedIds(cwd) {
|
|
10954
11102
|
const ids = /* @__PURE__ */ new Map();
|
|
@@ -10985,7 +11133,7 @@ function describeError(e) {
|
|
|
10985
11133
|
return e instanceof Error ? e.message : String(e);
|
|
10986
11134
|
}
|
|
10987
11135
|
function label3(cwd, filePath, count) {
|
|
10988
|
-
return `${
|
|
11136
|
+
return `${path39.relative(cwd, filePath)} (${count} records)`;
|
|
10989
11137
|
}
|
|
10990
11138
|
async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
|
|
10991
11139
|
const records = readRecords(filePath);
|
|
@@ -10993,7 +11141,7 @@ async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
|
|
|
10993
11141
|
try {
|
|
10994
11142
|
await pb.collection(collectionName).create(record);
|
|
10995
11143
|
} catch (e) {
|
|
10996
|
-
throw new DataLoadError(kind,
|
|
11144
|
+
throw new DataLoadError(kind, path39.relative(cwd, filePath), index, e);
|
|
10997
11145
|
}
|
|
10998
11146
|
}
|
|
10999
11147
|
return records.length;
|
|
@@ -11167,8 +11315,8 @@ var reset = new Command61("reset").description("clear and reload fixtures").conf
|
|
|
11167
11315
|
);
|
|
11168
11316
|
|
|
11169
11317
|
// src/commands/fixtures/generate.ts
|
|
11170
|
-
import
|
|
11171
|
-
import
|
|
11318
|
+
import fs40 from "node:fs";
|
|
11319
|
+
import path40 from "node:path";
|
|
11172
11320
|
import { Command as Command62, InvalidArgumentError } from "commander";
|
|
11173
11321
|
import * as p40 from "@clack/prompts";
|
|
11174
11322
|
import { annotate } from "annotate-json-schema";
|
|
@@ -11205,9 +11353,9 @@ async function loadCollections(pb) {
|
|
|
11205
11353
|
}
|
|
11206
11354
|
async function generateFixtureFiles(pb, workspaceRootDir, opts) {
|
|
11207
11355
|
const fixturesDir = dataDir(workspaceRootDir, "fixtures");
|
|
11208
|
-
|
|
11209
|
-
for (const file of
|
|
11210
|
-
if (file.endsWith(".json"))
|
|
11356
|
+
fs40.mkdirSync(fixturesDir, { recursive: true });
|
|
11357
|
+
for (const file of fs40.readdirSync(fixturesDir)) {
|
|
11358
|
+
if (file.endsWith(".json")) fs40.unlinkSync(path40.join(fixturesDir, file));
|
|
11211
11359
|
}
|
|
11212
11360
|
if (opts.seed !== void 0) faker.seed(opts.seed);
|
|
11213
11361
|
const generator = createGenerator({
|
|
@@ -11274,8 +11422,8 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
|
|
|
11274
11422
|
items.push(record);
|
|
11275
11423
|
}
|
|
11276
11424
|
const filename = `${padZeros(fileIndex, 2)}-${collection.name}.json`;
|
|
11277
|
-
|
|
11278
|
-
writtenFiles.push(`${
|
|
11425
|
+
fs40.writeFileSync(path40.join(fixturesDir, filename), JSON.stringify(items, null, 2));
|
|
11426
|
+
writtenFiles.push(`${path40.join(DATA_DIR, "fixtures", filename)} (${items.length} records)`);
|
|
11279
11427
|
fileIndex++;
|
|
11280
11428
|
}
|
|
11281
11429
|
return { writtenFiles, warnings };
|
|
@@ -11422,8 +11570,8 @@ var load2 = new Command65("load").description("load seeds into the database").op
|
|
|
11422
11570
|
);
|
|
11423
11571
|
|
|
11424
11572
|
// src/commands/seeds/save.ts
|
|
11425
|
-
import
|
|
11426
|
-
import
|
|
11573
|
+
import fs41 from "node:fs";
|
|
11574
|
+
import path41 from "node:path";
|
|
11427
11575
|
import { Command as Command66 } from "commander";
|
|
11428
11576
|
var padZeros2 = (num, length) => num.toString().padStart(length, "0");
|
|
11429
11577
|
function filterSystemFields(record, systemFieldNames) {
|
|
@@ -11443,10 +11591,10 @@ var save = new Command66("save").description("save the current data as seeds").o
|
|
|
11443
11591
|
if (existing.length > 0 && !opts.force) {
|
|
11444
11592
|
throw new Error("Existing seed files found in data/seeds. Pass --force to overwrite.");
|
|
11445
11593
|
}
|
|
11446
|
-
|
|
11594
|
+
fs41.mkdirSync(seedsPath, { recursive: true });
|
|
11447
11595
|
if (opts.force) {
|
|
11448
|
-
for (const file of
|
|
11449
|
-
if (file.endsWith(".json"))
|
|
11596
|
+
for (const file of fs41.readdirSync(seedsPath)) {
|
|
11597
|
+
if (file.endsWith(".json")) fs41.unlinkSync(path41.join(seedsPath, file));
|
|
11450
11598
|
}
|
|
11451
11599
|
}
|
|
11452
11600
|
const saved = [];
|
|
@@ -11475,13 +11623,13 @@ var save = new Command66("save").description("save the current data as seeds").o
|
|
|
11475
11623
|
const filtered = records.map(
|
|
11476
11624
|
(r) => filterSystemFields(r, systemFieldNames)
|
|
11477
11625
|
);
|
|
11478
|
-
const relativeSeedPath =
|
|
11626
|
+
const relativeSeedPath = path41.join(
|
|
11479
11627
|
DATA_DIR,
|
|
11480
11628
|
"seeds",
|
|
11481
11629
|
`${padZeros2(count, 2)}-${collectionName}.json`
|
|
11482
11630
|
);
|
|
11483
|
-
const seedPath =
|
|
11484
|
-
|
|
11631
|
+
const seedPath = path41.join(workspaceRootDir, relativeSeedPath);
|
|
11632
|
+
fs41.writeFileSync(seedPath, JSON.stringify(filtered, null, 2));
|
|
11485
11633
|
saved.push(`${relativeSeedPath} (${filtered.length} records)`);
|
|
11486
11634
|
count++;
|
|
11487
11635
|
}
|
|
@@ -11619,7 +11767,7 @@ import { Command as Command78 } from "commander";
|
|
|
11619
11767
|
import { Command as Command72 } from "commander";
|
|
11620
11768
|
|
|
11621
11769
|
// src/lib/migrate.ts
|
|
11622
|
-
import
|
|
11770
|
+
import path42 from "node:path";
|
|
11623
11771
|
import process27 from "node:process";
|
|
11624
11772
|
import { x as x3 } from "tinyexec";
|
|
11625
11773
|
function migrateRoot() {
|
|
@@ -11633,9 +11781,9 @@ async function runPocketbaseMigrate(args) {
|
|
|
11633
11781
|
binaryPath,
|
|
11634
11782
|
[
|
|
11635
11783
|
"--dir",
|
|
11636
|
-
|
|
11784
|
+
path42.join(cwd, DATA_DIR),
|
|
11637
11785
|
"--migrationsDir",
|
|
11638
|
-
|
|
11786
|
+
path42.join(cwd, MIGRATIONS_DIR),
|
|
11639
11787
|
"migrate",
|
|
11640
11788
|
...args
|
|
11641
11789
|
],
|
|
@@ -11683,8 +11831,8 @@ var down = new Command73("down").alias("rollback").description("revert the last
|
|
|
11683
11831
|
);
|
|
11684
11832
|
|
|
11685
11833
|
// src/commands/migrate/create.ts
|
|
11686
|
-
import
|
|
11687
|
-
import
|
|
11834
|
+
import fs42 from "node:fs";
|
|
11835
|
+
import path43 from "node:path";
|
|
11688
11836
|
import { Command as Command74 } from "commander";
|
|
11689
11837
|
var create2 = new Command74("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
|
|
11690
11838
|
(name) => runCommand(async () => {
|
|
@@ -11695,7 +11843,7 @@ var create2 = new Command74("create").alias("new").description("create a new bla
|
|
|
11695
11843
|
const added = [...after].filter((f) => !before.has(f));
|
|
11696
11844
|
reportResult({
|
|
11697
11845
|
summary: `Created blank migration ${name}.`,
|
|
11698
|
-
filesCreated: added.map((f) =>
|
|
11846
|
+
filesCreated: added.map((f) => path43.join(MIGRATIONS_DIR, f)),
|
|
11699
11847
|
nextSteps: [
|
|
11700
11848
|
`Open the new file in ${MIGRATIONS_DIR}/ and fill in the up/down handlers.`,
|
|
11701
11849
|
"Run `vela migrate up` to apply the migration once the handlers are written."
|
|
@@ -11704,14 +11852,14 @@ var create2 = new Command74("create").alias("new").description("create a new bla
|
|
|
11704
11852
|
}, "Failed to create migration.")
|
|
11705
11853
|
);
|
|
11706
11854
|
function listMigrationFiles(cwd) {
|
|
11707
|
-
const dir =
|
|
11708
|
-
if (!
|
|
11709
|
-
return new Set(
|
|
11855
|
+
const dir = path43.join(cwd, MIGRATIONS_DIR);
|
|
11856
|
+
if (!fs42.existsSync(dir)) return /* @__PURE__ */ new Set();
|
|
11857
|
+
return new Set(fs42.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
|
|
11710
11858
|
}
|
|
11711
11859
|
|
|
11712
11860
|
// src/commands/migrate/collections.ts
|
|
11713
|
-
import
|
|
11714
|
-
import
|
|
11861
|
+
import fs43 from "node:fs";
|
|
11862
|
+
import path44 from "node:path";
|
|
11715
11863
|
import { Command as Command75 } from "commander";
|
|
11716
11864
|
var collections = new Command75("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
|
|
11717
11865
|
() => runCommand(async () => {
|
|
@@ -11728,7 +11876,7 @@ var collections = new Command75("collections").alias("snapshot").description("sn
|
|
|
11728
11876
|
}
|
|
11729
11877
|
reportResult({
|
|
11730
11878
|
summary: "Snapshotted local collections into a new migration.",
|
|
11731
|
-
filesCreated: added.map((f) =>
|
|
11879
|
+
filesCreated: added.map((f) => path44.join(MIGRATIONS_DIR, f)),
|
|
11732
11880
|
nextSteps: [
|
|
11733
11881
|
`Review the generated snapshot in ${MIGRATIONS_DIR}/.`,
|
|
11734
11882
|
"Commit the snapshot so teammates pick up the new schema.",
|
|
@@ -11738,9 +11886,9 @@ var collections = new Command75("collections").alias("snapshot").description("sn
|
|
|
11738
11886
|
}, "Failed to snapshot collections.")
|
|
11739
11887
|
);
|
|
11740
11888
|
function listMigrationFiles2(cwd) {
|
|
11741
|
-
const dir =
|
|
11742
|
-
if (!
|
|
11743
|
-
return new Set(
|
|
11889
|
+
const dir = path44.join(cwd, MIGRATIONS_DIR);
|
|
11890
|
+
if (!fs43.existsSync(dir)) return /* @__PURE__ */ new Set();
|
|
11891
|
+
return new Set(fs43.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
|
|
11744
11892
|
}
|
|
11745
11893
|
|
|
11746
11894
|
// src/commands/migrate/history-sync.ts
|
|
@@ -11756,14 +11904,14 @@ var historySync = new Command76("history-sync").description("drop _migrations ro
|
|
|
11756
11904
|
);
|
|
11757
11905
|
|
|
11758
11906
|
// src/commands/migrate/sveltekit-3.ts
|
|
11759
|
-
import
|
|
11907
|
+
import path45 from "node:path";
|
|
11760
11908
|
import process28 from "node:process";
|
|
11761
11909
|
import { Command as Command77 } from "commander";
|
|
11762
11910
|
import * as p45 from "@clack/prompts";
|
|
11763
11911
|
import pc15 from "picocolors";
|
|
11764
11912
|
var sveltekit3 = new Command77("sveltekit-3").description("upgrade a SvelteKit 2 project to SvelteKit 3 (sv migrate, then the vela steps)").option("--cwd <path>", "the project to migrate (default: the current project)").option("--no-install", "skip installing dependencies").option("--force", "run even when the git working tree has uncommitted changes").option("--skip-sv", "only run the vela steps (sv has already been run)").configureHelp(helpConfig).action(
|
|
11765
11913
|
(options) => runCommand(async () => {
|
|
11766
|
-
const root = options.cwd ?
|
|
11914
|
+
const root = options.cwd ? path45.resolve(options.cwd) : findWorkspaceRoot() ?? process28.cwd();
|
|
11767
11915
|
p45.intro(pc15.bgCyan(pc15.black(" vela migrate sveltekit-3 ")));
|
|
11768
11916
|
const result = await runKit3Migration(root, {
|
|
11769
11917
|
install: options.install,
|
|
@@ -11780,7 +11928,7 @@ function printReport(root, result) {
|
|
|
11780
11928
|
sections.push({ label: "Build output removed first", items: result.sv.cleared });
|
|
11781
11929
|
}
|
|
11782
11930
|
for (const fixup2 of changed) sections.push({ label: fixup2.name, items: fixup2.details });
|
|
11783
|
-
const summary = result.mode === "repair" ? changed.length > 0 ? "Already on SvelteKit 3; brought the vela setup up to date." : "Already on SvelteKit 3; nothing left to change." : `Migrated ${
|
|
11931
|
+
const summary = result.mode === "repair" ? changed.length > 0 ? "Already on SvelteKit 3; brought the vela setup up to date." : "Already on SvelteKit 3; nothing left to change." : `Migrated ${path45.basename(root)} to SvelteKit 3.`;
|
|
11784
11932
|
reportResult({ summary, sections });
|
|
11785
11933
|
const tasks = result.tasks;
|
|
11786
11934
|
if (tasks && (tasks.sections.length > 0 || tasks.markerComments > 0)) {
|
|
@@ -11838,8 +11986,8 @@ function nextStepsFor(result) {
|
|
|
11838
11986
|
var migrate = new Command78("migrate").description("manage database migrations (and `migrate sveltekit-3` to upgrade SvelteKit)").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations.")).addCommand(up).addCommand(down).addCommand(create2).addCommand(collections).addCommand(historySync).addCommand(sveltekit3);
|
|
11839
11987
|
|
|
11840
11988
|
// src/commands/dev.ts
|
|
11841
|
-
import
|
|
11842
|
-
import
|
|
11989
|
+
import fs44 from "node:fs";
|
|
11990
|
+
import path47 from "node:path";
|
|
11843
11991
|
import process31 from "node:process";
|
|
11844
11992
|
import { performance } from "node:perf_hooks";
|
|
11845
11993
|
import { Command as Command79, InvalidArgumentError as InvalidArgumentError4 } from "commander";
|
|
@@ -11859,6 +12007,9 @@ function onTerminate(cleanup, proc = process29) {
|
|
|
11859
12007
|
});
|
|
11860
12008
|
}
|
|
11861
12009
|
}
|
|
12010
|
+
function stopChild(child) {
|
|
12011
|
+
if (child?.pid && child.exitCode === null && child.signalCode === null) child.kill();
|
|
12012
|
+
}
|
|
11862
12013
|
|
|
11863
12014
|
// src/lib/pocketbase-log-filter.ts
|
|
11864
12015
|
import { Transform } from "node:stream";
|
|
@@ -11885,7 +12036,7 @@ function createPocketbaseLogFilter() {
|
|
|
11885
12036
|
}
|
|
11886
12037
|
|
|
11887
12038
|
// src/lib/vite.ts
|
|
11888
|
-
import
|
|
12039
|
+
import path46 from "node:path";
|
|
11889
12040
|
import process30 from "node:process";
|
|
11890
12041
|
import { createRequire as createRequire3 } from "node:module";
|
|
11891
12042
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
@@ -11905,7 +12056,7 @@ function viteVersionError(version) {
|
|
|
11905
12056
|
}
|
|
11906
12057
|
function resolveProjectVite(cwd) {
|
|
11907
12058
|
try {
|
|
11908
|
-
return createRequire3(
|
|
12059
|
+
return createRequire3(path46.join(cwd, "package.json")).resolve("vite");
|
|
11909
12060
|
} catch {
|
|
11910
12061
|
return null;
|
|
11911
12062
|
}
|
|
@@ -11935,21 +12086,21 @@ var dev = new Command79("dev").description("start the development server").optio
|
|
|
11935
12086
|
process31.env.VELA_DATA_DIR ??= localDataDir(cwd);
|
|
11936
12087
|
const startTime = performance.now();
|
|
11937
12088
|
const { createServer, version } = await loadVite(cwd);
|
|
11938
|
-
const viteMetadataDir =
|
|
11939
|
-
const viteMetadataFile =
|
|
12089
|
+
const viteMetadataDir = path47.join(cwd, "node_modules", ".vite");
|
|
12090
|
+
const viteMetadataFile = path47.join(viteMetadataDir, "_pocketbase_metadata.json");
|
|
11940
12091
|
let pbProc;
|
|
11941
12092
|
const backend3 = hasBackend(cwd);
|
|
11942
12093
|
const needsStart = backend3 && !process31.env.POCKETBASE_URL;
|
|
11943
12094
|
const cleanup = () => {
|
|
11944
12095
|
if (pbProc?.pid) pbProc.kill();
|
|
11945
|
-
if (
|
|
12096
|
+
if (fs44.existsSync(viteMetadataFile)) fs44.rmSync(viteMetadataFile);
|
|
11946
12097
|
};
|
|
11947
12098
|
if (needsStart) {
|
|
11948
|
-
const dataDir2 =
|
|
12099
|
+
const dataDir2 = path47.join(cwd, DATA_DIR);
|
|
11949
12100
|
const started = await startPocketbaseServe({
|
|
11950
12101
|
dataDir: dataDir2,
|
|
11951
12102
|
migrationsDir: MIGRATIONS_DIR,
|
|
11952
|
-
hooksDir:
|
|
12103
|
+
hooksDir: path47.join(dataDir2, "hooks"),
|
|
11953
12104
|
dev: true,
|
|
11954
12105
|
stdio: "pipe"
|
|
11955
12106
|
});
|
|
@@ -11977,8 +12128,8 @@ var dev = new Command79("dev").description("start the development server").optio
|
|
|
11977
12128
|
if (!backend3) return;
|
|
11978
12129
|
const { address, port: vitePort } = server.httpServer.address();
|
|
11979
12130
|
const viteHost = address === "::1" ? "localhost" : address;
|
|
11980
|
-
await
|
|
11981
|
-
await
|
|
12131
|
+
await fs44.promises.mkdir(viteMetadataDir, { recursive: true });
|
|
12132
|
+
await fs44.promises.writeFile(
|
|
11982
12133
|
viteMetadataFile,
|
|
11983
12134
|
JSON.stringify({
|
|
11984
12135
|
pocketbaseUrl: process31.env.POCKETBASE_URL,
|
|
@@ -12023,18 +12174,18 @@ var dev = new Command79("dev").description("start the development server").optio
|
|
|
12023
12174
|
});
|
|
12024
12175
|
async function startWatchingTypes(cwd, pb) {
|
|
12025
12176
|
const { processTypes } = await import("@velastack/pocketbase-codegen");
|
|
12026
|
-
const typesDir =
|
|
12027
|
-
const pocketbaseDir =
|
|
12028
|
-
const pocketbaseTypes =
|
|
12177
|
+
const typesDir = path47.resolve(cwd, ".svelte-kit", "types");
|
|
12178
|
+
const pocketbaseDir = path47.join(typesDir, "pocketbase");
|
|
12179
|
+
const pocketbaseTypes = path47.join(pocketbaseDir, "$types.d.ts");
|
|
12029
12180
|
const regenerate = () => processTypes(pb, typesDir).catch(() => {
|
|
12030
12181
|
});
|
|
12031
12182
|
await regenerate();
|
|
12032
12183
|
void (async () => {
|
|
12033
12184
|
for (; ; ) {
|
|
12034
12185
|
try {
|
|
12035
|
-
await
|
|
12036
|
-
for await (const event of
|
|
12037
|
-
if (event.eventType === "rename" && event.filename === "$types.d.ts" && !
|
|
12186
|
+
await fs44.promises.mkdir(pocketbaseDir, { recursive: true });
|
|
12187
|
+
for await (const event of fs44.promises.watch(pocketbaseDir)) {
|
|
12188
|
+
if (event.eventType === "rename" && event.filename === "$types.d.ts" && !fs44.existsSync(pocketbaseTypes)) {
|
|
12038
12189
|
setTimeout(regenerate, 100);
|
|
12039
12190
|
}
|
|
12040
12191
|
}
|
|
@@ -12046,8 +12197,8 @@ async function startWatchingTypes(cwd, pb) {
|
|
|
12046
12197
|
}
|
|
12047
12198
|
|
|
12048
12199
|
// src/commands/build.ts
|
|
12049
|
-
import
|
|
12050
|
-
import
|
|
12200
|
+
import fs45 from "node:fs";
|
|
12201
|
+
import path48 from "node:path";
|
|
12051
12202
|
import process33 from "node:process";
|
|
12052
12203
|
import { Command as Command80 } from "commander";
|
|
12053
12204
|
import * as p46 from "@clack/prompts";
|
|
@@ -12089,45 +12240,60 @@ function splitHosts(value) {
|
|
|
12089
12240
|
}
|
|
12090
12241
|
|
|
12091
12242
|
// src/commands/build.ts
|
|
12092
|
-
var PRERENDERED_DIR =
|
|
12243
|
+
var PRERENDERED_DIR = path48.join(".svelte-kit", "output", "prerendered");
|
|
12093
12244
|
var build = new Command80("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
|
|
12094
12245
|
const cwd = process33.cwd();
|
|
12095
12246
|
warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) => p46.log.warn(m));
|
|
12247
|
+
warnIfSsrExternalMissing(findWorkspaceRoot(cwd) ?? cwd);
|
|
12096
12248
|
applyBuildEnv(cwd);
|
|
12097
12249
|
const origin = await originForBuild(cwd, options.target);
|
|
12098
12250
|
if (origin) process33.env.VELA_ORIGIN = origin;
|
|
12099
12251
|
let pbProc;
|
|
12100
12252
|
const needsStart = hasBackend(cwd) && !process33.env.POCKETBASE_URL;
|
|
12253
|
+
let viteProc;
|
|
12101
12254
|
const cleanup = () => {
|
|
12102
|
-
|
|
12255
|
+
stopChild(pbProc);
|
|
12256
|
+
stopChild(viteProc);
|
|
12103
12257
|
};
|
|
12258
|
+
onTerminate(cleanup);
|
|
12104
12259
|
if (needsStart) {
|
|
12105
12260
|
await ensureSuperuser(cwd);
|
|
12106
|
-
const dataDir2 =
|
|
12261
|
+
const dataDir2 = path48.join(cwd, DATA_DIR);
|
|
12107
12262
|
const started = await startPocketbaseServe({
|
|
12108
12263
|
dataDir: dataDir2,
|
|
12109
12264
|
migrationsDir: MIGRATIONS_DIR,
|
|
12110
|
-
hooksDir:
|
|
12265
|
+
hooksDir: path48.join(dataDir2, "hooks"),
|
|
12111
12266
|
dev: true
|
|
12112
12267
|
});
|
|
12113
12268
|
pbProc = started.proc;
|
|
12114
12269
|
process33.env.POCKETBASE_URL = started.url;
|
|
12115
|
-
onTerminate(cleanup);
|
|
12116
12270
|
}
|
|
12117
12271
|
try {
|
|
12118
12272
|
const pm = (await detect7({ cwd }))?.name ?? "npm";
|
|
12119
12273
|
const resolved = resolveCommand5(pm, "execute", ["vite", "build"]);
|
|
12120
12274
|
const args = resolved.args.slice();
|
|
12121
12275
|
if (pm === "npm") args.unshift("--yes");
|
|
12122
|
-
|
|
12276
|
+
const vite = x4(resolved.command, args, {
|
|
12123
12277
|
nodeOptions: { cwd, stdio: "inherit" },
|
|
12124
12278
|
throwOnError: true
|
|
12125
12279
|
});
|
|
12280
|
+
viteProc = vite.process;
|
|
12281
|
+
await vite;
|
|
12126
12282
|
} finally {
|
|
12127
12283
|
cleanup();
|
|
12128
12284
|
}
|
|
12129
12285
|
if (!origin) warnIfPrerendered(cwd);
|
|
12130
12286
|
});
|
|
12287
|
+
function warnIfSsrExternalMissing(root) {
|
|
12288
|
+
try {
|
|
12289
|
+
if (detectAdapter(root).kind !== "node") return;
|
|
12290
|
+
} catch {
|
|
12291
|
+
return;
|
|
12292
|
+
}
|
|
12293
|
+
const check2 = ssrExternalNotInDependencies(root);
|
|
12294
|
+
const problem = ssrExternalProblem(check2) ?? ssrExternalAllNotice(check2);
|
|
12295
|
+
if (problem) p46.log.warn(problem);
|
|
12296
|
+
}
|
|
12131
12297
|
async function originForBuild(cwd, target) {
|
|
12132
12298
|
const workspaceRootDir = findWorkspaceRoot(cwd);
|
|
12133
12299
|
if (!workspaceRootDir) return null;
|
|
@@ -12142,8 +12308,8 @@ async function originForBuild(cwd, target) {
|
|
|
12142
12308
|
}
|
|
12143
12309
|
}
|
|
12144
12310
|
function warnIfPrerendered(cwd) {
|
|
12145
|
-
const dir =
|
|
12146
|
-
if (!
|
|
12311
|
+
const dir = path48.join(cwd, PRERENDERED_DIR);
|
|
12312
|
+
if (!fs45.existsSync(dir) || fs45.readdirSync(dir).length === 0) return;
|
|
12147
12313
|
if (process33.env.VELA_ORIGIN === "") {
|
|
12148
12314
|
p46.log.warn(
|
|
12149
12315
|
`Prerendered pages were built with no origin, on purpose: this app is served on
|
|
@@ -12166,8 +12332,8 @@ Set one with ${pc18.cyan("vela deploy --domain example.com")}, or pass ${pc18.cy
|
|
|
12166
12332
|
}
|
|
12167
12333
|
|
|
12168
12334
|
// src/commands/preview.ts
|
|
12169
|
-
import
|
|
12170
|
-
import
|
|
12335
|
+
import fs46 from "node:fs";
|
|
12336
|
+
import path49 from "node:path";
|
|
12171
12337
|
import process34 from "node:process";
|
|
12172
12338
|
import { Command as Command81 } from "commander";
|
|
12173
12339
|
import * as p47 from "@clack/prompts";
|
|
@@ -12175,7 +12341,7 @@ import pc19 from "picocolors";
|
|
|
12175
12341
|
import { x as x5 } from "tinyexec";
|
|
12176
12342
|
import { detect as detect8 } from "package-manager-detector";
|
|
12177
12343
|
import { resolveCommand as resolveCommand6 } from "package-manager-detector/commands";
|
|
12178
|
-
var ADAPTER_NODE_MODULE =
|
|
12344
|
+
var ADAPTER_NODE_MODULE = path49.join("build", "adapter-node.js");
|
|
12179
12345
|
var preview = new Command81("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
|
|
12180
12346
|
const cwd = process34.cwd();
|
|
12181
12347
|
process34.env.VELA_DATA_DIR ??= localDataDir(cwd);
|
|
@@ -12183,30 +12349,34 @@ var preview = new Command81("preview").description("preview the built app").conf
|
|
|
12183
12349
|
warnIfOriginBaked(cwd);
|
|
12184
12350
|
let pbProc;
|
|
12185
12351
|
const needsStart = hasBackend(cwd) && !process34.env.POCKETBASE_URL;
|
|
12352
|
+
let viteProc;
|
|
12186
12353
|
const cleanup = () => {
|
|
12187
|
-
|
|
12354
|
+
stopChild(pbProc);
|
|
12355
|
+
stopChild(viteProc);
|
|
12188
12356
|
};
|
|
12357
|
+
onTerminate(cleanup);
|
|
12189
12358
|
if (needsStart) {
|
|
12190
|
-
const dataDir2 =
|
|
12359
|
+
const dataDir2 = path49.join(cwd, DATA_DIR);
|
|
12191
12360
|
const started = await startPocketbaseServe({
|
|
12192
12361
|
dataDir: dataDir2,
|
|
12193
12362
|
migrationsDir: MIGRATIONS_DIR,
|
|
12194
|
-
hooksDir:
|
|
12363
|
+
hooksDir: path49.join(dataDir2, "hooks"),
|
|
12195
12364
|
dev: true
|
|
12196
12365
|
});
|
|
12197
12366
|
pbProc = started.proc;
|
|
12198
12367
|
process34.env.POCKETBASE_URL = started.url;
|
|
12199
|
-
onTerminate(cleanup);
|
|
12200
12368
|
}
|
|
12201
12369
|
try {
|
|
12202
12370
|
const pm = (await detect8({ cwd }))?.name ?? "npm";
|
|
12203
12371
|
const resolved = resolveCommand6(pm, "execute", ["vite", "preview"]);
|
|
12204
12372
|
const args = resolved.args.slice();
|
|
12205
12373
|
if (pm === "npm") args.unshift("--yes");
|
|
12206
|
-
|
|
12374
|
+
const vite = x5(resolved.command, args, {
|
|
12207
12375
|
nodeOptions: { cwd, stdio: "inherit" },
|
|
12208
12376
|
throwOnError: true
|
|
12209
12377
|
});
|
|
12378
|
+
viteProc = vite.process;
|
|
12379
|
+
await vite;
|
|
12210
12380
|
} finally {
|
|
12211
12381
|
cleanup();
|
|
12212
12382
|
}
|
|
@@ -12224,7 +12394,7 @@ function bakedOrigin(source) {
|
|
|
12224
12394
|
function warnIfOriginBaked(cwd) {
|
|
12225
12395
|
let source;
|
|
12226
12396
|
try {
|
|
12227
|
-
source =
|
|
12397
|
+
source = fs46.readFileSync(path49.join(cwd, ADAPTER_NODE_MODULE), "utf8");
|
|
12228
12398
|
} catch {
|
|
12229
12399
|
return;
|
|
12230
12400
|
}
|
|
@@ -12240,12 +12410,12 @@ set empty so no domain is baked in.`
|
|
|
12240
12410
|
}
|
|
12241
12411
|
|
|
12242
12412
|
// src/commands/sync.ts
|
|
12243
|
-
import
|
|
12413
|
+
import path50 from "node:path";
|
|
12244
12414
|
import { Command as Command82 } from "commander";
|
|
12245
12415
|
var sync = new Command82("sync").description("sync types from the database").configureHelp(helpConfig).action(
|
|
12246
12416
|
() => runCommand(async () => {
|
|
12247
12417
|
const { workspaceRootDir } = await getWorkspace();
|
|
12248
|
-
const typesDir =
|
|
12418
|
+
const typesDir = path50.join(workspaceRootDir, ".svelte-kit", "types");
|
|
12249
12419
|
const { processTypes } = await import("@velastack/pocketbase-codegen");
|
|
12250
12420
|
await withPocketbase(workspaceRootDir, async (pb) => {
|
|
12251
12421
|
await processTypes(pb, typesDir);
|
|
@@ -12312,8 +12482,8 @@ var provision = addSshOptions(
|
|
|
12312
12482
|
);
|
|
12313
12483
|
|
|
12314
12484
|
// src/commands/deploy.ts
|
|
12315
|
-
import
|
|
12316
|
-
import
|
|
12485
|
+
import path52 from "node:path";
|
|
12486
|
+
import fs48 from "node:fs";
|
|
12317
12487
|
import process36 from "node:process";
|
|
12318
12488
|
import { Command as Command84, Option as Option2 } from "commander";
|
|
12319
12489
|
import * as p49 from "@clack/prompts";
|
|
@@ -12321,14 +12491,14 @@ import pc21 from "picocolors";
|
|
|
12321
12491
|
import * as v10 from "valibot";
|
|
12322
12492
|
|
|
12323
12493
|
// src/lib/pocketbase-settings.ts
|
|
12324
|
-
import
|
|
12325
|
-
import
|
|
12494
|
+
import fs47 from "node:fs";
|
|
12495
|
+
import path51 from "node:path";
|
|
12326
12496
|
import process35 from "node:process";
|
|
12327
12497
|
import PocketBase5 from "pocketbase";
|
|
12328
12498
|
var COPIED_KEYS = ["senderName", "senderAddress"];
|
|
12329
12499
|
async function readLocalMeta(cwd) {
|
|
12330
|
-
const dataDir2 =
|
|
12331
|
-
if (!
|
|
12500
|
+
const dataDir2 = path51.join(cwd, DATA_DIR);
|
|
12501
|
+
if (!fs47.existsSync(dataDir2)) return null;
|
|
12332
12502
|
const email2 = process35.env.POCKETBASE_SUPERUSER_EMAIL;
|
|
12333
12503
|
const password11 = process35.env.POCKETBASE_SUPERUSER_PASSWORD;
|
|
12334
12504
|
if (!email2 || !password11) return null;
|
|
@@ -12337,7 +12507,7 @@ async function readLocalMeta(cwd) {
|
|
|
12337
12507
|
const started = await startPocketbaseServe({
|
|
12338
12508
|
dataDir: dataDir2,
|
|
12339
12509
|
migrationsDir: MIGRATIONS_DIR,
|
|
12340
|
-
hooksDir:
|
|
12510
|
+
hooksDir: path51.join(dataDir2, "hooks")
|
|
12341
12511
|
});
|
|
12342
12512
|
proc = started.proc;
|
|
12343
12513
|
const pb = new PocketBase5(started.url);
|
|
@@ -12425,6 +12595,7 @@ ${pc21.cyan("package-lock.json")} (${pc21.dim("npm install --package-lock-only")
|
|
|
12425
12595
|
);
|
|
12426
12596
|
}
|
|
12427
12597
|
}
|
|
12598
|
+
ssrExternalPreflight(findWorkspaceRoot() ?? process36.cwd());
|
|
12428
12599
|
await withTarget(
|
|
12429
12600
|
raw,
|
|
12430
12601
|
{
|
|
@@ -12623,7 +12794,7 @@ ${pc21.cyan(err.snippet)}` : err.message);
|
|
|
12623
12794
|
const has = current.kind === "auto" ? `is on ${ADAPTER_AUTO}` : "has no SvelteKit adapter configured";
|
|
12624
12795
|
const confirmed = await p49.confirm({
|
|
12625
12796
|
message: `This project ${has}, and vela deploy runs the app as a Node server.
|
|
12626
|
-
Switch it to ${
|
|
12797
|
+
Switch it to ${ADAPTER_NODE}? This edits ${path52.basename(current.file)} and package.json.`
|
|
12627
12798
|
});
|
|
12628
12799
|
if (p49.isCancel(confirmed) || !confirmed) {
|
|
12629
12800
|
p49.cancel("Nothing was changed, and nothing was deployed.");
|
|
@@ -12636,8 +12807,8 @@ Switch it to ${ADAPTER_NODE2}? This edits ${path51.basename(current.file)} and p
|
|
|
12636
12807
|
outcome.configFile,
|
|
12637
12808
|
outcome.packageJsonChanged ? "package.json" : void 0
|
|
12638
12809
|
].filter((f) => Boolean(f));
|
|
12639
|
-
const why = outcome.previous === "auto" ? `${ADAPTER_AUTO} builds nothing for a server of your own` : outcome.previous === "none" ? "No adapter was configured" : `${
|
|
12640
|
-
p49.log.step(`Switching the adapter to ${pc21.cyan(
|
|
12810
|
+
const why = outcome.previous === "auto" ? `${ADAPTER_AUTO} builds nothing for a server of your own` : outcome.previous === "none" ? "No adapter was configured" : `${ADAPTER_NODE} was configured but not in package.json`;
|
|
12811
|
+
p49.log.step(`Switching the adapter to ${pc21.cyan(ADAPTER_NODE)}`);
|
|
12641
12812
|
p49.log.info(
|
|
12642
12813
|
`${why}, and vela deploy runs the app as a Node server.
|
|
12643
12814
|
|
|
@@ -12653,6 +12824,20 @@ Switch it to ${ADAPTER_NODE2}? This edits ${path51.basename(current.file)} and p
|
|
|
12653
12824
|
}
|
|
12654
12825
|
p49.log.warn(`Commit ${changed.join(", ")} so every deploy builds the same way.`);
|
|
12655
12826
|
}
|
|
12827
|
+
function ssrExternalPreflight(root) {
|
|
12828
|
+
let adapter;
|
|
12829
|
+
try {
|
|
12830
|
+
adapter = detectAdapter(root);
|
|
12831
|
+
} catch {
|
|
12832
|
+
return;
|
|
12833
|
+
}
|
|
12834
|
+
if (adapter.kind !== "node") return;
|
|
12835
|
+
const check2 = ssrExternalNotInDependencies(root);
|
|
12836
|
+
const problem = ssrExternalProblem(check2);
|
|
12837
|
+
if (problem) throw new Error(problem);
|
|
12838
|
+
const notice = ssrExternalAllNotice(check2);
|
|
12839
|
+
if (notice) p49.log.warn(notice);
|
|
12840
|
+
}
|
|
12656
12841
|
async function syncAppName(session, instance, appName, domain) {
|
|
12657
12842
|
if (!appName && !domain) return;
|
|
12658
12843
|
let result;
|
|
@@ -12790,7 +12975,7 @@ async function uploadRelease(session, instance, release, entries) {
|
|
|
12790
12975
|
}
|
|
12791
12976
|
function isDirectory(target) {
|
|
12792
12977
|
try {
|
|
12793
|
-
return
|
|
12978
|
+
return fs48.statSync(target).isDirectory();
|
|
12794
12979
|
} catch {
|
|
12795
12980
|
return false;
|
|
12796
12981
|
}
|
|
@@ -12798,7 +12983,7 @@ function isDirectory(target) {
|
|
|
12798
12983
|
async function reportEmptyEnvironment(session, instance, workspaceRootDir) {
|
|
12799
12984
|
const remote = await readRemoteEnv(session, instance);
|
|
12800
12985
|
if (Object.keys(remote).length > 0) return;
|
|
12801
|
-
if (!
|
|
12986
|
+
if (!fs48.existsSync(path52.join(workspaceRootDir, ".env"))) return;
|
|
12802
12987
|
p49.log.warn(
|
|
12803
12988
|
`This app has no production environment variables yet.
|
|
12804
12989
|
|
|
@@ -12835,7 +13020,7 @@ async function serverTimeOrLocal(session) {
|
|
|
12835
13020
|
}
|
|
12836
13021
|
|
|
12837
13022
|
// src/commands/link.ts
|
|
12838
|
-
import
|
|
13023
|
+
import path53 from "node:path";
|
|
12839
13024
|
import process37 from "node:process";
|
|
12840
13025
|
import { Command as Command85 } from "commander";
|
|
12841
13026
|
import * as p50 from "@clack/prompts";
|
|
@@ -12898,12 +13083,12 @@ async function promptProjectName(workspaceRootDir) {
|
|
|
12898
13083
|
}
|
|
12899
13084
|
function defaultProjectName2(workspaceRootDir) {
|
|
12900
13085
|
try {
|
|
12901
|
-
const pkg = readPackageJson(
|
|
13086
|
+
const pkg = readPackageJson(path53.join(workspaceRootDir, "package.json"));
|
|
12902
13087
|
const name = pkg.name;
|
|
12903
13088
|
if (typeof name === "string" && name.trim()) return name.trim();
|
|
12904
13089
|
} catch {
|
|
12905
13090
|
}
|
|
12906
|
-
return
|
|
13091
|
+
return path53.basename(workspaceRootDir);
|
|
12907
13092
|
}
|
|
12908
13093
|
|
|
12909
13094
|
// src/commands/env.ts
|
|
@@ -13034,8 +13219,8 @@ var envUnset = addTargetOptions(
|
|
|
13034
13219
|
);
|
|
13035
13220
|
|
|
13036
13221
|
// src/commands/env/import.ts
|
|
13037
|
-
import
|
|
13038
|
-
import
|
|
13222
|
+
import fs49 from "node:fs";
|
|
13223
|
+
import path54 from "node:path";
|
|
13039
13224
|
import process39 from "node:process";
|
|
13040
13225
|
import { Command as Command89 } from "commander";
|
|
13041
13226
|
import * as p54 from "@clack/prompts";
|
|
@@ -13081,10 +13266,10 @@ var envImport = addTargetOptions(
|
|
|
13081
13266
|
)
|
|
13082
13267
|
);
|
|
13083
13268
|
function resolve(file) {
|
|
13084
|
-
return
|
|
13269
|
+
return path54.resolve(process39.cwd(), file);
|
|
13085
13270
|
}
|
|
13086
13271
|
function read(resolved, shown) {
|
|
13087
|
-
if (!
|
|
13272
|
+
if (!fs49.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
|
|
13088
13273
|
const incoming = readLocalEnvFile(resolved);
|
|
13089
13274
|
if (Object.keys(incoming).length === 0) p54.log.info(`${shown} has no variables to import.`);
|
|
13090
13275
|
return incoming;
|
|
@@ -13371,8 +13556,8 @@ var admin = new Command95("admin").description("manage admin panel logins").conf
|
|
|
13371
13556
|
import { Command as Command101 } from "commander";
|
|
13372
13557
|
|
|
13373
13558
|
// src/commands/backup/create.ts
|
|
13374
|
-
import
|
|
13375
|
-
import
|
|
13559
|
+
import fs50 from "node:fs";
|
|
13560
|
+
import path55 from "node:path";
|
|
13376
13561
|
import { Command as Command96 } from "commander";
|
|
13377
13562
|
import * as p58 from "@clack/prompts";
|
|
13378
13563
|
import pc29 from "picocolors";
|
|
@@ -13526,12 +13711,12 @@ Your bucket's own versioning is what protects the uploaded files.`
|
|
|
13526
13711
|
}, "Failed to create the backup.")
|
|
13527
13712
|
);
|
|
13528
13713
|
async function download(ctx, key, outputDir) {
|
|
13529
|
-
const dir =
|
|
13530
|
-
|
|
13531
|
-
const destination =
|
|
13714
|
+
const dir = path55.resolve(ctx.workspaceRootDir, outputDir);
|
|
13715
|
+
fs50.mkdirSync(dir, { recursive: true });
|
|
13716
|
+
const destination = path55.join(dir, key);
|
|
13532
13717
|
if (!ctx.session) {
|
|
13533
|
-
|
|
13534
|
-
return
|
|
13718
|
+
fs50.copyFileSync(path55.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
13719
|
+
return path55.relative(ctx.workspaceRootDir, destination);
|
|
13535
13720
|
}
|
|
13536
13721
|
const spinner8 = p58.spinner();
|
|
13537
13722
|
spinner8.start(`Downloading ${key}`);
|
|
@@ -13542,7 +13727,7 @@ async function download(ctx, key, outputDir) {
|
|
|
13542
13727
|
throw error;
|
|
13543
13728
|
}
|
|
13544
13729
|
spinner8.stop(`Downloaded ${key}`);
|
|
13545
|
-
return
|
|
13730
|
+
return path55.relative(ctx.workspaceRootDir, destination);
|
|
13546
13731
|
}
|
|
13547
13732
|
|
|
13548
13733
|
// src/commands/backup/list.ts
|
|
@@ -13576,8 +13761,8 @@ Take one with ${pc30.cyan("vela backup create")}.`
|
|
|
13576
13761
|
);
|
|
13577
13762
|
|
|
13578
13763
|
// src/commands/backup/download.ts
|
|
13579
|
-
import
|
|
13580
|
-
import
|
|
13764
|
+
import fs51 from "node:fs";
|
|
13765
|
+
import path56 from "node:path";
|
|
13581
13766
|
import { Command as Command98 } from "commander";
|
|
13582
13767
|
import * as p60 from "@clack/prompts";
|
|
13583
13768
|
import pc31 from "picocolors";
|
|
@@ -13604,11 +13789,11 @@ Run ${pc31.cyan("vela backup list")} to see what it does have.`
|
|
|
13604
13789
|
Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
13605
13790
|
);
|
|
13606
13791
|
}
|
|
13607
|
-
const dir =
|
|
13608
|
-
|
|
13609
|
-
const destination =
|
|
13792
|
+
const dir = path56.resolve(ctx.workspaceRootDir, options.output);
|
|
13793
|
+
fs51.mkdirSync(dir, { recursive: true });
|
|
13794
|
+
const destination = path56.join(dir, key);
|
|
13610
13795
|
if (!ctx.session) {
|
|
13611
|
-
|
|
13796
|
+
fs51.copyFileSync(path56.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
13612
13797
|
} else {
|
|
13613
13798
|
const spinner8 = p60.spinner();
|
|
13614
13799
|
spinner8.start(`Downloading ${key} (${formatBytes(found.size)})`);
|
|
@@ -13622,7 +13807,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
13622
13807
|
}
|
|
13623
13808
|
reportResult({
|
|
13624
13809
|
summary: `Saved ${key} from ${ctx.targetName}.`,
|
|
13625
|
-
filesCreated: [
|
|
13810
|
+
filesCreated: [path56.relative(ctx.workspaceRootDir, destination)]
|
|
13626
13811
|
});
|
|
13627
13812
|
});
|
|
13628
13813
|
}, "Failed to download the backup.")
|
|
@@ -13717,8 +13902,8 @@ Set one with ${pc33.cyan('vela backup schedule "0 3 * * *"')}.`
|
|
|
13717
13902
|
var backup = new Command101("backup").description("back up the database and uploads, locally or on a target").configureHelp(helpConfig).addCommand(backupCreate).addCommand(backupList).addCommand(backupDownload).addCommand(backupDelete).addCommand(backupSchedule);
|
|
13718
13903
|
|
|
13719
13904
|
// src/commands/restore.ts
|
|
13720
|
-
import
|
|
13721
|
-
import
|
|
13905
|
+
import fs52 from "node:fs";
|
|
13906
|
+
import path57 from "node:path";
|
|
13722
13907
|
import process42 from "node:process";
|
|
13723
13908
|
import { Command as Command102 } from "commander";
|
|
13724
13909
|
import * as p63 from "@clack/prompts";
|
|
@@ -13748,7 +13933,7 @@ Run \`vela deploy\` first, then restore.`
|
|
|
13748
13933
|
`${ctx.targetName} was deployed without a database, so there is nothing to restore.`
|
|
13749
13934
|
);
|
|
13750
13935
|
}
|
|
13751
|
-
const local = source &&
|
|
13936
|
+
const local = source && fs52.existsSync(source) ? source : void 0;
|
|
13752
13937
|
const key = local ? void 0 : await resolveKey(ctx, source);
|
|
13753
13938
|
if (!options.yes) {
|
|
13754
13939
|
await confirm14(ctx.appName, ctx.targetName, ctx.envTag, local ?? key);
|
|
@@ -13771,7 +13956,7 @@ Run \`vela deploy\` first, then restore.`
|
|
|
13771
13956
|
});
|
|
13772
13957
|
p63.log.success(
|
|
13773
13958
|
`Restored ${pc34.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc34.cyan(
|
|
13774
|
-
local ?
|
|
13959
|
+
local ? path57.basename(local) : key
|
|
13775
13960
|
)}.`
|
|
13776
13961
|
);
|
|
13777
13962
|
if (result?.storageCarriedOver) {
|
|
@@ -13837,21 +14022,21 @@ Take one with ${pc34.cyan("vela backup create")}, or pass the path to an archive
|
|
|
13837
14022
|
}
|
|
13838
14023
|
async function stage(ctx, file) {
|
|
13839
14024
|
const dir = remotePaths.restoreStage(ctx.instance);
|
|
13840
|
-
const remote = `${dir}/${
|
|
14025
|
+
const remote = `${dir}/${path57.basename(file)}`;
|
|
13841
14026
|
const spinner8 = p63.spinner();
|
|
13842
|
-
spinner8.start(`Uploading ${
|
|
14027
|
+
spinner8.start(`Uploading ${path57.basename(file)}`);
|
|
13843
14028
|
try {
|
|
13844
14029
|
await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
|
|
13845
14030
|
await ctx.session.upload([file], dir);
|
|
13846
14031
|
} catch (error) {
|
|
13847
|
-
spinner8.stop(`Could not upload ${
|
|
14032
|
+
spinner8.stop(`Could not upload ${path57.basename(file)}.`);
|
|
13848
14033
|
throw error;
|
|
13849
14034
|
}
|
|
13850
|
-
spinner8.stop(`Uploaded ${
|
|
14035
|
+
spinner8.stop(`Uploaded ${path57.basename(file)}`);
|
|
13851
14036
|
return remote;
|
|
13852
14037
|
}
|
|
13853
14038
|
async function confirm14(appName, targetName, envTag, from) {
|
|
13854
|
-
const what = `${pc34.cyan(`${appName} (${targetName})`)} from ${pc34.cyan(
|
|
14039
|
+
const what = `${pc34.cyan(`${appName} (${targetName})`)} from ${pc34.cyan(path57.basename(from))}`;
|
|
13855
14040
|
if (isProd(envTag)) {
|
|
13856
14041
|
const answer = await p63.text({
|
|
13857
14042
|
message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
|
|
@@ -13962,7 +14147,7 @@ Release and domain are shown from what this project recorded.`
|
|
|
13962
14147
|
}
|
|
13963
14148
|
|
|
13964
14149
|
// src/commands/test.ts
|
|
13965
|
-
import
|
|
14150
|
+
import path58 from "node:path";
|
|
13966
14151
|
import process43 from "node:process";
|
|
13967
14152
|
import { Command as Command104 } from "commander";
|
|
13968
14153
|
import PocketBase6 from "pocketbase";
|
|
@@ -13970,21 +14155,21 @@ import pc36 from "picocolors";
|
|
|
13970
14155
|
import { x as x6 } from "tinyexec";
|
|
13971
14156
|
import { detect as detect9 } from "package-manager-detector";
|
|
13972
14157
|
import { resolveCommand as resolveCommand7 } from "package-manager-detector/commands";
|
|
13973
|
-
import
|
|
14158
|
+
import fs53 from "node:fs";
|
|
13974
14159
|
var testServer = new Command104("test:server").description("run server tests").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(async (_opts, cmd) => {
|
|
13975
14160
|
const cwd = process43.cwd();
|
|
13976
14161
|
warnIfKit2(cwd, (m) => console.warn(pc36.yellow(`\u25B2 ${m}`)));
|
|
13977
14162
|
const email2 = `test-${Math.random().toString(36).slice(2)}@example.com`;
|
|
13978
14163
|
const password11 = "password";
|
|
13979
|
-
const testDataDir =
|
|
13980
|
-
|
|
14164
|
+
const testDataDir = path58.join(cwd, "test-data");
|
|
14165
|
+
fs53.rmSync(testDataDir, { recursive: true, force: true });
|
|
13981
14166
|
const { stop, url } = await launchPocketbase(cwd, {
|
|
13982
14167
|
dir: testDataDir,
|
|
13983
|
-
migrationsDir:
|
|
14168
|
+
migrationsDir: path58.join(cwd, MIGRATIONS_DIR),
|
|
13984
14169
|
// The app's PocketBase hooks (slug generation, personal teams, …) are part
|
|
13985
14170
|
// of its behaviour; the suite runs against the same server dev and build
|
|
13986
14171
|
// start, so it loads them from the same place.
|
|
13987
|
-
hooksDir:
|
|
14172
|
+
hooksDir: path58.join(cwd, DATA_DIR, "hooks"),
|
|
13988
14173
|
email: email2,
|
|
13989
14174
|
password: password11
|
|
13990
14175
|
});
|
|
@@ -14000,7 +14185,7 @@ var testServer = new Command104("test:server").description("run server tests").a
|
|
|
14000
14185
|
if (cleanedUp) return;
|
|
14001
14186
|
cleanedUp = true;
|
|
14002
14187
|
stop();
|
|
14003
|
-
|
|
14188
|
+
fs53.rmSync(testDataDir, { recursive: true, force: true });
|
|
14004
14189
|
};
|
|
14005
14190
|
const cleanup = async () => {
|
|
14006
14191
|
if (cleanedUp) return;
|
|
@@ -14109,8 +14294,8 @@ function stubPagesPlugin() {
|
|
|
14109
14294
|
}
|
|
14110
14295
|
|
|
14111
14296
|
// src/commands/routes.ts
|
|
14112
|
-
import
|
|
14113
|
-
import
|
|
14297
|
+
import fs54 from "node:fs";
|
|
14298
|
+
import path59 from "node:path";
|
|
14114
14299
|
import { Command as Command105 } from "commander";
|
|
14115
14300
|
var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
14116
14301
|
"GET",
|
|
@@ -14124,30 +14309,30 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
|
14124
14309
|
]);
|
|
14125
14310
|
var routes = new Command105("routes").description("list routes").configureHelp(helpConfig).action(async () => {
|
|
14126
14311
|
const { workspaceRootDir, routesDir } = await getWorkspace();
|
|
14127
|
-
const routesRoot =
|
|
14312
|
+
const routesRoot = path59.join(workspaceRootDir, routesDir);
|
|
14128
14313
|
const found = walk(routesRoot, routesRoot).filter((r) => r.methods.length > 0);
|
|
14129
14314
|
found.sort((a, b) => a.urlPattern.localeCompare(b.urlPattern));
|
|
14130
14315
|
printTable(found);
|
|
14131
14316
|
});
|
|
14132
14317
|
function walk(root, dir) {
|
|
14133
|
-
const entries =
|
|
14318
|
+
const entries = fs54.readdirSync(dir, { withFileTypes: true });
|
|
14134
14319
|
const routes2 = [];
|
|
14135
14320
|
const hasLeaf = entries.some((e) => e.isFile() && isRouteFile(e.name));
|
|
14136
14321
|
if (hasLeaf) {
|
|
14137
|
-
const id = "/" +
|
|
14322
|
+
const id = "/" + path59.relative(root, dir).split(path59.sep).filter(Boolean).join("/");
|
|
14138
14323
|
const urlPattern = id.replace(/\([^)]+\)\/?/g, "").replace(/\/$/, "") || "/";
|
|
14139
14324
|
const methods = /* @__PURE__ */ new Set();
|
|
14140
14325
|
for (const entry of entries) {
|
|
14141
14326
|
if (!entry.isFile()) continue;
|
|
14142
14327
|
if (entry.name.endsWith("+page.svelte")) methods.add("GET");
|
|
14143
14328
|
if (entry.name.endsWith("+server.ts") || entry.name.endsWith("+server.js") || entry.name.endsWith("+page.server.ts") || entry.name.endsWith("+page.server.js")) {
|
|
14144
|
-
extractMethods(
|
|
14329
|
+
extractMethods(path59.join(dir, entry.name)).forEach((m) => methods.add(m));
|
|
14145
14330
|
}
|
|
14146
14331
|
}
|
|
14147
14332
|
routes2.push({ id: id || "/", urlPattern, methods: [...methods] });
|
|
14148
14333
|
}
|
|
14149
14334
|
for (const entry of entries) {
|
|
14150
|
-
if (entry.isDirectory()) routes2.push(...walk(root,
|
|
14335
|
+
if (entry.isDirectory()) routes2.push(...walk(root, path59.join(dir, entry.name)));
|
|
14151
14336
|
}
|
|
14152
14337
|
return routes2;
|
|
14153
14338
|
}
|
|
@@ -14156,7 +14341,7 @@ function isRouteFile(name) {
|
|
|
14156
14341
|
}
|
|
14157
14342
|
function extractMethods(file) {
|
|
14158
14343
|
try {
|
|
14159
|
-
const content =
|
|
14344
|
+
const content = fs54.readFileSync(file, "utf8");
|
|
14160
14345
|
const methods = [];
|
|
14161
14346
|
const exportRegex = /export\s+(?:const|async\s+function|function)\s+(\w+)/g;
|
|
14162
14347
|
let match;
|
|
@@ -14197,8 +14382,8 @@ function printTable(routes2) {
|
|
|
14197
14382
|
}
|
|
14198
14383
|
|
|
14199
14384
|
// src/commands/i18n.ts
|
|
14200
|
-
import
|
|
14201
|
-
import
|
|
14385
|
+
import fs55 from "node:fs";
|
|
14386
|
+
import path60 from "node:path";
|
|
14202
14387
|
import process44 from "node:process";
|
|
14203
14388
|
import { Command as Command106 } from "commander";
|
|
14204
14389
|
import { x as x7 } from "tinyexec";
|
|
@@ -14207,7 +14392,7 @@ import { resolveCommand as resolveCommand8 } from "package-manager-detector/comm
|
|
|
14207
14392
|
var WUCHALE_CONFIG_NAMES = ["js", "mjs", "ts", "mts"].map((ext) => `wuchale.config.${ext}`);
|
|
14208
14393
|
async function runWuchale(extraArgs) {
|
|
14209
14394
|
const cwd = findWorkspaceRoot() ?? process44.cwd();
|
|
14210
|
-
if (!WUCHALE_CONFIG_NAMES.some((name) =>
|
|
14395
|
+
if (!WUCHALE_CONFIG_NAMES.some((name) => fs55.existsSync(path60.join(cwd, name)))) {
|
|
14211
14396
|
throw new Error("No wuchale config found. Run `vela enable i18n` to set up i18n.");
|
|
14212
14397
|
}
|
|
14213
14398
|
const pm = (await detect10({ cwd }))?.name ?? "npm";
|
|
@@ -14335,7 +14520,7 @@ import pc39 from "picocolors";
|
|
|
14335
14520
|
|
|
14336
14521
|
// src/lib/cms-backend.ts
|
|
14337
14522
|
import { createRequire as createRequire4 } from "node:module";
|
|
14338
|
-
import
|
|
14523
|
+
import path61 from "node:path";
|
|
14339
14524
|
import process46 from "node:process";
|
|
14340
14525
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
14341
14526
|
import pc38 from "picocolors";
|
|
@@ -14343,7 +14528,7 @@ var DEFAULT_PROJECT = "default";
|
|
|
14343
14528
|
async function loadBackendModule(root) {
|
|
14344
14529
|
let entry;
|
|
14345
14530
|
try {
|
|
14346
|
-
entry = createRequire4(
|
|
14531
|
+
entry = createRequire4(path61.join(root, "package.json")).resolve("@velastack/cms/backend");
|
|
14347
14532
|
} catch {
|
|
14348
14533
|
throw new Error(
|
|
14349
14534
|
`@velastack/cms is not installed in this project.
|
|
@@ -14361,8 +14546,8 @@ async function withCmsBackend(fn, cwd = process46.cwd()) {
|
|
|
14361
14546
|
const { createCmsBackend } = await loadBackendModule(root);
|
|
14362
14547
|
const dataDir2 = localDataDir(root);
|
|
14363
14548
|
const backend3 = createCmsBackend({
|
|
14364
|
-
dbPath:
|
|
14365
|
-
uploadDir:
|
|
14549
|
+
dbPath: path61.join(dataDir2, "cms.sqlite"),
|
|
14550
|
+
uploadDir: path61.join(dataDir2, "uploads")
|
|
14366
14551
|
});
|
|
14367
14552
|
try {
|
|
14368
14553
|
return await fn(backend3);
|
|
@@ -14644,14 +14829,14 @@ var program = new Command117().name(package_default.name).description(package_de
|
|
|
14644
14829
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
14645
14830
|
const envRoot = findWorkspaceRoot() ?? process50.cwd();
|
|
14646
14831
|
dotenv2.config({ path: nodePath.join(envRoot, ".env"), quiet: true });
|
|
14647
|
-
const
|
|
14648
|
-
if (NO_BACKEND_COMMMANDS.has(
|
|
14649
|
-
const top =
|
|
14832
|
+
const path62 = getCommandPath(actionCommand);
|
|
14833
|
+
if (NO_BACKEND_COMMMANDS.has(path62)) return;
|
|
14834
|
+
const top = path62.split(" ", 1)[0];
|
|
14650
14835
|
if (NO_BACKEND_COMMMANDS.has(top)) return;
|
|
14651
14836
|
if (!hasBackend()) {
|
|
14652
14837
|
if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
|
|
14653
14838
|
p72.log.error(
|
|
14654
|
-
`${pc45.cyan(`vela ${
|
|
14839
|
+
`${pc45.cyan(`vela ${path62}`)} needs a backend, and this project does not have one.
|
|
14655
14840
|
|
|
14656
14841
|
There is no PocketBase database here for it to talk to.
|
|
14657
14842
|
|
|
@@ -14661,7 +14846,7 @@ To add one, run ${pc45.cyan("vela enable backend")}.`
|
|
|
14661
14846
|
p72.cancel("Operation failed.");
|
|
14662
14847
|
process50.exit(1);
|
|
14663
14848
|
}
|
|
14664
|
-
if (SELF_CREDENTIALED_COMMANDS.has(
|
|
14849
|
+
if (SELF_CREDENTIALED_COMMANDS.has(path62)) return;
|
|
14665
14850
|
if (!process50.env.POCKETBASE_SUPERUSER_EMAIL || !process50.env.POCKETBASE_SUPERUSER_PASSWORD) {
|
|
14666
14851
|
p72.log.error(
|
|
14667
14852
|
`PocketBase superuser credentials are required.
|