alepha 0.13.5 → 0.13.7

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 (136) hide show
  1. package/dist/api-audits/index.browser.js +116 -0
  2. package/dist/api-audits/index.browser.js.map +1 -0
  3. package/dist/api-audits/index.d.ts +1194 -0
  4. package/dist/api-audits/index.js +674 -0
  5. package/dist/api-audits/index.js.map +1 -0
  6. package/dist/api-notifications/index.d.ts +147 -147
  7. package/dist/api-parameters/index.browser.js +36 -5
  8. package/dist/api-parameters/index.browser.js.map +1 -1
  9. package/dist/api-parameters/index.d.ts +711 -33
  10. package/dist/api-parameters/index.js +831 -17
  11. package/dist/api-parameters/index.js.map +1 -1
  12. package/dist/api-users/index.d.ts +16 -3
  13. package/dist/api-users/index.js +699 -19
  14. package/dist/api-users/index.js.map +1 -1
  15. package/dist/api-verifications/index.js +2 -1
  16. package/dist/api-verifications/index.js.map +1 -1
  17. package/dist/bin/index.js +1 -0
  18. package/dist/bin/index.js.map +1 -1
  19. package/dist/cli/index.d.ts +85 -31
  20. package/dist/cli/index.js +205 -33
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/command/index.d.ts +67 -6
  23. package/dist/command/index.js +30 -3
  24. package/dist/command/index.js.map +1 -1
  25. package/dist/core/index.browser.js +241 -61
  26. package/dist/core/index.browser.js.map +1 -1
  27. package/dist/core/index.d.ts +170 -90
  28. package/dist/core/index.js +264 -67
  29. package/dist/core/index.js.map +1 -1
  30. package/dist/core/index.native.js +248 -65
  31. package/dist/core/index.native.js.map +1 -1
  32. package/dist/email/index.js +15 -10554
  33. package/dist/email/index.js.map +1 -1
  34. package/dist/logger/index.d.ts +4 -4
  35. package/dist/logger/index.js +77 -72
  36. package/dist/logger/index.js.map +1 -1
  37. package/dist/orm/index.d.ts +5 -1
  38. package/dist/orm/index.js +24 -7
  39. package/dist/orm/index.js.map +1 -1
  40. package/dist/queue/index.d.ts +4 -4
  41. package/dist/redis/index.d.ts +10 -10
  42. package/dist/security/index.d.ts +28 -28
  43. package/dist/server/index.d.ts +10 -1
  44. package/dist/server/index.js +20 -6
  45. package/dist/server/index.js.map +1 -1
  46. package/dist/server-auth/index.d.ts +163 -152
  47. package/dist/server-auth/index.js +40 -10
  48. package/dist/server-auth/index.js.map +1 -1
  49. package/dist/server-cookies/index.js +5 -1
  50. package/dist/server-cookies/index.js.map +1 -1
  51. package/dist/server-links/index.d.ts +33 -33
  52. package/dist/server-security/index.d.ts +9 -9
  53. package/dist/thread/index.js +2 -2
  54. package/dist/thread/index.js.map +1 -1
  55. package/dist/vite/index.d.ts +2 -2
  56. package/dist/vite/index.js +102 -45
  57. package/dist/vite/index.js.map +1 -1
  58. package/dist/websocket/index.browser.js +3 -3
  59. package/dist/websocket/index.browser.js.map +1 -1
  60. package/dist/websocket/index.d.ts +7 -7
  61. package/dist/websocket/index.js +4 -4
  62. package/dist/websocket/index.js.map +1 -1
  63. package/package.json +14 -9
  64. package/src/api-audits/controllers/AuditController.ts +186 -0
  65. package/src/api-audits/entities/audits.ts +132 -0
  66. package/src/api-audits/index.browser.ts +18 -0
  67. package/src/api-audits/index.ts +58 -0
  68. package/src/api-audits/primitives/$audit.ts +159 -0
  69. package/src/api-audits/schemas/auditQuerySchema.ts +23 -0
  70. package/src/api-audits/schemas/auditResourceSchema.ts +9 -0
  71. package/src/api-audits/schemas/createAuditSchema.ts +27 -0
  72. package/src/api-audits/services/AuditService.ts +412 -0
  73. package/src/api-parameters/controllers/ConfigController.ts +324 -0
  74. package/src/api-parameters/entities/parameters.ts +93 -10
  75. package/src/api-parameters/index.ts +43 -4
  76. package/src/api-parameters/primitives/$config.ts +291 -19
  77. package/src/api-parameters/schedulers/ConfigActivationScheduler.ts +30 -0
  78. package/src/api-parameters/services/ConfigStore.ts +491 -0
  79. package/src/api-users/atoms/realmAuthSettingsAtom.ts +19 -0
  80. package/src/api-users/controllers/UserRealmController.ts +0 -2
  81. package/src/api-users/index.ts +2 -0
  82. package/src/api-users/primitives/$userRealm.ts +18 -3
  83. package/src/api-users/providers/UserRealmProvider.ts +6 -3
  84. package/src/api-users/services/RegistrationService.ts +2 -1
  85. package/src/api-users/services/SessionService.ts +4 -0
  86. package/src/api-users/services/UserService.ts +3 -0
  87. package/src/api-verifications/index.ts +7 -1
  88. package/src/bin/index.ts +1 -0
  89. package/src/cli/assets/biomeJson.ts +1 -1
  90. package/src/cli/assets/dummySpecTs.ts +7 -0
  91. package/src/cli/assets/editorconfig.ts +13 -0
  92. package/src/cli/assets/mainTs.ts +14 -0
  93. package/src/cli/commands/BiomeCommands.ts +2 -0
  94. package/src/cli/commands/CoreCommands.ts +28 -9
  95. package/src/cli/commands/VerifyCommands.ts +2 -1
  96. package/src/cli/commands/ViteCommands.ts +8 -9
  97. package/src/cli/services/AlephaCliUtils.ts +214 -23
  98. package/src/command/helpers/Asker.ts +0 -1
  99. package/src/command/primitives/$command.ts +67 -0
  100. package/src/command/providers/CliProvider.ts +39 -8
  101. package/src/core/Alepha.ts +40 -30
  102. package/src/core/helpers/jsonSchemaToTypeBox.ts +307 -0
  103. package/src/core/index.shared.ts +1 -0
  104. package/src/core/index.ts +30 -3
  105. package/src/core/providers/EventManager.ts +1 -1
  106. package/src/core/providers/StateManager.ts +23 -12
  107. package/src/core/providers/TypeProvider.ts +26 -34
  108. package/src/logger/index.ts +8 -6
  109. package/src/logger/primitives/$logger.ts +1 -1
  110. package/src/logger/providers/{SimpleFormatterProvider.ts → PrettyFormatterProvider.ts} +10 -1
  111. package/src/orm/index.ts +6 -0
  112. package/src/orm/services/PgRelationManager.ts +2 -2
  113. package/src/orm/services/PostgresModelBuilder.ts +11 -7
  114. package/src/orm/services/Repository.ts +16 -7
  115. package/src/orm/services/SqliteModelBuilder.ts +10 -0
  116. package/src/server/index.ts +6 -0
  117. package/src/server/primitives/$action.ts +10 -1
  118. package/src/server/providers/ServerBodyParserProvider.ts +11 -5
  119. package/src/server/providers/ServerRouterProvider.ts +13 -7
  120. package/src/server-auth/primitives/$auth.ts +7 -0
  121. package/src/server-auth/providers/ServerAuthProvider.ts +51 -8
  122. package/src/server-cookies/index.ts +2 -1
  123. package/src/thread/primitives/$thread.ts +2 -2
  124. package/src/vite/index.ts +0 -2
  125. package/src/vite/tasks/buildServer.ts +3 -4
  126. package/src/vite/tasks/generateCloudflare.ts +35 -19
  127. package/src/vite/tasks/generateDocker.ts +18 -4
  128. package/src/vite/tasks/generateSitemap.ts +5 -7
  129. package/src/vite/tasks/generateVercel.ts +76 -41
  130. package/src/vite/tasks/runAlepha.ts +16 -1
  131. package/src/websocket/providers/NodeWebSocketServerProvider.ts +3 -11
  132. package/src/websocket/services/WebSocketClient.ts +3 -3
  133. package/dist/cli/dist-BlfFtOk2.js +0 -2770
  134. package/dist/cli/dist-BlfFtOk2.js.map +0 -1
  135. package/src/api-parameters/controllers/ParameterController.ts +0 -45
  136. package/src/api-parameters/services/ParameterStore.ts +0 -23
