alepha 0.14.3 → 0.14.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/README.md +1 -1
- package/dist/api/audits/index.d.ts +338 -417
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +1 -80
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +156 -235
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.d.ts +170 -249
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +266 -345
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +755 -834
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/verifications/index.d.ts +125 -125
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/cli/index.d.ts +116 -20
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +212 -124
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +6 -11
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +2 -2
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +26 -4
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +16 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +26 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +26 -4
- package/dist/core/index.native.js.map +1 -1
- package/dist/logger/index.d.ts +1 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +12 -2
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.d.ts +37 -173
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +193 -422
- package/dist/orm/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +167 -167
- package/dist/server/cache/index.d.ts +12 -0
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +55 -2
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +6 -0
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +36 -1
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/core/index.browser.js +2 -2
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +10 -10
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +6 -3
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/links/index.d.ts +39 -39
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/security/index.d.ts +9 -9
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/static/index.js +4 -0
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +2 -3
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/vite/index.d.ts +101 -106
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +571 -508
- package/dist/vite/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/apps/AlephaCli.ts +0 -2
- package/src/cli/atoms/buildOptions.ts +88 -0
- package/src/cli/commands/build.ts +32 -69
- package/src/cli/commands/db.ts +0 -4
- package/src/cli/commands/dev.ts +16 -4
- package/src/cli/commands/gen/env.ts +53 -0
- package/src/cli/commands/gen/openapi.ts +1 -1
- package/src/cli/commands/gen/resource.ts +15 -0
- package/src/cli/commands/gen.ts +7 -1
- package/src/cli/commands/init.ts +0 -1
- package/src/cli/commands/test.ts +0 -1
- package/src/cli/commands/verify.ts +1 -1
- package/src/cli/defineConfig.ts +49 -7
- package/src/cli/index.ts +0 -1
- package/src/cli/services/AlephaCliUtils.ts +36 -25
- package/src/command/helpers/Runner.spec.ts +2 -2
- package/src/command/helpers/Runner.ts +1 -1
- package/src/command/primitives/$command.ts +0 -6
- package/src/command/providers/CliProvider.ts +1 -3
- package/src/core/Alepha.ts +42 -0
- package/src/logger/index.ts +15 -3
- package/src/mcp/transports/StdioMcpTransport.ts +1 -1
- package/src/orm/index.ts +2 -8
- package/src/queue/core/providers/WorkerProvider.spec.ts +48 -32
- package/src/server/cache/providers/ServerCacheProvider.spec.ts +183 -0
- package/src/server/cache/providers/ServerCacheProvider.ts +94 -9
- package/src/server/compress/providers/ServerCompressProvider.ts +61 -2
- package/src/server/core/helpers/ServerReply.ts +2 -2
- package/src/server/core/providers/ServerProvider.ts +11 -1
- package/src/server/static/providers/ServerStaticProvider.ts +10 -0
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -8
- package/src/vite/helpers/importViteReact.ts +13 -0
- package/src/vite/index.ts +1 -21
- package/src/vite/plugins/viteAlephaDev.ts +16 -1
- package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
- package/src/vite/tasks/buildClient.ts +11 -0
- package/src/vite/tasks/buildServer.ts +47 -3
- package/src/vite/tasks/devServer.ts +69 -0
- package/src/vite/tasks/index.ts +2 -1
- package/src/cli/assets/viteConfigTs.ts +0 -14
- package/src/cli/commands/run.ts +0 -24
- package/src/vite/plugins/viteAlepha.ts +0 -37
- package/src/vite/plugins/viteAlephaBuild.ts +0 -281
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { access, readFile, unlink, writeFile } from "node:fs/promises";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
2
|
import { join } from "node:path";
|
|
4
|
-
import { $inject,
|
|
3
|
+
import { $inject, $use, t } from "alepha";
|
|
5
4
|
import { $command } from "alepha/command";
|
|
6
5
|
import { $logger } from "alepha/logger";
|
|
7
6
|
import {
|
|
@@ -15,15 +14,17 @@ import {
|
|
|
15
14
|
generateVercel,
|
|
16
15
|
prerenderPages,
|
|
17
16
|
} from "alepha/vite";
|
|
18
|
-
import
|
|
17
|
+
import { buildOptions } from "../atoms/buildOptions.ts";
|
|
19
18
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
20
19
|
|
|
21
20
|
export class BuildCommand {
|
|
22
21
|
protected readonly log = $logger();
|
|
23
22
|
protected readonly utils = $inject(AlephaCliUtils);
|
|
23
|
+
protected readonly options = $use(buildOptions);
|
|
24
24
|
|
|
25
25
|
public readonly build = $command({
|
|
26
26
|
name: "build",
|
|
27
|
+
mode: "production",
|
|
27
28
|
description: "Build the project for production",
|
|
28
29
|
args: t.optional(
|
|
29
30
|
t.text({ title: "path", description: "Filepath to build" }),
|
|
@@ -61,13 +62,11 @@ export class BuildCommand {
|
|
|
61
62
|
process.env.NODE_ENV = "production";
|
|
62
63
|
|
|
63
64
|
if (await this.utils.hasExpo(root)) {
|
|
64
|
-
// will
|
|
65
|
-
// 1. ensure "expo prebuild" is run
|
|
65
|
+
// will come soon
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
await this.utils.ensureConfig(root, {
|
|
70
|
-
viteConfigTs: true,
|
|
71
70
|
tsconfigJson: true,
|
|
72
71
|
});
|
|
73
72
|
|
|
@@ -77,25 +76,13 @@ export class BuildCommand {
|
|
|
77
76
|
const distDir = "dist";
|
|
78
77
|
const clientDir = "public";
|
|
79
78
|
|
|
80
|
-
await this.utils.ensureDependency(root, "vite", {
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
await run.rm("dist", {
|
|
85
|
-
alias: "clean dist",
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const vite: typeof Vite = createRequire(import.meta.url)("vite");
|
|
89
|
-
const config = await vite.resolveConfig({}, "build", "production");
|
|
90
|
-
const alephaPlugin: any = config.plugins.find(
|
|
91
|
-
(it) => it.name === "alepha:build",
|
|
92
|
-
);
|
|
93
|
-
const viteAlephaBuildOptions = alephaPlugin?.[OPTIONS] || {};
|
|
79
|
+
await this.utils.ensureDependency(root, "vite", { run });
|
|
80
|
+
await run.rm("dist", { alias: "clean dist" });
|
|
94
81
|
|
|
82
|
+
const options = this.options;
|
|
95
83
|
await this.utils.loadEnv(root, [".env", ".env.production"]);
|
|
96
84
|
|
|
97
|
-
const stats = flags.stats ??
|
|
98
|
-
const hasServer = viteAlephaBuildOptions.serverEntry !== false;
|
|
85
|
+
const stats = flags.stats ?? options.stats ?? false;
|
|
99
86
|
|
|
100
87
|
let hasClient = false;
|
|
101
88
|
try {
|
|
@@ -105,13 +92,7 @@ export class BuildCommand {
|
|
|
105
92
|
// No index.html
|
|
106
93
|
}
|
|
107
94
|
|
|
108
|
-
//
|
|
109
|
-
const clientOptions =
|
|
110
|
-
typeof viteAlephaBuildOptions.client === "object"
|
|
111
|
-
? viteAlephaBuildOptions.client
|
|
112
|
-
: {};
|
|
113
|
-
|
|
114
|
-
// Build client
|
|
95
|
+
// Build client (precompress always enabled)
|
|
115
96
|
if (hasClient) {
|
|
116
97
|
await run({
|
|
117
98
|
name: "vite build client",
|
|
@@ -120,7 +101,7 @@ export class BuildCommand {
|
|
|
120
101
|
silent: true,
|
|
121
102
|
dist: `${distDir}/${clientDir}`,
|
|
122
103
|
stats,
|
|
123
|
-
precompress:
|
|
104
|
+
precompress: true,
|
|
124
105
|
}),
|
|
125
106
|
});
|
|
126
107
|
}
|
|
@@ -129,7 +110,6 @@ export class BuildCommand {
|
|
|
129
110
|
await run({
|
|
130
111
|
name: "vite build server",
|
|
131
112
|
handler: async () => {
|
|
132
|
-
// Check if client template exists
|
|
133
113
|
let clientBuilt = false;
|
|
134
114
|
try {
|
|
135
115
|
await readFile(`${distDir}/${clientDir}/index.html`, "utf-8");
|
|
@@ -147,7 +127,7 @@ export class BuildCommand {
|
|
|
147
127
|
});
|
|
148
128
|
|
|
149
129
|
// Server will handle index.html if both client & server are built
|
|
150
|
-
if (clientBuilt
|
|
130
|
+
if (clientBuilt) {
|
|
151
131
|
await unlink(`${distDir}/${clientDir}/index.html`);
|
|
152
132
|
}
|
|
153
133
|
},
|
|
@@ -163,9 +143,8 @@ export class BuildCommand {
|
|
|
163
143
|
|
|
164
144
|
if (hasClient) {
|
|
165
145
|
// Generate sitemap
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
if (sitemapBaseUrl) {
|
|
146
|
+
const sitemapHostname = flags.sitemap ?? options.sitemap?.hostname;
|
|
147
|
+
if (sitemapHostname) {
|
|
169
148
|
await run({
|
|
170
149
|
name: "add sitemap",
|
|
171
150
|
handler: async () => {
|
|
@@ -173,73 +152,57 @@ export class BuildCommand {
|
|
|
173
152
|
`${distDir}/${clientDir}/sitemap.xml`,
|
|
174
153
|
await generateSitemap({
|
|
175
154
|
entry: `${distDir}/index.js`,
|
|
176
|
-
baseUrl:
|
|
155
|
+
baseUrl: sitemapHostname,
|
|
177
156
|
}),
|
|
178
157
|
);
|
|
179
158
|
},
|
|
180
159
|
});
|
|
181
160
|
}
|
|
182
161
|
|
|
183
|
-
// Pre-render static pages
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
});
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
}
|
|
162
|
+
// Pre-render static pages (always enabled)
|
|
163
|
+
await run({
|
|
164
|
+
name: "pre-render pages",
|
|
165
|
+
handler: async () => {
|
|
166
|
+
await prerenderPages({
|
|
167
|
+
dist: `${distDir}/${clientDir}`,
|
|
168
|
+
entry: `${distDir}/index.js`,
|
|
169
|
+
compress: true,
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
});
|
|
198
173
|
}
|
|
199
174
|
|
|
200
175
|
// Generate deployment configurations
|
|
201
|
-
if (flags.vercel ||
|
|
202
|
-
const config =
|
|
203
|
-
typeof viteAlephaBuildOptions.vercel === "object"
|
|
204
|
-
? viteAlephaBuildOptions.vercel
|
|
205
|
-
: {};
|
|
176
|
+
if (flags.vercel || options.vercel) {
|
|
206
177
|
await run({
|
|
207
178
|
name: "add Vercel config",
|
|
208
179
|
handler: () =>
|
|
209
180
|
generateVercel({
|
|
210
181
|
distDir,
|
|
211
182
|
clientDir,
|
|
212
|
-
config,
|
|
183
|
+
config: options.vercel,
|
|
213
184
|
}),
|
|
214
185
|
});
|
|
215
186
|
}
|
|
216
187
|
|
|
217
|
-
if (flags.cloudflare ||
|
|
218
|
-
const config =
|
|
219
|
-
typeof viteAlephaBuildOptions.cloudflare === "boolean"
|
|
220
|
-
? {}
|
|
221
|
-
: viteAlephaBuildOptions.cloudflare;
|
|
188
|
+
if (flags.cloudflare || options.cloudflare) {
|
|
222
189
|
await run({
|
|
223
190
|
name: "add Cloudflare config",
|
|
224
191
|
handler: () =>
|
|
225
192
|
generateCloudflare({
|
|
226
193
|
distDir,
|
|
227
|
-
config,
|
|
194
|
+
config: options.cloudflare?.config,
|
|
228
195
|
}),
|
|
229
196
|
});
|
|
230
197
|
}
|
|
231
198
|
|
|
232
|
-
if (flags.docker ||
|
|
233
|
-
const dockerConfig =
|
|
234
|
-
typeof viteAlephaBuildOptions.docker === "object"
|
|
235
|
-
? viteAlephaBuildOptions.docker
|
|
236
|
-
: {};
|
|
199
|
+
if (flags.docker || options.docker) {
|
|
237
200
|
await run({
|
|
238
201
|
name: "add Docker config",
|
|
239
202
|
handler: () =>
|
|
240
203
|
generateDocker({
|
|
241
204
|
distDir,
|
|
242
|
-
...
|
|
205
|
+
...options.docker,
|
|
243
206
|
}),
|
|
244
207
|
});
|
|
245
208
|
}
|
package/src/cli/commands/db.ts
CHANGED
|
@@ -134,7 +134,6 @@ export class DbCommand {
|
|
|
134
134
|
protected readonly generate = $command({
|
|
135
135
|
name: "generate",
|
|
136
136
|
description: "Generate migration files based on current database schema",
|
|
137
|
-
summary: false,
|
|
138
137
|
args: t.optional(
|
|
139
138
|
t.text({
|
|
140
139
|
title: "path",
|
|
@@ -173,7 +172,6 @@ export class DbCommand {
|
|
|
173
172
|
protected readonly push = $command({
|
|
174
173
|
name: "push",
|
|
175
174
|
description: "Push database schema changes directly to the database",
|
|
176
|
-
summary: false,
|
|
177
175
|
args: t.optional(
|
|
178
176
|
t.text({
|
|
179
177
|
title: "path",
|
|
@@ -200,7 +198,6 @@ export class DbCommand {
|
|
|
200
198
|
protected readonly migrate = $command({
|
|
201
199
|
name: "migrate",
|
|
202
200
|
description: "Apply pending database migrations",
|
|
203
|
-
summary: false,
|
|
204
201
|
args: t.optional(
|
|
205
202
|
t.text({
|
|
206
203
|
title: "path",
|
|
@@ -227,7 +224,6 @@ export class DbCommand {
|
|
|
227
224
|
protected readonly studio = $command({
|
|
228
225
|
name: "studio",
|
|
229
226
|
description: "Launch Drizzle Studio database browser",
|
|
230
|
-
summary: false,
|
|
231
227
|
args: t.optional(
|
|
232
228
|
t.text({
|
|
233
229
|
title: "path",
|
package/src/cli/commands/dev.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { $inject, Alepha, t } from "alepha";
|
|
4
4
|
import { $command } from "alepha/command";
|
|
5
5
|
import { $logger } from "alepha/logger";
|
|
6
|
-
import { boot } from "alepha/vite";
|
|
6
|
+
import { boot, devServer } from "alepha/vite";
|
|
7
7
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
8
8
|
|
|
9
9
|
export class DevCommand {
|
|
@@ -25,7 +25,6 @@ export class DevCommand {
|
|
|
25
25
|
const expo = await this.utils.hasExpo(root);
|
|
26
26
|
|
|
27
27
|
await this.utils.ensureConfig(root, {
|
|
28
|
-
viteConfigTs: !expo,
|
|
29
28
|
tsconfigJson: true,
|
|
30
29
|
});
|
|
31
30
|
|
|
@@ -40,7 +39,7 @@ export class DevCommand {
|
|
|
40
39
|
const isFullstack = await this.isFullstackProject(root);
|
|
41
40
|
|
|
42
41
|
if (!isFullstack) {
|
|
43
|
-
const exe = this.
|
|
42
|
+
const exe = (await this.isBunProject(root)) ? "bun" : "tsx";
|
|
44
43
|
let cmd = `${exe} --watch`;
|
|
45
44
|
if (await this.utils.exists(root, ".env")) {
|
|
46
45
|
cmd += " --env-file=./.env";
|
|
@@ -54,10 +53,23 @@ export class DevCommand {
|
|
|
54
53
|
|
|
55
54
|
// Ensure vite is installed before running
|
|
56
55
|
await this.utils.ensureDependency(root, "vite");
|
|
57
|
-
|
|
56
|
+
|
|
57
|
+
await devServer();
|
|
58
58
|
},
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
protected async isBunProject(root: string): Promise<boolean> {
|
|
62
|
+
if (this.alepha.isBun()) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
await access(join(root, "bun.lock"));
|
|
67
|
+
return true;
|
|
68
|
+
} catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
protected async isFullstackProject(root: string): Promise<boolean> {
|
|
62
74
|
try {
|
|
63
75
|
await access(join(root, "index.html"));
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { $inject, t } from "alepha";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
3
|
+
import { FileSystemProvider } from "alepha/file";
|
|
4
|
+
import { $logger } from "alepha/logger";
|
|
5
|
+
import { AlephaCliUtils } from "../../services/AlephaCliUtils.ts";
|
|
6
|
+
|
|
7
|
+
export class GenEnvCommand {
|
|
8
|
+
protected readonly log = $logger();
|
|
9
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
10
|
+
protected readonly fs = $inject(FileSystemProvider);
|
|
11
|
+
|
|
12
|
+
public readonly command = $command({
|
|
13
|
+
name: "env",
|
|
14
|
+
description: "Extract environment variables from server entry file",
|
|
15
|
+
flags: t.object({
|
|
16
|
+
out: t.optional(
|
|
17
|
+
t.text({
|
|
18
|
+
aliases: ["o"],
|
|
19
|
+
description: "Output file path (e.g., .env)",
|
|
20
|
+
}),
|
|
21
|
+
),
|
|
22
|
+
}),
|
|
23
|
+
handler: async ({ root, flags }) => {
|
|
24
|
+
const { alepha } = await this.utils.loadAlephaFromServerEntryFile(root);
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const { env } = alepha.dump();
|
|
28
|
+
|
|
29
|
+
let dotEnvFile = "";
|
|
30
|
+
for (const [key, value] of Object.entries(env)) {
|
|
31
|
+
if (value.description) {
|
|
32
|
+
dotEnvFile += `# ${value.description.split("\n").join("\n# ")}\n`;
|
|
33
|
+
}
|
|
34
|
+
if (value.required && !value.default) {
|
|
35
|
+
dotEnvFile += `# (required)\n`;
|
|
36
|
+
}
|
|
37
|
+
if (value.enum) {
|
|
38
|
+
dotEnvFile += `# Possible values: ${value.enum.join(", ")}\n`;
|
|
39
|
+
}
|
|
40
|
+
dotEnvFile += `${key}=${value.default || ""}\n\n`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (flags.out) {
|
|
44
|
+
await this.fs.writeFile(this.fs.join(root, flags.out), dotEnvFile);
|
|
45
|
+
} else {
|
|
46
|
+
this.log.info(dotEnvFile);
|
|
47
|
+
}
|
|
48
|
+
} catch (err) {
|
|
49
|
+
this.log.error("Failed to extract environment variables", err);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TODO:
|
|
3
|
+
*
|
|
4
|
+
* alepha gen resource <name>
|
|
5
|
+
*
|
|
6
|
+
* will generate:
|
|
7
|
+
*
|
|
8
|
+
* src/api/controllers/<name>Controller.ts
|
|
9
|
+
* src/api/entity/<name>Entity.ts
|
|
10
|
+
* (maybe) src/api/services/<name>Service.ts
|
|
11
|
+
* (maybe) src/api/repositories/<name>Repository.ts
|
|
12
|
+
*
|
|
13
|
+
* Each file will contain a basic scaffold for the respective component.
|
|
14
|
+
*
|
|
15
|
+
*/
|
package/src/cli/commands/gen.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { $inject } from "alepha";
|
|
2
2
|
import { $command } from "alepha/command";
|
|
3
3
|
import { ChangelogCommand } from "./gen/changelog.ts";
|
|
4
|
+
import { GenEnvCommand } from "./gen/env.ts";
|
|
4
5
|
import { OpenApiCommand } from "./gen/openapi.ts";
|
|
5
6
|
|
|
6
7
|
export class GenCommand {
|
|
7
8
|
protected readonly changelog = $inject(ChangelogCommand);
|
|
8
9
|
protected readonly openapi = $inject(OpenApiCommand);
|
|
10
|
+
protected readonly genEnv = $inject(GenEnvCommand);
|
|
9
11
|
|
|
10
12
|
public readonly gen = $command({
|
|
11
13
|
name: "gen",
|
|
12
14
|
description: "Generate code, documentation, ...",
|
|
13
|
-
children: [
|
|
15
|
+
children: [
|
|
16
|
+
this.changelog.command,
|
|
17
|
+
this.openapi.command,
|
|
18
|
+
this.genEnv.command,
|
|
19
|
+
],
|
|
14
20
|
handler: async ({ help }) => {
|
|
15
21
|
help();
|
|
16
22
|
},
|
package/src/cli/commands/init.ts
CHANGED
package/src/cli/commands/test.ts
CHANGED
package/src/cli/defineConfig.ts
CHANGED
|
@@ -1,19 +1,61 @@
|
|
|
1
1
|
import type { Alepha } from "alepha";
|
|
2
2
|
import type { CommandPrimitive } from "alepha/command";
|
|
3
|
+
import { type BuildOptions, buildOptions } from "./atoms/buildOptions.ts";
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
+
export interface AlephaCliConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Add custom commands to the Alepha CLI.
|
|
8
|
+
*
|
|
9
|
+
* You can override 'deploy', 'build', 'dev', 'start' commands this way.
|
|
10
|
+
* But you can also add your own commands and run them via `alepha <command>`.
|
|
11
|
+
*/
|
|
5
12
|
commands?: Record<string, CommandPrimitive>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Register more services to the Alepha CLI (enhancements, commands, etc.).
|
|
16
|
+
*/
|
|
6
17
|
services?: Array<any>;
|
|
7
|
-
};
|
|
8
18
|
|
|
9
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Configure Alepha build command.
|
|
21
|
+
*/
|
|
22
|
+
build?: BuildOptions;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Environment variables to set before running commands.
|
|
26
|
+
*
|
|
27
|
+
* Always use .env files by default, this is only for dynamic values.
|
|
28
|
+
*/
|
|
29
|
+
env?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type AlephaCliConfigFn = (alepha: Alepha) => AlephaCliConfig;
|
|
33
|
+
|
|
34
|
+
export const defineConfig = (
|
|
35
|
+
runConfig: AlephaCliConfig | AlephaCliConfigFn,
|
|
36
|
+
) => {
|
|
10
37
|
return (alepha: Alepha) => {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
38
|
+
const config =
|
|
39
|
+
typeof runConfig === "function" ? runConfig(alepha) : runConfig;
|
|
40
|
+
|
|
41
|
+
if (config.services) {
|
|
42
|
+
for (const it of config.services) {
|
|
43
|
+
alepha.with(it);
|
|
44
|
+
}
|
|
14
45
|
}
|
|
46
|
+
|
|
47
|
+
if (config.env) {
|
|
48
|
+
for (const [key, value] of Object.entries(config.env)) {
|
|
49
|
+
process.env[key] = String(value);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (config.build) {
|
|
54
|
+
alepha.set(buildOptions, config.build);
|
|
55
|
+
}
|
|
56
|
+
|
|
15
57
|
return {
|
|
16
|
-
...commands,
|
|
58
|
+
...config.commands,
|
|
17
59
|
};
|
|
18
60
|
};
|
|
19
61
|
};
|
package/src/cli/index.ts
CHANGED
|
@@ -12,7 +12,6 @@ export * from "./commands/gen/openapi.ts";
|
|
|
12
12
|
export * from "./commands/init.ts";
|
|
13
13
|
export * from "./commands/lint.ts";
|
|
14
14
|
export * from "./commands/root.ts";
|
|
15
|
-
export * from "./commands/run.ts";
|
|
16
15
|
export * from "./commands/test.ts";
|
|
17
16
|
export * from "./commands/typecheck.ts";
|
|
18
17
|
export * from "./commands/verify.ts";
|
|
@@ -14,7 +14,6 @@ import { indexHtml } from "../assets/indexHtml.ts";
|
|
|
14
14
|
import { mainBrowserTs } from "../assets/mainBrowserTs.ts";
|
|
15
15
|
import { mainTs } from "../assets/mainTs.ts";
|
|
16
16
|
import { tsconfigJson } from "../assets/tsconfigJson.ts";
|
|
17
|
-
import { viteConfigTs } from "../assets/viteConfigTs.ts";
|
|
18
17
|
import { version } from "../version.ts";
|
|
19
18
|
|
|
20
19
|
/**
|
|
@@ -142,6 +141,33 @@ export class AlephaCliUtils {
|
|
|
142
141
|
// Package Manager & Project Setup
|
|
143
142
|
// ===================================================================================================================
|
|
144
143
|
|
|
144
|
+
public async editFile(
|
|
145
|
+
root: string,
|
|
146
|
+
name: string,
|
|
147
|
+
editFn: (content: string) => string | Promise<string>,
|
|
148
|
+
): Promise<void> {
|
|
149
|
+
const filePath = join(root, name);
|
|
150
|
+
try {
|
|
151
|
+
const content = await readFile(filePath, "utf8");
|
|
152
|
+
const newContent = await editFn(content);
|
|
153
|
+
await writeFile(filePath, newContent);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
this.log.debug("Could not edit file", error);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public async editJsonFile(
|
|
160
|
+
root: string,
|
|
161
|
+
name: string,
|
|
162
|
+
editFn: (obj: any) => any | Promise<any>,
|
|
163
|
+
): Promise<void> {
|
|
164
|
+
return await this.editFile(root, name, async (content) => {
|
|
165
|
+
const obj = JSON.parse(content);
|
|
166
|
+
const newObj = await editFn(obj);
|
|
167
|
+
return JSON.stringify(newObj, null, 2);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
145
171
|
public async removeFiles(root: string, files: string[]): Promise<void> {
|
|
146
172
|
await Promise.all(
|
|
147
173
|
files.map((file) =>
|
|
@@ -151,11 +177,17 @@ export class AlephaCliUtils {
|
|
|
151
177
|
}
|
|
152
178
|
|
|
153
179
|
public async removeYarn(root: string): Promise<void> {
|
|
154
|
-
await this.removeFiles(root, [".yarn", ".yarnrc.yml", ".
|
|
180
|
+
await this.removeFiles(root, [".yarn", ".yarnrc.yml", "yarn.lock"]);
|
|
181
|
+
await this.editJsonFile(root, "package.json", (pkg) => {
|
|
182
|
+
delete pkg.packageManager;
|
|
183
|
+
});
|
|
155
184
|
}
|
|
156
185
|
|
|
157
186
|
public async removePnpm(root: string): Promise<void> {
|
|
158
187
|
await this.removeFiles(root, ["pnpm-lock.yaml", "pnpm-workspace.yaml"]);
|
|
188
|
+
await this.editJsonFile(root, "package.json", (pkg) => {
|
|
189
|
+
delete pkg.packageManager;
|
|
190
|
+
});
|
|
159
191
|
}
|
|
160
192
|
|
|
161
193
|
public async removeNpm(root: string): Promise<void> {
|
|
@@ -163,7 +195,7 @@ export class AlephaCliUtils {
|
|
|
163
195
|
}
|
|
164
196
|
|
|
165
197
|
public async removeBun(root: string): Promise<void> {
|
|
166
|
-
await this.removeFiles(root, ["bun.lockb"]);
|
|
198
|
+
await this.removeFiles(root, ["bun.lockb", "bun.lock"]);
|
|
167
199
|
}
|
|
168
200
|
|
|
169
201
|
public async removeAllPmFilesExcept(
|
|
@@ -300,7 +332,6 @@ export class AlephaCliUtils {
|
|
|
300
332
|
opts: {
|
|
301
333
|
packageJson?: boolean | DependencyModes;
|
|
302
334
|
tsconfigJson?: boolean;
|
|
303
|
-
viteConfigTs?: boolean;
|
|
304
335
|
indexHtml?: boolean;
|
|
305
336
|
biomeJson?: boolean;
|
|
306
337
|
editorconfig?: boolean;
|
|
@@ -319,9 +350,6 @@ export class AlephaCliUtils {
|
|
|
319
350
|
if (opts.tsconfigJson) {
|
|
320
351
|
tasks.push(this.ensureTsConfig(root));
|
|
321
352
|
}
|
|
322
|
-
if (opts.viteConfigTs) {
|
|
323
|
-
tasks.push(this.ensureViteConfig(root));
|
|
324
|
-
}
|
|
325
353
|
if (opts.indexHtml) {
|
|
326
354
|
tasks.push(this.ensureIndexHtml(root));
|
|
327
355
|
}
|
|
@@ -346,23 +374,6 @@ export class AlephaCliUtils {
|
|
|
346
374
|
await this.ensureFileExists(root, "tsconfig.json", tsconfigJson, true);
|
|
347
375
|
}
|
|
348
376
|
|
|
349
|
-
/**
|
|
350
|
-
* Ensure vite.config.ts exists in the project.
|
|
351
|
-
*
|
|
352
|
-
* Creates a standard Alepha vite.config.ts if none exists.
|
|
353
|
-
*/
|
|
354
|
-
public async ensureViteConfig(
|
|
355
|
-
root: string,
|
|
356
|
-
serverEntry?: string,
|
|
357
|
-
): Promise<void> {
|
|
358
|
-
await this.ensureFileExists(
|
|
359
|
-
root,
|
|
360
|
-
"vite.config.ts",
|
|
361
|
-
viteConfigTs(serverEntry),
|
|
362
|
-
false,
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
377
|
protected async checkFileExists(
|
|
367
378
|
root: string,
|
|
368
379
|
name: string,
|
|
@@ -657,7 +668,7 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
|
|
|
657
668
|
async readPackageJson(root: string): Promise<Record<string, any>> {
|
|
658
669
|
const packageJson = await this.fs
|
|
659
670
|
.createFile({
|
|
660
|
-
path: join(root, "package.json"),
|
|
671
|
+
path: this.fs.join(root, "package.json"),
|
|
661
672
|
})
|
|
662
673
|
.text();
|
|
663
674
|
return JSON.parse(packageJson);
|
|
@@ -109,7 +109,7 @@ describe("Runner", () => {
|
|
|
109
109
|
await runner.run(`echo "Task 1"`);
|
|
110
110
|
await runner.run("A slightly longer task name", () => {});
|
|
111
111
|
|
|
112
|
-
runner.
|
|
112
|
+
runner.end();
|
|
113
113
|
|
|
114
114
|
const logs = mockLogger.logs
|
|
115
115
|
.slice(4)
|
|
@@ -118,7 +118,7 @@ describe("Runner", () => {
|
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
test("summary() should not print a table if no tasks were run", () => {
|
|
121
|
-
runner.
|
|
121
|
+
runner.end();
|
|
122
122
|
|
|
123
123
|
const logs = mockLogger.logs.map((l) => l.message);
|
|
124
124
|
expect(logs.length).toBe(0);
|
|
@@ -179,7 +179,7 @@ export class Runner {
|
|
|
179
179
|
/**
|
|
180
180
|
* Prints a summary of all executed tasks and their durations.
|
|
181
181
|
*/
|
|
182
|
-
public
|
|
182
|
+
public end(): void {
|
|
183
183
|
if (this.useDynamicLogger && this.firstTaskStarted) {
|
|
184
184
|
this.prettyPrint.endCommand();
|
|
185
185
|
return;
|
|
@@ -105,12 +105,6 @@ export interface CommandPrimitiveOptions<
|
|
|
105
105
|
*/
|
|
106
106
|
args?: A;
|
|
107
107
|
|
|
108
|
-
/**
|
|
109
|
-
* If false, skip summary message at the end of the command execution.
|
|
110
|
-
* Summary will display only if ({ run }) method calls were made.
|
|
111
|
-
*/
|
|
112
|
-
summary?: boolean;
|
|
113
|
-
|
|
114
108
|
/**
|
|
115
109
|
* Marks this command as the root command.
|
|
116
110
|
* Equivalent to setting name to an empty string "".
|
|
@@ -237,9 +237,7 @@ export class CliProvider {
|
|
|
237
237
|
await hook.options.handler(args as CommandHandlerArgs<TObject>);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
|
|
241
|
-
runner.summary();
|
|
242
|
-
}
|
|
240
|
+
runner.end();
|
|
243
241
|
|
|
244
242
|
this.log.debug(`Command '${command.name}' executed successfully.`);
|
|
245
243
|
});
|