@cedarjs/cli-data-migrate 7.0.0-canary.3258 → 7.0.0-rc.123
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 +3 -3
- package/dist/commands/installHandler.js +1 -1
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +8 -3
- package/dist/commands/upHandler.d.ts.map +1 -1
- package/dist/commands/upHandler.js +22 -116
- package/dist/commands/upHandlerEsm.d.ts +4 -0
- package/dist/commands/upHandlerEsm.d.ts.map +1 -0
- package/dist/commands/upHandlerEsm.js +275 -0
- package/package.json +8 -7
package/dist/bin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
${
|
|
4
|
-
`)),process.exitCode=0
|
|
2
|
+
var j=(t,i,r)=>()=>{if(r)throw r[0];try{return t&&(i=t(t=0)),i}catch(a){throw r=[a],a}};import g from"node:fs";import{createRequire as C}from"node:module";import c from"node:path";import{Listr as S}from"listr2";import{registerApiSideBabelHook as D}from"@cedarjs/babel-config";import{colors as m}from"@cedarjs/cli-helpers";import{getPaths as b,getDataMigrationsPath as $}from"@cedarjs/project-config";async function y({importDbClientFromDist:t,distPath:i}){let r,a=!1;if(t){if(!g.existsSync(i)){console.warn(`Can't find api dist at ${i}. You may need to build first: yarn cedar build api`),process.exitCode=1;return}let s=c.join(i,"lib"),d=c.join(s,"db.js");if(!g.existsSync(d)){console.error(`Can't find db.js at ${d}. CedarJS expects the db.js file to be in the ${s} directory`),process.exitCode=1;return}r=(await import(d)).db}else D(),a=!0,r=h(c.join(b().api.lib,"db")).db;let n=await P(r);if(!n.length){console.info(m.success(`
|
|
3
|
+
${L}
|
|
4
|
+
`)),process.exitCode=0;return}let o={run:0,skipped:0,error:0},e=n.map(s=>{let d=c.basename(s.path,".js");return{title:d,skip(){return o.error>0?(o.skipped++,!0):!1},async task(){a||D();try{let{startedAt:f,finishedAt:A}=await I(r,s.path);o.run++,await R(r,{version:s.version,name:d,startedAt:f,finishedAt:A})}catch(f){o.error++,console.error(m.error(`Error in data migration: ${f.message}`))}}}}),p=new S(e,{renderer:"verbose"});try{await p.run(),await r.$disconnect(),console.log(),M(o),console.log(),o.error&&(process.exitCode=1)}catch{process.exitCode=1,await r.$disconnect(),console.log(),M(o),console.log()}}async function P(t){let i=await $(b().api.prismaConfig);if(!g.existsSync(i))return[];let r=g.readdirSync(i).filter(e=>["js",".ts"].some(p=>e.endsWith(p))).map(e=>{let[p]=e.split("-");return{version:p,path:c.join(i,e)}}),n=(await t.rW_DataMigration.findMany({orderBy:{version:"asc"}})).map(e=>e.version.toString());return r.filter(({version:e})=>!n.includes(e)).sort(_)}function _(t,i){let r=parseInt(t.version),a=parseInt(i.version);return r>a?1:r<a?-1:0}async function I(t,i){let r=h(i),a=new Date;return await r.default({db:t}),{startedAt:a,finishedAt:new Date}}async function R(t,{version:i,name:r,startedAt:a,finishedAt:n}){await t.rW_DataMigration.create({data:{version:i,name:r,startedAt:a,finishedAt:n}})}function M(t){t.run&&console.info(m.success(`${t.run} data migration(s) completed successfully.`)),t.error&&console.error(m.error(`${t.error} data migration(s) exited with errors.`)),t.skipped&&console.warn(m.warning(`${t.skipped} data migration(s) skipped due to previous error.`))}var h,L,w=j(()=>{"use strict";h=C(import.meta.url);L="No pending data migrations run, already up-to-date."});import v from"path";import{config as N}from"dotenv-defaults";import{hideBin as O}from"yargs/helpers";import U from"yargs/yargs";import{getPaths as x}from"@cedarjs/project-config";import{terminalLink as k}from"termi-link";import{getPaths as E,projectIsEsm as W}from"@cedarjs/project-config";var l="Run any outstanding Data Migrations against the database";function u(t){return t.option("import-db-client-from-dist",{type:"boolean",alias:["db-from-dist"],description:"Import the db client from dist",default:!1}).option("dist-path",{type:"string",alias:"d",description:"Path to the api dist directory",default:E().api.dist}).epilogue(`Also see the ${k("CedarJS CLI Reference","https://cedarjs.com/docs/cli-commands#datamigrate-up")}`)}w();process.env.CEDAR_ENV_FILES_LOADED||(N({path:v.join(x().base,".env"),defaults:v.join(x().base,".env.defaults"),multiline:!0}),process.env.CEDAR_ENV_FILES_LOADED="true");U(O(process.argv)).scriptName("data-migrate").command("$0",l,u,y).parse();
|
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import execa from "execa";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
|
-
import { colors as c } from "@cedarjs/cli-helpers
|
|
5
|
+
import { colors as c } from "@cedarjs/cli-helpers";
|
|
6
6
|
import {
|
|
7
7
|
getPaths,
|
|
8
8
|
getSchemaPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAIjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,eAAO,MAAM,OAAO,OAAO,CAAA;AAC3B,eAAO,MAAM,WAAW,6DACoC,CAAA;AAE5D,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAoBzC;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAIjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,eAAO,MAAM,OAAO,OAAO,CAAA;AAC3B,eAAO,MAAM,WAAW,6DACoC,CAAA;AAE5D,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAoBzC;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ1E"}
|
package/dist/commands/up.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { terminalLink } from "termi-link";
|
|
2
|
-
import { getPaths } from "@cedarjs/project-config";
|
|
2
|
+
import { getPaths, projectIsEsm } from "@cedarjs/project-config";
|
|
3
3
|
const command = "up";
|
|
4
4
|
const description = "Run any outstanding Data Migrations against the database";
|
|
5
5
|
function builder(yargs) {
|
|
@@ -21,8 +21,13 @@ function builder(yargs) {
|
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
async function handler(options) {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
if (projectIsEsm()) {
|
|
25
|
+
const { handler: dataMigrateUpHandler } = await import("./upHandlerEsm.js");
|
|
26
|
+
await dataMigrateUpHandler(options);
|
|
27
|
+
} else {
|
|
28
|
+
const { handler: dataMigrateUpHandler } = await import("./upHandler.js");
|
|
29
|
+
await dataMigrateUpHandler(options);
|
|
30
|
+
}
|
|
26
31
|
}
|
|
27
32
|
export {
|
|
28
33
|
builder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upHandler.d.ts","sourceRoot":"","sources":["../../src/commands/upHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upHandler.d.ts","sourceRoot":"","sources":["../../src/commands/upHandler.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,aAAa,CAAA;AA2BtE,wBAAsB,OAAO,CAAC,EAC5B,sBAAsB,EACtB,QAAQ,GACT,EAAE,oBAAoB,iBA2GtB;AA8ED,eAAO,MAAM,6BAA6B,wDACa,CAAA"}
|
|
@@ -1,97 +1,17 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { Listr } from "listr2";
|
|
4
|
-
import {
|
|
5
|
-
import { colors as c } from "@cedarjs/cli-helpers
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
getDataMigrationsPath,
|
|
9
|
-
resolveFile,
|
|
10
|
-
importStatementPath
|
|
11
|
-
} from "@cedarjs/project-config";
|
|
12
|
-
function resolveId(id) {
|
|
13
|
-
if (fs.existsSync(id) && fs.statSync(id).isFile()) {
|
|
14
|
-
return id;
|
|
15
|
-
}
|
|
16
|
-
const withoutExt = /\.jsx?$/.test(id) ? id.replace(/\.jsx?$/, "") : id;
|
|
17
|
-
for (const ext of [".ts", ".tsx", ".js", ".jsx"]) {
|
|
18
|
-
if (fs.existsSync(withoutExt + ext)) {
|
|
19
|
-
return withoutExt + ext;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
if (fs.existsSync(id) && fs.statSync(id).isDirectory()) {
|
|
23
|
-
for (const base of ["index", path.basename(id)]) {
|
|
24
|
-
for (const ext of [".ts", ".tsx", ".js", ".jsx"]) {
|
|
25
|
-
const candidate = path.join(id, base + ext);
|
|
26
|
-
if (fs.existsSync(candidate)) {
|
|
27
|
-
return candidate;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return id;
|
|
33
|
-
}
|
|
5
|
+
import { registerApiSideBabelHook } from "@cedarjs/babel-config";
|
|
6
|
+
import { colors as c } from "@cedarjs/cli-helpers";
|
|
7
|
+
import { getPaths, getDataMigrationsPath } from "@cedarjs/project-config";
|
|
8
|
+
const require2 = createRequire(import.meta.url);
|
|
34
9
|
async function handler({
|
|
35
10
|
importDbClientFromDist,
|
|
36
11
|
distPath
|
|
37
12
|
}) {
|
|
38
13
|
let db;
|
|
39
|
-
let
|
|
40
|
-
let cedarPlugins;
|
|
41
|
-
async function getRunner() {
|
|
42
|
-
if (!server) {
|
|
43
|
-
if (!cedarPlugins) {
|
|
44
|
-
const mod = await import("@cedarjs/vite");
|
|
45
|
-
cedarPlugins = mod;
|
|
46
|
-
}
|
|
47
|
-
server = await createServer({
|
|
48
|
-
mode: "production",
|
|
49
|
-
optimizeDeps: {
|
|
50
|
-
noDiscovery: true,
|
|
51
|
-
include: void 0
|
|
52
|
-
},
|
|
53
|
-
server: {
|
|
54
|
-
hmr: false,
|
|
55
|
-
watch: null
|
|
56
|
-
},
|
|
57
|
-
environments: {
|
|
58
|
-
nodeRunnerEnv: {}
|
|
59
|
-
},
|
|
60
|
-
resolve: {
|
|
61
|
-
alias: [
|
|
62
|
-
{
|
|
63
|
-
find: /^api\//,
|
|
64
|
-
replacement: getPaths().api.base + "/"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
find: /^src\//,
|
|
68
|
-
replacement: "src/",
|
|
69
|
-
customResolver: (id, importer, _options) => {
|
|
70
|
-
const apiImportBase = importStatementPath(getPaths().api.base);
|
|
71
|
-
if (importer?.startsWith(apiImportBase)) {
|
|
72
|
-
const apiImportSrc = importStatementPath(getPaths().api.src);
|
|
73
|
-
const apiId = id.replace("src", apiImportSrc);
|
|
74
|
-
return { id: resolveId(apiId) };
|
|
75
|
-
}
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
},
|
|
81
|
-
plugins: [
|
|
82
|
-
cedarPlugins.cedarCjsCompatPlugin(),
|
|
83
|
-
cedarPlugins.cedarjsResolveCedarStyleImportsPlugin(),
|
|
84
|
-
cedarPlugins.cedarImportDirPlugin(),
|
|
85
|
-
cedarPlugins.cedarAutoImportsPlugin()
|
|
86
|
-
]
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
const env = server.environments.nodeRunnerEnv;
|
|
90
|
-
if (!env || !isRunnableDevEnvironment(env)) {
|
|
91
|
-
throw new Error("Vite environment is not runnable.");
|
|
92
|
-
}
|
|
93
|
-
return env.runner;
|
|
94
|
-
}
|
|
14
|
+
let requireHookRegistered = false;
|
|
95
15
|
if (importDbClientFromDist) {
|
|
96
16
|
if (!fs.existsSync(distPath)) {
|
|
97
17
|
console.warn(
|
|
@@ -111,20 +31,9 @@ async function handler({
|
|
|
111
31
|
}
|
|
112
32
|
db = (await import(distLibDbPath)).db;
|
|
113
33
|
} else {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
process.exitCode = 1;
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
const runner = await getRunner();
|
|
122
|
-
const dbModule = await runner.import(dbPath);
|
|
123
|
-
db = dbModule.db;
|
|
124
|
-
} catch (e) {
|
|
125
|
-
await server?.close();
|
|
126
|
-
throw e;
|
|
127
|
-
}
|
|
34
|
+
registerApiSideBabelHook();
|
|
35
|
+
requireHookRegistered = true;
|
|
36
|
+
db = require2(path.join(getPaths().api.lib, "db")).db;
|
|
128
37
|
}
|
|
129
38
|
const pendingDataMigrations = await getPendingDataMigrations(db);
|
|
130
39
|
if (!pendingDataMigrations.length) {
|
|
@@ -132,7 +41,6 @@ async function handler({
|
|
|
132
41
|
${NO_PENDING_MIGRATIONS_MESSAGE}
|
|
133
42
|
`));
|
|
134
43
|
process.exitCode = 0;
|
|
135
|
-
await server?.close();
|
|
136
44
|
return;
|
|
137
45
|
}
|
|
138
46
|
const counters = { run: 0, skipped: 0, error: 0 };
|
|
@@ -149,6 +57,9 @@ ${NO_PENDING_MIGRATIONS_MESSAGE}
|
|
|
149
57
|
}
|
|
150
58
|
},
|
|
151
59
|
async task() {
|
|
60
|
+
if (!requireHookRegistered) {
|
|
61
|
+
registerApiSideBabelHook();
|
|
62
|
+
}
|
|
152
63
|
try {
|
|
153
64
|
const { startedAt, finishedAt } = await runDataMigration(
|
|
154
65
|
db,
|
|
@@ -163,8 +74,9 @@ ${NO_PENDING_MIGRATIONS_MESSAGE}
|
|
|
163
74
|
});
|
|
164
75
|
} catch (e) {
|
|
165
76
|
counters.error++;
|
|
166
|
-
|
|
167
|
-
|
|
77
|
+
console.error(
|
|
78
|
+
c.error(`Error in data migration: ${e.message}`)
|
|
79
|
+
);
|
|
168
80
|
}
|
|
169
81
|
}
|
|
170
82
|
};
|
|
@@ -187,19 +99,6 @@ ${NO_PENDING_MIGRATIONS_MESSAGE}
|
|
|
187
99
|
console.log();
|
|
188
100
|
reportDataMigrations(counters);
|
|
189
101
|
console.log();
|
|
190
|
-
} finally {
|
|
191
|
-
if (server) {
|
|
192
|
-
await server.close();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
async function runDataMigration(db2, dataMigrationPath) {
|
|
196
|
-
const runner = await getRunner();
|
|
197
|
-
const dataMigrationModule = await runner.import(dataMigrationPath);
|
|
198
|
-
const dataMigration = dataMigrationModule.default;
|
|
199
|
-
const startedAt = /* @__PURE__ */ new Date();
|
|
200
|
-
await dataMigration({ db: db2 });
|
|
201
|
-
const finishedAt = /* @__PURE__ */ new Date();
|
|
202
|
-
return { startedAt, finishedAt };
|
|
203
102
|
}
|
|
204
103
|
}
|
|
205
104
|
async function getPendingDataMigrations(db) {
|
|
@@ -244,6 +143,13 @@ function sortDataMigrationsByVersion(dataMigrationA, dataMigrationB) {
|
|
|
244
143
|
}
|
|
245
144
|
return 0;
|
|
246
145
|
}
|
|
146
|
+
async function runDataMigration(db, dataMigrationPath) {
|
|
147
|
+
const dataMigration = require2(dataMigrationPath);
|
|
148
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
149
|
+
await dataMigration.default({ db });
|
|
150
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
151
|
+
return { startedAt, finishedAt };
|
|
152
|
+
}
|
|
247
153
|
const NO_PENDING_MIGRATIONS_MESSAGE = "No pending data migrations run, already up-to-date.";
|
|
248
154
|
async function recordDataMigration(db, { version, name, startedAt, finishedAt }) {
|
|
249
155
|
await db.rW_DataMigration.create({
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DataMigrateUpOptions } from '../types.js';
|
|
2
|
+
export declare function handler({ importDbClientFromDist, distPath, }: DataMigrateUpOptions): Promise<void>;
|
|
3
|
+
export declare const NO_PENDING_MIGRATIONS_MESSAGE = "No pending data migrations run, already up-to-date.";
|
|
4
|
+
//# sourceMappingURL=upHandlerEsm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upHandlerEsm.d.ts","sourceRoot":"","sources":["../../src/commands/upHandlerEsm.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,aAAa,CAAA;AAsCtE,wBAAsB,OAAO,CAAC,EAC5B,sBAAsB,EACtB,QAAQ,GACT,EAAE,oBAAoB,iBAoMtB;AA6DD,eAAO,MAAM,6BAA6B,wDACa,CAAA"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { Listr } from "listr2";
|
|
4
|
+
import { createServer, isRunnableDevEnvironment } from "vite";
|
|
5
|
+
import { colors as c } from "@cedarjs/cli-helpers";
|
|
6
|
+
import {
|
|
7
|
+
getPaths,
|
|
8
|
+
getDataMigrationsPath,
|
|
9
|
+
resolveFile,
|
|
10
|
+
importStatementPath
|
|
11
|
+
} from "@cedarjs/project-config";
|
|
12
|
+
function resolveId(id) {
|
|
13
|
+
if (fs.existsSync(id) && fs.statSync(id).isFile()) {
|
|
14
|
+
return id;
|
|
15
|
+
}
|
|
16
|
+
const withoutExt = /\.jsx?$/.test(id) ? id.replace(/\.jsx?$/, "") : id;
|
|
17
|
+
for (const ext of [".ts", ".tsx", ".js", ".jsx"]) {
|
|
18
|
+
if (fs.existsSync(withoutExt + ext)) {
|
|
19
|
+
return withoutExt + ext;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (fs.existsSync(id) && fs.statSync(id).isDirectory()) {
|
|
23
|
+
for (const base of ["index", path.basename(id)]) {
|
|
24
|
+
for (const ext of [".ts", ".tsx", ".js", ".jsx"]) {
|
|
25
|
+
const candidate = path.join(id, base + ext);
|
|
26
|
+
if (fs.existsSync(candidate)) {
|
|
27
|
+
return candidate;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return id;
|
|
33
|
+
}
|
|
34
|
+
async function handler({
|
|
35
|
+
importDbClientFromDist,
|
|
36
|
+
distPath
|
|
37
|
+
}) {
|
|
38
|
+
let db;
|
|
39
|
+
let server = null;
|
|
40
|
+
let cedarPlugins;
|
|
41
|
+
async function getRunner() {
|
|
42
|
+
if (!server) {
|
|
43
|
+
if (!cedarPlugins) {
|
|
44
|
+
const mod = await import("@cedarjs/vite");
|
|
45
|
+
cedarPlugins = mod;
|
|
46
|
+
}
|
|
47
|
+
server = await createServer({
|
|
48
|
+
mode: "production",
|
|
49
|
+
optimizeDeps: {
|
|
50
|
+
noDiscovery: true,
|
|
51
|
+
include: void 0
|
|
52
|
+
},
|
|
53
|
+
server: {
|
|
54
|
+
hmr: false,
|
|
55
|
+
watch: null
|
|
56
|
+
},
|
|
57
|
+
environments: {
|
|
58
|
+
nodeRunnerEnv: {}
|
|
59
|
+
},
|
|
60
|
+
resolve: {
|
|
61
|
+
alias: [
|
|
62
|
+
{
|
|
63
|
+
find: /^api\//,
|
|
64
|
+
replacement: getPaths().api.base + "/"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
find: /^src\//,
|
|
68
|
+
replacement: "src/",
|
|
69
|
+
customResolver: (id, importer, _options) => {
|
|
70
|
+
const apiImportBase = importStatementPath(getPaths().api.base);
|
|
71
|
+
if (importer?.startsWith(apiImportBase)) {
|
|
72
|
+
const apiImportSrc = importStatementPath(getPaths().api.src);
|
|
73
|
+
const apiId = id.replace("src", apiImportSrc);
|
|
74
|
+
return { id: resolveId(apiId) };
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
plugins: [
|
|
82
|
+
cedarPlugins.cedarCjsCompatPlugin(),
|
|
83
|
+
cedarPlugins.cedarjsResolveCedarStyleImportsPlugin(),
|
|
84
|
+
cedarPlugins.cedarImportDirPlugin(),
|
|
85
|
+
cedarPlugins.cedarAutoImportsPlugin()
|
|
86
|
+
]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const env = server.environments.nodeRunnerEnv;
|
|
90
|
+
if (!env || !isRunnableDevEnvironment(env)) {
|
|
91
|
+
throw new Error("Vite environment is not runnable.");
|
|
92
|
+
}
|
|
93
|
+
return env.runner;
|
|
94
|
+
}
|
|
95
|
+
if (importDbClientFromDist) {
|
|
96
|
+
if (!fs.existsSync(distPath)) {
|
|
97
|
+
console.warn(
|
|
98
|
+
`Can't find api dist at ${distPath}. You may need to build first: yarn cedar build api`
|
|
99
|
+
);
|
|
100
|
+
process.exitCode = 1;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const distLibPath = path.join(distPath, "lib");
|
|
104
|
+
const distLibDbPath = path.join(distLibPath, "db.js");
|
|
105
|
+
if (!fs.existsSync(distLibDbPath)) {
|
|
106
|
+
console.error(
|
|
107
|
+
`Can't find db.js at ${distLibDbPath}. CedarJS expects the db.js file to be in the ${distLibPath} directory`
|
|
108
|
+
);
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
db = (await import(distLibDbPath)).db;
|
|
113
|
+
} else {
|
|
114
|
+
const dbPath = resolveFile(path.join(getPaths().api.lib, "db"));
|
|
115
|
+
if (!dbPath) {
|
|
116
|
+
console.error(`Can't find your db file in ${getPaths().api.lib}`);
|
|
117
|
+
process.exitCode = 1;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
const runner = await getRunner();
|
|
122
|
+
const dbModule = await runner.import(dbPath);
|
|
123
|
+
db = dbModule.db;
|
|
124
|
+
} catch (e) {
|
|
125
|
+
await server?.close();
|
|
126
|
+
throw e;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const pendingDataMigrations = await getPendingDataMigrations(db);
|
|
130
|
+
if (!pendingDataMigrations.length) {
|
|
131
|
+
console.info(c.success(`
|
|
132
|
+
${NO_PENDING_MIGRATIONS_MESSAGE}
|
|
133
|
+
`));
|
|
134
|
+
process.exitCode = 0;
|
|
135
|
+
await server?.close();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const counters = { run: 0, skipped: 0, error: 0 };
|
|
139
|
+
const dataMigrationTasks = pendingDataMigrations.map((dataMigration) => {
|
|
140
|
+
const dataMigrationName = path.basename(dataMigration.path, ".js");
|
|
141
|
+
return {
|
|
142
|
+
title: dataMigrationName,
|
|
143
|
+
skip() {
|
|
144
|
+
if (counters.error > 0) {
|
|
145
|
+
counters.skipped++;
|
|
146
|
+
return true;
|
|
147
|
+
} else {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
async task() {
|
|
152
|
+
try {
|
|
153
|
+
const { startedAt, finishedAt } = await runDataMigration(
|
|
154
|
+
db,
|
|
155
|
+
dataMigration.path
|
|
156
|
+
);
|
|
157
|
+
counters.run++;
|
|
158
|
+
await recordDataMigration(db, {
|
|
159
|
+
version: dataMigration.version,
|
|
160
|
+
name: dataMigrationName,
|
|
161
|
+
startedAt,
|
|
162
|
+
finishedAt
|
|
163
|
+
});
|
|
164
|
+
} catch (e) {
|
|
165
|
+
counters.error++;
|
|
166
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
167
|
+
console.error(c.error(`Error in data migration: ${message}`));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
const tasks = new Listr(dataMigrationTasks, {
|
|
173
|
+
renderer: "verbose"
|
|
174
|
+
});
|
|
175
|
+
try {
|
|
176
|
+
await tasks.run();
|
|
177
|
+
await db.$disconnect();
|
|
178
|
+
console.log();
|
|
179
|
+
reportDataMigrations(counters);
|
|
180
|
+
console.log();
|
|
181
|
+
if (counters.error) {
|
|
182
|
+
process.exitCode = 1;
|
|
183
|
+
}
|
|
184
|
+
} catch {
|
|
185
|
+
process.exitCode = 1;
|
|
186
|
+
await db.$disconnect();
|
|
187
|
+
console.log();
|
|
188
|
+
reportDataMigrations(counters);
|
|
189
|
+
console.log();
|
|
190
|
+
} finally {
|
|
191
|
+
if (server) {
|
|
192
|
+
await server.close();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async function runDataMigration(db2, dataMigrationPath) {
|
|
196
|
+
const runner = await getRunner();
|
|
197
|
+
const dataMigrationModule = await runner.import(dataMigrationPath);
|
|
198
|
+
const dataMigration = dataMigrationModule.default;
|
|
199
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
200
|
+
await dataMigration({ db: db2 });
|
|
201
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
202
|
+
return { startedAt, finishedAt };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async function getPendingDataMigrations(db) {
|
|
206
|
+
const dataMigrationsPath = await getDataMigrationsPath(
|
|
207
|
+
getPaths().api.prismaConfig
|
|
208
|
+
);
|
|
209
|
+
if (!fs.existsSync(dataMigrationsPath)) {
|
|
210
|
+
return [];
|
|
211
|
+
}
|
|
212
|
+
const dataMigrations = fs.readdirSync(dataMigrationsPath).filter(
|
|
213
|
+
(dataMigrationFileName) => ["js", ".ts"].some(
|
|
214
|
+
(extension) => dataMigrationFileName.endsWith(extension)
|
|
215
|
+
)
|
|
216
|
+
).map((dataMigrationFileName) => {
|
|
217
|
+
const [version] = dataMigrationFileName.split("-");
|
|
218
|
+
return {
|
|
219
|
+
version,
|
|
220
|
+
path: path.join(dataMigrationsPath, dataMigrationFileName)
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
const ranDataMigrations = await db.rW_DataMigration.findMany(
|
|
224
|
+
{
|
|
225
|
+
orderBy: { version: "asc" }
|
|
226
|
+
}
|
|
227
|
+
);
|
|
228
|
+
const ranDataMigrationVersions = ranDataMigrations.map(
|
|
229
|
+
(dataMigration) => dataMigration.version.toString()
|
|
230
|
+
);
|
|
231
|
+
const pendingDataMigrations = dataMigrations.filter(({ version }) => {
|
|
232
|
+
return !ranDataMigrationVersions.includes(version);
|
|
233
|
+
}).sort(sortDataMigrationsByVersion);
|
|
234
|
+
return pendingDataMigrations;
|
|
235
|
+
}
|
|
236
|
+
function sortDataMigrationsByVersion(dataMigrationA, dataMigrationB) {
|
|
237
|
+
const aVersion = parseInt(dataMigrationA.version);
|
|
238
|
+
const bVersion = parseInt(dataMigrationB.version);
|
|
239
|
+
if (aVersion > bVersion) {
|
|
240
|
+
return 1;
|
|
241
|
+
}
|
|
242
|
+
if (aVersion < bVersion) {
|
|
243
|
+
return -1;
|
|
244
|
+
}
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
247
|
+
const NO_PENDING_MIGRATIONS_MESSAGE = "No pending data migrations run, already up-to-date.";
|
|
248
|
+
async function recordDataMigration(db, { version, name, startedAt, finishedAt }) {
|
|
249
|
+
await db.rW_DataMigration.create({
|
|
250
|
+
data: { version, name, startedAt, finishedAt }
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
function reportDataMigrations(counters) {
|
|
254
|
+
if (counters.run) {
|
|
255
|
+
console.info(
|
|
256
|
+
c.success(`${counters.run} data migration(s) completed successfully.`)
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
if (counters.error) {
|
|
260
|
+
console.error(
|
|
261
|
+
c.error(`${counters.error} data migration(s) exited with errors.`)
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
if (counters.skipped) {
|
|
265
|
+
console.warn(
|
|
266
|
+
c.warning(
|
|
267
|
+
`${counters.skipped} data migration(s) skipped due to previous error.`
|
|
268
|
+
)
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
export {
|
|
273
|
+
NO_PENDING_MIGRATIONS_MESSAGE,
|
|
274
|
+
handler
|
|
275
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/cli-data-migrate",
|
|
3
|
-
"version": "7.0.0-
|
|
3
|
+
"version": "7.0.0-rc.123",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -26,9 +26,10 @@
|
|
|
26
26
|
"test:unit": "vitest run src"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@cedarjs/
|
|
30
|
-
"@cedarjs/
|
|
31
|
-
"@cedarjs/
|
|
29
|
+
"@cedarjs/babel-config": "7.0.0-rc.123",
|
|
30
|
+
"@cedarjs/cli-helpers": "7.0.0-rc.123",
|
|
31
|
+
"@cedarjs/project-config": "7.0.0-rc.123",
|
|
32
|
+
"@cedarjs/vite": "7.0.0-rc.123",
|
|
32
33
|
"dotenv-defaults": "5.0.2",
|
|
33
34
|
"execa": "5.1.1",
|
|
34
35
|
"listr2": "10.2.2",
|
|
@@ -37,10 +38,10 @@
|
|
|
37
38
|
"yargs": "17.7.3"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"@cedarjs/framework-tools": "7.0.0-
|
|
41
|
-
"@prisma/client": "7.
|
|
41
|
+
"@cedarjs/framework-tools": "7.0.0-rc.123",
|
|
42
|
+
"@prisma/client": "7.8.0",
|
|
42
43
|
"@types/yargs": "17.0.35",
|
|
43
|
-
"memfs": "4.
|
|
44
|
+
"memfs": "4.78.1",
|
|
44
45
|
"typescript": "5.9.3",
|
|
45
46
|
"vitest": "4.1.11"
|
|
46
47
|
},
|