alepha 0.14.0 → 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 +80 -1
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +80 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +236 -157
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +21 -1
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +451 -4
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.d.ts +252 -249
- 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 +304 -115
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +650 -531
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +210 -13
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +306 -69
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +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.d.ts.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 +294 -215
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +522 -523
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/redis/index.js +2 -4
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/redis/index.d.ts +400 -29
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +412 -21
- 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.js.map +1 -1
- 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.d.ts +0 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/helmet/index.d.ts +4 -1
- package/dist/server/helmet/index.d.ts.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/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/topic/redis/index.js +3 -3
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/vite/index.js +9 -6
- 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 +36 -14
- package/src/cli/apps/AlephaPackageBuilderCli.ts +5 -1
- package/src/cli/assets/appRouterTs.ts +1 -1
- package/src/cli/atoms/changelogOptions.ts +45 -0
- package/src/cli/commands/{ViteCommands.ts → build.ts} +4 -93
- package/src/cli/commands/changelog.ts +244 -0
- package/src/cli/commands/clean.ts +14 -0
- package/src/cli/commands/{DrizzleCommands.ts → db.ts} +37 -124
- package/src/cli/commands/deploy.ts +118 -0
- 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 +24 -0
- package/src/cli/index.ts +17 -5
- package/src/cli/services/AlephaCliUtils.ts +4 -21
- package/src/cli/services/GitMessageParser.ts +77 -0
- package/src/command/helpers/EnvUtils.ts +37 -0
- package/src/command/index.ts +3 -1
- package/src/command/primitives/$command.ts +172 -6
- package/src/command/providers/CliProvider.ts +424 -91
- package/src/core/Alepha.ts +8 -5
- package/src/file/providers/NodeFileSystemProvider.ts +3 -1
- package/src/orm/index.browser.ts +1 -1
- package/src/orm/index.ts +18 -10
- package/src/orm/interfaces/PgQueryWhere.ts +1 -26
- package/src/orm/providers/{PostgresTypeProvider.ts → DatabaseTypeProvider.ts} +25 -3
- package/src/orm/providers/drivers/BunPostgresProvider.ts +225 -0
- package/src/orm/providers/drivers/BunSqliteProvider.ts +180 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +25 -0
- package/src/orm/providers/drivers/NodePostgresProvider.ts +0 -25
- package/src/orm/services/QueryManager.ts +10 -125
- package/src/queue/redis/providers/RedisQueueProvider.ts +2 -7
- package/src/redis/index.ts +65 -3
- package/src/redis/providers/BunRedisProvider.ts +304 -0
- package/src/redis/providers/BunRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/NodeRedisProvider.ts +280 -0
- package/src/redis/providers/NodeRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/RedisProvider.ts +134 -140
- package/src/redis/providers/RedisSubscriberProvider.ts +58 -49
- package/src/server/core/providers/BunHttpServerProvider.ts +0 -3
- package/src/server/core/providers/ServerBodyParserProvider.ts +3 -1
- package/src/server/core/providers/ServerProvider.ts +7 -4
- package/src/server/multipart/providers/ServerMultipartProvider.ts +3 -1
- package/src/server/proxy/providers/ServerProxyProvider.ts +1 -1
- package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
- package/src/vite/tasks/buildServer.ts +1 -0
- package/src/cli/commands/BiomeCommands.ts +0 -29
- package/src/cli/commands/ChangelogCommands.ts +0 -389
- package/src/orm/services/PgJsonQueryManager.ts +0 -511
package/dist/cli/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { $
|
|
3
|
+
import { $atom, $hook, $inject, $module, $use, Alepha, AlephaError, OPTIONS, t } from "alepha";
|
|
4
4
|
import { FileSystemProvider } from "alepha/file";
|
|
5
|
-
import { $command, CliProvider } from "alepha/command";
|
|
6
|
-
import { $logger } from "alepha/logger";
|
|
7
|
-
import { exec, spawn } from "node:child_process";
|
|
8
5
|
import { access, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
|
|
6
|
+
import { $command, CliProvider, EnvUtils } from "alepha/command";
|
|
7
|
+
import { $logger } from "alepha/logger";
|
|
9
8
|
import { boot, buildClient, buildServer, copyAssets, generateCloudflare, generateDocker, generateSitemap, generateVercel, prerenderPages } from "alepha/vite";
|
|
9
|
+
import { exec, spawn } from "node:child_process";
|
|
10
10
|
import { tsImport } from "tsx/esm/api";
|
|
11
11
|
import { readFileSync } from "node:fs";
|
|
12
12
|
import { promisify } from "node:util";
|
|
@@ -14,7 +14,7 @@ import * as os from "node:os";
|
|
|
14
14
|
|
|
15
15
|
//#region ../../src/cli/assets/appRouterTs.ts
|
|
16
16
|
const appRouterTs = () => `
|
|
17
|
-
import { $page } from "@alepha/react";
|
|
17
|
+
import { $page } from "@alepha/react/router";
|
|
18
18
|
|
|
19
19
|
export class AppRouter {
|
|
20
20
|
home = $page({
|
|
@@ -173,6 +173,7 @@ const version = packageJson.version;
|
|
|
173
173
|
var AlephaCliUtils = class {
|
|
174
174
|
log = $logger();
|
|
175
175
|
fs = $inject(FileSystemProvider);
|
|
176
|
+
envUtils = $inject(EnvUtils);
|
|
176
177
|
/**
|
|
177
178
|
* Execute a command using npx with inherited stdio.
|
|
178
179
|
*
|
|
@@ -461,23 +462,8 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
|
|
|
461
462
|
* Reads the .env file in the specified root directory and sets
|
|
462
463
|
* the environment variables in process.env.
|
|
463
464
|
*/
|
|
464
|
-
async
|
|
465
|
-
|
|
466
|
-
const envPath = join(root, file);
|
|
467
|
-
try {
|
|
468
|
-
const lines = (await readFile(envPath, "utf8")).split("\n");
|
|
469
|
-
for (const line of lines) {
|
|
470
|
-
const [key, ...rest] = line.split("=");
|
|
471
|
-
if (key) {
|
|
472
|
-
const value = rest.join("=");
|
|
473
|
-
process.env[key.trim()] = value.trim();
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
this.log.debug(`Loaded environment variables from ${envPath}`);
|
|
477
|
-
} catch {
|
|
478
|
-
this.log.debug(`No ${file} file found at ${envPath}, skipping load.`);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
465
|
+
async loadEnv(root, files = [".env"]) {
|
|
466
|
+
await this.envUtils.loadEnv(root, files);
|
|
481
467
|
}
|
|
482
468
|
async getPackageManager(root, flags) {
|
|
483
469
|
if (flags?.yarn) return "yarn";
|
|
@@ -601,33 +587,144 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
|
|
|
601
587
|
};
|
|
602
588
|
|
|
603
589
|
//#endregion
|
|
604
|
-
//#region ../../src/cli/commands/
|
|
605
|
-
var
|
|
590
|
+
//#region ../../src/cli/commands/build.ts
|
|
591
|
+
var BuildCommand = class {
|
|
606
592
|
log = $logger();
|
|
607
593
|
utils = $inject(AlephaCliUtils);
|
|
608
|
-
|
|
609
|
-
name: "
|
|
610
|
-
description: "
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
594
|
+
build = $command({
|
|
595
|
+
name: "build",
|
|
596
|
+
description: "Build the project for production",
|
|
597
|
+
args: t.optional(t.text({
|
|
598
|
+
title: "path",
|
|
599
|
+
description: "Filepath to build"
|
|
600
|
+
})),
|
|
601
|
+
flags: t.object({
|
|
602
|
+
stats: t.optional(t.boolean({ description: "Generate build stats report" })),
|
|
603
|
+
vercel: t.optional(t.boolean({ description: "Generate Vercel deployment configuration" })),
|
|
604
|
+
cloudflare: t.optional(t.boolean({ description: "Generate Cloudflare Workers configuration" })),
|
|
605
|
+
docker: t.optional(t.boolean({ description: "Generate Docker configuration" })),
|
|
606
|
+
sitemap: t.optional(t.text({ description: "Generate sitemap.xml with base URL" }))
|
|
607
|
+
}),
|
|
608
|
+
handler: async ({ flags, args, run, root }) => {
|
|
609
|
+
process.env.ALEPHA_BUILD_MODE = "cli";
|
|
610
|
+
process.env.NODE_ENV = "production";
|
|
611
|
+
if (await this.utils.hasExpo(root)) return;
|
|
612
|
+
await this.utils.ensureConfig(root, {
|
|
613
|
+
viteConfigTs: true,
|
|
614
|
+
tsconfigJson: true
|
|
615
|
+
});
|
|
616
|
+
const entry = await boot.getServerEntry(root, args);
|
|
617
|
+
this.log.trace("Entry file found", { entry });
|
|
618
|
+
const distDir = "dist";
|
|
619
|
+
const clientDir = "public";
|
|
620
|
+
await this.utils.ensureDependency(root, "vite", { run });
|
|
621
|
+
await run.rm("dist", { alias: "clean dist" });
|
|
622
|
+
const viteAlephaBuildOptions = (await createRequire(import.meta.url)("vite").resolveConfig({}, "build", "production")).plugins.find((it) => it.name === "alepha:build")?.[OPTIONS] || {};
|
|
623
|
+
await this.utils.loadEnv(root, [".env", ".env.production"]);
|
|
624
|
+
const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;
|
|
625
|
+
const hasServer = viteAlephaBuildOptions.serverEntry !== false;
|
|
626
|
+
let hasClient = false;
|
|
627
|
+
try {
|
|
628
|
+
await access(join(root, "index.html"));
|
|
629
|
+
hasClient = true;
|
|
630
|
+
} catch {}
|
|
631
|
+
const clientOptions = typeof viteAlephaBuildOptions.client === "object" ? viteAlephaBuildOptions.client : {};
|
|
632
|
+
if (hasClient) await run({
|
|
633
|
+
name: "vite build client",
|
|
634
|
+
handler: () => buildClient({
|
|
635
|
+
silent: true,
|
|
636
|
+
dist: `${distDir}/${clientDir}`,
|
|
637
|
+
stats,
|
|
638
|
+
precompress: clientOptions.precompress
|
|
639
|
+
})
|
|
640
|
+
});
|
|
641
|
+
await run({
|
|
642
|
+
name: "vite build server",
|
|
643
|
+
handler: async () => {
|
|
644
|
+
let clientBuilt = false;
|
|
645
|
+
try {
|
|
646
|
+
await readFile(`${distDir}/${clientDir}/index.html`, "utf-8");
|
|
647
|
+
clientBuilt = true;
|
|
648
|
+
} catch {}
|
|
649
|
+
await buildServer({
|
|
650
|
+
silent: true,
|
|
651
|
+
entry,
|
|
652
|
+
distDir,
|
|
653
|
+
clientDir: clientBuilt ? clientDir : void 0,
|
|
654
|
+
stats
|
|
655
|
+
});
|
|
656
|
+
if (clientBuilt && hasServer) await unlink(`${distDir}/${clientDir}/index.html`);
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
await copyAssets({
|
|
660
|
+
root,
|
|
661
|
+
entry: `${distDir}/index.js`,
|
|
662
|
+
distDir,
|
|
663
|
+
run
|
|
664
|
+
});
|
|
665
|
+
if (hasClient) {
|
|
666
|
+
const sitemapBaseUrl = flags.sitemap ?? clientOptions.sitemap?.hostname;
|
|
667
|
+
if (sitemapBaseUrl) await run({
|
|
668
|
+
name: "add sitemap",
|
|
669
|
+
handler: async () => {
|
|
670
|
+
await writeFile(`${distDir}/${clientDir}/sitemap.xml`, await generateSitemap({
|
|
671
|
+
entry: `${distDir}/index.js`,
|
|
672
|
+
baseUrl: sitemapBaseUrl
|
|
673
|
+
}));
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
if (clientOptions.prerender) await run({
|
|
677
|
+
name: "pre-render pages",
|
|
678
|
+
handler: async () => {
|
|
679
|
+
await prerenderPages({
|
|
680
|
+
dist: `${distDir}/${clientDir}`,
|
|
681
|
+
entry: `${distDir}/index.js`,
|
|
682
|
+
compress: clientOptions.precompress
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
if (flags.vercel || viteAlephaBuildOptions.vercel) {
|
|
688
|
+
const config = typeof viteAlephaBuildOptions.vercel === "object" ? viteAlephaBuildOptions.vercel : {};
|
|
689
|
+
await run({
|
|
690
|
+
name: "add Vercel config",
|
|
691
|
+
handler: () => generateVercel({
|
|
692
|
+
distDir,
|
|
693
|
+
clientDir,
|
|
694
|
+
config
|
|
695
|
+
})
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
if (flags.cloudflare || viteAlephaBuildOptions.cloudflare) {
|
|
699
|
+
const config = typeof viteAlephaBuildOptions.cloudflare === "boolean" ? {} : viteAlephaBuildOptions.cloudflare;
|
|
700
|
+
await run({
|
|
701
|
+
name: "add Cloudflare config",
|
|
702
|
+
handler: () => generateCloudflare({
|
|
703
|
+
distDir,
|
|
704
|
+
config
|
|
705
|
+
})
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
if (flags.docker || viteAlephaBuildOptions.docker) {
|
|
709
|
+
const dockerConfig = typeof viteAlephaBuildOptions.docker === "object" ? viteAlephaBuildOptions.docker : {};
|
|
710
|
+
await run({
|
|
711
|
+
name: "add Docker config",
|
|
712
|
+
handler: () => generateDocker({
|
|
713
|
+
distDir,
|
|
714
|
+
...dockerConfig
|
|
715
|
+
})
|
|
716
|
+
});
|
|
717
|
+
}
|
|
624
718
|
}
|
|
625
719
|
});
|
|
626
720
|
};
|
|
627
721
|
|
|
628
722
|
//#endregion
|
|
629
|
-
//#region ../../src/cli/
|
|
630
|
-
|
|
723
|
+
//#region ../../src/cli/atoms/changelogOptions.ts
|
|
724
|
+
/**
|
|
725
|
+
* Default scopes to ignore in changelog generation.
|
|
726
|
+
* Commits with these scopes won't appear in release notes.
|
|
727
|
+
*/
|
|
631
728
|
const DEFAULT_IGNORE = [
|
|
632
729
|
"project",
|
|
633
730
|
"release",
|
|
@@ -639,240 +736,208 @@ const DEFAULT_IGNORE = [
|
|
|
639
736
|
"test",
|
|
640
737
|
"style"
|
|
641
738
|
];
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
739
|
+
/**
|
|
740
|
+
* Changelog configuration atom.
|
|
741
|
+
*
|
|
742
|
+
* Configure in `alepha.config.ts`:
|
|
743
|
+
* ```ts
|
|
744
|
+
* import { changelogOptions } from "alepha/cli";
|
|
745
|
+
*
|
|
746
|
+
* alepha.set(changelogOptions, {
|
|
747
|
+
* ignore: ["project", "release", "chore", "docs"],
|
|
748
|
+
* });
|
|
749
|
+
* ```
|
|
750
|
+
*/
|
|
751
|
+
const changelogOptions = $atom({
|
|
752
|
+
name: "alepha.changelog",
|
|
753
|
+
schema: t.object({ ignore: t.optional(t.array(t.string())) }),
|
|
754
|
+
default: { ignore: DEFAULT_IGNORE }
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region ../../src/cli/services/GitMessageParser.ts
|
|
759
|
+
/**
|
|
760
|
+
* Service for parsing git commit messages into structured format.
|
|
761
|
+
*
|
|
762
|
+
* Only parses **conventional commits with a scope**:
|
|
763
|
+
* - `feat(scope): description` → feature
|
|
764
|
+
* - `fix(scope): description` → bug fix
|
|
765
|
+
* - `feat(scope)!: description` → breaking change
|
|
766
|
+
*
|
|
767
|
+
* Commits without scope are ignored, allowing developers to commit
|
|
768
|
+
* work-in-progress changes without polluting release notes:
|
|
769
|
+
* - `cli: work in progress` → ignored (no type)
|
|
770
|
+
* - `fix: quick patch` → ignored (no scope)
|
|
771
|
+
* - `feat(cli): add command` → included
|
|
772
|
+
*/
|
|
773
|
+
var GitMessageParser = class {
|
|
774
|
+
log = $logger();
|
|
775
|
+
/**
|
|
776
|
+
* Parse a git commit line into a structured Commit object.
|
|
777
|
+
*
|
|
778
|
+
* **Format:** `type(scope): description` or `type(scope)!: description`
|
|
779
|
+
*
|
|
780
|
+
* **Supported types:** feat, fix, docs, refactor, perf, revert
|
|
781
|
+
*
|
|
782
|
+
* **Breaking changes:** Use `!` before `:` (e.g., `feat(api)!: remove endpoint`)
|
|
783
|
+
*
|
|
784
|
+
* @returns Commit object or null if not matching/ignored
|
|
785
|
+
*/
|
|
786
|
+
parseCommit(line, config) {
|
|
787
|
+
const match = line.match(/^([a-f0-9]+)\s+(.+)$/);
|
|
788
|
+
if (!match) return null;
|
|
789
|
+
const [, hash, message] = match;
|
|
790
|
+
const ignore = config.ignore ?? DEFAULT_IGNORE;
|
|
791
|
+
const conventionalMatch = message.match(/^(feat|fix|docs|refactor|perf|revert)\(([^)]+)\)(!)?:\s*(.+)$/i);
|
|
792
|
+
if (!conventionalMatch) return null;
|
|
793
|
+
const [, type, scope, breakingMark, description] = conventionalMatch;
|
|
794
|
+
const baseScope = scope.split("/")[0];
|
|
795
|
+
if (ignore.includes(baseScope) || ignore.includes(scope)) return null;
|
|
796
|
+
const breaking = breakingMark === "!" || description.toLowerCase().includes("breaking");
|
|
656
797
|
return {
|
|
657
798
|
hash: hash.substring(0, 8),
|
|
658
799
|
type: type.toLowerCase(),
|
|
659
|
-
scope
|
|
800
|
+
scope,
|
|
660
801
|
description: description.trim(),
|
|
661
802
|
breaking
|
|
662
803
|
};
|
|
663
804
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
scope: module,
|
|
678
|
-
description: description.trim(),
|
|
679
|
-
breaking
|
|
680
|
-
};
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
//#endregion
|
|
808
|
+
//#region ../../src/cli/commands/changelog.ts
|
|
809
|
+
const execAsync = promisify(exec);
|
|
810
|
+
/**
|
|
811
|
+
* Git provider for executing git commands.
|
|
812
|
+
* Can be substituted in tests with a mock implementation.
|
|
813
|
+
*/
|
|
814
|
+
var GitProvider = class {
|
|
815
|
+
async exec(cmd, cwd) {
|
|
816
|
+
const { stdout } = await execAsync(`git ${cmd}`, { cwd });
|
|
817
|
+
return stdout;
|
|
681
818
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
819
|
+
};
|
|
820
|
+
/**
|
|
821
|
+
* Changelog command for generating release notes from git commits.
|
|
822
|
+
*
|
|
823
|
+
* Usage:
|
|
824
|
+
* - `alepha changelog` - Show unreleased changes since latest tag to HEAD
|
|
825
|
+
* - `alepha changelog --from=1.0.0` - Show changes from version to HEAD
|
|
826
|
+
* - `alepha changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs
|
|
827
|
+
* - `alepha changelog | tee -a CHANGELOG.md` - Append to file
|
|
828
|
+
*/
|
|
829
|
+
var ChangelogCommand = class {
|
|
830
|
+
log = $logger();
|
|
831
|
+
git = $inject(GitProvider);
|
|
832
|
+
parser = $inject(GitMessageParser);
|
|
833
|
+
config = $use(changelogOptions);
|
|
834
|
+
/**
|
|
835
|
+
* Format a single commit line.
|
|
836
|
+
* Example: `- **cli**: add new command (\`abc1234\`)`
|
|
837
|
+
* Breaking changes are flagged: `- **cli**: add new command [BREAKING] (\`abc1234\`)`
|
|
838
|
+
*/
|
|
839
|
+
formatCommit(commit) {
|
|
840
|
+
const breaking = commit.breaking ? " [BREAKING]" : "";
|
|
841
|
+
return `- **${commit.scope}**: ${commit.description}${breaking} (\`${commit.hash}\`)`;
|
|
693
842
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
843
|
+
/**
|
|
844
|
+
* Format the changelog entry with sections.
|
|
845
|
+
*/
|
|
846
|
+
formatEntry(entry) {
|
|
847
|
+
const sections = [];
|
|
848
|
+
if (entry.features.length > 0) {
|
|
849
|
+
sections.push("### Features\n");
|
|
850
|
+
for (const commit of entry.features) sections.push(this.formatCommit(commit));
|
|
851
|
+
sections.push("");
|
|
852
|
+
}
|
|
853
|
+
if (entry.fixes.length > 0) {
|
|
854
|
+
sections.push("### Bug Fixes\n");
|
|
855
|
+
for (const commit of entry.fixes) sections.push(this.formatCommit(commit));
|
|
856
|
+
sections.push("");
|
|
857
|
+
}
|
|
858
|
+
return sections.join("\n");
|
|
702
859
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
860
|
+
/**
|
|
861
|
+
* Parse git log output into a changelog entry.
|
|
862
|
+
*/
|
|
863
|
+
parseCommits(commitsOutput) {
|
|
864
|
+
const entry = {
|
|
865
|
+
features: [],
|
|
866
|
+
fixes: []
|
|
867
|
+
};
|
|
868
|
+
for (const line of commitsOutput.trim().split("\n")) {
|
|
869
|
+
if (!line.trim()) continue;
|
|
870
|
+
const commit = this.parser.parseCommit(line, this.config);
|
|
871
|
+
if (!commit) {
|
|
872
|
+
this.log.trace("Skipping commit", { line });
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
this.log.trace("Parsed commit", { commit });
|
|
876
|
+
if (commit.type === "feat") entry.features.push(commit);
|
|
877
|
+
else if (commit.type === "fix") entry.fixes.push(commit);
|
|
878
|
+
}
|
|
879
|
+
return entry;
|
|
707
880
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
881
|
+
/**
|
|
882
|
+
* Check if entry has any public commits.
|
|
883
|
+
*/
|
|
884
|
+
hasChanges(entry) {
|
|
885
|
+
return entry.features.length > 0 || entry.fixes.length > 0;
|
|
712
886
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
return JSON.parse(await readFile(pkgPath, "utf8")).changelog ?? {};
|
|
719
|
-
} catch {
|
|
720
|
-
return {};
|
|
887
|
+
/**
|
|
888
|
+
* Get the latest version tag.
|
|
889
|
+
*/
|
|
890
|
+
async getLatestTag(git) {
|
|
891
|
+
return (await git("tag --sort=-version:refname")).trim().split("\n").filter((tag) => tag.match(/^\d+\.\d+\.\d+$/))[0] || null;
|
|
721
892
|
}
|
|
722
|
-
}
|
|
723
|
-
var ChangelogCommands = class {
|
|
724
893
|
changelog = $command({
|
|
725
894
|
name: "changelog",
|
|
726
|
-
description: "Generate
|
|
895
|
+
description: "Generate changelog from conventional commits (outputs to stdout)",
|
|
727
896
|
flags: t.object({
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
description: "
|
|
731
|
-
})),
|
|
732
|
-
preview: t.optional(t.boolean({
|
|
733
|
-
when: ["--preview", "-p"],
|
|
734
|
-
description: "Preview unreleased changes (commits since last tag)"
|
|
735
|
-
})),
|
|
736
|
-
output: t.optional(t.string({
|
|
737
|
-
when: ["--output", "-o"],
|
|
738
|
-
description: "Output file path (defaults to CHANGELOG.md, use - for stdout)"
|
|
897
|
+
from: t.optional(t.string({
|
|
898
|
+
aliases: ["f"],
|
|
899
|
+
description: "Starting ref (default: latest tag)"
|
|
739
900
|
})),
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
description: "
|
|
901
|
+
to: t.optional(t.string({
|
|
902
|
+
aliases: ["t"],
|
|
903
|
+
description: "Ending ref (default: HEAD)"
|
|
743
904
|
}))
|
|
744
905
|
}),
|
|
745
|
-
handler: async ({ flags,
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
const commitsOutput = await git(`log ${latestTag}..HEAD --oneline`);
|
|
756
|
-
if (!commitsOutput.trim()) {
|
|
757
|
-
console.log("No unreleased changes since", latestTag);
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
const entry = {
|
|
761
|
-
version: "Unreleased",
|
|
762
|
-
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
763
|
-
features: [],
|
|
764
|
-
fixes: [],
|
|
765
|
-
docs: [],
|
|
766
|
-
improvements: [],
|
|
767
|
-
breaking: []
|
|
768
|
-
};
|
|
769
|
-
for (const line of commitsOutput.trim().split("\n")) {
|
|
770
|
-
if (!line.trim()) continue;
|
|
771
|
-
const commit = parseCommit(line, config);
|
|
772
|
-
if (!commit) continue;
|
|
773
|
-
if (commit.breaking) entry.breaking.push(commit);
|
|
774
|
-
switch (commit.type) {
|
|
775
|
-
case "feat":
|
|
776
|
-
entry.features.push(commit);
|
|
777
|
-
break;
|
|
778
|
-
case "fix":
|
|
779
|
-
entry.fixes.push(commit);
|
|
780
|
-
break;
|
|
781
|
-
case "docs":
|
|
782
|
-
entry.docs.push(commit);
|
|
783
|
-
break;
|
|
784
|
-
case "refactor":
|
|
785
|
-
case "perf":
|
|
786
|
-
case "improve":
|
|
787
|
-
entry.improvements.push(commit);
|
|
788
|
-
break;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
if (!(entry.features.length > 0 || entry.fixes.length > 0 || entry.breaking.length > 0)) {
|
|
792
|
-
console.log("No public changes since", latestTag);
|
|
906
|
+
handler: async ({ flags, root }) => {
|
|
907
|
+
const git = (cmd) => this.git.exec(cmd, root);
|
|
908
|
+
let fromRef;
|
|
909
|
+
if (flags.from) {
|
|
910
|
+
fromRef = flags.from;
|
|
911
|
+
this.log.debug("Using specified from ref", { from: fromRef });
|
|
912
|
+
} else {
|
|
913
|
+
const latestTag = await this.getLatestTag(git);
|
|
914
|
+
if (!latestTag) {
|
|
915
|
+
process.stdout.write("No version tags found in repository\n");
|
|
793
916
|
return;
|
|
794
917
|
}
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
return;
|
|
918
|
+
fromRef = latestTag;
|
|
919
|
+
this.log.debug("Using latest tag", { from: fromRef });
|
|
798
920
|
}
|
|
799
|
-
const
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
const commitsOutput = await git(`log ${prevTag ? `${prevTag}..${tag}` : tag} --oneline`);
|
|
806
|
-
const entry = {
|
|
807
|
-
version: tag,
|
|
808
|
-
date,
|
|
809
|
-
features: [],
|
|
810
|
-
fixes: [],
|
|
811
|
-
docs: [],
|
|
812
|
-
improvements: [],
|
|
813
|
-
breaking: []
|
|
814
|
-
};
|
|
815
|
-
for (const line of commitsOutput.trim().split("\n")) {
|
|
816
|
-
if (!line.trim()) continue;
|
|
817
|
-
const commit = parseCommit(line, config);
|
|
818
|
-
if (!commit) continue;
|
|
819
|
-
if (commit.breaking) entry.breaking.push(commit);
|
|
820
|
-
switch (commit.type) {
|
|
821
|
-
case "feat":
|
|
822
|
-
entry.features.push(commit);
|
|
823
|
-
break;
|
|
824
|
-
case "fix":
|
|
825
|
-
entry.fixes.push(commit);
|
|
826
|
-
break;
|
|
827
|
-
case "docs":
|
|
828
|
-
entry.docs.push(commit);
|
|
829
|
-
break;
|
|
830
|
-
case "refactor":
|
|
831
|
-
case "perf":
|
|
832
|
-
case "improve":
|
|
833
|
-
entry.improvements.push(commit);
|
|
834
|
-
break;
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
if (entry.features.length > 0 || entry.fixes.length > 0 || entry.breaking.length > 0) entries.push(entry);
|
|
921
|
+
const toRef = flags.to || "HEAD";
|
|
922
|
+
this.log.debug("Using to ref", { to: toRef });
|
|
923
|
+
const commitsOutput = await git(`log ${fromRef}..${toRef} --oneline`);
|
|
924
|
+
if (!commitsOutput.trim()) {
|
|
925
|
+
process.stdout.write(`No changes in range ${fromRef}..${toRef}\n`);
|
|
926
|
+
return;
|
|
838
927
|
}
|
|
839
|
-
|
|
840
|
-
|
|
928
|
+
const entry = this.parseCommits(commitsOutput);
|
|
929
|
+
if (!this.hasChanges(entry)) {
|
|
930
|
+
process.stdout.write(`No public changes in range ${fromRef}..${toRef}\n`);
|
|
841
931
|
return;
|
|
842
932
|
}
|
|
843
|
-
|
|
844
|
-
if (flags.release) output = formatEntry(entries[0]);
|
|
845
|
-
else output = generateChangelog(entries);
|
|
846
|
-
const outputPath = flags.output ?? "CHANGELOG.md";
|
|
847
|
-
if (outputPath === "-") console.log(output);
|
|
848
|
-
else await run(`Writing ${outputPath}`, () => writeFile(join(root, outputPath), output, "utf8"));
|
|
933
|
+
process.stdout.write(this.formatEntry(entry));
|
|
849
934
|
}
|
|
850
935
|
});
|
|
851
936
|
};
|
|
852
937
|
|
|
853
938
|
//#endregion
|
|
854
|
-
//#region ../../src/cli/commands/
|
|
855
|
-
var
|
|
856
|
-
log = $logger();
|
|
857
|
-
cli = $inject(CliProvider);
|
|
858
|
-
utils = $inject(AlephaCliUtils);
|
|
859
|
-
/**
|
|
860
|
-
* Called when no command is provided
|
|
861
|
-
*/
|
|
862
|
-
root = $command({
|
|
863
|
-
root: true,
|
|
864
|
-
flags: t.object({ version: t.optional(t.boolean({
|
|
865
|
-
description: "Show Alepha CLI version",
|
|
866
|
-
aliases: ["v"]
|
|
867
|
-
})) }),
|
|
868
|
-
handler: async ({ flags }) => {
|
|
869
|
-
if (flags.version) {
|
|
870
|
-
this.log.info(version);
|
|
871
|
-
return;
|
|
872
|
-
}
|
|
873
|
-
this.cli.printHelp();
|
|
874
|
-
}
|
|
875
|
-
});
|
|
939
|
+
//#region ../../src/cli/commands/clean.ts
|
|
940
|
+
var CleanCommand = class {
|
|
876
941
|
/**
|
|
877
942
|
* Clean the project, removing the "dist" directory
|
|
878
943
|
*/
|
|
@@ -883,70 +948,22 @@ var CoreCommands = class {
|
|
|
883
948
|
await run.rm("./dist");
|
|
884
949
|
}
|
|
885
950
|
});
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
//#endregion
|
|
954
|
+
//#region ../../src/cli/commands/db.ts
|
|
955
|
+
const drizzleCommandFlags = t.object({
|
|
956
|
+
provider: t.optional(t.text({ description: "Database provider name to target (e.g., 'postgres', 'sqlite')" })),
|
|
957
|
+
mode: t.optional(t.text({ description: "Environment variable file(s) to load (e.g., 'production' to load .env.production) https://vite.dev/guide/env-and-mode" }))
|
|
958
|
+
});
|
|
959
|
+
var DbCommand = class {
|
|
960
|
+
log = $logger();
|
|
961
|
+
utils = $inject(AlephaCliUtils);
|
|
886
962
|
/**
|
|
887
|
-
*
|
|
888
|
-
* Add the correct dependencies to package.json and install them.
|
|
889
|
-
*/
|
|
890
|
-
init = $command({
|
|
891
|
-
name: "init",
|
|
892
|
-
description: "Add missing Alepha configuration files to the project",
|
|
893
|
-
flags: t.object({
|
|
894
|
-
yarn: t.optional(t.boolean({ description: "Use Yarn package manager" })),
|
|
895
|
-
pnpm: t.optional(t.boolean({ description: "Use pnpm package manager" })),
|
|
896
|
-
npm: t.optional(t.boolean({ description: "Use npm package manager" })),
|
|
897
|
-
bun: t.optional(t.boolean({ description: "Use Bun package manager" })),
|
|
898
|
-
react: t.optional(t.boolean({ description: "Include Alepha React dependencies" })),
|
|
899
|
-
ui: t.optional(t.boolean({ description: "Include Alepha UI dependencies" })),
|
|
900
|
-
test: t.optional(t.boolean({ description: "Include Vitest and create test directory" }))
|
|
901
|
-
}),
|
|
902
|
-
handler: async ({ run, flags, root }) => {
|
|
903
|
-
if (flags.ui) flags.react = true;
|
|
904
|
-
const isExpo = await this.utils.hasExpo(root);
|
|
905
|
-
await run({
|
|
906
|
-
name: "ensuring configuration files",
|
|
907
|
-
handler: async () => {
|
|
908
|
-
await this.utils.ensureConfig(root, {
|
|
909
|
-
tsconfigJson: true,
|
|
910
|
-
packageJson: flags,
|
|
911
|
-
biomeJson: true,
|
|
912
|
-
viteConfigTs: !isExpo,
|
|
913
|
-
editorconfig: true,
|
|
914
|
-
indexHtml: !!flags.react && !isExpo
|
|
915
|
-
});
|
|
916
|
-
if (!flags.react) await this.utils.ensureSrcMain(root);
|
|
917
|
-
}
|
|
918
|
-
});
|
|
919
|
-
const pm = await this.utils.getPackageManager(root, flags);
|
|
920
|
-
if (pm === "yarn") {
|
|
921
|
-
await this.utils.ensureYarn(root);
|
|
922
|
-
await run("yarn set version stable");
|
|
923
|
-
} else if (pm === "pnpm") await this.utils.ensurePnpm(root);
|
|
924
|
-
else await this.utils.ensureNpm(root);
|
|
925
|
-
await run(`${pm} install`, { alias: `installing dependencies with ${pm}` });
|
|
926
|
-
if (!isExpo) await this.utils.ensureDependency(root, "vite", { run });
|
|
927
|
-
await this.utils.ensureDependency(root, "@biomejs/biome", { run });
|
|
928
|
-
if (flags.test) {
|
|
929
|
-
await this.utils.ensureTestDir(root);
|
|
930
|
-
await run(`${pm} ${pm === "yarn" ? "add" : "install"} -D vitest`, { alias: "setup testing with Vitest" });
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
});
|
|
934
|
-
};
|
|
935
|
-
|
|
936
|
-
//#endregion
|
|
937
|
-
//#region ../../src/cli/commands/DrizzleCommands.ts
|
|
938
|
-
const drizzleCommandFlags = t.object({
|
|
939
|
-
provider: t.optional(t.text({ description: "Database provider name to target (e.g., 'postgres', 'sqlite')" })),
|
|
940
|
-
mode: t.optional(t.text({ description: "Environment variable file(s) to load (e.g., 'production' to load .env.production) https://vite.dev/guide/env-and-mode" }))
|
|
941
|
-
});
|
|
942
|
-
var DrizzleCommands = class {
|
|
943
|
-
log = $logger();
|
|
944
|
-
utils = $inject(AlephaCliUtils);
|
|
945
|
-
/**
|
|
946
|
-
* Check if database migrations are up to date.
|
|
963
|
+
* Check if database migrations are up to date.
|
|
947
964
|
*/
|
|
948
965
|
check = $command({
|
|
949
|
-
name: "
|
|
966
|
+
name: "check-migrations",
|
|
950
967
|
description: "Check if database migration files are up to date",
|
|
951
968
|
args: t.optional(t.text({
|
|
952
969
|
title: "path",
|
|
@@ -968,7 +985,7 @@ var DrizzleCommands = class {
|
|
|
968
985
|
const migrationDir = join(rootDir, "migrations", providerName);
|
|
969
986
|
const journalFile = await readFile(`${migrationDir}/meta/_journal.json`, "utf-8").catch(() => null);
|
|
970
987
|
if (!journalFile) {
|
|
971
|
-
this.log.info(
|
|
988
|
+
this.log.info("No migration journal found.");
|
|
972
989
|
return;
|
|
973
990
|
}
|
|
974
991
|
const journal = JSON.parse(journalFile);
|
|
@@ -1005,15 +1022,9 @@ var DrizzleCommands = class {
|
|
|
1005
1022
|
});
|
|
1006
1023
|
/**
|
|
1007
1024
|
* Generate database migration files
|
|
1008
|
-
*
|
|
1009
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
1010
|
-
* - Retrieves all repository primitives to gather database models.
|
|
1011
|
-
* - Creates temporary entity definitions based on the current database schema.
|
|
1012
|
-
* - Writes these definitions to a temporary schema file. (node_modules/.db/entities.ts)
|
|
1013
|
-
* - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.
|
|
1014
1025
|
*/
|
|
1015
1026
|
generate = $command({
|
|
1016
|
-
name: "
|
|
1027
|
+
name: "generate",
|
|
1017
1028
|
description: "Generate migration files based on current database schema",
|
|
1018
1029
|
summary: false,
|
|
1019
1030
|
args: t.optional(t.text({
|
|
@@ -1036,14 +1047,9 @@ var DrizzleCommands = class {
|
|
|
1036
1047
|
});
|
|
1037
1048
|
/**
|
|
1038
1049
|
* Push database schema changes directly to the database
|
|
1039
|
-
*
|
|
1040
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
1041
|
-
* - Retrieves all repository primitives to gather database models.
|
|
1042
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
1043
|
-
* - Invokes Drizzle Kit's push command to apply schema changes directly.
|
|
1044
1050
|
*/
|
|
1045
1051
|
push = $command({
|
|
1046
|
-
name: "
|
|
1052
|
+
name: "push",
|
|
1047
1053
|
description: "Push database schema changes directly to the database",
|
|
1048
1054
|
summary: false,
|
|
1049
1055
|
args: t.optional(t.text({
|
|
@@ -1064,14 +1070,9 @@ var DrizzleCommands = class {
|
|
|
1064
1070
|
});
|
|
1065
1071
|
/**
|
|
1066
1072
|
* Apply pending database migrations
|
|
1067
|
-
*
|
|
1068
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
1069
|
-
* - Retrieves all repository primitives to gather database models.
|
|
1070
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
1071
|
-
* - Invokes Drizzle Kit's migrate command to apply pending migrations.
|
|
1072
1073
|
*/
|
|
1073
1074
|
migrate = $command({
|
|
1074
|
-
name: "
|
|
1075
|
+
name: "migrate",
|
|
1075
1076
|
description: "Apply pending database migrations",
|
|
1076
1077
|
summary: false,
|
|
1077
1078
|
args: t.optional(t.text({
|
|
@@ -1092,14 +1093,9 @@ var DrizzleCommands = class {
|
|
|
1092
1093
|
});
|
|
1093
1094
|
/**
|
|
1094
1095
|
* Launch Drizzle Studio database browser
|
|
1095
|
-
*
|
|
1096
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
1097
|
-
* - Retrieves all repository primitives to gather database models.
|
|
1098
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
1099
|
-
* - Invokes Drizzle Kit's studio command to launch the web-based database browser.
|
|
1100
1096
|
*/
|
|
1101
1097
|
studio = $command({
|
|
1102
|
-
name: "
|
|
1098
|
+
name: "studio",
|
|
1103
1099
|
description: "Launch Drizzle Studio database browser",
|
|
1104
1100
|
summary: false,
|
|
1105
1101
|
args: t.optional(t.text({
|
|
@@ -1119,18 +1115,30 @@ var DrizzleCommands = class {
|
|
|
1119
1115
|
}
|
|
1120
1116
|
});
|
|
1121
1117
|
/**
|
|
1118
|
+
* Parent command for database operations.
|
|
1119
|
+
*/
|
|
1120
|
+
db = $command({
|
|
1121
|
+
name: "db",
|
|
1122
|
+
description: "Database management commands",
|
|
1123
|
+
children: [
|
|
1124
|
+
this.check,
|
|
1125
|
+
this.generate,
|
|
1126
|
+
this.push,
|
|
1127
|
+
this.migrate,
|
|
1128
|
+
this.studio
|
|
1129
|
+
],
|
|
1130
|
+
handler: async ({ help }) => {
|
|
1131
|
+
help();
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1134
|
+
/**
|
|
1122
1135
|
* Run a drizzle-kit command for all database providers in an Alepha instance.
|
|
1123
|
-
*
|
|
1124
|
-
* Iterates through all repository providers, prepares Drizzle config for each,
|
|
1125
|
-
* and executes the specified drizzle-kit command.
|
|
1126
|
-
*
|
|
1127
|
-
* @param options - Configuration including command to run, flags, and logging
|
|
1128
1136
|
*/
|
|
1129
1137
|
async runDrizzleKitCommand(options) {
|
|
1130
1138
|
const rootDir = options.root;
|
|
1131
1139
|
const envFiles = [".env"];
|
|
1132
1140
|
if (options.env) envFiles.push(`.env.${options.env}`);
|
|
1133
|
-
await this.utils.
|
|
1141
|
+
await this.utils.loadEnv(rootDir, envFiles);
|
|
1134
1142
|
this.log.debug(`Using project root: ${rootDir}`);
|
|
1135
1143
|
const { alepha, entry } = await this.utils.loadAlephaFromServerEntryFile(rootDir, options.args);
|
|
1136
1144
|
const drizzleKitProvider = alepha.inject("DrizzleKitProvider");
|
|
@@ -1163,12 +1171,6 @@ var DrizzleCommands = class {
|
|
|
1163
1171
|
}
|
|
1164
1172
|
/**
|
|
1165
1173
|
* Prepare Drizzle configuration files for a database provider.
|
|
1166
|
-
*
|
|
1167
|
-
* Creates temporary entities.js and drizzle.config.js files needed
|
|
1168
|
-
* for Drizzle Kit commands to run properly.
|
|
1169
|
-
*
|
|
1170
|
-
* @param options - Configuration options including kit, provider info, and paths
|
|
1171
|
-
* @returns Path to the generated drizzle.config.js file
|
|
1172
1174
|
*/
|
|
1173
1175
|
async prepareDrizzleConfig(options) {
|
|
1174
1176
|
const models = Object.keys(options.kit.getModels(options.provider));
|
|
@@ -1179,6 +1181,7 @@ var DrizzleCommands = class {
|
|
|
1179
1181
|
dialect: options.dialect,
|
|
1180
1182
|
dbCredentials: { url: options.providerUrl }
|
|
1181
1183
|
};
|
|
1184
|
+
if (options.provider.schema) config.schemaFilter = options.provider.schema;
|
|
1182
1185
|
if (options.providerName === "d1") config.driver = "d1-http";
|
|
1183
1186
|
if (options.providerName === "pglite") config.driver = "pglite";
|
|
1184
1187
|
if (options.dialect === "sqlite") if (options.providerName === "d1") {
|
|
@@ -1207,73 +1210,91 @@ var DrizzleCommands = class {
|
|
|
1207
1210
|
};
|
|
1208
1211
|
|
|
1209
1212
|
//#endregion
|
|
1210
|
-
//#region ../../src/cli/commands/
|
|
1211
|
-
var
|
|
1213
|
+
//#region ../../src/cli/commands/deploy.ts
|
|
1214
|
+
var DeployCommand = class {
|
|
1215
|
+
log = $logger();
|
|
1212
1216
|
utils = $inject(AlephaCliUtils);
|
|
1213
1217
|
/**
|
|
1214
|
-
*
|
|
1218
|
+
* Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)
|
|
1215
1219
|
*
|
|
1216
|
-
*
|
|
1217
|
-
*
|
|
1218
|
-
*
|
|
1219
|
-
*
|
|
1220
|
-
*
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1224
|
-
*
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
await run("alepha format");
|
|
1232
|
-
await run("alepha lint");
|
|
1233
|
-
await run("alepha typecheck");
|
|
1234
|
-
if ((await this.utils.readPackageJson(root)).devDependencies?.vitest) await run("alepha test");
|
|
1235
|
-
if (await this.utils.exists(root, "migrations")) await run("alepha db:check-migrations");
|
|
1236
|
-
if (!await this.utils.hasExpo(root)) await run("alepha build");
|
|
1237
|
-
await run("alepha clean");
|
|
1238
|
-
}
|
|
1239
|
-
});
|
|
1240
|
-
/**
|
|
1241
|
-
* Run TypeScript type checking across the codebase with no emit.
|
|
1220
|
+
* Deploy command can be overridden by creating a alepha.config.ts in the project root:
|
|
1221
|
+
*
|
|
1222
|
+
* ```ts
|
|
1223
|
+
* import { defineConfig } from "alepha/cli";
|
|
1224
|
+
*
|
|
1225
|
+
* export default defineConfig({
|
|
1226
|
+
* commands: {
|
|
1227
|
+
* deploy: {
|
|
1228
|
+
* handler: async ({ root, mode, flags }) => {
|
|
1229
|
+
* // Custom deployment logic here
|
|
1230
|
+
* },
|
|
1231
|
+
* },
|
|
1232
|
+
* },
|
|
1233
|
+
* });
|
|
1234
|
+
* ```
|
|
1242
1235
|
*/
|
|
1243
|
-
|
|
1244
|
-
name: "
|
|
1245
|
-
description: "
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1236
|
+
deploy = $command({
|
|
1237
|
+
name: "deploy",
|
|
1238
|
+
description: "Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)",
|
|
1239
|
+
mode: true,
|
|
1240
|
+
flags: t.object({
|
|
1241
|
+
build: t.boolean({
|
|
1242
|
+
description: "Build the project before deployment",
|
|
1243
|
+
default: false
|
|
1244
|
+
}),
|
|
1245
|
+
migrate: t.boolean({
|
|
1246
|
+
description: "Run database migrations before deployment (if applicable)",
|
|
1247
|
+
default: false
|
|
1248
|
+
})
|
|
1249
|
+
}),
|
|
1250
|
+
env: t.object({
|
|
1251
|
+
VERCEL_TOKEN: t.optional(t.text({ description: "Vercel API token (e.g., xxxxxxxxxxxxxxxxxxxx)" })),
|
|
1252
|
+
VERCEL_ORG_ID: t.optional(t.text({ description: "Vercel organization ID (e.g., team_abc123...)" })),
|
|
1253
|
+
VERCEL_PROJECT_ID: t.optional(t.text({ description: "Vercel project ID (e.g., prj_abc123...)" })),
|
|
1254
|
+
CLOUDFLARE_API_TOKEN: t.optional(t.text({ description: "Cloudflare API token (e.g., xxxx-xxxx-xxxx-xxxx)" })),
|
|
1255
|
+
CLOUDFLARE_ACCOUNT_ID: t.optional(t.text({ description: "Cloudflare account ID (e.g., abc123def456...)" }))
|
|
1256
|
+
}),
|
|
1257
|
+
handler: async ({ root, mode, flags }) => {
|
|
1258
|
+
if (flags.build) await this.utils.exec("alepha build");
|
|
1259
|
+
if (await this.utils.exists(root, "dist/vercel.json")) {
|
|
1260
|
+
if (flags.migrate) {
|
|
1261
|
+
this.log.debug("Running database migrations before deployment...");
|
|
1262
|
+
await this.utils.exec(`alepha db migrate --mode=${mode}`);
|
|
1263
|
+
}
|
|
1264
|
+
await this.utils.ensureDependency(root, "vercel", { dev: true });
|
|
1265
|
+
const command = `vercel . --cwd=dist ${mode === "production" ? "--prod" : ""}`.trim();
|
|
1266
|
+
this.log.debug(`Deploying to Vercel with command: ${command}`);
|
|
1267
|
+
await this.utils.exec(command);
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
if (await this.utils.exists(root, "dist/wrangler.jsonc")) {
|
|
1271
|
+
if (flags.migrate) {
|
|
1272
|
+
this.log.debug("Running database migrations before deployment...");
|
|
1273
|
+
await this.utils.exec(`alepha db migrate --mode=${mode}`);
|
|
1274
|
+
}
|
|
1275
|
+
await this.utils.ensureDependency(root, "wrangler", { dev: true });
|
|
1276
|
+
const command = `wrangler deploy ${mode === "production" ? "" : "--env preview"} --config=dist/wrangler.jsonc`.trim();
|
|
1277
|
+
this.log.info(`Deploying to Cloudflare with command: ${command}`);
|
|
1278
|
+
await this.utils.exec(command);
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
if (await this.utils.exists(root, "dist/public/404.html")) {
|
|
1282
|
+
await this.utils.ensureDependency(root, "surge", { dev: true });
|
|
1283
|
+
const distPath = join(root, "dist/public");
|
|
1284
|
+
this.log.debug(`Deploying to Surge from directory: ${distPath}`);
|
|
1285
|
+
await this.utils.exec(`surge ${distPath}`);
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
throw new AlephaError("No deployment configuration found in the dist folder.");
|
|
1249
1289
|
}
|
|
1250
1290
|
});
|
|
1251
1291
|
};
|
|
1252
1292
|
|
|
1253
1293
|
//#endregion
|
|
1254
|
-
//#region ../../src/cli/commands/
|
|
1255
|
-
var
|
|
1294
|
+
//#region ../../src/cli/commands/dev.ts
|
|
1295
|
+
var DevCommand = class {
|
|
1256
1296
|
log = $logger();
|
|
1257
1297
|
utils = $inject(AlephaCliUtils);
|
|
1258
|
-
env = $env(t.object({ VITEST_ARGS: t.string({ default: "" }) }));
|
|
1259
|
-
run = $command({
|
|
1260
|
-
name: "run",
|
|
1261
|
-
hide: true,
|
|
1262
|
-
description: "Run a TypeScript file directly",
|
|
1263
|
-
flags: t.object({ watch: t.optional(t.boolean({
|
|
1264
|
-
description: "Watch file for changes",
|
|
1265
|
-
alias: "w"
|
|
1266
|
-
})) }),
|
|
1267
|
-
summary: false,
|
|
1268
|
-
args: t.text({
|
|
1269
|
-
title: "path",
|
|
1270
|
-
description: "Filepath to run"
|
|
1271
|
-
}),
|
|
1272
|
-
handler: async ({ args, flags, root }) => {
|
|
1273
|
-
await this.utils.ensureTsConfig(root);
|
|
1274
|
-
await this.utils.exec(`tsx ${flags.watch ? "watch " : ""}${args}`);
|
|
1275
|
-
}
|
|
1276
|
-
});
|
|
1277
1298
|
/**
|
|
1278
1299
|
* Will run the project in watch mode.
|
|
1279
1300
|
*
|
|
@@ -1294,7 +1315,7 @@ var ViteCommands = class {
|
|
|
1294
1315
|
tsconfigJson: true
|
|
1295
1316
|
});
|
|
1296
1317
|
if (expo) {
|
|
1297
|
-
await this.utils.exec(
|
|
1318
|
+
await this.utils.exec("expo start");
|
|
1298
1319
|
return;
|
|
1299
1320
|
}
|
|
1300
1321
|
const entry = await boot.getServerEntry(root, args);
|
|
@@ -1304,152 +1325,222 @@ var ViteCommands = class {
|
|
|
1304
1325
|
} catch {
|
|
1305
1326
|
this.log.trace("No index.html found, running entry file with tsx");
|
|
1306
1327
|
let cmd = "tsx --watch";
|
|
1307
|
-
if (await this.utils.exists(root, ".env")) cmd +=
|
|
1328
|
+
if (await this.utils.exists(root, ".env")) cmd += " --env-file=./.env";
|
|
1308
1329
|
cmd += ` ${entry}`;
|
|
1309
1330
|
await this.utils.exec(cmd);
|
|
1310
1331
|
return;
|
|
1311
1332
|
}
|
|
1312
1333
|
await this.utils.ensureDependency(root, "vite");
|
|
1313
|
-
await this.utils.exec(
|
|
1334
|
+
await this.utils.exec("vite");
|
|
1314
1335
|
}
|
|
1315
1336
|
});
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
//#endregion
|
|
1340
|
+
//#region ../../src/cli/commands/format.ts
|
|
1341
|
+
var FormatCommand = class {
|
|
1342
|
+
utils = $inject(AlephaCliUtils);
|
|
1343
|
+
format = $command({
|
|
1344
|
+
name: "format",
|
|
1345
|
+
description: "Format the codebase using Biome",
|
|
1346
|
+
handler: async ({ root }) => {
|
|
1347
|
+
await this.utils.ensureConfig(root, { biomeJson: true });
|
|
1348
|
+
await this.utils.ensureDependency(root, "@biomejs/biome");
|
|
1349
|
+
await this.utils.exec("biome format --fix");
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
};
|
|
1353
|
+
|
|
1354
|
+
//#endregion
|
|
1355
|
+
//#region ../../src/cli/commands/init.ts
|
|
1356
|
+
var InitCommand = class {
|
|
1357
|
+
utils = $inject(AlephaCliUtils);
|
|
1358
|
+
/**
|
|
1359
|
+
* Ensure the project has the necessary Alepha configuration files.
|
|
1360
|
+
* Add the correct dependencies to package.json and install them.
|
|
1361
|
+
*/
|
|
1362
|
+
init = $command({
|
|
1363
|
+
name: "init",
|
|
1364
|
+
description: "Add missing Alepha configuration files to the project",
|
|
1323
1365
|
flags: t.object({
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1366
|
+
yarn: t.optional(t.boolean({ description: "Use Yarn package manager" })),
|
|
1367
|
+
pnpm: t.optional(t.boolean({ description: "Use pnpm package manager" })),
|
|
1368
|
+
npm: t.optional(t.boolean({ description: "Use npm package manager" })),
|
|
1369
|
+
bun: t.optional(t.boolean({ description: "Use Bun package manager" })),
|
|
1370
|
+
react: t.optional(t.boolean({ description: "Include Alepha React dependencies" })),
|
|
1371
|
+
ui: t.optional(t.boolean({ description: "Include Alepha UI dependencies" })),
|
|
1372
|
+
test: t.optional(t.boolean({ description: "Include Vitest and create test directory" }))
|
|
1330
1373
|
}),
|
|
1331
|
-
handler: async ({
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
if (await this.utils.hasExpo(root)) return;
|
|
1335
|
-
await this.utils.ensureConfig(root, {
|
|
1336
|
-
viteConfigTs: true,
|
|
1337
|
-
tsconfigJson: true
|
|
1338
|
-
});
|
|
1339
|
-
const entry = await boot.getServerEntry(root, args);
|
|
1340
|
-
this.log.trace("Entry file found", { entry });
|
|
1341
|
-
const distDir = "dist";
|
|
1342
|
-
const clientDir = "public";
|
|
1343
|
-
await this.utils.ensureDependency(root, "vite", { run });
|
|
1344
|
-
await run.rm("dist", { alias: "clean dist" });
|
|
1345
|
-
const viteAlephaBuildOptions = (await createRequire(import.meta.url)("vite").resolveConfig({}, "build", "production")).plugins.find((it) => it.name === "alepha:build")?.[OPTIONS] || {};
|
|
1346
|
-
await this.utils.loadEnvFile(root, [".env", ".env.production"]);
|
|
1347
|
-
const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;
|
|
1348
|
-
const hasServer = viteAlephaBuildOptions.serverEntry !== false;
|
|
1349
|
-
let hasClient = false;
|
|
1350
|
-
try {
|
|
1351
|
-
await access(join(root, "index.html"));
|
|
1352
|
-
hasClient = true;
|
|
1353
|
-
} catch {}
|
|
1354
|
-
const clientOptions = typeof viteAlephaBuildOptions.client === "object" ? viteAlephaBuildOptions.client : {};
|
|
1355
|
-
if (hasClient) await run({
|
|
1356
|
-
name: "vite build client",
|
|
1357
|
-
handler: () => buildClient({
|
|
1358
|
-
silent: true,
|
|
1359
|
-
dist: `${distDir}/${clientDir}`,
|
|
1360
|
-
stats,
|
|
1361
|
-
precompress: clientOptions.precompress
|
|
1362
|
-
})
|
|
1363
|
-
});
|
|
1374
|
+
handler: async ({ run, flags, root }) => {
|
|
1375
|
+
if (flags.ui) flags.react = true;
|
|
1376
|
+
const isExpo = await this.utils.hasExpo(root);
|
|
1364
1377
|
await run({
|
|
1365
|
-
name: "
|
|
1378
|
+
name: "ensuring configuration files",
|
|
1366
1379
|
handler: async () => {
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
entry,
|
|
1375
|
-
distDir,
|
|
1376
|
-
clientDir: clientBuilt ? clientDir : void 0,
|
|
1377
|
-
stats
|
|
1380
|
+
await this.utils.ensureConfig(root, {
|
|
1381
|
+
tsconfigJson: true,
|
|
1382
|
+
packageJson: flags,
|
|
1383
|
+
biomeJson: true,
|
|
1384
|
+
viteConfigTs: !isExpo,
|
|
1385
|
+
editorconfig: true,
|
|
1386
|
+
indexHtml: !!flags.react && !isExpo
|
|
1378
1387
|
});
|
|
1379
|
-
if (
|
|
1388
|
+
if (!flags.react) await this.utils.ensureSrcMain(root);
|
|
1380
1389
|
}
|
|
1381
1390
|
});
|
|
1382
|
-
await
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
entry: `${distDir}/index.js`,
|
|
1395
|
-
baseUrl: sitemapBaseUrl
|
|
1396
|
-
}));
|
|
1397
|
-
}
|
|
1398
|
-
});
|
|
1399
|
-
if (flags.prerender ?? clientOptions.prerender) await run({
|
|
1400
|
-
name: "pre-render pages",
|
|
1401
|
-
handler: async () => {
|
|
1402
|
-
await prerenderPages({
|
|
1403
|
-
dist: `${distDir}/${clientDir}`,
|
|
1404
|
-
entry: `${distDir}/index.js`,
|
|
1405
|
-
compress: clientOptions.precompress
|
|
1406
|
-
});
|
|
1407
|
-
}
|
|
1408
|
-
});
|
|
1409
|
-
}
|
|
1410
|
-
if (flags.vercel || viteAlephaBuildOptions.vercel) {
|
|
1411
|
-
const config = typeof viteAlephaBuildOptions.vercel === "object" ? viteAlephaBuildOptions.vercel : {};
|
|
1412
|
-
await run({
|
|
1413
|
-
name: "add Vercel config",
|
|
1414
|
-
handler: () => generateVercel({
|
|
1415
|
-
distDir,
|
|
1416
|
-
clientDir,
|
|
1417
|
-
config
|
|
1418
|
-
})
|
|
1419
|
-
});
|
|
1420
|
-
}
|
|
1421
|
-
if (flags.cloudflare || viteAlephaBuildOptions.cloudflare) {
|
|
1422
|
-
const config = typeof viteAlephaBuildOptions.cloudflare === "boolean" ? {} : viteAlephaBuildOptions.cloudflare;
|
|
1423
|
-
await run({
|
|
1424
|
-
name: "add Cloudflare config",
|
|
1425
|
-
handler: () => generateCloudflare({
|
|
1426
|
-
distDir,
|
|
1427
|
-
config
|
|
1428
|
-
})
|
|
1429
|
-
});
|
|
1391
|
+
const pm = await this.utils.getPackageManager(root, flags);
|
|
1392
|
+
if (pm === "yarn") {
|
|
1393
|
+
await this.utils.ensureYarn(root);
|
|
1394
|
+
await run("yarn set version stable");
|
|
1395
|
+
} else if (pm === "pnpm") await this.utils.ensurePnpm(root);
|
|
1396
|
+
else await this.utils.ensureNpm(root);
|
|
1397
|
+
await run(`${pm} install`, { alias: `installing dependencies with ${pm}` });
|
|
1398
|
+
if (!isExpo) await this.utils.ensureDependency(root, "vite", { run });
|
|
1399
|
+
await this.utils.ensureDependency(root, "@biomejs/biome", { run });
|
|
1400
|
+
if (flags.test) {
|
|
1401
|
+
await this.utils.ensureTestDir(root);
|
|
1402
|
+
await run(`${pm} ${pm === "yarn" ? "add" : "install"} -D vitest`, { alias: "setup testing with Vitest" });
|
|
1430
1403
|
}
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1404
|
+
}
|
|
1405
|
+
});
|
|
1406
|
+
};
|
|
1407
|
+
|
|
1408
|
+
//#endregion
|
|
1409
|
+
//#region ../../src/cli/commands/lint.ts
|
|
1410
|
+
var LintCommand = class {
|
|
1411
|
+
utils = $inject(AlephaCliUtils);
|
|
1412
|
+
lint = $command({
|
|
1413
|
+
name: "lint",
|
|
1414
|
+
description: "Run linter across the codebase using Biome",
|
|
1415
|
+
handler: async ({ root }) => {
|
|
1416
|
+
await this.utils.ensureConfig(root, { biomeJson: true });
|
|
1417
|
+
await this.utils.ensureDependency(root, "@biomejs/biome");
|
|
1418
|
+
await this.utils.exec("biome check --formatter-enabled=false --fix");
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
};
|
|
1422
|
+
|
|
1423
|
+
//#endregion
|
|
1424
|
+
//#region ../../src/cli/commands/root.ts
|
|
1425
|
+
var RootCommand = class {
|
|
1426
|
+
log = $logger();
|
|
1427
|
+
cli = $inject(CliProvider);
|
|
1428
|
+
/**
|
|
1429
|
+
* Called when no command is provided
|
|
1430
|
+
*/
|
|
1431
|
+
root = $command({
|
|
1432
|
+
root: true,
|
|
1433
|
+
flags: t.object({ version: t.optional(t.boolean({
|
|
1434
|
+
description: "Show Alepha CLI version",
|
|
1435
|
+
aliases: ["v"]
|
|
1436
|
+
})) }),
|
|
1437
|
+
handler: async ({ flags }) => {
|
|
1438
|
+
if (flags.version) {
|
|
1439
|
+
this.log.info(version);
|
|
1440
|
+
return;
|
|
1440
1441
|
}
|
|
1442
|
+
this.cli.printHelp();
|
|
1441
1443
|
}
|
|
1442
1444
|
});
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
//#endregion
|
|
1448
|
+
//#region ../../src/cli/commands/run.ts
|
|
1449
|
+
var RunCommand = class {
|
|
1450
|
+
utils = $inject(AlephaCliUtils);
|
|
1451
|
+
run = $command({
|
|
1452
|
+
name: "run",
|
|
1453
|
+
hide: true,
|
|
1454
|
+
description: "Run a TypeScript file directly",
|
|
1455
|
+
flags: t.object({ watch: t.optional(t.boolean({
|
|
1456
|
+
description: "Watch file for changes",
|
|
1457
|
+
alias: "w"
|
|
1458
|
+
})) }),
|
|
1459
|
+
summary: false,
|
|
1460
|
+
args: t.text({
|
|
1461
|
+
title: "path",
|
|
1462
|
+
description: "Filepath to run"
|
|
1463
|
+
}),
|
|
1464
|
+
handler: async ({ args, flags, root }) => {
|
|
1465
|
+
await this.utils.ensureTsConfig(root);
|
|
1466
|
+
await this.utils.exec(`tsx ${flags.watch ? "watch " : ""}${args}`);
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
};
|
|
1470
|
+
|
|
1471
|
+
//#endregion
|
|
1472
|
+
//#region ../../src/cli/commands/test.ts
|
|
1473
|
+
var TestCommand = class {
|
|
1474
|
+
utils = $inject(AlephaCliUtils);
|
|
1443
1475
|
test = $command({
|
|
1444
1476
|
name: "test",
|
|
1445
1477
|
description: "Run tests using Vitest",
|
|
1446
|
-
|
|
1478
|
+
flags: t.object({ config: t.optional(t.string({
|
|
1479
|
+
description: "Path to Vitest config file",
|
|
1480
|
+
alias: "c"
|
|
1481
|
+
})) }),
|
|
1482
|
+
env: t.object({ VITEST_ARGS: t.optional(t.string({
|
|
1483
|
+
default: "",
|
|
1484
|
+
description: "Additional arguments to pass to Vitest. E.g., --coverage"
|
|
1485
|
+
})) }),
|
|
1486
|
+
handler: async ({ root, flags, env }) => {
|
|
1447
1487
|
await this.utils.ensureConfig(root, {
|
|
1448
1488
|
tsconfigJson: true,
|
|
1449
1489
|
viteConfigTs: true
|
|
1450
1490
|
});
|
|
1451
1491
|
await this.utils.ensureDependency(root, "vitest");
|
|
1452
|
-
|
|
1492
|
+
const config = flags.config ? `--config=${flags.config}` : "";
|
|
1493
|
+
await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);
|
|
1494
|
+
}
|
|
1495
|
+
});
|
|
1496
|
+
};
|
|
1497
|
+
|
|
1498
|
+
//#endregion
|
|
1499
|
+
//#region ../../src/cli/commands/typecheck.ts
|
|
1500
|
+
var TypecheckCommand = class {
|
|
1501
|
+
utils = $inject(AlephaCliUtils);
|
|
1502
|
+
/**
|
|
1503
|
+
* Run TypeScript type checking across the codebase with no emit.
|
|
1504
|
+
*/
|
|
1505
|
+
typecheck = $command({
|
|
1506
|
+
name: "typecheck",
|
|
1507
|
+
description: "Check TypeScript types across the codebase",
|
|
1508
|
+
handler: async ({ root }) => {
|
|
1509
|
+
await this.utils.ensureDependency(root, "typescript");
|
|
1510
|
+
await this.utils.exec("tsc --noEmit");
|
|
1511
|
+
}
|
|
1512
|
+
});
|
|
1513
|
+
};
|
|
1514
|
+
|
|
1515
|
+
//#endregion
|
|
1516
|
+
//#region ../../src/cli/commands/verify.ts
|
|
1517
|
+
var VerifyCommand = class {
|
|
1518
|
+
utils = $inject(AlephaCliUtils);
|
|
1519
|
+
/**
|
|
1520
|
+
* Run a series of verification commands to ensure code quality and correctness.
|
|
1521
|
+
*
|
|
1522
|
+
* This command runs the following checks in order:
|
|
1523
|
+
* - Clean the project
|
|
1524
|
+
* - Format the code
|
|
1525
|
+
* - Lint the code
|
|
1526
|
+
* - Run tests (if Vitest is a dev dependency)
|
|
1527
|
+
* - Check database migrations (if a migrations directory exists)
|
|
1528
|
+
* - Type check the code
|
|
1529
|
+
* - Build the project
|
|
1530
|
+
* - Clean the project again
|
|
1531
|
+
*/
|
|
1532
|
+
verify = $command({
|
|
1533
|
+
name: "verify",
|
|
1534
|
+
description: "Verify the Alepha project",
|
|
1535
|
+
handler: async ({ root, run }) => {
|
|
1536
|
+
await run("alepha clean");
|
|
1537
|
+
await run("alepha format");
|
|
1538
|
+
await run("alepha lint");
|
|
1539
|
+
await run("alepha typecheck");
|
|
1540
|
+
if ((await this.utils.readPackageJson(root)).devDependencies?.vitest) await run("alepha test");
|
|
1541
|
+
if (await this.utils.exists(root, "migrations")) await run("alepha db:check-migrations");
|
|
1542
|
+
if (!await this.utils.hasExpo(root)) await run("alepha build");
|
|
1543
|
+
await run("alepha clean");
|
|
1453
1544
|
}
|
|
1454
1545
|
});
|
|
1455
1546
|
};
|
|
@@ -1466,7 +1557,7 @@ var AlephaCliExtension = class {
|
|
|
1466
1557
|
if (!await this.fs.exists(extensionPath)) return;
|
|
1467
1558
|
const { default: Extension } = await import(extensionPath);
|
|
1468
1559
|
if (typeof Extension !== "function") return;
|
|
1469
|
-
this.alepha.
|
|
1560
|
+
this.alepha.inject(Extension, { args: [this.alepha] });
|
|
1470
1561
|
}
|
|
1471
1562
|
});
|
|
1472
1563
|
};
|
|
@@ -1474,12 +1565,21 @@ const AlephaCli = $module({
|
|
|
1474
1565
|
name: "alepha.cli",
|
|
1475
1566
|
services: [
|
|
1476
1567
|
AlephaCliExtension,
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1568
|
+
BuildCommand,
|
|
1569
|
+
ChangelogCommand,
|
|
1570
|
+
CleanCommand,
|
|
1571
|
+
DbCommand,
|
|
1572
|
+
DeployCommand,
|
|
1573
|
+
DevCommand,
|
|
1574
|
+
FormatCommand,
|
|
1575
|
+
InitCommand,
|
|
1576
|
+
LintCommand,
|
|
1577
|
+
RootCommand,
|
|
1578
|
+
RunCommand,
|
|
1579
|
+
TestCommand,
|
|
1580
|
+
TypecheckCommand,
|
|
1581
|
+
VerifyCommand,
|
|
1582
|
+
GitProvider
|
|
1483
1583
|
]
|
|
1484
1584
|
});
|
|
1485
1585
|
|
|
@@ -1516,13 +1616,18 @@ var AlephaPackageBuilderCli = class {
|
|
|
1516
1616
|
pkgData.exports["./tsconfig.base"] = "./tsconfig.base.json";
|
|
1517
1617
|
pkgData.exports["./package.json"] = "./package.json";
|
|
1518
1618
|
}
|
|
1519
|
-
if (packageName === "@alepha/ui")
|
|
1619
|
+
if (packageName === "@alepha/ui") {
|
|
1620
|
+
pkgData.exports["./styles"] = "./src/core/styles.css";
|
|
1621
|
+
pkgData.exports["./json/styles"] = "./src/json/styles.css";
|
|
1622
|
+
}
|
|
1520
1623
|
await this.fs.writeFile("package.json", JSON.stringify(pkgData, null, 2));
|
|
1521
1624
|
const tmpDir = join(root, "node_modules/.alepha");
|
|
1522
1625
|
await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});
|
|
1523
1626
|
await this.fs.writeFile(join(tmpDir, "module-dependencies.json"), JSON.stringify(modules, null, 2));
|
|
1524
1627
|
const tsconfig = await readFile(join(root, "../../tsconfig.json"), "utf-8");
|
|
1525
1628
|
const external = Object.keys(JSON.parse(tsconfig).compilerOptions.paths);
|
|
1629
|
+
external.push("bun");
|
|
1630
|
+
external.push("bun:sqlite");
|
|
1526
1631
|
await run.rm(this.dist);
|
|
1527
1632
|
const build = async (item) => {
|
|
1528
1633
|
const entries = [];
|
|
@@ -1672,5 +1777,19 @@ async function analyzeModules(srcDir, packageName) {
|
|
|
1672
1777
|
}
|
|
1673
1778
|
|
|
1674
1779
|
//#endregion
|
|
1675
|
-
|
|
1780
|
+
//#region ../../src/cli/defineConfig.ts
|
|
1781
|
+
const defineConfig = (config) => {
|
|
1782
|
+
return (alepha) => {
|
|
1783
|
+
const { commands, services = [] } = config(alepha);
|
|
1784
|
+
for (const it of services) alepha.with(it);
|
|
1785
|
+
return { ...commands };
|
|
1786
|
+
};
|
|
1787
|
+
};
|
|
1788
|
+
/**
|
|
1789
|
+
* @alias defineConfig
|
|
1790
|
+
*/
|
|
1791
|
+
const defineAlephaConfig = defineConfig;
|
|
1792
|
+
|
|
1793
|
+
//#endregion
|
|
1794
|
+
export { AlephaCli, AlephaCliUtils, AlephaPackageBuilderCli, BuildCommand, ChangelogCommand, CleanCommand, DEFAULT_IGNORE, DbCommand, DeployCommand, DevCommand, FormatCommand, GitMessageParser, GitProvider, InitCommand, LintCommand, RootCommand, RunCommand, TestCommand, TypecheckCommand, VerifyCommand, analyzeModules, changelogOptions, defineAlephaConfig, defineConfig, version };
|
|
1676
1795
|
//# sourceMappingURL=index.js.map
|