package/dist/cli/index.js CHANGED
@@ -36,7 +36,7 @@ const biomeJson = `
36
36
  },
37
37
  "formatter": {
38
38
  "enabled": true,
39
- "indentStyle": "space"
39
+ "useEditorconfig": true
40
40
  },
41
41
  "linter": {
42
42
  "enabled": true,
@@ -57,6 +57,32 @@ const biomeJson = `
57
57
  }
58
58
  `.trim();
59
59
 
60
+ //#endregion
61
+ //#region ../../src/cli/assets/dummySpecTs.ts
62
+ const dummySpecTs = () => `
63
+ import { test, expect } from "vitest";
64
+
65
+ test("dummy test", () => {
66
+ expect(1 + 1).toBe(2);
67
+ });
68
+ `.trim();
69
+
70
+ //#endregion
71
+ //#region ../../src/cli/assets/editorconfig.ts
72
+ const editorconfig = `
73
+ # https://editorconfig.org
74
+
75
+ root = true
76
+
77
+ [*]
78
+ charset = utf-8
79
+ end_of_line = lf
80
+ insert_final_newline = true
81
+ trim_trailing_whitespace = true
82
+ indent_style = space
83
+ indent_size = 2
84
+ `.trim();
85
+
60
86
  //#endregion
61
87
  //#region ../../src/cli/assets/indexHtml.ts
62
88
  const indexHtml = (browserEntry) => `
