@nexusts/cli 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/commands/config.d.ts +43 -0
- package/dist/commands/db-generate.d.ts +19 -0
- package/dist/commands/db-migrate.d.ts +32 -0
- package/dist/commands/db-seed.d.ts +42 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/info.d.ts +10 -0
- package/dist/commands/init.d.ts +37 -0
- package/dist/commands/make-auth.d.ts +16 -0
- package/dist/commands/make-controller.d.ts +15 -0
- package/dist/commands/make-crud.d.ts +27 -0
- package/dist/commands/make-listener.d.ts +14 -0
- package/dist/commands/make-middleware.d.ts +6 -0
- package/dist/commands/make-migration.d.ts +20 -0
- package/dist/commands/make-model.d.ts +21 -0
- package/dist/commands/make-module.d.ts +10 -0
- package/dist/commands/make-queue.d.ts +16 -0
- package/dist/commands/make-schedule.d.ts +16 -0
- package/dist/commands/make-service.d.ts +6 -0
- package/dist/commands/make-session.d.ts +14 -0
- package/dist/commands/make-validator.d.ts +6 -0
- package/dist/commands/new.d.ts +13 -0
- package/dist/commands/repl.d.ts +41 -0
- package/dist/commands/route-list.d.ts +11 -0
- package/dist/core/args.d.ts +28 -0
- package/dist/core/config.d.ts +136 -0
- package/dist/core/fs.d.ts +37 -0
- package/dist/core/index.d.ts +42 -0
- package/dist/core/logger.d.ts +45 -0
- package/dist/core/loose-json.d.ts +25 -0
- package/dist/core/prompts.d.ts +21 -0
- package/dist/core/template.d.ts +25 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +1290 -1091
- package/dist/index.js.map +37 -33
- package/dist/templates/controller/adonis.d.ts +9 -0
- package/dist/templates/controller/functional.d.ts +8 -0
- package/dist/templates/controller/nest.d.ts +16 -0
- package/dist/templates/crud/controller.d.ts +7 -0
- package/dist/templates/crud/dto.d.ts +7 -0
- package/dist/templates/crud/module.d.ts +5 -0
- package/dist/templates/crud/test.d.ts +9 -0
- package/dist/templates/index.d.ts +38 -0
- package/dist/templates/middleware/middleware.d.ts +7 -0
- package/dist/templates/migration/drizzle.d.ts +11 -0
- package/dist/templates/migration/sql.d.ts +9 -0
- package/dist/templates/model/drizzle-dialect.d.ts +28 -0
- package/dist/templates/model/drizzle.d.ts +13 -0
- package/dist/templates/model/kysely.d.ts +11 -0
- package/dist/templates/model/prisma.d.ts +11 -0
- package/dist/templates/module/module.d.ts +15 -0
- package/dist/templates/project/drizzle.config.d.ts +11 -0
- package/dist/templates/project/nx.config.d.ts +6 -0
- package/dist/templates/repository/repository.d.ts +12 -0
- package/dist/templates/service/service.d.ts +11 -0
- package/dist/templates/validator/validator.d.ts +7 -0
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -1,26 +1,483 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
5
|
-
var __defProp = Object.defineProperty;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
9
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
|
-
for (let key of __getOwnPropNames(mod))
|
|
12
|
-
if (!__hasOwnProp.call(to, key))
|
|
13
|
-
__defProp(to, key, {
|
|
14
|
-
get: () => mod[key],
|
|
15
|
-
enumerable: true
|
|
16
|
-
});
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
3
|
var __require = import.meta.require;
|
|
20
4
|
|
|
21
5
|
// packages/cli/src/commands/info.ts
|
|
6
|
+
import { resolve as resolve3 } from "path";
|
|
7
|
+
|
|
8
|
+
// packages/cli/src/core/args.ts
|
|
9
|
+
var LONG_RE = /^--([^=]+)(?:=(.*))?$/;
|
|
10
|
+
var SHORT_RE = /^-([A-Za-z])$/;
|
|
11
|
+
function parseArgs(argv) {
|
|
12
|
+
const positional = [];
|
|
13
|
+
const flags = {};
|
|
14
|
+
let endOfOptions = false;
|
|
15
|
+
let i = 0;
|
|
16
|
+
while (i < argv.length) {
|
|
17
|
+
const arg = argv[i];
|
|
18
|
+
if (arg === "--") {
|
|
19
|
+
endOfOptions = true;
|
|
20
|
+
i++;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (endOfOptions || !arg.startsWith("-")) {
|
|
24
|
+
positional.push(arg);
|
|
25
|
+
i++;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const longMatch = LONG_RE.exec(arg);
|
|
29
|
+
if (longMatch) {
|
|
30
|
+
const [, name, inline] = longMatch;
|
|
31
|
+
const flagName = name;
|
|
32
|
+
if (inline !== undefined) {
|
|
33
|
+
setFlag(flags, flagName, inline);
|
|
34
|
+
i++;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const next = argv[i + 1];
|
|
38
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
39
|
+
setFlag(flags, flagName, next);
|
|
40
|
+
i += 2;
|
|
41
|
+
} else {
|
|
42
|
+
setFlag(flags, flagName, true);
|
|
43
|
+
i++;
|
|
44
|
+
}
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const shortMatch = SHORT_RE.exec(arg);
|
|
48
|
+
if (shortMatch) {
|
|
49
|
+
const flagName = shortMatch[1];
|
|
50
|
+
const next = argv[i + 1];
|
|
51
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
52
|
+
setFlag(flags, flagName, next);
|
|
53
|
+
i += 2;
|
|
54
|
+
} else {
|
|
55
|
+
setFlag(flags, flagName, true);
|
|
56
|
+
i++;
|
|
57
|
+
}
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
positional.push(arg);
|
|
61
|
+
i++;
|
|
62
|
+
}
|
|
63
|
+
const command = positional.shift();
|
|
64
|
+
return { command, positional, flags };
|
|
65
|
+
}
|
|
66
|
+
function setFlag(flags, name, value) {
|
|
67
|
+
if (name.startsWith("no-") && value === true) {
|
|
68
|
+
const key = name.slice(3);
|
|
69
|
+
flags[key] = false;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const existing = flags[name];
|
|
73
|
+
if (existing === undefined) {
|
|
74
|
+
flags[name] = value;
|
|
75
|
+
} else if (Array.isArray(existing)) {
|
|
76
|
+
existing.push(typeof value === "string" ? value : String(value));
|
|
77
|
+
} else {
|
|
78
|
+
flags[name] = [
|
|
79
|
+
String(existing),
|
|
80
|
+
typeof value === "string" ? value : String(value)
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function flagBool(flags, name, fallback = false) {
|
|
85
|
+
const v = flags[name];
|
|
86
|
+
if (v === undefined)
|
|
87
|
+
return fallback;
|
|
88
|
+
if (typeof v === "boolean")
|
|
89
|
+
return v;
|
|
90
|
+
return v !== "false" && v !== "0" && v !== "no";
|
|
91
|
+
}
|
|
92
|
+
function flagList(flags, name) {
|
|
93
|
+
const v = flags[name];
|
|
94
|
+
if (v === undefined)
|
|
95
|
+
return [];
|
|
96
|
+
if (Array.isArray(v))
|
|
97
|
+
return v;
|
|
98
|
+
if (typeof v === "string")
|
|
99
|
+
return [v];
|
|
100
|
+
return [String(v)];
|
|
101
|
+
}
|
|
102
|
+
// packages/cli/src/core/config.ts
|
|
103
|
+
import { existsSync, readFileSync } from "fs";
|
|
22
104
|
import { resolve } from "path";
|
|
23
|
-
|
|
105
|
+
var DEFAULT_CONFIG = {
|
|
106
|
+
routing: "nest",
|
|
107
|
+
view: "inertia",
|
|
108
|
+
orm: "drizzle",
|
|
109
|
+
database: {
|
|
110
|
+
driver: "bun-sqlite",
|
|
111
|
+
url: "app.db"
|
|
112
|
+
},
|
|
113
|
+
inertia: {
|
|
114
|
+
frontend: "react",
|
|
115
|
+
ssr: true,
|
|
116
|
+
version: "1.0.0"
|
|
117
|
+
},
|
|
118
|
+
paths: {
|
|
119
|
+
app: "app",
|
|
120
|
+
controllers: "app/controllers",
|
|
121
|
+
services: "app/services",
|
|
122
|
+
modules: "app/modules",
|
|
123
|
+
models: "app/models",
|
|
124
|
+
migrations: "app/database/migrations",
|
|
125
|
+
seeds: "db/seeds",
|
|
126
|
+
middleware: "app/middleware",
|
|
127
|
+
dto: "app/dto"
|
|
128
|
+
},
|
|
129
|
+
moduleStyle: "nest",
|
|
130
|
+
auth: undefined,
|
|
131
|
+
queue: undefined
|
|
132
|
+
};
|
|
133
|
+
var CONFIG_CANDIDATES = [
|
|
134
|
+
"nx.config.ts",
|
|
135
|
+
"nx.config.js",
|
|
136
|
+
"nx.config.mjs",
|
|
137
|
+
".nxrc.json"
|
|
138
|
+
];
|
|
139
|
+
async function loadConfig(cwd = process.cwd()) {
|
|
140
|
+
let config = {};
|
|
141
|
+
let configSource = "<defaults>";
|
|
142
|
+
for (const candidate of CONFIG_CANDIDATES) {
|
|
143
|
+
const path = resolve(cwd, candidate);
|
|
144
|
+
if (!existsSync(path))
|
|
145
|
+
continue;
|
|
146
|
+
try {
|
|
147
|
+
if (candidate.endsWith(".json")) {
|
|
148
|
+
const raw = readFileSync(path, "utf8");
|
|
149
|
+
config = JSON.parse(raw);
|
|
150
|
+
} else {
|
|
151
|
+
try {
|
|
152
|
+
const mod = await import(path);
|
|
153
|
+
config = mod.default ?? mod;
|
|
154
|
+
} catch (importErr) {
|
|
155
|
+
console.warn(`[nx] Could not dynamically import ${candidate}: ${importErr.message ?? importErr}. Falling back to defaults.`);
|
|
156
|
+
config = {};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
configSource = candidate;
|
|
160
|
+
break;
|
|
161
|
+
} catch (err) {
|
|
162
|
+
throw new Error(`Failed to load ${candidate}: ${err.message ?? String(err)}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const merged = mergeWithEnv(DEFAULT_CONFIG, config);
|
|
166
|
+
assertEnum("routing", merged.routing, [
|
|
167
|
+
"nest",
|
|
168
|
+
"adonis",
|
|
169
|
+
"functional",
|
|
170
|
+
"mixed"
|
|
171
|
+
]);
|
|
172
|
+
assertEnum("view", merged.view, ["rendu", "edge", "inertia", "none"]);
|
|
173
|
+
assertEnum("orm", merged.orm, ["drizzle", "prisma", "kysely", "none"]);
|
|
174
|
+
assertEnum("database.driver", merged.database.driver, [
|
|
175
|
+
"bun-sqlite",
|
|
176
|
+
"node-sqlite",
|
|
177
|
+
"libsql",
|
|
178
|
+
"postgres",
|
|
179
|
+
"mysql",
|
|
180
|
+
"none"
|
|
181
|
+
]);
|
|
182
|
+
assertEnum("inertia.frontend", merged.inertia.frontend, [
|
|
183
|
+
"react",
|
|
184
|
+
"vue",
|
|
185
|
+
"svelte",
|
|
186
|
+
"solid"
|
|
187
|
+
]);
|
|
188
|
+
if (process.env["NX_DEBUG"] === "1") {
|
|
189
|
+
console.log(`[nx] config source: ${configSource}`);
|
|
190
|
+
}
|
|
191
|
+
return merged;
|
|
192
|
+
}
|
|
193
|
+
function mergeWithEnv(base, override) {
|
|
194
|
+
const env = process.env;
|
|
195
|
+
const merged = {
|
|
196
|
+
...base,
|
|
197
|
+
...override,
|
|
198
|
+
database: { ...base.database, ...override.database ?? {} },
|
|
199
|
+
inertia: { ...base.inertia, ...override.inertia ?? {} },
|
|
200
|
+
paths: { ...base.paths, ...override.paths ?? {} }
|
|
201
|
+
};
|
|
202
|
+
if (env["NX_ROUTING"])
|
|
203
|
+
merged.routing = env["NX_ROUTING"];
|
|
204
|
+
if (env["NX_VIEW"])
|
|
205
|
+
merged.view = env["NX_VIEW"];
|
|
206
|
+
if (env["NX_ORM"])
|
|
207
|
+
merged.orm = env["NX_ORM"];
|
|
208
|
+
if (env["NX_DATABASE_DRIVER"])
|
|
209
|
+
merged.database.driver = env["NX_DATABASE_DRIVER"];
|
|
210
|
+
if (env["NX_DATABASE_URL"])
|
|
211
|
+
merged.database.url = env["NX_DATABASE_URL"];
|
|
212
|
+
if (env["NX_INERTIA_FRONTEND"])
|
|
213
|
+
merged.inertia.frontend = env["NX_INERTIA_FRONTEND"];
|
|
214
|
+
if (env["NX_INERTIA_SSR"])
|
|
215
|
+
merged.inertia.ssr = env["NX_INERTIA_SSR"] !== "false" && env["NX_INERTIA_SSR"] !== "0";
|
|
216
|
+
if (env["NX_INERTIA_VERSION"])
|
|
217
|
+
merged.inertia.version = env["NX_INERTIA_VERSION"];
|
|
218
|
+
return merged;
|
|
219
|
+
}
|
|
220
|
+
function assertEnum(key, value, allowed) {
|
|
221
|
+
if (!allowed.includes(value)) {
|
|
222
|
+
throw new Error(`Invalid value for ${key}: "${value}". Allowed: ${allowed.join(", ")}.`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// packages/cli/src/core/fs.ts
|
|
226
|
+
import {
|
|
227
|
+
existsSync as existsSync2,
|
|
228
|
+
mkdirSync,
|
|
229
|
+
readFileSync as readFileSync2,
|
|
230
|
+
statSync,
|
|
231
|
+
writeFileSync
|
|
232
|
+
} from "fs";
|
|
233
|
+
import { dirname, isAbsolute, relative, resolve as resolve2 } from "path";
|
|
234
|
+
function writeFile(path, contents, opts = {}) {
|
|
235
|
+
const base = opts.base ?? process.cwd();
|
|
236
|
+
const target = isAbsolute(path) ? path : resolve2(base, path);
|
|
237
|
+
if (opts.skipIfExists && existsSync2(target)) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
241
|
+
writeFileSync(target, contents);
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
function nameVariants(input) {
|
|
245
|
+
const trimmed = input.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
246
|
+
const pascal = trimmed.split(/[\s_-]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).filter(Boolean).join("") || input;
|
|
247
|
+
const camel = pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
248
|
+
const snake = pascal.split(/(?=[A-Z])/).map((w) => w.toLowerCase()).filter(Boolean).join("_");
|
|
249
|
+
const kebab = snake.replace(/_/g, "-");
|
|
250
|
+
return {
|
|
251
|
+
pascal,
|
|
252
|
+
camel,
|
|
253
|
+
snake,
|
|
254
|
+
kebab,
|
|
255
|
+
plural: pluralize(pascal),
|
|
256
|
+
pluralSnake: pluralize(snake),
|
|
257
|
+
pluralKebab: pluralize(kebab)
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function pluralize(s) {
|
|
261
|
+
if (!s)
|
|
262
|
+
return s;
|
|
263
|
+
if (/(s|x|z|ch|sh)$/i.test(s))
|
|
264
|
+
return `${s}es`;
|
|
265
|
+
if (/[^aeiou]y$/i.test(s))
|
|
266
|
+
return `${s.slice(0, -1)}ies`;
|
|
267
|
+
if (/y$/i.test(s))
|
|
268
|
+
return `${s}s`;
|
|
269
|
+
return `${s}s`;
|
|
270
|
+
}
|
|
271
|
+
// packages/cli/src/core/logger.ts
|
|
272
|
+
var USE_COLOR = process.env["NO_COLOR"] === undefined && process.env["FORCE_COLOR"] !== "0" && process.stdout.isTTY === true;
|
|
273
|
+
var wrap = (open, close) => (s) => USE_COLOR ? `\x1B[${open}m${s}\x1B[${close}m` : s;
|
|
274
|
+
var c = {
|
|
275
|
+
reset: wrap(0, 0),
|
|
276
|
+
bold: wrap(1, 22),
|
|
277
|
+
dim: wrap(2, 22),
|
|
278
|
+
red: wrap(31, 39),
|
|
279
|
+
green: wrap(32, 39),
|
|
280
|
+
yellow: wrap(33, 39),
|
|
281
|
+
blue: wrap(34, 39),
|
|
282
|
+
magenta: wrap(35, 39),
|
|
283
|
+
cyan: wrap(36, 39),
|
|
284
|
+
gray: wrap(90, 39)
|
|
285
|
+
};
|
|
286
|
+
var PREFIXES = {
|
|
287
|
+
info: `${c.cyan("\u2139")}`,
|
|
288
|
+
success: `${c.green("\u2714")}`,
|
|
289
|
+
warn: `${c.yellow("\u26A0")}`,
|
|
290
|
+
error: `${c.red("\u2716")}`,
|
|
291
|
+
debug: `${c.gray("\xB7")}`,
|
|
292
|
+
finger: `${c.magenta("\u279C")}`
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
class Logger {
|
|
296
|
+
verbose = false;
|
|
297
|
+
setVerbose(v) {
|
|
298
|
+
this.verbose = v;
|
|
299
|
+
}
|
|
300
|
+
info(message) {
|
|
301
|
+
console.log(`${PREFIXES.info} ${message}`);
|
|
302
|
+
}
|
|
303
|
+
success(message) {
|
|
304
|
+
console.log(`${PREFIXES.success} ${message}`);
|
|
305
|
+
}
|
|
306
|
+
warn(message) {
|
|
307
|
+
console.warn(`${PREFIXES.warn} ${c.yellow(message)}`);
|
|
308
|
+
}
|
|
309
|
+
error(message) {
|
|
310
|
+
console.error(`${PREFIXES.error} ${c.red(message)}`);
|
|
311
|
+
}
|
|
312
|
+
debug(message) {
|
|
313
|
+
if (!this.verbose)
|
|
314
|
+
return;
|
|
315
|
+
console.log(`${PREFIXES.debug} ${c.gray(message)}`);
|
|
316
|
+
}
|
|
317
|
+
finger(message) {
|
|
318
|
+
console.log(`${PREFIXES.finger} ${c.magenta(message)}`);
|
|
319
|
+
}
|
|
320
|
+
table(rows) {
|
|
321
|
+
const labelWidth = Math.max(...rows.map(([l]) => l.length));
|
|
322
|
+
for (const [label, value] of rows) {
|
|
323
|
+
const padded = label.padEnd(labelWidth);
|
|
324
|
+
console.log(` ${c.dim(padded)} ${value}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
heading(text) {
|
|
328
|
+
const bar = "\u2500".repeat(text.length + 4);
|
|
329
|
+
console.log(`
|
|
330
|
+
${c.bold(c.cyan(bar))}`);
|
|
331
|
+
console.log(`${c.bold(c.cyan(` ${text} `))}`);
|
|
332
|
+
console.log(`${c.bold(c.cyan(bar))}
|
|
333
|
+
`);
|
|
334
|
+
}
|
|
335
|
+
blank() {
|
|
336
|
+
console.log("");
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
var logger = new Logger;
|
|
340
|
+
var colors = c;
|
|
341
|
+
// packages/cli/src/core/loose-json.ts
|
|
342
|
+
function parseJsonLoose(text) {
|
|
343
|
+
return Bun.JSON5.parse(text);
|
|
344
|
+
}
|
|
345
|
+
// packages/cli/src/core/prompts.ts
|
|
346
|
+
import { createInterface } from "readline";
|
|
347
|
+
async function prompt(message, options = {}) {
|
|
348
|
+
const interactive = options.interactive ?? true;
|
|
349
|
+
const fallback = options.default ?? options.choices?.[0];
|
|
350
|
+
if (!interactive || !process.stdin.isTTY) {
|
|
351
|
+
if (fallback === undefined) {
|
|
352
|
+
throw new Error(`No default provided for non-interactive prompt: ${message}`);
|
|
353
|
+
}
|
|
354
|
+
return fallback;
|
|
355
|
+
}
|
|
356
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
357
|
+
return new Promise((resolve3) => {
|
|
358
|
+
const suffix = options.choices ? ` [${options.choices.join("/")}]` : "";
|
|
359
|
+
const def = options.default ?? options.choices?.[0] ?? "";
|
|
360
|
+
const promptStr = ` ${message}${suffix} (${def}): `;
|
|
361
|
+
rl.question(promptStr, (answer) => {
|
|
362
|
+
rl.close();
|
|
363
|
+
const trimmed = answer.trim();
|
|
364
|
+
resolve3(trimmed === "" ? def : trimmed);
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async function select(message, choices, options = {}) {
|
|
369
|
+
return prompt(message, { ...options, choices });
|
|
370
|
+
}
|
|
371
|
+
// packages/cli/src/core/template.ts
|
|
372
|
+
var VAR_RE = /\{\{\s*([\w.]+)(?:\s*\|\s*(\w+))?\s*\}\}/;
|
|
373
|
+
var SECTION_RE = /\{\{\s*([#^])\s*([\w.]+)\s*\}\}([\s\S]*?)\{\{\s*\/\s*\2\s*\}\}/g;
|
|
374
|
+
function render(template, context) {
|
|
375
|
+
let out = template.replace(SECTION_RE, (_, kind, key, body) => {
|
|
376
|
+
const v = lookup(context, key);
|
|
377
|
+
const truthy = isTruthy(v);
|
|
378
|
+
if (kind === "#")
|
|
379
|
+
return truthy ? body : "";
|
|
380
|
+
return truthy ? "" : body;
|
|
381
|
+
});
|
|
382
|
+
let prev;
|
|
383
|
+
do {
|
|
384
|
+
prev = out;
|
|
385
|
+
out = out.replace(VAR_RE, (_, key, filter) => {
|
|
386
|
+
const v = lookup(context, key);
|
|
387
|
+
return applyFilter(v === undefined || v === null ? "" : String(v), filter);
|
|
388
|
+
});
|
|
389
|
+
} while (out !== prev);
|
|
390
|
+
return out;
|
|
391
|
+
}
|
|
392
|
+
function lookup(ctx, dotted) {
|
|
393
|
+
if (dotted in ctx)
|
|
394
|
+
return ctx[dotted];
|
|
395
|
+
const parts = dotted.split(".");
|
|
396
|
+
let cur = ctx;
|
|
397
|
+
for (const p of parts) {
|
|
398
|
+
if (cur == null || typeof cur !== "object")
|
|
399
|
+
return;
|
|
400
|
+
cur = cur[p];
|
|
401
|
+
}
|
|
402
|
+
return cur === undefined || cur === null ? undefined : cur;
|
|
403
|
+
}
|
|
404
|
+
function isTruthy(v) {
|
|
405
|
+
if (v === undefined || v === null)
|
|
406
|
+
return false;
|
|
407
|
+
if (typeof v === "string")
|
|
408
|
+
return v.length > 0 && v !== "false" && v !== "0";
|
|
409
|
+
if (typeof v === "number")
|
|
410
|
+
return v !== 0;
|
|
411
|
+
if (typeof v === "boolean")
|
|
412
|
+
return v;
|
|
413
|
+
if (Array.isArray(v))
|
|
414
|
+
return v.length > 0;
|
|
415
|
+
return Object.keys(v).length > 0;
|
|
416
|
+
}
|
|
417
|
+
function applyFilter(value, filter) {
|
|
418
|
+
switch (filter) {
|
|
419
|
+
case undefined:
|
|
420
|
+
case "raw":
|
|
421
|
+
return value;
|
|
422
|
+
case "upper":
|
|
423
|
+
return value.toUpperCase();
|
|
424
|
+
case "lower":
|
|
425
|
+
return value.toLowerCase();
|
|
426
|
+
case "pascal":
|
|
427
|
+
return toPascal(value);
|
|
428
|
+
case "camel":
|
|
429
|
+
return toCamel(value);
|
|
430
|
+
case "snake":
|
|
431
|
+
return toSnake(value);
|
|
432
|
+
case "kebab":
|
|
433
|
+
return toKebab(value);
|
|
434
|
+
case "plural":
|
|
435
|
+
return pluralize2(value);
|
|
436
|
+
case "singular":
|
|
437
|
+
return singularize(value);
|
|
438
|
+
default:
|
|
439
|
+
throw new Error(`Unknown template filter: ${filter}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
function splitWords(s) {
|
|
443
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[\s_-]+/).filter(Boolean);
|
|
444
|
+
}
|
|
445
|
+
function toPascal(s) {
|
|
446
|
+
return splitWords(s).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join("");
|
|
447
|
+
}
|
|
448
|
+
function toCamel(s) {
|
|
449
|
+
const p = toPascal(s);
|
|
450
|
+
return p.charAt(0).toLowerCase() + p.slice(1);
|
|
451
|
+
}
|
|
452
|
+
function toSnake(s) {
|
|
453
|
+
return splitWords(s).map((w) => w.toLowerCase()).join("_");
|
|
454
|
+
}
|
|
455
|
+
function toKebab(s) {
|
|
456
|
+
return splitWords(s).map((w) => w.toLowerCase()).join("-");
|
|
457
|
+
}
|
|
458
|
+
function pluralize2(s) {
|
|
459
|
+
if (!s)
|
|
460
|
+
return s;
|
|
461
|
+
if (/(s|x|z|ch|sh)$/i.test(s))
|
|
462
|
+
return `${s}es`;
|
|
463
|
+
if (/[^aeiou]y$/i.test(s))
|
|
464
|
+
return `${s.slice(0, -1)}ies`;
|
|
465
|
+
if (/y$/i.test(s))
|
|
466
|
+
return `${s}s`;
|
|
467
|
+
return `${s}s`;
|
|
468
|
+
}
|
|
469
|
+
function singularize(s) {
|
|
470
|
+
if (!s)
|
|
471
|
+
return s;
|
|
472
|
+
if (/(ses|xes|zes|ches|shes)$/i.test(s))
|
|
473
|
+
return s.slice(0, -2);
|
|
474
|
+
if (/ies$/i.test(s))
|
|
475
|
+
return `${s.slice(0, -3)}y`;
|
|
476
|
+
if (/s$/i.test(s) && s.length > 1)
|
|
477
|
+
return s.slice(0, -1);
|
|
478
|
+
return s;
|
|
479
|
+
}
|
|
480
|
+
// packages/cli/src/commands/info.ts
|
|
24
481
|
var infoCommand = {
|
|
25
482
|
name: "info",
|
|
26
483
|
aliases: ["i"],
|
|
@@ -71,7 +528,7 @@ var infoCommand = {
|
|
|
71
528
|
logger.blank();
|
|
72
529
|
logger.info(colors.bold("Working directory"));
|
|
73
530
|
logger.blank();
|
|
74
|
-
logger.info(` ${
|
|
531
|
+
logger.info(` ${resolve3(ctx.cwd)}`);
|
|
75
532
|
logger.blank();
|
|
76
533
|
return 0;
|
|
77
534
|
}
|
|
@@ -79,10 +536,8 @@ var infoCommand = {
|
|
|
79
536
|
var info_default = infoCommand;
|
|
80
537
|
|
|
81
538
|
// packages/cli/src/commands/init.ts
|
|
82
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
83
|
-
import { resolve as
|
|
84
|
-
import { flagBool, logger as logger2, render, select } from "@nexusts/core/index.js";
|
|
85
|
-
import { parseJsonLoose } from "@nexusts/core/loose-json.js";
|
|
539
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
540
|
+
import { resolve as resolve4 } from "path";
|
|
86
541
|
|
|
87
542
|
// packages/cli/src/templates/controller/adonis.ts
|
|
88
543
|
var adonis_default = `
|
|
@@ -187,7 +642,7 @@ import { Body, Controller, Delete, Get, Inject, Param, Post, Put } from '@nexust
|
|
|
187
642
|
import { z } from 'zod';
|
|
188
643
|
import { Validate } from '@nexusts/core';
|
|
189
644
|
import { {{ service }} } from '../services/{{ kebab }}.service.js';
|
|
190
|
-
{{#hasInertia}}import { Inertia } from '@nexusts/view
|
|
645
|
+
{{#hasInertia}}import { Inertia } from '@nexusts/view';{{/hasInertia}}
|
|
191
646
|
|
|
192
647
|
const Create{{ name }}Schema = z.object({
|
|
193
648
|
// TODO: define fields
|
|
@@ -570,15 +1025,17 @@ export default defineConfig({
|
|
|
570
1025
|
|
|
571
1026
|
// packages/cli/src/templates/repository/repository.ts
|
|
572
1027
|
var repository_default = `
|
|
573
|
-
import { Injectable } from '@nexusts/core';
|
|
574
|
-
import { DrizzleRepository } from '@nexusts/drizzle';
|
|
575
|
-
import { {{
|
|
1028
|
+
import { Injectable, Inject } from '@nexusts/core';
|
|
1029
|
+
import { DrizzleRepository, DrizzleService } from '@nexusts/drizzle';
|
|
1030
|
+
import { {{ snake }} } from '../models/{{ kebab }}.model.js';
|
|
576
1031
|
import type { {{ name }}, New{{ name }} } from '../models/{{ kebab }}.model.js';
|
|
577
1032
|
|
|
578
1033
|
@Injectable()
|
|
579
|
-
export class {{ repository }} extends DrizzleRepository<typeof {{
|
|
580
|
-
constructor(
|
|
581
|
-
|
|
1034
|
+
export class {{ repository }} extends DrizzleRepository<typeof {{ snake }}, {{ name }}> {
|
|
1035
|
+
constructor(
|
|
1036
|
+
@Inject(DrizzleService.TOKEN) db: DrizzleService,
|
|
1037
|
+
) {
|
|
1038
|
+
super(db, {{ snake }});
|
|
582
1039
|
}
|
|
583
1040
|
}
|
|
584
1041
|
`.trimStart();
|
|
@@ -586,7 +1043,9 @@ export class {{ repository }} extends DrizzleRepository<typeof {{ tableName }},
|
|
|
586
1043
|
// packages/cli/src/templates/service/service.ts
|
|
587
1044
|
var service_default = `
|
|
588
1045
|
import { Inject, Injectable } from '@nexusts/core';
|
|
589
|
-
{{#hasRepo}}import {
|
|
1046
|
+
{{#hasRepo}}import { eq } from '@nexusts/drizzle';
|
|
1047
|
+
import { {{ repository }} } from '../repositories/{{ kebab }}.repository.js';
|
|
1048
|
+
import { {{ snake }} } from '../models/{{ kebab }}.model.js';{{/hasRepo}}
|
|
590
1049
|
|
|
591
1050
|
@Injectable()
|
|
592
1051
|
export class {{ name }}Service {
|
|
@@ -600,7 +1059,7 @@ export class {{ name }}Service {
|
|
|
600
1059
|
}
|
|
601
1060
|
|
|
602
1061
|
async findOne(id: number) {
|
|
603
|
-
{{#hasRepo}}return this.{{ repositoryCamel }}.findOne(id);{{/hasRepo}}
|
|
1062
|
+
{{#hasRepo}}return this.{{ repositoryCamel }}.findOne(eq({{ snake }}.id, id));{{/hasRepo}}
|
|
604
1063
|
{{^hasRepo}}return { id }; // TODO: implement{{/hasRepo}}
|
|
605
1064
|
}
|
|
606
1065
|
|
|
@@ -610,12 +1069,12 @@ export class {{ name }}Service {
|
|
|
610
1069
|
}
|
|
611
1070
|
|
|
612
1071
|
async update(id: number, data: any) {
|
|
613
|
-
{{#hasRepo}}return this.{{ repositoryCamel }}.update(id, data);{{/hasRepo}}
|
|
1072
|
+
{{#hasRepo}}return this.{{ repositoryCamel }}.update(eq({{ snake }}.id, id), data);{{/hasRepo}}
|
|
614
1073
|
{{^hasRepo}}return { id, ...data }; // TODO: implement{{/hasRepo}}
|
|
615
1074
|
}
|
|
616
1075
|
|
|
617
1076
|
async delete(id: number) {
|
|
618
|
-
{{#hasRepo}}return this.{{ repositoryCamel }}.delete(id);{{/hasRepo}}
|
|
1077
|
+
{{#hasRepo}}return this.{{ repositoryCamel }}.delete(eq({{ snake }}.id, id));{{/hasRepo}}
|
|
619
1078
|
{{^hasRepo}}return { removed: id }; // TODO: implement{{/hasRepo}}
|
|
620
1079
|
}
|
|
621
1080
|
}
|
|
@@ -706,10 +1165,10 @@ var initCommand = {
|
|
|
706
1165
|
async run(ctx) {
|
|
707
1166
|
const interactive = !flagBool(ctx.flags, "no-interaction", false);
|
|
708
1167
|
const force = flagBool(ctx.flags, "force", false);
|
|
709
|
-
const target =
|
|
710
|
-
if (!
|
|
711
|
-
|
|
712
|
-
|
|
1168
|
+
const target = resolve4(ctx.cwd, ctx.flags["target"] ?? ".");
|
|
1169
|
+
if (!existsSync3(target)) {
|
|
1170
|
+
logger.error(`Target directory does not exist: ${target}`);
|
|
1171
|
+
logger.info(`Run \`nx new <name>\` to create a fresh project, or \`mkdir -p ${target}\` first.`);
|
|
713
1172
|
return 1;
|
|
714
1173
|
}
|
|
715
1174
|
const routing = ctx.flags["style"] ?? await select("Routing style", ["nest", "adonis", "functional"], {
|
|
@@ -738,7 +1197,7 @@ var initCommand = {
|
|
|
738
1197
|
{ path: "package.json", mode: "merge-pkg" },
|
|
739
1198
|
{ path: "tsconfig.json", mode: "merge-tsconfig" },
|
|
740
1199
|
{ path: "public/.gitkeep", mode: "write" },
|
|
741
|
-
{ path: "resources/views/welcome.html", mode: "write" },
|
|
1200
|
+
...view !== "none" ? [{ path: "resources/views/welcome.html", mode: "write" }] : [],
|
|
742
1201
|
{ path: ".env", mode: "skip" },
|
|
743
1202
|
{ path: ".env.local", mode: "skip" },
|
|
744
1203
|
{ path: ".gitignore", mode: "skip" },
|
|
@@ -750,23 +1209,33 @@ var initCommand = {
|
|
|
750
1209
|
const created = [];
|
|
751
1210
|
const skipped = [];
|
|
752
1211
|
const merged = [];
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
1212
|
+
mkdirSync2(resolve4(target, "app/controllers"), { recursive: true });
|
|
1213
|
+
mkdirSync2(resolve4(target, "public"), { recursive: true });
|
|
1214
|
+
if (view !== "none") {
|
|
1215
|
+
mkdirSync2(resolve4(target, "resources/views"), { recursive: true });
|
|
1216
|
+
}
|
|
756
1217
|
for (const entry of plan) {
|
|
757
|
-
const abs =
|
|
758
|
-
const exists =
|
|
1218
|
+
const abs = resolve4(target, entry.path);
|
|
1219
|
+
const exists = existsSync3(abs);
|
|
759
1220
|
if (entry.mode === "merge-pkg") {
|
|
1221
|
+
const coreDeps = {
|
|
1222
|
+
"@nexusts/core": "*",
|
|
1223
|
+
"reflect-metadata": "^0.2.2",
|
|
1224
|
+
hono: "^4.6.0",
|
|
1225
|
+
zod: "^3.23.8"
|
|
1226
|
+
};
|
|
1227
|
+
if (orm === "drizzle") {
|
|
1228
|
+
coreDeps["@nexusts/drizzle"] = "*";
|
|
1229
|
+
coreDeps["drizzle-orm"] = "^0.45.0";
|
|
1230
|
+
}
|
|
1231
|
+
if (view !== "none") {
|
|
1232
|
+
coreDeps["@nexusts/static"] = "*";
|
|
1233
|
+
}
|
|
760
1234
|
if (exists) {
|
|
761
|
-
mergePackageJson(abs,
|
|
762
|
-
"@nexusts/core": "*",
|
|
763
|
-
"reflect-metadata": "^0.2.2",
|
|
764
|
-
hono: "^4.6.0",
|
|
765
|
-
zod: "^3.23.8"
|
|
766
|
-
});
|
|
1235
|
+
mergePackageJson(abs, coreDeps);
|
|
767
1236
|
merged.push(entry.path);
|
|
768
1237
|
} else {
|
|
769
|
-
|
|
1238
|
+
writeFileSync2(abs, JSON.stringify({
|
|
770
1239
|
name: target.split("/").pop() ?? "nexus-app",
|
|
771
1240
|
version: "0.1.0",
|
|
772
1241
|
type: "module",
|
|
@@ -778,12 +1247,7 @@ var initCommand = {
|
|
|
778
1247
|
test: "vitest",
|
|
779
1248
|
nx: "nx"
|
|
780
1249
|
},
|
|
781
|
-
dependencies:
|
|
782
|
-
"@nexusts/core": "*",
|
|
783
|
-
"reflect-metadata": "^0.2.2",
|
|
784
|
-
hono: "^4.6.0",
|
|
785
|
-
zod: "^3.23.8"
|
|
786
|
-
}
|
|
1250
|
+
dependencies: coreDeps
|
|
787
1251
|
}, null, 2));
|
|
788
1252
|
created.push(entry.path);
|
|
789
1253
|
}
|
|
@@ -797,7 +1261,7 @@ var initCommand = {
|
|
|
797
1261
|
});
|
|
798
1262
|
merged.push(entry.path);
|
|
799
1263
|
} else {
|
|
800
|
-
|
|
1264
|
+
writeFileSync2(abs, defaultTsconfig());
|
|
801
1265
|
created.push(entry.path);
|
|
802
1266
|
}
|
|
803
1267
|
continue;
|
|
@@ -818,32 +1282,32 @@ var initCommand = {
|
|
|
818
1282
|
inertiaVersion: "1.0.0",
|
|
819
1283
|
targetName: target.split("/").pop() ?? "nexus-app"
|
|
820
1284
|
});
|
|
821
|
-
|
|
1285
|
+
writeFileSync2(abs, content);
|
|
822
1286
|
created.push(entry.path);
|
|
823
1287
|
}
|
|
824
|
-
|
|
825
|
-
|
|
1288
|
+
logger.success(`initialized NexusTS in ${target}`);
|
|
1289
|
+
logger.blank();
|
|
826
1290
|
if (created.length) {
|
|
827
|
-
|
|
1291
|
+
logger.heading("Created");
|
|
828
1292
|
for (const f of created)
|
|
829
|
-
|
|
1293
|
+
logger.info(` + ${f}`);
|
|
830
1294
|
}
|
|
831
1295
|
if (merged.length) {
|
|
832
|
-
|
|
1296
|
+
logger.heading("Merged into existing files");
|
|
833
1297
|
for (const f of merged)
|
|
834
|
-
|
|
1298
|
+
logger.info(` ~ ${f}`);
|
|
835
1299
|
}
|
|
836
1300
|
if (skipped.length) {
|
|
837
|
-
|
|
1301
|
+
logger.heading("Skipped (already exist; use --force to overwrite)");
|
|
838
1302
|
for (const f of skipped)
|
|
839
|
-
|
|
1303
|
+
logger.info(` - ${f}`);
|
|
840
1304
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
1305
|
+
logger.blank();
|
|
1306
|
+
logger.heading("Next steps");
|
|
1307
|
+
logger.info(` cd ${target === ctx.cwd ? "." : target}`);
|
|
1308
|
+
logger.info(` bun install`);
|
|
1309
|
+
logger.info(` bun run dev`);
|
|
1310
|
+
logger.blank();
|
|
847
1311
|
return 0;
|
|
848
1312
|
}
|
|
849
1313
|
};
|
|
@@ -910,44 +1374,66 @@ DATABASE_URL=app.db
|
|
|
910
1374
|
# DATABASE_URL=postgres://user:password@localhost:5432/myapp
|
|
911
1375
|
# SESSION_SECRET=my-local-secret
|
|
912
1376
|
`;
|
|
913
|
-
case "app/main.ts":
|
|
1377
|
+
case "app/main.ts": {
|
|
1378
|
+
const hasView = ctx.view !== "none";
|
|
1379
|
+
const staticMw = hasView ? `import { StaticModule } from '@nexusts/static';
|
|
1380
|
+
` + `const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static' });
|
|
1381
|
+
` : "";
|
|
1382
|
+
const staticOpt = hasView ? `
|
|
1383
|
+
middleware: [staticMiddleware],` : "";
|
|
914
1384
|
return `import 'reflect-metadata';
|
|
915
1385
|
import { Application } from '@nexusts/core';
|
|
916
|
-
import {
|
|
917
|
-
import { AppModule } from './app.module.js';
|
|
1386
|
+
${staticMw}import { AppModule } from './app.module.js';
|
|
918
1387
|
|
|
919
|
-
const app = new Application(AppModule
|
|
920
|
-
|
|
921
|
-
|
|
1388
|
+
const app = new Application(AppModule, {
|
|
1389
|
+
logging: true,
|
|
1390
|
+
port: Number(process.env['PORT'] ?? 3000),${staticOpt}
|
|
1391
|
+
});
|
|
922
1392
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
console.log("[nexusjs] Listening on http://localhost:" + port);
|
|
1393
|
+
await app.listen();
|
|
1394
|
+
console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
|
|
926
1395
|
`;
|
|
927
|
-
|
|
928
|
-
|
|
1396
|
+
}
|
|
1397
|
+
case "app/app.module.ts": {
|
|
1398
|
+
const hasOrm = ctx.orm === "drizzle";
|
|
1399
|
+
const ormImport = hasOrm ? `import { DrizzleModule } from '@nexusts/drizzle';
|
|
1400
|
+
` : "";
|
|
1401
|
+
const forRootDialect = ctx.dbDriver === "bun-sqlite" ? "bun-sqlite" : "sqlite";
|
|
1402
|
+
const forRootFile = ctx.dbUrl || "app.db";
|
|
1403
|
+
const ormBlock = hasOrm ? ` DrizzleModule.forRoot({
|
|
1404
|
+
dialect: '` + forRootDialect + `',
|
|
1405
|
+
connection: { filename: '` + forRootFile + `' },
|
|
1406
|
+
logging: true,
|
|
1407
|
+
})` : "";
|
|
1408
|
+
return `${ormImport}import { Module } from '@nexusts/core';
|
|
929
1409
|
import { HomeController } from './controllers/home.controller.js';
|
|
930
1410
|
|
|
931
1411
|
@Module({
|
|
932
|
-
imports: [
|
|
1412
|
+
imports: [${hasOrm ? `
|
|
1413
|
+
${ormBlock},
|
|
1414
|
+
` : ""} ],
|
|
933
1415
|
controllers: [HomeController],
|
|
934
1416
|
})
|
|
935
1417
|
export class AppModule {}
|
|
936
1418
|
`;
|
|
937
|
-
|
|
1419
|
+
}
|
|
1420
|
+
case "app/controllers/home.controller.ts": {
|
|
1421
|
+
const hasView = ctx.view !== "none";
|
|
1422
|
+
const body = hasView ? `{
|
|
1423
|
+
view: 'welcome.html',
|
|
1424
|
+
data: { year: new Date().getFullYear() },
|
|
1425
|
+
}` : `{ status: 200, body: { message: 'Hello from NexusTS!' } }`;
|
|
938
1426
|
return `import { Controller, Get } from '@nexusts/core';
|
|
939
1427
|
|
|
940
1428
|
@Controller('/')
|
|
941
1429
|
export class HomeController {
|
|
942
1430
|
@Get('/')
|
|
943
1431
|
index() {
|
|
944
|
-
return {
|
|
945
|
-
view: 'welcome.html',
|
|
946
|
-
data: { year: new Date().getFullYear() },
|
|
947
|
-
};
|
|
1432
|
+
return ${body};
|
|
948
1433
|
}
|
|
949
1434
|
}
|
|
950
1435
|
`;
|
|
1436
|
+
}
|
|
951
1437
|
case "README.md":
|
|
952
1438
|
return `# ${ctx.targetName}
|
|
953
1439
|
|
|
@@ -988,7 +1474,7 @@ function defaultTsconfig() {
|
|
|
988
1474
|
`;
|
|
989
1475
|
}
|
|
990
1476
|
function mergePackageJson(path, additions) {
|
|
991
|
-
const raw =
|
|
1477
|
+
const raw = readFileSync3(path, "utf8");
|
|
992
1478
|
const pkg = parseJsonLoose(raw);
|
|
993
1479
|
let changed = false;
|
|
994
1480
|
if (!pkg["type"]) {
|
|
@@ -1025,12 +1511,12 @@ function mergePackageJson(path, additions) {
|
|
|
1025
1511
|
}
|
|
1026
1512
|
pkg["dependencies"] = deps;
|
|
1027
1513
|
if (changed) {
|
|
1028
|
-
|
|
1514
|
+
writeFileSync2(path, JSON.stringify(pkg, null, 2) + `
|
|
1029
1515
|
`);
|
|
1030
1516
|
}
|
|
1031
1517
|
}
|
|
1032
1518
|
function mergeTsconfig(path, additions) {
|
|
1033
|
-
const raw =
|
|
1519
|
+
const raw = readFileSync3(path, "utf8");
|
|
1034
1520
|
const cfg = parseJsonLoose(raw);
|
|
1035
1521
|
const co = cfg.compilerOptions ?? {};
|
|
1036
1522
|
let changed = false;
|
|
@@ -1052,20 +1538,14 @@ function mergeTsconfig(path, additions) {
|
|
|
1052
1538
|
if (changed) {
|
|
1053
1539
|
cfg.compilerOptions = co;
|
|
1054
1540
|
cfg.include = inc;
|
|
1055
|
-
|
|
1541
|
+
writeFileSync2(path, JSON.stringify(cfg, null, 2) + `
|
|
1056
1542
|
`);
|
|
1057
1543
|
}
|
|
1058
1544
|
}
|
|
1059
1545
|
var init_default = initCommand;
|
|
1060
1546
|
|
|
1061
1547
|
// packages/cli/src/commands/make-auth.ts
|
|
1062
|
-
import { resolve as
|
|
1063
|
-
import {
|
|
1064
|
-
flagList,
|
|
1065
|
-
logger as logger3,
|
|
1066
|
-
render as render2,
|
|
1067
|
-
writeFile
|
|
1068
|
-
} from "@nexusts/core/index.js";
|
|
1548
|
+
import { resolve as resolve5 } from "path";
|
|
1069
1549
|
var AUTH_INSTANCE_TEMPLATE = `/**
|
|
1070
1550
|
* Better-auth instance \u2014 generated by \`nx make:auth\`.
|
|
1071
1551
|
*
|
|
@@ -1157,7 +1637,7 @@ var makeAuthCommand = {
|
|
|
1157
1637
|
}
|
|
1158
1638
|
],
|
|
1159
1639
|
async run(ctx) {
|
|
1160
|
-
|
|
1640
|
+
logger.heading("Scaffolding auth module");
|
|
1161
1641
|
const providers = flagList(ctx.flags, "provider");
|
|
1162
1642
|
const jwtEnabled = ctx.flags["jwt"] === true;
|
|
1163
1643
|
const passkeyEnabled = ctx.flags["passkey"] === true;
|
|
@@ -1171,7 +1651,7 @@ var makeAuthCommand = {
|
|
|
1171
1651
|
envVar: known?.env ?? p.toUpperCase()
|
|
1172
1652
|
};
|
|
1173
1653
|
});
|
|
1174
|
-
const authCode =
|
|
1654
|
+
const authCode = render(AUTH_INSTANCE_TEMPLATE, {
|
|
1175
1655
|
jwt: jwtEnabled,
|
|
1176
1656
|
passkey: passkeyEnabled,
|
|
1177
1657
|
providers: providers.length > 0,
|
|
@@ -1180,44 +1660,43 @@ var makeAuthCommand = {
|
|
|
1180
1660
|
passkeyRpId: rpId,
|
|
1181
1661
|
passkeyOrigin: Array.isArray(origin) ? origin.join(",") : origin
|
|
1182
1662
|
});
|
|
1183
|
-
const authOut =
|
|
1663
|
+
const authOut = resolve5(ctx.cwd, "app/auth/auth.ts");
|
|
1184
1664
|
if (writeFile(authOut, authCode)) {
|
|
1185
|
-
|
|
1665
|
+
logger.success(`created ${authOut}`);
|
|
1186
1666
|
} else {
|
|
1187
|
-
|
|
1667
|
+
logger.warn(`skipped (exists): ${authOut}`);
|
|
1188
1668
|
}
|
|
1189
|
-
const envCode =
|
|
1669
|
+
const envCode = render(ENV_EXAMPLE_TEMPLATE, {
|
|
1190
1670
|
providers: providers.length > 0,
|
|
1191
1671
|
entries
|
|
1192
1672
|
});
|
|
1193
|
-
const envOut =
|
|
1673
|
+
const envOut = resolve5(ctx.cwd, ".env.example");
|
|
1194
1674
|
if (writeFile(envOut, envCode, { skipIfExists: true })) {
|
|
1195
|
-
|
|
1675
|
+
logger.success(`created ${envOut}`);
|
|
1196
1676
|
} else {
|
|
1197
|
-
|
|
1677
|
+
logger.warn(`skipped (exists): ${envOut}`);
|
|
1198
1678
|
}
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1679
|
+
logger.blank();
|
|
1680
|
+
logger.heading("Next steps");
|
|
1681
|
+
logger.info("1. Add a secret to .env:");
|
|
1682
|
+
logger.info(" BETTER_AUTH_SECRET=$(openssl rand -base64 32)");
|
|
1683
|
+
logger.info("2. Wire the module in AppModule:");
|
|
1684
|
+
logger.info(` ${MODULE_UPDATE_HINT.trim()}`);
|
|
1205
1685
|
if (providers.length > 0) {
|
|
1206
|
-
|
|
1686
|
+
logger.info(`3. Set up OAuth credentials for: ${providers.join(", ")}`);
|
|
1207
1687
|
}
|
|
1208
1688
|
if (passkeyEnabled) {
|
|
1209
|
-
|
|
1689
|
+
logger.info("4. Configure passkey RP ID + origin for your domain.");
|
|
1210
1690
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1691
|
+
logger.info("5. Run `bun --hot app/main.ts` to start the server.");
|
|
1692
|
+
logger.blank();
|
|
1213
1693
|
return 0;
|
|
1214
1694
|
}
|
|
1215
1695
|
};
|
|
1216
1696
|
var make_auth_default = makeAuthCommand;
|
|
1217
1697
|
|
|
1218
1698
|
// packages/cli/src/commands/make-controller.ts
|
|
1219
|
-
import { resolve as
|
|
1220
|
-
import { logger as logger4, nameVariants, render as render3, writeFile as writeFile2 } from "@nexusts/core/index.js";
|
|
1699
|
+
import { resolve as resolve6 } from "path";
|
|
1221
1700
|
var makeControllerCommand = {
|
|
1222
1701
|
name: "make:controller",
|
|
1223
1702
|
aliases: ["mc", "make-controller"],
|
|
@@ -1241,20 +1720,20 @@ var makeControllerCommand = {
|
|
|
1241
1720
|
async run(ctx) {
|
|
1242
1721
|
const name = ctx.positional[0];
|
|
1243
1722
|
if (!name) {
|
|
1244
|
-
|
|
1723
|
+
logger.error("Usage: nx make:controller <Name>");
|
|
1245
1724
|
return 1;
|
|
1246
1725
|
}
|
|
1247
1726
|
const variants = nameVariants(name);
|
|
1248
1727
|
const style = ctx.flags["style"] ?? ctx.config.routing;
|
|
1249
1728
|
if (!["nest", "adonis", "functional"].includes(style)) {
|
|
1250
|
-
|
|
1729
|
+
logger.error(`Unknown style: ${style}. Allowed: nest, adonis, functional.`);
|
|
1251
1730
|
return 1;
|
|
1252
1731
|
}
|
|
1253
1732
|
const skipService = ctx.flags["no-service"] === true;
|
|
1254
1733
|
const serviceName = `${variants.pascal}Service`;
|
|
1255
1734
|
const serviceCamel = variants.camel + "Service";
|
|
1256
1735
|
const tpl = templates.controller[style];
|
|
1257
|
-
const code =
|
|
1736
|
+
const code = render(tpl, {
|
|
1258
1737
|
name: variants.pascal,
|
|
1259
1738
|
camel: variants.camel,
|
|
1260
1739
|
kebab: variants.kebab,
|
|
@@ -1263,29 +1742,22 @@ var makeControllerCommand = {
|
|
|
1263
1742
|
service: serviceName,
|
|
1264
1743
|
serviceCamel
|
|
1265
1744
|
}).replace(/import .*\n/g, skipService ? (m) => m.includes("services/") ? "" : m : (m) => m);
|
|
1266
|
-
const out =
|
|
1267
|
-
const ok =
|
|
1745
|
+
const out = resolve6(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
|
|
1746
|
+
const ok = writeFile(out, code, { skipIfExists: false });
|
|
1268
1747
|
if (!ok) {
|
|
1269
|
-
|
|
1748
|
+
logger.error(`Refusing to overwrite existing file: ${out}`);
|
|
1270
1749
|
return 1;
|
|
1271
1750
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1751
|
+
logger.success(`created ${out}`);
|
|
1752
|
+
logger.finger(`edit ${variants.kebab}.controller.ts and add to a module.`);
|
|
1274
1753
|
return 0;
|
|
1275
1754
|
}
|
|
1276
1755
|
};
|
|
1277
1756
|
var make_controller_default = makeControllerCommand;
|
|
1278
1757
|
|
|
1279
1758
|
// packages/cli/src/commands/make-crud.ts
|
|
1280
|
-
import { mkdirSync as
|
|
1281
|
-
import { dirname, resolve as
|
|
1282
|
-
import {
|
|
1283
|
-
flagBool as flagBool2,
|
|
1284
|
-
logger as logger5,
|
|
1285
|
-
nameVariants as nameVariants2,
|
|
1286
|
-
render as render4,
|
|
1287
|
-
writeFile as writeFile3
|
|
1288
|
-
} from "@nexusts/core/index.js";
|
|
1759
|
+
import { mkdirSync as mkdirSync3 } from "fs";
|
|
1760
|
+
import { dirname as dirname2, resolve as resolve7 } from "path";
|
|
1289
1761
|
|
|
1290
1762
|
// packages/cli/src/templates/model/drizzle-dialect.ts
|
|
1291
1763
|
function renderDrizzleDialect(dialect) {
|
|
@@ -1299,8 +1771,8 @@ import { ${spec.imports.join(", ")} } from '${spec.importPath}';
|
|
|
1299
1771
|
export const {{ snake }} = ${spec.tableFn}('{{ tableName }}', {
|
|
1300
1772
|
id: ${spec.idHelper}('id').primaryKey(${spec.idOpts}),
|
|
1301
1773
|
{{ columns }}
|
|
1302
|
-
createdAt: ${spec.tsTimestamp}('created_at'${spec.tsDateMode}).notNull()
|
|
1303
|
-
updatedAt: ${spec.tsTimestamp}('updated_at'${spec.tsDateMode}).
|
|
1774
|
+
createdAt: ${spec.tsTimestamp}('created_at'${spec.tsDateMode}).notNull()${spec.defaultTs},
|
|
1775
|
+
updatedAt: ${spec.tsTimestamp}('updated_at'${spec.tsDateMode})${spec.defaultTsUpdate},
|
|
1304
1776
|
});
|
|
1305
1777
|
|
|
1306
1778
|
export type {{ name }} = typeof {{ snake }}.$inferSelect;
|
|
@@ -1323,16 +1795,20 @@ var DIALECT_SPECS = {
|
|
|
1323
1795
|
idHelper: "serial",
|
|
1324
1796
|
idOpts: "",
|
|
1325
1797
|
tsTimestamp: "timestamp",
|
|
1326
|
-
tsDateMode: ""
|
|
1798
|
+
tsDateMode: "",
|
|
1799
|
+
defaultTs: ".defaultNow()",
|
|
1800
|
+
defaultTsUpdate: ""
|
|
1327
1801
|
},
|
|
1328
1802
|
"bun-sqlite": {
|
|
1329
|
-
imports: ["sqliteTable", "integer", "text"
|
|
1803
|
+
imports: ["sqliteTable", "integer", "text"],
|
|
1330
1804
|
importPath: "drizzle-orm/sqlite-core",
|
|
1331
1805
|
tableFn: "sqliteTable",
|
|
1332
1806
|
idHelper: "integer",
|
|
1333
1807
|
idOpts: "{ autoIncrement: true }",
|
|
1334
|
-
tsTimestamp: "
|
|
1335
|
-
tsDateMode: ",
|
|
1808
|
+
tsTimestamp: "text",
|
|
1809
|
+
tsDateMode: "",
|
|
1810
|
+
defaultTs: `.default("(datetime('now'))")`,
|
|
1811
|
+
defaultTsUpdate: ""
|
|
1336
1812
|
},
|
|
1337
1813
|
sqlite: {
|
|
1338
1814
|
imports: ["sqliteTable", "integer", "text", "real"],
|
|
@@ -1341,7 +1817,9 @@ var DIALECT_SPECS = {
|
|
|
1341
1817
|
idHelper: "integer",
|
|
1342
1818
|
idOpts: "{ autoIncrement: true }",
|
|
1343
1819
|
tsTimestamp: "integer",
|
|
1344
|
-
tsDateMode: ", { mode: 'timestamp' }"
|
|
1820
|
+
tsDateMode: ", { mode: 'timestamp' }",
|
|
1821
|
+
defaultTs: ".$defaultFn(() => Date.now())",
|
|
1822
|
+
defaultTsUpdate: ".$defaultFn(() => Date.now())"
|
|
1345
1823
|
},
|
|
1346
1824
|
d1: {
|
|
1347
1825
|
imports: ["sqliteTable", "integer", "text", "real"],
|
|
@@ -1350,7 +1828,9 @@ var DIALECT_SPECS = {
|
|
|
1350
1828
|
idHelper: "integer",
|
|
1351
1829
|
idOpts: "{ autoIncrement: true }",
|
|
1352
1830
|
tsTimestamp: "integer",
|
|
1353
|
-
tsDateMode: ", { mode: 'timestamp' }"
|
|
1831
|
+
tsDateMode: ", { mode: 'timestamp' }",
|
|
1832
|
+
defaultTs: ".$defaultFn(() => Date.now())",
|
|
1833
|
+
defaultTsUpdate: ".$defaultFn(() => Date.now())"
|
|
1354
1834
|
},
|
|
1355
1835
|
mysql: {
|
|
1356
1836
|
imports: [
|
|
@@ -1367,7 +1847,9 @@ var DIALECT_SPECS = {
|
|
|
1367
1847
|
idHelper: "int",
|
|
1368
1848
|
idOpts: "{ autoIncrement: true }",
|
|
1369
1849
|
tsTimestamp: "timestamp",
|
|
1370
|
-
tsDateMode: ""
|
|
1850
|
+
tsDateMode: "",
|
|
1851
|
+
defaultTs: ".defaultNow()",
|
|
1852
|
+
defaultTsUpdate: ""
|
|
1371
1853
|
}
|
|
1372
1854
|
};
|
|
1373
1855
|
function mapDrizzleType(dialect, type) {
|
|
@@ -1418,26 +1900,26 @@ var makeCrudCommand = {
|
|
|
1418
1900
|
async run(ctx) {
|
|
1419
1901
|
const name = ctx.positional[0];
|
|
1420
1902
|
if (!name) {
|
|
1421
|
-
|
|
1903
|
+
logger.error("Usage: nx make:crud <Name>");
|
|
1422
1904
|
return 1;
|
|
1423
1905
|
}
|
|
1424
|
-
const variants =
|
|
1906
|
+
const variants = nameVariants(name);
|
|
1425
1907
|
const style = ctx.flags["style"] ?? ctx.config.routing;
|
|
1426
1908
|
const orm = ctx.flags["orm"] ?? ctx.config.orm;
|
|
1427
1909
|
const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
|
|
1428
|
-
const noRepo =
|
|
1429
|
-
const noTest =
|
|
1430
|
-
const hasInertia = ctx.config.view === "inertia" && !
|
|
1910
|
+
const noRepo = flagBool(ctx.flags, "no-repo", false) || orm === "none";
|
|
1911
|
+
const noTest = flagBool(ctx.flags, "no-test", false);
|
|
1912
|
+
const hasInertia = ctx.config.view === "inertia" && !flagBool(ctx.flags, "no-views", false);
|
|
1431
1913
|
const controller = `${variants.pascal}Controller`;
|
|
1432
1914
|
const service = `${variants.pascal}Service`;
|
|
1433
1915
|
const repository = `${variants.pascal}Repository`;
|
|
1434
1916
|
const tableName = variants.pluralSnake;
|
|
1435
1917
|
const viewComponent = `${variants.pascal}s/Index`;
|
|
1436
1918
|
const viewShowComponent = `${variants.pascal}s/Show`;
|
|
1437
|
-
|
|
1919
|
+
logger.heading(`Scaffolding ${variants.pascal} (style=${style}, view=${ctx.config.view}, orm=${orm})`);
|
|
1438
1920
|
const written = [];
|
|
1439
1921
|
{
|
|
1440
|
-
const code =
|
|
1922
|
+
const code = render(templates.crud.controller, {
|
|
1441
1923
|
name: variants.pascal,
|
|
1442
1924
|
camel: variants.camel,
|
|
1443
1925
|
kebab: variants.kebab,
|
|
@@ -1450,28 +1932,29 @@ var makeCrudCommand = {
|
|
|
1450
1932
|
viewShowComponent,
|
|
1451
1933
|
hasInertia
|
|
1452
1934
|
});
|
|
1453
|
-
const out =
|
|
1454
|
-
if (!
|
|
1455
|
-
|
|
1935
|
+
const out = resolve7(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
|
|
1936
|
+
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
1937
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
1456
1938
|
} else {
|
|
1457
|
-
|
|
1939
|
+
logger.success(`created ${out}`);
|
|
1458
1940
|
written.push(out);
|
|
1459
1941
|
}
|
|
1460
1942
|
}
|
|
1461
1943
|
{
|
|
1462
|
-
const code =
|
|
1944
|
+
const code = render(templates.service, {
|
|
1463
1945
|
name: variants.pascal,
|
|
1464
1946
|
camel: variants.camel,
|
|
1465
1947
|
kebab: variants.kebab,
|
|
1948
|
+
snake: variants.snake,
|
|
1466
1949
|
hasRepo: !noRepo,
|
|
1467
1950
|
repository,
|
|
1468
1951
|
repositoryCamel: variants.camel + "Repository"
|
|
1469
1952
|
});
|
|
1470
|
-
const out =
|
|
1471
|
-
if (!
|
|
1472
|
-
|
|
1953
|
+
const out = resolve7(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
|
|
1954
|
+
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
1955
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
1473
1956
|
} else {
|
|
1474
|
-
|
|
1957
|
+
logger.success(`created ${out}`);
|
|
1475
1958
|
written.push(out);
|
|
1476
1959
|
}
|
|
1477
1960
|
}
|
|
@@ -1480,7 +1963,7 @@ var makeCrudCommand = {
|
|
|
1480
1963
|
let code;
|
|
1481
1964
|
if (orm === "drizzle") {
|
|
1482
1965
|
const tpl = renderDrizzleDialect(dialect);
|
|
1483
|
-
code =
|
|
1966
|
+
code = render(tpl, {
|
|
1484
1967
|
name: variants.pascal,
|
|
1485
1968
|
camel: variants.camel,
|
|
1486
1969
|
kebab: variants.kebab,
|
|
@@ -1491,7 +1974,7 @@ var makeCrudCommand = {
|
|
|
1491
1974
|
});
|
|
1492
1975
|
} else {
|
|
1493
1976
|
const tpl = templates.model[orm];
|
|
1494
|
-
code =
|
|
1977
|
+
code = render(tpl, {
|
|
1495
1978
|
name: variants.pascal,
|
|
1496
1979
|
camel: variants.camel,
|
|
1497
1980
|
kebab: variants.kebab,
|
|
@@ -1501,46 +1984,47 @@ var makeCrudCommand = {
|
|
|
1501
1984
|
prismaBlock: ""
|
|
1502
1985
|
});
|
|
1503
1986
|
}
|
|
1504
|
-
const out =
|
|
1505
|
-
if (!
|
|
1506
|
-
|
|
1987
|
+
const out = resolve7(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
|
|
1988
|
+
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
1989
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
1507
1990
|
} else {
|
|
1508
|
-
|
|
1991
|
+
logger.success(`created ${out}`);
|
|
1509
1992
|
written.push(out);
|
|
1510
1993
|
}
|
|
1511
1994
|
}
|
|
1512
|
-
const repoCode =
|
|
1995
|
+
const repoCode = render(templates.repository, {
|
|
1513
1996
|
name: variants.pascal,
|
|
1514
1997
|
camel: variants.camel,
|
|
1515
1998
|
kebab: variants.kebab,
|
|
1999
|
+
snake: variants.snake,
|
|
1516
2000
|
tableName,
|
|
1517
2001
|
repository
|
|
1518
2002
|
});
|
|
1519
|
-
const repoOut =
|
|
1520
|
-
|
|
1521
|
-
if (!
|
|
1522
|
-
|
|
2003
|
+
const repoOut = resolve7(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
|
|
2004
|
+
mkdirSync3(dirname2(repoOut), { recursive: true });
|
|
2005
|
+
if (!writeFile(repoOut, repoCode, { skipIfExists: true })) {
|
|
2006
|
+
logger.warn(`skipped (exists): ${repoOut}`);
|
|
1523
2007
|
} else {
|
|
1524
|
-
|
|
2008
|
+
logger.success(`created ${repoOut}`);
|
|
1525
2009
|
written.push(repoOut);
|
|
1526
2010
|
}
|
|
1527
2011
|
}
|
|
1528
2012
|
{
|
|
1529
|
-
const code =
|
|
2013
|
+
const code = render(templates.crud.dto, {
|
|
1530
2014
|
name: variants.pascal,
|
|
1531
2015
|
camel: variants.camel,
|
|
1532
2016
|
kebab: variants.kebab
|
|
1533
2017
|
});
|
|
1534
|
-
const out =
|
|
1535
|
-
if (!
|
|
1536
|
-
|
|
2018
|
+
const out = resolve7(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
|
|
2019
|
+
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2020
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
1537
2021
|
} else {
|
|
1538
|
-
|
|
2022
|
+
logger.success(`created ${out}`);
|
|
1539
2023
|
written.push(out);
|
|
1540
2024
|
}
|
|
1541
2025
|
}
|
|
1542
2026
|
{
|
|
1543
|
-
const code =
|
|
2027
|
+
const code = render(templates.crud.module, {
|
|
1544
2028
|
name: variants.pascal,
|
|
1545
2029
|
camel: variants.camel,
|
|
1546
2030
|
kebab: variants.kebab,
|
|
@@ -1549,39 +2033,39 @@ var makeCrudCommand = {
|
|
|
1549
2033
|
repository,
|
|
1550
2034
|
hasRepo: !noRepo
|
|
1551
2035
|
});
|
|
1552
|
-
const out =
|
|
1553
|
-
if (!
|
|
1554
|
-
|
|
2036
|
+
const out = resolve7(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
|
|
2037
|
+
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2038
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
1555
2039
|
} else {
|
|
1556
|
-
|
|
2040
|
+
logger.success(`created ${out}`);
|
|
1557
2041
|
written.push(out);
|
|
1558
2042
|
}
|
|
1559
2043
|
}
|
|
1560
2044
|
if (!noTest) {
|
|
1561
|
-
const code =
|
|
2045
|
+
const code = render(templates.crud.test, {
|
|
1562
2046
|
name: variants.pascal,
|
|
1563
2047
|
camel: variants.camel,
|
|
1564
2048
|
kebab: variants.kebab,
|
|
1565
2049
|
controller,
|
|
1566
2050
|
service
|
|
1567
2051
|
});
|
|
1568
|
-
const out =
|
|
1569
|
-
if (!
|
|
1570
|
-
|
|
2052
|
+
const out = resolve7(ctx.cwd, "tests", `${variants.kebab}.test.ts`);
|
|
2053
|
+
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2054
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
1571
2055
|
} else {
|
|
1572
|
-
|
|
2056
|
+
logger.success(`created ${out}`);
|
|
1573
2057
|
written.push(out);
|
|
1574
2058
|
}
|
|
1575
2059
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
2060
|
+
logger.blank();
|
|
2061
|
+
logger.heading("Next steps");
|
|
2062
|
+
logger.info(`1. Review the generated files:`);
|
|
1579
2063
|
for (const f of written)
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
2064
|
+
logger.info(` ${f}`);
|
|
2065
|
+
logger.info(`2. Add ${variants.pascal}Module to AppModule.imports.`);
|
|
2066
|
+
logger.info(`3. ${noRepo ? "" : `Run \`bunx drizzle-kit migrate\` (or your migration tool).`}`);
|
|
2067
|
+
logger.info(`4. Start the dev server: \`bun --hot app/main.ts\`.`);
|
|
2068
|
+
logger.blank();
|
|
1585
2069
|
return 0;
|
|
1586
2070
|
}
|
|
1587
2071
|
};
|
|
@@ -1601,8 +2085,7 @@ function renderDrizzleColumns(dialect) {
|
|
|
1601
2085
|
var make_crud_default = makeCrudCommand;
|
|
1602
2086
|
|
|
1603
2087
|
// packages/cli/src/commands/make-listener.ts
|
|
1604
|
-
import { resolve as
|
|
1605
|
-
import { logger as logger6, nameVariants as nameVariants3, render as render5, writeFile as writeFile4 } from "@nexusts/core/index.js";
|
|
2088
|
+
import { resolve as resolve8 } from "path";
|
|
1606
2089
|
var LISTENER_TEMPLATE = `
|
|
1607
2090
|
import { Inject, Injectable } from '@nexusts/core';
|
|
1608
2091
|
import { EventService, OnEvent } from '@nexusts/events';
|
|
@@ -1645,36 +2128,35 @@ var makeListenerCommand = {
|
|
|
1645
2128
|
async run(ctx) {
|
|
1646
2129
|
const name = ctx.positional[0];
|
|
1647
2130
|
if (!name) {
|
|
1648
|
-
|
|
2131
|
+
logger.error("Usage: nx make:listener <Name>");
|
|
1649
2132
|
return 1;
|
|
1650
2133
|
}
|
|
1651
|
-
const variants =
|
|
1652
|
-
const code =
|
|
2134
|
+
const variants = nameVariants(name);
|
|
2135
|
+
const code = render(LISTENER_TEMPLATE, {
|
|
1653
2136
|
name: variants.pascal,
|
|
1654
2137
|
kebab: variants.kebab
|
|
1655
2138
|
});
|
|
1656
|
-
const out =
|
|
1657
|
-
if (
|
|
1658
|
-
|
|
2139
|
+
const out = resolve8(ctx.cwd, "app/events/listeners", `${variants.kebab}.listener.ts`);
|
|
2140
|
+
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2141
|
+
logger.success(`created ${out}`);
|
|
1659
2142
|
} else {
|
|
1660
|
-
|
|
2143
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
1661
2144
|
}
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
2145
|
+
logger.blank();
|
|
2146
|
+
logger.heading("Next steps");
|
|
2147
|
+
logger.info("1. Add @OnEvent('your.event') handlers to the class.");
|
|
2148
|
+
logger.info(`2. Import + register at boot:`);
|
|
2149
|
+
logger.info(` scanForListeners(listener, events)`);
|
|
2150
|
+
logger.info(`3. Emit events from anywhere:`);
|
|
2151
|
+
logger.info(` await events.emit('user.created', { userId: '1' })`);
|
|
2152
|
+
logger.blank();
|
|
1670
2153
|
return 0;
|
|
1671
2154
|
}
|
|
1672
2155
|
};
|
|
1673
2156
|
var make_listener_default = makeListenerCommand;
|
|
1674
2157
|
|
|
1675
2158
|
// packages/cli/src/commands/make-middleware.ts
|
|
1676
|
-
import { resolve as
|
|
1677
|
-
import { logger as logger7, nameVariants as nameVariants4, render as render6, writeFile as writeFile5 } from "@nexusts/core/index.js";
|
|
2159
|
+
import { resolve as resolve9 } from "path";
|
|
1678
2160
|
var makeMiddlewareCommand = {
|
|
1679
2161
|
name: "make:middleware",
|
|
1680
2162
|
aliases: ["mwm", "make-middleware"],
|
|
@@ -1684,25 +2166,24 @@ var makeMiddlewareCommand = {
|
|
|
1684
2166
|
async run(ctx) {
|
|
1685
2167
|
const name = ctx.positional[0];
|
|
1686
2168
|
if (!name) {
|
|
1687
|
-
|
|
2169
|
+
logger.error("Usage: nx make:middleware <Name>");
|
|
1688
2170
|
return 1;
|
|
1689
2171
|
}
|
|
1690
|
-
const variants =
|
|
1691
|
-
const code =
|
|
2172
|
+
const variants = nameVariants(name);
|
|
2173
|
+
const code = render(templates.middleware, {
|
|
1692
2174
|
name: variants.pascal
|
|
1693
2175
|
});
|
|
1694
|
-
const out =
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
2176
|
+
const out = resolve9(ctx.cwd, ctx.config.paths.middleware, `${variants.kebab}.middleware.ts`);
|
|
2177
|
+
writeFile(out, code);
|
|
2178
|
+
logger.success(`created ${out}`);
|
|
2179
|
+
logger.finger(`register with: app.server.app.use('*', new ${variants.pascal}Middleware().handle)`);
|
|
1698
2180
|
return 0;
|
|
1699
2181
|
}
|
|
1700
2182
|
};
|
|
1701
2183
|
var make_middleware_default = makeMiddlewareCommand;
|
|
1702
2184
|
|
|
1703
2185
|
// packages/cli/src/commands/make-migration.ts
|
|
1704
|
-
import { resolve as
|
|
1705
|
-
import { logger as logger8, nameVariants as nameVariants5, render as render7, writeFile as writeFile6 } from "@nexusts/core/index.js";
|
|
2186
|
+
import { resolve as resolve10 } from "path";
|
|
1706
2187
|
var makeMigrationCommand = {
|
|
1707
2188
|
name: "make:migration",
|
|
1708
2189
|
aliases: ["mkm", "make-migration"],
|
|
@@ -1730,14 +2211,14 @@ var makeMigrationCommand = {
|
|
|
1730
2211
|
async run(ctx) {
|
|
1731
2212
|
const name = ctx.positional[0];
|
|
1732
2213
|
if (!name) {
|
|
1733
|
-
|
|
2214
|
+
logger.error("Usage: nx make:migration <Name> [--dialect ...]");
|
|
1734
2215
|
return 1;
|
|
1735
2216
|
}
|
|
1736
2217
|
const orm = ctx.flags["orm"] ?? ctx.config.orm;
|
|
1737
2218
|
const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
|
|
1738
2219
|
const isDrizzle = orm === "drizzle";
|
|
1739
2220
|
const useGenericSql = orm === "none" || orm === "prisma" || orm === "kysely";
|
|
1740
|
-
const variants =
|
|
2221
|
+
const variants = nameVariants(name);
|
|
1741
2222
|
const tableName = inferTableName(name);
|
|
1742
2223
|
const colsFlag = ctx.flags["columns"];
|
|
1743
2224
|
const cols = parseColumns(colsFlag ?? "title:text");
|
|
@@ -1747,11 +2228,11 @@ var makeMigrationCommand = {
|
|
|
1747
2228
|
let extension;
|
|
1748
2229
|
if (isDrizzle) {
|
|
1749
2230
|
if (!isValidDialect(dialect)) {
|
|
1750
|
-
|
|
2231
|
+
logger.error(`Unsupported drizzle dialect: ${dialect}. Allowed: postgres, mysql, sqlite, bun-sqlite, d1.`);
|
|
1751
2232
|
return 1;
|
|
1752
2233
|
}
|
|
1753
2234
|
code = renderDrizzleDialect(dialect);
|
|
1754
|
-
code =
|
|
2235
|
+
code = render(code, {
|
|
1755
2236
|
name: variants.pascal,
|
|
1756
2237
|
snake: variants.snake,
|
|
1757
2238
|
tableName,
|
|
@@ -1761,7 +2242,7 @@ var makeMigrationCommand = {
|
|
|
1761
2242
|
extension = "ts";
|
|
1762
2243
|
} else if (useGenericSql) {
|
|
1763
2244
|
const tpl = templates.migration.sql;
|
|
1764
|
-
code =
|
|
2245
|
+
code = render(tpl, {
|
|
1765
2246
|
name: variants.pascal,
|
|
1766
2247
|
snake: variants.snake,
|
|
1767
2248
|
tableName,
|
|
@@ -1770,17 +2251,17 @@ var makeMigrationCommand = {
|
|
|
1770
2251
|
});
|
|
1771
2252
|
extension = "sql";
|
|
1772
2253
|
} else {
|
|
1773
|
-
|
|
2254
|
+
logger.error(`Unsupported ORM for migration: ${orm}. Allowed: drizzle, none, prisma, kysely.`);
|
|
1774
2255
|
return 1;
|
|
1775
2256
|
}
|
|
1776
2257
|
const filename = `${formatTimestamp(new Date)}_${variants.snake}.${extension}`;
|
|
1777
|
-
const out =
|
|
1778
|
-
|
|
1779
|
-
|
|
2258
|
+
const out = resolve10(ctx.cwd, ctx.config.paths.migrations, filename);
|
|
2259
|
+
writeFile(out, code);
|
|
2260
|
+
logger.success(`created ${out}`);
|
|
1780
2261
|
if (isDrizzle) {
|
|
1781
|
-
|
|
2262
|
+
logger.finger(`run \`nx migrate\` to apply pending migrations.`);
|
|
1782
2263
|
} else {
|
|
1783
|
-
|
|
2264
|
+
logger.finger(`run \`bunx drizzle-kit migrate\` or your migration tool.`);
|
|
1784
2265
|
}
|
|
1785
2266
|
return 0;
|
|
1786
2267
|
}
|
|
@@ -1799,8 +2280,8 @@ function inferTableName(input) {
|
|
|
1799
2280
|
}
|
|
1800
2281
|
function parseColumns(input) {
|
|
1801
2282
|
const list = Array.isArray(input) ? input : input.split(",");
|
|
1802
|
-
return list.map((s) => s.trim()).filter(Boolean).map((
|
|
1803
|
-
const [name, type = "text"] =
|
|
2283
|
+
return list.map((s) => s.trim()).filter(Boolean).map((c2) => {
|
|
2284
|
+
const [name, type = "text"] = c2.split(":");
|
|
1804
2285
|
return [name, type];
|
|
1805
2286
|
});
|
|
1806
2287
|
}
|
|
@@ -1862,14 +2343,7 @@ function formatTimestamp(d) {
|
|
|
1862
2343
|
var make_migration_default = makeMigrationCommand;
|
|
1863
2344
|
|
|
1864
2345
|
// packages/cli/src/commands/make-model.ts
|
|
1865
|
-
import { resolve as
|
|
1866
|
-
import {
|
|
1867
|
-
flagList as flagList2,
|
|
1868
|
-
logger as logger9,
|
|
1869
|
-
nameVariants as nameVariants6,
|
|
1870
|
-
render as render8,
|
|
1871
|
-
writeFile as writeFile7
|
|
1872
|
-
} from "@nexusts/core/index.js";
|
|
2346
|
+
import { resolve as resolve11 } from "path";
|
|
1873
2347
|
var makeModelCommand = {
|
|
1874
2348
|
name: "make:model",
|
|
1875
2349
|
aliases: ["mmodel", "make-model"],
|
|
@@ -1898,17 +2372,17 @@ var makeModelCommand = {
|
|
|
1898
2372
|
async run(ctx) {
|
|
1899
2373
|
const name = ctx.positional[0];
|
|
1900
2374
|
if (!name) {
|
|
1901
|
-
|
|
2375
|
+
logger.error("Usage: nx make:model <Name> [--columns name:type,...] [--dialect ...]");
|
|
1902
2376
|
return 1;
|
|
1903
2377
|
}
|
|
1904
2378
|
const orm = ctx.flags["orm"] ?? ctx.config.orm;
|
|
1905
2379
|
if (orm !== "drizzle" && orm !== "prisma" && orm !== "kysely") {
|
|
1906
|
-
|
|
2380
|
+
logger.error(`Unsupported ORM: ${orm}. Allowed: drizzle, prisma, kysely. Use --orm or set "orm" in nx.config.ts.`);
|
|
1907
2381
|
return 1;
|
|
1908
2382
|
}
|
|
1909
|
-
const variants =
|
|
2383
|
+
const variants = nameVariants(name);
|
|
1910
2384
|
const tableName = variants.pluralSnake;
|
|
1911
|
-
const colsFlag =
|
|
2385
|
+
const colsFlag = flagList(ctx.flags, "columns");
|
|
1912
2386
|
const columns = colsFlag.length > 0 ? colsFlag : ["title:text"];
|
|
1913
2387
|
const columnLines = renderColumns(columns, orm, ctx.flags["dialect"]);
|
|
1914
2388
|
const prismaBlock = renderPrismaBlock(variants.pascal, columns);
|
|
@@ -1916,11 +2390,11 @@ var makeModelCommand = {
|
|
|
1916
2390
|
if (orm === "drizzle") {
|
|
1917
2391
|
const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
|
|
1918
2392
|
if (!isValidDialect2(dialect)) {
|
|
1919
|
-
|
|
2393
|
+
logger.error(`Unsupported drizzle dialect: ${dialect}. Allowed: postgres, mysql, sqlite, bun-sqlite, d1.`);
|
|
1920
2394
|
return 1;
|
|
1921
2395
|
}
|
|
1922
2396
|
code = renderDrizzleDialect(dialect);
|
|
1923
|
-
code =
|
|
2397
|
+
code = render(code, {
|
|
1924
2398
|
name: variants.pascal,
|
|
1925
2399
|
camel: variants.camel,
|
|
1926
2400
|
kebab: variants.kebab,
|
|
@@ -1931,7 +2405,7 @@ var makeModelCommand = {
|
|
|
1931
2405
|
});
|
|
1932
2406
|
} else {
|
|
1933
2407
|
const tpl = templates.model[orm];
|
|
1934
|
-
code =
|
|
2408
|
+
code = render(tpl, {
|
|
1935
2409
|
name: variants.pascal,
|
|
1936
2410
|
camel: variants.camel,
|
|
1937
2411
|
kebab: variants.kebab,
|
|
@@ -1941,12 +2415,12 @@ var makeModelCommand = {
|
|
|
1941
2415
|
prismaBlock
|
|
1942
2416
|
});
|
|
1943
2417
|
}
|
|
1944
|
-
const out =
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
2418
|
+
const out = resolve11(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
|
|
2419
|
+
writeFile(out, code);
|
|
2420
|
+
logger.success(`created ${out}`);
|
|
2421
|
+
logger.finger(`run \`nx make:migration create_${tableName}_table\` to scaffold a migration.`);
|
|
1948
2422
|
if (orm === "drizzle") {
|
|
1949
|
-
|
|
2423
|
+
logger.finger(`run \`nx migrate\` to apply pending migrations to the database.`);
|
|
1950
2424
|
}
|
|
1951
2425
|
return 0;
|
|
1952
2426
|
}
|
|
@@ -1955,10 +2429,10 @@ function isValidDialect2(d) {
|
|
|
1955
2429
|
return ["postgres", "mysql", "sqlite", "bun-sqlite", "d1"].includes(d);
|
|
1956
2430
|
}
|
|
1957
2431
|
function renderColumns(cols, orm, dialect) {
|
|
1958
|
-
const flat = cols.flatMap((
|
|
2432
|
+
const flat = cols.flatMap((c2) => c2.split(",")).map((c2) => c2.trim()).filter(Boolean);
|
|
1959
2433
|
return flat.map((col) => {
|
|
1960
2434
|
const [colName, colType = "text"] = col.split(":");
|
|
1961
|
-
const tsName =
|
|
2435
|
+
const tsName = toCamel2(colName);
|
|
1962
2436
|
switch (orm) {
|
|
1963
2437
|
case "drizzle": {
|
|
1964
2438
|
const d = dialect ?? "bun-sqlite";
|
|
@@ -1977,8 +2451,8 @@ function renderColumns(cols, orm, dialect) {
|
|
|
1977
2451
|
`);
|
|
1978
2452
|
}
|
|
1979
2453
|
function renderPrismaBlock(modelName, cols) {
|
|
1980
|
-
const fieldLines = cols.map((
|
|
1981
|
-
const [name, type = "String"] =
|
|
2454
|
+
const fieldLines = cols.map((c2) => {
|
|
2455
|
+
const [name, type = "String"] = c2.split(":");
|
|
1982
2456
|
return ` ${name.padEnd(16)} ${capitalize(type)}`;
|
|
1983
2457
|
}).join(`
|
|
1984
2458
|
`);
|
|
@@ -1991,8 +2465,8 @@ ${fieldLines.split(`
|
|
|
1991
2465
|
* updatedAt DateTime @updatedAt
|
|
1992
2466
|
* }`;
|
|
1993
2467
|
}
|
|
1994
|
-
function
|
|
1995
|
-
return s.replace(/_([a-z])/g, (_,
|
|
2468
|
+
function toCamel2(s) {
|
|
2469
|
+
return s.replace(/_([a-z])/g, (_, c2) => c2.toUpperCase());
|
|
1996
2470
|
}
|
|
1997
2471
|
function capitalize(s) {
|
|
1998
2472
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
@@ -2000,14 +2474,7 @@ function capitalize(s) {
|
|
|
2000
2474
|
var make_model_default = makeModelCommand;
|
|
2001
2475
|
|
|
2002
2476
|
// packages/cli/src/commands/make-module.ts
|
|
2003
|
-
import { resolve as
|
|
2004
|
-
import {
|
|
2005
|
-
flagBool as flagBool3,
|
|
2006
|
-
logger as logger10,
|
|
2007
|
-
nameVariants as nameVariants7,
|
|
2008
|
-
render as render9,
|
|
2009
|
-
writeFile as writeFile8
|
|
2010
|
-
} from "@nexusts/core/index.js";
|
|
2477
|
+
import { resolve as resolve12 } from "path";
|
|
2011
2478
|
var makeModuleCommand = {
|
|
2012
2479
|
name: "make:module",
|
|
2013
2480
|
aliases: ["mm", "make-module"],
|
|
@@ -2025,14 +2492,14 @@ var makeModuleCommand = {
|
|
|
2025
2492
|
async run(ctx) {
|
|
2026
2493
|
const name = ctx.positional[0];
|
|
2027
2494
|
if (!name) {
|
|
2028
|
-
|
|
2495
|
+
logger.error("Usage: nx make:module <Name>");
|
|
2029
2496
|
return 1;
|
|
2030
2497
|
}
|
|
2031
|
-
const variants =
|
|
2032
|
-
const hasController = !
|
|
2033
|
-
const hasService = !
|
|
2034
|
-
const hasRepo = !
|
|
2035
|
-
const code =
|
|
2498
|
+
const variants = nameVariants(name);
|
|
2499
|
+
const hasController = !flagBool(ctx.flags, "no-controller", false);
|
|
2500
|
+
const hasService = !flagBool(ctx.flags, "no-service", false);
|
|
2501
|
+
const hasRepo = !flagBool(ctx.flags, "no-repo", false) && ctx.config.orm !== "none";
|
|
2502
|
+
const code = render(templates.module, {
|
|
2036
2503
|
name: variants.pascal,
|
|
2037
2504
|
kebab: variants.kebab,
|
|
2038
2505
|
controller: `${variants.pascal}Controller`,
|
|
@@ -2041,24 +2508,17 @@ var makeModuleCommand = {
|
|
|
2041
2508
|
hasService,
|
|
2042
2509
|
hasRepo
|
|
2043
2510
|
});
|
|
2044
|
-
const out =
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2511
|
+
const out = resolve12(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
|
|
2512
|
+
writeFile(out, code);
|
|
2513
|
+
logger.success(`created ${out}`);
|
|
2514
|
+
logger.finger(`add ${variants.pascal}Module to AppModule.imports.`);
|
|
2048
2515
|
return 0;
|
|
2049
2516
|
}
|
|
2050
2517
|
};
|
|
2051
2518
|
var make_module_default = makeModuleCommand;
|
|
2052
2519
|
|
|
2053
2520
|
// packages/cli/src/commands/make-queue.ts
|
|
2054
|
-
import { resolve as
|
|
2055
|
-
import {
|
|
2056
|
-
flagBool as flagBool4,
|
|
2057
|
-
logger as logger11,
|
|
2058
|
-
nameVariants as nameVariants8,
|
|
2059
|
-
render as render10,
|
|
2060
|
-
writeFile as writeFile9
|
|
2061
|
-
} from "@nexusts/core/index.js";
|
|
2521
|
+
import { resolve as resolve13 } from "path";
|
|
2062
2522
|
var WORKER_TEMPLATE = `
|
|
2063
2523
|
import { Inject, Injectable } from '@nexusts/core';
|
|
2064
2524
|
import { QueueService, OnQueueReady } from '@nexusts/queue';
|
|
@@ -2171,58 +2631,57 @@ var makeQueueCommand = {
|
|
|
2171
2631
|
async run(ctx) {
|
|
2172
2632
|
const name = ctx.positional[0];
|
|
2173
2633
|
if (!name) {
|
|
2174
|
-
|
|
2634
|
+
logger.error("Usage: nx make:queue <Name>");
|
|
2175
2635
|
return 1;
|
|
2176
2636
|
}
|
|
2177
|
-
const variants =
|
|
2637
|
+
const variants = nameVariants(name);
|
|
2178
2638
|
const backend = ctx.flags["backend"] ?? ctx.config.queue?.backend ?? "memory";
|
|
2179
2639
|
if (!["bullmq", "cloudflare", "memory"].includes(backend)) {
|
|
2180
|
-
|
|
2640
|
+
logger.error(`Unknown backend: ${backend}. Allowed: bullmq, cloudflare, memory.`);
|
|
2181
2641
|
return 1;
|
|
2182
2642
|
}
|
|
2183
|
-
|
|
2184
|
-
if (!
|
|
2185
|
-
const code =
|
|
2643
|
+
logger.heading(`Scaffolding ${variants.pascal} (backend=${backend})`);
|
|
2644
|
+
if (!flagBool(ctx.flags, "no-worker", false)) {
|
|
2645
|
+
const code = render(WORKER_TEMPLATE, {
|
|
2186
2646
|
name: variants.pascal,
|
|
2187
2647
|
kebab: variants.kebab
|
|
2188
2648
|
});
|
|
2189
|
-
const out =
|
|
2190
|
-
if (
|
|
2191
|
-
|
|
2649
|
+
const out = resolve13(ctx.cwd, "app/queue/workers", `${variants.kebab}.worker.ts`);
|
|
2650
|
+
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2651
|
+
logger.success(`created ${out}`);
|
|
2192
2652
|
} else {
|
|
2193
|
-
|
|
2653
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
2194
2654
|
}
|
|
2195
2655
|
}
|
|
2196
|
-
if (!
|
|
2197
|
-
const code =
|
|
2656
|
+
if (!flagBool(ctx.flags, "no-job", false)) {
|
|
2657
|
+
const code = render(JOB_HELPER_TEMPLATE, {
|
|
2198
2658
|
name: variants.pascal,
|
|
2199
2659
|
kebab: variants.kebab
|
|
2200
2660
|
});
|
|
2201
|
-
const out =
|
|
2202
|
-
if (
|
|
2203
|
-
|
|
2661
|
+
const out = resolve13(ctx.cwd, "app/queue/jobs", `${variants.kebab}.job.ts`);
|
|
2662
|
+
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2663
|
+
logger.success(`created ${out}`);
|
|
2204
2664
|
} else {
|
|
2205
|
-
|
|
2665
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
2206
2666
|
}
|
|
2207
2667
|
}
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2668
|
+
logger.blank();
|
|
2669
|
+
logger.heading("Next steps");
|
|
2670
|
+
logger.info(`1. Add QueueModule.forRoot() to your AppModule.imports:`);
|
|
2671
|
+
logger.info(` QueueModule.forRoot({ backend: '${backend}', ... })`);
|
|
2672
|
+
logger.info(`2. Wire the worker + helper as providers:`);
|
|
2673
|
+
logger.info(render(WIRE_HINT, { name: variants.pascal, kebab: variants.kebab }).split(`
|
|
2214
2674
|
`).map((l) => " " + l).join(`
|
|
2215
2675
|
`));
|
|
2216
|
-
|
|
2217
|
-
|
|
2676
|
+
logger.info(`3. Replace the TODO in ${variants.pascal}Worker.handle() with your logic.`);
|
|
2677
|
+
logger.blank();
|
|
2218
2678
|
return 0;
|
|
2219
2679
|
}
|
|
2220
2680
|
};
|
|
2221
2681
|
var make_queue_default = makeQueueCommand;
|
|
2222
2682
|
|
|
2223
2683
|
// packages/cli/src/commands/make-schedule.ts
|
|
2224
|
-
import { resolve as
|
|
2225
|
-
import { logger as logger12, nameVariants as nameVariants9, render as render11, writeFile as writeFile10 } from "@nexusts/core/index.js";
|
|
2684
|
+
import { resolve as resolve14 } from "path";
|
|
2226
2685
|
var TASK_TEMPLATE = `
|
|
2227
2686
|
import { Inject, Injectable } from '@nexusts/core';
|
|
2228
2687
|
import { Cron, Interval, Timeout, ScheduleService } from '@nexusts/schedule';
|
|
@@ -2270,35 +2729,34 @@ var makeScheduleCommand = {
|
|
|
2270
2729
|
async run(ctx) {
|
|
2271
2730
|
const name = ctx.positional[0];
|
|
2272
2731
|
if (!name) {
|
|
2273
|
-
|
|
2732
|
+
logger.error("Usage: nx make:schedule <Name>");
|
|
2274
2733
|
return 1;
|
|
2275
2734
|
}
|
|
2276
|
-
const variants =
|
|
2277
|
-
const code =
|
|
2735
|
+
const variants = nameVariants(name);
|
|
2736
|
+
const code = render(TASK_TEMPLATE, {
|
|
2278
2737
|
name: variants.pascal,
|
|
2279
2738
|
kebab: variants.kebab
|
|
2280
2739
|
});
|
|
2281
|
-
const out =
|
|
2282
|
-
if (
|
|
2283
|
-
|
|
2740
|
+
const out = resolve14(ctx.cwd, "app/schedule/tasks", `${variants.kebab}.task.ts`);
|
|
2741
|
+
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2742
|
+
logger.success(`created ${out}`);
|
|
2284
2743
|
} else {
|
|
2285
|
-
|
|
2744
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
2286
2745
|
}
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2746
|
+
logger.blank();
|
|
2747
|
+
logger.heading("Next steps");
|
|
2748
|
+
logger.info("1. Add @Cron / @Interval / @Timeout handlers to the class.");
|
|
2749
|
+
logger.info(`2. Import + register at boot:`);
|
|
2750
|
+
logger.info(` scanForSchedulers(task, schedule)`);
|
|
2751
|
+
logger.info(`3. Don't forget to call \`schedule.start()\` to begin the tick.`);
|
|
2752
|
+
logger.blank();
|
|
2294
2753
|
return 0;
|
|
2295
2754
|
}
|
|
2296
2755
|
};
|
|
2297
2756
|
var make_schedule_default = makeScheduleCommand;
|
|
2298
2757
|
|
|
2299
2758
|
// packages/cli/src/commands/make-service.ts
|
|
2300
|
-
import { resolve as
|
|
2301
|
-
import { logger as logger13, nameVariants as nameVariants10, render as render12, writeFile as writeFile11 } from "@nexusts/core/index.js";
|
|
2759
|
+
import { resolve as resolve15 } from "path";
|
|
2302
2760
|
var makeServiceCommand = {
|
|
2303
2761
|
name: "make:service",
|
|
2304
2762
|
aliases: ["ms", "make-service"],
|
|
@@ -2314,14 +2772,14 @@ var makeServiceCommand = {
|
|
|
2314
2772
|
async run(ctx) {
|
|
2315
2773
|
const name = ctx.positional[0];
|
|
2316
2774
|
if (!name) {
|
|
2317
|
-
|
|
2775
|
+
logger.error("Usage: nx make:service <Name>");
|
|
2318
2776
|
return 1;
|
|
2319
2777
|
}
|
|
2320
|
-
const variants =
|
|
2778
|
+
const variants = nameVariants(name);
|
|
2321
2779
|
const hasRepo = ctx.flags["no-repo"] !== true && ctx.config.orm !== "none";
|
|
2322
2780
|
const repository = `${variants.pascal}Repository`;
|
|
2323
2781
|
const repositoryCamel = variants.camel + "Repository";
|
|
2324
|
-
const code =
|
|
2782
|
+
const code = render(templates.service, {
|
|
2325
2783
|
name: variants.pascal,
|
|
2326
2784
|
camel: variants.camel,
|
|
2327
2785
|
kebab: variants.kebab,
|
|
@@ -2329,17 +2787,16 @@ var makeServiceCommand = {
|
|
|
2329
2787
|
repository,
|
|
2330
2788
|
repositoryCamel
|
|
2331
2789
|
});
|
|
2332
|
-
const out =
|
|
2333
|
-
|
|
2334
|
-
|
|
2790
|
+
const out = resolve15(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
|
|
2791
|
+
writeFile(out, code);
|
|
2792
|
+
logger.success(`created ${out}`);
|
|
2335
2793
|
return 0;
|
|
2336
2794
|
}
|
|
2337
2795
|
};
|
|
2338
2796
|
var make_service_default = makeServiceCommand;
|
|
2339
2797
|
|
|
2340
2798
|
// packages/cli/src/commands/make-session.ts
|
|
2341
|
-
import { resolve as
|
|
2342
|
-
import { logger as logger14, nameVariants as nameVariants11, render as render13, writeFile as writeFile12 } from "@nexusts/core/index.js";
|
|
2799
|
+
import { resolve as resolve16 } from "path";
|
|
2343
2800
|
var SESSION_TEMPLATE = `
|
|
2344
2801
|
import { Inject, Injectable } from '@nexusts/core';
|
|
2345
2802
|
import { SessionService } from '@nexusts/session';
|
|
@@ -2393,34 +2850,33 @@ var makeSessionCommand = {
|
|
|
2393
2850
|
async run(ctx) {
|
|
2394
2851
|
const name = ctx.positional[0];
|
|
2395
2852
|
if (!name) {
|
|
2396
|
-
|
|
2853
|
+
logger.error("Usage: nx make:session <Name>");
|
|
2397
2854
|
return 1;
|
|
2398
2855
|
}
|
|
2399
|
-
const variants =
|
|
2400
|
-
const code =
|
|
2856
|
+
const variants = nameVariants(name);
|
|
2857
|
+
const code = render(SESSION_TEMPLATE, {
|
|
2401
2858
|
name: variants.pascal,
|
|
2402
2859
|
kebab: variants.kebab
|
|
2403
2860
|
});
|
|
2404
|
-
const out =
|
|
2405
|
-
if (
|
|
2406
|
-
|
|
2861
|
+
const out = resolve16(ctx.cwd, "app/session/services", `${variants.kebab}.session.ts`);
|
|
2862
|
+
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2863
|
+
logger.success(`created ${out}`);
|
|
2407
2864
|
} else {
|
|
2408
|
-
|
|
2865
|
+
logger.warn(`skipped (exists): ${out}`);
|
|
2409
2866
|
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2867
|
+
logger.blank();
|
|
2868
|
+
logger.heading("Next steps");
|
|
2869
|
+
logger.info("1. Define the typed payload (replace the TODO interface).");
|
|
2870
|
+
logger.info(`2. Inject {{name}}Session in your controllers / services.`);
|
|
2871
|
+
logger.info("3. Bind it in the module's providers array.");
|
|
2872
|
+
logger.blank();
|
|
2416
2873
|
return 0;
|
|
2417
2874
|
}
|
|
2418
2875
|
};
|
|
2419
2876
|
var make_session_default = makeSessionCommand;
|
|
2420
2877
|
|
|
2421
2878
|
// packages/cli/src/commands/make-validator.ts
|
|
2422
|
-
import { resolve as
|
|
2423
|
-
import { logger as logger15, nameVariants as nameVariants12, render as render14, writeFile as writeFile13 } from "@nexusts/core/index.js";
|
|
2879
|
+
import { resolve as resolve17 } from "path";
|
|
2424
2880
|
var makeValidatorCommand = {
|
|
2425
2881
|
name: "make:validator",
|
|
2426
2882
|
aliases: ["mv", "make-validator"],
|
|
@@ -2430,16 +2886,16 @@ var makeValidatorCommand = {
|
|
|
2430
2886
|
async run(ctx) {
|
|
2431
2887
|
const name = ctx.positional[0];
|
|
2432
2888
|
if (!name) {
|
|
2433
|
-
|
|
2889
|
+
logger.error("Usage: nx make:validator <Name>");
|
|
2434
2890
|
return 1;
|
|
2435
2891
|
}
|
|
2436
|
-
const variants =
|
|
2437
|
-
const code =
|
|
2892
|
+
const variants = nameVariants(name);
|
|
2893
|
+
const code = render(templates.validator, {
|
|
2438
2894
|
name: variants.pascal
|
|
2439
2895
|
});
|
|
2440
|
-
const out =
|
|
2441
|
-
|
|
2442
|
-
|
|
2896
|
+
const out = resolve17(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
|
|
2897
|
+
writeFile(out, code);
|
|
2898
|
+
logger.success(`created ${out}`);
|
|
2443
2899
|
return 0;
|
|
2444
2900
|
}
|
|
2445
2901
|
};
|
|
@@ -2447,9 +2903,8 @@ var make_validator_default = makeValidatorCommand;
|
|
|
2447
2903
|
|
|
2448
2904
|
// packages/cli/src/commands/db-migrate.ts
|
|
2449
2905
|
import { spawn } from "child_process";
|
|
2450
|
-
import { existsSync as
|
|
2451
|
-
import { resolve as
|
|
2452
|
-
import { logger as logger16 } from "@nexusts/core/index.js";
|
|
2906
|
+
import { existsSync as existsSync4 } from "fs";
|
|
2907
|
+
import { resolve as resolve18 } from "path";
|
|
2453
2908
|
var dbMigrateCommand = {
|
|
2454
2909
|
name: "db:migrate",
|
|
2455
2910
|
aliases: ["db:m", "migrate"],
|
|
@@ -2484,15 +2939,15 @@ var dbMigrateCommand = {
|
|
|
2484
2939
|
}
|
|
2485
2940
|
],
|
|
2486
2941
|
async run(ctx) {
|
|
2487
|
-
const folder = ctx.flags["folder"] ??
|
|
2942
|
+
const folder = ctx.flags["folder"] ?? resolve18(ctx.cwd, ctx.config.paths.migrations);
|
|
2488
2943
|
const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
|
|
2489
|
-
const configPath = ctx.flags["config"] ??
|
|
2944
|
+
const configPath = ctx.flags["config"] ?? resolve18(ctx.cwd, "drizzle.config.ts");
|
|
2490
2945
|
const wantStatus = Boolean(ctx.flags["status"]);
|
|
2491
2946
|
const generateName = ctx.flags["generate"];
|
|
2492
2947
|
if (generateName) {
|
|
2493
2948
|
return runDrizzleKit(ctx.cwd, [
|
|
2494
2949
|
"generate",
|
|
2495
|
-
...
|
|
2950
|
+
...existsSync4(configPath) ? [`--config=${configPath}`] : [],
|
|
2496
2951
|
"--name",
|
|
2497
2952
|
generateName
|
|
2498
2953
|
]);
|
|
@@ -2502,34 +2957,34 @@ var dbMigrateCommand = {
|
|
|
2502
2957
|
}
|
|
2503
2958
|
return runDrizzleKit(ctx.cwd, [
|
|
2504
2959
|
"migrate",
|
|
2505
|
-
...
|
|
2960
|
+
...existsSync4(configPath) ? [`--config=${configPath}`] : []
|
|
2506
2961
|
]);
|
|
2507
2962
|
}
|
|
2508
2963
|
};
|
|
2509
|
-
function runDrizzleKit(cwd,
|
|
2964
|
+
function runDrizzleKit(cwd, args2) {
|
|
2510
2965
|
return new Promise((resolveP) => {
|
|
2511
2966
|
const cmd = "bunx";
|
|
2512
|
-
|
|
2513
|
-
const child = spawn(cmd, ["drizzle-kit", ...
|
|
2967
|
+
logger.info(`$ ${cmd} drizzle-kit ${args2.join(" ")}`);
|
|
2968
|
+
const child = spawn(cmd, ["drizzle-kit", ...args2], {
|
|
2514
2969
|
cwd,
|
|
2515
2970
|
stdio: "inherit",
|
|
2516
2971
|
shell: process.platform === "win32"
|
|
2517
2972
|
});
|
|
2518
2973
|
child.on("exit", (code) => resolveP(code ?? 0));
|
|
2519
2974
|
child.on("error", (err) => {
|
|
2520
|
-
|
|
2975
|
+
logger.error(`failed to spawn drizzle-kit: ${err.message}`);
|
|
2521
2976
|
resolveP(1);
|
|
2522
2977
|
});
|
|
2523
2978
|
});
|
|
2524
2979
|
}
|
|
2525
2980
|
async function runStatus(cwd, folder, dialect, configUrl = "") {
|
|
2526
|
-
if (!
|
|
2527
|
-
|
|
2981
|
+
if (!existsSync4(folder)) {
|
|
2982
|
+
logger.warn(`migrations folder not found: ${folder}`);
|
|
2528
2983
|
return 0;
|
|
2529
2984
|
}
|
|
2530
2985
|
const url = readEnvUrl(dialect) ?? configUrl;
|
|
2531
2986
|
if (!url) {
|
|
2532
|
-
|
|
2987
|
+
logger.error(`could not read ${dialect} URL from environment. Set DATABASE_URL or NEXUS_DB_URL.`);
|
|
2533
2988
|
return 1;
|
|
2534
2989
|
}
|
|
2535
2990
|
const script = `
|
|
@@ -2547,7 +3002,7 @@ const applied = await svc.appliedMigrations();
|
|
|
2547
3002
|
console.log(JSON.stringify({ total: applied.length, applied }, null, 2));
|
|
2548
3003
|
await svc.close();
|
|
2549
3004
|
`;
|
|
2550
|
-
const tmpFile =
|
|
3005
|
+
const tmpFile = resolve18(cwd, ".nx-migrate-status.mjs");
|
|
2551
3006
|
await import("fs/promises").then((m) => m.writeFile(tmpFile, script, "utf-8"));
|
|
2552
3007
|
try {
|
|
2553
3008
|
const code = await new Promise((resP) => {
|
|
@@ -2556,7 +3011,7 @@ await svc.close();
|
|
|
2556
3011
|
stdio: "inherit",
|
|
2557
3012
|
shell: process.platform === "win32"
|
|
2558
3013
|
});
|
|
2559
|
-
child.on("exit", (
|
|
3014
|
+
child.on("exit", (c2) => resP(c2 ?? 0));
|
|
2560
3015
|
child.on("error", () => resP(1));
|
|
2561
3016
|
});
|
|
2562
3017
|
return code;
|
|
@@ -2571,8 +3026,7 @@ function readEnvUrl(dialect) {
|
|
|
2571
3026
|
var db_migrate_default = dbMigrateCommand;
|
|
2572
3027
|
|
|
2573
3028
|
// packages/cli/src/commands/db-generate.ts
|
|
2574
|
-
import { resolve as
|
|
2575
|
-
import { logger as logger17 } from "@nexusts/core/index.js";
|
|
3029
|
+
import { resolve as resolve19 } from "path";
|
|
2576
3030
|
var dbGenerateCommand = {
|
|
2577
3031
|
name: "db:generate",
|
|
2578
3032
|
aliases: ["db:g", "db-generate", "generate-migration"],
|
|
@@ -2599,25 +3053,25 @@ var dbGenerateCommand = {
|
|
|
2599
3053
|
const isSql = ctx.flags["sql"] === true;
|
|
2600
3054
|
if (isSql) {
|
|
2601
3055
|
if (!name) {
|
|
2602
|
-
|
|
3056
|
+
logger.error("Usage: nx db:generate <name> --sql");
|
|
2603
3057
|
return 1;
|
|
2604
3058
|
}
|
|
2605
|
-
|
|
3059
|
+
logger.info(`Generating raw SQL migration: ${name} (dialect=${dialect})`);
|
|
2606
3060
|
return runSqlTemplate(ctx.cwd, name, dialect);
|
|
2607
3061
|
}
|
|
2608
|
-
const configPath =
|
|
2609
|
-
const
|
|
3062
|
+
const configPath = resolve19(ctx.cwd, "drizzle.config.ts");
|
|
3063
|
+
const args2 = ["generate", "--config", configPath];
|
|
2610
3064
|
if (name)
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
return runDrizzleKit(ctx.cwd,
|
|
3065
|
+
args2.push("--name", name);
|
|
3066
|
+
logger.info(`Generating migration: ${name} (dialect=${dialect})`);
|
|
3067
|
+
return runDrizzleKit(ctx.cwd, args2);
|
|
2614
3068
|
}
|
|
2615
3069
|
};
|
|
2616
3070
|
async function runSqlTemplate(cwd, name, dialect) {
|
|
2617
|
-
const { mkdirSync:
|
|
3071
|
+
const { mkdirSync: mkdirSync4, writeFileSync: writeFileSync3 } = await import("fs");
|
|
2618
3072
|
const { join } = await import("path");
|
|
2619
3073
|
const migrationsDir = join(cwd, "app", "database", "migrations");
|
|
2620
|
-
|
|
3074
|
+
mkdirSync4(migrationsDir, { recursive: true });
|
|
2621
3075
|
const timestamp = Date.now();
|
|
2622
3076
|
const filename = `${timestamp}_${name.replace(/[^a-z0-9_]+/g, "_")}.sql`;
|
|
2623
3077
|
const filepath = join(migrationsDir, filename);
|
|
@@ -2630,19 +3084,18 @@ async function runSqlTemplate(cwd, name, dialect) {
|
|
|
2630
3084
|
-- Generated: ${new Date().toISOString()}
|
|
2631
3085
|
|
|
2632
3086
|
`;
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
3087
|
+
writeFileSync3(filepath, header);
|
|
3088
|
+
logger.success(`created ${filepath}`);
|
|
3089
|
+
logger.info("Edit the SQL file, then run `nx db:migrate` to apply it.");
|
|
2636
3090
|
return 0;
|
|
2637
3091
|
}
|
|
2638
3092
|
var db_generate_default = dbGenerateCommand;
|
|
2639
3093
|
|
|
2640
3094
|
// packages/cli/src/commands/db-seed.ts
|
|
2641
3095
|
import { spawn as spawn2 } from "child_process";
|
|
2642
|
-
import { existsSync as
|
|
2643
|
-
import { mkdir, readdir, writeFile as
|
|
2644
|
-
import { resolve as
|
|
2645
|
-
import { logger as logger18 } from "@nexusts/core/index.js";
|
|
3096
|
+
import { existsSync as existsSync5 } from "fs";
|
|
3097
|
+
import { mkdir, readdir, writeFile as writeFile2, unlink } from "fs/promises";
|
|
3098
|
+
import { resolve as resolve20 } from "path";
|
|
2646
3099
|
var SEED_TEMPLATE = `/**
|
|
2647
3100
|
* Seed: {name}
|
|
2648
3101
|
*
|
|
@@ -2703,7 +3156,7 @@ var dbSeedCommand = {
|
|
|
2703
3156
|
}
|
|
2704
3157
|
],
|
|
2705
3158
|
async run(ctx) {
|
|
2706
|
-
const folder =
|
|
3159
|
+
const folder = resolve20(ctx.cwd, ctx.flags["folder"] ?? ctx.config.paths?.seeds ?? "db/seeds");
|
|
2707
3160
|
const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
|
|
2708
3161
|
const createName = ctx.flags["create"];
|
|
2709
3162
|
const fileName = ctx.flags["file"];
|
|
@@ -2711,10 +3164,10 @@ var dbSeedCommand = {
|
|
|
2711
3164
|
if (createName) {
|
|
2712
3165
|
return await createSeedFile(folder, createName);
|
|
2713
3166
|
}
|
|
2714
|
-
if (!
|
|
2715
|
-
|
|
3167
|
+
if (!existsSync5(folder)) {
|
|
3168
|
+
logger.info(`creating empty seeds folder at ${folder}`);
|
|
2716
3169
|
await mkdir(folder, { recursive: true });
|
|
2717
|
-
await
|
|
3170
|
+
await writeFile2(resolve20(folder, "_README.ts"), `// Seed files go here. Run with: nx db:seed
|
|
2718
3171
|
`, "utf-8");
|
|
2719
3172
|
return 0;
|
|
2720
3173
|
}
|
|
@@ -2722,23 +3175,23 @@ var dbSeedCommand = {
|
|
|
2722
3175
|
if (fileName) {
|
|
2723
3176
|
const matched = files.filter((f) => f.toLowerCase().includes(fileName.toLowerCase()));
|
|
2724
3177
|
if (matched.length === 0) {
|
|
2725
|
-
|
|
3178
|
+
logger.error(`no seed file matching "${fileName}" in ${folder}`);
|
|
2726
3179
|
return 1;
|
|
2727
3180
|
}
|
|
2728
3181
|
} else if (files.length === 0) {
|
|
2729
|
-
|
|
3182
|
+
logger.warn(`no seed files found in ${folder}`);
|
|
2730
3183
|
return 0;
|
|
2731
3184
|
}
|
|
2732
3185
|
const target = fileName ? files.filter((f) => f.toLowerCase().includes(fileName.toLowerCase())) : files;
|
|
2733
3186
|
const url = readEnvUrl2(dialect);
|
|
2734
3187
|
if (!url) {
|
|
2735
|
-
|
|
3188
|
+
logger.error(`could not read ${dialect} URL from environment. Set DATABASE_URL or NEXUS_DB_URL.`);
|
|
2736
3189
|
return 1;
|
|
2737
3190
|
}
|
|
2738
3191
|
if (reset) {
|
|
2739
|
-
|
|
3192
|
+
logger.warn("--reset is set: truncating every table in the schema before running seeds.");
|
|
2740
3193
|
}
|
|
2741
|
-
const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(
|
|
3194
|
+
const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(resolve20(folder, f))};`).join(`
|
|
2742
3195
|
`);
|
|
2743
3196
|
const seedCalls = target.map((_, i) => ` await seed_${i}({ db, logger, dialect, truncate: (t) => db.truncate(t) });`).join(`
|
|
2744
3197
|
`);
|
|
@@ -2771,8 +3224,8 @@ ${seedCalls}
|
|
|
2771
3224
|
await db.close();
|
|
2772
3225
|
logger.info(\`Seeds complete (\${${target.length}} file(s))\`);
|
|
2773
3226
|
`;
|
|
2774
|
-
const tmpFile =
|
|
2775
|
-
await
|
|
3227
|
+
const tmpFile = resolve20(ctx.cwd, ".nx-db-seed.mjs");
|
|
3228
|
+
await writeFile2(tmpFile, script, "utf-8");
|
|
2776
3229
|
try {
|
|
2777
3230
|
const code = await new Promise((resP) => {
|
|
2778
3231
|
const child = spawn2("bun", [tmpFile], {
|
|
@@ -2780,7 +3233,7 @@ logger.info(\`Seeds complete (\${${target.length}} file(s))\`);
|
|
|
2780
3233
|
stdio: "inherit",
|
|
2781
3234
|
shell: process.platform === "win32"
|
|
2782
3235
|
});
|
|
2783
|
-
child.on("exit", (
|
|
3236
|
+
child.on("exit", (c2) => resP(c2 ?? 0));
|
|
2784
3237
|
child.on("error", () => resP(1));
|
|
2785
3238
|
});
|
|
2786
3239
|
return code;
|
|
@@ -2806,21 +3259,21 @@ async function collectSeedFiles(folder) {
|
|
|
2806
3259
|
}
|
|
2807
3260
|
async function createSeedFile(folder, name) {
|
|
2808
3261
|
if (!/^[a-z0-9_-]+$/i.test(name)) {
|
|
2809
|
-
|
|
3262
|
+
logger.error(`invalid seed name "${name}" \u2014 use letters, numbers, dash, underscore.`);
|
|
2810
3263
|
return 1;
|
|
2811
3264
|
}
|
|
2812
|
-
if (!
|
|
3265
|
+
if (!existsSync5(folder))
|
|
2813
3266
|
await mkdir(folder, { recursive: true });
|
|
2814
3267
|
let candidate = `${name}.ts`;
|
|
2815
3268
|
let i = 1;
|
|
2816
|
-
while (
|
|
3269
|
+
while (existsSync5(resolve20(folder, candidate))) {
|
|
2817
3270
|
candidate = `${name}_${i}.ts`;
|
|
2818
3271
|
i++;
|
|
2819
3272
|
}
|
|
2820
|
-
const path =
|
|
3273
|
+
const path = resolve20(folder, candidate);
|
|
2821
3274
|
const body = SEED_TEMPLATE.replace(/\{name\}/g, name);
|
|
2822
|
-
await
|
|
2823
|
-
|
|
3275
|
+
await writeFile2(path, body, "utf-8");
|
|
3276
|
+
logger.info(`created ${path}`);
|
|
2824
3277
|
return 0;
|
|
2825
3278
|
}
|
|
2826
3279
|
function readEnvUrl2(dialect) {
|
|
@@ -2828,7 +3281,7 @@ function readEnvUrl2(dialect) {
|
|
|
2828
3281
|
return url ?? null;
|
|
2829
3282
|
}
|
|
2830
3283
|
function relativeImport(cwd, target) {
|
|
2831
|
-
const abs =
|
|
3284
|
+
const abs = resolve20(cwd, target);
|
|
2832
3285
|
let rel = abs;
|
|
2833
3286
|
if (rel.startsWith(cwd))
|
|
2834
3287
|
rel = rel.slice(cwd.length);
|
|
@@ -2841,9 +3294,8 @@ function relativeImport(cwd, target) {
|
|
|
2841
3294
|
var db_seed_default = dbSeedCommand;
|
|
2842
3295
|
|
|
2843
3296
|
// packages/cli/src/commands/new.ts
|
|
2844
|
-
import { existsSync as
|
|
2845
|
-
import { resolve as
|
|
2846
|
-
import { flagBool as flagBool5, logger as logger19, render as render15, select as select2 } from "@nexusts/core/index.js";
|
|
3297
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
3298
|
+
import { resolve as resolve21 } from "path";
|
|
2847
3299
|
var newCommand = {
|
|
2848
3300
|
name: "new",
|
|
2849
3301
|
aliases: ["n"],
|
|
@@ -2874,48 +3326,52 @@ var newCommand = {
|
|
|
2874
3326
|
async run(ctx) {
|
|
2875
3327
|
const name = ctx.positional[0];
|
|
2876
3328
|
if (!name) {
|
|
2877
|
-
|
|
3329
|
+
logger.error("Usage: nx new <project-name>");
|
|
2878
3330
|
return 1;
|
|
2879
3331
|
}
|
|
2880
|
-
const interactive = !
|
|
2881
|
-
const target =
|
|
2882
|
-
if (
|
|
2883
|
-
|
|
3332
|
+
const interactive = !flagBool(ctx.flags, "no-interaction", false);
|
|
3333
|
+
const target = resolve21(ctx.cwd, name);
|
|
3334
|
+
if (existsSync6(target)) {
|
|
3335
|
+
logger.error(`Directory already exists: ${target}`);
|
|
2884
3336
|
return 1;
|
|
2885
3337
|
}
|
|
2886
|
-
const routing = ctx.flags["style"] ?? await
|
|
3338
|
+
const routing = ctx.flags["style"] ?? await select("Routing style", ["nest", "adonis", "functional"], {
|
|
2887
3339
|
interactive,
|
|
2888
3340
|
default: "nest"
|
|
2889
3341
|
});
|
|
2890
|
-
const view = ctx.flags["view"] ?? await
|
|
3342
|
+
const view = ctx.flags["view"] ?? await select("View engine", ["rendu", "edge", "eta", "inertia", "none"], {
|
|
2891
3343
|
interactive,
|
|
2892
3344
|
default: "rendu"
|
|
2893
3345
|
});
|
|
2894
|
-
const orm = ctx.flags["orm"] ?? await
|
|
3346
|
+
const orm = ctx.flags["orm"] ?? await select("ORM driver", ["drizzle", "prisma", "kysely", "none"], {
|
|
2895
3347
|
interactive,
|
|
2896
3348
|
default: "drizzle"
|
|
2897
3349
|
});
|
|
2898
|
-
const db = ctx.flags["db"] ?? await
|
|
3350
|
+
const db = ctx.flags["db"] ?? await select("Database driver", ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"], {
|
|
2899
3351
|
interactive,
|
|
2900
3352
|
default: "bun-sqlite"
|
|
2901
3353
|
});
|
|
2902
|
-
const frontend = ctx.flags["frontend"] ?? await
|
|
3354
|
+
const frontend = ctx.flags["frontend"] ?? await select("Inertia frontend", ["react", "vue", "svelte", "solid"], {
|
|
2903
3355
|
interactive,
|
|
2904
3356
|
default: "react"
|
|
2905
3357
|
});
|
|
2906
|
-
const ssr = !
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
3358
|
+
const ssr = !flagBool(ctx.flags, "no-ssr", false);
|
|
3359
|
+
mkdirSync4(resolve21(target, "app"), { recursive: true });
|
|
3360
|
+
if (view !== "none") {
|
|
3361
|
+
mkdirSync4(resolve21(target, "resources/views"), { recursive: true });
|
|
3362
|
+
}
|
|
3363
|
+
mkdirSync4(resolve21(target, "public"), { recursive: true });
|
|
3364
|
+
writeFileSync3(resolve21(target, "public/.gitkeep"), "");
|
|
3365
|
+
if (view !== "none") {
|
|
3366
|
+
writeFileSync3(resolve21(target, "resources/views/welcome.html"), `<h1>Welcome to ${name}</h1>
|
|
2912
3367
|
<p>This is a sample Rendu template.</p>
|
|
2913
3368
|
<p>Founded <?= year ?>.</p>
|
|
2914
3369
|
`);
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
3370
|
+
}
|
|
3371
|
+
writeFileSync3(resolve21(target, ".env"), generateEnvFile());
|
|
3372
|
+
writeFileSync3(resolve21(target, ".env.local"), generateEnvLocalFile());
|
|
3373
|
+
writeFileSync3(resolve21(target, ".gitignore"), generateGitIgnore());
|
|
3374
|
+
const code = render(templates.project["nx.config.ts"], {
|
|
2919
3375
|
routing,
|
|
2920
3376
|
view,
|
|
2921
3377
|
viewPaths: view === "none" ? "" : "resources/views",
|
|
@@ -2926,8 +3382,21 @@ var newCommand = {
|
|
|
2926
3382
|
inertiaSSR: ssr,
|
|
2927
3383
|
inertiaVersion: "1.0.0"
|
|
2928
3384
|
});
|
|
2929
|
-
|
|
2930
|
-
|
|
3385
|
+
writeFileSync3(resolve21(target, "nx.config.ts"), code);
|
|
3386
|
+
const deps = {
|
|
3387
|
+
"@nexusts/core": "*",
|
|
3388
|
+
"reflect-metadata": "^0.2.2",
|
|
3389
|
+
hono: "^4.6.0",
|
|
3390
|
+
zod: "^3.23.8"
|
|
3391
|
+
};
|
|
3392
|
+
if (orm === "drizzle") {
|
|
3393
|
+
deps["@nexusts/drizzle"] = "*";
|
|
3394
|
+
deps["drizzle-orm"] = "^0.45.0";
|
|
3395
|
+
}
|
|
3396
|
+
if (view !== "none") {
|
|
3397
|
+
deps["@nexusts/static"] = "*";
|
|
3398
|
+
}
|
|
3399
|
+
writeFileSync3(resolve21(target, "package.json"), JSON.stringify({
|
|
2931
3400
|
name,
|
|
2932
3401
|
version: "0.1.0",
|
|
2933
3402
|
type: "module",
|
|
@@ -2938,14 +3407,9 @@ var newCommand = {
|
|
|
2938
3407
|
test: "vitest",
|
|
2939
3408
|
nx: "nx"
|
|
2940
3409
|
},
|
|
2941
|
-
dependencies:
|
|
2942
|
-
"@nexusts/core": "*",
|
|
2943
|
-
"reflect-metadata": "^0.2.2",
|
|
2944
|
-
hono: "^4.6.0",
|
|
2945
|
-
zod: "^3.23.8"
|
|
2946
|
-
}
|
|
3410
|
+
dependencies: deps
|
|
2947
3411
|
}, null, 2));
|
|
2948
|
-
|
|
3412
|
+
writeFileSync3(resolve21(target, "tsconfig.json"), `{
|
|
2949
3413
|
"compilerOptions": {
|
|
2950
3414
|
"target": "ES2022",
|
|
2951
3415
|
"module": "ESNext",
|
|
@@ -2960,43 +3424,59 @@ var newCommand = {
|
|
|
2960
3424
|
"include": ["app/**/*.ts", "nx.config.ts"]
|
|
2961
3425
|
}
|
|
2962
3426
|
`);
|
|
2963
|
-
|
|
3427
|
+
const hasView = view !== "none";
|
|
3428
|
+
const staticImport = hasView ? `import { StaticModule } from '@nexusts/static';
|
|
3429
|
+
const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static' });
|
|
3430
|
+
` : "";
|
|
3431
|
+
const staticOption = hasView ? `
|
|
3432
|
+
middleware: [staticMiddleware],` : "";
|
|
3433
|
+
writeFileSync3(resolve21(target, "app/main.ts"), `import 'reflect-metadata';
|
|
2964
3434
|
import { Application } from '@nexusts/core';
|
|
2965
|
-
import {
|
|
2966
|
-
import { AppModule } from './app.module.js';
|
|
3435
|
+
${staticImport}import { AppModule } from './app.module.js';
|
|
2967
3436
|
|
|
2968
|
-
const app = new Application(AppModule
|
|
2969
|
-
|
|
2970
|
-
|
|
3437
|
+
const app = new Application(AppModule, {
|
|
3438
|
+
logging: true,
|
|
3439
|
+
port: Number(process.env['PORT'] ?? 3000),${staticOption}
|
|
3440
|
+
});
|
|
2971
3441
|
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
console.log("[nexusjs] Listening on http://localhost:" + port);
|
|
3442
|
+
await app.listen();
|
|
3443
|
+
console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
|
|
2975
3444
|
`);
|
|
2976
|
-
|
|
3445
|
+
const ormImport = orm === "drizzle" ? `import { DrizzleModule } from '@nexusts/drizzle';
|
|
3446
|
+
` : "";
|
|
3447
|
+
const forRootDialect = db === "bun-sqlite" ? "bun-sqlite" : "sqlite";
|
|
3448
|
+
const ormBlock = orm === "drizzle" ? ` DrizzleModule.forRoot({
|
|
3449
|
+
dialect: '${forRootDialect}',
|
|
3450
|
+
connection: { filename: 'app.db' },
|
|
3451
|
+
logging: true,
|
|
3452
|
+
})` : "";
|
|
3453
|
+
writeFileSync3(resolve21(target, "app/app.module.ts"), `${ormImport}import { Module } from '@nexusts/core';
|
|
2977
3454
|
import { HomeController } from './controllers/home.controller.js';
|
|
2978
3455
|
|
|
2979
3456
|
@Module({
|
|
2980
|
-
imports: [
|
|
3457
|
+
imports: [${orm === "drizzle" ? `
|
|
3458
|
+
${ormBlock},
|
|
3459
|
+
` : ""} ],
|
|
2981
3460
|
controllers: [HomeController],
|
|
2982
3461
|
})
|
|
2983
3462
|
export class AppModule {}
|
|
2984
3463
|
`);
|
|
2985
|
-
|
|
2986
|
-
|
|
3464
|
+
mkdirSync4(resolve21(target, "app/controllers"), { recursive: true });
|
|
3465
|
+
const homeViewReturn = view !== "none" ? `{
|
|
3466
|
+
view: 'welcome.html',
|
|
3467
|
+
data: { year: new Date().getFullYear() },
|
|
3468
|
+
}` : `{ status: 200, body: { message: 'Hello from NexusTS!' } }`;
|
|
3469
|
+
writeFileSync3(resolve21(target, "app/controllers/home.controller.ts"), `import { Controller, Get } from '@nexusts/core';
|
|
2987
3470
|
|
|
2988
3471
|
@Controller('/')
|
|
2989
3472
|
export class HomeController {
|
|
2990
3473
|
@Get('/')
|
|
2991
3474
|
index() {
|
|
2992
|
-
return {
|
|
2993
|
-
view: 'welcome.html',
|
|
2994
|
-
data: { year: new Date().getFullYear() },
|
|
2995
|
-
};
|
|
3475
|
+
return ${homeViewReturn};
|
|
2996
3476
|
}
|
|
2997
3477
|
}
|
|
2998
3478
|
`);
|
|
2999
|
-
|
|
3479
|
+
writeFileSync3(resolve21(target, "README.md"), `# ${name}
|
|
3000
3480
|
|
|
3001
3481
|
A new Nexus project.
|
|
3002
3482
|
|
|
@@ -3013,13 +3493,13 @@ bun run dev
|
|
|
3013
3493
|
bunx nx make:crud Post
|
|
3014
3494
|
\`\`\`
|
|
3015
3495
|
`);
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3496
|
+
logger.success(`created ${target}`);
|
|
3497
|
+
logger.blank();
|
|
3498
|
+
logger.heading("Next steps");
|
|
3499
|
+
logger.info(` cd ${name}`);
|
|
3500
|
+
logger.info(` bun install`);
|
|
3501
|
+
logger.info(` bun run dev`);
|
|
3502
|
+
logger.blank();
|
|
3023
3503
|
return 0;
|
|
3024
3504
|
}
|
|
3025
3505
|
};
|
|
@@ -3077,9 +3557,8 @@ dist/
|
|
|
3077
3557
|
var new_default = newCommand;
|
|
3078
3558
|
|
|
3079
3559
|
// packages/cli/src/commands/config.ts
|
|
3080
|
-
import { existsSync as
|
|
3081
|
-
import { resolve as
|
|
3082
|
-
import { flagBool as flagBool6, logger as logger20, render as render16, select as select3 } from "@nexusts/core/index.js";
|
|
3560
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
3561
|
+
import { resolve as resolve22 } from "path";
|
|
3083
3562
|
var DEFAULT_VALUES = {
|
|
3084
3563
|
routing: "nest",
|
|
3085
3564
|
view: "rendu",
|
|
@@ -3093,9 +3572,9 @@ var DEFAULT_VALUES = {
|
|
|
3093
3572
|
};
|
|
3094
3573
|
function parseExistingConfig(path) {
|
|
3095
3574
|
const out = { ...DEFAULT_VALUES };
|
|
3096
|
-
if (!
|
|
3575
|
+
if (!existsSync7(path))
|
|
3097
3576
|
return out;
|
|
3098
|
-
const src =
|
|
3577
|
+
const src = readFileSync4(path, "utf8");
|
|
3099
3578
|
const grab = (re) => {
|
|
3100
3579
|
const m = src.match(re);
|
|
3101
3580
|
return m?.[1];
|
|
@@ -3192,17 +3671,17 @@ var configCommand = {
|
|
|
3192
3671
|
{ name: "no-interaction", description: "Disable interactive prompts" }
|
|
3193
3672
|
],
|
|
3194
3673
|
async run(ctx) {
|
|
3195
|
-
const interactive = !
|
|
3196
|
-
const force =
|
|
3197
|
-
const target =
|
|
3198
|
-
if (!
|
|
3199
|
-
|
|
3674
|
+
const interactive = !flagBool(ctx.flags, "no-interaction", false);
|
|
3675
|
+
const force = flagBool(ctx.flags, "force", false);
|
|
3676
|
+
const target = resolve22(ctx.cwd, ctx.flags["target"] ?? ".");
|
|
3677
|
+
if (!existsSync7(target)) {
|
|
3678
|
+
logger.error(`Target directory does not exist: ${target}`);
|
|
3200
3679
|
return 1;
|
|
3201
3680
|
}
|
|
3202
|
-
const nxConfigPath =
|
|
3681
|
+
const nxConfigPath = resolve22(target, "nx.config.ts");
|
|
3203
3682
|
const values = parseExistingConfig(nxConfigPath);
|
|
3204
3683
|
const flag = (k) => ctx.flags[k];
|
|
3205
|
-
const flagBoolStrict = (k, def) =>
|
|
3684
|
+
const flagBoolStrict = (k, def) => flagBool(ctx.flags, k, def);
|
|
3206
3685
|
if (flag("style"))
|
|
3207
3686
|
values.routing = flag("style");
|
|
3208
3687
|
if (flag("view"))
|
|
@@ -3223,84 +3702,83 @@ var configCommand = {
|
|
|
3223
3702
|
if (flagBoolStrict("no-ssr", false))
|
|
3224
3703
|
values.inertiaSSR = false;
|
|
3225
3704
|
const anyFlag = Object.values(ctx.flags).some((v) => v !== undefined && v !== false);
|
|
3226
|
-
if (interactive && !anyFlag && !
|
|
3227
|
-
values.routing = await
|
|
3705
|
+
if (interactive && !anyFlag && !existsSync7(nxConfigPath)) {
|
|
3706
|
+
values.routing = await select("Routing style", ["nest", "adonis", "functional"], {
|
|
3228
3707
|
interactive,
|
|
3229
3708
|
default: values.routing
|
|
3230
3709
|
}) ?? values.routing;
|
|
3231
|
-
values.view = await
|
|
3710
|
+
values.view = await select("View engine", ["inertia", "rendu", "edge", "none"], {
|
|
3232
3711
|
interactive,
|
|
3233
3712
|
default: values.view
|
|
3234
3713
|
}) ?? values.view;
|
|
3235
|
-
values.orm = await
|
|
3714
|
+
values.orm = await select("ORM driver", ["drizzle", "prisma", "kysely", "none"], {
|
|
3236
3715
|
interactive,
|
|
3237
3716
|
default: values.orm
|
|
3238
3717
|
}) ?? values.orm;
|
|
3239
|
-
values.dbDriver = await
|
|
3240
|
-
values.inertiaFrontend = await
|
|
3718
|
+
values.dbDriver = await select("Database driver", ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"], { interactive, default: values.dbDriver }) ?? values.dbDriver;
|
|
3719
|
+
values.inertiaFrontend = await select("Inertia frontend", ["react", "vue", "svelte", "solid"], { interactive, default: values.inertiaFrontend }) ?? values.inertiaFrontend;
|
|
3241
3720
|
}
|
|
3242
3721
|
if (flag("db-url") === undefined && flag("db") !== undefined) {
|
|
3243
3722
|
values.dbUrl = defaultDbUrl(values.dbDriver);
|
|
3244
3723
|
}
|
|
3245
|
-
const existed =
|
|
3724
|
+
const existed = existsSync7(nxConfigPath);
|
|
3246
3725
|
if (existed && !force) {
|
|
3247
3726
|
if (anyFlag) {
|
|
3248
3727
|
writeNxConfig(target, values);
|
|
3249
|
-
|
|
3728
|
+
logger.info(` ~ nx.config.ts (updated)`);
|
|
3250
3729
|
} else {
|
|
3251
|
-
|
|
3730
|
+
logger.info(` - nx.config.ts (unchanged; pass --force or a flag to update)`);
|
|
3252
3731
|
}
|
|
3253
3732
|
} else {
|
|
3254
3733
|
writeNxConfig(target, values);
|
|
3255
|
-
|
|
3734
|
+
logger.info(` + nx.config.ts`);
|
|
3256
3735
|
}
|
|
3257
|
-
const drizzleConfigPath =
|
|
3736
|
+
const drizzleConfigPath = resolve22(target, "drizzle.config.ts");
|
|
3258
3737
|
if (values.orm === "drizzle") {
|
|
3259
3738
|
const dialect = driverToDialect(values.dbDriver);
|
|
3260
3739
|
const dbUrl = values.dbUrl;
|
|
3261
|
-
const existedDrizzle =
|
|
3740
|
+
const existedDrizzle = existsSync7(drizzleConfigPath);
|
|
3262
3741
|
if (existedDrizzle && !force && !anyFlag) {
|
|
3263
|
-
|
|
3742
|
+
logger.info(` - drizzle.config.ts (unchanged; pass --force or a flag to update)`);
|
|
3264
3743
|
} else {
|
|
3265
3744
|
writeDrizzleConfig(target, { dialect, dbUrl });
|
|
3266
|
-
|
|
3745
|
+
logger.info(` ${existedDrizzle ? "~" : "+"} drizzle.config.ts`);
|
|
3267
3746
|
}
|
|
3268
|
-
} else if (
|
|
3269
|
-
|
|
3747
|
+
} else if (existsSync7(drizzleConfigPath)) {
|
|
3748
|
+
logger.info(` - drizzle.config.ts (left as-is; ORM is '${values.orm}', not 'drizzle')`);
|
|
3270
3749
|
}
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3750
|
+
logger.blank();
|
|
3751
|
+
logger.success(`config updated in ${target}`);
|
|
3752
|
+
logger.blank();
|
|
3753
|
+
logger.heading("Next steps");
|
|
3754
|
+
logger.info(` cd ${target === ctx.cwd ? "." : target}`);
|
|
3276
3755
|
if (values.orm === "drizzle") {
|
|
3277
|
-
|
|
3756
|
+
logger.info(` bun run db:generate # generate migrations`);
|
|
3278
3757
|
}
|
|
3279
|
-
|
|
3758
|
+
logger.blank();
|
|
3280
3759
|
return 0;
|
|
3281
3760
|
}
|
|
3282
3761
|
};
|
|
3283
3762
|
function writeNxConfig(target, values) {
|
|
3284
|
-
const code =
|
|
3285
|
-
|
|
3763
|
+
const code = render(templates.project["nx.config.ts"], values);
|
|
3764
|
+
writeFileSync4(resolve22(target, "nx.config.ts"), code);
|
|
3286
3765
|
}
|
|
3287
3766
|
function writeDrizzleConfig(target, values) {
|
|
3288
|
-
const code =
|
|
3289
|
-
|
|
3767
|
+
const code = render(templates.project["drizzle.config.ts"], values);
|
|
3768
|
+
writeFileSync4(resolve22(target, "drizzle.config.ts"), code);
|
|
3290
3769
|
}
|
|
3291
3770
|
var config_default = configCommand;
|
|
3292
3771
|
|
|
3293
3772
|
// packages/cli/src/commands/repl.ts
|
|
3294
3773
|
import {
|
|
3295
|
-
existsSync as
|
|
3296
|
-
mkdirSync as
|
|
3297
|
-
readFileSync as
|
|
3298
|
-
writeFileSync as
|
|
3774
|
+
existsSync as existsSync8,
|
|
3775
|
+
mkdirSync as mkdirSync5,
|
|
3776
|
+
readFileSync as readFileSync5,
|
|
3777
|
+
writeFileSync as writeFileSync5
|
|
3299
3778
|
} from "fs";
|
|
3300
|
-
import { dirname as
|
|
3779
|
+
import { dirname as dirname3, resolve as resolve23 } from "path";
|
|
3301
3780
|
import * as readline from "readline";
|
|
3302
3781
|
import * as vm from "vm";
|
|
3303
|
-
import { logger as logger21 } from "@nexusts/core/index.js";
|
|
3304
3782
|
var BANNER = `
|
|
3305
3783
|
\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E
|
|
3306
3784
|
\u2502 NexusTS REPL \u2502
|
|
@@ -3366,32 +3844,32 @@ var replCommand = {
|
|
|
3366
3844
|
async run(ctx) {
|
|
3367
3845
|
const mod = ctx.flags["module"];
|
|
3368
3846
|
const noBoot = Boolean(ctx.flags["no-boot"]);
|
|
3369
|
-
const histPath =
|
|
3847
|
+
const histPath = resolve23(ctx.cwd, ctx.flags["history"] ?? ".nx-repl-history");
|
|
3370
3848
|
const env = { console };
|
|
3371
3849
|
if (!noBoot) {
|
|
3372
|
-
const modPath =
|
|
3373
|
-
if (!
|
|
3374
|
-
|
|
3375
|
-
|
|
3850
|
+
const modPath = resolve23(ctx.cwd, mod ?? "app/app.module.ts");
|
|
3851
|
+
if (!existsSync8(modPath)) {
|
|
3852
|
+
logger.error(`module not found: ${modPath}`);
|
|
3853
|
+
logger.info("pass --module <path> or --no-boot to skip booting");
|
|
3376
3854
|
return 1;
|
|
3377
3855
|
}
|
|
3378
3856
|
try {
|
|
3379
3857
|
const modSpec = await import(modPath);
|
|
3380
3858
|
const AppModule = modSpec.default ?? modSpec.AppModule;
|
|
3381
3859
|
if (!AppModule) {
|
|
3382
|
-
|
|
3860
|
+
logger.error(`module at ${modPath} does not export AppModule as default or named export`);
|
|
3383
3861
|
return 1;
|
|
3384
3862
|
}
|
|
3385
|
-
const { Application } = await import("@nexusts/core
|
|
3863
|
+
const { Application } = await import("@nexusts/core");
|
|
3386
3864
|
const app = new Application(AppModule);
|
|
3387
3865
|
env.app = app;
|
|
3388
3866
|
env.container = app.container;
|
|
3389
3867
|
for (const [name, path, className] of PRELOAD) {
|
|
3390
3868
|
await preloadService(env, app, name, path, className);
|
|
3391
3869
|
}
|
|
3392
|
-
|
|
3870
|
+
logger.info(`\u2713 Booted ${modPath}`);
|
|
3393
3871
|
} catch (err) {
|
|
3394
|
-
|
|
3872
|
+
logger.error(`failed to boot: ${err.message}`);
|
|
3395
3873
|
return 1;
|
|
3396
3874
|
}
|
|
3397
3875
|
}
|
|
@@ -3487,580 +3965,301 @@ var replCommand = {
|
|
|
3487
3965
|
}
|
|
3488
3966
|
return true;
|
|
3489
3967
|
}
|
|
3490
|
-
case ".history": {
|
|
3491
|
-
const hist = rl.history ?? [];
|
|
3492
|
-
const histArr = hist;
|
|
3493
|
-
histArr.forEach((h, i) => {
|
|
3494
|
-
console.log(` ${(i + 1).toString().padStart(4)}: ${h}`);
|
|
3495
|
-
});
|
|
3496
|
-
return true;
|
|
3497
|
-
}
|
|
3498
|
-
case ".reset": {
|
|
3499
|
-
for (const k of Object.keys(env)) {
|
|
3500
|
-
if (k !== "console")
|
|
3501
|
-
delete env[k];
|
|
3502
|
-
}
|
|
3503
|
-
console.log(" context reset");
|
|
3504
|
-
return true;
|
|
3505
|
-
}
|
|
3506
|
-
default:
|
|
3507
|
-
console.error(` unknown command: ${cmd}`);
|
|
3508
|
-
console.log(" type .help for the list");
|
|
3509
|
-
return true;
|
|
3510
|
-
}
|
|
3511
|
-
};
|
|
3512
|
-
rl.on("line", async (line) => {
|
|
3513
|
-
const trimmed = line.trim();
|
|
3514
|
-
if (trimmed.startsWith(".")) {
|
|
3515
|
-
await handleDotCommand(trimmed);
|
|
3516
|
-
} else {
|
|
3517
|
-
buffer += line + `
|
|
3518
|
-
`;
|
|
3519
|
-
if (isIncomplete(buffer)) {
|
|
3520
|
-
rl.setPrompt("... ");
|
|
3521
|
-
rl.prompt();
|
|
3522
|
-
return;
|
|
3523
|
-
}
|
|
3524
|
-
await evaluate(buffer);
|
|
3525
|
-
buffer = "";
|
|
3526
|
-
rl.setPrompt("\u276F ");
|
|
3527
|
-
}
|
|
3528
|
-
rl.prompt();
|
|
3529
|
-
});
|
|
3530
|
-
rl.prompt();
|
|
3531
|
-
return new Promise(() => {});
|
|
3532
|
-
}
|
|
3533
|
-
};
|
|
3534
|
-
async function preloadService(env, app, name, path, className) {
|
|
3535
|
-
try {
|
|
3536
|
-
const mod = await import(path);
|
|
3537
|
-
const ServiceClass = mod[className];
|
|
3538
|
-
if (!ServiceClass)
|
|
3539
|
-
return;
|
|
3540
|
-
const Token = ServiceClass.TOKEN ?? ServiceClass[`${className.toUpperCase()}_TOKEN`];
|
|
3541
|
-
if (!Token)
|
|
3542
|
-
return;
|
|
3543
|
-
try {
|
|
3544
|
-
env[name] = app.container.resolve(Token);
|
|
3545
|
-
} catch {
|
|
3546
|
-
try {
|
|
3547
|
-
env[name] = app.container.resolve(ServiceClass);
|
|
3548
|
-
} catch {}
|
|
3549
|
-
}
|
|
3550
|
-
} catch {}
|
|
3551
|
-
}
|
|
3552
|
-
function listServices(container) {
|
|
3553
|
-
if (!container)
|
|
3554
|
-
return [];
|
|
3555
|
-
const c = container;
|
|
3556
|
-
if (typeof c.listProviders !== "function")
|
|
3557
|
-
return [];
|
|
3558
|
-
try {
|
|
3559
|
-
return c.listProviders().map((p) => p.token?.toString?.() ?? String(p.token));
|
|
3560
|
-
} catch {
|
|
3561
|
-
return [];
|
|
3562
|
-
}
|
|
3563
|
-
}
|
|
3564
|
-
function isIncomplete(code) {
|
|
3565
|
-
const stack = [];
|
|
3566
|
-
let inString = null;
|
|
3567
|
-
let inComment = null;
|
|
3568
|
-
for (let i = 0;i < code.length; i++) {
|
|
3569
|
-
const c = code[i];
|
|
3570
|
-
const next = code[i + 1];
|
|
3571
|
-
if (inComment === "line") {
|
|
3572
|
-
if (c === `
|
|
3573
|
-
`)
|
|
3574
|
-
inComment = null;
|
|
3575
|
-
continue;
|
|
3576
|
-
}
|
|
3577
|
-
if (inComment === "block") {
|
|
3578
|
-
if (c === "*" && next === "/") {
|
|
3579
|
-
inComment = null;
|
|
3580
|
-
i++;
|
|
3581
|
-
}
|
|
3582
|
-
continue;
|
|
3583
|
-
}
|
|
3584
|
-
if (inString) {
|
|
3585
|
-
if (c === "\\") {
|
|
3586
|
-
i++;
|
|
3587
|
-
continue;
|
|
3588
|
-
}
|
|
3589
|
-
if (c === inString)
|
|
3590
|
-
inString = null;
|
|
3591
|
-
continue;
|
|
3592
|
-
}
|
|
3593
|
-
if (c === "/" && next === "/") {
|
|
3594
|
-
inComment = "line";
|
|
3595
|
-
i++;
|
|
3596
|
-
continue;
|
|
3597
|
-
}
|
|
3598
|
-
if (c === "/" && next === "*") {
|
|
3599
|
-
inComment = "block";
|
|
3600
|
-
i++;
|
|
3601
|
-
continue;
|
|
3602
|
-
}
|
|
3603
|
-
if (c === '"' || c === "'" || c === "`") {
|
|
3604
|
-
inString = c;
|
|
3605
|
-
continue;
|
|
3606
|
-
}
|
|
3607
|
-
if (c === "{" || c === "[" || c === "(")
|
|
3608
|
-
stack.push(c);
|
|
3609
|
-
else if (c === "}" || c === "]" || c === ")")
|
|
3610
|
-
stack.pop();
|
|
3611
|
-
}
|
|
3612
|
-
return stack.length > 0 || inString !== null || inComment === "block";
|
|
3613
|
-
}
|
|
3614
|
-
function formatResult(r) {
|
|
3615
|
-
if (r === null)
|
|
3616
|
-
return "null";
|
|
3617
|
-
if (r === undefined)
|
|
3618
|
-
return "undefined";
|
|
3619
|
-
if (typeof r === "string")
|
|
3620
|
-
return r;
|
|
3621
|
-
if (typeof r === "number" || typeof r === "boolean" || typeof r === "bigint")
|
|
3622
|
-
return String(r);
|
|
3623
|
-
if (typeof r === "function") {
|
|
3624
|
-
const fn = r;
|
|
3625
|
-
return `[Function: ${fn.name || "anonymous"}]`;
|
|
3626
|
-
}
|
|
3627
|
-
if (typeof r === "symbol")
|
|
3628
|
-
return r.toString();
|
|
3629
|
-
try {
|
|
3630
|
-
return JSON.stringify(r, null, 2);
|
|
3631
|
-
} catch {
|
|
3632
|
-
return Object.prototype.toString.call(r);
|
|
3633
|
-
}
|
|
3634
|
-
}
|
|
3635
|
-
function formatError(e) {
|
|
3636
|
-
if (e.name === "SyntaxError")
|
|
3637
|
-
return e.message;
|
|
3638
|
-
return e.stack ? e.stack.split(`
|
|
3639
|
-
`).slice(0, 5).join(`
|
|
3640
|
-
`) : e.message;
|
|
3641
|
-
}
|
|
3642
|
-
function loadHistory(path) {
|
|
3643
|
-
if (!existsSync6(path))
|
|
3644
|
-
return [];
|
|
3645
|
-
try {
|
|
3646
|
-
return readFileSync3(path, "utf-8").split(`
|
|
3647
|
-
`).filter(Boolean);
|
|
3648
|
-
} catch {
|
|
3649
|
-
return [];
|
|
3650
|
-
}
|
|
3651
|
-
}
|
|
3652
|
-
function saveHistoryFile(path, history) {
|
|
3653
|
-
try {
|
|
3654
|
-
const dir = dirname2(path);
|
|
3655
|
-
if (!existsSync6(dir))
|
|
3656
|
-
mkdirSync4(dir, { recursive: true });
|
|
3657
|
-
writeFileSync4(path, history.slice(-1000).join(`
|
|
3658
|
-
`));
|
|
3659
|
-
} catch {}
|
|
3660
|
-
}
|
|
3661
|
-
var repl_default = replCommand;
|
|
3662
|
-
|
|
3663
|
-
// packages/cli/src/commands/route-list.ts
|
|
3664
|
-
import { readdirSync, statSync } from "fs";
|
|
3665
|
-
import { resolve as resolve22 } from "path";
|
|
3666
|
-
import { colors as colors2, logger as logger22 } from "@nexusts/core/index.js";
|
|
3667
|
-
var routeListCommand = {
|
|
3668
|
-
name: "route:list",
|
|
3669
|
-
aliases: ["routes", "route-list"],
|
|
3670
|
-
summary: "List registered HTTP routes",
|
|
3671
|
-
description: "Reads route metadata from controllers and prints a table. Falls back to a scan message when controllers don't use the decorator style.",
|
|
3672
|
-
flags: [
|
|
3673
|
-
{ name: "format", description: "Output format: table (default) | json" }
|
|
3674
|
-
],
|
|
3675
|
-
async run(ctx) {
|
|
3676
|
-
const controllersDir = resolve22(ctx.cwd, ctx.config.paths.controllers);
|
|
3677
|
-
try {
|
|
3678
|
-
statSync(controllersDir);
|
|
3679
|
-
} catch {
|
|
3680
|
-
logger22.warn(`No controllers directory at ${controllersDir}.`);
|
|
3681
|
-
return 0;
|
|
3682
|
-
}
|
|
3683
|
-
const files = readdirSync(controllersDir).filter((f) => f.endsWith(".ts"));
|
|
3684
|
-
if (files.length === 0) {
|
|
3685
|
-
logger22.info("No controllers found.");
|
|
3686
|
-
return 0;
|
|
3687
|
-
}
|
|
3688
|
-
const routes = [];
|
|
3689
|
-
for (const file of files) {
|
|
3690
|
-
const fullPath = resolve22(controllersDir, file);
|
|
3691
|
-
try {
|
|
3692
|
-
const mod = await import(`${fullPath}?t=${Date.now()}`);
|
|
3693
|
-
for (const exportName of Object.keys(mod)) {
|
|
3694
|
-
const cls = mod[exportName];
|
|
3695
|
-
if (typeof cls !== "function")
|
|
3696
|
-
continue;
|
|
3697
|
-
const prefix = Reflect.getMetadata("nexus:controller:prefix", cls) ?? "";
|
|
3698
|
-
const routeList = Reflect.getMetadata("nexus:routes", cls) ?? [];
|
|
3699
|
-
for (const r of routeList) {
|
|
3700
|
-
routes.push({
|
|
3701
|
-
method: String(r.method).toUpperCase(),
|
|
3702
|
-
path: joinPath(prefix, r.path),
|
|
3703
|
-
handler: String(r.propertyKey),
|
|
3704
|
-
controller: cls.name || exportName
|
|
3705
|
-
});
|
|
3968
|
+
case ".history": {
|
|
3969
|
+
const hist = rl.history ?? [];
|
|
3970
|
+
const histArr = hist;
|
|
3971
|
+
histArr.forEach((h, i) => {
|
|
3972
|
+
console.log(` ${(i + 1).toString().padStart(4)}: ${h}`);
|
|
3973
|
+
});
|
|
3974
|
+
return true;
|
|
3975
|
+
}
|
|
3976
|
+
case ".reset": {
|
|
3977
|
+
for (const k of Object.keys(env)) {
|
|
3978
|
+
if (k !== "console")
|
|
3979
|
+
delete env[k];
|
|
3706
3980
|
}
|
|
3981
|
+
console.log(" context reset");
|
|
3982
|
+
return true;
|
|
3707
3983
|
}
|
|
3708
|
-
|
|
3709
|
-
|
|
3984
|
+
default:
|
|
3985
|
+
console.error(` unknown command: ${cmd}`);
|
|
3986
|
+
console.log(" type .help for the list");
|
|
3987
|
+
return true;
|
|
3710
3988
|
}
|
|
3711
|
-
}
|
|
3712
|
-
if (routes.length === 0) {
|
|
3713
|
-
logger22.info("No routes discovered via metadata. " + "This usually means the controllers use the Adonis or functional style \u2014 see nx.config.ts:routing.");
|
|
3714
|
-
return 0;
|
|
3715
|
-
}
|
|
3716
|
-
const format = ctx.flags["format"] ?? "table";
|
|
3717
|
-
if (format === "json") {
|
|
3718
|
-
console.log(JSON.stringify(routes, null, 2));
|
|
3719
|
-
return 0;
|
|
3720
|
-
}
|
|
3721
|
-
routes.sort((a, b) => a.path.localeCompare(b.path));
|
|
3722
|
-
logger22.heading(`Routes (${routes.length})`);
|
|
3723
|
-
const methodColors = {
|
|
3724
|
-
GET: colors2.cyan,
|
|
3725
|
-
POST: colors2.green,
|
|
3726
|
-
PUT: colors2.yellow,
|
|
3727
|
-
PATCH: colors2.yellow,
|
|
3728
|
-
DELETE: colors2.red,
|
|
3729
|
-
OPTIONS: colors2.gray,
|
|
3730
|
-
HEAD: colors2.gray
|
|
3731
3989
|
};
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
const m = colorize(r.method.padEnd(methodWidth));
|
|
3737
|
-
const p = colors2.bold(r.path.padEnd(pathWidth));
|
|
3738
|
-
const c = colors2.dim(`${r.controller}.${r.handler}`);
|
|
3739
|
-
console.log(` ${m} ${p} ${c}`);
|
|
3740
|
-
}
|
|
3741
|
-
logger22.blank();
|
|
3742
|
-
return 0;
|
|
3743
|
-
}
|
|
3744
|
-
};
|
|
3745
|
-
function joinPath(prefix, sub) {
|
|
3746
|
-
const a = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
3747
|
-
const b = sub.startsWith("/") ? sub : `/${sub}`;
|
|
3748
|
-
return `${a}${b}` || "/";
|
|
3749
|
-
}
|
|
3750
|
-
var route_list_default = routeListCommand;
|
|
3751
|
-
|
|
3752
|
-
// packages/cli/src/commands/index.ts
|
|
3753
|
-
var commands = [
|
|
3754
|
-
new_default,
|
|
3755
|
-
init_default,
|
|
3756
|
-
config_default,
|
|
3757
|
-
make_crud_default,
|
|
3758
|
-
make_controller_default,
|
|
3759
|
-
make_service_default,
|
|
3760
|
-
make_module_default,
|
|
3761
|
-
make_model_default,
|
|
3762
|
-
make_migration_default,
|
|
3763
|
-
make_middleware_default,
|
|
3764
|
-
make_validator_default,
|
|
3765
|
-
make_auth_default,
|
|
3766
|
-
make_queue_default,
|
|
3767
|
-
make_schedule_default,
|
|
3768
|
-
make_listener_default,
|
|
3769
|
-
make_session_default,
|
|
3770
|
-
db_migrate_default,
|
|
3771
|
-
db_generate_default,
|
|
3772
|
-
db_seed_default,
|
|
3773
|
-
route_list_default,
|
|
3774
|
-
info_default,
|
|
3775
|
-
repl_default
|
|
3776
|
-
];
|
|
3777
|
-
function findCommand(name) {
|
|
3778
|
-
return commands.find((c) => c.name === name || (c.aliases ?? []).includes(name));
|
|
3779
|
-
}
|
|
3780
|
-
|
|
3781
|
-
// packages/cli/src/core/config.ts
|
|
3782
|
-
import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
|
|
3783
|
-
import { resolve as resolve23 } from "path";
|
|
3784
|
-
var DEFAULT_CONFIG = {
|
|
3785
|
-
routing: "nest",
|
|
3786
|
-
view: "inertia",
|
|
3787
|
-
orm: "drizzle",
|
|
3788
|
-
database: {
|
|
3789
|
-
driver: "bun-sqlite",
|
|
3790
|
-
url: "app.db"
|
|
3791
|
-
},
|
|
3792
|
-
inertia: {
|
|
3793
|
-
frontend: "react",
|
|
3794
|
-
ssr: true,
|
|
3795
|
-
version: "1.0.0"
|
|
3796
|
-
},
|
|
3797
|
-
paths: {
|
|
3798
|
-
app: "app",
|
|
3799
|
-
controllers: "app/controllers",
|
|
3800
|
-
services: "app/services",
|
|
3801
|
-
modules: "app/modules",
|
|
3802
|
-
models: "app/models",
|
|
3803
|
-
migrations: "app/database/migrations",
|
|
3804
|
-
seeds: "db/seeds",
|
|
3805
|
-
middleware: "app/middleware",
|
|
3806
|
-
dto: "app/dto"
|
|
3807
|
-
},
|
|
3808
|
-
moduleStyle: "nest",
|
|
3809
|
-
auth: undefined,
|
|
3810
|
-
queue: undefined
|
|
3811
|
-
};
|
|
3812
|
-
var CONFIG_CANDIDATES = [
|
|
3813
|
-
"nx.config.ts",
|
|
3814
|
-
"nx.config.js",
|
|
3815
|
-
"nx.config.mjs",
|
|
3816
|
-
".nxrc.json"
|
|
3817
|
-
];
|
|
3818
|
-
async function loadConfig(cwd = process.cwd()) {
|
|
3819
|
-
let config = {};
|
|
3820
|
-
let configSource = "<defaults>";
|
|
3821
|
-
for (const candidate of CONFIG_CANDIDATES) {
|
|
3822
|
-
const path = resolve23(cwd, candidate);
|
|
3823
|
-
if (!existsSync7(path))
|
|
3824
|
-
continue;
|
|
3825
|
-
try {
|
|
3826
|
-
if (candidate.endsWith(".json")) {
|
|
3827
|
-
const raw = readFileSync4(path, "utf8");
|
|
3828
|
-
config = JSON.parse(raw);
|
|
3990
|
+
rl.on("line", async (line) => {
|
|
3991
|
+
const trimmed = line.trim();
|
|
3992
|
+
if (trimmed.startsWith(".")) {
|
|
3993
|
+
await handleDotCommand(trimmed);
|
|
3829
3994
|
} else {
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3995
|
+
buffer += line + `
|
|
3996
|
+
`;
|
|
3997
|
+
if (isIncomplete(buffer)) {
|
|
3998
|
+
rl.setPrompt("... ");
|
|
3999
|
+
rl.prompt();
|
|
4000
|
+
return;
|
|
3836
4001
|
}
|
|
4002
|
+
await evaluate(buffer);
|
|
4003
|
+
buffer = "";
|
|
4004
|
+
rl.setPrompt("\u276F ");
|
|
3837
4005
|
}
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
}
|
|
3843
|
-
}
|
|
3844
|
-
const merged = mergeWithEnv(DEFAULT_CONFIG, config);
|
|
3845
|
-
assertEnum("routing", merged.routing, [
|
|
3846
|
-
"nest",
|
|
3847
|
-
"adonis",
|
|
3848
|
-
"functional",
|
|
3849
|
-
"mixed"
|
|
3850
|
-
]);
|
|
3851
|
-
assertEnum("view", merged.view, ["rendu", "edge", "inertia", "none"]);
|
|
3852
|
-
assertEnum("orm", merged.orm, ["drizzle", "prisma", "kysely", "none"]);
|
|
3853
|
-
assertEnum("database.driver", merged.database.driver, [
|
|
3854
|
-
"bun-sqlite",
|
|
3855
|
-
"node-sqlite",
|
|
3856
|
-
"libsql",
|
|
3857
|
-
"postgres",
|
|
3858
|
-
"mysql",
|
|
3859
|
-
"none"
|
|
3860
|
-
]);
|
|
3861
|
-
assertEnum("inertia.frontend", merged.inertia.frontend, [
|
|
3862
|
-
"react",
|
|
3863
|
-
"vue",
|
|
3864
|
-
"svelte",
|
|
3865
|
-
"solid"
|
|
3866
|
-
]);
|
|
3867
|
-
if (process.env["NX_DEBUG"] === "1") {
|
|
3868
|
-
console.log(`[nx] config source: ${configSource}`);
|
|
4006
|
+
rl.prompt();
|
|
4007
|
+
});
|
|
4008
|
+
rl.prompt();
|
|
4009
|
+
return new Promise(() => {});
|
|
3869
4010
|
}
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
merged.database.driver = env["NX_DATABASE_DRIVER"];
|
|
3889
|
-
if (env["NX_DATABASE_URL"])
|
|
3890
|
-
merged.database.url = env["NX_DATABASE_URL"];
|
|
3891
|
-
if (env["NX_INERTIA_FRONTEND"])
|
|
3892
|
-
merged.inertia.frontend = env["NX_INERTIA_FRONTEND"];
|
|
3893
|
-
if (env["NX_INERTIA_SSR"])
|
|
3894
|
-
merged.inertia.ssr = env["NX_INERTIA_SSR"] !== "false" && env["NX_INERTIA_SSR"] !== "0";
|
|
3895
|
-
if (env["NX_INERTIA_VERSION"])
|
|
3896
|
-
merged.inertia.version = env["NX_INERTIA_VERSION"];
|
|
3897
|
-
return merged;
|
|
4011
|
+
};
|
|
4012
|
+
async function preloadService(env, app, name, path, className) {
|
|
4013
|
+
try {
|
|
4014
|
+
const mod = await import(path);
|
|
4015
|
+
const ServiceClass = mod[className];
|
|
4016
|
+
if (!ServiceClass)
|
|
4017
|
+
return;
|
|
4018
|
+
const Token = ServiceClass.TOKEN ?? ServiceClass[`${className.toUpperCase()}_TOKEN`];
|
|
4019
|
+
if (!Token)
|
|
4020
|
+
return;
|
|
4021
|
+
try {
|
|
4022
|
+
env[name] = app.container.resolve(Token);
|
|
4023
|
+
} catch {
|
|
4024
|
+
try {
|
|
4025
|
+
env[name] = app.container.resolve(ServiceClass);
|
|
4026
|
+
} catch {}
|
|
4027
|
+
}
|
|
4028
|
+
} catch {}
|
|
3898
4029
|
}
|
|
3899
|
-
function
|
|
3900
|
-
if (!
|
|
3901
|
-
|
|
4030
|
+
function listServices(container) {
|
|
4031
|
+
if (!container)
|
|
4032
|
+
return [];
|
|
4033
|
+
const c2 = container;
|
|
4034
|
+
if (typeof c2.listProviders !== "function")
|
|
4035
|
+
return [];
|
|
4036
|
+
try {
|
|
4037
|
+
return c2.listProviders().map((p) => p.token?.toString?.() ?? String(p.token));
|
|
4038
|
+
} catch {
|
|
4039
|
+
return [];
|
|
3902
4040
|
}
|
|
3903
4041
|
}
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
if (arg === "--") {
|
|
3916
|
-
endOfOptions = true;
|
|
3917
|
-
i++;
|
|
4042
|
+
function isIncomplete(code) {
|
|
4043
|
+
const stack = [];
|
|
4044
|
+
let inString = null;
|
|
4045
|
+
let inComment = null;
|
|
4046
|
+
for (let i = 0;i < code.length; i++) {
|
|
4047
|
+
const c2 = code[i];
|
|
4048
|
+
const next = code[i + 1];
|
|
4049
|
+
if (inComment === "line") {
|
|
4050
|
+
if (c2 === `
|
|
4051
|
+
`)
|
|
4052
|
+
inComment = null;
|
|
3918
4053
|
continue;
|
|
3919
4054
|
}
|
|
3920
|
-
if (
|
|
3921
|
-
|
|
3922
|
-
|
|
4055
|
+
if (inComment === "block") {
|
|
4056
|
+
if (c2 === "*" && next === "/") {
|
|
4057
|
+
inComment = null;
|
|
4058
|
+
i++;
|
|
4059
|
+
}
|
|
3923
4060
|
continue;
|
|
3924
4061
|
}
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
const [, name, inline] = longMatch;
|
|
3928
|
-
const flagName = name;
|
|
3929
|
-
if (inline !== undefined) {
|
|
3930
|
-
setFlag(flags, flagName, inline);
|
|
4062
|
+
if (inString) {
|
|
4063
|
+
if (c2 === "\\") {
|
|
3931
4064
|
i++;
|
|
3932
4065
|
continue;
|
|
3933
4066
|
}
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
setFlag(flags, flagName, next);
|
|
3937
|
-
i += 2;
|
|
3938
|
-
} else {
|
|
3939
|
-
setFlag(flags, flagName, true);
|
|
3940
|
-
i++;
|
|
3941
|
-
}
|
|
4067
|
+
if (c2 === inString)
|
|
4068
|
+
inString = null;
|
|
3942
4069
|
continue;
|
|
3943
4070
|
}
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
const next = argv[i + 1];
|
|
3948
|
-
if (next !== undefined && !next.startsWith("-")) {
|
|
3949
|
-
setFlag(flags, flagName, next);
|
|
3950
|
-
i += 2;
|
|
3951
|
-
} else {
|
|
3952
|
-
setFlag(flags, flagName, true);
|
|
3953
|
-
i++;
|
|
3954
|
-
}
|
|
4071
|
+
if (c2 === "/" && next === "/") {
|
|
4072
|
+
inComment = "line";
|
|
4073
|
+
i++;
|
|
3955
4074
|
continue;
|
|
3956
4075
|
}
|
|
3957
|
-
|
|
3958
|
-
|
|
4076
|
+
if (c2 === "/" && next === "*") {
|
|
4077
|
+
inComment = "block";
|
|
4078
|
+
i++;
|
|
4079
|
+
continue;
|
|
4080
|
+
}
|
|
4081
|
+
if (c2 === '"' || c2 === "'" || c2 === "`") {
|
|
4082
|
+
inString = c2;
|
|
4083
|
+
continue;
|
|
4084
|
+
}
|
|
4085
|
+
if (c2 === "{" || c2 === "[" || c2 === "(")
|
|
4086
|
+
stack.push(c2);
|
|
4087
|
+
else if (c2 === "}" || c2 === "]" || c2 === ")")
|
|
4088
|
+
stack.pop();
|
|
3959
4089
|
}
|
|
3960
|
-
|
|
3961
|
-
return { command, positional, flags };
|
|
4090
|
+
return stack.length > 0 || inString !== null || inComment === "block";
|
|
3962
4091
|
}
|
|
3963
|
-
function
|
|
3964
|
-
if (
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
return;
|
|
4092
|
+
function formatResult(r) {
|
|
4093
|
+
if (r === null)
|
|
4094
|
+
return "null";
|
|
4095
|
+
if (r === undefined)
|
|
4096
|
+
return "undefined";
|
|
4097
|
+
if (typeof r === "string")
|
|
4098
|
+
return r;
|
|
4099
|
+
if (typeof r === "number" || typeof r === "boolean" || typeof r === "bigint")
|
|
4100
|
+
return String(r);
|
|
4101
|
+
if (typeof r === "function") {
|
|
4102
|
+
const fn = r;
|
|
4103
|
+
return `[Function: ${fn.name || "anonymous"}]`;
|
|
3968
4104
|
}
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
flags[name] = [
|
|
3976
|
-
String(existing),
|
|
3977
|
-
typeof value === "string" ? value : String(value)
|
|
3978
|
-
];
|
|
4105
|
+
if (typeof r === "symbol")
|
|
4106
|
+
return r.toString();
|
|
4107
|
+
try {
|
|
4108
|
+
return JSON.stringify(r, null, 2);
|
|
4109
|
+
} catch {
|
|
4110
|
+
return Object.prototype.toString.call(r);
|
|
3979
4111
|
}
|
|
3980
4112
|
}
|
|
3981
|
-
function
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
return v !== "false" && v !== "0" && v !== "no";
|
|
4113
|
+
function formatError(e) {
|
|
4114
|
+
if (e.name === "SyntaxError")
|
|
4115
|
+
return e.message;
|
|
4116
|
+
return e.stack ? e.stack.split(`
|
|
4117
|
+
`).slice(0, 5).join(`
|
|
4118
|
+
`) : e.message;
|
|
3988
4119
|
}
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
green: wrap(32, 39),
|
|
3998
|
-
yellow: wrap(33, 39),
|
|
3999
|
-
blue: wrap(34, 39),
|
|
4000
|
-
magenta: wrap(35, 39),
|
|
4001
|
-
cyan: wrap(36, 39),
|
|
4002
|
-
gray: wrap(90, 39)
|
|
4003
|
-
};
|
|
4004
|
-
var PREFIXES = {
|
|
4005
|
-
info: `${c.cyan("\u2139")}`,
|
|
4006
|
-
success: `${c.green("\u2714")}`,
|
|
4007
|
-
warn: `${c.yellow("\u26A0")}`,
|
|
4008
|
-
error: `${c.red("\u2716")}`,
|
|
4009
|
-
debug: `${c.gray("\xB7")}`,
|
|
4010
|
-
finger: `${c.magenta("\u279C")}`
|
|
4011
|
-
};
|
|
4012
|
-
|
|
4013
|
-
class Logger {
|
|
4014
|
-
verbose = false;
|
|
4015
|
-
setVerbose(v) {
|
|
4016
|
-
this.verbose = v;
|
|
4017
|
-
}
|
|
4018
|
-
info(message) {
|
|
4019
|
-
console.log(`${PREFIXES.info} ${message}`);
|
|
4020
|
-
}
|
|
4021
|
-
success(message) {
|
|
4022
|
-
console.log(`${PREFIXES.success} ${message}`);
|
|
4023
|
-
}
|
|
4024
|
-
warn(message) {
|
|
4025
|
-
console.warn(`${PREFIXES.warn} ${c.yellow(message)}`);
|
|
4026
|
-
}
|
|
4027
|
-
error(message) {
|
|
4028
|
-
console.error(`${PREFIXES.error} ${c.red(message)}`);
|
|
4029
|
-
}
|
|
4030
|
-
debug(message) {
|
|
4031
|
-
if (!this.verbose)
|
|
4032
|
-
return;
|
|
4033
|
-
console.log(`${PREFIXES.debug} ${c.gray(message)}`);
|
|
4034
|
-
}
|
|
4035
|
-
finger(message) {
|
|
4036
|
-
console.log(`${PREFIXES.finger} ${c.magenta(message)}`);
|
|
4120
|
+
function loadHistory(path) {
|
|
4121
|
+
if (!existsSync8(path))
|
|
4122
|
+
return [];
|
|
4123
|
+
try {
|
|
4124
|
+
return readFileSync5(path, "utf-8").split(`
|
|
4125
|
+
`).filter(Boolean);
|
|
4126
|
+
} catch {
|
|
4127
|
+
return [];
|
|
4037
4128
|
}
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4129
|
+
}
|
|
4130
|
+
function saveHistoryFile(path, history) {
|
|
4131
|
+
try {
|
|
4132
|
+
const dir = dirname3(path);
|
|
4133
|
+
if (!existsSync8(dir))
|
|
4134
|
+
mkdirSync5(dir, { recursive: true });
|
|
4135
|
+
writeFileSync5(path, history.slice(-1000).join(`
|
|
4136
|
+
`));
|
|
4137
|
+
} catch {}
|
|
4138
|
+
}
|
|
4139
|
+
var repl_default = replCommand;
|
|
4140
|
+
|
|
4141
|
+
// packages/cli/src/commands/route-list.ts
|
|
4142
|
+
import { readdirSync, statSync as statSync2 } from "fs";
|
|
4143
|
+
import { resolve as resolve24 } from "path";
|
|
4144
|
+
var routeListCommand = {
|
|
4145
|
+
name: "route:list",
|
|
4146
|
+
aliases: ["routes", "route-list"],
|
|
4147
|
+
summary: "List registered HTTP routes",
|
|
4148
|
+
description: "Reads route metadata from controllers and prints a table. Falls back to a scan message when controllers don't use the decorator style.",
|
|
4149
|
+
flags: [
|
|
4150
|
+
{ name: "format", description: "Output format: table (default) | json" }
|
|
4151
|
+
],
|
|
4152
|
+
async run(ctx) {
|
|
4153
|
+
const controllersDir = resolve24(ctx.cwd, ctx.config.paths.controllers);
|
|
4154
|
+
try {
|
|
4155
|
+
statSync2(controllersDir);
|
|
4156
|
+
} catch {
|
|
4157
|
+
logger.warn(`No controllers directory at ${controllersDir}.`);
|
|
4158
|
+
return 0;
|
|
4043
4159
|
}
|
|
4160
|
+
const files = readdirSync(controllersDir).filter((f) => f.endsWith(".ts"));
|
|
4161
|
+
if (files.length === 0) {
|
|
4162
|
+
logger.info("No controllers found.");
|
|
4163
|
+
return 0;
|
|
4164
|
+
}
|
|
4165
|
+
const routes = [];
|
|
4166
|
+
for (const file of files) {
|
|
4167
|
+
const fullPath = resolve24(controllersDir, file);
|
|
4168
|
+
try {
|
|
4169
|
+
const mod = await import(`${fullPath}?t=${Date.now()}`);
|
|
4170
|
+
for (const exportName of Object.keys(mod)) {
|
|
4171
|
+
const cls = mod[exportName];
|
|
4172
|
+
if (typeof cls !== "function")
|
|
4173
|
+
continue;
|
|
4174
|
+
const prefix = Reflect.getMetadata("nexus:controller:prefix", cls) ?? "";
|
|
4175
|
+
const routeList = Reflect.getMetadata("nexus:routes", cls) ?? [];
|
|
4176
|
+
for (const r of routeList) {
|
|
4177
|
+
routes.push({
|
|
4178
|
+
method: String(r.method).toUpperCase(),
|
|
4179
|
+
path: joinPath(prefix, r.path),
|
|
4180
|
+
handler: String(r.propertyKey),
|
|
4181
|
+
controller: cls.name || exportName
|
|
4182
|
+
});
|
|
4183
|
+
}
|
|
4184
|
+
}
|
|
4185
|
+
} catch (err) {
|
|
4186
|
+
logger.warn(`could not parse ${file}: ${err.message ?? err}`);
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4189
|
+
if (routes.length === 0) {
|
|
4190
|
+
logger.info("No routes discovered via metadata. " + "This usually means the controllers use the Adonis or functional style \u2014 see nx.config.ts:routing.");
|
|
4191
|
+
return 0;
|
|
4192
|
+
}
|
|
4193
|
+
const format = ctx.flags["format"] ?? "table";
|
|
4194
|
+
if (format === "json") {
|
|
4195
|
+
console.log(JSON.stringify(routes, null, 2));
|
|
4196
|
+
return 0;
|
|
4197
|
+
}
|
|
4198
|
+
routes.sort((a, b) => a.path.localeCompare(b.path));
|
|
4199
|
+
logger.heading(`Routes (${routes.length})`);
|
|
4200
|
+
const methodColors = {
|
|
4201
|
+
GET: colors.cyan,
|
|
4202
|
+
POST: colors.green,
|
|
4203
|
+
PUT: colors.yellow,
|
|
4204
|
+
PATCH: colors.yellow,
|
|
4205
|
+
DELETE: colors.red,
|
|
4206
|
+
OPTIONS: colors.gray,
|
|
4207
|
+
HEAD: colors.gray
|
|
4208
|
+
};
|
|
4209
|
+
const pathWidth = Math.max(...routes.map((r) => r.path.length));
|
|
4210
|
+
const methodWidth = Math.max(...routes.map((r) => r.method.length));
|
|
4211
|
+
for (const r of routes) {
|
|
4212
|
+
const colorize = methodColors[r.method] ?? colors.reset;
|
|
4213
|
+
const m = colorize(r.method.padEnd(methodWidth));
|
|
4214
|
+
const p = colors.bold(r.path.padEnd(pathWidth));
|
|
4215
|
+
const c2 = colors.dim(`${r.controller}.${r.handler}`);
|
|
4216
|
+
console.log(` ${m} ${p} ${c2}`);
|
|
4217
|
+
}
|
|
4218
|
+
logger.blank();
|
|
4219
|
+
return 0;
|
|
4044
4220
|
}
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4221
|
+
};
|
|
4222
|
+
function joinPath(prefix, sub) {
|
|
4223
|
+
const a = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
4224
|
+
const b = sub.startsWith("/") ? sub : `/${sub}`;
|
|
4225
|
+
return `${a}${b}` || "/";
|
|
4226
|
+
}
|
|
4227
|
+
var route_list_default = routeListCommand;
|
|
4228
|
+
|
|
4229
|
+
// packages/cli/src/commands/index.ts
|
|
4230
|
+
var commands = [
|
|
4231
|
+
new_default,
|
|
4232
|
+
init_default,
|
|
4233
|
+
config_default,
|
|
4234
|
+
make_crud_default,
|
|
4235
|
+
make_controller_default,
|
|
4236
|
+
make_service_default,
|
|
4237
|
+
make_module_default,
|
|
4238
|
+
make_model_default,
|
|
4239
|
+
make_migration_default,
|
|
4240
|
+
make_middleware_default,
|
|
4241
|
+
make_validator_default,
|
|
4242
|
+
make_auth_default,
|
|
4243
|
+
make_queue_default,
|
|
4244
|
+
make_schedule_default,
|
|
4245
|
+
make_listener_default,
|
|
4246
|
+
make_session_default,
|
|
4247
|
+
db_migrate_default,
|
|
4248
|
+
db_generate_default,
|
|
4249
|
+
db_seed_default,
|
|
4250
|
+
route_list_default,
|
|
4251
|
+
info_default,
|
|
4252
|
+
repl_default
|
|
4253
|
+
];
|
|
4254
|
+
function findCommand(name) {
|
|
4255
|
+
return commands.find((c2) => c2.name === name || (c2.aliases ?? []).includes(name));
|
|
4056
4256
|
}
|
|
4057
|
-
|
|
4058
|
-
var colors3 = c;
|
|
4257
|
+
|
|
4059
4258
|
// packages/cli/src/index.ts
|
|
4060
4259
|
async function main() {
|
|
4061
4260
|
const parsed = parseArgs(process.argv.slice(2));
|
|
4062
|
-
const verbose =
|
|
4063
|
-
|
|
4261
|
+
const verbose = flagBool(parsed.flags, "verbose", false);
|
|
4262
|
+
logger.setVerbose(verbose);
|
|
4064
4263
|
if (parsed.flags["version"] === true) {
|
|
4065
4264
|
console.log(PKG_VERSION);
|
|
4066
4265
|
return 0;
|
|
@@ -4071,8 +4270,8 @@ async function main() {
|
|
|
4071
4270
|
const command = parsed.command ? findCommand(parsed.command) : undefined;
|
|
4072
4271
|
if (!command) {
|
|
4073
4272
|
if (parsed.command) {
|
|
4074
|
-
|
|
4075
|
-
|
|
4273
|
+
logger.error(`Unknown command: ${parsed.command}`);
|
|
4274
|
+
logger.info(`Run \`nx help\` for a list of commands.`);
|
|
4076
4275
|
return 1;
|
|
4077
4276
|
}
|
|
4078
4277
|
return renderHelp();
|
|
@@ -4090,80 +4289,80 @@ function renderHelp(commandName) {
|
|
|
4090
4289
|
if (commandName) {
|
|
4091
4290
|
const cmd = findCommand(commandName);
|
|
4092
4291
|
if (!cmd) {
|
|
4093
|
-
|
|
4292
|
+
logger.error(`Unknown command: ${commandName}`);
|
|
4094
4293
|
return 1;
|
|
4095
4294
|
}
|
|
4096
4295
|
renderCommandHelp(cmd);
|
|
4097
4296
|
return 0;
|
|
4098
4297
|
}
|
|
4099
|
-
|
|
4298
|
+
logger.heading("nx \u2014 Nexus CLI");
|
|
4100
4299
|
console.log(`
|
|
4101
|
-
${
|
|
4300
|
+
${colors.dim("Adonis ACE-style command runner for the NexusTS framework.")}
|
|
4102
4301
|
|
|
4103
|
-
${
|
|
4302
|
+
${colors.bold("Usage")}
|
|
4104
4303
|
nx <command> [args...]
|
|
4105
4304
|
|
|
4106
|
-
${
|
|
4305
|
+
${colors.bold("Commands")}
|
|
4107
4306
|
`);
|
|
4108
4307
|
const nameWidth = Math.max(...commands.map((c2) => c2.name.length));
|
|
4109
4308
|
for (const c2 of commands) {
|
|
4110
4309
|
const padded = c2.name.padEnd(nameWidth);
|
|
4111
|
-
const aliasStr = c2.aliases?.length ? ` ${
|
|
4112
|
-
console.log(` ${
|
|
4310
|
+
const aliasStr = c2.aliases?.length ? ` ${colors.dim(`(${c2.aliases.join(", ")})`)}` : "";
|
|
4311
|
+
console.log(` ${colors.cyan(padded)}${aliasStr} ${c2.summary}`);
|
|
4113
4312
|
}
|
|
4114
4313
|
console.log(`
|
|
4115
|
-
${
|
|
4314
|
+
${colors.bold("Global flags")}
|
|
4116
4315
|
--help, -h Show help (or \`nx help <command>\`)
|
|
4117
4316
|
--version, -v Print the CLI version
|
|
4118
4317
|
--verbose Verbose output
|
|
4119
4318
|
--no-color Disable ANSI color output
|
|
4120
4319
|
|
|
4121
|
-
${
|
|
4122
|
-
${
|
|
4123
|
-
${
|
|
4124
|
-
${
|
|
4125
|
-
${
|
|
4126
|
-
${
|
|
4127
|
-
${
|
|
4128
|
-
${
|
|
4320
|
+
${colors.bold("Examples")}
|
|
4321
|
+
${colors.dim("nx new my-app")}
|
|
4322
|
+
${colors.dim("nx init --style nest --view inertia --orm drizzle")}
|
|
4323
|
+
${colors.dim("nx make:crud Post")}
|
|
4324
|
+
${colors.dim("nx make:controller User")}
|
|
4325
|
+
${colors.dim("nx make:migration create_users_table")}
|
|
4326
|
+
${colors.dim("nx info")}
|
|
4327
|
+
${colors.dim("nx route:list")}
|
|
4129
4328
|
`);
|
|
4130
4329
|
return 0;
|
|
4131
4330
|
}
|
|
4132
4331
|
function renderCommandHelp(cmd) {
|
|
4133
|
-
|
|
4332
|
+
logger.heading(cmd.name);
|
|
4134
4333
|
if (cmd.aliases?.length) {
|
|
4135
|
-
console.log(` ${
|
|
4334
|
+
console.log(` ${colors.dim("aliases:")} ${cmd.aliases.join(", ")}`);
|
|
4136
4335
|
}
|
|
4137
4336
|
if (cmd.description)
|
|
4138
4337
|
console.log(`
|
|
4139
4338
|
${cmd.description}
|
|
4140
4339
|
`);
|
|
4141
4340
|
if (cmd.flags?.length) {
|
|
4142
|
-
console.log(
|
|
4341
|
+
console.log(colors.bold(`
|
|
4143
4342
|
Flags`));
|
|
4144
4343
|
for (const f of cmd.flags) {
|
|
4145
4344
|
const short = f.short ? `, -${f.short}` : "";
|
|
4146
|
-
const def = f.default !== undefined ? ` ${
|
|
4345
|
+
const def = f.default !== undefined ? ` ${colors.dim(`(default: ${String(f.default)})`)}` : "";
|
|
4147
4346
|
console.log(` --${f.name}${short.padEnd(6)} ${f.description}${def}`);
|
|
4148
4347
|
}
|
|
4149
4348
|
}
|
|
4150
4349
|
if (cmd.examples?.length) {
|
|
4151
|
-
console.log(
|
|
4350
|
+
console.log(colors.bold(`
|
|
4152
4351
|
Examples`));
|
|
4153
4352
|
for (const ex of cmd.examples) {
|
|
4154
|
-
console.log(` ${
|
|
4353
|
+
console.log(` ${colors.cyan(ex)}`);
|
|
4155
4354
|
}
|
|
4156
4355
|
}
|
|
4157
4356
|
console.log();
|
|
4158
4357
|
}
|
|
4159
4358
|
var PKG_VERSION = "0.1.0";
|
|
4160
4359
|
main().then((code) => process.exit(code)).catch((err) => {
|
|
4161
|
-
|
|
4360
|
+
logger.error(err?.message ?? String(err));
|
|
4162
4361
|
if (process.env["NX_DEBUG"] === "1" && err?.stack) {
|
|
4163
4362
|
console.error(err.stack);
|
|
4164
4363
|
}
|
|
4165
4364
|
process.exit(1);
|
|
4166
4365
|
});
|
|
4167
4366
|
|
|
4168
|
-
//# debugId=
|
|
4367
|
+
//# debugId=CB0A9796F624CF2164756E2164756E21
|
|
4169
4368
|
//# sourceMappingURL=index.js.map
|