@nexusts/cli 0.8.2 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/init.d.ts +2 -12
- package/dist/commands/new.d.ts +6 -6
- package/dist/core/index.d.ts +1 -0
- package/dist/core/scaffold.d.ts +38 -0
- package/dist/index.js +642 -675
- package/dist/index.js.map +6 -5
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
var __require = import.meta.require;
|
|
20
20
|
|
|
21
21
|
// packages/cli/src/commands/info.ts
|
|
22
|
-
import { resolve as
|
|
22
|
+
import { resolve as resolve5 } from "path";
|
|
23
23
|
|
|
24
24
|
// packages/cli/src/core/args.ts
|
|
25
25
|
var LONG_RE = /^--([^=]+)(?:=(.*))?$/;
|
|
@@ -511,67 +511,9 @@ function loadVersion() {
|
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
513
|
var VERSION = loadVersion();
|
|
514
|
-
// packages/cli/src/
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
aliases: ["i"],
|
|
518
|
-
summary: "Show project configuration",
|
|
519
|
-
description: "Prints the resolved nx.config.ts plus relevant env vars.",
|
|
520
|
-
async run(ctx) {
|
|
521
|
-
logger.heading("NexusTS CLI \u2014 Project Info");
|
|
522
|
-
logger.info(colors.bold("Resolved configuration"));
|
|
523
|
-
logger.blank();
|
|
524
|
-
logger.table([
|
|
525
|
-
["routing", String(ctx.config.routing)],
|
|
526
|
-
["view", String(ctx.config.view)],
|
|
527
|
-
["orm", String(ctx.config.orm)],
|
|
528
|
-
["dialect", String(ctx.config.dialect ?? "(none)")],
|
|
529
|
-
["database.driver", String(ctx.config.database.driver)],
|
|
530
|
-
["database.url", String(ctx.config.database.url)],
|
|
531
|
-
["inertia.frontend", String(ctx.config.inertia.frontend)],
|
|
532
|
-
["inertia.ssr", String(ctx.config.inertia.ssr)],
|
|
533
|
-
["inertia.version", String(ctx.config.inertia.version)]
|
|
534
|
-
]);
|
|
535
|
-
logger.blank();
|
|
536
|
-
logger.info(colors.bold("Paths"));
|
|
537
|
-
logger.blank();
|
|
538
|
-
for (const [k, v] of Object.entries(ctx.config.paths)) {
|
|
539
|
-
logger.table([[k, v]]);
|
|
540
|
-
}
|
|
541
|
-
logger.blank();
|
|
542
|
-
logger.info(colors.bold("Environment"));
|
|
543
|
-
logger.blank();
|
|
544
|
-
const envKeys = [
|
|
545
|
-
"NODE_ENV",
|
|
546
|
-
"PORT",
|
|
547
|
-
"NEXUS_DEBUG",
|
|
548
|
-
"NO_COLOR",
|
|
549
|
-
"FORCE_COLOR",
|
|
550
|
-
"NX_ROUTING",
|
|
551
|
-
"NX_VIEW",
|
|
552
|
-
"NX_ORM",
|
|
553
|
-
"NX_DATABASE_DRIVER",
|
|
554
|
-
"NX_DATABASE_URL",
|
|
555
|
-
"NX_INERTIA_FRONTEND",
|
|
556
|
-
"NX_INERTIA_SSR"
|
|
557
|
-
];
|
|
558
|
-
for (const k of envKeys) {
|
|
559
|
-
const v = process.env[k];
|
|
560
|
-
logger.table([[k, v === undefined ? colors.dim("(unset)") : v]]);
|
|
561
|
-
}
|
|
562
|
-
logger.blank();
|
|
563
|
-
logger.info(colors.bold("Working directory"));
|
|
564
|
-
logger.blank();
|
|
565
|
-
logger.info(` ${resolve4(ctx.cwd)}`);
|
|
566
|
-
logger.blank();
|
|
567
|
-
return 0;
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
var info_default = infoCommand;
|
|
571
|
-
|
|
572
|
-
// packages/cli/src/commands/init.ts
|
|
573
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
574
|
-
import { resolve as resolve5 } from "path";
|
|
514
|
+
// packages/cli/src/core/scaffold.ts
|
|
515
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
516
|
+
import { resolve as resolve4 } from "path";
|
|
575
517
|
|
|
576
518
|
// packages/cli/src/templates/controller/adonis.ts
|
|
577
519
|
var adonis_default = `
|
|
@@ -1164,140 +1106,508 @@ var templates = {
|
|
|
1164
1106
|
}
|
|
1165
1107
|
};
|
|
1166
1108
|
|
|
1109
|
+
// packages/cli/src/core/scaffold.ts
|
|
1110
|
+
function ensureDirectories(target, view) {
|
|
1111
|
+
mkdirSync2(resolve4(target, "app/controllers"), { recursive: true });
|
|
1112
|
+
mkdirSync2(resolve4(target, "app/modules"), { recursive: true });
|
|
1113
|
+
mkdirSync2(resolve4(target, "app/services"), { recursive: true });
|
|
1114
|
+
mkdirSync2(resolve4(target, "app/models"), { recursive: true });
|
|
1115
|
+
mkdirSync2(resolve4(target, "app/repositories"), { recursive: true });
|
|
1116
|
+
mkdirSync2(resolve4(target, "app/dto"), { recursive: true });
|
|
1117
|
+
mkdirSync2(resolve4(target, "public"), { recursive: true });
|
|
1118
|
+
if (view === "inertia") {
|
|
1119
|
+
mkdirSync2(resolve4(target, "resources/js/Pages"), { recursive: true });
|
|
1120
|
+
} else if (view !== "none") {
|
|
1121
|
+
mkdirSync2(resolve4(target, "resources/views"), { recursive: true });
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
function computeDeps(view, orm, db, frontend) {
|
|
1125
|
+
const deps = {
|
|
1126
|
+
"@nexusts/core": "*",
|
|
1127
|
+
"reflect-metadata": "^0.2.2",
|
|
1128
|
+
hono: "^4.6.0",
|
|
1129
|
+
zod: "^3.23.8"
|
|
1130
|
+
};
|
|
1131
|
+
const devDeps = {};
|
|
1132
|
+
if (orm === "drizzle") {
|
|
1133
|
+
deps["@nexusts/drizzle"] = "*";
|
|
1134
|
+
deps["drizzle-orm"] = "^0.45.0";
|
|
1135
|
+
if (db === "postgres")
|
|
1136
|
+
deps["pg"] = "^8.13.0";
|
|
1137
|
+
if (db === "mysql")
|
|
1138
|
+
deps["mysql2"] = "^3.11.0";
|
|
1139
|
+
if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
|
|
1140
|
+
deps["better-sqlite3"] = "^12.0.0";
|
|
1141
|
+
devDeps["drizzle-kit"] = "^0.31.0";
|
|
1142
|
+
}
|
|
1143
|
+
if (view !== "none") {
|
|
1144
|
+
deps["@nexusts/static"] = "*";
|
|
1145
|
+
}
|
|
1146
|
+
deps["@nexusts/view"] = "*";
|
|
1147
|
+
if (view === "inertia") {
|
|
1148
|
+
if (frontend === "vue") {
|
|
1149
|
+
deps["@inertiajs/vue3"] = "^3.0.0";
|
|
1150
|
+
deps["vue"] = "^3.5.0";
|
|
1151
|
+
} else {
|
|
1152
|
+
deps["@inertiajs/react"] = "^3.0.0";
|
|
1153
|
+
deps["react"] = "^19.0.0";
|
|
1154
|
+
deps["react-dom"] = "^19.0.0";
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
return { deps, devDeps };
|
|
1158
|
+
}
|
|
1159
|
+
function buildPackageJson(name, deps, devDeps, view, frontend) {
|
|
1160
|
+
const scripts = {
|
|
1161
|
+
dev: "bun --hot app/main.ts",
|
|
1162
|
+
build: "bun run build.ts",
|
|
1163
|
+
start: "bun app/main.ts",
|
|
1164
|
+
test: "vitest",
|
|
1165
|
+
nx: "nx"
|
|
1166
|
+
};
|
|
1167
|
+
if (view === "inertia") {
|
|
1168
|
+
const ext = frontend === "vue" ? "ts" : "tsx";
|
|
1169
|
+
scripts["build:frontend"] = `bun build ./resources/js/app.${ext} --outdir=./public --target=browser --format=esm --minify`;
|
|
1170
|
+
scripts["dev"] = `bun run build:frontend && bun --hot app/main.ts`;
|
|
1171
|
+
}
|
|
1172
|
+
const pkg = {
|
|
1173
|
+
name,
|
|
1174
|
+
version: "0.1.0",
|
|
1175
|
+
type: "module",
|
|
1176
|
+
private: true,
|
|
1177
|
+
scripts,
|
|
1178
|
+
dependencies: deps
|
|
1179
|
+
};
|
|
1180
|
+
if (Object.keys(devDeps).length > 0) {
|
|
1181
|
+
pkg.devDependencies = devDeps;
|
|
1182
|
+
}
|
|
1183
|
+
return pkg;
|
|
1184
|
+
}
|
|
1185
|
+
function generateNxConfig(target, opts) {
|
|
1186
|
+
const code = render(templates.project["nx.config.ts"], {
|
|
1187
|
+
routing: opts.routing,
|
|
1188
|
+
view: opts.view,
|
|
1189
|
+
viewPaths: opts.view === "none" ? "" : "resources/views",
|
|
1190
|
+
orm: opts.orm,
|
|
1191
|
+
dbDriver: opts.db,
|
|
1192
|
+
dbUrl: opts.dbUrl,
|
|
1193
|
+
inertiaFrontend: opts.frontend,
|
|
1194
|
+
inertiaSSR: opts.ssr,
|
|
1195
|
+
inertiaVersion: "1.0.0"
|
|
1196
|
+
});
|
|
1197
|
+
writeFileSync2(resolve4(target, "nx.config.ts"), code);
|
|
1198
|
+
}
|
|
1199
|
+
function generateDrizzleConfig(target, db, dbUrl) {
|
|
1200
|
+
if (db !== "bun-sqlite" && db !== "node-sqlite" && db !== "libsql" && db !== "postgres" && db !== "mysql")
|
|
1201
|
+
return;
|
|
1202
|
+
const dialect = db === "bun-sqlite" || db === "node-sqlite" || db === "libsql" ? "sqlite" : db === "postgres" ? "postgresql" : "mysql";
|
|
1203
|
+
const code = render(templates.project["drizzle.config.ts"], {
|
|
1204
|
+
dialect,
|
|
1205
|
+
dbUrl: dbUrl || "app.db"
|
|
1206
|
+
});
|
|
1207
|
+
writeFileSync2(resolve4(target, "drizzle.config.ts"), code);
|
|
1208
|
+
}
|
|
1209
|
+
function generateEnvFile() {
|
|
1210
|
+
return [
|
|
1211
|
+
"# \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\u2500\u2500\u2500\u2500\u2500",
|
|
1212
|
+
"# NexusTS \u2014 Environment Variables (committed to git)",
|
|
1213
|
+
"#",
|
|
1214
|
+
"# Shared defaults for all environments. Override locally via",
|
|
1215
|
+
"# .env.local (gitignored) or by environment via .env.{NODE_ENV}",
|
|
1216
|
+
"# (e.g. .env.production, .env.development).",
|
|
1217
|
+
"# \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\u2500\u2500\u2500\u2500\u2500",
|
|
1218
|
+
"",
|
|
1219
|
+
"# \u2500\u2500 App \u2500\u2500",
|
|
1220
|
+
"NODE_ENV=development",
|
|
1221
|
+
"PORT=3000",
|
|
1222
|
+
"",
|
|
1223
|
+
"# \u2500\u2500 Session secret (REQUIRED) \u2500\u2500",
|
|
1224
|
+
"# Generate with: openssl rand -base64 32",
|
|
1225
|
+
"SESSION_SECRET=change-me-in-production",
|
|
1226
|
+
"",
|
|
1227
|
+
"# \u2500\u2500 Database: SQLite (default, zero config) \u2500\u2500",
|
|
1228
|
+
"DATABASE_URL=app.db",
|
|
1229
|
+
"",
|
|
1230
|
+
"# \u2500\u2500 Database: PostgreSQL \u2500\u2500",
|
|
1231
|
+
"# DATABASE_URL=postgres://user:password@localhost:5432/myapp",
|
|
1232
|
+
"",
|
|
1233
|
+
"# \u2500\u2500 Database: MySQL \u2500\u2500",
|
|
1234
|
+
"# DATABASE_URL=mysql://user:password@localhost:3306/myapp",
|
|
1235
|
+
"",
|
|
1236
|
+
"# \u2500\u2500 Better Auth (if using nexusjs/auth) \u2500\u2500",
|
|
1237
|
+
"# BETTER_AUTH_SECRET=",
|
|
1238
|
+
"# BETTER_AUTH_URL=http://localhost:3000"
|
|
1239
|
+
].join(`
|
|
1240
|
+
`) + `
|
|
1241
|
+
`;
|
|
1242
|
+
}
|
|
1243
|
+
function generateEnvLocalFile() {
|
|
1244
|
+
return [
|
|
1245
|
+
"# \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\u2500\u2500\u2500\u2500\u2500",
|
|
1246
|
+
"# NexusTS \u2014 Local Overrides (DO NOT COMMIT to git)",
|
|
1247
|
+
"#",
|
|
1248
|
+
"# This file is gitignored. Use it for secrets and local",
|
|
1249
|
+
"# configuration that should never be checked in.",
|
|
1250
|
+
"# \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\u2500\u2500\u2500\u2500\u2500",
|
|
1251
|
+
"",
|
|
1252
|
+
"# Override any value from .env here:",
|
|
1253
|
+
"# DATABASE_URL=postgres://user:password@localhost:5432/myapp",
|
|
1254
|
+
"# SESSION_SECRET=my-local-secret"
|
|
1255
|
+
].join(`
|
|
1256
|
+
`) + `
|
|
1257
|
+
`;
|
|
1258
|
+
}
|
|
1259
|
+
function generateGitIgnore() {
|
|
1260
|
+
return `# NexusTS
|
|
1261
|
+
node_modules/
|
|
1262
|
+
app.db
|
|
1263
|
+
*.db
|
|
1264
|
+
.env.local
|
|
1265
|
+
dist/
|
|
1266
|
+
`;
|
|
1267
|
+
}
|
|
1268
|
+
function generateProjectFiles(target, opts) {
|
|
1269
|
+
const created = [];
|
|
1270
|
+
const write = (path, content) => {
|
|
1271
|
+
writeFileSync2(resolve4(target, path), content);
|
|
1272
|
+
created.push(path);
|
|
1273
|
+
};
|
|
1274
|
+
generateNxConfig(target, opts);
|
|
1275
|
+
write("public/.gitkeep", "");
|
|
1276
|
+
if (opts.view === "inertia") {
|
|
1277
|
+
if (opts.frontend === "vue") {
|
|
1278
|
+
write("resources/js/Pages/Welcome.vue", `<template>
|
|
1279
|
+
<main style="font-family: system-ui, sans-serif; max-width: 560px; margin: 2em auto">
|
|
1280
|
+
<h1>Hello, {{ name }}!</h1>
|
|
1281
|
+
</main>
|
|
1282
|
+
</template>
|
|
1283
|
+
|
|
1284
|
+
<script setup lang="ts">
|
|
1285
|
+
defineProps<{ name: string }>();
|
|
1286
|
+
</script>
|
|
1287
|
+
`);
|
|
1288
|
+
write("resources/js/app.ts", `import { createInertiaApp } from "@inertiajs/vue3";
|
|
1289
|
+
import { createApp, h } from "vue";
|
|
1290
|
+
import Welcome from "./Pages/Welcome.vue";
|
|
1291
|
+
|
|
1292
|
+
createInertiaApp({
|
|
1293
|
+
resolve: (name: string) => {
|
|
1294
|
+
if (name === "Welcome") return Welcome;
|
|
1295
|
+
throw new Error("Unknown page: " + name);
|
|
1296
|
+
},
|
|
1297
|
+
setup({ el, App, props }: any) {
|
|
1298
|
+
createApp({ render: () => h(App, props) }).mount(el);
|
|
1299
|
+
},
|
|
1300
|
+
});
|
|
1301
|
+
`);
|
|
1302
|
+
} else {
|
|
1303
|
+
write("resources/js/Pages/Welcome.tsx", `import { useState } from "react";
|
|
1304
|
+
|
|
1305
|
+
export default function Welcome({ name }: { name: string }) {
|
|
1306
|
+
const [count, setCount] = useState(0);
|
|
1307
|
+
return (
|
|
1308
|
+
<main style={{ fontFamily: "system-ui, sans-serif", maxWidth: 560, margin: "2em auto" }}>
|
|
1309
|
+
<h1>Hello, {name}!</h1>
|
|
1310
|
+
<p>Counter: <strong>{count}</strong></p>
|
|
1311
|
+
<button onClick={() => setCount((c) => c + 1)} style={{ padding: "0.5em 1em" }}>
|
|
1312
|
+
+1
|
|
1313
|
+
</button>
|
|
1314
|
+
</main>
|
|
1315
|
+
);
|
|
1316
|
+
}
|
|
1317
|
+
`);
|
|
1318
|
+
write("resources/js/app.tsx", `import { createInertiaApp } from "@inertiajs/react";
|
|
1319
|
+
import { createRoot } from "react-dom/client";
|
|
1320
|
+
import Welcome from "./Pages/Welcome.js";
|
|
1321
|
+
|
|
1322
|
+
createInertiaApp({
|
|
1323
|
+
resolve: (name: string) => {
|
|
1324
|
+
if (name === "Welcome") return Welcome;
|
|
1325
|
+
throw new Error("Unknown page: " + name);
|
|
1326
|
+
},
|
|
1327
|
+
setup({ el, App, props }: any) {
|
|
1328
|
+
createRoot(el).render(<App {...props} />);
|
|
1329
|
+
},
|
|
1330
|
+
});
|
|
1331
|
+
`);
|
|
1332
|
+
}
|
|
1333
|
+
} else if (opts.view !== "none") {
|
|
1334
|
+
write("resources/views/welcome.html", `<h1>Welcome to ${opts.name}</h1>
|
|
1335
|
+
<p>This is a sample Rendu template.</p>
|
|
1336
|
+
<p>Founded <?= year ?>.</p>
|
|
1337
|
+
`);
|
|
1338
|
+
}
|
|
1339
|
+
write(".env", generateEnvFile());
|
|
1340
|
+
write(".env.local", generateEnvLocalFile());
|
|
1341
|
+
write(".gitignore", generateGitIgnore());
|
|
1342
|
+
{
|
|
1343
|
+
const hasView = opts.view !== "none";
|
|
1344
|
+
const staticMw = hasView ? `import { StaticModule } from '@nexusts/static';
|
|
1345
|
+
const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static' });
|
|
1346
|
+
` : "";
|
|
1347
|
+
const staticOpt = hasView ? `
|
|
1348
|
+
middleware: [staticMiddleware],` : "";
|
|
1349
|
+
write("app/main.ts", `import 'reflect-metadata';
|
|
1350
|
+
import { Application } from '@nexusts/core';
|
|
1351
|
+
${staticMw}import { AppModule } from './app.module.js';
|
|
1352
|
+
|
|
1353
|
+
const app = new Application(AppModule, {
|
|
1354
|
+
logging: true,
|
|
1355
|
+
port: Number(process.env['PORT'] ?? 3000),${staticOpt}
|
|
1356
|
+
});
|
|
1357
|
+
|
|
1358
|
+
await app.listen();
|
|
1359
|
+
console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
|
|
1360
|
+
`);
|
|
1361
|
+
}
|
|
1362
|
+
{
|
|
1363
|
+
const hasOrm = opts.orm === "drizzle";
|
|
1364
|
+
const ormImport = hasOrm ? `import { DrizzleModule } from '@nexusts/drizzle';
|
|
1365
|
+
` : "";
|
|
1366
|
+
const forRootDialect = opts.db === "bun-sqlite" ? "bun-sqlite" : "sqlite";
|
|
1367
|
+
const ormBlock = hasOrm ? ` DrizzleModule.forRoot({
|
|
1368
|
+
dialect: '${forRootDialect}',
|
|
1369
|
+
connection: { filename: '${opts.dbUrl || "app.db"}' },
|
|
1370
|
+
logging: true,
|
|
1371
|
+
})` : "";
|
|
1372
|
+
const isInertia = opts.view === "inertia";
|
|
1373
|
+
const inertiaImport = isInertia ? `import { Inertia } from '@nexusts/view';
|
|
1374
|
+
` : "";
|
|
1375
|
+
const inertiaProvider = isInertia ? ` providers: [{ provide: Inertia.TOKEN, useValue: new Inertia({ scripts: ['/static/app.js'] }) }],
|
|
1376
|
+
` : "";
|
|
1377
|
+
write("app/app.module.ts", `${ormImport}${inertiaImport}import { Module } from '@nexusts/core';
|
|
1378
|
+
import { HomeController } from './controllers/home.controller.js';
|
|
1379
|
+
|
|
1380
|
+
@Module({
|
|
1381
|
+
imports: [${hasOrm ? `
|
|
1382
|
+
${ormBlock},
|
|
1383
|
+
` : ""} ],
|
|
1384
|
+
${inertiaProvider} controllers: [HomeController],
|
|
1385
|
+
})
|
|
1386
|
+
export class AppModule {}
|
|
1387
|
+
`);
|
|
1388
|
+
}
|
|
1389
|
+
{
|
|
1390
|
+
if (opts.view === "inertia") {
|
|
1391
|
+
write("app/controllers/home.controller.ts", `import { Controller, Get, Inject } from '@nexusts/core';
|
|
1392
|
+
import { Inertia } from '@nexusts/view';
|
|
1393
|
+
|
|
1394
|
+
@Controller('/')
|
|
1395
|
+
export class HomeController {
|
|
1396
|
+
constructor(@Inject(Inertia.TOKEN) private inertia: Inertia) {}
|
|
1397
|
+
|
|
1398
|
+
@Get('/')
|
|
1399
|
+
index() {
|
|
1400
|
+
return this.inertia.render('Welcome', { name: 'NexusTS' });
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
`);
|
|
1404
|
+
} else if (opts.view !== "none") {
|
|
1405
|
+
write("app/controllers/home.controller.ts", `import { Controller, Get } from '@nexusts/core';
|
|
1406
|
+
|
|
1407
|
+
@Controller('/')
|
|
1408
|
+
export class HomeController {
|
|
1409
|
+
@Get('/')
|
|
1410
|
+
index() {
|
|
1411
|
+
return {
|
|
1412
|
+
view: 'welcome.html',
|
|
1413
|
+
data: { year: new Date().getFullYear() },
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
`);
|
|
1418
|
+
} else {
|
|
1419
|
+
write("app/controllers/home.controller.ts", `import { Controller, Get } from '@nexusts/core';
|
|
1420
|
+
|
|
1421
|
+
@Controller('/')
|
|
1422
|
+
export class HomeController {
|
|
1423
|
+
@Get('/')
|
|
1424
|
+
index() {
|
|
1425
|
+
return { status: 200, body: { message: 'Hello from NexusTS!' } };
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
`);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
if (opts.orm === "drizzle") {
|
|
1432
|
+
generateDrizzleConfig(target, opts.db, opts.dbUrl);
|
|
1433
|
+
}
|
|
1434
|
+
write("README.md", `# ${opts.name}
|
|
1435
|
+
|
|
1436
|
+
A NexusTS project.
|
|
1437
|
+
|
|
1438
|
+
## Run
|
|
1439
|
+
|
|
1440
|
+
\`\`\`bash
|
|
1441
|
+
bun install
|
|
1442
|
+
bun run dev
|
|
1443
|
+
\`\`\`
|
|
1444
|
+
|
|
1445
|
+
## Scaffolding
|
|
1446
|
+
|
|
1447
|
+
\`\`\`bash
|
|
1448
|
+
bunx nx make:crud Post
|
|
1449
|
+
\`\`\`
|
|
1450
|
+
`);
|
|
1451
|
+
return created;
|
|
1452
|
+
}
|
|
1453
|
+
// packages/cli/src/commands/info.ts
|
|
1454
|
+
var infoCommand = {
|
|
1455
|
+
name: "info",
|
|
1456
|
+
aliases: ["i"],
|
|
1457
|
+
summary: "Show project configuration",
|
|
1458
|
+
description: "Prints the resolved nx.config.ts plus relevant env vars.",
|
|
1459
|
+
async run(ctx) {
|
|
1460
|
+
logger.heading("NexusTS CLI \u2014 Project Info");
|
|
1461
|
+
logger.info(colors.bold("Resolved configuration"));
|
|
1462
|
+
logger.blank();
|
|
1463
|
+
logger.table([
|
|
1464
|
+
["routing", String(ctx.config.routing)],
|
|
1465
|
+
["view", String(ctx.config.view)],
|
|
1466
|
+
["orm", String(ctx.config.orm)],
|
|
1467
|
+
["dialect", String(ctx.config.dialect ?? "(none)")],
|
|
1468
|
+
["database.driver", String(ctx.config.database.driver)],
|
|
1469
|
+
["database.url", String(ctx.config.database.url)],
|
|
1470
|
+
["inertia.frontend", String(ctx.config.inertia.frontend)],
|
|
1471
|
+
["inertia.ssr", String(ctx.config.inertia.ssr)],
|
|
1472
|
+
["inertia.version", String(ctx.config.inertia.version)]
|
|
1473
|
+
]);
|
|
1474
|
+
logger.blank();
|
|
1475
|
+
logger.info(colors.bold("Paths"));
|
|
1476
|
+
logger.blank();
|
|
1477
|
+
for (const [k, v] of Object.entries(ctx.config.paths)) {
|
|
1478
|
+
logger.table([[k, v]]);
|
|
1479
|
+
}
|
|
1480
|
+
logger.blank();
|
|
1481
|
+
logger.info(colors.bold("Environment"));
|
|
1482
|
+
logger.blank();
|
|
1483
|
+
const envKeys = [
|
|
1484
|
+
"NODE_ENV",
|
|
1485
|
+
"PORT",
|
|
1486
|
+
"NEXUS_DEBUG",
|
|
1487
|
+
"NO_COLOR",
|
|
1488
|
+
"FORCE_COLOR",
|
|
1489
|
+
"NX_ROUTING",
|
|
1490
|
+
"NX_VIEW",
|
|
1491
|
+
"NX_ORM",
|
|
1492
|
+
"NX_DATABASE_DRIVER",
|
|
1493
|
+
"NX_DATABASE_URL",
|
|
1494
|
+
"NX_INERTIA_FRONTEND",
|
|
1495
|
+
"NX_INERTIA_SSR"
|
|
1496
|
+
];
|
|
1497
|
+
for (const k of envKeys) {
|
|
1498
|
+
const v = process.env[k];
|
|
1499
|
+
logger.table([[k, v === undefined ? colors.dim("(unset)") : v]]);
|
|
1500
|
+
}
|
|
1501
|
+
logger.blank();
|
|
1502
|
+
logger.info(colors.bold("Working directory"));
|
|
1503
|
+
logger.blank();
|
|
1504
|
+
logger.info(` ${resolve5(ctx.cwd)}`);
|
|
1505
|
+
logger.blank();
|
|
1506
|
+
return 0;
|
|
1507
|
+
}
|
|
1508
|
+
};
|
|
1509
|
+
var info_default = infoCommand;
|
|
1510
|
+
|
|
1167
1511
|
// packages/cli/src/commands/init.ts
|
|
1512
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
1513
|
+
import { resolve as resolve6 } from "path";
|
|
1514
|
+
var VALID_OPTIONS = {
|
|
1515
|
+
style: ["nest", "adonis", "functional"],
|
|
1516
|
+
view: ["rendu", "edge", "eta", "inertia", "none"],
|
|
1517
|
+
orm: ["drizzle", "prisma", "kysely", "none"],
|
|
1518
|
+
db: ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"],
|
|
1519
|
+
frontend: ["react", "vue", "svelte", "solid"]
|
|
1520
|
+
};
|
|
1521
|
+
async function resolveOpt(flags, key, valid, defaultVal, interactive) {
|
|
1522
|
+
const flagVal = flags[key];
|
|
1523
|
+
if (flagVal) {
|
|
1524
|
+
if (valid.includes(flagVal))
|
|
1525
|
+
return flagVal;
|
|
1526
|
+
if (!interactive) {
|
|
1527
|
+
logger.error(`Invalid --${key} "${flagVal}". Valid values: ${valid.join(", ")}`);
|
|
1528
|
+
process.exit(1);
|
|
1529
|
+
}
|
|
1530
|
+
logger.warn(`"${flagVal}" is not valid for --${key}. Please choose from the list.`);
|
|
1531
|
+
}
|
|
1532
|
+
const label = key === "style" ? "Routing style" : key === "view" ? "View engine" : key === "orm" ? "ORM driver" : key === "db" ? "Database driver" : "Inertia frontend";
|
|
1533
|
+
for (;; ) {
|
|
1534
|
+
const answer = await select(label, [...valid], { default: defaultVal });
|
|
1535
|
+
if (valid.includes(answer))
|
|
1536
|
+
return answer;
|
|
1537
|
+
logger.warn(`"${answer}" is not valid. Please choose from: ${valid.join(", ")}`);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1168
1540
|
var initCommand = {
|
|
1169
1541
|
name: "init",
|
|
1170
1542
|
aliases: ["i"],
|
|
1171
|
-
summary: "Initialize
|
|
1172
|
-
description: "
|
|
1543
|
+
summary: "Initialize NexusTS in an existing directory",
|
|
1544
|
+
description: "Scaffolds a new NexusTS project in the current or target directory. Non-destructive: skips existing files, merges package.json and tsconfig.json.",
|
|
1173
1545
|
examples: [
|
|
1174
1546
|
"nx init",
|
|
1175
|
-
"nx init ./my-
|
|
1547
|
+
"nx init ./my-app",
|
|
1176
1548
|
"nx init --style nest --view inertia --orm drizzle --db bun-sqlite",
|
|
1177
1549
|
"nx init --force"
|
|
1178
1550
|
],
|
|
1179
1551
|
flags: [
|
|
1180
1552
|
{ name: "target", description: "Target directory (default: cwd)" },
|
|
1181
|
-
{
|
|
1182
|
-
name: "style",
|
|
1183
|
-
description: "Routing style (nest|adonis|functional|mixed)"
|
|
1184
|
-
},
|
|
1553
|
+
{ name: "style", description: "Routing style (nest|adonis|functional)" },
|
|
1185
1554
|
{ name: "view", description: "View engine (rendu|edge|eta|inertia|none)" },
|
|
1186
1555
|
{ name: "orm", description: "ORM driver (drizzle|prisma|kysely|none)" },
|
|
1187
|
-
{
|
|
1188
|
-
name: "db",
|
|
1189
|
-
description: "Database driver (bun-sqlite|node-sqlite|libsql|postgres|mysql|none)"
|
|
1190
|
-
},
|
|
1556
|
+
{ name: "db", description: "Database driver (bun-sqlite|node-sqlite|libsql|postgres|mysql|none)" },
|
|
1191
1557
|
{
|
|
1192
1558
|
name: "frontend",
|
|
1193
1559
|
description: "Inertia frontend (react|vue|svelte|solid)"
|
|
1194
1560
|
},
|
|
1195
1561
|
{ name: "no-ssr", description: "Disable Inertia SSR" },
|
|
1196
|
-
{ name: "force", description: "Overwrite files
|
|
1197
|
-
{ name: "no-interaction", description: "
|
|
1562
|
+
{ name: "force", description: "Overwrite existing files" },
|
|
1563
|
+
{ name: "no-interaction", description: "Skip interactive prompts" }
|
|
1198
1564
|
],
|
|
1199
1565
|
async run(ctx) {
|
|
1200
|
-
const interactive =
|
|
1566
|
+
const interactive = flagBool(ctx.flags, "interaction", true);
|
|
1201
1567
|
const force = flagBool(ctx.flags, "force", false);
|
|
1202
|
-
const target =
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
const routing = ctx.flags["style"] ?? await select("Routing style", ["nest", "adonis", "functional"], {
|
|
1209
|
-
interactive,
|
|
1210
|
-
default: "nest"
|
|
1211
|
-
});
|
|
1212
|
-
const view = ctx.flags["view"] ?? await select("View engine", ["rendu", "edge", "eta", "inertia", "none"], {
|
|
1213
|
-
interactive,
|
|
1214
|
-
default: "rendu"
|
|
1215
|
-
});
|
|
1216
|
-
const orm = ctx.flags["orm"] ?? await select("ORM driver", ["drizzle", "prisma", "kysely", "none"], {
|
|
1217
|
-
interactive,
|
|
1218
|
-
default: "drizzle"
|
|
1219
|
-
});
|
|
1220
|
-
const db = ctx.flags["db"] ?? await select("Database driver", ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"], {
|
|
1221
|
-
interactive,
|
|
1222
|
-
default: "bun-sqlite"
|
|
1223
|
-
});
|
|
1224
|
-
const frontend = ctx.flags["frontend"] ?? await select("Inertia frontend", ["react", "vue", "svelte", "solid"], {
|
|
1225
|
-
interactive,
|
|
1226
|
-
default: "react"
|
|
1227
|
-
});
|
|
1568
|
+
const target = resolve6(ctx.cwd, ctx.flags["target"] ?? ".");
|
|
1569
|
+
const routing = await resolveOpt(ctx.flags, "style", VALID_OPTIONS.style, "nest", interactive);
|
|
1570
|
+
const view = await resolveOpt(ctx.flags, "view", VALID_OPTIONS.view, "rendu", interactive);
|
|
1571
|
+
const orm = await resolveOpt(ctx.flags, "orm", VALID_OPTIONS.orm, "drizzle", interactive);
|
|
1572
|
+
const db = await resolveOpt(ctx.flags, "db", VALID_OPTIONS.db, "bun-sqlite", interactive);
|
|
1573
|
+
const frontend = await resolveOpt(ctx.flags, "frontend", VALID_OPTIONS.frontend, "react", interactive);
|
|
1228
1574
|
const ssr = !flagBool(ctx.flags, "no-ssr", false);
|
|
1575
|
+
const name = target.split("/").pop() ?? "nexus-app";
|
|
1576
|
+
const dbUrl = db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "";
|
|
1229
1577
|
const plan = [
|
|
1230
|
-
{ path: "nx.config.ts", mode: "write" },
|
|
1231
1578
|
{ path: "package.json", mode: "merge-pkg" },
|
|
1232
1579
|
{ path: "tsconfig.json", mode: "merge-tsconfig" },
|
|
1233
|
-
{ path: "public/.gitkeep", mode: "write" },
|
|
1234
|
-
...view !== "none" ? [{ path: "resources/views/welcome.html", mode: "write" }] : [],
|
|
1235
1580
|
{ path: ".env", mode: "skip" },
|
|
1236
1581
|
{ path: ".env.local", mode: "skip" },
|
|
1237
1582
|
{ path: ".gitignore", mode: "skip" },
|
|
1238
|
-
|
|
1583
|
+
{ path: "nx.config.ts", mode: "write" },
|
|
1584
|
+
{ path: "public/.gitkeep", mode: "write" },
|
|
1239
1585
|
{ path: "app/main.ts", mode: "write" },
|
|
1240
1586
|
{ path: "app/app.module.ts", mode: "write" },
|
|
1241
1587
|
{ path: "app/controllers/home.controller.ts", mode: "write" },
|
|
1242
|
-
{ path: "README.md", mode: "write" }
|
|
1588
|
+
{ path: "README.md", mode: "write" },
|
|
1589
|
+
...view === "inertia" ? [
|
|
1590
|
+
{ path: `resources/js/Pages/Welcome.${frontend === "vue" ? "vue" : "tsx"}`, mode: "write" },
|
|
1591
|
+
{ path: `resources/js/app.${frontend === "vue" ? "ts" : "tsx"}`, mode: "write" }
|
|
1592
|
+
] : view !== "none" ? [{ path: "resources/views/welcome.html", mode: "write" }] : [],
|
|
1593
|
+
...orm === "drizzle" ? [{ path: "drizzle.config.ts", mode: "write" }] : []
|
|
1243
1594
|
];
|
|
1244
1595
|
const created = [];
|
|
1245
1596
|
const skipped = [];
|
|
1246
1597
|
const merged = [];
|
|
1247
|
-
|
|
1248
|
-
mkdirSync2(resolve5(target, "public"), { recursive: true });
|
|
1249
|
-
if (view !== "none") {
|
|
1250
|
-
mkdirSync2(resolve5(target, "resources/views"), { recursive: true });
|
|
1251
|
-
}
|
|
1598
|
+
ensureDirectories(target, view);
|
|
1252
1599
|
for (const entry of plan) {
|
|
1253
|
-
const abs =
|
|
1600
|
+
const abs = resolve6(target, entry.path);
|
|
1254
1601
|
const exists = existsSync4(abs);
|
|
1255
1602
|
if (entry.mode === "merge-pkg") {
|
|
1256
|
-
const
|
|
1257
|
-
"@nexusts/core": "*",
|
|
1258
|
-
"reflect-metadata": "^0.2.2",
|
|
1259
|
-
hono: "^4.6.0",
|
|
1260
|
-
zod: "^3.23.8"
|
|
1261
|
-
};
|
|
1262
|
-
const devDeps = {};
|
|
1263
|
-
if (orm === "drizzle") {
|
|
1264
|
-
coreDeps["@nexusts/drizzle"] = "*";
|
|
1265
|
-
coreDeps["drizzle-orm"] = "^0.45.0";
|
|
1266
|
-
if (db === "postgres")
|
|
1267
|
-
coreDeps["pg"] = "^8.13.0";
|
|
1268
|
-
if (db === "mysql")
|
|
1269
|
-
coreDeps["mysql2"] = "^3.11.0";
|
|
1270
|
-
if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
|
|
1271
|
-
coreDeps["better-sqlite3"] = "^12.0.0";
|
|
1272
|
-
devDeps["drizzle-kit"] = "^0.31.0";
|
|
1273
|
-
}
|
|
1274
|
-
if (view !== "none") {
|
|
1275
|
-
coreDeps["@nexusts/static"] = "*";
|
|
1276
|
-
}
|
|
1603
|
+
const { deps, devDeps } = computeDeps(view, orm, db, frontend);
|
|
1277
1604
|
if (exists) {
|
|
1278
|
-
mergePackageJson(abs,
|
|
1605
|
+
mergePackageJson(abs, deps, devDeps, view, frontend);
|
|
1279
1606
|
merged.push(entry.path);
|
|
1280
1607
|
} else {
|
|
1281
|
-
const pkgJson =
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
type: "module",
|
|
1285
|
-
private: true,
|
|
1286
|
-
scripts: {
|
|
1287
|
-
dev: "bun --hot app/main.ts",
|
|
1288
|
-
build: "bun run build.ts",
|
|
1289
|
-
start: "bun app/main.ts",
|
|
1290
|
-
test: "vitest",
|
|
1291
|
-
nx: "nx"
|
|
1292
|
-
},
|
|
1293
|
-
dependencies: coreDeps
|
|
1294
|
-
};
|
|
1295
|
-
if (orm === "drizzle") {
|
|
1296
|
-
pkgJson.devDependencies = {
|
|
1297
|
-
"drizzle-kit": "^0.31.0"
|
|
1298
|
-
};
|
|
1299
|
-
}
|
|
1300
|
-
writeFileSync2(abs, JSON.stringify(pkgJson, null, 2));
|
|
1608
|
+
const pkgJson = buildPackageJson(name, deps, devDeps, view, frontend);
|
|
1609
|
+
writeFileSync3(abs, JSON.stringify(pkgJson, null, 2) + `
|
|
1610
|
+
`);
|
|
1301
1611
|
created.push(entry.path);
|
|
1302
1612
|
}
|
|
1303
1613
|
continue;
|
|
@@ -1310,7 +1620,7 @@ var initCommand = {
|
|
|
1310
1620
|
});
|
|
1311
1621
|
merged.push(entry.path);
|
|
1312
1622
|
} else {
|
|
1313
|
-
|
|
1623
|
+
writeFileSync3(abs, defaultTsconfig());
|
|
1314
1624
|
created.push(entry.path);
|
|
1315
1625
|
}
|
|
1316
1626
|
continue;
|
|
@@ -1319,217 +1629,34 @@ var initCommand = {
|
|
|
1319
1629
|
skipped.push(entry.path);
|
|
1320
1630
|
continue;
|
|
1321
1631
|
}
|
|
1322
|
-
const content = renderContent(entry.path, {
|
|
1323
|
-
routing,
|
|
1324
|
-
view,
|
|
1325
|
-
viewPaths: view === "none" ? "" : "resources/views",
|
|
1326
|
-
orm,
|
|
1327
|
-
dbDriver: db,
|
|
1328
|
-
dbUrl: db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "",
|
|
1329
|
-
inertiaFrontend: frontend,
|
|
1330
|
-
inertiaSSR: ssr,
|
|
1331
|
-
inertiaVersion: "1.0.0",
|
|
1332
|
-
targetName: target.split("/").pop() ?? "nexus-app"
|
|
1333
|
-
});
|
|
1334
|
-
writeFileSync2(abs, content);
|
|
1335
1632
|
created.push(entry.path);
|
|
1336
1633
|
}
|
|
1634
|
+
const scaffoldOpts = { target, name, routing, view, orm, db, frontend, ssr, dbUrl };
|
|
1635
|
+
const scaffoldFiles = generateProjectFiles(target, scaffoldOpts);
|
|
1636
|
+
for (const f of scaffoldFiles) {
|
|
1637
|
+
if (!plan.some((p) => p.path === f)) {
|
|
1638
|
+
created.push(f);
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1337
1641
|
logger.success(`initialized NexusTS in ${target}`);
|
|
1338
1642
|
logger.blank();
|
|
1339
|
-
if (created.length)
|
|
1643
|
+
if (created.length)
|
|
1340
1644
|
logger.heading("Created");
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
if (merged.length) {
|
|
1645
|
+
for (const f of created)
|
|
1646
|
+
logger.info(` + ${f}`);
|
|
1647
|
+
if (merged.length)
|
|
1345
1648
|
logger.heading("Merged into existing files");
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
if (skipped.length) {
|
|
1649
|
+
for (const f of merged)
|
|
1650
|
+
logger.info(` ~ ${f}`);
|
|
1651
|
+
if (skipped.length)
|
|
1350
1652
|
logger.heading("Skipped (already exist; use --force to overwrite)");
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
}
|
|
1354
|
-
logger.blank();
|
|
1355
|
-
logger.heading("Next steps");
|
|
1356
|
-
logger.info(` cd ${target === ctx.cwd ? "." : target}`);
|
|
1357
|
-
logger.info(` bun install`);
|
|
1358
|
-
logger.info(` bun run dev`);
|
|
1653
|
+
for (const f of skipped)
|
|
1654
|
+
logger.info(` - ${f}`);
|
|
1359
1655
|
logger.blank();
|
|
1360
1656
|
return 0;
|
|
1361
1657
|
}
|
|
1362
1658
|
};
|
|
1363
|
-
function
|
|
1364
|
-
switch (path) {
|
|
1365
|
-
case "nx.config.ts":
|
|
1366
|
-
return render(templates.project["nx.config.ts"], ctx);
|
|
1367
|
-
case "public/.gitkeep":
|
|
1368
|
-
return "";
|
|
1369
|
-
case "resources/views/welcome.html":
|
|
1370
|
-
return `<h1>Welcome to ${ctx.targetName}</h1>
|
|
1371
|
-
<p>This is a sample Rendu template.</p>
|
|
1372
|
-
<p>Founded <?= year ?>.</p>
|
|
1373
|
-
`;
|
|
1374
|
-
case ".gitignore":
|
|
1375
|
-
return `# NexusTS
|
|
1376
|
-
node_modules/
|
|
1377
|
-
app.db
|
|
1378
|
-
*.db
|
|
1379
|
-
.env.local
|
|
1380
|
-
dist/
|
|
1381
|
-
`;
|
|
1382
|
-
case ".env":
|
|
1383
|
-
return `# \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\u2500\u2500\u2500\u2500\u2500
|
|
1384
|
-
# NexusTS \u2014 Environment Variables (committed to git)
|
|
1385
|
-
#
|
|
1386
|
-
# Shared defaults for all environments. Override locally via
|
|
1387
|
-
# .env.local (gitignored) or by environment via .env.{NODE_ENV}
|
|
1388
|
-
# (e.g. .env.production, .env.development).
|
|
1389
|
-
#
|
|
1390
|
-
# Uncomment the database config for your driver:
|
|
1391
|
-
# \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\u2500\u2500\u2500\u2500\u2500
|
|
1392
|
-
|
|
1393
|
-
# \u2500\u2500 App \u2500\u2500
|
|
1394
|
-
NODE_ENV=development
|
|
1395
|
-
PORT=3000
|
|
1396
|
-
|
|
1397
|
-
# \u2500\u2500 Session secret (REQUIRED) \u2500\u2500
|
|
1398
|
-
# Generate with: openssl rand -base64 32
|
|
1399
|
-
SESSION_SECRET=change-me-in-production
|
|
1400
|
-
|
|
1401
|
-
# \u2500\u2500 Database: SQLite (default, zero config) \u2500\u2500
|
|
1402
|
-
DATABASE_URL=app.db
|
|
1403
|
-
|
|
1404
|
-
# \u2500\u2500 Database: PostgreSQL \u2500\u2500
|
|
1405
|
-
# DATABASE_URL=postgres://user:password@localhost:5432/myapp
|
|
1406
|
-
|
|
1407
|
-
# \u2500\u2500 Database: MySQL \u2500\u2500
|
|
1408
|
-
# DATABASE_URL=mysql://user:password@localhost:3306/myapp
|
|
1409
|
-
|
|
1410
|
-
# \u2500\u2500 Better Auth (if using nexusjs/auth) \u2500\u2500
|
|
1411
|
-
# BETTER_AUTH_SECRET=
|
|
1412
|
-
# BETTER_AUTH_URL=http://localhost:3000
|
|
1413
|
-
`;
|
|
1414
|
-
case ".env.local":
|
|
1415
|
-
return `# \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\u2500\u2500\u2500\u2500\u2500
|
|
1416
|
-
# NexusTS \u2014 Local Overrides (DO NOT COMMIT to git)
|
|
1417
|
-
#
|
|
1418
|
-
# This file is gitignored. Use it for secrets and local
|
|
1419
|
-
# configuration that should never be checked in.
|
|
1420
|
-
# \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\u2500\u2500\u2500\u2500\u2500
|
|
1421
|
-
|
|
1422
|
-
# Override any value from .env here:
|
|
1423
|
-
# DATABASE_URL=postgres://user:password@localhost:5432/myapp
|
|
1424
|
-
# SESSION_SECRET=my-local-secret
|
|
1425
|
-
`;
|
|
1426
|
-
case "drizzle.config.ts": {
|
|
1427
|
-
const dialect = ctx.dbDriver === "bun-sqlite" || ctx.dbDriver === "node-sqlite" || ctx.dbDriver === "libsql" ? "sqlite" : ctx.dbDriver === "postgres" ? "postgresql" : "sqlite";
|
|
1428
|
-
return render(templates.project["drizzle.config.ts"], {
|
|
1429
|
-
dialect,
|
|
1430
|
-
dbUrl: ctx.dbUrl || "app.db"
|
|
1431
|
-
});
|
|
1432
|
-
}
|
|
1433
|
-
case "app/main.ts": {
|
|
1434
|
-
const hasView = ctx.view !== "none";
|
|
1435
|
-
const staticMw = hasView ? `import { StaticModule } from '@nexusts/static';
|
|
1436
|
-
` + `const staticMiddleware = StaticModule.mount({ root: './public', prefix: '/static' });
|
|
1437
|
-
` : "";
|
|
1438
|
-
const staticOpt = hasView ? `
|
|
1439
|
-
middleware: [staticMiddleware],` : "";
|
|
1440
|
-
return `import 'reflect-metadata';
|
|
1441
|
-
import { Application } from '@nexusts/core';
|
|
1442
|
-
${staticMw}import { AppModule } from './app.module.js';
|
|
1443
|
-
|
|
1444
|
-
const app = new Application(AppModule, {
|
|
1445
|
-
logging: true,
|
|
1446
|
-
port: Number(process.env['PORT'] ?? 3000),${staticOpt}
|
|
1447
|
-
});
|
|
1448
|
-
|
|
1449
|
-
await app.listen();
|
|
1450
|
-
console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
|
|
1451
|
-
`;
|
|
1452
|
-
}
|
|
1453
|
-
case "app/app.module.ts": {
|
|
1454
|
-
const hasOrm = ctx.orm === "drizzle";
|
|
1455
|
-
const ormImport = hasOrm ? `import { DrizzleModule } from '@nexusts/drizzle';
|
|
1456
|
-
` : "";
|
|
1457
|
-
const forRootDialect = ctx.dbDriver === "bun-sqlite" ? "bun-sqlite" : "sqlite";
|
|
1458
|
-
const forRootFile = ctx.dbUrl || "app.db";
|
|
1459
|
-
const ormBlock = hasOrm ? ` DrizzleModule.forRoot({
|
|
1460
|
-
dialect: '` + forRootDialect + `',
|
|
1461
|
-
connection: { filename: '` + forRootFile + `' },
|
|
1462
|
-
logging: true,
|
|
1463
|
-
})` : "";
|
|
1464
|
-
return `${ormImport}import { Module } from '@nexusts/core';
|
|
1465
|
-
import { HomeController } from './controllers/home.controller.js';
|
|
1466
|
-
|
|
1467
|
-
@Module({
|
|
1468
|
-
imports: [${hasOrm ? `
|
|
1469
|
-
${ormBlock},
|
|
1470
|
-
` : ""} ],
|
|
1471
|
-
controllers: [HomeController],
|
|
1472
|
-
})
|
|
1473
|
-
export class AppModule {}
|
|
1474
|
-
`;
|
|
1475
|
-
}
|
|
1476
|
-
case "app/controllers/home.controller.ts": {
|
|
1477
|
-
const hasView = ctx.view !== "none";
|
|
1478
|
-
const body = hasView ? `{
|
|
1479
|
-
view: 'welcome.html',
|
|
1480
|
-
data: { year: new Date().getFullYear() },
|
|
1481
|
-
}` : `{ status: 200, body: { message: 'Hello from NexusTS!' } }`;
|
|
1482
|
-
return `import { Controller, Get } from '@nexusts/core';
|
|
1483
|
-
|
|
1484
|
-
@Controller('/')
|
|
1485
|
-
export class HomeController {
|
|
1486
|
-
@Get('/')
|
|
1487
|
-
index() {
|
|
1488
|
-
return ${body};
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
`;
|
|
1492
|
-
}
|
|
1493
|
-
case "README.md":
|
|
1494
|
-
return `# ${ctx.targetName}
|
|
1495
|
-
|
|
1496
|
-
A NexusTS project.
|
|
1497
|
-
|
|
1498
|
-
## Run
|
|
1499
|
-
|
|
1500
|
-
\`\`\`bash
|
|
1501
|
-
bun install
|
|
1502
|
-
bun run dev
|
|
1503
|
-
\`\`\`
|
|
1504
|
-
|
|
1505
|
-
## Scaffolding
|
|
1506
|
-
|
|
1507
|
-
\`\`\`bash
|
|
1508
|
-
bunx nx make:crud Post
|
|
1509
|
-
\`\`\`
|
|
1510
|
-
`;
|
|
1511
|
-
default:
|
|
1512
|
-
throw new Error(`No render template for: ${path}`);
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
function defaultTsconfig() {
|
|
1516
|
-
return `{
|
|
1517
|
-
"compilerOptions": {
|
|
1518
|
-
"target": "ES2022",
|
|
1519
|
-
"module": "ESNext",
|
|
1520
|
-
"moduleResolution": "bundler",
|
|
1521
|
-
"experimentalDecorators": true,
|
|
1522
|
-
"emitDecoratorMetadata": true,
|
|
1523
|
-
"strict": true,
|
|
1524
|
-
"esModuleInterop": true,
|
|
1525
|
-
"skipLibCheck": true,
|
|
1526
|
-
"types": ["bun-types"]
|
|
1527
|
-
},
|
|
1528
|
-
"include": ["app/**/*.ts", "nx.config.ts"]
|
|
1529
|
-
}
|
|
1530
|
-
`;
|
|
1531
|
-
}
|
|
1532
|
-
function mergePackageJson(path, additions, devAdditions = {}) {
|
|
1659
|
+
function mergePackageJson(path, additions, devAdditions = {}, view, frontend) {
|
|
1533
1660
|
const raw = readFileSync4(path, "utf8");
|
|
1534
1661
|
const pkg = parseJsonLoose(raw);
|
|
1535
1662
|
let changed = false;
|
|
@@ -1548,6 +1675,11 @@ function mergePackageJson(path, additions, devAdditions = {}) {
|
|
|
1548
1675
|
test: "vitest",
|
|
1549
1676
|
nx: "nx"
|
|
1550
1677
|
};
|
|
1678
|
+
if (view === "inertia") {
|
|
1679
|
+
const ext = frontend === "vue" ? "ts" : "tsx";
|
|
1680
|
+
SCRIPTS["build:frontend"] = `bun build ./resources/js/app.${ext} --outdir=./public --target=browser --format=esm --minify`;
|
|
1681
|
+
SCRIPTS["dev"] = `bun run build:frontend && bun --hot app/main.ts`;
|
|
1682
|
+
}
|
|
1551
1683
|
const existingScripts = pkg["scripts"] ?? {};
|
|
1552
1684
|
for (const [k, v] of Object.entries(SCRIPTS)) {
|
|
1553
1685
|
if (!(k in existingScripts)) {
|
|
@@ -1555,9 +1687,8 @@ function mergePackageJson(path, additions, devAdditions = {}) {
|
|
|
1555
1687
|
changed = true;
|
|
1556
1688
|
}
|
|
1557
1689
|
}
|
|
1558
|
-
if (Object.keys(existingScripts).length > 0)
|
|
1690
|
+
if (Object.keys(existingScripts).length > 0)
|
|
1559
1691
|
pkg["scripts"] = existingScripts;
|
|
1560
|
-
}
|
|
1561
1692
|
const deps = pkg["dependencies"] ?? {};
|
|
1562
1693
|
for (const [k, v] of Object.entries(additions)) {
|
|
1563
1694
|
if (!(k in deps)) {
|
|
@@ -1576,10 +1707,9 @@ function mergePackageJson(path, additions, devAdditions = {}) {
|
|
|
1576
1707
|
}
|
|
1577
1708
|
pkg["devDependencies"] = devDeps;
|
|
1578
1709
|
}
|
|
1579
|
-
if (changed)
|
|
1580
|
-
|
|
1710
|
+
if (changed)
|
|
1711
|
+
writeFileSync3(path, JSON.stringify(pkg, null, 2) + `
|
|
1581
1712
|
`);
|
|
1582
|
-
}
|
|
1583
1713
|
}
|
|
1584
1714
|
function mergeTsconfig(path, additions) {
|
|
1585
1715
|
const raw = readFileSync4(path, "utf8");
|
|
@@ -1592,26 +1722,40 @@ function mergeTsconfig(path, additions) {
|
|
|
1592
1722
|
changed = true;
|
|
1593
1723
|
}
|
|
1594
1724
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
changed = true;
|
|
1725
|
+
cfg.compilerOptions = co;
|
|
1726
|
+
const include = cfg.include ?? [];
|
|
1727
|
+
for (const g of ["app/**/*.ts", "nx.config.ts"]) {
|
|
1728
|
+
if (!include.includes(g)) {
|
|
1729
|
+
include.push(g);
|
|
1730
|
+
changed = true;
|
|
1731
|
+
}
|
|
1603
1732
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
cfg
|
|
1607
|
-
writeFileSync2(path, JSON.stringify(cfg, null, 2) + `
|
|
1733
|
+
cfg.include = include;
|
|
1734
|
+
if (changed)
|
|
1735
|
+
writeFileSync3(path, JSON.stringify(cfg, null, 2) + `
|
|
1608
1736
|
`);
|
|
1609
|
-
|
|
1737
|
+
}
|
|
1738
|
+
function defaultTsconfig() {
|
|
1739
|
+
return `{
|
|
1740
|
+
"compilerOptions": {
|
|
1741
|
+
"target": "ES2022",
|
|
1742
|
+
"module": "ESNext",
|
|
1743
|
+
"moduleResolution": "bundler",
|
|
1744
|
+
"experimentalDecorators": true,
|
|
1745
|
+
"emitDecoratorMetadata": true,
|
|
1746
|
+
"strict": true,
|
|
1747
|
+
"esModuleInterop": true,
|
|
1748
|
+
"skipLibCheck": true,
|
|
1749
|
+
"types": ["@types/bun"]
|
|
1750
|
+
},
|
|
1751
|
+
"include": ["app/**/*.ts", "nx.config.ts"]
|
|
1752
|
+
}
|
|
1753
|
+
`;
|
|
1610
1754
|
}
|
|
1611
1755
|
var init_default = initCommand;
|
|
1612
1756
|
|
|
1613
1757
|
// packages/cli/src/commands/make-auth.ts
|
|
1614
|
-
import { resolve as
|
|
1758
|
+
import { resolve as resolve7 } from "path";
|
|
1615
1759
|
var AUTH_INSTANCE_TEMPLATE = `/**
|
|
1616
1760
|
* Better-auth instance \u2014 generated by \`nx make:auth\`.
|
|
1617
1761
|
*
|
|
@@ -1726,7 +1870,7 @@ var makeAuthCommand = {
|
|
|
1726
1870
|
passkeyRpId: rpId,
|
|
1727
1871
|
passkeyOrigin: Array.isArray(origin) ? origin.join(",") : origin
|
|
1728
1872
|
});
|
|
1729
|
-
const authOut =
|
|
1873
|
+
const authOut = resolve7(ctx.cwd, "app/auth/auth.ts");
|
|
1730
1874
|
if (writeFile(authOut, authCode)) {
|
|
1731
1875
|
logger.success(`created ${authOut}`);
|
|
1732
1876
|
} else {
|
|
@@ -1736,7 +1880,7 @@ var makeAuthCommand = {
|
|
|
1736
1880
|
providers: providers.length > 0,
|
|
1737
1881
|
entries
|
|
1738
1882
|
});
|
|
1739
|
-
const envOut =
|
|
1883
|
+
const envOut = resolve7(ctx.cwd, ".env.example");
|
|
1740
1884
|
if (writeFile(envOut, envCode, { skipIfExists: true })) {
|
|
1741
1885
|
logger.success(`created ${envOut}`);
|
|
1742
1886
|
} else {
|
|
@@ -1762,7 +1906,7 @@ var makeAuthCommand = {
|
|
|
1762
1906
|
var make_auth_default = makeAuthCommand;
|
|
1763
1907
|
|
|
1764
1908
|
// packages/cli/src/commands/make-controller.ts
|
|
1765
|
-
import { resolve as
|
|
1909
|
+
import { resolve as resolve8 } from "path";
|
|
1766
1910
|
var makeControllerCommand = {
|
|
1767
1911
|
name: "make:controller",
|
|
1768
1912
|
aliases: ["mc", "make-controller"],
|
|
@@ -1808,7 +1952,7 @@ var makeControllerCommand = {
|
|
|
1808
1952
|
service: serviceName,
|
|
1809
1953
|
serviceCamel
|
|
1810
1954
|
}).replace(/import .*\n/g, skipService ? (m) => m.includes("services/") ? "" : m : (m) => m);
|
|
1811
|
-
const out =
|
|
1955
|
+
const out = resolve8(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
|
|
1812
1956
|
const ok = writeFile(out, code, { skipIfExists: false });
|
|
1813
1957
|
if (!ok) {
|
|
1814
1958
|
logger.error(`Refusing to overwrite existing file: ${out}`);
|
|
@@ -1823,7 +1967,7 @@ var make_controller_default = makeControllerCommand;
|
|
|
1823
1967
|
|
|
1824
1968
|
// packages/cli/src/commands/make-crud.ts
|
|
1825
1969
|
import { mkdirSync as mkdirSync3 } from "fs";
|
|
1826
|
-
import { dirname as dirname3, resolve as
|
|
1970
|
+
import { dirname as dirname3, resolve as resolve9 } from "path";
|
|
1827
1971
|
|
|
1828
1972
|
// packages/cli/src/templates/model/drizzle-dialect.ts
|
|
1829
1973
|
function renderDrizzleDialect(dialect) {
|
|
@@ -1998,7 +2142,7 @@ var makeCrudCommand = {
|
|
|
1998
2142
|
viewShowComponent,
|
|
1999
2143
|
hasInertia
|
|
2000
2144
|
});
|
|
2001
|
-
const out =
|
|
2145
|
+
const out = resolve9(ctx.cwd, ctx.config.paths.controllers, `${variants.kebab}.controller.ts`);
|
|
2002
2146
|
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2003
2147
|
logger.warn(`skipped (exists): ${out}`);
|
|
2004
2148
|
} else {
|
|
@@ -2016,7 +2160,7 @@ var makeCrudCommand = {
|
|
|
2016
2160
|
repository,
|
|
2017
2161
|
repositoryCamel: variants.camel + "Repository"
|
|
2018
2162
|
});
|
|
2019
|
-
const out =
|
|
2163
|
+
const out = resolve9(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
|
|
2020
2164
|
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2021
2165
|
logger.warn(`skipped (exists): ${out}`);
|
|
2022
2166
|
} else {
|
|
@@ -2050,7 +2194,7 @@ var makeCrudCommand = {
|
|
|
2050
2194
|
prismaBlock: ""
|
|
2051
2195
|
});
|
|
2052
2196
|
}
|
|
2053
|
-
const out =
|
|
2197
|
+
const out = resolve9(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
|
|
2054
2198
|
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2055
2199
|
logger.warn(`skipped (exists): ${out}`);
|
|
2056
2200
|
} else {
|
|
@@ -2066,7 +2210,7 @@ var makeCrudCommand = {
|
|
|
2066
2210
|
tableName,
|
|
2067
2211
|
repository
|
|
2068
2212
|
});
|
|
2069
|
-
const repoOut =
|
|
2213
|
+
const repoOut = resolve9(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
|
|
2070
2214
|
mkdirSync3(dirname3(repoOut), { recursive: true });
|
|
2071
2215
|
if (!writeFile(repoOut, repoCode, { skipIfExists: true })) {
|
|
2072
2216
|
logger.warn(`skipped (exists): ${repoOut}`);
|
|
@@ -2081,7 +2225,7 @@ var makeCrudCommand = {
|
|
|
2081
2225
|
camel: variants.camel,
|
|
2082
2226
|
kebab: variants.kebab
|
|
2083
2227
|
});
|
|
2084
|
-
const out =
|
|
2228
|
+
const out = resolve9(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
|
|
2085
2229
|
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2086
2230
|
logger.warn(`skipped (exists): ${out}`);
|
|
2087
2231
|
} else {
|
|
@@ -2099,7 +2243,7 @@ var makeCrudCommand = {
|
|
|
2099
2243
|
repository,
|
|
2100
2244
|
hasRepo: !noRepo
|
|
2101
2245
|
});
|
|
2102
|
-
const out =
|
|
2246
|
+
const out = resolve9(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
|
|
2103
2247
|
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2104
2248
|
logger.warn(`skipped (exists): ${out}`);
|
|
2105
2249
|
} else {
|
|
@@ -2115,7 +2259,7 @@ var makeCrudCommand = {
|
|
|
2115
2259
|
controller,
|
|
2116
2260
|
service
|
|
2117
2261
|
});
|
|
2118
|
-
const out =
|
|
2262
|
+
const out = resolve9(ctx.cwd, "tests", `${variants.kebab}.test.ts`);
|
|
2119
2263
|
if (!writeFile(out, code, { skipIfExists: true })) {
|
|
2120
2264
|
logger.warn(`skipped (exists): ${out}`);
|
|
2121
2265
|
} else {
|
|
@@ -2151,7 +2295,7 @@ function renderDrizzleColumns(dialect) {
|
|
|
2151
2295
|
var make_crud_default = makeCrudCommand;
|
|
2152
2296
|
|
|
2153
2297
|
// packages/cli/src/commands/make-listener.ts
|
|
2154
|
-
import { resolve as
|
|
2298
|
+
import { resolve as resolve10 } from "path";
|
|
2155
2299
|
var LISTENER_TEMPLATE = `
|
|
2156
2300
|
import { Inject, Injectable } from '@nexusts/core';
|
|
2157
2301
|
import { EventService, OnEvent } from '@nexusts/events';
|
|
@@ -2202,7 +2346,7 @@ var makeListenerCommand = {
|
|
|
2202
2346
|
name: variants.pascal,
|
|
2203
2347
|
kebab: variants.kebab
|
|
2204
2348
|
});
|
|
2205
|
-
const out =
|
|
2349
|
+
const out = resolve10(ctx.cwd, "app/events/listeners", `${variants.kebab}.listener.ts`);
|
|
2206
2350
|
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2207
2351
|
logger.success(`created ${out}`);
|
|
2208
2352
|
} else {
|
|
@@ -2222,7 +2366,7 @@ var makeListenerCommand = {
|
|
|
2222
2366
|
var make_listener_default = makeListenerCommand;
|
|
2223
2367
|
|
|
2224
2368
|
// packages/cli/src/commands/make-middleware.ts
|
|
2225
|
-
import { resolve as
|
|
2369
|
+
import { resolve as resolve11 } from "path";
|
|
2226
2370
|
var makeMiddlewareCommand = {
|
|
2227
2371
|
name: "make:middleware",
|
|
2228
2372
|
aliases: ["mwm", "make-middleware"],
|
|
@@ -2239,7 +2383,7 @@ var makeMiddlewareCommand = {
|
|
|
2239
2383
|
const code = render(templates.middleware, {
|
|
2240
2384
|
name: variants.pascal
|
|
2241
2385
|
});
|
|
2242
|
-
const out =
|
|
2386
|
+
const out = resolve11(ctx.cwd, ctx.config.paths.middleware, `${variants.kebab}.middleware.ts`);
|
|
2243
2387
|
writeFile(out, code);
|
|
2244
2388
|
logger.success(`created ${out}`);
|
|
2245
2389
|
logger.finger(`register with: app.server.app.use('*', new ${variants.pascal}Middleware().handle)`);
|
|
@@ -2249,7 +2393,7 @@ var makeMiddlewareCommand = {
|
|
|
2249
2393
|
var make_middleware_default = makeMiddlewareCommand;
|
|
2250
2394
|
|
|
2251
2395
|
// packages/cli/src/commands/make-migration.ts
|
|
2252
|
-
import { resolve as
|
|
2396
|
+
import { resolve as resolve12 } from "path";
|
|
2253
2397
|
var makeMigrationCommand = {
|
|
2254
2398
|
name: "make:migration",
|
|
2255
2399
|
aliases: ["mkm", "make-migration"],
|
|
@@ -2321,7 +2465,7 @@ var makeMigrationCommand = {
|
|
|
2321
2465
|
return 1;
|
|
2322
2466
|
}
|
|
2323
2467
|
const filename = `${formatTimestamp(new Date)}_${variants.snake}.${extension}`;
|
|
2324
|
-
const out =
|
|
2468
|
+
const out = resolve12(ctx.cwd, ctx.config.paths.migrations, filename);
|
|
2325
2469
|
writeFile(out, code);
|
|
2326
2470
|
logger.success(`created ${out}`);
|
|
2327
2471
|
if (isDrizzle) {
|
|
@@ -2409,7 +2553,7 @@ function formatTimestamp(d) {
|
|
|
2409
2553
|
var make_migration_default = makeMigrationCommand;
|
|
2410
2554
|
|
|
2411
2555
|
// packages/cli/src/commands/make-model.ts
|
|
2412
|
-
import { resolve as
|
|
2556
|
+
import { resolve as resolve13 } from "path";
|
|
2413
2557
|
var makeModelCommand = {
|
|
2414
2558
|
name: "make:model",
|
|
2415
2559
|
aliases: ["mmodel", "make-model"],
|
|
@@ -2481,7 +2625,7 @@ var makeModelCommand = {
|
|
|
2481
2625
|
prismaBlock
|
|
2482
2626
|
});
|
|
2483
2627
|
}
|
|
2484
|
-
const out =
|
|
2628
|
+
const out = resolve13(ctx.cwd, ctx.config.paths.models, `${variants.kebab}.model.ts`);
|
|
2485
2629
|
writeFile(out, code);
|
|
2486
2630
|
logger.success(`created ${out}`);
|
|
2487
2631
|
logger.finger(`run \`nx make:migration create_${tableName}_table\` to scaffold a migration.`);
|
|
@@ -2540,7 +2684,7 @@ function capitalize(s) {
|
|
|
2540
2684
|
var make_model_default = makeModelCommand;
|
|
2541
2685
|
|
|
2542
2686
|
// packages/cli/src/commands/make-module.ts
|
|
2543
|
-
import { resolve as
|
|
2687
|
+
import { resolve as resolve14 } from "path";
|
|
2544
2688
|
var makeModuleCommand = {
|
|
2545
2689
|
name: "make:module",
|
|
2546
2690
|
aliases: ["mm", "make-module"],
|
|
@@ -2574,7 +2718,7 @@ var makeModuleCommand = {
|
|
|
2574
2718
|
hasService,
|
|
2575
2719
|
hasRepo
|
|
2576
2720
|
});
|
|
2577
|
-
const out =
|
|
2721
|
+
const out = resolve14(ctx.cwd, ctx.config.paths.modules, `${variants.kebab}.module.ts`);
|
|
2578
2722
|
writeFile(out, code);
|
|
2579
2723
|
logger.success(`created ${out}`);
|
|
2580
2724
|
logger.finger(`add ${variants.pascal}Module to AppModule.imports.`);
|
|
@@ -2584,7 +2728,7 @@ var makeModuleCommand = {
|
|
|
2584
2728
|
var make_module_default = makeModuleCommand;
|
|
2585
2729
|
|
|
2586
2730
|
// packages/cli/src/commands/make-queue.ts
|
|
2587
|
-
import { resolve as
|
|
2731
|
+
import { resolve as resolve15 } from "path";
|
|
2588
2732
|
var WORKER_TEMPLATE = `
|
|
2589
2733
|
import { Inject, Injectable } from '@nexusts/core';
|
|
2590
2734
|
import { QueueService, OnQueueReady } from '@nexusts/queue';
|
|
@@ -2712,7 +2856,7 @@ var makeQueueCommand = {
|
|
|
2712
2856
|
name: variants.pascal,
|
|
2713
2857
|
kebab: variants.kebab
|
|
2714
2858
|
});
|
|
2715
|
-
const out =
|
|
2859
|
+
const out = resolve15(ctx.cwd, "app/queue/workers", `${variants.kebab}.worker.ts`);
|
|
2716
2860
|
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2717
2861
|
logger.success(`created ${out}`);
|
|
2718
2862
|
} else {
|
|
@@ -2724,7 +2868,7 @@ var makeQueueCommand = {
|
|
|
2724
2868
|
name: variants.pascal,
|
|
2725
2869
|
kebab: variants.kebab
|
|
2726
2870
|
});
|
|
2727
|
-
const out =
|
|
2871
|
+
const out = resolve15(ctx.cwd, "app/queue/jobs", `${variants.kebab}.job.ts`);
|
|
2728
2872
|
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2729
2873
|
logger.success(`created ${out}`);
|
|
2730
2874
|
} else {
|
|
@@ -2748,7 +2892,7 @@ var make_queue_default = makeQueueCommand;
|
|
|
2748
2892
|
|
|
2749
2893
|
// packages/cli/src/commands/make-repository.ts
|
|
2750
2894
|
import { mkdirSync as mkdirSync4 } from "fs";
|
|
2751
|
-
import { resolve as
|
|
2895
|
+
import { resolve as resolve16, dirname as dirname4 } from "path";
|
|
2752
2896
|
var makeRepositoryCommand = {
|
|
2753
2897
|
name: "make:repository",
|
|
2754
2898
|
aliases: ["mr", "make-repository", "make:repo"],
|
|
@@ -2773,7 +2917,7 @@ var makeRepositoryCommand = {
|
|
|
2773
2917
|
snake: variants.snake,
|
|
2774
2918
|
repository
|
|
2775
2919
|
});
|
|
2776
|
-
const out =
|
|
2920
|
+
const out = resolve16(ctx.cwd, `${ctx.config.paths.app}/repositories`, `${variants.kebab}.repository.ts`);
|
|
2777
2921
|
mkdirSync4(dirname4(out), { recursive: true });
|
|
2778
2922
|
writeFile(out, code);
|
|
2779
2923
|
logger.success(`created ${out}`);
|
|
@@ -2783,7 +2927,7 @@ var makeRepositoryCommand = {
|
|
|
2783
2927
|
var make_repository_default = makeRepositoryCommand;
|
|
2784
2928
|
|
|
2785
2929
|
// packages/cli/src/commands/make-schedule.ts
|
|
2786
|
-
import { resolve as
|
|
2930
|
+
import { resolve as resolve17 } from "path";
|
|
2787
2931
|
var TASK_TEMPLATE = `
|
|
2788
2932
|
import { Injectable } from '@nexusts/core';
|
|
2789
2933
|
import { Cron, Interval, Timeout } from '@nexusts/schedule';
|
|
@@ -2827,7 +2971,7 @@ var makeScheduleCommand = {
|
|
|
2827
2971
|
name: variants.pascal,
|
|
2828
2972
|
kebab: variants.kebab
|
|
2829
2973
|
});
|
|
2830
|
-
const out =
|
|
2974
|
+
const out = resolve17(ctx.cwd, "app/schedule/tasks", `${variants.kebab}.task.ts`);
|
|
2831
2975
|
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2832
2976
|
logger.success(`created ${out}`);
|
|
2833
2977
|
} else {
|
|
@@ -2845,7 +2989,7 @@ var makeScheduleCommand = {
|
|
|
2845
2989
|
var make_schedule_default = makeScheduleCommand;
|
|
2846
2990
|
|
|
2847
2991
|
// packages/cli/src/commands/make-service.ts
|
|
2848
|
-
import { resolve as
|
|
2992
|
+
import { resolve as resolve18 } from "path";
|
|
2849
2993
|
var makeServiceCommand = {
|
|
2850
2994
|
name: "make:service",
|
|
2851
2995
|
aliases: ["ms", "make-service"],
|
|
@@ -2877,7 +3021,7 @@ var makeServiceCommand = {
|
|
|
2877
3021
|
repository,
|
|
2878
3022
|
repositoryCamel
|
|
2879
3023
|
});
|
|
2880
|
-
const out =
|
|
3024
|
+
const out = resolve18(ctx.cwd, ctx.config.paths.services, `${variants.kebab}.service.ts`);
|
|
2881
3025
|
writeFile(out, code);
|
|
2882
3026
|
logger.success(`created ${out}`);
|
|
2883
3027
|
return 0;
|
|
@@ -2886,7 +3030,7 @@ var makeServiceCommand = {
|
|
|
2886
3030
|
var make_service_default = makeServiceCommand;
|
|
2887
3031
|
|
|
2888
3032
|
// packages/cli/src/commands/make-session.ts
|
|
2889
|
-
import { resolve as
|
|
3033
|
+
import { resolve as resolve19 } from "path";
|
|
2890
3034
|
var SESSION_TEMPLATE = `
|
|
2891
3035
|
import { Inject, Injectable } from '@nexusts/core';
|
|
2892
3036
|
import { SessionService } from '@nexusts/session';
|
|
@@ -2948,7 +3092,7 @@ var makeSessionCommand = {
|
|
|
2948
3092
|
name: variants.pascal,
|
|
2949
3093
|
kebab: variants.kebab
|
|
2950
3094
|
});
|
|
2951
|
-
const out =
|
|
3095
|
+
const out = resolve19(ctx.cwd, "app/session/services", `${variants.kebab}.session.ts`);
|
|
2952
3096
|
if (writeFile(out, code, { skipIfExists: true })) {
|
|
2953
3097
|
logger.success(`created ${out}`);
|
|
2954
3098
|
} else {
|
|
@@ -2966,7 +3110,7 @@ var makeSessionCommand = {
|
|
|
2966
3110
|
var make_session_default = makeSessionCommand;
|
|
2967
3111
|
|
|
2968
3112
|
// packages/cli/src/commands/make-validator.ts
|
|
2969
|
-
import { resolve as
|
|
3113
|
+
import { resolve as resolve20 } from "path";
|
|
2970
3114
|
var makeValidatorCommand = {
|
|
2971
3115
|
name: "make:validator",
|
|
2972
3116
|
aliases: ["mv", "make-validator"],
|
|
@@ -2983,7 +3127,7 @@ var makeValidatorCommand = {
|
|
|
2983
3127
|
const code = render(templates.validator, {
|
|
2984
3128
|
name: variants.pascal
|
|
2985
3129
|
});
|
|
2986
|
-
const out =
|
|
3130
|
+
const out = resolve20(ctx.cwd, ctx.config.paths.dto, `${variants.kebab}.dto.ts`);
|
|
2987
3131
|
writeFile(out, code);
|
|
2988
3132
|
logger.success(`created ${out}`);
|
|
2989
3133
|
return 0;
|
|
@@ -2994,7 +3138,7 @@ var make_validator_default = makeValidatorCommand;
|
|
|
2994
3138
|
// packages/cli/src/commands/db-migrate.ts
|
|
2995
3139
|
import { spawn } from "child_process";
|
|
2996
3140
|
import { existsSync as existsSync5 } from "fs";
|
|
2997
|
-
import { resolve as
|
|
3141
|
+
import { resolve as resolve21 } from "path";
|
|
2998
3142
|
var dbMigrateCommand = {
|
|
2999
3143
|
name: "db:migrate",
|
|
3000
3144
|
aliases: ["db:m", "migrate"],
|
|
@@ -3029,9 +3173,9 @@ var dbMigrateCommand = {
|
|
|
3029
3173
|
}
|
|
3030
3174
|
],
|
|
3031
3175
|
async run(ctx) {
|
|
3032
|
-
const folder = ctx.flags["folder"] ??
|
|
3176
|
+
const folder = ctx.flags["folder"] ?? resolve21(ctx.cwd, ctx.config.paths.migrations);
|
|
3033
3177
|
const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
|
|
3034
|
-
const configPath = ctx.flags["config"] ??
|
|
3178
|
+
const configPath = ctx.flags["config"] ?? resolve21(ctx.cwd, "drizzle.config.ts");
|
|
3035
3179
|
const wantStatus = Boolean(ctx.flags["status"]);
|
|
3036
3180
|
const generateName = ctx.flags["generate"];
|
|
3037
3181
|
if (generateName) {
|
|
@@ -3092,7 +3236,7 @@ const applied = await svc.appliedMigrations();
|
|
|
3092
3236
|
console.log(JSON.stringify({ total: applied.length, applied }, null, 2));
|
|
3093
3237
|
await svc.close();
|
|
3094
3238
|
`;
|
|
3095
|
-
const tmpFile =
|
|
3239
|
+
const tmpFile = resolve21(cwd, ".nx-migrate-status.mjs");
|
|
3096
3240
|
await import("fs/promises").then((m) => m.writeFile(tmpFile, script, "utf-8"));
|
|
3097
3241
|
try {
|
|
3098
3242
|
const code = await new Promise((resP) => {
|
|
@@ -3116,7 +3260,7 @@ function readEnvUrl(dialect) {
|
|
|
3116
3260
|
var db_migrate_default = dbMigrateCommand;
|
|
3117
3261
|
|
|
3118
3262
|
// packages/cli/src/commands/db-generate.ts
|
|
3119
|
-
import { resolve as
|
|
3263
|
+
import { resolve as resolve22 } from "path";
|
|
3120
3264
|
var dbGenerateCommand = {
|
|
3121
3265
|
name: "db:generate",
|
|
3122
3266
|
aliases: ["db:g", "db-generate", "generate-migration"],
|
|
@@ -3149,7 +3293,7 @@ var dbGenerateCommand = {
|
|
|
3149
3293
|
logger.info(`Generating raw SQL migration: ${name} (dialect=${dialect})`);
|
|
3150
3294
|
return runSqlTemplate(ctx.cwd, name, dialect);
|
|
3151
3295
|
}
|
|
3152
|
-
const configPath =
|
|
3296
|
+
const configPath = resolve22(ctx.cwd, "drizzle.config.ts");
|
|
3153
3297
|
const args2 = ["generate", "--config", configPath];
|
|
3154
3298
|
if (name)
|
|
3155
3299
|
args2.push("--name", name);
|
|
@@ -3158,7 +3302,7 @@ var dbGenerateCommand = {
|
|
|
3158
3302
|
}
|
|
3159
3303
|
};
|
|
3160
3304
|
async function runSqlTemplate(cwd, name, dialect) {
|
|
3161
|
-
const { mkdirSync: mkdirSync5, writeFileSync:
|
|
3305
|
+
const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync4 } = await import("fs");
|
|
3162
3306
|
const { join } = await import("path");
|
|
3163
3307
|
const migrationsDir = join(cwd, "app", "database", "migrations");
|
|
3164
3308
|
mkdirSync5(migrationsDir, { recursive: true });
|
|
@@ -3174,7 +3318,7 @@ async function runSqlTemplate(cwd, name, dialect) {
|
|
|
3174
3318
|
-- Generated: ${new Date().toISOString()}
|
|
3175
3319
|
|
|
3176
3320
|
`;
|
|
3177
|
-
|
|
3321
|
+
writeFileSync4(filepath, header);
|
|
3178
3322
|
logger.success(`created ${filepath}`);
|
|
3179
3323
|
logger.info("Edit the SQL file, then run `nx db:migrate` to apply it.");
|
|
3180
3324
|
return 0;
|
|
@@ -3185,7 +3329,7 @@ var db_generate_default = dbGenerateCommand;
|
|
|
3185
3329
|
import { spawn as spawn2 } from "child_process";
|
|
3186
3330
|
import { existsSync as existsSync6 } from "fs";
|
|
3187
3331
|
import { mkdir, readdir, writeFile as writeFile2, unlink } from "fs/promises";
|
|
3188
|
-
import { resolve as
|
|
3332
|
+
import { resolve as resolve23 } from "path";
|
|
3189
3333
|
var SEED_TEMPLATE = `/**
|
|
3190
3334
|
* Seed: {name}
|
|
3191
3335
|
*
|
|
@@ -3255,7 +3399,7 @@ var dbSeedCommand = {
|
|
|
3255
3399
|
}
|
|
3256
3400
|
],
|
|
3257
3401
|
async run(ctx) {
|
|
3258
|
-
const folder =
|
|
3402
|
+
const folder = resolve23(ctx.cwd, ctx.flags["folder"] ?? ctx.config.paths?.seeds ?? "db/seeds");
|
|
3259
3403
|
const dialect = ctx.flags["dialect"] ?? ctx.config.dialect ?? "bun-sqlite";
|
|
3260
3404
|
const createName = ctx.flags["create"];
|
|
3261
3405
|
const fileName = ctx.flags["file"];
|
|
@@ -3266,7 +3410,7 @@ var dbSeedCommand = {
|
|
|
3266
3410
|
if (!existsSync6(folder)) {
|
|
3267
3411
|
logger.info(`creating empty seeds folder at ${folder}`);
|
|
3268
3412
|
await mkdir(folder, { recursive: true });
|
|
3269
|
-
await writeFile2(
|
|
3413
|
+
await writeFile2(resolve23(folder, "_README.ts"), `// Seed files go here. Run with: nx db:seed
|
|
3270
3414
|
`, "utf-8");
|
|
3271
3415
|
return 0;
|
|
3272
3416
|
}
|
|
@@ -3290,7 +3434,7 @@ var dbSeedCommand = {
|
|
|
3290
3434
|
if (reset) {
|
|
3291
3435
|
logger.warn("--reset is set: truncating every table in the schema before running seeds.");
|
|
3292
3436
|
}
|
|
3293
|
-
const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(
|
|
3437
|
+
const seedImports = target.map((f, i) => `import seed_${i} from ${JSON.stringify(resolve23(folder, f))};`).join(`
|
|
3294
3438
|
`);
|
|
3295
3439
|
const seedCalls = target.map((_, i) => ` await seed_${i}({ db, logger, dialect, truncate: (t) => db.truncate(t) });`).join(`
|
|
3296
3440
|
`);
|
|
@@ -3324,7 +3468,7 @@ ${seedCalls}
|
|
|
3324
3468
|
await db.close();
|
|
3325
3469
|
logger.info(\`Seeds complete (\${${target.length}} file(s))\`);
|
|
3326
3470
|
`;
|
|
3327
|
-
const tmpFile =
|
|
3471
|
+
const tmpFile = resolve23(ctx.cwd, ".nx-db-seed.mjs");
|
|
3328
3472
|
await writeFile2(tmpFile, script, "utf-8");
|
|
3329
3473
|
try {
|
|
3330
3474
|
const code = await new Promise((resP) => {
|
|
@@ -3366,11 +3510,11 @@ async function createSeedFile(folder, name) {
|
|
|
3366
3510
|
await mkdir(folder, { recursive: true });
|
|
3367
3511
|
let candidate = `${name}.ts`;
|
|
3368
3512
|
let i = 1;
|
|
3369
|
-
while (existsSync6(
|
|
3513
|
+
while (existsSync6(resolve23(folder, candidate))) {
|
|
3370
3514
|
candidate = `${name}_${i}.ts`;
|
|
3371
3515
|
i++;
|
|
3372
3516
|
}
|
|
3373
|
-
const path =
|
|
3517
|
+
const path = resolve23(folder, candidate);
|
|
3374
3518
|
const body = SEED_TEMPLATE.replace(/\{name\}/g, name);
|
|
3375
3519
|
await writeFile2(path, body, "utf-8");
|
|
3376
3520
|
logger.info(`created ${path}`);
|
|
@@ -3383,8 +3527,34 @@ function readEnvUrl2(dialect) {
|
|
|
3383
3527
|
var db_seed_default = dbSeedCommand;
|
|
3384
3528
|
|
|
3385
3529
|
// packages/cli/src/commands/new.ts
|
|
3386
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as
|
|
3387
|
-
import { resolve as
|
|
3530
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
3531
|
+
import { resolve as resolve24 } from "path";
|
|
3532
|
+
var VALID_OPTIONS2 = {
|
|
3533
|
+
style: ["nest", "adonis", "functional"],
|
|
3534
|
+
view: ["rendu", "edge", "eta", "inertia", "none"],
|
|
3535
|
+
orm: ["drizzle", "prisma", "kysely", "none"],
|
|
3536
|
+
db: ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"],
|
|
3537
|
+
frontend: ["react", "vue", "svelte", "solid"]
|
|
3538
|
+
};
|
|
3539
|
+
async function resolveOpt2(flags, key, valid, defaultVal, interactive) {
|
|
3540
|
+
const flagVal = flags[key];
|
|
3541
|
+
if (flagVal) {
|
|
3542
|
+
if (valid.includes(flagVal))
|
|
3543
|
+
return flagVal;
|
|
3544
|
+
if (!interactive) {
|
|
3545
|
+
logger.error(`Invalid --${key} "${flagVal}". Valid values: ${valid.join(", ")}`);
|
|
3546
|
+
process.exit(1);
|
|
3547
|
+
}
|
|
3548
|
+
logger.warn(`"${flagVal}" is not valid for --${key}. Please choose from the list.`);
|
|
3549
|
+
}
|
|
3550
|
+
const label = key === "style" ? "Routing style" : key === "view" ? "View engine" : key === "orm" ? "ORM driver" : key === "db" ? "Database driver" : "Inertia frontend";
|
|
3551
|
+
for (;; ) {
|
|
3552
|
+
const answer = await select(label, [...valid], { default: defaultVal });
|
|
3553
|
+
if (valid.includes(answer))
|
|
3554
|
+
return answer;
|
|
3555
|
+
logger.warn(`"${answer}" is not valid. Please choose from: ${valid.join(", ")}`);
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3388
3558
|
var newCommand = {
|
|
3389
3559
|
name: "new",
|
|
3390
3560
|
aliases: ["n"],
|
|
@@ -3392,131 +3562,38 @@ var newCommand = {
|
|
|
3392
3562
|
description: "Generates a new project directory with nx.config.ts, tsconfig, package.json, and a starter app/main.ts.",
|
|
3393
3563
|
examples: [
|
|
3394
3564
|
"nx new my-app",
|
|
3395
|
-
"nx new my-app --
|
|
3565
|
+
"nx new my-app --view inertia --frontend vue"
|
|
3396
3566
|
],
|
|
3397
3567
|
flags: [
|
|
3398
|
-
{
|
|
3399
|
-
name: "style",
|
|
3400
|
-
description: "Routing style (nest|adonis|functional|mixed)"
|
|
3401
|
-
},
|
|
3568
|
+
{ name: "style", description: "Routing style (nest|adonis|functional)" },
|
|
3402
3569
|
{ name: "view", description: "View engine (rendu|edge|eta|inertia|none)" },
|
|
3403
3570
|
{ name: "orm", description: "ORM driver (drizzle|prisma|kysely|none)" },
|
|
3404
|
-
{
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
},
|
|
3408
|
-
{
|
|
3409
|
-
name: "frontend",
|
|
3410
|
-
description: "Inertia frontend (react|vue|svelte|solid)"
|
|
3411
|
-
},
|
|
3412
|
-
{ name: "no-ssr", description: "Disable Inertia SSR" },
|
|
3413
|
-
{ name: "no-interaction", description: "Disable interactive prompts" }
|
|
3571
|
+
{ name: "db", description: "Database driver" },
|
|
3572
|
+
{ name: "frontend", description: "Inertia frontend (react|vue|svelte|solid)" },
|
|
3573
|
+
{ name: "no-ssr", description: "Disable SSR" }
|
|
3414
3574
|
],
|
|
3415
3575
|
async run(ctx) {
|
|
3416
3576
|
const name = ctx.positional[0];
|
|
3417
3577
|
if (!name) {
|
|
3418
|
-
logger.error("Usage: nx new <
|
|
3578
|
+
logger.error("Usage: nx new <name>");
|
|
3419
3579
|
return 1;
|
|
3420
3580
|
}
|
|
3421
|
-
const interactive =
|
|
3422
|
-
const target =
|
|
3581
|
+
const interactive = flagBool(ctx.flags, "interaction", true);
|
|
3582
|
+
const target = resolve24(ctx.cwd, name);
|
|
3423
3583
|
if (existsSync7(target)) {
|
|
3424
|
-
logger.error(`Directory already exists
|
|
3584
|
+
logger.error(`Directory "${name}" already exists.`);
|
|
3425
3585
|
return 1;
|
|
3426
3586
|
}
|
|
3427
|
-
const routing = ctx.flags
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
const
|
|
3432
|
-
interactive,
|
|
3433
|
-
default: "rendu"
|
|
3434
|
-
});
|
|
3435
|
-
const orm = ctx.flags["orm"] ?? await select("ORM driver", ["drizzle", "prisma", "kysely", "none"], {
|
|
3436
|
-
interactive,
|
|
3437
|
-
default: "drizzle"
|
|
3438
|
-
});
|
|
3439
|
-
const db = ctx.flags["db"] ?? await select("Database driver", ["bun-sqlite", "node-sqlite", "libsql", "postgres", "mysql", "none"], {
|
|
3440
|
-
interactive,
|
|
3441
|
-
default: "bun-sqlite"
|
|
3442
|
-
});
|
|
3443
|
-
const frontend = ctx.flags["frontend"] ?? await select("Inertia frontend", ["react", "vue", "svelte", "solid"], {
|
|
3444
|
-
interactive,
|
|
3445
|
-
default: "react"
|
|
3446
|
-
});
|
|
3587
|
+
const routing = await resolveOpt2(ctx.flags, "style", VALID_OPTIONS2.style, "nest", interactive);
|
|
3588
|
+
const view = await resolveOpt2(ctx.flags, "view", VALID_OPTIONS2.view, "rendu", interactive);
|
|
3589
|
+
const orm = await resolveOpt2(ctx.flags, "orm", VALID_OPTIONS2.orm, "drizzle", interactive);
|
|
3590
|
+
const db = await resolveOpt2(ctx.flags, "db", VALID_OPTIONS2.db, "bun-sqlite", interactive);
|
|
3591
|
+
const frontend = await resolveOpt2(ctx.flags, "frontend", VALID_OPTIONS2.frontend, "react", interactive);
|
|
3447
3592
|
const ssr = !flagBool(ctx.flags, "no-ssr", false);
|
|
3448
|
-
mkdirSync5(
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
mkdirSync5(resolve23(target, "public"), { recursive: true });
|
|
3453
|
-
writeFileSync3(resolve23(target, "public/.gitkeep"), "");
|
|
3454
|
-
if (view !== "none") {
|
|
3455
|
-
writeFileSync3(resolve23(target, "resources/views/welcome.html"), `<h1>Welcome to ${name}</h1>
|
|
3456
|
-
<p>This is a sample Rendu template.</p>
|
|
3457
|
-
<p>Founded <?= year ?>.</p>
|
|
3458
|
-
`);
|
|
3459
|
-
}
|
|
3460
|
-
writeFileSync3(resolve23(target, ".env"), generateEnvFile());
|
|
3461
|
-
writeFileSync3(resolve23(target, ".env.local"), generateEnvLocalFile());
|
|
3462
|
-
writeFileSync3(resolve23(target, ".gitignore"), generateGitIgnore());
|
|
3463
|
-
const code = render(templates.project["nx.config.ts"], {
|
|
3464
|
-
routing,
|
|
3465
|
-
view,
|
|
3466
|
-
viewPaths: view === "none" ? "" : "resources/views",
|
|
3467
|
-
orm,
|
|
3468
|
-
dbDriver: db,
|
|
3469
|
-
dbUrl: db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "",
|
|
3470
|
-
inertiaFrontend: frontend,
|
|
3471
|
-
inertiaSSR: ssr,
|
|
3472
|
-
inertiaVersion: "1.0.0"
|
|
3473
|
-
});
|
|
3474
|
-
writeFileSync3(resolve23(target, "nx.config.ts"), code);
|
|
3475
|
-
if (orm === "drizzle") {
|
|
3476
|
-
const dialect = db === "bun-sqlite" || db === "node-sqlite" || db === "libsql" ? "sqlite" : db === "postgres" ? "postgresql" : "sqlite";
|
|
3477
|
-
const drizzleConfig = render(templates.project["drizzle.config.ts"], {
|
|
3478
|
-
dialect,
|
|
3479
|
-
dbUrl: db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : ""
|
|
3480
|
-
});
|
|
3481
|
-
writeFileSync3(resolve23(target, "drizzle.config.ts"), drizzleConfig);
|
|
3482
|
-
}
|
|
3483
|
-
const deps = {
|
|
3484
|
-
"@nexusts/core": "*",
|
|
3485
|
-
"reflect-metadata": "^0.2.2",
|
|
3486
|
-
hono: "^4.6.0",
|
|
3487
|
-
zod: "^3.23.8"
|
|
3488
|
-
};
|
|
3489
|
-
if (orm === "drizzle") {
|
|
3490
|
-
deps["@nexusts/drizzle"] = "*";
|
|
3491
|
-
deps["drizzle-orm"] = "^0.45.0";
|
|
3492
|
-
if (db === "postgres")
|
|
3493
|
-
deps["pg"] = "^8.13.0";
|
|
3494
|
-
if (db === "mysql")
|
|
3495
|
-
deps["mysql2"] = "^3.11.0";
|
|
3496
|
-
if (db === "sqlite" || db === "node-sqlite" || db === "bun-sqlite")
|
|
3497
|
-
deps["better-sqlite3"] = "^12.0.0";
|
|
3498
|
-
}
|
|
3499
|
-
if (view !== "none") {
|
|
3500
|
-
deps["@nexusts/static"] = "*";
|
|
3501
|
-
}
|
|
3502
|
-
const pkgJson = {
|
|
3503
|
-
name,
|
|
3504
|
-
version: "0.1.0",
|
|
3505
|
-
type: "module",
|
|
3506
|
-
scripts: {
|
|
3507
|
-
dev: "bun --hot app/main.ts",
|
|
3508
|
-
build: "bun run build.ts",
|
|
3509
|
-
start: "bun app/main.ts",
|
|
3510
|
-
test: "vitest",
|
|
3511
|
-
nx: "nx"
|
|
3512
|
-
},
|
|
3513
|
-
dependencies: deps
|
|
3514
|
-
};
|
|
3515
|
-
if (orm === "drizzle") {
|
|
3516
|
-
pkgJson.devDependencies = { "drizzle-kit": "^0.31.0" };
|
|
3517
|
-
}
|
|
3518
|
-
writeFileSync3(resolve23(target, "package.json"), JSON.stringify(pkgJson, null, 2));
|
|
3519
|
-
writeFileSync3(resolve23(target, "tsconfig.json"), `{
|
|
3593
|
+
mkdirSync5(target, { recursive: true });
|
|
3594
|
+
const dbUrl = db === "bun-sqlite" || db === "node-sqlite" ? "app.db" : "";
|
|
3595
|
+
ensureDirectories(target, view);
|
|
3596
|
+
writeFileSync4(resolve24(target, "tsconfig.json"), `{
|
|
3520
3597
|
"compilerOptions": {
|
|
3521
3598
|
"target": "ES2022",
|
|
3522
3599
|
"module": "ESNext",
|
|
@@ -3526,81 +3603,22 @@ var newCommand = {
|
|
|
3526
3603
|
"strict": true,
|
|
3527
3604
|
"esModuleInterop": true,
|
|
3528
3605
|
"skipLibCheck": true,
|
|
3529
|
-
"types": ["bun
|
|
3606
|
+
"types": ["@types/bun"]
|
|
3530
3607
|
},
|
|
3531
3608
|
"include": ["app/**/*.ts", "nx.config.ts"]
|
|
3532
3609
|
}
|
|
3533
3610
|
`);
|
|
3534
|
-
const
|
|
3535
|
-
const
|
|
3536
|
-
|
|
3537
|
-
` : "";
|
|
3538
|
-
const staticOption = hasView ? `
|
|
3539
|
-
middleware: [staticMiddleware],` : "";
|
|
3540
|
-
writeFileSync3(resolve23(target, "app/main.ts"), `import 'reflect-metadata';
|
|
3541
|
-
import { Application } from '@nexusts/core';
|
|
3542
|
-
${staticImport}import { AppModule } from './app.module.js';
|
|
3543
|
-
|
|
3544
|
-
const app = new Application(AppModule, {
|
|
3545
|
-
logging: true,
|
|
3546
|
-
port: Number(process.env['PORT'] ?? 3000),${staticOption}
|
|
3547
|
-
});
|
|
3548
|
-
|
|
3549
|
-
await app.listen();
|
|
3550
|
-
console.log('[nexus] Listening on http://localhost:' + (process.env['PORT'] ?? 3000));
|
|
3551
|
-
`);
|
|
3552
|
-
const ormImport = orm === "drizzle" ? `import { DrizzleModule } from '@nexusts/drizzle';
|
|
3553
|
-
` : "";
|
|
3554
|
-
const forRootDialect = db === "bun-sqlite" ? "bun-sqlite" : "sqlite";
|
|
3555
|
-
const ormBlock = orm === "drizzle" ? ` DrizzleModule.forRoot({
|
|
3556
|
-
dialect: '${forRootDialect}',
|
|
3557
|
-
connection: { filename: 'app.db' },
|
|
3558
|
-
logging: true,
|
|
3559
|
-
})` : "";
|
|
3560
|
-
writeFileSync3(resolve23(target, "app/app.module.ts"), `${ormImport}import { Module } from '@nexusts/core';
|
|
3561
|
-
import { HomeController } from './controllers/home.controller.js';
|
|
3562
|
-
|
|
3563
|
-
@Module({
|
|
3564
|
-
imports: [${orm === "drizzle" ? `
|
|
3565
|
-
${ormBlock},
|
|
3566
|
-
` : ""} ],
|
|
3567
|
-
controllers: [HomeController],
|
|
3568
|
-
})
|
|
3569
|
-
export class AppModule {}
|
|
3570
|
-
`);
|
|
3571
|
-
mkdirSync5(resolve23(target, "app/controllers"), { recursive: true });
|
|
3572
|
-
const homeViewReturn = view !== "none" ? `{
|
|
3573
|
-
view: 'welcome.html',
|
|
3574
|
-
data: { year: new Date().getFullYear() },
|
|
3575
|
-
}` : `{ status: 200, body: { message: 'Hello from NexusTS!' } }`;
|
|
3576
|
-
writeFileSync3(resolve23(target, "app/controllers/home.controller.ts"), `import { Controller, Get } from '@nexusts/core';
|
|
3577
|
-
|
|
3578
|
-
@Controller('/')
|
|
3579
|
-
export class HomeController {
|
|
3580
|
-
@Get('/')
|
|
3581
|
-
index() {
|
|
3582
|
-
return ${homeViewReturn};
|
|
3583
|
-
}
|
|
3584
|
-
}
|
|
3585
|
-
`);
|
|
3586
|
-
writeFileSync3(resolve23(target, "README.md"), `# ${name}
|
|
3587
|
-
|
|
3588
|
-
A new NexusTS project.
|
|
3589
|
-
|
|
3590
|
-
## Run
|
|
3591
|
-
|
|
3592
|
-
\`\`\`bash
|
|
3593
|
-
bun install
|
|
3594
|
-
bun run dev
|
|
3595
|
-
\`\`\`
|
|
3596
|
-
|
|
3597
|
-
## Scaffolding
|
|
3598
|
-
|
|
3599
|
-
\`\`\`bash
|
|
3600
|
-
bunx nx make:crud Post
|
|
3601
|
-
\`\`\`
|
|
3611
|
+
const { deps, devDeps } = computeDeps(view, orm, db, frontend);
|
|
3612
|
+
const pkgJson = buildPackageJson(name, deps, devDeps, view, frontend);
|
|
3613
|
+
writeFileSync4(resolve24(target, "package.json"), JSON.stringify(pkgJson, null, 2) + `
|
|
3602
3614
|
`);
|
|
3603
|
-
|
|
3615
|
+
const opts = { target, name, routing, view, orm, db, frontend, ssr, dbUrl };
|
|
3616
|
+
const files = generateProjectFiles(target, opts);
|
|
3617
|
+
logger.success(`created ${name}`);
|
|
3618
|
+
for (const f of files)
|
|
3619
|
+
logger.info(` + ${f}`);
|
|
3620
|
+
logger.info(` + tsconfig.json`);
|
|
3621
|
+
logger.info(` + package.json`);
|
|
3604
3622
|
logger.blank();
|
|
3605
3623
|
logger.heading("Next steps");
|
|
3606
3624
|
logger.info(` cd ${name}`);
|
|
@@ -3610,62 +3628,11 @@ bunx nx make:crud Post
|
|
|
3610
3628
|
return 0;
|
|
3611
3629
|
}
|
|
3612
3630
|
};
|
|
3613
|
-
function generateEnvFile() {
|
|
3614
|
-
return `# \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\u2500\u2500\u2500\u2500\u2500
|
|
3615
|
-
# NexusTS \u2014 Environment Variables (committed to git)
|
|
3616
|
-
#
|
|
3617
|
-
# Shared defaults for all environments. Override locally via
|
|
3618
|
-
# .env.local (gitignored) or by environment via .env.{NODE_ENV}
|
|
3619
|
-
# (e.g. .env.production, .env.development).
|
|
3620
|
-
#
|
|
3621
|
-
# Uncomment the database config for your driver:
|
|
3622
|
-
# \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\u2500\u2500\u2500\u2500\u2500
|
|
3623
|
-
|
|
3624
|
-
# \u2500\u2500 App \u2500\u2500
|
|
3625
|
-
NODE_ENV=development
|
|
3626
|
-
PORT=3000
|
|
3627
|
-
|
|
3628
|
-
# \u2500\u2500 Session secret (REQUIRED) \u2500\u2500
|
|
3629
|
-
# Generate with: openssl rand -base64 32
|
|
3630
|
-
SESSION_SECRET=change-me-in-production
|
|
3631
|
-
|
|
3632
|
-
# \u2500\u2500 Database: SQLite (default, zero config) \u2500\u2500
|
|
3633
|
-
DATABASE_URL=app.db
|
|
3634
|
-
|
|
3635
|
-
# \u2500\u2500 Database: PostgreSQL \u2500\u2500
|
|
3636
|
-
# DATABASE_URL=postgres://user:password@localhost:5432/myapp
|
|
3637
|
-
|
|
3638
|
-
# \u2500\u2500 Database: MySQL \u2500\u2500
|
|
3639
|
-
# DATABASE_URL=mysql://user:password@localhost:3306/myapp
|
|
3640
|
-
`;
|
|
3641
|
-
}
|
|
3642
|
-
function generateEnvLocalFile() {
|
|
3643
|
-
return `# \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\u2500\u2500\u2500\u2500\u2500
|
|
3644
|
-
# NexusTS \u2014 Local Overrides (DO NOT COMMIT to git)
|
|
3645
|
-
#
|
|
3646
|
-
# This file is gitignored. Use it for secrets and local
|
|
3647
|
-
# configuration that should never be checked in.
|
|
3648
|
-
# \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\u2500\u2500\u2500\u2500\u2500
|
|
3649
|
-
|
|
3650
|
-
# Override any value from .env here:
|
|
3651
|
-
# DATABASE_URL=postgres://user:password@localhost:5432/myapp
|
|
3652
|
-
# SESSION_SECRET=my-local-secret
|
|
3653
|
-
`;
|
|
3654
|
-
}
|
|
3655
|
-
function generateGitIgnore() {
|
|
3656
|
-
return `# NexusTS
|
|
3657
|
-
node_modules/
|
|
3658
|
-
app.db
|
|
3659
|
-
*.db
|
|
3660
|
-
.env.local
|
|
3661
|
-
dist/
|
|
3662
|
-
`;
|
|
3663
|
-
}
|
|
3664
3631
|
var new_default = newCommand;
|
|
3665
3632
|
|
|
3666
3633
|
// packages/cli/src/commands/config.ts
|
|
3667
|
-
import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as
|
|
3668
|
-
import { resolve as
|
|
3634
|
+
import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
3635
|
+
import { resolve as resolve25 } from "path";
|
|
3669
3636
|
var DEFAULT_VALUES = {
|
|
3670
3637
|
routing: "nest",
|
|
3671
3638
|
view: "rendu",
|
|
@@ -3780,12 +3747,12 @@ var configCommand = {
|
|
|
3780
3747
|
async run(ctx) {
|
|
3781
3748
|
const interactive = !flagBool(ctx.flags, "no-interaction", false);
|
|
3782
3749
|
const force = flagBool(ctx.flags, "force", false);
|
|
3783
|
-
const target =
|
|
3750
|
+
const target = resolve25(ctx.cwd, ctx.flags["target"] ?? ".");
|
|
3784
3751
|
if (!existsSync8(target)) {
|
|
3785
3752
|
logger.error(`Target directory does not exist: ${target}`);
|
|
3786
3753
|
return 1;
|
|
3787
3754
|
}
|
|
3788
|
-
const nxConfigPath =
|
|
3755
|
+
const nxConfigPath = resolve25(target, "nx.config.ts");
|
|
3789
3756
|
const values = parseExistingConfig(nxConfigPath);
|
|
3790
3757
|
const flag = (k) => ctx.flags[k];
|
|
3791
3758
|
const flagBoolStrict = (k, def) => flagBool(ctx.flags, k, def);
|
|
@@ -3840,7 +3807,7 @@ var configCommand = {
|
|
|
3840
3807
|
writeNxConfig(target, values);
|
|
3841
3808
|
logger.info(` + nx.config.ts`);
|
|
3842
3809
|
}
|
|
3843
|
-
const drizzleConfigPath =
|
|
3810
|
+
const drizzleConfigPath = resolve25(target, "drizzle.config.ts");
|
|
3844
3811
|
if (values.orm === "drizzle") {
|
|
3845
3812
|
const dialect = driverToDialect(values.dbDriver);
|
|
3846
3813
|
const dbUrl = values.dbUrl;
|
|
@@ -3868,11 +3835,11 @@ var configCommand = {
|
|
|
3868
3835
|
};
|
|
3869
3836
|
function writeNxConfig(target, values) {
|
|
3870
3837
|
const code = render(templates.project["nx.config.ts"], values);
|
|
3871
|
-
|
|
3838
|
+
writeFileSync5(resolve25(target, "nx.config.ts"), code);
|
|
3872
3839
|
}
|
|
3873
3840
|
function writeDrizzleConfig(target, values) {
|
|
3874
3841
|
const code = render(templates.project["drizzle.config.ts"], values);
|
|
3875
|
-
|
|
3842
|
+
writeFileSync5(resolve25(target, "drizzle.config.ts"), code);
|
|
3876
3843
|
}
|
|
3877
3844
|
var config_default = configCommand;
|
|
3878
3845
|
|
|
@@ -3881,9 +3848,9 @@ import {
|
|
|
3881
3848
|
existsSync as existsSync9,
|
|
3882
3849
|
mkdirSync as mkdirSync6,
|
|
3883
3850
|
readFileSync as readFileSync6,
|
|
3884
|
-
writeFileSync as
|
|
3851
|
+
writeFileSync as writeFileSync6
|
|
3885
3852
|
} from "fs";
|
|
3886
|
-
import { dirname as dirname5, resolve as
|
|
3853
|
+
import { dirname as dirname5, resolve as resolve26 } from "path";
|
|
3887
3854
|
import * as readline from "readline";
|
|
3888
3855
|
import * as vm from "vm";
|
|
3889
3856
|
var BANNER = (() => {
|
|
@@ -3965,10 +3932,10 @@ var replCommand = {
|
|
|
3965
3932
|
async run(ctx) {
|
|
3966
3933
|
const mod = ctx.flags["module"];
|
|
3967
3934
|
const noBoot = Boolean(ctx.flags["no-boot"]);
|
|
3968
|
-
const histPath =
|
|
3935
|
+
const histPath = resolve26(ctx.cwd, ctx.flags["history"] ?? ".nx-repl-history");
|
|
3969
3936
|
const env = { console };
|
|
3970
3937
|
if (!noBoot) {
|
|
3971
|
-
const modPath =
|
|
3938
|
+
const modPath = resolve26(ctx.cwd, mod ?? "app/app.module.ts");
|
|
3972
3939
|
if (!existsSync9(modPath)) {
|
|
3973
3940
|
logger.error(`module not found: ${modPath}`);
|
|
3974
3941
|
logger.info("pass --module <path> or --no-boot to skip booting");
|
|
@@ -4286,7 +4253,7 @@ function saveHistoryFile(path, history) {
|
|
|
4286
4253
|
const dir = dirname5(path);
|
|
4287
4254
|
if (!existsSync9(dir))
|
|
4288
4255
|
mkdirSync6(dir, { recursive: true });
|
|
4289
|
-
|
|
4256
|
+
writeFileSync6(path, history.slice(-1000).join(`
|
|
4290
4257
|
`));
|
|
4291
4258
|
} catch {}
|
|
4292
4259
|
}
|
|
@@ -4294,7 +4261,7 @@ var repl_default = replCommand;
|
|
|
4294
4261
|
|
|
4295
4262
|
// packages/cli/src/commands/route-list.ts
|
|
4296
4263
|
import { readdirSync, statSync as statSync2 } from "fs";
|
|
4297
|
-
import { resolve as
|
|
4264
|
+
import { resolve as resolve27 } from "path";
|
|
4298
4265
|
var routeListCommand = {
|
|
4299
4266
|
name: "route:list",
|
|
4300
4267
|
aliases: ["routes", "route-list"],
|
|
@@ -4304,7 +4271,7 @@ var routeListCommand = {
|
|
|
4304
4271
|
{ name: "format", description: "Output format: table (default) | json" }
|
|
4305
4272
|
],
|
|
4306
4273
|
async run(ctx) {
|
|
4307
|
-
const controllersDir =
|
|
4274
|
+
const controllersDir = resolve27(ctx.cwd, ctx.config.paths.controllers);
|
|
4308
4275
|
try {
|
|
4309
4276
|
statSync2(controllersDir);
|
|
4310
4277
|
} catch {
|
|
@@ -4318,7 +4285,7 @@ var routeListCommand = {
|
|
|
4318
4285
|
}
|
|
4319
4286
|
const routes = [];
|
|
4320
4287
|
for (const file of files) {
|
|
4321
|
-
const fullPath =
|
|
4288
|
+
const fullPath = resolve27(controllersDir, file);
|
|
4322
4289
|
try {
|
|
4323
4290
|
const mod = await import(`${fullPath}?t=${Date.now()}`);
|
|
4324
4291
|
for (const exportName of Object.keys(mod)) {
|
|
@@ -4520,5 +4487,5 @@ main().then((code) => process.exit(code)).catch((err) => {
|
|
|
4520
4487
|
process.exit(1);
|
|
4521
4488
|
});
|
|
4522
4489
|
|
|
4523
|
-
//# debugId=
|
|
4490
|
+
//# debugId=C2DE7496FA294EC464756E2164756E21
|
|
4524
4491
|
//# sourceMappingURL=index.js.map
|