spfn 0.2.0-beta.59 → 0.2.0-beta.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.js +166 -70
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -184,6 +184,16 @@ loaded `.env` chain.
|
|
|
184
184
|
> `db push` is for development. For production, use `db generate` + `db migrate` to keep
|
|
185
185
|
> migration history.
|
|
186
186
|
|
|
187
|
+
`db push` and `db migrate` also replay migrations shipped by installed SPFN function
|
|
188
|
+
packages (`@spfn/auth`, `@spfn/cms`, …) into per-package tracking tables
|
|
189
|
+
(`drizzle.__spfn_fn_<pkg>_migrations`). The CLI applies these with a built-in runner
|
|
190
|
+
that reads both migration layouts — drizzle-kit ≤0.31 (`NNNN_name.sql` +
|
|
191
|
+
`meta/_journal.json`) and drizzle-kit 1.0 (`<timestamp>_name/migration.sql`) — so a
|
|
192
|
+
package's layout never has to match the CLI's bundled drizzle version. `db push`
|
|
193
|
+
validates every package's migration folder before applying the project schema, and a
|
|
194
|
+
function-migration failure after a successful schema apply exits 1 with a message
|
|
195
|
+
making clear the project schema was already committed.
|
|
196
|
+
|
|
187
197
|
Database TLS is controlled by `DATABASE_URL`. Loopback URLs (`localhost`, `127.0.0.1`,
|
|
188
198
|
and `::1`) default to `ssl: false`; add an explicit `sslmode` when the local server uses
|
|
189
199
|
TLS. For a TLS connection with a self-signed certificate, set
|
package/dist/index.js
CHANGED
|
@@ -869,7 +869,7 @@ var init_deployment_config = __esm({
|
|
|
869
869
|
|
|
870
870
|
// src/utils/version.ts
|
|
871
871
|
function getCliVersion() {
|
|
872
|
-
return "0.2.0-beta.
|
|
872
|
+
return "0.2.0-beta.60";
|
|
873
873
|
}
|
|
874
874
|
function getTagFromVersion(version) {
|
|
875
875
|
const match = version.match(/-([a-z]+)\./i);
|
|
@@ -1336,10 +1336,14 @@ var init_init = __esm({
|
|
|
1336
1336
|
// src/utils/function-migrations.ts
|
|
1337
1337
|
var function_migrations_exports = {};
|
|
1338
1338
|
__export(function_migrations_exports, {
|
|
1339
|
+
applyFunctionMigrationPlan: () => applyFunctionMigrationPlan,
|
|
1339
1340
|
discoverFunctionMigrations: () => discoverFunctionMigrations,
|
|
1340
|
-
executeFunctionMigrations: () => executeFunctionMigrations
|
|
1341
|
+
executeFunctionMigrations: () => executeFunctionMigrations,
|
|
1342
|
+
loadFunctionMigrationPlans: () => loadFunctionMigrationPlans,
|
|
1343
|
+
readMigrationEntries: () => readMigrationEntries
|
|
1341
1344
|
});
|
|
1342
1345
|
import chalk13 from "chalk";
|
|
1346
|
+
import { createHash } from "crypto";
|
|
1343
1347
|
import { join as join19 } from "path";
|
|
1344
1348
|
import { env as env2 } from "@spfn/core/config";
|
|
1345
1349
|
import { loadEnv as loadEnv2 } from "@spfn/core/server";
|
|
@@ -1385,8 +1389,75 @@ function discoverFunctionMigrations(cwd = process.cwd()) {
|
|
|
1385
1389
|
}
|
|
1386
1390
|
return functions;
|
|
1387
1391
|
}
|
|
1388
|
-
|
|
1389
|
-
const
|
|
1392
|
+
function readMigrationEntries(migrationsDir, packageName) {
|
|
1393
|
+
const journalPath = join19(migrationsDir, "meta", "_journal.json");
|
|
1394
|
+
return existsSync19(journalPath) ? readJournalEntries(migrationsDir, journalPath, packageName) : readFolderEntries(migrationsDir, packageName);
|
|
1395
|
+
}
|
|
1396
|
+
function loadFunctionMigrationPlans(functionMigrations) {
|
|
1397
|
+
return functionMigrations.map((func) => ({
|
|
1398
|
+
...func,
|
|
1399
|
+
entries: readMigrationEntries(func.migrationsDir, func.packageName)
|
|
1400
|
+
}));
|
|
1401
|
+
}
|
|
1402
|
+
function readJournalEntries(migrationsDir, journalPath, packageName) {
|
|
1403
|
+
let journal;
|
|
1404
|
+
try {
|
|
1405
|
+
journal = JSON.parse(readFileSync9(journalPath, "utf-8"));
|
|
1406
|
+
} catch {
|
|
1407
|
+
journal = {};
|
|
1408
|
+
}
|
|
1409
|
+
if (!Array.isArray(journal.entries)) {
|
|
1410
|
+
throw new Error(`${packageName}: invalid migration journal at ${journalPath}`);
|
|
1411
|
+
}
|
|
1412
|
+
const entries = [...journal.entries];
|
|
1413
|
+
entries.sort((a, b) => a.idx - b.idx);
|
|
1414
|
+
return entries.map((entry) => {
|
|
1415
|
+
if (typeof entry?.tag !== "string" || typeof entry?.when !== "number") {
|
|
1416
|
+
throw new Error(`${packageName}: invalid journal entry in ${journalPath}`);
|
|
1417
|
+
}
|
|
1418
|
+
const sqlPath = join19(migrationsDir, `${entry.tag}.sql`);
|
|
1419
|
+
if (!existsSync19(sqlPath)) {
|
|
1420
|
+
throw new Error(`${packageName}: migration file not found: ${entry.tag}.sql`);
|
|
1421
|
+
}
|
|
1422
|
+
return toEntry(entry.tag, readFileSync9(sqlPath, "utf-8"), entry.when);
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1425
|
+
function readFolderEntries(migrationsDir, packageName) {
|
|
1426
|
+
const folders = readdirSync2(migrationsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).filter((name) => existsSync19(join19(migrationsDir, name, "migration.sql"))).sort((a, b) => a.localeCompare(b));
|
|
1427
|
+
return folders.map((name) => toEntry(
|
|
1428
|
+
name,
|
|
1429
|
+
readFileSync9(join19(migrationsDir, name, "migration.sql"), "utf-8"),
|
|
1430
|
+
folderTimestampMillis(name, packageName)
|
|
1431
|
+
));
|
|
1432
|
+
}
|
|
1433
|
+
function folderTimestampMillis(name, packageName) {
|
|
1434
|
+
const match = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/.exec(name);
|
|
1435
|
+
if (!match) {
|
|
1436
|
+
throw new Error(`${packageName}: migration folder name must start with a YYYYMMDDHHMMSS timestamp: ${name}`);
|
|
1437
|
+
}
|
|
1438
|
+
const [, year, month, day, hour, minute, second] = match;
|
|
1439
|
+
return Date.UTC(
|
|
1440
|
+
Number(year),
|
|
1441
|
+
Number(month) - 1,
|
|
1442
|
+
Number(day),
|
|
1443
|
+
Number(hour),
|
|
1444
|
+
Number(minute),
|
|
1445
|
+
Number(second)
|
|
1446
|
+
);
|
|
1447
|
+
}
|
|
1448
|
+
function toEntry(name, content, millis) {
|
|
1449
|
+
return {
|
|
1450
|
+
name,
|
|
1451
|
+
millis,
|
|
1452
|
+
hash: createHash("sha256").update(content).digest("hex"),
|
|
1453
|
+
statements: content.split("--> statement-breakpoint").map((statement) => statement.trim()).filter((statement) => statement.length > 0)
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
function functionMigrationsTable(packageName) {
|
|
1457
|
+
return `__spfn_fn_${packageName.replace("@spfn/", "")}_migrations`;
|
|
1458
|
+
}
|
|
1459
|
+
async function migrateLegacyTable(db, plans) {
|
|
1460
|
+
const legacyCheck = await db.query(
|
|
1390
1461
|
`SELECT EXISTS (
|
|
1391
1462
|
SELECT 1 FROM information_schema.tables
|
|
1392
1463
|
WHERE table_schema = 'drizzle' AND table_name = '__spfn_fn_migrations'
|
|
@@ -1396,89 +1467,103 @@ async function migrateLegacyTable(db, functionMigrations) {
|
|
|
1396
1467
|
return;
|
|
1397
1468
|
}
|
|
1398
1469
|
console.log(chalk13.dim("\n Migrating legacy shared migration table to per-package tables..."));
|
|
1399
|
-
const legacyRows = await db.
|
|
1470
|
+
const legacyRows = await db.query(
|
|
1400
1471
|
`SELECT hash, created_at FROM drizzle."__spfn_fn_migrations" ORDER BY id`
|
|
1401
1472
|
);
|
|
1402
1473
|
if (legacyRows.length === 0) {
|
|
1403
|
-
await db.
|
|
1474
|
+
await db.query(`DROP TABLE drizzle."__spfn_fn_migrations"`);
|
|
1404
1475
|
return;
|
|
1405
1476
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
const journal = JSON.parse(readFileSync9(journalPath, "utf-8"));
|
|
1412
|
-
const entries = journal.entries || [];
|
|
1413
|
-
const tableName = `__spfn_fn_${func.packageName.replace("@spfn/", "")}_migrations`;
|
|
1414
|
-
await db.execute(
|
|
1415
|
-
`CREATE SCHEMA IF NOT EXISTS drizzle`
|
|
1416
|
-
);
|
|
1417
|
-
await db.execute(
|
|
1418
|
-
`CREATE TABLE IF NOT EXISTS drizzle."${tableName}" (
|
|
1419
|
-
id serial PRIMARY KEY,
|
|
1420
|
-
hash text NOT NULL,
|
|
1421
|
-
created_at bigint
|
|
1422
|
-
)`
|
|
1423
|
-
);
|
|
1424
|
-
const existing = await db.execute(
|
|
1477
|
+
const legacyHashes = new Set(legacyRows.map((row) => row.hash));
|
|
1478
|
+
for (const plan of plans) {
|
|
1479
|
+
const tableName = functionMigrationsTable(plan.packageName);
|
|
1480
|
+
await ensureMigrationsTable(db, tableName);
|
|
1481
|
+
const existing = await db.query(
|
|
1425
1482
|
`SELECT COUNT(*) AS "count" FROM drizzle."${tableName}"`
|
|
1426
1483
|
);
|
|
1427
1484
|
if (Number(existing[0]?.count) > 0) {
|
|
1428
1485
|
continue;
|
|
1429
1486
|
}
|
|
1430
|
-
const { createHash } = await import("crypto");
|
|
1431
1487
|
let copied = 0;
|
|
1432
|
-
for (const entry of entries) {
|
|
1433
|
-
|
|
1434
|
-
if (!existsSync19(sqlPath)) {
|
|
1488
|
+
for (const entry of plan.entries) {
|
|
1489
|
+
if (!legacyHashes.has(entry.hash)) {
|
|
1435
1490
|
continue;
|
|
1436
1491
|
}
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
`INSERT INTO drizzle."${tableName}" (hash, created_at) VALUES ('${hash}', ${entry.when})`
|
|
1443
|
-
);
|
|
1444
|
-
copied++;
|
|
1445
|
-
}
|
|
1492
|
+
await db.query(
|
|
1493
|
+
`INSERT INTO drizzle."${tableName}" (hash, created_at) VALUES ($1, $2)`,
|
|
1494
|
+
[entry.hash, entry.millis]
|
|
1495
|
+
);
|
|
1496
|
+
copied++;
|
|
1446
1497
|
}
|
|
1447
1498
|
if (copied > 0) {
|
|
1448
|
-
console.log(chalk13.dim(` \u2713 ${
|
|
1499
|
+
console.log(chalk13.dim(` \u2713 ${plan.packageName}: copied ${copied} migration record(s)`));
|
|
1449
1500
|
}
|
|
1450
1501
|
}
|
|
1451
|
-
await db.
|
|
1502
|
+
await db.query(`DROP TABLE drizzle."__spfn_fn_migrations"`);
|
|
1452
1503
|
console.log(chalk13.dim(" \u2713 Legacy migration table removed\n"));
|
|
1453
1504
|
}
|
|
1454
|
-
async function
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1505
|
+
async function ensureMigrationsTable(db, tableName) {
|
|
1506
|
+
await db.query(`CREATE SCHEMA IF NOT EXISTS drizzle`);
|
|
1507
|
+
await db.query(
|
|
1508
|
+
`CREATE TABLE IF NOT EXISTS drizzle."${tableName}" (
|
|
1509
|
+
id serial PRIMARY KEY,
|
|
1510
|
+
hash text NOT NULL,
|
|
1511
|
+
created_at bigint
|
|
1512
|
+
)`
|
|
1513
|
+
);
|
|
1514
|
+
}
|
|
1515
|
+
async function applyFunctionMigrationPlan(db, plan) {
|
|
1516
|
+
const tableName = functionMigrationsTable(plan.packageName);
|
|
1517
|
+
await ensureMigrationsTable(db, tableName);
|
|
1518
|
+
const rows = await db.query(
|
|
1519
|
+
`SELECT created_at FROM drizzle."${tableName}" ORDER BY created_at DESC LIMIT 1`
|
|
1520
|
+
);
|
|
1521
|
+
const lastMillis = rows.length > 0 ? Number(rows[0]?.created_at) : Number.NEGATIVE_INFINITY;
|
|
1522
|
+
const pending = plan.entries.filter((entry) => entry.millis > lastMillis);
|
|
1523
|
+
if (pending.length === 0) {
|
|
1524
|
+
return 0;
|
|
1525
|
+
}
|
|
1526
|
+
await db.transaction(async (tx) => {
|
|
1527
|
+
for (const entry of pending) {
|
|
1528
|
+
for (const statement of entry.statements) {
|
|
1529
|
+
await tx.query(statement);
|
|
1530
|
+
}
|
|
1531
|
+
await tx.query(
|
|
1532
|
+
`INSERT INTO drizzle."${tableName}" (hash, created_at) VALUES ($1, $2)`,
|
|
1533
|
+
[entry.hash, entry.millis]
|
|
1534
|
+
);
|
|
1535
|
+
}
|
|
1536
|
+
});
|
|
1537
|
+
return pending.length;
|
|
1538
|
+
}
|
|
1539
|
+
function createPostgresJsMigrationDb(client) {
|
|
1540
|
+
return {
|
|
1541
|
+
query: (text, params) => client.unsafe(text, params ?? []),
|
|
1542
|
+
transaction: (fn) => client.begin((tx) => fn(createPostgresJsMigrationDb(tx)))
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
async function executeFunctionMigrations(plans) {
|
|
1458
1546
|
const postgres = await import("postgres");
|
|
1459
1547
|
loadEnv2();
|
|
1460
1548
|
if (!env2.DATABASE_URL) {
|
|
1461
1549
|
throw new Error("DATABASE_URL not found in environment");
|
|
1462
1550
|
}
|
|
1463
1551
|
const connection = postgres.default(env2.DATABASE_URL, { max: 1 });
|
|
1464
|
-
const db =
|
|
1552
|
+
const db = createPostgresJsMigrationDb(connection);
|
|
1553
|
+
let appliedCount = 0;
|
|
1465
1554
|
try {
|
|
1466
|
-
await migrateLegacyTable(db,
|
|
1467
|
-
for (const
|
|
1555
|
+
await migrateLegacyTable(db, plans);
|
|
1556
|
+
for (const plan of plans) {
|
|
1468
1557
|
console.log(chalk13.blue(`
|
|
1469
|
-
\u{1F4E6} Running ${
|
|
1470
|
-
const
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
migrationsTable: tableName
|
|
1474
|
-
});
|
|
1475
|
-
console.log(chalk13.green(` \u2713 ${func.packageName} migrations applied`));
|
|
1476
|
-
executedCount++;
|
|
1558
|
+
\u{1F4E6} Running ${plan.packageName} migrations...`));
|
|
1559
|
+
const applied = await applyFunctionMigrationPlan(db, plan);
|
|
1560
|
+
console.log(applied > 0 ? chalk13.green(` \u2713 ${plan.packageName}: ${applied} migration(s) applied`) : chalk13.dim(` \u2013 ${plan.packageName}: up to date`));
|
|
1561
|
+
appliedCount += applied;
|
|
1477
1562
|
}
|
|
1478
1563
|
} finally {
|
|
1479
1564
|
await connection.end();
|
|
1480
1565
|
}
|
|
1481
|
-
return
|
|
1566
|
+
return appliedCount;
|
|
1482
1567
|
}
|
|
1483
1568
|
var init_function_migrations = __esm({
|
|
1484
1569
|
"src/utils/function-migrations.ts"() {
|
|
@@ -3039,6 +3124,7 @@ function displayApplySummary(applied, skipped) {
|
|
|
3039
3124
|
}
|
|
3040
3125
|
|
|
3041
3126
|
// src/commands/db/push.ts
|
|
3127
|
+
init_function_migrations();
|
|
3042
3128
|
async function resolvePushPlan(imports, db, schemaFilter) {
|
|
3043
3129
|
const { pushSchema } = await import("drizzle-kit/api-postgres");
|
|
3044
3130
|
const { sqlStatements, hints } = await pushSchema(
|
|
@@ -3094,6 +3180,7 @@ async function dbPush(options = {}) {
|
|
|
3094
3180
|
}
|
|
3095
3181
|
}
|
|
3096
3182
|
const schemaFilter = Array.from(detectedSchemas);
|
|
3183
|
+
const functionPlans = loadFunctionPlansOrExit();
|
|
3097
3184
|
const { db, close } = await createPushConnection();
|
|
3098
3185
|
try {
|
|
3099
3186
|
const { statements, hints } = await resolvePushPlan(imports, db, schemaFilter);
|
|
@@ -3102,7 +3189,7 @@ async function dbPush(options = {}) {
|
|
|
3102
3189
|
}
|
|
3103
3190
|
if (statements.length === 0) {
|
|
3104
3191
|
console.log(chalk14.green("\u2705 No changes detected \u2014 database is up to date\n"));
|
|
3105
|
-
await applyFunctionMigrations();
|
|
3192
|
+
await applyFunctionMigrations(functionPlans);
|
|
3106
3193
|
return;
|
|
3107
3194
|
}
|
|
3108
3195
|
const result = classifyStatements(statements);
|
|
@@ -3144,27 +3231,36 @@ async function dbPush(options = {}) {
|
|
|
3144
3231
|
console.log(chalk14.dim("Tip: Use --force to apply all changes without prompting.\n"));
|
|
3145
3232
|
}
|
|
3146
3233
|
}
|
|
3147
|
-
await applyFunctionMigrations();
|
|
3234
|
+
await applyFunctionMigrations(functionPlans);
|
|
3148
3235
|
} finally {
|
|
3149
3236
|
await close();
|
|
3150
3237
|
}
|
|
3151
3238
|
}
|
|
3152
|
-
|
|
3153
|
-
const
|
|
3154
|
-
|
|
3155
|
-
|
|
3239
|
+
function loadFunctionPlansOrExit() {
|
|
3240
|
+
const functions = discoverFunctionMigrations(process.cwd());
|
|
3241
|
+
try {
|
|
3242
|
+
return loadFunctionMigrationPlans(functions);
|
|
3243
|
+
} catch (error) {
|
|
3244
|
+
console.error(chalk14.red("\n\u274C Invalid function package migrations \u2014 nothing was applied"));
|
|
3245
|
+
console.error(chalk14.red(error instanceof Error ? error.message : "Unknown error"));
|
|
3246
|
+
process.exit(1);
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
async function applyFunctionMigrations(plans) {
|
|
3250
|
+
if (plans.length === 0) {
|
|
3156
3251
|
return;
|
|
3157
3252
|
}
|
|
3158
3253
|
console.log(chalk14.blue("\n\u{1F4E6} Applying function package migrations:"));
|
|
3159
|
-
|
|
3160
|
-
console.log(chalk14.dim(` - ${
|
|
3254
|
+
plans.forEach((plan) => {
|
|
3255
|
+
console.log(chalk14.dim(` - ${plan.packageName}`));
|
|
3161
3256
|
});
|
|
3162
3257
|
try {
|
|
3163
|
-
await
|
|
3258
|
+
await executeFunctionMigrations(plans);
|
|
3164
3259
|
console.log(chalk14.green("\n\u2705 All function migrations applied\n"));
|
|
3165
3260
|
} catch (error) {
|
|
3166
|
-
console.error(chalk14.red("\n\u274C Failed to apply function migrations"));
|
|
3261
|
+
console.error(chalk14.red("\n\u274C Failed to apply function package migrations"));
|
|
3167
3262
|
console.error(chalk14.red(error instanceof Error ? error.message : "Unknown error"));
|
|
3263
|
+
console.error(chalk14.yellow("Project schema changes (if any) were already applied \u2014 only function package migrations failed."));
|
|
3168
3264
|
process.exit(1);
|
|
3169
3265
|
}
|
|
3170
3266
|
}
|
|
@@ -3571,14 +3667,14 @@ async function dbMigrate(options = {}) {
|
|
|
3571
3667
|
console.error(chalk19.red("\u274C DATABASE_URL not found in environment"));
|
|
3572
3668
|
process.exit(1);
|
|
3573
3669
|
}
|
|
3574
|
-
const { discoverFunctionMigrations: discoverFunctionMigrations2, executeFunctionMigrations: executeFunctionMigrations2 } = await Promise.resolve().then(() => (init_function_migrations(), function_migrations_exports));
|
|
3670
|
+
const { discoverFunctionMigrations: discoverFunctionMigrations2, loadFunctionMigrationPlans: loadFunctionMigrationPlans2, executeFunctionMigrations: executeFunctionMigrations2 } = await Promise.resolve().then(() => (init_function_migrations(), function_migrations_exports));
|
|
3575
3671
|
const functions = discoverFunctionMigrations2(process.cwd());
|
|
3576
3672
|
if (functions.length > 0) {
|
|
3577
3673
|
console.log(chalk19.blue("\u{1F4E6} Applying function package migrations:"));
|
|
3578
3674
|
functions.forEach((func) => {
|
|
3579
3675
|
console.log(chalk19.dim(` - ${func.packageName}`));
|
|
3580
3676
|
});
|
|
3581
|
-
await executeFunctionMigrations2(functions);
|
|
3677
|
+
await executeFunctionMigrations2(loadFunctionMigrationPlans2(functions));
|
|
3582
3678
|
console.log(chalk19.green("\u2705 Function migrations applied\n"));
|
|
3583
3679
|
}
|
|
3584
3680
|
const projectMigrationsDir = join20(process.cwd(), "src/server/drizzle");
|
|
@@ -4227,13 +4323,13 @@ async function addPackage(packageName) {
|
|
|
4227
4323
|
console.log(chalk27.gray("Skipping database setup. Run migrations manually when ready:\n"));
|
|
4228
4324
|
console.log(chalk27.gray(" pnpm spfn db push\n"));
|
|
4229
4325
|
} else {
|
|
4230
|
-
const { discoverFunctionMigrations: discoverFunctionMigrations2, executeFunctionMigrations: executeFunctionMigrations2 } = await Promise.resolve().then(() => (init_function_migrations(), function_migrations_exports));
|
|
4326
|
+
const { discoverFunctionMigrations: discoverFunctionMigrations2, loadFunctionMigrationPlans: loadFunctionMigrationPlans2, executeFunctionMigrations: executeFunctionMigrations2 } = await Promise.resolve().then(() => (init_function_migrations(), function_migrations_exports));
|
|
4231
4327
|
const functions = discoverFunctionMigrations2(process.cwd());
|
|
4232
4328
|
const targetFunction = functions.find((f) => f.packageName === packageName);
|
|
4233
4329
|
if (targetFunction) {
|
|
4234
4330
|
const spinner = ora11("Applying migrations...").start();
|
|
4235
4331
|
try {
|
|
4236
|
-
await executeFunctionMigrations2([targetFunction]);
|
|
4332
|
+
await executeFunctionMigrations2(loadFunctionMigrationPlans2([targetFunction]));
|
|
4237
4333
|
spinner.succeed("Migrations applied");
|
|
4238
4334
|
} catch (error) {
|
|
4239
4335
|
spinner.fail("Failed to apply migrations");
|