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.
Files changed (97) hide show
  1. package/README.md +3 -3
  2. package/dist/api/audits/index.d.ts +342 -342
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js.map +1 -1
  5. package/dist/api/files/index.js.map +1 -1
  6. package/dist/api/jobs/index.d.ts +161 -161
  7. package/dist/api/jobs/index.js.map +1 -1
  8. package/dist/api/parameters/index.js.map +1 -1
  9. package/dist/api/users/index.d.ts +791 -791
  10. package/dist/api/users/index.d.ts.map +1 -1
  11. package/dist/api/users/index.js +4 -0
  12. package/dist/api/users/index.js.map +1 -1
  13. package/dist/api/verifications/index.d.ts +128 -128
  14. package/dist/api/verifications/index.d.ts.map +1 -1
  15. package/dist/batch/index.js.map +1 -1
  16. package/dist/cache/core/index.js.map +1 -1
  17. package/dist/cli/index.d.ts +173 -167
  18. package/dist/cli/index.d.ts.map +1 -1
  19. package/dist/cli/index.js +427 -409
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/command/index.d.ts +5 -5
  22. package/dist/command/index.js.map +1 -1
  23. package/dist/core/index.browser.js.map +1 -1
  24. package/dist/core/index.d.ts.map +1 -1
  25. package/dist/core/index.js +7 -6
  26. package/dist/core/index.js.map +1 -1
  27. package/dist/core/index.native.js +7 -6
  28. package/dist/core/index.native.js.map +1 -1
  29. package/dist/datetime/index.js.map +1 -1
  30. package/dist/fake/index.js.map +1 -1
  31. package/dist/file/index.js.map +1 -1
  32. package/dist/lock/redis/index.js.map +1 -1
  33. package/dist/logger/index.js.map +1 -1
  34. package/dist/mcp/index.js.map +1 -1
  35. package/dist/orm/index.browser.js +26 -5
  36. package/dist/orm/index.browser.js.map +1 -1
  37. package/dist/orm/index.d.ts +115 -90
  38. package/dist/orm/index.d.ts.map +1 -1
  39. package/dist/orm/index.js +37 -12
  40. package/dist/orm/index.js.map +1 -1
  41. package/dist/redis/index.js.map +1 -1
  42. package/dist/retry/index.js.map +1 -1
  43. package/dist/router/index.js.map +1 -1
  44. package/dist/scheduler/index.d.ts +6 -6
  45. package/dist/scheduler/index.js.map +1 -1
  46. package/dist/security/index.d.ts +28 -28
  47. package/dist/security/index.d.ts.map +1 -1
  48. package/dist/security/index.js.map +1 -1
  49. package/dist/server/auth/index.d.ts +155 -155
  50. package/dist/server/auth/index.js.map +1 -1
  51. package/dist/server/cache/index.js.map +1 -1
  52. package/dist/server/cookies/index.browser.js.map +1 -1
  53. package/dist/server/cookies/index.js.map +1 -1
  54. package/dist/server/core/index.browser.js.map +1 -1
  55. package/dist/server/core/index.js.map +1 -1
  56. package/dist/server/health/index.d.ts +17 -17
  57. package/dist/server/helmet/index.js.map +1 -1
  58. package/dist/server/links/index.browser.js.map +1 -1
  59. package/dist/server/links/index.js.map +1 -1
  60. package/dist/server/multipart/index.js.map +1 -1
  61. package/dist/server/rate-limit/index.js.map +1 -1
  62. package/dist/server/security/index.d.ts +9 -9
  63. package/dist/server/security/index.js.map +1 -1
  64. package/dist/server/swagger/index.js.map +1 -1
  65. package/dist/thread/index.js.map +1 -1
  66. package/dist/topic/core/index.js.map +1 -1
  67. package/dist/vite/index.js.map +1 -1
  68. package/dist/websocket/index.browser.js.map +1 -1
  69. package/dist/websocket/index.d.ts +7 -7
  70. package/dist/websocket/index.js.map +1 -1
  71. package/package.json +3 -3
  72. package/src/api/users/index.ts +4 -0
  73. package/src/cli/apps/AlephaCli.ts +31 -14
  74. package/src/cli/apps/AlephaPackageBuilderCli.ts +2 -1
  75. package/src/cli/assets/appRouterTs.ts +1 -1
  76. package/src/cli/commands/{ViteCommands.ts → build.ts} +2 -105
  77. package/src/cli/commands/{ChangelogCommands.ts → changelog.ts} +7 -22
  78. package/src/cli/commands/clean.ts +14 -0
  79. package/src/cli/commands/{DrizzleCommands.ts → db.ts} +10 -117
  80. package/src/cli/commands/{DeployCommands.ts → deploy.ts} +1 -1
  81. package/src/cli/commands/dev.ts +57 -0
  82. package/src/cli/commands/format.ts +17 -0
  83. package/src/cli/commands/{CoreCommands.ts → init.ts} +2 -40
  84. package/src/cli/commands/lint.ts +17 -0
  85. package/src/cli/commands/root.ts +32 -0
  86. package/src/cli/commands/run.ts +24 -0
  87. package/src/cli/commands/test.ts +42 -0
  88. package/src/cli/commands/typecheck.ts +19 -0
  89. package/src/cli/commands/{VerifyCommands.ts → verify.ts} +1 -13
  90. package/src/cli/defineConfig.ts +10 -1
  91. package/src/cli/index.ts +16 -7
  92. package/src/cli/services/GitMessageParser.ts +1 -1
  93. package/src/core/Alepha.ts +7 -4
  94. package/src/orm/index.browser.ts +1 -1
  95. package/src/orm/index.ts +10 -6
  96. package/src/orm/providers/{PostgresTypeProvider.ts → DatabaseTypeProvider.ts} +25 -3
  97. package/src/cli/commands/BiomeCommands.ts +0 -29
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 { $atom, $env, $hook, $inject, $module, $use, Alepha, AlephaError, OPTIONS, t } from "alepha";
3
+ import { $atom, $hook, $inject, $module, $use, Alepha, AlephaError, OPTIONS, t } from "alepha";
4
4
  import { FileSystemProvider } from "alepha/file";
