alepha 0.14.1 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/api/audits/index.d.ts +342 -342
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +161 -161
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.d.ts +791 -791
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +4 -0
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +128 -128
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.js.map +1 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cli/index.d.ts +173 -167
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +427 -409
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +5 -5
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +7 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +7 -6
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/fake/index.js.map +1 -1
- package/dist/file/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.browser.js +26 -5
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.d.ts +115 -90
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +37 -12
- package/dist/orm/index.js.map +1 -1
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.js.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +28 -28
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +155 -155
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/cookies/index.browser.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/health/index.d.ts +17 -17
- package/dist/server/helmet/index.js.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/security/index.d.ts +9 -9
- package/dist/server/security/index.js.map +1 -1
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +7 -7
- package/dist/websocket/index.js.map +1 -1
- package/package.json +3 -3
- package/src/api/users/index.ts +4 -0
- package/src/cli/apps/AlephaCli.ts +31 -14
- package/src/cli/apps/AlephaPackageBuilderCli.ts +2 -1
- package/src/cli/assets/appRouterTs.ts +1 -1
- package/src/cli/commands/{ViteCommands.ts → build.ts} +2 -105
- package/src/cli/commands/{ChangelogCommands.ts → changelog.ts} +7 -22
- package/src/cli/commands/clean.ts +14 -0
- package/src/cli/commands/{DrizzleCommands.ts → db.ts} +10 -117
- package/src/cli/commands/{DeployCommands.ts → deploy.ts} +1 -1
- package/src/cli/commands/dev.ts +57 -0
- package/src/cli/commands/format.ts +17 -0
- package/src/cli/commands/{CoreCommands.ts → init.ts} +2 -40
- package/src/cli/commands/lint.ts +17 -0
- package/src/cli/commands/root.ts +32 -0
- package/src/cli/commands/run.ts +24 -0
- package/src/cli/commands/test.ts +42 -0
- package/src/cli/commands/typecheck.ts +19 -0
- package/src/cli/commands/{VerifyCommands.ts → verify.ts} +1 -13
- package/src/cli/defineConfig.ts +10 -1
- package/src/cli/index.ts +16 -7
- package/src/cli/services/GitMessageParser.ts +1 -1
- package/src/core/Alepha.ts +7 -4
- package/src/orm/index.browser.ts +1 -1
- package/src/orm/index.ts +10 -6
- package/src/orm/providers/{PostgresTypeProvider.ts → DatabaseTypeProvider.ts} +25 -3
- package/src/cli/commands/BiomeCommands.ts +0 -29
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { access, readFile, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { $
|
|
4
|
+
import { $inject, OPTIONS, t } from "alepha";
|
|
5
5
|
import { $command } from "alepha/command";
|
|
6
6
|
import { $logger } from "alepha/logger";
|
|
7
7
|
import {
|
|
@@ -18,78 +18,10 @@ import {
|
|
|
18
18
|
import type * as Vite from "vite";
|
|
19
19
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
20
20
|
|
|
21
|
-
export class
|
|
21
|
+
export class BuildCommand {
|
|
22
22
|
protected readonly log = $logger();
|
|
23
23
|
protected readonly utils = $inject(AlephaCliUtils);
|
|
24
24
|
|
|
25
|
-
protected readonly env = $env(
|
|
26
|
-
t.object({
|
|
27
|
-
VITEST_ARGS: t.string({ default: "" }),
|
|
28
|
-
}),
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
public readonly run = $command({
|
|
32
|
-
name: "run",
|
|
33
|
-
hide: true,
|
|
34
|
-
description: "Run a TypeScript file directly",
|
|
35
|
-
flags: t.object({
|
|
36
|
-
watch: t.optional(
|
|
37
|
-
t.boolean({ description: "Watch file for changes", alias: "w" }),
|
|
38
|
-
),
|
|
39
|
-
}),
|
|
40
|
-
summary: false,
|
|
41
|
-
args: t.text({ title: "path", description: "Filepath to run" }),
|
|
42
|
-
handler: async ({ args, flags, root }) => {
|
|
43
|
-
await this.utils.ensureTsConfig(root);
|
|
44
|
-
await this.utils.exec(`tsx ${flags.watch ? "watch " : ""}${args}`);
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Will run the project in watch mode.
|
|
50
|
-
*
|
|
51
|
-
* - If an index.html file is found in the project root, it will run Vite in dev mode.
|
|
52
|
-
* - Otherwise, it will look for a server entry file and run it with tsx in watch mode.
|
|
53
|
-
*/
|
|
54
|
-
public readonly dev = $command({
|
|
55
|
-
name: "dev",
|
|
56
|
-
description: "Run the project in development mode",
|
|
57
|
-
args: t.optional(t.text({ title: "path", description: "Filepath to run" })),
|
|
58
|
-
handler: async ({ args, root }) => {
|
|
59
|
-
const expo = await this.utils.hasExpo(root);
|
|
60
|
-
|
|
61
|
-
await this.utils.ensureConfig(root, {
|
|
62
|
-
viteConfigTs: !expo,
|
|
63
|
-
tsconfigJson: true,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
if (expo) {
|
|
67
|
-
await this.utils.exec(`expo start`);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const entry = await boot.getServerEntry(root, args);
|
|
72
|
-
this.log.trace("Entry file found", { entry });
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
await access(join(root, "index.html"));
|
|
76
|
-
} catch {
|
|
77
|
-
this.log.trace("No index.html found, running entry file with tsx");
|
|
78
|
-
let cmd = "tsx --watch";
|
|
79
|
-
if (await this.utils.exists(root, ".env")) {
|
|
80
|
-
cmd += ` --env-file=./.env`;
|
|
81
|
-
}
|
|
82
|
-
cmd += ` ${entry}`;
|
|
83
|
-
await this.utils.exec(cmd);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Ensure vite is installed before running
|
|
88
|
-
await this.utils.ensureDependency(root, "vite");
|
|
89
|
-
await this.utils.exec(`vite`);
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
|
|
93
25
|
public readonly build = $command({
|
|
94
26
|
name: "build",
|
|
95
27
|
description: "Build the project for production",
|
|
@@ -313,39 +245,4 @@ export class ViteCommands {
|
|
|
313
245
|
}
|
|
314
246
|
},
|
|
315
247
|
});
|
|
316
|
-
|
|
317
|
-
public readonly test = $command({
|
|
318
|
-
name: "test",
|
|
319
|
-
description: "Run tests using Vitest",
|
|
320
|
-
flags: t.object({
|
|
321
|
-
config: t.optional(
|
|
322
|
-
t.string({
|
|
323
|
-
description: "Path to Vitest config file",
|
|
324
|
-
alias: "c",
|
|
325
|
-
}),
|
|
326
|
-
),
|
|
327
|
-
}),
|
|
328
|
-
env: t.object({
|
|
329
|
-
VITEST_ARGS: t.optional(
|
|
330
|
-
t.string({
|
|
331
|
-
default: "",
|
|
332
|
-
description:
|
|
333
|
-
"Additional arguments to pass to Vitest. E.g., --coverage",
|
|
334
|
-
}),
|
|
335
|
-
),
|
|
336
|
-
}),
|
|
337
|
-
handler: async ({ root, flags, env }) => {
|
|
338
|
-
await this.utils.ensureConfig(root, {
|
|
339
|
-
tsconfigJson: true,
|
|
340
|
-
viteConfigTs: true,
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
// Ensure vitest is installed before running
|
|
344
|
-
await this.utils.ensureDependency(root, "vitest");
|
|
345
|
-
|
|
346
|
-
const config = flags.config ? `--config=${flags.config}` : "";
|
|
347
|
-
|
|
348
|
-
await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);
|
|
349
|
-
},
|
|
350
|
-
});
|
|
351
248
|
}
|
|
@@ -45,11 +45,10 @@ export interface Commit {
|
|
|
45
45
|
interface ChangelogEntry {
|
|
46
46
|
features: Commit[];
|
|
47
47
|
fixes: Commit[];
|
|
48
|
-
breaking: Commit[];
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
// =============================================================================
|
|
52
|
-
// CHANGELOG
|
|
51
|
+
// CHANGELOG COMMAND
|
|
53
52
|
// =============================================================================
|
|
54
53
|
|
|
55
54
|
/**
|
|
@@ -61,7 +60,7 @@ interface ChangelogEntry {
|
|
|
61
60
|
* - `alepha changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs
|
|
62
61
|
* - `alepha changelog | tee -a CHANGELOG.md` - Append to file
|
|
63
62
|
*/
|
|
64
|
-
export class
|
|
63
|
+
export class ChangelogCommand {
|
|
65
64
|
protected readonly log = $logger();
|
|
66
65
|
protected readonly git = $inject(GitProvider);
|
|
67
66
|
protected readonly parser = $inject(GitMessageParser);
|
|
@@ -74,9 +73,11 @@ export class ChangelogCommands {
|
|
|
74
73
|
/**
|
|
75
74
|
* Format a single commit line.
|
|
76
75
|
* Example: `- **cli**: add new command (\`abc1234\`)`
|
|
76
|
+
* Breaking changes are flagged: `- **cli**: add new command [BREAKING] (\`abc1234\`)`
|
|
77
77
|
*/
|
|
78
78
|
protected formatCommit(commit: Commit): string {
|
|
79
|
-
|
|
79
|
+
const breaking = commit.breaking ? " [BREAKING]" : "";
|
|
80
|
+
return `- **${commit.scope}**: ${commit.description}${breaking} (\`${commit.hash}\`)`;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
/**
|
|
@@ -85,14 +86,6 @@ export class ChangelogCommands {
|
|
|
85
86
|
protected formatEntry(entry: ChangelogEntry): string {
|
|
86
87
|
const sections: string[] = [];
|
|
87
88
|
|
|
88
|
-
if (entry.breaking.length > 0) {
|
|
89
|
-
sections.push("### Breaking Changes\n");
|
|
90
|
-
for (const commit of entry.breaking) {
|
|
91
|
-
sections.push(this.formatCommit(commit));
|
|
92
|
-
}
|
|
93
|
-
sections.push("");
|
|
94
|
-
}
|
|
95
|
-
|
|
96
89
|
if (entry.features.length > 0) {
|
|
97
90
|
sections.push("### Features\n");
|
|
98
91
|
for (const commit of entry.features) {
|
|
@@ -123,7 +116,6 @@ export class ChangelogCommands {
|
|
|
123
116
|
const entry: ChangelogEntry = {
|
|
124
117
|
features: [],
|
|
125
118
|
fixes: [],
|
|
126
|
-
breaking: [],
|
|
127
119
|
};
|
|
128
120
|
|
|
129
121
|
for (const line of commitsOutput.trim().split("\n")) {
|
|
@@ -137,10 +129,7 @@ export class ChangelogCommands {
|
|
|
137
129
|
|
|
138
130
|
this.log.trace("Parsed commit", { commit });
|
|
139
131
|
|
|
140
|
-
// Categorize commit
|
|
141
|
-
if (commit.breaking) {
|
|
142
|
-
entry.breaking.push(commit);
|
|
143
|
-
}
|
|
132
|
+
// Categorize commit (breaking flag is preserved on the commit itself)
|
|
144
133
|
if (commit.type === "feat") {
|
|
145
134
|
entry.features.push(commit);
|
|
146
135
|
} else if (commit.type === "fix") {
|
|
@@ -155,11 +144,7 @@ export class ChangelogCommands {
|
|
|
155
144
|
* Check if entry has any public commits.
|
|
156
145
|
*/
|
|
157
146
|
protected hasChanges(entry: ChangelogEntry): boolean {
|
|
158
|
-
return
|
|
159
|
-
entry.features.length > 0 ||
|
|
160
|
-
entry.fixes.length > 0 ||
|
|
161
|
-
entry.breaking.length > 0
|
|
162
|
-
);
|
|
147
|
+
return entry.features.length > 0 || entry.fixes.length > 0;
|
|
163
148
|
}
|
|
164
149
|
|
|
165
150
|
/**
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { $command } from "alepha/command";
|
|
2
|
+
|
|
3
|
+
export class CleanCommand {
|
|
4
|
+
/**
|
|
5
|
+
* Clean the project, removing the "dist" directory
|
|
6
|
+
*/
|
|
7
|
+
public readonly clean = $command({
|
|
8
|
+
name: "clean",
|
|
9
|
+
description: "Clean the project",
|
|
10
|
+
handler: async ({ run }) => {
|
|
11
|
+
await run.rm("./dist");
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -25,14 +25,14 @@ const drizzleCommandFlags = t.object({
|
|
|
25
25
|
),
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
export class
|
|
29
|
-
log = $logger();
|
|
30
|
-
utils = $inject(AlephaCliUtils);
|
|
28
|
+
export class DbCommand {
|
|
29
|
+
protected readonly log = $logger();
|
|
30
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Check if database migrations are up to date.
|
|
34
34
|
*/
|
|
35
|
-
check = $command({
|
|
35
|
+
protected readonly check = $command({
|
|
36
36
|
name: "check-migrations",
|
|
37
37
|
description: "Check if database migration files are up to date",
|
|
38
38
|
args: t.optional(
|
|
@@ -74,7 +74,7 @@ export class DrizzleCommands {
|
|
|
74
74
|
).catch(() => null);
|
|
75
75
|
|
|
76
76
|
if (!journalFile) {
|
|
77
|
-
this.log.info(
|
|
77
|
+
this.log.info("No migration journal found.");
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -130,14 +130,8 @@ export class DrizzleCommands {
|
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
132
|
* Generate database migration files
|
|
133
|
-
*
|
|
134
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
135
|
-
* - Retrieves all repository primitives to gather database models.
|
|
136
|
-
* - Creates temporary entity definitions based on the current database schema.
|
|
137
|
-
* - Writes these definitions to a temporary schema file. (node_modules/.db/entities.ts)
|
|
138
|
-
* - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.
|
|
139
133
|
*/
|
|
140
|
-
generate = $command({
|
|
134
|
+
protected readonly generate = $command({
|
|
141
135
|
name: "generate",
|
|
142
136
|
description: "Generate migration files based on current database schema",
|
|
143
137
|
summary: false,
|
|
@@ -175,13 +169,8 @@ export class DrizzleCommands {
|
|
|
175
169
|
|
|
176
170
|
/**
|
|
177
171
|
* Push database schema changes directly to the database
|
|
178
|
-
*
|
|
179
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
180
|
-
* - Retrieves all repository primitives to gather database models.
|
|
181
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
182
|
-
* - Invokes Drizzle Kit's push command to apply schema changes directly.
|
|
183
172
|
*/
|
|
184
|
-
push = $command({
|
|
173
|
+
protected readonly push = $command({
|
|
185
174
|
name: "push",
|
|
186
175
|
description: "Push database schema changes directly to the database",
|
|
187
176
|
summary: false,
|
|
@@ -207,13 +196,8 @@ export class DrizzleCommands {
|
|
|
207
196
|
|
|
208
197
|
/**
|
|
209
198
|
* Apply pending database migrations
|
|
210
|
-
*
|
|
211
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
212
|
-
* - Retrieves all repository primitives to gather database models.
|
|
213
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
214
|
-
* - Invokes Drizzle Kit's migrate command to apply pending migrations.
|
|
215
199
|
*/
|
|
216
|
-
migrate = $command({
|
|
200
|
+
protected readonly migrate = $command({
|
|
217
201
|
name: "migrate",
|
|
218
202
|
description: "Apply pending database migrations",
|
|
219
203
|
summary: false,
|
|
@@ -239,13 +223,8 @@ export class DrizzleCommands {
|
|
|
239
223
|
|
|
240
224
|
/**
|
|
241
225
|
* Launch Drizzle Studio database browser
|
|
242
|
-
*
|
|
243
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
244
|
-
* - Retrieves all repository primitives to gather database models.
|
|
245
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
246
|
-
* - Invokes Drizzle Kit's studio command to launch the web-based database browser.
|
|
247
226
|
*/
|
|
248
|
-
studio = $command({
|
|
227
|
+
protected readonly studio = $command({
|
|
249
228
|
name: "studio",
|
|
250
229
|
description: "Launch Drizzle Studio database browser",
|
|
251
230
|
summary: false,
|
|
@@ -272,7 +251,7 @@ export class DrizzleCommands {
|
|
|
272
251
|
/**
|
|
273
252
|
* Parent command for database operations.
|
|
274
253
|
*/
|
|
275
|
-
db = $command({
|
|
254
|
+
public readonly db = $command({
|
|
276
255
|
name: "db",
|
|
277
256
|
description: "Database management commands",
|
|
278
257
|
children: [this.check, this.generate, this.push, this.migrate, this.studio],
|
|
@@ -283,11 +262,6 @@ export class DrizzleCommands {
|
|
|
283
262
|
|
|
284
263
|
/**
|
|
285
264
|
* Run a drizzle-kit command for all database providers in an Alepha instance.
|
|
286
|
-
*
|
|
287
|
-
* Iterates through all repository providers, prepares Drizzle config for each,
|
|
288
|
-
* and executes the specified drizzle-kit command.
|
|
289
|
-
*
|
|
290
|
-
* @param options - Configuration including command to run, flags, and logging
|
|
291
265
|
*/
|
|
292
266
|
public async runDrizzleKitCommand(options: {
|
|
293
267
|
root: string;
|
|
@@ -365,12 +339,6 @@ export class DrizzleCommands {
|
|
|
365
339
|
|
|
366
340
|
/**
|
|
367
341
|
* Prepare Drizzle configuration files for a database provider.
|
|
368
|
-
*
|
|
369
|
-
* Creates temporary entities.js and drizzle.config.js files needed
|
|
370
|
-
* for Drizzle Kit commands to run properly.
|
|
371
|
-
*
|
|
372
|
-
* @param options - Configuration options including kit, provider info, and paths
|
|
373
|
-
* @returns Path to the generated drizzle.config.js file
|
|
374
342
|
*/
|
|
375
343
|
public async prepareDrizzleConfig(options: {
|
|
376
344
|
kit: any;
|
|
@@ -473,79 +441,4 @@ export class DrizzleCommands {
|
|
|
473
441
|
options.rootDir,
|
|
474
442
|
);
|
|
475
443
|
}
|
|
476
|
-
|
|
477
|
-
// /**
|
|
478
|
-
// * Drop database schema (development only)
|
|
479
|
-
// *
|
|
480
|
-
// * @experimental
|
|
481
|
-
// */
|
|
482
|
-
// drop = $command({
|
|
483
|
-
// name: "db:drop",
|
|
484
|
-
// description: "Drop database schema (development only)",
|
|
485
|
-
// summary: false,
|
|
486
|
-
// args: t.optional(
|
|
487
|
-
// t.text({
|
|
488
|
-
// title: "path",
|
|
489
|
-
// description: "Path to the Alepha server entry file",
|
|
490
|
-
// }),
|
|
491
|
-
// ),
|
|
492
|
-
// flags: drizzleCommandFlags,
|
|
493
|
-
// handler: async ({ flags }) => {
|
|
494
|
-
// // TODO: Implement db:drop
|
|
495
|
-
// this.log.warn("db:drop is not yet implemented");
|
|
496
|
-
// if (flags.provider) {
|
|
497
|
-
// this.log.info(`Provider filter: ${flags.provider}`);
|
|
498
|
-
// }
|
|
499
|
-
// },
|
|
500
|
-
// });
|
|
501
|
-
//
|
|
502
|
-
// /**
|
|
503
|
-
// * Seed database with initial data
|
|
504
|
-
// *
|
|
505
|
-
// * @experimental
|
|
506
|
-
// */
|
|
507
|
-
// seed = $command({
|
|
508
|
-
// name: "db:seed",
|
|
509
|
-
// description: "Seed database with initial data",
|
|
510
|
-
// summary: false,
|
|
511
|
-
// args: t.optional(
|
|
512
|
-
// t.text({
|
|
513
|
-
// title: "path",
|
|
514
|
-
// description: "Path to the Alepha server entry file",
|
|
515
|
-
// }),
|
|
516
|
-
// ),
|
|
517
|
-
// flags: drizzleCommandFlags,
|
|
518
|
-
// handler: async ({ flags }) => {
|
|
519
|
-
// // TODO: Implement db:seed
|
|
520
|
-
// this.log.warn("db:seed is not yet implemented");
|
|
521
|
-
// if (flags.provider) {
|
|
522
|
-
// this.log.info(`Provider filter: ${flags.provider}`);
|
|
523
|
-
// }
|
|
524
|
-
// },
|
|
525
|
-
// });
|
|
526
|
-
//
|
|
527
|
-
// /**
|
|
528
|
-
// * Show pending database migrations status
|
|
529
|
-
// *
|
|
530
|
-
// * @experimental
|
|
531
|
-
// */
|
|
532
|
-
// status = $command({
|
|
533
|
-
// name: "db:status",
|
|
534
|
-
// description: "Show pending database migrations status",
|
|
535
|
-
// summary: false,
|
|
536
|
-
// args: t.optional(
|
|
537
|
-
// t.text({
|
|
538
|
-
// title: "path",
|
|
539
|
-
// description: "Path to the Alepha server entry file",
|
|
540
|
-
// }),
|
|
541
|
-
// ),
|
|
542
|
-
// flags: drizzleCommandFlags,
|
|
543
|
-
// handler: async ({ flags }) => {
|
|
544
|
-
// // TODO: Implement db:status
|
|
545
|
-
// this.log.warn("db:status is not yet implemented");
|
|
546
|
-
// if (flags.provider) {
|
|
547
|
-
// this.log.info(`Provider filter: ${flags.provider}`);
|
|
548
|
-
// }
|
|
549
|
-
// },
|
|
550
|
-
// });
|
|
551
444
|
}
|
|
@@ -4,7 +4,7 @@ import { $command } from "alepha/command";
|
|
|
4
4
|
import { $logger } from "alepha/logger";
|
|
5
5
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
6
6
|
|
|
7
|
-
export class
|
|
7
|
+
export class DeployCommand {
|
|
8
8
|
protected readonly log = $logger();
|
|
9
9
|
protected readonly utils = $inject(AlephaCliUtils);
|
|
10
10
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { $inject, t } from "alepha";
|
|
4
|
+
import { $command } from "alepha/command";
|
|
5
|
+
import { $logger } from "alepha/logger";
|
|
6
|
+
import { boot } from "alepha/vite";
|
|
7
|
+
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
8
|
+
|
|
9
|
+
export class DevCommand {
|
|
10
|
+
protected readonly log = $logger();
|
|
11
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Will run the project in watch mode.
|
|
15
|
+
*
|
|
16
|
+
* - If an index.html file is found in the project root, it will run Vite in dev mode.
|
|
17
|
+
* - Otherwise, it will look for a server entry file and run it with tsx in watch mode.
|
|
18
|
+
*/
|
|
19
|
+
public readonly dev = $command({
|
|
20
|
+
name: "dev",
|
|
21
|
+
description: "Run the project in development mode",
|
|
22
|
+
args: t.optional(t.text({ title: "path", description: "Filepath to run" })),
|
|
23
|
+
handler: async ({ args, root }) => {
|
|
24
|
+
const expo = await this.utils.hasExpo(root);
|
|
25
|
+
|
|
26
|
+
await this.utils.ensureConfig(root, {
|
|
27
|
+
viteConfigTs: !expo,
|
|
28
|
+
tsconfigJson: true,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (expo) {
|
|
32
|
+
await this.utils.exec("expo start");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const entry = await boot.getServerEntry(root, args);
|
|
37
|
+
this.log.trace("Entry file found", { entry });
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await access(join(root, "index.html"));
|
|
41
|
+
} catch {
|
|
42
|
+
this.log.trace("No index.html found, running entry file with tsx");
|
|
43
|
+
let cmd = "tsx --watch";
|
|
44
|
+
if (await this.utils.exists(root, ".env")) {
|
|
45
|
+
cmd += " --env-file=./.env";
|
|
46
|
+
}
|
|
47
|
+
cmd += ` ${entry}`;
|
|
48
|
+
await this.utils.exec(cmd);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Ensure vite is installed before running
|
|
53
|
+
await this.utils.ensureDependency(root, "vite");
|
|
54
|
+
await this.utils.exec("vite");
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { $inject } from "alepha";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
3
|
+
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
4
|
+
|
|
5
|
+
export class FormatCommand {
|
|
6
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
7
|
+
|
|
8
|
+
public readonly format = $command({
|
|
9
|
+
name: "format",
|
|
10
|
+
description: "Format the codebase using Biome",
|
|
11
|
+
handler: async ({ root }) => {
|
|
12
|
+
await this.utils.ensureConfig(root, { biomeJson: true });
|
|
13
|
+
await this.utils.ensureDependency(root, "@biomejs/biome");
|
|
14
|
+
await this.utils.exec("biome format --fix");
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -1,48 +1,10 @@
|
|
|
1
1
|
import { $inject, t } from "alepha";
|
|
2
|
-
import { $command
|
|
3
|
-
import { $logger } from "alepha/logger";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
4
3
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
5
|
-
import { version } from "../version.ts";
|
|
6
4
|
|
|
7
|
-
export class
|
|
8
|
-
protected readonly log = $logger();
|
|
9
|
-
protected readonly cli = $inject(CliProvider);
|
|
5
|
+
export class InitCommand {
|
|
10
6
|
protected readonly utils = $inject(AlephaCliUtils);
|
|
11
7
|
|
|
12
|
-
/**
|
|
13
|
-
* Called when no command is provided
|
|
14
|
-
*/
|
|
15
|
-
public readonly root = $command({
|
|
16
|
-
root: true,
|
|
17
|
-
flags: t.object({
|
|
18
|
-
version: t.optional(
|
|
19
|
-
t.boolean({
|
|
20
|
-
description: "Show Alepha CLI version",
|
|
21
|
-
aliases: ["v"],
|
|
22
|
-
}),
|
|
23
|
-
),
|
|
24
|
-
}),
|
|
25
|
-
handler: async ({ flags }) => {
|
|
26
|
-
if (flags.version) {
|
|
27
|
-
this.log.info(version);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
this.cli.printHelp();
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Clean the project, removing the "dist" directory
|
|
37
|
-
*/
|
|
38
|
-
public readonly clean = $command({
|
|
39
|
-
name: "clean",
|
|
40
|
-
description: "Clean the project",
|
|
41
|
-
handler: async ({ run }) => {
|
|
42
|
-
await run.rm("./dist");
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
8
|
/**
|
|
47
9
|
* Ensure the project has the necessary Alepha configuration files.
|
|
48
10
|
* Add the correct dependencies to package.json and install them.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { $inject } from "alepha";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
3
|
+
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
4
|
+
|
|
5
|
+
export class LintCommand {
|
|
6
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
7
|
+
|
|
8
|
+
public readonly lint = $command({
|
|
9
|
+
name: "lint",
|
|
10
|
+
description: "Run linter across the codebase using Biome",
|
|
11
|
+
handler: async ({ root }) => {
|
|
12
|
+
await this.utils.ensureConfig(root, { biomeJson: true });
|
|
13
|
+
await this.utils.ensureDependency(root, "@biomejs/biome");
|
|
14
|
+
await this.utils.exec("biome check --formatter-enabled=false --fix");
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { $inject, t } from "alepha";
|
|
2
|
+
import { $command, CliProvider } from "alepha/command";
|
|
3
|
+
import { $logger } from "alepha/logger";
|
|
4
|
+
import { version } from "../version.ts";
|
|
5
|
+
|
|
6
|
+
export class RootCommand {
|
|
7
|
+
protected readonly log = $logger();
|
|
8
|
+
protected readonly cli = $inject(CliProvider);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Called when no command is provided
|
|
12
|
+
*/
|
|
13
|
+
public readonly root = $command({
|
|
14
|
+
root: true,
|
|
15
|
+
flags: t.object({
|
|
16
|
+
version: t.optional(
|
|
17
|
+
t.boolean({
|
|
18
|
+
description: "Show Alepha CLI version",
|
|
19
|
+
aliases: ["v"],
|
|
20
|
+
}),
|
|
21
|
+
),
|
|
22
|
+
}),
|
|
23
|
+
handler: async ({ flags }) => {
|
|
24
|
+
if (flags.version) {
|
|
25
|
+
this.log.info(version);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this.cli.printHelp();
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { $inject, t } from "alepha";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
3
|
+
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
4
|
+
|
|
5
|
+
export class RunCommand {
|
|
6
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
7
|
+
|
|
8
|
+
public readonly run = $command({
|
|
9
|
+
name: "run",
|
|
10
|
+
hide: true,
|
|
11
|
+
description: "Run a TypeScript file directly",
|
|
12
|
+
flags: t.object({
|
|
13
|
+
watch: t.optional(
|
|
14
|
+
t.boolean({ description: "Watch file for changes", alias: "w" }),
|
|
15
|
+
),
|
|
16
|
+
}),
|
|
17
|
+
summary: false,
|
|
18
|
+
args: t.text({ title: "path", description: "Filepath to run" }),
|
|
19
|
+
handler: async ({ args, flags, root }) => {
|
|
20
|
+
await this.utils.ensureTsConfig(root);
|
|
21
|
+
await this.utils.exec(`tsx ${flags.watch ? "watch " : ""}${args}`);
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { $inject, t } from "alepha";
|
|
2
|
+
import { $command } from "alepha/command";
|
|
3
|
+
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
4
|
+
|
|
5
|
+
export class TestCommand {
|
|
6
|
+
protected readonly utils = $inject(AlephaCliUtils);
|
|
7
|
+
|
|
8
|
+
public readonly test = $command({
|
|
9
|
+
name: "test",
|
|
10
|
+
description: "Run tests using Vitest",
|
|
11
|
+
flags: t.object({
|
|
12
|
+
config: t.optional(
|
|
13
|
+
t.string({
|
|
14
|
+
description: "Path to Vitest config file",
|
|
15
|
+
alias: "c",
|
|
16
|
+
}),
|
|
17
|
+
),
|
|
18
|
+
}),
|
|
19
|
+
env: t.object({
|
|
20
|
+
VITEST_ARGS: t.optional(
|
|
21
|
+
t.string({
|
|
22
|
+
default: "",
|
|
23
|
+
description:
|
|
24
|
+
"Additional arguments to pass to Vitest. E.g., --coverage",
|
|
25
|
+
}),
|
|
26
|
+
),
|
|
27
|
+
}),
|
|
28
|
+
handler: async ({ root, flags, env }) => {
|
|
29
|
+
await this.utils.ensureConfig(root, {
|
|
30
|
+
tsconfigJson: true,
|
|
31
|
+
viteConfigTs: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Ensure vitest is installed before running
|
|
35
|
+
await this.utils.ensureDependency(root, "vitest");
|
|
36
|
+
|
|
37
|
+
const config = flags.config ? `--config=${flags.config}` : "";
|
|
38
|
+
|
|
39
|
+
await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|