@porulle/cli 0.1.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/README.md +40 -0
- package/dist/commands/api-key.d.ts +34 -0
- package/dist/commands/api-key.d.ts.map +1 -0
- package/dist/commands/api-key.js +202 -0
- package/dist/commands/deploy.d.ts +13 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +45 -0
- package/dist/commands/dev.d.ts +15 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +173 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +413 -0
- package/dist/commands/generate-migration.d.ts +2 -0
- package/dist/commands/generate-migration.d.ts.map +1 -0
- package/dist/commands/generate-migration.js +20 -0
- package/dist/commands/import.d.ts +45 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +237 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +52 -0
- package/dist/commands/migrate.d.ts +2 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +20 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +17 -0
- package/package.json +53 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
+
import { defineCommand } from "citty";
|
|
6
|
+
import postgres from "postgres";
|
|
7
|
+
import { readJson } from "../utils.js";
|
|
8
|
+
const CLI_ROOT = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
function normalizeProjectRel(cwd, projectRel) {
|
|
10
|
+
const stripped = projectRel.startsWith("./") ? projectRel.slice(2) : projectRel;
|
|
11
|
+
return resolve(cwd, stripped);
|
|
12
|
+
}
|
|
13
|
+
function walkFiles(dir, visit) {
|
|
14
|
+
if (!existsSync(dir))
|
|
15
|
+
return;
|
|
16
|
+
for (const name of readdirSync(dir)) {
|
|
17
|
+
const abs = join(dir, name);
|
|
18
|
+
if (statSync(abs).isDirectory())
|
|
19
|
+
walkFiles(abs, visit);
|
|
20
|
+
else
|
|
21
|
+
visit(abs);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function extractBracketArrayBody(src, key) {
|
|
25
|
+
const needle = `${key}:`;
|
|
26
|
+
const keyIdx = src.indexOf(needle);
|
|
27
|
+
if (keyIdx === -1)
|
|
28
|
+
return null;
|
|
29
|
+
const bracketIdx = src.indexOf("[", keyIdx);
|
|
30
|
+
if (bracketIdx === -1)
|
|
31
|
+
return null;
|
|
32
|
+
let depth = 0;
|
|
33
|
+
for (let i = bracketIdx; i < src.length; i++) {
|
|
34
|
+
const c = src[i];
|
|
35
|
+
if (c === "[")
|
|
36
|
+
depth++;
|
|
37
|
+
else if (c === "]") {
|
|
38
|
+
depth--;
|
|
39
|
+
if (depth === 0)
|
|
40
|
+
return src.slice(bracketIdx + 1, i);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
function parseImportBindings(src) {
|
|
46
|
+
const map = new Map();
|
|
47
|
+
const importRe = /import\s+(?:type\s+)?(?:\{([^}]+)\}|(\w+))\s+from\s+["']([^"']+)["']/gs;
|
|
48
|
+
let m;
|
|
49
|
+
while ((m = importRe.exec(src)) !== null) {
|
|
50
|
+
const named = m[1];
|
|
51
|
+
const defaultImport = m[2];
|
|
52
|
+
const from = m[3];
|
|
53
|
+
if (!from)
|
|
54
|
+
continue;
|
|
55
|
+
if (defaultImport)
|
|
56
|
+
map.set(defaultImport, from);
|
|
57
|
+
if (named) {
|
|
58
|
+
for (const part of named.split(",")) {
|
|
59
|
+
const trimmed = part.trim();
|
|
60
|
+
if (!trimmed)
|
|
61
|
+
continue;
|
|
62
|
+
const withoutType = trimmed.replace(/^type\s+/, "");
|
|
63
|
+
const rawName = withoutType.split(/\s+as\s+/)[0];
|
|
64
|
+
const name = rawName?.trim() ?? "";
|
|
65
|
+
if (name)
|
|
66
|
+
map.set(name, from);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return map;
|
|
71
|
+
}
|
|
72
|
+
function extractSchemaIdentifiers(schemaBody) {
|
|
73
|
+
const ids = [];
|
|
74
|
+
const objRe = /\{\s*([^}]+?)\s*\}/g;
|
|
75
|
+
let m;
|
|
76
|
+
while ((m = objRe.exec(schemaBody)) !== null) {
|
|
77
|
+
const inner = m[1];
|
|
78
|
+
if (!inner)
|
|
79
|
+
continue;
|
|
80
|
+
for (const part of inner.split(",")) {
|
|
81
|
+
const tok = part.trim().split(/\s+/)[0];
|
|
82
|
+
if (tok && /^[a-zA-Z_$]/.test(tok))
|
|
83
|
+
ids.push(tok);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return ids;
|
|
87
|
+
}
|
|
88
|
+
function extractPluginCallerIds(pluginsBody) {
|
|
89
|
+
const ids = [];
|
|
90
|
+
const callRe = /(\w+)\s*\(/g;
|
|
91
|
+
let m;
|
|
92
|
+
while ((m = callRe.exec(pluginsBody)) !== null) {
|
|
93
|
+
const id = m[1];
|
|
94
|
+
if (!id || id === "if" || id === "switch" || id === "require")
|
|
95
|
+
continue;
|
|
96
|
+
ids.push(id);
|
|
97
|
+
}
|
|
98
|
+
return [...new Set(ids)];
|
|
99
|
+
}
|
|
100
|
+
function resolveLocalModulePath(commerceDir, specifier) {
|
|
101
|
+
const base = specifier.startsWith("./") || specifier.startsWith("../") ? specifier : `./${specifier}`;
|
|
102
|
+
const withoutJs = base.replace(/\.js$/i, ".ts");
|
|
103
|
+
const tsCandidate = resolve(commerceDir, withoutJs);
|
|
104
|
+
const jsCandidate = resolve(commerceDir, base);
|
|
105
|
+
if (existsSync(tsCandidate))
|
|
106
|
+
return tsCandidate;
|
|
107
|
+
if (existsSync(jsCandidate))
|
|
108
|
+
return jsCandidate;
|
|
109
|
+
return tsCandidate;
|
|
110
|
+
}
|
|
111
|
+
function expandDrizzlePatterns(patterns, cwd) {
|
|
112
|
+
const out = new Set();
|
|
113
|
+
for (const raw of patterns) {
|
|
114
|
+
const pat = raw.replace(/\\/g, "/");
|
|
115
|
+
if (!pat.includes("*")) {
|
|
116
|
+
const abs = normalizeProjectRel(cwd, pat);
|
|
117
|
+
if (existsSync(abs))
|
|
118
|
+
out.add(abs);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const pluginGlob = pat === "./node_modules/@porulle/plugin-*/src/schema.ts" ||
|
|
122
|
+
pat === "node_modules/@porulle/plugin-*/src/schema.ts";
|
|
123
|
+
if (pluginGlob) {
|
|
124
|
+
const base = join(cwd, "node_modules/@porulle");
|
|
125
|
+
if (existsSync(base)) {
|
|
126
|
+
for (const name of readdirSync(base)) {
|
|
127
|
+
if (!name.startsWith("plugin-"))
|
|
128
|
+
continue;
|
|
129
|
+
const file = join(base, name, "src/schema.ts");
|
|
130
|
+
if (existsSync(file))
|
|
131
|
+
out.add(file);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const starStarIdx = pat.indexOf("/**/");
|
|
137
|
+
if (starStarIdx !== -1) {
|
|
138
|
+
const prefixRaw = pat.slice(0, starStarIdx).replace(/^\.\//, "");
|
|
139
|
+
const tailRaw = pat.slice(starStarIdx + 4);
|
|
140
|
+
const root = join(cwd, prefixRaw);
|
|
141
|
+
if (!existsSync(root))
|
|
142
|
+
continue;
|
|
143
|
+
if (tailRaw.includes("*")) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
walkFiles(root, (abs) => {
|
|
147
|
+
const rel = relative(root, abs).replace(/\\/g, "/");
|
|
148
|
+
if (tailRaw === "schema.ts") {
|
|
149
|
+
if (basename(abs) === "schema.ts")
|
|
150
|
+
out.add(abs);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (rel === tailRaw || rel.endsWith(`/${tailRaw}`) || abs.endsWith(`/${tailRaw}`)) {
|
|
154
|
+
out.add(abs);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (pat.includes("*")) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
function formatPgEndpoint(databaseUrl) {
|
|
166
|
+
try {
|
|
167
|
+
const u = new URL(databaseUrl);
|
|
168
|
+
const host = u.hostname || "localhost";
|
|
169
|
+
const port = u.port || "5432";
|
|
170
|
+
return `${host}:${port}`;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return "database host";
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function semverMajor(version) {
|
|
177
|
+
const v = version.trim().replace(/^v/i, "");
|
|
178
|
+
const major = Number.parseInt(v.split(".")[0] ?? "", 10);
|
|
179
|
+
return Number.isFinite(major) ? major : null;
|
|
180
|
+
}
|
|
181
|
+
function symbolFor(status) {
|
|
182
|
+
switch (status) {
|
|
183
|
+
case "ok":
|
|
184
|
+
return "✓";
|
|
185
|
+
case "warn":
|
|
186
|
+
return "⚠";
|
|
187
|
+
case "fail":
|
|
188
|
+
return "✗";
|
|
189
|
+
case "info":
|
|
190
|
+
return "ℹ";
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export const doctorCommand = defineCommand({
|
|
194
|
+
meta: {
|
|
195
|
+
name: "doctor",
|
|
196
|
+
description: "Validate project setup (database, Drizzle schema, auth, env, adapters)",
|
|
197
|
+
},
|
|
198
|
+
args: {
|
|
199
|
+
cwd: {
|
|
200
|
+
type: "string",
|
|
201
|
+
description: "Project root (default: current working directory)",
|
|
202
|
+
default: ".",
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
async run({ args }) {
|
|
206
|
+
const cwd = resolve(process.cwd(), String(args.cwd ?? "."));
|
|
207
|
+
const lines = [];
|
|
208
|
+
let redCount = 0;
|
|
209
|
+
const push = (status, text) => {
|
|
210
|
+
lines.push({ status, text });
|
|
211
|
+
if (status === "fail")
|
|
212
|
+
redCount++;
|
|
213
|
+
};
|
|
214
|
+
const commercePath = join(cwd, "commerce.config.ts");
|
|
215
|
+
const drizzlePath = join(cwd, "drizzle.config.ts");
|
|
216
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
217
|
+
if (databaseUrl) {
|
|
218
|
+
push("ok", "DATABASE_URL set");
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
push("fail", 'DATABASE_URL not set — add it to `.env` or your shell (e.g. `postgres://localhost:5432/mydb`).');
|
|
222
|
+
}
|
|
223
|
+
let pgReachable = false;
|
|
224
|
+
if (databaseUrl) {
|
|
225
|
+
const sql = postgres(databaseUrl, { max: 1, connect_timeout: 5 });
|
|
226
|
+
try {
|
|
227
|
+
await sql `SELECT 1`;
|
|
228
|
+
pgReachable = true;
|
|
229
|
+
push("ok", `Postgres reachable at ${formatPgEndpoint(databaseUrl)}`);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
push("fail", "Cannot connect to Postgres — start your database or fix DATABASE_URL (check host, port, credentials).");
|
|
233
|
+
}
|
|
234
|
+
finally {
|
|
235
|
+
await sql.end({ timeout: 2 }).catch(() => undefined);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
push("warn", "Postgres connectivity not checked — DATABASE_URL is missing.");
|
|
240
|
+
}
|
|
241
|
+
let drizzleLoaded = false;
|
|
242
|
+
let expandedSchemaFiles = new Set();
|
|
243
|
+
try {
|
|
244
|
+
const drizzleMod = await import(pathToFileURL(drizzlePath).href);
|
|
245
|
+
const cfg = drizzleMod.default;
|
|
246
|
+
const drizzlePatterns = Array.isArray(cfg.schema)
|
|
247
|
+
? cfg.schema.filter((x) => typeof x === "string")
|
|
248
|
+
: [];
|
|
249
|
+
expandedSchemaFiles = expandDrizzlePatterns(drizzlePatterns, cwd);
|
|
250
|
+
drizzleLoaded = true;
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
push("fail", "Could not load drizzle.config.ts — add one at the project root (see store-example).");
|
|
254
|
+
}
|
|
255
|
+
if (!existsSync(commercePath)) {
|
|
256
|
+
push("fail", "commerce.config.ts not found — run `unifiedcommerce init` or add a config at the project root.");
|
|
257
|
+
}
|
|
258
|
+
else if (drizzleLoaded) {
|
|
259
|
+
const src = readFileSync(commercePath, "utf8");
|
|
260
|
+
const bindings = parseImportBindings(src);
|
|
261
|
+
const schemaBody = extractBracketArrayBody(src, "schema");
|
|
262
|
+
const schemaIds = schemaBody ? extractSchemaIdentifiers(schemaBody) : [];
|
|
263
|
+
const commerceDir = dirname(commercePath);
|
|
264
|
+
const pluginsBody = extractBracketArrayBody(src, "plugins");
|
|
265
|
+
const pluginIds = pluginsBody ? extractPluginCallerIds(pluginsBody) : [];
|
|
266
|
+
const paths = new Set();
|
|
267
|
+
for (const pid of pluginIds) {
|
|
268
|
+
const mod = bindings.get(pid);
|
|
269
|
+
if (!mod || !mod.startsWith("@porulle/plugin-"))
|
|
270
|
+
continue;
|
|
271
|
+
const pkgRel = mod.replace(/^@porulle\//, "");
|
|
272
|
+
paths.add(join(cwd, "node_modules/@porulle", pkgRel, "src/schema.ts"));
|
|
273
|
+
}
|
|
274
|
+
for (const sid of schemaIds) {
|
|
275
|
+
const mod = bindings.get(sid);
|
|
276
|
+
if (!mod || !(mod.startsWith("./") || mod.startsWith("../")))
|
|
277
|
+
continue;
|
|
278
|
+
paths.add(resolveLocalModulePath(commerceDir, mod));
|
|
279
|
+
}
|
|
280
|
+
const requiredPaths = [...paths];
|
|
281
|
+
const missingOnDisk = requiredPaths.filter((p) => !existsSync(p));
|
|
282
|
+
if (missingOnDisk.length > 0) {
|
|
283
|
+
push("fail", `Schema file missing — run \`bun install\` so plugins exist (${missingOnDisk.length} path(s) not found under node_modules or src).`);
|
|
284
|
+
}
|
|
285
|
+
else if (requiredPaths.length === 0) {
|
|
286
|
+
push("ok", "No extra plugin/app schema paths detected in commerce.config.ts (core-only)");
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
const uncovered = requiredPaths.filter((p) => !expandedSchemaFiles.has(p));
|
|
290
|
+
if (uncovered.length === 0) {
|
|
291
|
+
push("ok", `drizzle.config.ts covers all ${requiredPaths.length} required schema path(s)`);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
push("fail", `drizzle.config.ts does not cover ${uncovered.length} schema path(s) — extend the \`schema\` array in drizzle.config.ts so Drizzle sees every plugin and local schema file (then run \`bun run db:push\`).`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (pgReachable && databaseUrl) {
|
|
299
|
+
const sql = postgres(databaseUrl, { max: 1, connect_timeout: 5 });
|
|
300
|
+
try {
|
|
301
|
+
await sql `SELECT 1 FROM "user" LIMIT 1`;
|
|
302
|
+
push("ok", 'Auth tables present — "user" table is readable');
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
push("fail", "Auth tables not pushed — run `bun run db:push` (or your package's Drizzle push script).");
|
|
306
|
+
}
|
|
307
|
+
finally {
|
|
308
|
+
await sql.end({ timeout: 2 }).catch(() => undefined);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
push("warn", 'Skipped auth table check — Postgres not reachable (needs `"user"` table from Better Auth).');
|
|
313
|
+
}
|
|
314
|
+
if (process.env.BETTER_AUTH_SECRET && process.env.BETTER_AUTH_SECRET.length > 0) {
|
|
315
|
+
push("ok", "BETTER_AUTH_SECRET set");
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
push("fail", "BETTER_AUTH_SECRET not set — generate one with `openssl rand -hex 32` and add it to `.env`.");
|
|
319
|
+
}
|
|
320
|
+
if (process.env.BETTER_AUTH_URL && process.env.BETTER_AUTH_URL.length > 0) {
|
|
321
|
+
push("ok", "BETTER_AUTH_URL set");
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
push("fail", "BETTER_AUTH_URL not set — set it to your app's public base URL (e.g. `http://localhost:4000`).");
|
|
325
|
+
}
|
|
326
|
+
push("info", "BETTER_AUTH_URL defaults to http://localhost:4000");
|
|
327
|
+
if (!process.env.PORT) {
|
|
328
|
+
push("info", "PORT is unset (optional)");
|
|
329
|
+
}
|
|
330
|
+
let configLoaded = false;
|
|
331
|
+
try {
|
|
332
|
+
if (existsSync(commercePath)) {
|
|
333
|
+
const mod = await import(pathToFileURL(commercePath).href);
|
|
334
|
+
let cfg = mod.default;
|
|
335
|
+
cfg = await Promise.resolve(cfg);
|
|
336
|
+
if (cfg && typeof cfg === "object") {
|
|
337
|
+
const o = cfg;
|
|
338
|
+
const storage = o.storage;
|
|
339
|
+
const databaseAdapter = o.databaseAdapter;
|
|
340
|
+
if (storage && typeof storage === "object") {
|
|
341
|
+
const providerId = storage.providerId;
|
|
342
|
+
const label = typeof providerId === "string" && providerId.length > 0
|
|
343
|
+
? providerId
|
|
344
|
+
: "storage adapter";
|
|
345
|
+
push("ok", `Storage adapter configured (${label})`);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
push("fail", "Storage adapter missing — set `storage` in commerce.config.ts (e.g. localStorageAdapter or s3StorageAdapter).");
|
|
349
|
+
}
|
|
350
|
+
if (databaseAdapter && typeof databaseAdapter === "object") {
|
|
351
|
+
const provider = databaseAdapter.provider;
|
|
352
|
+
const label = typeof provider === "string" && provider.length > 0
|
|
353
|
+
? provider
|
|
354
|
+
: "database adapter";
|
|
355
|
+
push("ok", `Database adapter configured (${label})`);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
push("fail", "Database adapter missing — set `databaseAdapter` in commerce.config.ts (e.g. postgresAdapter).");
|
|
359
|
+
}
|
|
360
|
+
configLoaded = true;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
push("fail", "Could not load commerce.config.ts — fix syntax/runtime errors; doctor needs the resolved config.");
|
|
366
|
+
}
|
|
367
|
+
let cliVersion = "";
|
|
368
|
+
try {
|
|
369
|
+
const cliPkg = await readJson(join(CLI_ROOT, "../../package.json"));
|
|
370
|
+
cliVersion = cliPkg.version ?? "";
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
cliVersion = "";
|
|
374
|
+
}
|
|
375
|
+
let coreVersion = "";
|
|
376
|
+
try {
|
|
377
|
+
const req = createRequire(join(cwd, "package.json"));
|
|
378
|
+
const corePkgPath = req.resolve("@porulle/core/package.json");
|
|
379
|
+
const corePkg = await readJson(corePkgPath);
|
|
380
|
+
coreVersion = corePkg.version ?? "";
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
coreVersion = "";
|
|
384
|
+
}
|
|
385
|
+
if (!cliVersion || !coreVersion) {
|
|
386
|
+
push("warn", "Could not compare CLI vs @porulle/core versions (package missing or not installed).");
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
const cliM = semverMajor(cliVersion);
|
|
390
|
+
const coreM = semverMajor(coreVersion);
|
|
391
|
+
if (cliM !== null && coreM !== null && cliM !== coreM) {
|
|
392
|
+
push("warn", `CLI ${cliVersion} major (${cliM}) differs from @porulle/core ${coreVersion} major (${coreM}) — align versions to avoid subtle breakage.`);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
push("ok", `CLI ${cliVersion} matches core ${coreVersion}`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
console.log("");
|
|
399
|
+
console.log("unicore doctor");
|
|
400
|
+
console.log("");
|
|
401
|
+
for (const { status, text } of lines) {
|
|
402
|
+
console.log(`${symbolFor(status)} ${text}`);
|
|
403
|
+
}
|
|
404
|
+
const problems = redCount;
|
|
405
|
+
console.log("");
|
|
406
|
+
console.log(problems === 0
|
|
407
|
+
? "Result: no problems found."
|
|
408
|
+
: problems === 1
|
|
409
|
+
? "Result: 1 problem found."
|
|
410
|
+
: `Result: ${problems} problems found.`);
|
|
411
|
+
process.exit(problems > 0 ? 1 : 0);
|
|
412
|
+
},
|
|
413
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-migration.d.ts","sourceRoot":"","sources":["../../src/commands/generate-migration.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,wBAAwB,qDAmBnC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { defineCommand } from "citty";
|
|
3
|
+
export const generateMigrationCommand = defineCommand({
|
|
4
|
+
meta: {
|
|
5
|
+
name: "generate migration",
|
|
6
|
+
description: "Generate Drizzle migration",
|
|
7
|
+
},
|
|
8
|
+
async run() {
|
|
9
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
10
|
+
const proc = spawn(process.platform === "win32" ? "npx.cmd" : "npx", ["drizzle-kit", "generate"], { stdio: "inherit" });
|
|
11
|
+
proc.on("exit", (code) => {
|
|
12
|
+
if (code === 0)
|
|
13
|
+
resolvePromise();
|
|
14
|
+
else
|
|
15
|
+
rejectPromise(new Error(`drizzle-kit generate failed with code ${code}`));
|
|
16
|
+
});
|
|
17
|
+
proc.on("error", rejectPromise);
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const importCommand: import("citty").CommandDef<{
|
|
2
|
+
source: {
|
|
3
|
+
type: "string";
|
|
4
|
+
required: true;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
input: {
|
|
8
|
+
type: "string";
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
targetUrl: {
|
|
12
|
+
type: "string";
|
|
13
|
+
default: string;
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
authToken: {
|
|
17
|
+
type: "string";
|
|
18
|
+
description: string;
|
|
19
|
+
};
|
|
20
|
+
apiKey: {
|
|
21
|
+
type: "string";
|
|
22
|
+
description: string;
|
|
23
|
+
};
|
|
24
|
+
storeUrl: {
|
|
25
|
+
type: "string";
|
|
26
|
+
description: string;
|
|
27
|
+
};
|
|
28
|
+
consumerKey: {
|
|
29
|
+
type: "string";
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
consumerSecret: {
|
|
33
|
+
type: "string";
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
mapping: {
|
|
37
|
+
type: "string";
|
|
38
|
+
description: string;
|
|
39
|
+
};
|
|
40
|
+
entityType: {
|
|
41
|
+
type: "string";
|
|
42
|
+
default: string;
|
|
43
|
+
};
|
|
44
|
+
}>;
|
|
45
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"AAwJA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2KxB,CAAC"}
|