5
+ import { access, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
5
6
  import { $command, CliProvider, EnvUtils } from "alepha/command";
6
7
  import { $logger } from "alepha/logger";
7
- import { exec, spawn } from "node:child_process";
8
- import { access, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
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({
@@ -587,26 +587,134 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
587
587
  };
588
588
 
589
589
  //#endregion
590
- //#region ../../src/cli/commands/BiomeCommands.ts
591
- var BiomeCommands = class {
590
+ //#region ../../src/cli/commands/build.ts
591
+ var BuildCommand = class {
592
592
  log = $logger();
593
593
  utils = $inject(AlephaCliUtils);
594
- format = $command({
595
- name: "format",
596
- description: "Format the codebase using Biome",
597
- handler: async ({ root }) => {
598
- await this.utils.ensureConfig(root, { biomeJson: true });
599
- await this.utils.ensureDependency(root, "@biomejs/biome");
600
- await this.utils.exec(`biome format --fix`);
601
- }
602
- });
603
- lint = $command({
604
- name: "lint",
605
- description: "Run linter across the codebase using Biome",
606
- handler: async ({ root }) => {
607
- await this.utils.ensureConfig(root, { biomeJson: true });
608
- await this.utils.ensureDependency(root, "@biomejs/biome");
609
- await this.utils.exec(`biome check --formatter-enabled=false --fix`);
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
+ }
610
718
  }
611
719
  });
612
720
  };
@@ -697,7 +805,7 @@ var GitMessageParser = class {
697
805
  };
698
806
 
699
807
  //#endregion
700
- //#region ../../src/cli/commands/ChangelogCommands.ts
808
+ //#region ../../src/cli/commands/changelog.ts
701
809
  const execAsync = promisify(exec);
702
810
  /**
703
811
  * Git provider for executing git commands.
@@ -718,7 +826,7 @@ var GitProvider = class {
718
826
  * - `alepha changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs
719
827
  * - `alepha changelog | tee -a CHANGELOG.md` - Append to file
720
828
  */
721
- var ChangelogCommands = class {
829
+ var ChangelogCommand = class {
722
830
  log = $logger();
723
831
  git = $inject(GitProvider);
724
832
  parser = $inject(GitMessageParser);
@@ -726,20 +834,17 @@ var ChangelogCommands = class {
726
834
  /**
727
835
  * Format a single commit line.
728
836
  * Example: `- **cli**: add new command (\`abc1234\`)`
837
+ * Breaking changes are flagged: `- **cli**: add new command [BREAKING] (\`abc1234\`)`
729
838
  */
730
839
  formatCommit(commit) {
731
- return `- **${commit.scope}**: ${commit.description} (\`${commit.hash}\`)`;
840
+ const breaking = commit.breaking ? " [BREAKING]" : "";
841
+ return `- **${commit.scope}**: ${commit.description}${breaking} (\`${commit.hash}\`)`;
732
842
  }
733
843
  /**
734
844
  * Format the changelog entry with sections.
735
845
  */
736
846
  formatEntry(entry) {
737
847
  const sections = [];
738
- if (entry.breaking.length > 0) {
739
- sections.push("### Breaking Changes\n");
740
- for (const commit of entry.breaking) sections.push(this.formatCommit(commit));
741
- sections.push("");
742
- }
743
848
  if (entry.features.length > 0) {
744
849
  sections.push("### Features\n");
745
850
  for (const commit of entry.features) sections.push(this.formatCommit(commit));
@@ -758,8 +863,7 @@ var ChangelogCommands = class {
758
863
  parseCommits(commitsOutput) {
759
864
  const entry = {
760
865
  features: [],
761
- fixes: [],
762
- breaking: []
866
+ fixes: []
763
867
  };
764
868
  for (const line of commitsOutput.trim().split("\n")) {
765
869
  if (!line.trim()) continue;
@@ -769,7 +873,6 @@ var ChangelogCommands = class {
769
873
  continue;
770
874
  }
771
875
  this.log.trace("Parsed commit", { commit });
772
- if (commit.breaking) entry.breaking.push(commit);
773
876
  if (commit.type === "feat") entry.features.push(commit);
774
877
  else if (commit.type === "fix") entry.fixes.push(commit);
775
878
  }
@@ -779,7 +882,7 @@ var ChangelogCommands = class {
779
882
  * Check if entry has any public commits.
780
883
  */
781
884
  hasChanges(entry) {
782
- return entry.features.length > 0 || entry.fixes.length > 0 || entry.breaking.length > 0;
885
+ return entry.features.length > 0 || entry.fixes.length > 0;
783
886
  }
784
887
  /**
785
888
  * Get the latest version tag.
@@ -833,28 +936,8 @@ var ChangelogCommands = class {
833
936
  };
834
937
 
835
938
  //#endregion
836
- //#region ../../src/cli/commands/CoreCommands.ts
837
- var CoreCommands = class {
838
- log = $logger();
839
- cli = $inject(CliProvider);
840
- utils = $inject(AlephaCliUtils);
841
- /**
842
- * Called when no command is provided
843
- */
844
- root = $command({
845
- root: true,
846
- flags: t.object({ version: t.optional(t.boolean({
847
- description: "Show Alepha CLI version",
848
- aliases: ["v"]
849
- })) }),
850
- handler: async ({ flags }) => {
851
- if (flags.version) {
852
- this.log.info(version);
853
- return;
854
- }
855
- this.cli.printHelp();
856
- }
857
- });
939
+ //#region ../../src/cli/commands/clean.ts
940
+ var CleanCommand = class {
858
941
  /**
859
942
  * Clean the project, removing the "dist" directory
860
943
  */
@@ -865,148 +948,19 @@ var CoreCommands = class {
865
948
  await run.rm("./dist");
866
949
  }
867
950
  });
868
- /**
869
- * Ensure the project has the necessary Alepha configuration files.
870
- * Add the correct dependencies to package.json and install them.
871
- */
872
- init = $command({
873
- name: "init",
874
- description: "Add missing Alepha configuration files to the project",
875
- flags: t.object({
876
- yarn: t.optional(t.boolean({ description: "Use Yarn package manager" })),
877
- pnpm: t.optional(t.boolean({ description: "Use pnpm package manager" })),
878
- npm: t.optional(t.boolean({ description: "Use npm package manager" })),
879
- bun: t.optional(t.boolean({ description: "Use Bun package manager" })),
880
- react: t.optional(t.boolean({ description: "Include Alepha React dependencies" })),
881
- ui: t.optional(t.boolean({ description: "Include Alepha UI dependencies" })),
882
- test: t.optional(t.boolean({ description: "Include Vitest and create test directory" }))
883
- }),
884
- handler: async ({ run, flags, root }) => {
885
- if (flags.ui) flags.react = true;
886
- const isExpo = await this.utils.hasExpo(root);
887
- await run({
888
- name: "ensuring configuration files",
889
- handler: async () => {
890
- await this.utils.ensureConfig(root, {
891
- tsconfigJson: true,
892
- packageJson: flags,
893
- biomeJson: true,
894
- viteConfigTs: !isExpo,
895
- editorconfig: true,
896
- indexHtml: !!flags.react && !isExpo
897
- });
898
- if (!flags.react) await this.utils.ensureSrcMain(root);
899
- }
900
- });
901
- const pm = await this.utils.getPackageManager(root, flags);
902
- if (pm === "yarn") {
903
- await this.utils.ensureYarn(root);
904
- await run("yarn set version stable");
905
- } else if (pm === "pnpm") await this.utils.ensurePnpm(root);
906
- else await this.utils.ensureNpm(root);
907
- await run(`${pm} install`, { alias: `installing dependencies with ${pm}` });
908
- if (!isExpo) await this.utils.ensureDependency(root, "vite", { run });
909
- await this.utils.ensureDependency(root, "@biomejs/biome", { run });
910
- if (flags.test) {
911
- await this.utils.ensureTestDir(root);
912
- await run(`${pm} ${pm === "yarn" ? "add" : "install"} -D vitest`, { alias: "setup testing with Vitest" });
913
- }
914
- }
915
- });
916
951
  };
917
952
 
918
953
  //#endregion
919
- //#region ../../src/cli/commands/DeployCommands.ts
920
- var DeployCommands = class {
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 {
921
960
  log = $logger();
922
961
  utils = $inject(AlephaCliUtils);
923
962
  /**
924
- * Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)
925
- *
926
- * Deploy command can be overridden by creating a alepha.config.ts in the project root:
927
- *
928
- * ```ts
929
- * import { defineConfig } from "alepha/cli";
930
- *
931
- * export default defineConfig({
932
- * commands: {
933
- * deploy: {
934
- * handler: async ({ root, mode, flags }) => {
935
- * // Custom deployment logic here
936
- * },
937
- * },
938
- * },
939
- * });
940
- * ```
941
- */
942
- deploy = $command({
943
- name: "deploy",
944
- description: "Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)",
945
- mode: true,
946
- flags: t.object({
947
- build: t.boolean({
948
- description: "Build the project before deployment",
949
- default: false
950
- }),
951
- migrate: t.boolean({
952
- description: "Run database migrations before deployment (if applicable)",
953
- default: false
954
- })
955
- }),
956
- env: t.object({
957
- VERCEL_TOKEN: t.optional(t.text({ description: "Vercel API token (e.g., xxxxxxxxxxxxxxxxxxxx)" })),
958
- VERCEL_ORG_ID: t.optional(t.text({ description: "Vercel organization ID (e.g., team_abc123...)" })),
959
- VERCEL_PROJECT_ID: t.optional(t.text({ description: "Vercel project ID (e.g., prj_abc123...)" })),
960
- CLOUDFLARE_API_TOKEN: t.optional(t.text({ description: "Cloudflare API token (e.g., xxxx-xxxx-xxxx-xxxx)" })),
961
- CLOUDFLARE_ACCOUNT_ID: t.optional(t.text({ description: "Cloudflare account ID (e.g., abc123def456...)" }))
962
- }),
963
- handler: async ({ root, mode, flags }) => {
964
- if (flags.build) await this.utils.exec("alepha build");
965
- if (await this.utils.exists(root, "dist/vercel.json")) {
966
- if (flags.migrate) {
967
- this.log.debug("Running database migrations before deployment...");
968
- await this.utils.exec(`alepha db migrate --mode=${mode}`);
969
- }
970
- await this.utils.ensureDependency(root, "vercel", { dev: true });
971
- const command = `vercel . --cwd=dist ${mode === "production" ? "--prod" : ""}`.trim();
972
- this.log.debug(`Deploying to Vercel with command: ${command}`);
973
- await this.utils.exec(command);
974
- return;
975
- }
976
- if (await this.utils.exists(root, "dist/wrangler.jsonc")) {
977
- if (flags.migrate) {
978
- this.log.debug("Running database migrations before deployment...");
979
- await this.utils.exec(`alepha db migrate --mode=${mode}`);
980
- }
981
- await this.utils.ensureDependency(root, "wrangler", { dev: true });
982
- const command = `wrangler deploy ${mode === "production" ? "" : "--env preview"} --config=dist/wrangler.jsonc`.trim();
983
- this.log.info(`Deploying to Cloudflare with command: ${command}`);
984
- await this.utils.exec(command);
985
- return;
986
- }
987
- if (await this.utils.exists(root, "dist/public/404.html")) {
988
- await this.utils.ensureDependency(root, "surge", { dev: true });
989
- const distPath = join(root, "dist/public");
990
- this.log.debug(`Deploying to Surge from directory: ${distPath}`);
991
- await this.utils.exec(`surge ${distPath}`);
992
- return;
993
- }
994
- throw new AlephaError("No deployment configuration found in the dist folder.");
995
- }
996
- });
997
- };
998
-
999
- //#endregion
1000
- //#region ../../src/cli/commands/DrizzleCommands.ts
1001
- const drizzleCommandFlags = t.object({
1002
- provider: t.optional(t.text({ description: "Database provider name to target (e.g., 'postgres', 'sqlite')" })),
1003
- 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" }))
1004
- });
1005
- var DrizzleCommands = class {
1006
- log = $logger();
1007
- utils = $inject(AlephaCliUtils);
1008
- /**
1009
- * Check if database migrations are up to date.
963
+ * Check if database migrations are up to date.
1010
964
  */
1011
965
  check = $command({
1012
966
  name: "check-migrations",
@@ -1031,7 +985,7 @@ var DrizzleCommands = class {
1031
985
  const migrationDir = join(rootDir, "migrations", providerName);
1032
986
  const journalFile = await readFile(`${migrationDir}/meta/_journal.json`, "utf-8").catch(() => null);
1033
987
  if (!journalFile) {
1034
- this.log.info(`No migration journal found.`);
988
+ this.log.info("No migration journal found.");
1035
989
  return;
1036
990
  }
1037
991
  const journal = JSON.parse(journalFile);
@@ -1068,12 +1022,6 @@ var DrizzleCommands = class {
1068
1022
  });
1069
1023
  /**
1070
1024
  * Generate database migration files
1071
- *
1072
- * - Loads the Alepha instance from the specified entry file.
1073
- * - Retrieves all repository primitives to gather database models.
1074
- * - Creates temporary entity definitions based on the current database schema.
1075
- * - Writes these definitions to a temporary schema file. (node_modules/.db/entities.ts)
1076
- * - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.
1077
1025
  */
1078
1026
  generate = $command({
1079
1027
  name: "generate",
@@ -1099,11 +1047,6 @@ var DrizzleCommands = class {
1099
1047
  });
1100
1048
  /**
1101
1049
  * Push database schema changes directly to the database
1102
- *
1103
- * - Loads the Alepha instance from the specified entry file.
1104
- * - Retrieves all repository primitives to gather database models.
1105
- * - Creates temporary entity definitions and Drizzle config.
1106
- * - Invokes Drizzle Kit's push command to apply schema changes directly.
1107
1050
  */
1108
1051
  push = $command({
1109
1052
  name: "push",
@@ -1127,11 +1070,6 @@ var DrizzleCommands = class {
1127
1070
  });
1128
1071
  /**
1129
1072
  * Apply pending database migrations
1130
- *
1131
- * - Loads the Alepha instance from the specified entry file.
1132
- * - Retrieves all repository primitives to gather database models.
1133
- * - Creates temporary entity definitions and Drizzle config.
1134
- * - Invokes Drizzle Kit's migrate command to apply pending migrations.
1135
1073
  */
1136
1074
  migrate = $command({
1137
1075
  name: "migrate",
@@ -1155,11 +1093,6 @@ var DrizzleCommands = class {
1155
1093
  });
1156
1094
  /**
1157
1095
  * Launch Drizzle Studio database browser
1158
- *
1159
- * - Loads the Alepha instance from the specified entry file.
1160
- * - Retrieves all repository primitives to gather database models.
1161
- * - Creates temporary entity definitions and Drizzle config.
1162
- * - Invokes Drizzle Kit's studio command to launch the web-based database browser.
1163
1096
  */
1164
1097
  studio = $command({
1165
1098
  name: "studio",
@@ -1200,11 +1133,6 @@ var DrizzleCommands = class {
1200
1133
  });
1201
1134
  /**
1202
1135
  * Run a drizzle-kit command for all database providers in an Alepha instance.
1203
- *
1204
- * Iterates through all repository providers, prepares Drizzle config for each,
1205
- * and executes the specified drizzle-kit command.
1206
- *
1207
- * @param options - Configuration including command to run, flags, and logging
1208
1136
  */
1209
1137
  async runDrizzleKitCommand(options) {
1210
1138
  const rootDir = options.root;
@@ -1243,12 +1171,6 @@ var DrizzleCommands = class {
1243
1171
  }
1244
1172
  /**
1245
1173
  * Prepare Drizzle configuration files for a database provider.
1246
- *
1247
- * Creates temporary entities.js and drizzle.config.js files needed
1248
- * for Drizzle Kit commands to run properly.
1249
- *
1250
- * @param options - Configuration options including kit, provider info, and paths
1251
- * @returns Path to the generated drizzle.config.js file
1252
1174
  */
1253
1175
  async prepareDrizzleConfig(options) {
1254
1176
  const models = Object.keys(options.kit.getModels(options.provider));
@@ -1288,73 +1210,91 @@ var DrizzleCommands = class {
1288
1210
  };
1289
1211
 
1290
1212
  //#endregion
1291
- //#region ../../src/cli/commands/VerifyCommands.ts
1292
- var VerifyCommands = class {
1213
+ //#region ../../src/cli/commands/deploy.ts
1214
+ var DeployCommand = class {
1215
+ log = $logger();
1293
1216
  utils = $inject(AlephaCliUtils);
1294
1217
  /**
1295
- * Run a series of verification commands to ensure code quality and correctness.
1218
+ * Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)
1296
1219
  *
1297
- * This command runs the following checks in order:
1298
- * - Clean the project
1299
- * - Format the code
1300
- * - Lint the code
1301
- * - Run tests (if Vitest is a dev dependency)
1302
- * - Check database migrations (if a migrations directory exists)
1303
- * - Type check the code
1304
- * - Build the project
1305
- * - Clean the project again
1306
- */
1307
- verify = $command({
1308
- name: "verify",
1309
- description: "Verify the Alepha project",
1310
- handler: async ({ root, run }) => {
1311
- await run("alepha clean");
1312
- await run("alepha format");
1313
- await run("alepha lint");
1314
- await run("alepha typecheck");
1315
- if ((await this.utils.readPackageJson(root)).devDependencies?.vitest) await run("alepha test");
1316
- if (await this.utils.exists(root, "migrations")) await run("alepha db:check-migrations");
1317
- if (!await this.utils.hasExpo(root)) await run("alepha build");
1318
- await run("alepha clean");
1319
- }
1320
- });
1321
- /**
1322
- * 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
+ * ```
1323
1235
  */
1324
- typecheck = $command({
1325
- name: "typecheck",
1326
- description: "Check TypeScript types across the codebase",
1327
- handler: async ({ root }) => {
1328
- await this.utils.ensureDependency(root, "typescript");
1329
- await this.utils.exec("tsc --noEmit");
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.");
1330
1289
  }
1331
1290
  });
1332
1291
  };
1333
1292
 
1334
1293
  //#endregion
1335
- //#region ../../src/cli/commands/ViteCommands.ts
1336
- var ViteCommands = class {
1294
+ //#region ../../src/cli/commands/dev.ts
1295
+ var DevCommand = class {
1337
1296
  log = $logger();
1338
1297
  utils = $inject(AlephaCliUtils);
1339
- env = $env(t.object({ VITEST_ARGS: t.string({ default: "" }) }));
1340
- run = $command({
1341
- name: "run",
1342
- hide: true,
1343
- description: "Run a TypeScript file directly",
1344
- flags: t.object({ watch: t.optional(t.boolean({
1345
- description: "Watch file for changes",
1346
- alias: "w"
1347
- })) }),
1348
- summary: false,
1349
- args: t.text({
1350
- title: "path",
1351
- description: "Filepath to run"
1352
- }),
1353
- handler: async ({ args, flags, root }) => {
1354
- await this.utils.ensureTsConfig(root);
1355
- await this.utils.exec(`tsx ${flags.watch ? "watch " : ""}${args}`);
1356
- }
1357
- });
1358
1298
  /**
1359
1299
  * Will run the project in watch mode.
1360
1300
  *
@@ -1375,7 +1315,7 @@ var ViteCommands = class {
1375
1315
  tsconfigJson: true
1376
1316
  });
1377
1317
  if (expo) {
1378
- await this.utils.exec(`expo start`);
1318
+ await this.utils.exec("expo start");
1379
1319
  return;
1380
1320
  }
1381
1321
  const entry = await boot.getServerEntry(root, args);
@@ -1385,141 +1325,153 @@ var ViteCommands = class {
1385
1325
  } catch {
1386
1326
  this.log.trace("No index.html found, running entry file with tsx");
1387
1327
  let cmd = "tsx --watch";
1388
- if (await this.utils.exists(root, ".env")) cmd += ` --env-file=./.env`;
1328
+ if (await this.utils.exists(root, ".env")) cmd += " --env-file=./.env";
1389
1329
  cmd += ` ${entry}`;
1390
1330
  await this.utils.exec(cmd);
1391
1331
  return;
1392
1332
  }
1393
1333
  await this.utils.ensureDependency(root, "vite");
1394
- await this.utils.exec(`vite`);
1334
+ await this.utils.exec("vite");
1395
1335
  }
1396
1336
  });
1397
- build = $command({
1398
- name: "build",
1399
- description: "Build the project for production",
1400
- args: t.optional(t.text({
1401
- title: "path",
1402
- description: "Filepath to build"
1403
- })),
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",
1404
1365
  flags: t.object({
1405
- stats: t.optional(t.boolean({ description: "Generate build stats report" })),
1406
- vercel: t.optional(t.boolean({ description: "Generate Vercel deployment configuration" })),
1407
- cloudflare: t.optional(t.boolean({ description: "Generate Cloudflare Workers configuration" })),
1408
- docker: t.optional(t.boolean({ description: "Generate Docker configuration" })),
1409
- sitemap: t.optional(t.text({ description: "Generate sitemap.xml with base URL" }))
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" }))
1410
1373
  }),
1411
- handler: async ({ flags, args, run, root }) => {
1412
- process.env.ALEPHA_BUILD_MODE = "cli";
1413
- process.env.NODE_ENV = "production";
1414
- if (await this.utils.hasExpo(root)) return;
1415
- await this.utils.ensureConfig(root, {
1416
- viteConfigTs: true,
1417
- tsconfigJson: true
1418
- });
1419
- const entry = await boot.getServerEntry(root, args);
1420
- this.log.trace("Entry file found", { entry });
1421
- const distDir = "dist";
1422
- const clientDir = "public";
1423
- await this.utils.ensureDependency(root, "vite", { run });
1424
- await run.rm("dist", { alias: "clean dist" });
1425
- const viteAlephaBuildOptions = (await createRequire(import.meta.url)("vite").resolveConfig({}, "build", "production")).plugins.find((it) => it.name === "alepha:build")?.[OPTIONS] || {};
1426
- await this.utils.loadEnv(root, [".env", ".env.production"]);
1427
- const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;
1428
- const hasServer = viteAlephaBuildOptions.serverEntry !== false;
1429
- let hasClient = false;
1430
- try {
1431
- await access(join(root, "index.html"));
1432
- hasClient = true;
1433
- } catch {}
1434
- const clientOptions = typeof viteAlephaBuildOptions.client === "object" ? viteAlephaBuildOptions.client : {};
1435
- if (hasClient) await run({
1436
- name: "vite build client",
1437
- handler: () => buildClient({
1438
- silent: true,
1439
- dist: `${distDir}/${clientDir}`,
1440
- stats,
1441
- precompress: clientOptions.precompress
1442
- })
1443
- });
1374
+ handler: async ({ run, flags, root }) => {
1375
+ if (flags.ui) flags.react = true;
1376
+ const isExpo = await this.utils.hasExpo(root);
1444
1377
  await run({
1445
- name: "vite build server",
1378
+ name: "ensuring configuration files",
1446
1379
  handler: async () => {
1447
- let clientBuilt = false;
1448
- try {
1449
- await readFile(`${distDir}/${clientDir}/index.html`, "utf-8");
1450
- clientBuilt = true;
1451
- } catch {}
1452
- await buildServer({
1453
- silent: true,
1454
- entry,
1455
- distDir,
1456
- clientDir: clientBuilt ? clientDir : void 0,
1457
- 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
1458
1387
  });
1459
- if (clientBuilt && hasServer) await unlink(`${distDir}/${clientDir}/index.html`);
1388
+ if (!flags.react) await this.utils.ensureSrcMain(root);
1460
1389
  }
1461
1390
  });
1462
- await copyAssets({
1463
- root,
1464
- entry: `${distDir}/index.js`,
1465
- distDir,
1466
- run
1467
- });
1468
- if (hasClient) {
1469
- const sitemapBaseUrl = flags.sitemap ?? clientOptions.sitemap?.hostname;
1470
- if (sitemapBaseUrl) await run({
1471
- name: "add sitemap",
1472
- handler: async () => {
1473
- await writeFile(`${distDir}/${clientDir}/sitemap.xml`, await generateSitemap({
1474
- entry: `${distDir}/index.js`,
1475
- baseUrl: sitemapBaseUrl
1476
- }));
1477
- }
1478
- });
1479
- if (clientOptions.prerender) await run({
1480
- name: "pre-render pages",
1481
- handler: async () => {
1482
- await prerenderPages({
1483
- dist: `${distDir}/${clientDir}`,
1484
- entry: `${distDir}/index.js`,
1485
- compress: clientOptions.precompress
1486
- });
1487
- }
1488
- });
1489
- }
1490
- if (flags.vercel || viteAlephaBuildOptions.vercel) {
1491
- const config = typeof viteAlephaBuildOptions.vercel === "object" ? viteAlephaBuildOptions.vercel : {};
1492
- await run({
1493
- name: "add Vercel config",
1494
- handler: () => generateVercel({
1495
- distDir,
1496
- clientDir,
1497
- config
1498
- })
1499
- });
1500
- }
1501
- if (flags.cloudflare || viteAlephaBuildOptions.cloudflare) {
1502
- const config = typeof viteAlephaBuildOptions.cloudflare === "boolean" ? {} : viteAlephaBuildOptions.cloudflare;
1503
- await run({
1504
- name: "add Cloudflare config",
1505
- handler: () => generateCloudflare({
1506
- distDir,
1507
- config
1508
- })
1509
- });
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" });
1510
1403
  }
1511
- if (flags.docker || viteAlephaBuildOptions.docker) {
1512
- const dockerConfig = typeof viteAlephaBuildOptions.docker === "object" ? viteAlephaBuildOptions.docker : {};
1513
- await run({
1514
- name: "add Docker config",
1515
- handler: () => generateDocker({
1516
- distDir,
1517
- ...dockerConfig
1518
- })
1519
- });
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;
1520
1441
  }
1442
+ this.cli.printHelp();
1443
+ }
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}`);
1521
1467
  }
1522
1468
  });
1469
+ };
1470
+
1471
+ //#endregion
1472
+ //#region ../../src/cli/commands/test.ts
1473
+ var TestCommand = class {
1474
+ utils = $inject(AlephaCliUtils);
1523
1475
  test = $command({
1524
1476
  name: "test",
1525
1477
  description: "Run tests using Vitest",
@@ -1543,6 +1495,56 @@ var ViteCommands = class {
1543
1495
  });
1544
1496
  };
1545
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");
1544
+ }
1545
+ });
1546
+ };
1547
+
1546
1548
  //#endregion
1547
1549
  //#region ../../src/cli/apps/AlephaCli.ts
1548
1550
  var AlephaCliExtension = class {
@@ -1563,13 +1565,21 @@ const AlephaCli = $module({
1563
1565
  name: "alepha.cli",
1564
1566
  services: [
1565
1567
  AlephaCliExtension,
1566
- BiomeCommands,
1567
- ChangelogCommands,
1568
- CoreCommands,
1569
- DeployCommands,
1570
- DrizzleCommands,
1571
- VerifyCommands,
1572
- ViteCommands
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
1573
1583
  ]
1574
1584
  });
1575
1585
 
@@ -1606,7 +1616,10 @@ var AlephaPackageBuilderCli = class {
1606
1616
  pkgData.exports["./tsconfig.base"] = "./tsconfig.base.json";
1607
1617
  pkgData.exports["./package.json"] = "./package.json";
1608
1618
  }
1609
- if (packageName === "@alepha/ui") pkgData.exports["./styles"] = "./styles.css";
1619
+ if (packageName === "@alepha/ui") {
1620
+ pkgData.exports["./styles"] = "./src/core/styles.css";
1621
+ pkgData.exports["./json/styles"] = "./src/json/styles.css";
1622
+ }
1610
1623
  await this.fs.writeFile("package.json", JSON.stringify(pkgData, null, 2));
1611
1624
  const tmpDir = join(root, "node_modules/.alepha");
1612
1625
  await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});
@@ -1767,11 +1780,16 @@ async function analyzeModules(srcDir, packageName) {
1767
1780
  //#region ../../src/cli/defineConfig.ts
1768
1781
  const defineConfig = (config) => {
1769
1782
  return (alepha) => {
1770
- const { commands } = config(alepha);
1783
+ const { commands, services = [] } = config(alepha);
1784
+ for (const it of services) alepha.with(it);
1771
1785
  return { ...commands };
1772
1786
  };
1773
1787
  };
1788
+ /**
1789
+ * @alias defineConfig
1790
+ */
1791
+ const defineAlephaConfig = defineConfig;
1774
1792
 
1775
1793
  //#endregion
1776
- export { AlephaCli, AlephaCliUtils, AlephaPackageBuilderCli, BiomeCommands, ChangelogCommands, CoreCommands, DEFAULT_IGNORE, DeployCommands, DrizzleCommands, GitMessageParser, GitProvider, VerifyCommands, ViteCommands, analyzeModules, changelogOptions, defineConfig, version };
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 };
1777
1795
  //# sourceMappingURL=index.js.map