@@ -86,6 +112,23 @@ alepha.with(AppRouter);
86
112
  run(alepha);
87
113
  `.trim();
88
114
 
115
+ //#endregion
116
+ //#region ../../src/cli/assets/mainTs.ts
117
+ const mainTs = () => `
118
+ import { Alepha, run } from "alepha";
119
+ import { $logger } from "alepha/logger";
120
+
121
+ const alepha = Alepha.create();
122
+
123
+ alepha.with(() => {
124
+ const log = $logger();
125
+
126
+ log.info("Hello from Alepha!");
127
+ });
128
+
129
+ run(alepha);
130
+ `.trim();
131
+
89
132
  //#endregion
90
133
  //#region ../../src/cli/assets/tsconfigJson.ts
91
134
  const tsconfigJson = `
@@ -132,34 +175,39 @@ var AlephaCliUtils = class {
132
175
  /**
133
176
  * Execute a command using npx with inherited stdio.
134
177
  *
135
- * @param command - The command to execute (will be passed to npx)
136
- * @param env - Optional environment variables to set for the command
137
- * @returns Promise that resolves when the process exits
138
- *
139
178
  * @example
140
179
  * ```ts
141
180
  * const runner = alepha.inject(ProcessRunner);
142
181
  * await runner.exec("tsx watch src/index.ts");
143
182
  * ```
144
183
  */
145
- async exec(command, env = {}) {
184
+ async exec(command, options = {}) {
146
185
  const root = process.cwd();
147
186
  this.log.debug(`Executing command: ${command}`, { cwd: root });
187
+ const runExec = async (app$1, args$1) => {
188
+ const prog = spawn(app$1, args$1, {
189
+ stdio: "inherit",
190
+ cwd: root,
191
+ env: {
192
+ ...process.env,
193
+ ...options.env
194
+ }
195
+ });
196
+ await new Promise((resolve) => prog.on("exit", () => {
197
+ resolve();
198
+ }));
199
+ };
200
+ if (options.global) {
201
+ const [app$1, ...args$1] = command.split(" ");
202
+ await runExec(app$1, args$1);
203
+ return;
204
+ }
148
205
  const suffix = process.platform === "win32" ? ".cmd" : "";
149
206
  const [app, ...args] = command.split(" ");
150
- const execPath = await this.checkFileExists(root, `node_modules/.bin/${app}${suffix}`, true);
207
+ let execPath = await this.checkFileExists(root, `node_modules/.bin/${app}${suffix}`, true);
208
+ if (!execPath) execPath = await this.checkFileExists(root, `node_modules/alepha/node_modules/.bin/${app}${suffix}`, true);
151
209
  if (!execPath) throw new AlephaError(`Could not find executable for command '${app}'. Make sure the package is installed.`);
152
- const prog = spawn(execPath, args, {
153
- stdio: "inherit",
154
- cwd: root,
155
- env: {
156
- ...process.env,
157
- ...env
158
- }
159
- });
160
- await new Promise((resolve) => prog.on("exit", () => {
161
- resolve();
162
- }));
210
+ await runExec(execPath, args);
163
211
  }
164
212
  /**
165
213
  * Write a configuration file to node_modules/.alepha directory.
@@ -197,6 +245,24 @@ var AlephaCliUtils = class {
197
245
  await this.fs.rm(join(root, "package-lock.json"), { force: true });
198
246
  await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
199
247
  }
248
+ async ensurePnpm(root) {
249
+ await this.fs.rm(join(root, "package-lock.json"), { force: true });
250
+ await this.fs.rm(join(root, "yarn.lock"), { force: true });
251
+ await this.fs.rm(join(root, ".yarn"), {
252
+ force: true,
253
+ recursive: true
254
+ });
255
+ await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
256
+ }
257
+ async ensureNpm(root) {
258
+ await this.fs.rm(join(root, "pnpm-lock.yaml"), { force: true });
259
+ await this.fs.rm(join(root, "yarn.lock"), { force: true });
260
+ await this.fs.rm(join(root, ".yarn"), {
261
+ force: true,
262
+ recursive: true
263
+ });
264
+ await this.fs.rm(join(root, ".yarnrc.yml"), { force: true });
265
+ }
200
266
  /**
201
267
  * Generate package.json content with Alepha dependencies.
202
268
  *
@@ -265,6 +331,7 @@ var AlephaCliUtils = class {
265
331
  if (opts.viteConfigTs) tasks.push(this.ensureViteConfig(root));
266
332
  if (opts.indexHtml) tasks.push(this.ensureIndexHtml(root));
267
333
  if (opts.biomeJson) tasks.push(this.ensureBiomeConfig(root));
334
+ if (opts.editorconfig) tasks.push(this.ensureEditorConfig(root));
268
335
  await Promise.all(tasks);
269
336
  }
270
337
  /**
@@ -321,6 +388,16 @@ var AlephaCliUtils = class {
321
388
  await this.ensureFileExists(root, "biome.json", biomeJson, true);
322
389
  }
323
390
  /**
391
+ * Ensure .editorconfig exists in the project.
392
+ *
393
+ * Creates a standard .editorconfig if none exists.
394
+ *
395
+ * @param root - The root directory of the project
396
+ */
397
+ async ensureEditorConfig(root) {
398
+ await this.ensureFileExists(root, ".editorconfig", editorconfig, true);
399
+ }
400
+ /**
324
401
  * Load Alepha instance from a server entry file.
325
402
  *
326
403
  * Dynamically imports the server entry file and extracts the Alepha instance.
@@ -454,10 +531,14 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
454
531
  rootDir
455
532
  });
456
533
  const flags = options.commandFlags ? ` ${options.commandFlags}` : "";
457
- await this.exec(`drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`, { NODE_OPTIONS: "--import tsx" });
534
+ await this.exec(`drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`, { env: { NODE_OPTIONS: "--import tsx" } });
458
535
  }
459
536
  }
460
- async getPackageManager(root) {
537
+ async getPackageManager(root, flags) {
538
+ if (flags?.yarn) return "yarn";
539
+ if (flags?.pnpm) return "pnpm";
540
+ if (flags?.npm) return "npm";
541
+ if (flags?.bun) return "bun";
461
542
  if (await this.checkFileExists(root, "yarn.lock", true)) return "yarn";
462
543
  if (await this.checkFileExists(root, "pnpm-lock.yaml", true)) return "pnpm";
463
544
  return "npm";
@@ -478,10 +559,91 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
478
559
  async exists(root, dirName) {
479
560
  return this.fs.exists(join(root, dirName));
480
561
  }
562
+ /**
563
+ * Ensure src/main.ts exists with a minimal Alepha bootstrap.
564
+ *
565
+ * Creates the src directory and main.ts file if the src directory
566
+ * doesn't exist or is empty.
567
+ *
568
+ * @param root - The root directory of the project
569
+ */
570
+ async ensureSrcMain(root) {
571
+ const srcDir = join(root, "src");
572
+ const mainPath = join(srcDir, "main.ts");
573
+ if (!await this.fs.exists(srcDir)) {
574
+ await this.fs.mkdir(srcDir, { recursive: true });
575
+ await this.fs.writeFile(mainPath, mainTs());
576
+ return;
577
+ }
578
+ if ((await this.fs.ls(srcDir)).length === 0) await this.fs.writeFile(mainPath, mainTs());
579
+ }
580
+ /**
581
+ * Ensure test directory exists with a dummy test file.
582
+ *
583
+ * Creates the test directory and a dummy.spec.ts file if the test directory
584
+ * doesn't exist or is empty.
585
+ *
586
+ * @param root - The root directory of the project
587
+ */
588
+ async ensureTestDir(root) {
589
+ const testDir = join(root, "test");
590
+ const dummyPath = join(testDir, "dummy.spec.ts");
591
+ if (!await this.fs.exists(testDir)) {
592
+ await this.fs.mkdir(testDir, { recursive: true });
593
+ await this.fs.writeFile(dummyPath, dummySpecTs());
594
+ return;
595
+ }
596
+ if ((await this.fs.ls(testDir)).length === 0) await this.fs.writeFile(dummyPath, dummySpecTs());
597
+ }
481
598
  async readPackageJson(root) {
482
599
  const packageJson$1 = await this.fs.createFile({ path: join(root, "package.json") }).text();
483
600
  return JSON.parse(packageJson$1);
484
601
  }
602
+ /**
603
+ * Check if a dependency is installed in the project.
604
+ *
605
+ * @param root - The root directory of the project
606
+ * @param packageName - The name of the package to check
607
+ * @returns True if the package is in dependencies or devDependencies
608
+ */
609
+ async hasDependency(root, packageName) {
610
+ try {
611
+ const pkg = await this.readPackageJson(root);
612
+ return !!(pkg.dependencies?.[packageName] || pkg.devDependencies?.[packageName]);
613
+ } catch {
614
+ return false;
615
+ }
616
+ }
617
+ /**
618
+ * Install a dependency if it's missing from the project.
619
+ *
620
+ * Automatically detects the package manager (yarn, pnpm, npm) and installs
621
+ * the package as a dev dependency if not already present.
622
+ */
623
+ async ensureDependency(root, packageName, options = {}) {
624
+ const { dev = true } = options;
625
+ if (await this.hasDependency(root, packageName)) {
626
+ this.log.debug(`Dependency '${packageName}' is already installed`);
627
+ return;
628
+ }
629
+ const pm = await this.getPackageManager(root);
630
+ let cmd;
631
+ switch (pm) {
632
+ case "yarn":
633
+ cmd = `yarn add ${dev ? "-D" : ""} ${packageName}`;
634
+ break;
635
+ case "pnpm":
636
+ cmd = `pnpm add ${dev ? "-D" : ""} ${packageName}`;
637
+ break;
638
+ default: cmd = `npm install ${dev ? "--save-dev" : ""} ${packageName}`;
639
+ }
640
+ cmd = cmd.replace(/\s+/g, " ").trim();
641
+ if (options.run) await options.run(cmd, { alias: `installing ${packageName}` });
642
+ else {
643
+ this.log.debug(`Installing ${packageName}`);
644
+ await this.exec(cmd, { global: true });
645
+ }
646
+ }
485
647
  };
486
648
 
487
649
  //#endregion
@@ -494,6 +656,7 @@ var BiomeCommands = class {
494
656
  description: "Format the codebase using Biome",
495
657
  handler: async ({ root }) => {
496
658
  await this.utils.ensureConfig(root, { biomeJson: true });
659
+ await this.utils.ensureDependency(root, "@biomejs/biome");
497
660
  await this.utils.exec(`biome format --fix`);
498
661
  }
499
662
  });
