@tsed/cli 7.3.4 → 7.5.0-rc.1
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/lib/esm/commands/build/BuildCmd.js +21 -0
- package/lib/esm/commands/dev/DevCmd.js +118 -0
- package/lib/esm/commands/index.js +3 -1
- package/lib/esm/commands/init/InitCmd.js +30 -8
- package/lib/esm/commands/init/config/FeaturesPrompt.js +11 -7
- package/lib/esm/commands/init/config/InitSchema.js +4 -0
- package/lib/esm/commands/init/prompts/getFeaturesPrompt.js +6 -2
- package/lib/esm/commands/init/utils/hasFeature.js +5 -2
- package/lib/esm/commands/mcp/schema/ProjectPreferencesSchema.js +2 -2
- package/lib/esm/commands/run/RunCmd.js +0 -1
- package/lib/esm/runtimes/RuntimesModule.js +2 -1
- package/lib/esm/runtimes/index.js +1 -0
- package/lib/esm/runtimes/supports/ViteRuntime.js +30 -0
- package/lib/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/commands/build/BuildCmd.d.ts +9 -0
- package/lib/types/commands/dev/DevCmd.d.ts +12 -0
- package/lib/types/commands/index.d.ts +3 -1
- package/lib/types/commands/init/InitCmd.d.ts +3 -0
- package/lib/types/commands/mcp/schema/ProjectPreferencesSchema.d.ts +1 -1
- package/lib/types/interfaces/RenderDataContext.d.ts +1 -0
- package/lib/types/interfaces/RuntimeTypes.d.ts +1 -1
- package/lib/types/runtimes/index.d.ts +1 -0
- package/lib/types/runtimes/supports/ViteRuntime.d.ts +11 -0
- package/package.json +10 -7
- package/templates/vite.config.ts +21 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { command, inject } from "@tsed/cli-core";
|
|
2
|
+
import { taskLogger } from "@tsed/cli-tasks";
|
|
3
|
+
import { CliRunScript } from "../../services/CliRunScript.js";
|
|
4
|
+
export class BuildCmd {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.runScript = inject(CliRunScript);
|
|
7
|
+
}
|
|
8
|
+
async $exec(ctx) {
|
|
9
|
+
const command = "vite build";
|
|
10
|
+
taskLogger().info(`Run ${[command, ...ctx.rawArgs].join(" ")}`);
|
|
11
|
+
await this.runScript.run(command, ctx.rawArgs, {
|
|
12
|
+
env: process.env
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
command({
|
|
17
|
+
token: BuildCmd,
|
|
18
|
+
name: "build",
|
|
19
|
+
description: "Build the project",
|
|
20
|
+
allowUnknownOption: true
|
|
21
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import { command, normalizePath } from "@tsed/cli-core";
|
|
4
|
+
import { taskLogger } from "@tsed/cli-tasks";
|
|
5
|
+
export class DevCmd {
|
|
6
|
+
async $exec(ctx) {
|
|
7
|
+
await this.runViteDev(ctx.rawArgs);
|
|
8
|
+
}
|
|
9
|
+
parseWatchValue(args) {
|
|
10
|
+
const watchArg = args.find((arg) => arg === "--watch" || arg.startsWith("--watch="));
|
|
11
|
+
if (!watchArg) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if (watchArg === "--watch") {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return watchArg !== "--watch=false";
|
|
18
|
+
}
|
|
19
|
+
async createViteDevServer() {
|
|
20
|
+
const { createServer } = await import("vite");
|
|
21
|
+
return createServer({
|
|
22
|
+
configFile: normalizePath("vite.config.ts"),
|
|
23
|
+
server: {
|
|
24
|
+
middlewareMode: true,
|
|
25
|
+
hmr: false,
|
|
26
|
+
ws: false
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async runViteApp() {
|
|
31
|
+
const vite = await this.createViteDevServer();
|
|
32
|
+
const shutdown = async () => {
|
|
33
|
+
await vite.close();
|
|
34
|
+
process.exit(0);
|
|
35
|
+
};
|
|
36
|
+
process.on("SIGINT", shutdown);
|
|
37
|
+
process.on("SIGTERM", shutdown);
|
|
38
|
+
await vite.ssrLoadModule(`/src/index.ts?t=${Date.now()}`);
|
|
39
|
+
await new Promise(() => { });
|
|
40
|
+
}
|
|
41
|
+
async runViteController(rawArgs) {
|
|
42
|
+
const watch = this.parseWatchValue(rawArgs);
|
|
43
|
+
const vite = await this.createViteDevServer();
|
|
44
|
+
let childProcess;
|
|
45
|
+
let restarting = false;
|
|
46
|
+
let queued = false;
|
|
47
|
+
const startChild = () => {
|
|
48
|
+
const [, scriptPath] = process.argv;
|
|
49
|
+
const args = scriptPath ? [scriptPath, "dev", ...rawArgs] : ["dev", ...rawArgs];
|
|
50
|
+
childProcess = spawn(process.execPath, args, {
|
|
51
|
+
env: {
|
|
52
|
+
...process.env,
|
|
53
|
+
TSED_VITE_RUN_MODE: "app"
|
|
54
|
+
},
|
|
55
|
+
stdio: "inherit"
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
const stopChild = async () => {
|
|
59
|
+
if (!childProcess || childProcess.killed) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
await new Promise((resolve) => {
|
|
63
|
+
childProcess.once("exit", resolve);
|
|
64
|
+
childProcess.kill("SIGTERM");
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
const restartChild = async (reason, file = "") => {
|
|
68
|
+
if (restarting) {
|
|
69
|
+
queued = true;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
restarting = true;
|
|
73
|
+
const suffix = file ? `: ${file}` : "";
|
|
74
|
+
taskLogger().info(`[tsed-dev] restart (${reason})${suffix}`);
|
|
75
|
+
await stopChild();
|
|
76
|
+
startChild();
|
|
77
|
+
restarting = false;
|
|
78
|
+
if (queued) {
|
|
79
|
+
queued = false;
|
|
80
|
+
await restartChild("queued");
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
if (watch) {
|
|
84
|
+
vite.watcher.on("all", async (event, file) => {
|
|
85
|
+
if (!file || file.includes("node_modules") || file.includes(".git") || file.includes("/dist/")) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (["add", "change", "unlink"].includes(event)) {
|
|
89
|
+
await restartChild(event, file);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
vite.watcher.once("ready", () => {
|
|
94
|
+
startChild();
|
|
95
|
+
});
|
|
96
|
+
const shutdown = async () => {
|
|
97
|
+
await stopChild();
|
|
98
|
+
await vite.close();
|
|
99
|
+
process.exit(0);
|
|
100
|
+
};
|
|
101
|
+
process.on("SIGINT", shutdown);
|
|
102
|
+
process.on("SIGTERM", shutdown);
|
|
103
|
+
await new Promise(() => { });
|
|
104
|
+
}
|
|
105
|
+
async runViteDev(rawArgs) {
|
|
106
|
+
if (process.env.TSED_VITE_RUN_MODE === "app") {
|
|
107
|
+
await this.runViteApp();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
await this.runViteController(rawArgs);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
command({
|
|
114
|
+
token: DevCmd,
|
|
115
|
+
name: "dev",
|
|
116
|
+
description: "Run the project in development mode",
|
|
117
|
+
allowUnknownOption: true
|
|
118
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { AddCmd } from "./add/AddCmd.js";
|
|
2
|
+
import { BuildCmd } from "./build/BuildCmd.js";
|
|
3
|
+
import { DevCmd } from "./dev/DevCmd.js";
|
|
2
4
|
import { GenerateCmd } from "./generate/GenerateCmd.js";
|
|
3
5
|
import { InitCmd } from "./init/InitCmd.js";
|
|
4
6
|
import { InitOptionsCommand } from "./init/InitOptionsCmd.js";
|
|
@@ -6,4 +8,4 @@ import { McpCommand } from "./mcp/McpCommand.js";
|
|
|
6
8
|
import { RunCmd } from "./run/RunCmd.js";
|
|
7
9
|
import { CreateTemplateCommand } from "./template/CreateTemplateCommand.js";
|
|
8
10
|
import { UpdateCmd } from "./update/UpdateCmd.js";
|
|
9
|
-
export default [AddCmd, InitCmd, InitOptionsCommand, GenerateCmd, UpdateCmd, RunCmd, CreateTemplateCommand, McpCommand];
|
|
11
|
+
export default [AddCmd, InitCmd, InitOptionsCommand, GenerateCmd, UpdateCmd, RunCmd, DevCmd, BuildCmd, CreateTemplateCommand, McpCommand];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as os from "node:os";
|
|
2
2
|
import { basename, join } from "node:path";
|
|
3
|
-
import { CliExeca, CliFs, CliLoadFile, cliPackageJson, CliPlugins, command, Configuration, inject, PackageManagersModule, ProjectPackageJson } from "@tsed/cli-core";
|
|
3
|
+
import { CliExeca, CliFs, CliLoadFile, cliPackageJson, CliPlugins, command, Configuration, inject, PackageManager, PackageManagersModule, ProjectPackageJson } from "@tsed/cli-core";
|
|
4
4
|
import { tasks } from "@tsed/cli-tasks";
|
|
5
5
|
import { isString } from "@tsed/core";
|
|
6
6
|
import { constant } from "@tsed/di";
|
|
@@ -14,6 +14,7 @@ import { PlatformsModule } from "../../platforms/PlatformsModule.js";
|
|
|
14
14
|
import { RuntimesModule } from "../../runtimes/RuntimesModule.js";
|
|
15
15
|
import { BunRuntime } from "../../runtimes/supports/BunRuntime.js";
|
|
16
16
|
import { NodeRuntime } from "../../runtimes/supports/NodeRuntime.js";
|
|
17
|
+
import { ViteRuntime } from "../../runtimes/supports/ViteRuntime.js";
|
|
17
18
|
import { CliProjectService } from "../../services/CliProjectService.js";
|
|
18
19
|
import { anonymizePaths } from "../../services/mappers/anonymizePaths.js";
|
|
19
20
|
import { FeaturesMap, FeatureType } from "./config/FeaturesPrompt.js";
|
|
@@ -46,8 +47,16 @@ export class InitCmd {
|
|
|
46
47
|
if (initialOptions.skipPrompt) {
|
|
47
48
|
return [];
|
|
48
49
|
}
|
|
49
|
-
const
|
|
50
|
-
const
|
|
50
|
+
const forceBunRuntime = this.isLaunchedWithBunx();
|
|
51
|
+
const packageManagers = forceBunRuntime ? this.filterOnlyBun(this.packageManagers.list()) : this.packageManagers.list();
|
|
52
|
+
const runtimes = forceBunRuntime ? this.filterOnlyBun(this.runtimes.list()) : this.runtimes.list();
|
|
53
|
+
const promptOptions = forceBunRuntime
|
|
54
|
+
? {
|
|
55
|
+
...initialOptions,
|
|
56
|
+
runtime: "bun",
|
|
57
|
+
packageManager: PackageManager.BUN
|
|
58
|
+
}
|
|
59
|
+
: initialOptions;
|
|
51
60
|
return [
|
|
52
61
|
{
|
|
53
62
|
type: "input",
|
|
@@ -59,12 +68,16 @@ export class InitCmd {
|
|
|
59
68
|
return kebabCase(input);
|
|
60
69
|
}
|
|
61
70
|
},
|
|
62
|
-
...getFeaturesPrompt(runtimes, packageManagers.filter((o) => o !== "bun"),
|
|
71
|
+
...getFeaturesPrompt(runtimes, forceBunRuntime ? packageManagers : packageManagers.filter((o) => o !== "bun"), promptOptions)
|
|
63
72
|
];
|
|
64
73
|
}
|
|
65
74
|
$mapContext(ctx) {
|
|
66
75
|
this.resolveRootDir(ctx);
|
|
67
76
|
ctx = mapToContext(ctx);
|
|
77
|
+
if (this.isLaunchedWithBunx()) {
|
|
78
|
+
ctx.runtime = "bun";
|
|
79
|
+
ctx.packageManager = "bun";
|
|
80
|
+
}
|
|
68
81
|
this.runtimes.init(ctx);
|
|
69
82
|
this.runtimes.list().forEach((key) => {
|
|
70
83
|
ctx[key] = ctx.runtime === key;
|
|
@@ -78,6 +91,16 @@ export class InitCmd {
|
|
|
78
91
|
srcDir: constant("project.srcDir", "src")
|
|
79
92
|
};
|
|
80
93
|
}
|
|
94
|
+
isLaunchedWithBunx() {
|
|
95
|
+
return Boolean(globalThis.Bun);
|
|
96
|
+
}
|
|
97
|
+
filterOnlyBun(values) {
|
|
98
|
+
const filtered = values.filter((value) => value === "bun");
|
|
99
|
+
return filtered.length ? filtered : values;
|
|
100
|
+
}
|
|
101
|
+
async writeRcFiles(ctx) {
|
|
102
|
+
await Promise.all([render(".npmrc", ctx), render(".yarnrc", ctx)]);
|
|
103
|
+
}
|
|
81
104
|
preExec(ctx) {
|
|
82
105
|
this.fs.ensureDirSync(this.packageJson.cwd);
|
|
83
106
|
ctx.projectName && (this.packageJson.name = ctx.projectName);
|
|
@@ -91,9 +114,7 @@ export class InitCmd {
|
|
|
91
114
|
{
|
|
92
115
|
title: "Write RC files",
|
|
93
116
|
skip: () => !ctx.premium,
|
|
94
|
-
task: () =>
|
|
95
|
-
return Promise.all([render(".npmrc", ctx), render(".yarnrc", ctx)]);
|
|
96
|
-
}
|
|
117
|
+
task: () => this.writeRcFiles(ctx)
|
|
97
118
|
},
|
|
98
119
|
{
|
|
99
120
|
title: "Initialize package.json",
|
|
@@ -123,7 +144,8 @@ export class InitCmd {
|
|
|
123
144
|
...ctx,
|
|
124
145
|
node: runtime instanceof NodeRuntime,
|
|
125
146
|
bun: runtime instanceof BunRuntime,
|
|
126
|
-
|
|
147
|
+
vite: runtime instanceof ViteRuntime,
|
|
148
|
+
compiled: runtime.isCompiled()
|
|
127
149
|
};
|
|
128
150
|
return [
|
|
129
151
|
{
|
|
@@ -329,6 +329,10 @@ export const FeaturesMap = {
|
|
|
329
329
|
[FeatureType.LINT_STAGED]: {
|
|
330
330
|
name: "Lint on commit"
|
|
331
331
|
},
|
|
332
|
+
vite: {
|
|
333
|
+
name: "Node.js + Vite",
|
|
334
|
+
checked: false
|
|
335
|
+
},
|
|
332
336
|
node: {
|
|
333
337
|
name: "Node.js + SWC",
|
|
334
338
|
checked: true
|
|
@@ -345,17 +349,17 @@ export const FeaturesMap = {
|
|
|
345
349
|
name: "Bun.js",
|
|
346
350
|
checked: false
|
|
347
351
|
},
|
|
348
|
-
|
|
349
|
-
name: "
|
|
350
|
-
checked:
|
|
352
|
+
npm: {
|
|
353
|
+
name: "NPM",
|
|
354
|
+
checked: false
|
|
351
355
|
},
|
|
352
356
|
yarn_berry: {
|
|
353
357
|
name: "Yarn Berry",
|
|
354
358
|
checked: false
|
|
355
359
|
},
|
|
356
|
-
|
|
357
|
-
name: "
|
|
358
|
-
checked:
|
|
360
|
+
yarn: {
|
|
361
|
+
name: "Yarn",
|
|
362
|
+
checked: true
|
|
359
363
|
},
|
|
360
364
|
pnpm: {
|
|
361
365
|
name: "PNPM",
|
|
@@ -512,7 +516,7 @@ export const FeaturesPrompt = (availableRuntimes, availablePackageManagers) => [
|
|
|
512
516
|
message: "Choose the package manager:",
|
|
513
517
|
type: "list",
|
|
514
518
|
name: "packageManager",
|
|
515
|
-
when: hasValue("runtime", ["node", "babel", "swc", "webpack"]),
|
|
519
|
+
when: hasValue("runtime", ["vite", "node", "babel", "swc", "webpack"]),
|
|
516
520
|
choices: availablePackageManagers
|
|
517
521
|
}
|
|
518
522
|
];
|
|
@@ -2,9 +2,13 @@ import { cleanObject, isFunction } from "@tsed/core";
|
|
|
2
2
|
import { FeaturesMap, FeaturesPrompt } from "../config/FeaturesPrompt.js";
|
|
3
3
|
function mapChoices(item, options) {
|
|
4
4
|
return item.choices.map((choice) => {
|
|
5
|
-
const
|
|
5
|
+
const config = FeaturesMap[choice];
|
|
6
|
+
if (!config) {
|
|
7
|
+
throw new Error(`Unknown init prompt choice "${choice}" for prompt "${item.name}"`);
|
|
8
|
+
}
|
|
9
|
+
const { checked } = config;
|
|
6
10
|
return cleanObject({
|
|
7
|
-
...
|
|
11
|
+
...config,
|
|
8
12
|
value: choice,
|
|
9
13
|
checked: isFunction(checked) ? checked(options) : checked
|
|
10
14
|
});
|
|
@@ -3,8 +3,11 @@ export function hasValue(expression, value) {
|
|
|
3
3
|
return (ctx) => [].concat(value).includes(getValue(expression, ctx));
|
|
4
4
|
}
|
|
5
5
|
export function hasFeature(feature) {
|
|
6
|
-
return (ctx) => !!ctx.features
|
|
6
|
+
return (ctx) => !!ctx.features?.find((item) => item === feature);
|
|
7
7
|
}
|
|
8
8
|
export function hasValuePremium() {
|
|
9
|
-
return (ctx) =>
|
|
9
|
+
return (ctx) => Object.entries(ctx)
|
|
10
|
+
.filter(([key]) => key.startsWith("features"))
|
|
11
|
+
.flatMap(([, value]) => [].concat(value))
|
|
12
|
+
.some((item) => typeof item === "string" && item.endsWith(":premium"));
|
|
10
13
|
}
|
|
@@ -8,8 +8,8 @@ export const ProjectPreferenceSchema = s
|
|
|
8
8
|
packageManager: s.string().enum(PackageManager).description("Used project manager to install dependencies"),
|
|
9
9
|
runtime: s
|
|
10
10
|
.string()
|
|
11
|
-
.enum("node", "babel", "swc", "webpack", "bun")
|
|
12
|
-
.description("The javascript runtime used to start application (node, node + webpack, node + swc, node + babel, bun)"),
|
|
11
|
+
.enum("vite", "node", "babel", "swc", "webpack", "bun")
|
|
12
|
+
.description("The javascript runtime used to start application (node, node + webpack, node + swc, node + babel, bun, vite)"),
|
|
13
13
|
platform: s.string().enum(PlatformType).description("Node.js framework used to run server (Express, Koa, Fastify)")
|
|
14
14
|
})
|
|
15
15
|
.optional()
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CliFs, command, inject, normalizePath, ProjectPackageJson } from "@tsed/cli-core";
|
|
2
2
|
import { taskLogger } from "@tsed/cli-tasks";
|
|
3
|
-
import { logger } from "@tsed/di";
|
|
4
3
|
import { CliRunScript } from "../../services/CliRunScript.js";
|
|
5
4
|
export class RunCmd {
|
|
6
5
|
constructor() {
|
|
@@ -4,6 +4,7 @@ import { BabelRuntime } from "./supports/BabelRuntime.js";
|
|
|
4
4
|
import { BaseRuntime } from "./supports/BaseRuntime.js";
|
|
5
5
|
import { BunRuntime } from "./supports/BunRuntime.js";
|
|
6
6
|
import { NodeRuntime } from "./supports/NodeRuntime.js";
|
|
7
|
+
import { ViteRuntime } from "./supports/ViteRuntime.js";
|
|
7
8
|
import { WebpackRuntime } from "./supports/WebpackRuntime.js";
|
|
8
9
|
export class RuntimesModule {
|
|
9
10
|
constructor() {
|
|
@@ -41,4 +42,4 @@ export class RuntimesModule {
|
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
|
-
injectable(RuntimesModule).imports([NodeRuntime, BabelRuntime, WebpackRuntime, BunRuntime]);
|
|
45
|
+
injectable(RuntimesModule).imports([ViteRuntime, NodeRuntime, BabelRuntime, WebpackRuntime, , BunRuntime]);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { injectable } from "@tsed/di";
|
|
2
|
+
import { BaseRuntime } from "./BaseRuntime.js";
|
|
3
|
+
export class ViteRuntime extends BaseRuntime {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(...arguments);
|
|
6
|
+
this.name = "vite";
|
|
7
|
+
this.cmd = "node";
|
|
8
|
+
this.order = -1;
|
|
9
|
+
}
|
|
10
|
+
files() {
|
|
11
|
+
return ["vite.config.ts"];
|
|
12
|
+
}
|
|
13
|
+
compile() {
|
|
14
|
+
return "tsed build";
|
|
15
|
+
}
|
|
16
|
+
startDev() {
|
|
17
|
+
return "tsed dev";
|
|
18
|
+
}
|
|
19
|
+
startProd(args) {
|
|
20
|
+
return `node ${args}`;
|
|
21
|
+
}
|
|
22
|
+
devDependencies() {
|
|
23
|
+
return {
|
|
24
|
+
"@tsed/cli": "{{cliVersion}}",
|
|
25
|
+
typescript: "latest",
|
|
26
|
+
vite: "latest"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
injectable(ViteRuntime).type("runtime");
|