@@ -502,6 +665,7 @@ var BiomeCommands = class {
502
665
  description: "Run linter across the codebase using Biome",
503
666
  handler: async ({ root }) => {
504
667
  await this.utils.ensureConfig(root, { biomeJson: true });
668
+ await this.utils.ensureDependency(root, "@biomejs/biome");
505
669
  await this.utils.exec(`biome check --formatter-enabled=false --fix`);
506
670
  }
507
671
  });
@@ -550,29 +714,39 @@ var CoreCommands = class {
550
714
  flags: t.object({
551
715
  yarn: t.optional(t.boolean({ description: "Use Yarn package manager" })),
552
716
  pnpm: t.optional(t.boolean({ description: "Use pnpm package manager" })),
717
+ npm: t.optional(t.boolean({ description: "Use npm package manager" })),
718
+ bun: t.optional(t.boolean({ description: "Use Bun package manager" })),
553
719
  react: t.optional(t.boolean({ description: "Include Alepha React dependencies" })),
554
- ui: t.optional(t.boolean({ description: "Include Alepha UI dependencies" }))
720
+ ui: t.optional(t.boolean({ description: "Include Alepha UI dependencies" })),
721
+ test: t.optional(t.boolean({ description: "Include Vitest and create test directory" }))
555
722
  }),
556
723
  handler: async ({ run, flags, root }) => {
557
724
  if (flags.ui) flags.react = true;
558
725
  await run({
559
- name: "Ensuring configuration files",
726
+ name: "ensuring configuration files",
560
727
  handler: async () => {
561
728
  await this.utils.ensureConfig(root, {
562
729
  tsconfigJson: true,
563
730
  packageJson: flags,
564
731
  biomeJson: true,
565
732
  viteConfigTs: true,
733
+ editorconfig: true,
566
734
  indexHtml: !!flags.react
567
735
  });
736
+ if (!flags.react) await this.utils.ensureSrcMain(root);
568
737
  }
569
738
  });
570
- const guessedPm = await this.utils.getPackageManager(root);
571
- if (flags.yarn || guessedPm === "yarn") {
739
+ const pm = await this.utils.getPackageManager(root, flags);
740
+ if (pm === "yarn") {
572
741
  await this.utils.ensureYarn(root);
573
742
  await run("yarn set version stable");
574
- await run("yarn install", { alias: "Installing dependencies with Yarn" });
575
- } else await run("npm install", { alias: "Installing dependencies with npm" });
743
+ } else if (pm === "pnpm") await this.utils.ensurePnpm(root);
744
+ else await this.utils.ensureNpm(root);
745
+ await run(`${pm} install`, { alias: `installing dependencies with ${pm}` });
746
+ if (flags.test) {
747
+ await this.utils.ensureTestDir(root);
748
+ await run(`${pm} ${pm === "yarn" ? "add" : "install"} -D vitest`, { alias: "setup testing with Vitest" });
749
+ }
576
750
  }
577
751
  });
578
752
  };
@@ -794,7 +968,8 @@ var VerifyCommands = class {
794
968
  typecheck = $command({
795
969
  name: "typecheck",
796
970
  description: "Check TypeScript types across the codebase",
797
- handler: async () => {
971
+ handler: async ({ root }) => {
972
+ await this.utils.ensureDependency(root, "typescript");
798
973
  await this.utils.exec("tsc --noEmit");
799
974
  }
800
975
  });
@@ -853,6 +1028,7 @@ var ViteCommands = class {
853
1028
  await this.utils.exec(cmd);
854
1029
  return;
855
1030
  }
1031
+ await this.utils.ensureDependency(root, "vite");
856
1032
  await this.utils.exec(`vite`);
857
1033
  }
858
1034
  });
@@ -881,6 +1057,7 @@ var ViteCommands = class {
881
1057
  this.log.trace("Entry file found", { entry });
882
1058
  const distDir = "dist";
883
1059
  const clientDir = "public";
1060
+ await this.utils.ensureDependency(root, "vite", { run });
884
1061
  await run.rm("dist", { alias: "clean dist" });
885
1062
  const viteAlephaBuildOptions = (await import(join(root, "vite.config.ts")))?.default?.plugins.find((it) => !!it[OPTIONS])?.[OPTIONS] ?? {};
886
1063
  const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;
@@ -979,12 +1156,7 @@ var ViteCommands = class {
979
1156
  tsconfigJson: true,
980
1157
  viteConfigTs: true
981
1158
  });
982
- try {
983
- await import("./dist-BlfFtOk2.js");
984
- } catch {
985
- this.log.error("Vitest is not installed. Please install it with `npm install -D vitest` or `yarn add -D vitest`.");
986
- process.exit(1);
987
- }
1159
+ await this.utils.ensureDependency(root, "vitest");
988
1160
  await this.utils.exec(`vitest run ${this.env.VITEST_ARGS}`);
989
1161
  }
990
1162
  });