alepha 0.13.8 → 0.14.1
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/dist/api/audits/index.d.ts +418 -338
- package/dist/api/audits/index.d.ts.map +1 -0
- package/dist/api/files/index.d.ts +81 -1
- package/dist/api/files/index.d.ts.map +1 -0
- package/dist/api/jobs/index.d.ts +107 -27
- package/dist/api/jobs/index.d.ts.map +1 -0
- package/dist/api/notifications/index.d.ts +21 -1
- package/dist/api/notifications/index.d.ts.map +1 -0
- package/dist/api/parameters/index.d.ts +455 -8
- package/dist/api/parameters/index.d.ts.map +1 -0
- package/dist/api/users/index.d.ts +844 -840
- package/dist/api/users/index.d.ts.map +1 -0
- package/dist/api/verifications/index.d.ts.map +1 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/bucket/index.d.ts.map +1 -0
- package/dist/cache/core/index.d.ts.map +1 -0
- package/dist/cache/redis/index.d.ts.map +1 -0
- package/dist/cli/index.d.ts +254 -59
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +499 -127
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +217 -10
- package/dist/command/index.d.ts.map +1 -0
- package/dist/command/index.js +350 -74
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +1334 -1318
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +76 -72
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +1337 -1321
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +1337 -1321
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts.map +1 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/fake/index.d.ts.map +1 -0
- package/dist/file/index.d.ts.map +1 -0
- package/dist/file/index.js.map +1 -1
- package/dist/lock/core/index.d.ts.map +1 -0
- package/dist/lock/redis/index.d.ts.map +1 -0
- package/dist/logger/index.d.ts +1 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +820 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +978 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/orm/index.d.ts +234 -107
- package/dist/orm/index.d.ts.map +1 -0
- package/dist/orm/index.js +376 -316
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +4 -4
- package/dist/queue/core/index.d.ts.map +1 -0
- package/dist/queue/redis/index.d.ts.map +1 -0
- 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 -0
- package/dist/redis/index.js +412 -21
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts.map +1 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/security/index.d.ts +28 -28
- package/dist/security/index.d.ts.map +1 -0
- package/dist/server/auth/index.d.ts +155 -155
- package/dist/server/auth/index.d.ts.map +1 -0
- package/dist/server/cache/index.d.ts.map +1 -0
- package/dist/server/compress/index.d.ts.map +1 -0
- package/dist/server/cookies/index.d.ts.map +1 -0
- package/dist/server/core/index.d.ts +0 -1
- package/dist/server/core/index.d.ts.map +1 -0
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts.map +1 -0
- package/dist/server/health/index.d.ts +17 -17
- package/dist/server/health/index.d.ts.map +1 -0
- package/dist/server/helmet/index.d.ts +4 -1
- package/dist/server/helmet/index.d.ts.map +1 -0
- package/dist/server/links/index.d.ts +33 -33
- package/dist/server/links/index.d.ts.map +1 -0
- package/dist/server/metrics/index.d.ts.map +1 -0
- package/dist/server/multipart/index.d.ts.map +1 -0
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts.map +1 -0
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts.map +1 -0
- package/dist/server/security/index.d.ts +9 -9
- package/dist/server/security/index.d.ts.map +1 -0
- package/dist/server/static/index.d.ts.map +1 -0
- package/dist/server/swagger/index.d.ts.map +1 -0
- package/dist/sms/index.d.ts.map +1 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/topic/core/index.d.ts.map +1 -0
- package/dist/topic/redis/index.d.ts.map +1 -0
- package/dist/topic/redis/index.js +3 -3
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/vite/index.d.ts +10 -2
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +45 -20
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts.map +1 -0
- package/package.json +9 -4
- package/src/cli/apps/AlephaCli.ts +10 -3
- package/src/cli/apps/AlephaPackageBuilderCli.ts +15 -8
- package/src/cli/assets/mainTs.ts +9 -10
- package/src/cli/atoms/changelogOptions.ts +45 -0
- package/src/cli/commands/ChangelogCommands.ts +259 -0
- package/src/cli/commands/DeployCommands.ts +118 -0
- package/src/cli/commands/DrizzleCommands.ts +230 -10
- package/src/cli/commands/ViteCommands.ts +47 -23
- package/src/cli/defineConfig.ts +15 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/services/AlephaCliUtils.ts +10 -154
- 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 +499 -95
- package/src/core/Alepha.ts +1 -1
- package/src/core/providers/SchemaValidator.ts +23 -1
- package/src/file/providers/NodeFileSystemProvider.ts +3 -1
- package/src/mcp/errors/McpError.ts +72 -0
- package/src/mcp/helpers/jsonrpc.ts +163 -0
- package/src/mcp/index.ts +132 -0
- package/src/mcp/interfaces/McpTypes.ts +248 -0
- package/src/mcp/primitives/$prompt.ts +188 -0
- package/src/mcp/primitives/$resource.ts +171 -0
- package/src/mcp/primitives/$tool.ts +285 -0
- package/src/mcp/providers/McpServerProvider.ts +382 -0
- package/src/mcp/transports/SseMcpTransport.ts +172 -0
- package/src/mcp/transports/StdioMcpTransport.ts +126 -0
- package/src/orm/index.ts +20 -4
- package/src/orm/interfaces/PgQueryWhere.ts +1 -26
- package/src/orm/providers/drivers/BunPostgresProvider.ts +225 -0
- package/src/orm/providers/drivers/BunSqliteProvider.ts +180 -0
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +164 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +25 -0
- package/src/orm/providers/drivers/NodePostgresProvider.ts +0 -25
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +3 -1
- 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/plugins/viteAlephaBuild.ts +8 -2
- package/src/vite/plugins/viteAlephaDev.ts +6 -2
- package/src/vite/tasks/buildServer.ts +2 -1
- package/src/vite/tasks/generateCloudflare.ts +43 -15
- package/src/vite/tasks/runAlepha.ts +1 -0
- package/src/orm/services/PgJsonQueryManager.ts +0 -511
package/dist/cli/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { join } from "node:path";
|
|
2
|
-
import { $env, $hook, $inject, $module, Alepha, AlephaError, OPTIONS, t } from "alepha";
|
|
3
|
+
import { $atom, $env, $hook, $inject, $module, $use, Alepha, AlephaError, OPTIONS, t } from "alepha";
|
|
3
4
|
import { FileSystemProvider } from "alepha/file";
|
|
4
|
-
import { $command, CliProvider } from "alepha/command";
|
|
5
|
+
import { $command, CliProvider, EnvUtils } from "alepha/command";
|
|
5
6
|
import { $logger } from "alepha/logger";
|
|
6
|
-
import { spawn } from "node:child_process";
|
|
7
|
+
import { exec, spawn } from "node:child_process";
|
|
7
8
|
import { access, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
|
|
8
9
|
import { boot, buildClient, buildServer, copyAssets, generateCloudflare, generateDocker, generateSitemap, generateVercel, prerenderPages } from "alepha/vite";
|
|
9
10
|
import { tsImport } from "tsx/esm/api";
|
|
10
11
|
import { readFileSync } from "node:fs";
|
|
12
|
+
import { promisify } from "node:util";
|
|
11
13
|
import * as os from "node:os";
|
|
12
14
|
|
|
13
15
|
//#region ../../src/cli/assets/appRouterTs.ts
|
|
@@ -115,18 +117,17 @@ run(alepha);
|
|
|
115
117
|
//#endregion
|
|
116
118
|
//#region ../../src/cli/assets/mainTs.ts
|
|
117
119
|
const mainTs = () => `
|
|
118
|
-
import {
|
|
119
|
-
import { $
|
|
120
|
-
|
|
121
|
-
const alepha = Alepha.create();
|
|
120
|
+
import { run } from "alepha";
|
|
121
|
+
import { $route } from "alepha/server";
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
123
|
+
class App {
|
|
124
|
+
root = $route({
|
|
125
|
+
path: "/",
|
|
126
|
+
handler: () => "Hello, Alepha!",
|
|
127
|
+
});
|
|
128
|
+
}
|
|
128
129
|
|
|
129
|
-
run(
|
|
130
|
+
run(App);
|
|
130
131
|
`.trim();
|
|
131
132
|
|
|
132
133
|
//#endregion
|
|
@@ -172,6 +173,7 @@ const version = packageJson.version;
|
|
|
172
173
|
var AlephaCliUtils = class {
|
|
173
174
|
log = $logger();
|
|
174
175
|
fs = $inject(FileSystemProvider);
|
|
176
|
+
envUtils = $inject(EnvUtils);
|
|
175
177
|
/**
|
|
176
178
|
* Execute a command using npx with inherited stdio.
|
|
177
179
|
*
|
|
@@ -455,89 +457,13 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
|
|
|
455
457
|
`.trim();
|
|
456
458
|
}
|
|
457
459
|
/**
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
* Creates temporary entities.js and drizzle.config.js files needed
|
|
461
|
-
* for Drizzle Kit commands to run properly.
|
|
460
|
+
* Load environment variables from a .env file.
|
|
462
461
|
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
462
|
+
* Reads the .env file in the specified root directory and sets
|
|
463
|
+
* the environment variables in process.env.
|
|
465
464
|
*/
|
|
466
|
-
async
|
|
467
|
-
|
|
468
|
-
const entitiesJs = this.generateEntitiesJs(options.entry, options.providerName, models);
|
|
469
|
-
const config = {
|
|
470
|
-
schema: await this.writeConfigFile("entities.js", entitiesJs, options.rootDir),
|
|
471
|
-
out: `./migrations/${options.providerName}`,
|
|
472
|
-
dialect: options.dialect,
|
|
473
|
-
dbCredentials: { url: options.providerUrl }
|
|
474
|
-
};
|
|
475
|
-
if (options.dialect === "sqlite") {
|
|
476
|
-
let url = options.providerUrl;
|
|
477
|
-
url = url.replace("sqlite://", "").replace("file://", "");
|
|
478
|
-
url = join(options.rootDir, url);
|
|
479
|
-
config.dbCredentials = { url };
|
|
480
|
-
}
|
|
481
|
-
if (options.providerName === "pglite") config.driver = "pglite";
|
|
482
|
-
const drizzleConfigJs = `export default ${JSON.stringify(config, null, 2)}`;
|
|
483
|
-
return await this.writeConfigFile("drizzle.config.js", drizzleConfigJs, options.rootDir);
|
|
484
|
-
}
|
|
485
|
-
async loadEnvFile(root) {
|
|
486
|
-
const envPath = join(root, ".env");
|
|
487
|
-
try {
|
|
488
|
-
const lines = (await readFile(envPath, "utf8")).split("\n");
|
|
489
|
-
for (const line of lines) {
|
|
490
|
-
const [key, ...rest] = line.split("=");
|
|
491
|
-
if (key) {
|
|
492
|
-
const value = rest.join("=");
|
|
493
|
-
process.env[key.trim()] = value.trim();
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
this.log.debug(`Loaded environment variables from ${envPath}`);
|
|
497
|
-
} catch {
|
|
498
|
-
this.log.debug(`No .env file found at ${envPath}, skipping load.`);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
/**
|
|
502
|
-
* Run a drizzle-kit command for all database providers in an Alepha instance.
|
|
503
|
-
*
|
|
504
|
-
* Iterates through all repository providers, prepares Drizzle config for each,
|
|
505
|
-
* and executes the specified drizzle-kit command.
|
|
506
|
-
*
|
|
507
|
-
* @param options - Configuration including command to run, flags, and logging
|
|
508
|
-
*/
|
|
509
|
-
async runDrizzleKitCommand(options) {
|
|
510
|
-
const rootDir = options.root;
|
|
511
|
-
await this.loadEnvFile(rootDir);
|
|
512
|
-
this.log.debug(`Using project root: ${rootDir}`);
|
|
513
|
-
const { alepha, entry } = await this.loadAlephaFromServerEntryFile(rootDir, options.args);
|
|
514
|
-
const drizzleKitProvider = alepha.inject("DrizzleKitProvider");
|
|
515
|
-
const repositoryProvider = alepha.inject("RepositoryProvider");
|
|
516
|
-
const accepted = /* @__PURE__ */ new Set([]);
|
|
517
|
-
for (const primitive of repositoryProvider.getRepositories()) {
|
|
518
|
-
const provider = primitive.provider;
|
|
519
|
-
const providerName = provider.name;
|
|
520
|
-
const dialect = provider.dialect;
|
|
521
|
-
if (accepted.has(providerName)) continue;
|
|
522
|
-
accepted.add(providerName);
|
|
523
|
-
if (options.provider && options.provider !== providerName) {
|
|
524
|
-
this.log.debug(`Skipping provider '${providerName}' (filter: ${options.provider})`);
|
|
525
|
-
continue;
|
|
526
|
-
}
|
|
527
|
-
this.log.info("");
|
|
528
|
-
this.log.info(options.logMessage(providerName, dialect));
|
|
529
|
-
const drizzleConfigJsPath = await this.prepareDrizzleConfig({
|
|
530
|
-
kit: drizzleKitProvider,
|
|
531
|
-
provider,
|
|
532
|
-
providerName,
|
|
533
|
-
providerUrl: provider.url,
|
|
534
|
-
dialect,
|
|
535
|
-
entry,
|
|
536
|
-
rootDir
|
|
537
|
-
});
|
|
538
|
-
const flags = options.commandFlags ? ` ${options.commandFlags}` : "";
|
|
539
|
-
await this.exec(`drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`, { env: { NODE_OPTIONS: "--import tsx" } });
|
|
540
|
-
}
|
|
465
|
+
async loadEnv(root, files = [".env"]) {
|
|
466
|
+
await this.envUtils.loadEnv(root, files);
|
|
541
467
|
}
|
|
542
468
|
async getPackageManager(root, flags) {
|
|
543
469
|
if (flags?.yarn) return "yarn";
|
|
@@ -685,6 +611,227 @@ var BiomeCommands = class {
|
|
|
685
611
|
});
|
|
686
612
|
};
|
|
687
613
|
|
|
614
|
+
//#endregion
|
|
615
|
+
//#region ../../src/cli/atoms/changelogOptions.ts
|
|
616
|
+
/**
|
|
617
|
+
* Default scopes to ignore in changelog generation.
|
|
618
|
+
* Commits with these scopes won't appear in release notes.
|
|
619
|
+
*/
|
|
620
|
+
const DEFAULT_IGNORE = [
|
|
621
|
+
"project",
|
|
622
|
+
"release",
|
|
623
|
+
"starter",
|
|
624
|
+
"example",
|
|
625
|
+
"chore",
|
|
626
|
+
"ci",
|
|
627
|
+
"build",
|
|
628
|
+
"test",
|
|
629
|
+
"style"
|
|
630
|
+
];
|
|
631
|
+
/**
|
|
632
|
+
* Changelog configuration atom.
|
|
633
|
+
*
|
|
634
|
+
* Configure in `alepha.config.ts`:
|
|
635
|
+
* ```ts
|
|
636
|
+
* import { changelogOptions } from "alepha/cli";
|
|
637
|
+
*
|
|
638
|
+
* alepha.set(changelogOptions, {
|
|
639
|
+
* ignore: ["project", "release", "chore", "docs"],
|
|
640
|
+
* });
|
|
641
|
+
* ```
|
|
642
|
+
*/
|
|
643
|
+
const changelogOptions = $atom({
|
|
644
|
+
name: "alepha.changelog",
|
|
645
|
+
schema: t.object({ ignore: t.optional(t.array(t.string())) }),
|
|
646
|
+
default: { ignore: DEFAULT_IGNORE }
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
//#endregion
|
|
650
|
+
//#region ../../src/cli/services/GitMessageParser.ts
|
|
651
|
+
/**
|
|
652
|
+
* Service for parsing git commit messages into structured format.
|
|
653
|
+
*
|
|
654
|
+
* Only parses **conventional commits with a scope**:
|
|
655
|
+
* - `feat(scope): description` → feature
|
|
656
|
+
* - `fix(scope): description` → bug fix
|
|
657
|
+
* - `feat(scope)!: description` → breaking change
|
|
658
|
+
*
|
|
659
|
+
* Commits without scope are ignored, allowing developers to commit
|
|
660
|
+
* work-in-progress changes without polluting release notes:
|
|
661
|
+
* - `cli: work in progress` → ignored (no type)
|
|
662
|
+
* - `fix: quick patch` → ignored (no scope)
|
|
663
|
+
* - `feat(cli): add command` → included
|
|
664
|
+
*/
|
|
665
|
+
var GitMessageParser = class {
|
|
666
|
+
log = $logger();
|
|
667
|
+
/**
|
|
668
|
+
* Parse a git commit line into a structured Commit object.
|
|
669
|
+
*
|
|
670
|
+
* **Format:** `type(scope): description` or `type(scope)!: description`
|
|
671
|
+
*
|
|
672
|
+
* **Supported types:** feat, fix, docs, refactor, perf, revert
|
|
673
|
+
*
|
|
674
|
+
* **Breaking changes:** Use `!` before `:` (e.g., `feat(api)!: remove endpoint`)
|
|
675
|
+
*
|
|
676
|
+
* @returns Commit object or null if not matching/ignored
|
|
677
|
+
*/
|
|
678
|
+
parseCommit(line, config) {
|
|
679
|
+
const match = line.match(/^([a-f0-9]+)\s+(.+)$/);
|
|
680
|
+
if (!match) return null;
|
|
681
|
+
const [, hash, message] = match;
|
|
682
|
+
const ignore = config.ignore ?? DEFAULT_IGNORE;
|
|
683
|
+
const conventionalMatch = message.match(/^(feat|fix|docs|refactor|perf|revert)\(([^)]+)\)(!)?:\s*(.+)$/i);
|
|
684
|
+
if (!conventionalMatch) return null;
|
|
685
|
+
const [, type, scope, breakingMark, description] = conventionalMatch;
|
|
686
|
+
const baseScope = scope.split("/")[0];
|
|
687
|
+
if (ignore.includes(baseScope) || ignore.includes(scope)) return null;
|
|
688
|
+
const breaking = breakingMark === "!" || description.toLowerCase().includes("breaking");
|
|
689
|
+
return {
|
|
690
|
+
hash: hash.substring(0, 8),
|
|
691
|
+
type: type.toLowerCase(),
|
|
692
|
+
scope,
|
|
693
|
+
description: description.trim(),
|
|
694
|
+
breaking
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
//#endregion
|
|
700
|
+
//#region ../../src/cli/commands/ChangelogCommands.ts
|
|
701
|
+
const execAsync = promisify(exec);
|
|
702
|
+
/**
|
|
703
|
+
* Git provider for executing git commands.
|
|
704
|
+
* Can be substituted in tests with a mock implementation.
|
|
705
|
+
*/
|
|
706
|
+
var GitProvider = class {
|
|
707
|
+
async exec(cmd, cwd) {
|
|
708
|
+
const { stdout } = await execAsync(`git ${cmd}`, { cwd });
|
|
709
|
+
return stdout;
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
/**
|
|
713
|
+
* Changelog command for generating release notes from git commits.
|
|
714
|
+
*
|
|
715
|
+
* Usage:
|
|
716
|
+
* - `alepha changelog` - Show unreleased changes since latest tag to HEAD
|
|
717
|
+
* - `alepha changelog --from=1.0.0` - Show changes from version to HEAD
|
|
718
|
+
* - `alepha changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs
|
|
719
|
+
* - `alepha changelog | tee -a CHANGELOG.md` - Append to file
|
|
720
|
+
*/
|
|
721
|
+
var ChangelogCommands = class {
|
|
722
|
+
log = $logger();
|
|
723
|
+
git = $inject(GitProvider);
|
|
724
|
+
parser = $inject(GitMessageParser);
|
|
725
|
+
config = $use(changelogOptions);
|
|
726
|
+
/**
|
|
727
|
+
* Format a single commit line.
|
|
728
|
+
* Example: `- **cli**: add new command (\`abc1234\`)`
|
|
729
|
+
*/
|
|
730
|
+
formatCommit(commit) {
|
|
731
|
+
return `- **${commit.scope}**: ${commit.description} (\`${commit.hash}\`)`;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Format the changelog entry with sections.
|
|
735
|
+
*/
|
|
736
|
+
formatEntry(entry) {
|
|
737
|
+
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
|
+
if (entry.features.length > 0) {
|
|
744
|
+
sections.push("### Features\n");
|
|
745
|
+
for (const commit of entry.features) sections.push(this.formatCommit(commit));
|
|
746
|
+
sections.push("");
|
|
747
|
+
}
|
|
748
|
+
if (entry.fixes.length > 0) {
|
|
749
|
+
sections.push("### Bug Fixes\n");
|
|
750
|
+
for (const commit of entry.fixes) sections.push(this.formatCommit(commit));
|
|
751
|
+
sections.push("");
|
|
752
|
+
}
|
|
753
|
+
return sections.join("\n");
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Parse git log output into a changelog entry.
|
|
757
|
+
*/
|
|
758
|
+
parseCommits(commitsOutput) {
|
|
759
|
+
const entry = {
|
|
760
|
+
features: [],
|
|
761
|
+
fixes: [],
|
|
762
|
+
breaking: []
|
|
763
|
+
};
|
|
764
|
+
for (const line of commitsOutput.trim().split("\n")) {
|
|
765
|
+
if (!line.trim()) continue;
|
|
766
|
+
const commit = this.parser.parseCommit(line, this.config);
|
|
767
|
+
if (!commit) {
|
|
768
|
+
this.log.trace("Skipping commit", { line });
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
this.log.trace("Parsed commit", { commit });
|
|
772
|
+
if (commit.breaking) entry.breaking.push(commit);
|
|
773
|
+
if (commit.type === "feat") entry.features.push(commit);
|
|
774
|
+
else if (commit.type === "fix") entry.fixes.push(commit);
|
|
775
|
+
}
|
|
776
|
+
return entry;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Check if entry has any public commits.
|
|
780
|
+
*/
|
|
781
|
+
hasChanges(entry) {
|
|
782
|
+
return entry.features.length > 0 || entry.fixes.length > 0 || entry.breaking.length > 0;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Get the latest version tag.
|
|
786
|
+
*/
|
|
787
|
+
async getLatestTag(git) {
|
|
788
|
+
return (await git("tag --sort=-version:refname")).trim().split("\n").filter((tag) => tag.match(/^\d+\.\d+\.\d+$/))[0] || null;
|
|
789
|
+
}
|
|
790
|
+
changelog = $command({
|
|
791
|
+
name: "changelog",
|
|
792
|
+
description: "Generate changelog from conventional commits (outputs to stdout)",
|
|
793
|
+
flags: t.object({
|
|
794
|
+
from: t.optional(t.string({
|
|
795
|
+
aliases: ["f"],
|
|
796
|
+
description: "Starting ref (default: latest tag)"
|
|
797
|
+
})),
|
|
798
|
+
to: t.optional(t.string({
|
|
799
|
+
aliases: ["t"],
|
|
800
|
+
description: "Ending ref (default: HEAD)"
|
|
801
|
+
}))
|
|
802
|
+
}),
|
|
803
|
+
handler: async ({ flags, root }) => {
|
|
804
|
+
const git = (cmd) => this.git.exec(cmd, root);
|
|
805
|
+
let fromRef;
|
|
806
|
+
if (flags.from) {
|
|
807
|
+
fromRef = flags.from;
|
|
808
|
+
this.log.debug("Using specified from ref", { from: fromRef });
|
|
809
|
+
} else {
|
|
810
|
+
const latestTag = await this.getLatestTag(git);
|
|
811
|
+
if (!latestTag) {
|
|
812
|
+
process.stdout.write("No version tags found in repository\n");
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
fromRef = latestTag;
|
|
816
|
+
this.log.debug("Using latest tag", { from: fromRef });
|
|
817
|
+
}
|
|
818
|
+
const toRef = flags.to || "HEAD";
|
|
819
|
+
this.log.debug("Using to ref", { to: toRef });
|
|
820
|
+
const commitsOutput = await git(`log ${fromRef}..${toRef} --oneline`);
|
|
821
|
+
if (!commitsOutput.trim()) {
|
|
822
|
+
process.stdout.write(`No changes in range ${fromRef}..${toRef}\n`);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
const entry = this.parseCommits(commitsOutput);
|
|
826
|
+
if (!this.hasChanges(entry)) {
|
|
827
|
+
process.stdout.write(`No public changes in range ${fromRef}..${toRef}\n`);
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
process.stdout.write(this.formatEntry(entry));
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
};
|
|
834
|
+
|
|
688
835
|
//#endregion
|
|
689
836
|
//#region ../../src/cli/commands/CoreCommands.ts
|
|
690
837
|
var CoreCommands = class {
|
|
@@ -768,9 +915,93 @@ var CoreCommands = class {
|
|
|
768
915
|
});
|
|
769
916
|
};
|
|
770
917
|
|
|
918
|
+
//#endregion
|
|
919
|
+
//#region ../../src/cli/commands/DeployCommands.ts
|
|
920
|
+
var DeployCommands = class {
|
|
921
|
+
log = $logger();
|
|
922
|
+
utils = $inject(AlephaCliUtils);
|
|
923
|
+
/**
|
|
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
|
+
|
|
771
999
|
//#endregion
|
|
772
1000
|
//#region ../../src/cli/commands/DrizzleCommands.ts
|
|
773
|
-
const drizzleCommandFlags = t.object({
|
|
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
|
+
});
|
|
774
1005
|
var DrizzleCommands = class {
|
|
775
1006
|
log = $logger();
|
|
776
1007
|
utils = $inject(AlephaCliUtils);
|
|
@@ -778,7 +1009,7 @@ var DrizzleCommands = class {
|
|
|
778
1009
|
* Check if database migrations are up to date.
|
|
779
1010
|
*/
|
|
780
1011
|
check = $command({
|
|
781
|
-
name: "
|
|
1012
|
+
name: "check-migrations",
|
|
782
1013
|
description: "Check if database migration files are up to date",
|
|
783
1014
|
args: t.optional(t.text({
|
|
784
1015
|
title: "path",
|
|
@@ -845,7 +1076,7 @@ var DrizzleCommands = class {
|
|
|
845
1076
|
* - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.
|
|
846
1077
|
*/
|
|
847
1078
|
generate = $command({
|
|
848
|
-
name: "
|
|
1079
|
+
name: "generate",
|
|
849
1080
|
description: "Generate migration files based on current database schema",
|
|
850
1081
|
summary: false,
|
|
851
1082
|
args: t.optional(t.text({
|
|
@@ -855,12 +1086,13 @@ var DrizzleCommands = class {
|
|
|
855
1086
|
flags: t.extend(drizzleCommandFlags, { custom: t.optional(t.text({ description: "Custom migration name for drizzle-kit generate --custom" })) }),
|
|
856
1087
|
handler: async ({ args, flags, root }) => {
|
|
857
1088
|
const commandFlags = flags.custom ? `--custom=${flags.custom}` : void 0;
|
|
858
|
-
await this.
|
|
1089
|
+
await this.runDrizzleKitCommand({
|
|
859
1090
|
root,
|
|
860
1091
|
args,
|
|
861
1092
|
command: "generate",
|
|
862
1093
|
commandFlags,
|
|
863
1094
|
provider: flags.provider,
|
|
1095
|
+
env: flags.mode,
|
|
864
1096
|
logMessage: (providerName, dialect) => `Generate '${providerName}' migrations (${dialect}) ...`
|
|
865
1097
|
});
|
|
866
1098
|
}
|
|
@@ -874,7 +1106,7 @@ var DrizzleCommands = class {
|
|
|
874
1106
|
* - Invokes Drizzle Kit's push command to apply schema changes directly.
|
|
875
1107
|
*/
|
|
876
1108
|
push = $command({
|
|
877
|
-
name: "
|
|
1109
|
+
name: "push",
|
|
878
1110
|
description: "Push database schema changes directly to the database",
|
|
879
1111
|
summary: false,
|
|
880
1112
|
args: t.optional(t.text({
|
|
@@ -883,11 +1115,12 @@ var DrizzleCommands = class {
|
|
|
883
1115
|
})),
|
|
884
1116
|
flags: drizzleCommandFlags,
|
|
885
1117
|
handler: async ({ root, args, flags }) => {
|
|
886
|
-
await this.
|
|
1118
|
+
await this.runDrizzleKitCommand({
|
|
887
1119
|
root,
|
|
888
1120
|
args,
|
|
889
1121
|
command: "push",
|
|
890
1122
|
provider: flags.provider,
|
|
1123
|
+
env: flags.mode,
|
|
891
1124
|
logMessage: (providerName, dialect) => `Push '${providerName}' schema (${dialect}) ...`
|
|
892
1125
|
});
|
|
893
1126
|
}
|
|
@@ -901,7 +1134,7 @@ var DrizzleCommands = class {
|
|
|
901
1134
|
* - Invokes Drizzle Kit's migrate command to apply pending migrations.
|
|
902
1135
|
*/
|
|
903
1136
|
migrate = $command({
|
|
904
|
-
name: "
|
|
1137
|
+
name: "migrate",
|
|
905
1138
|
description: "Apply pending database migrations",
|
|
906
1139
|
summary: false,
|
|
907
1140
|
args: t.optional(t.text({
|
|
@@ -910,11 +1143,12 @@ var DrizzleCommands = class {
|
|
|
910
1143
|
})),
|
|
911
1144
|
flags: drizzleCommandFlags,
|
|
912
1145
|
handler: async ({ root, args, flags }) => {
|
|
913
|
-
await this.
|
|
1146
|
+
await this.runDrizzleKitCommand({
|
|
914
1147
|
root,
|
|
915
1148
|
args,
|
|
916
1149
|
command: "migrate",
|
|
917
1150
|
provider: flags.provider,
|
|
1151
|
+
env: flags.mode,
|
|
918
1152
|
logMessage: (providerName, dialect) => `Migrate '${providerName}' database (${dialect}) ...`
|
|
919
1153
|
});
|
|
920
1154
|
}
|
|
@@ -928,7 +1162,7 @@ var DrizzleCommands = class {
|
|
|
928
1162
|
* - Invokes Drizzle Kit's studio command to launch the web-based database browser.
|
|
929
1163
|
*/
|
|
930
1164
|
studio = $command({
|
|
931
|
-
name: "
|
|
1165
|
+
name: "studio",
|
|
932
1166
|
description: "Launch Drizzle Studio database browser",
|
|
933
1167
|
summary: false,
|
|
934
1168
|
args: t.optional(t.text({
|
|
@@ -937,15 +1171,120 @@ var DrizzleCommands = class {
|
|
|
937
1171
|
})),
|
|
938
1172
|
flags: drizzleCommandFlags,
|
|
939
1173
|
handler: async ({ root, args, flags }) => {
|
|
940
|
-
await this.
|
|
1174
|
+
await this.runDrizzleKitCommand({
|
|
941
1175
|
root,
|
|
942
1176
|
args,
|
|
943
1177
|
command: "studio",
|
|
944
1178
|
provider: flags.provider,
|
|
1179
|
+
env: flags.mode,
|
|
945
1180
|
logMessage: (providerName, dialect) => `Launch Studio for '${providerName}' (${dialect}) ...`
|
|
946
1181
|
});
|
|
947
1182
|
}
|
|
948
1183
|
});
|
|
1184
|
+
/**
|
|
1185
|
+
* Parent command for database operations.
|
|
1186
|
+
*/
|
|
1187
|
+
db = $command({
|
|
1188
|
+
name: "db",
|
|
1189
|
+
description: "Database management commands",
|
|
1190
|
+
children: [
|
|
1191
|
+
this.check,
|
|
1192
|
+
this.generate,
|
|
1193
|
+
this.push,
|
|
1194
|
+
this.migrate,
|
|
1195
|
+
this.studio
|
|
1196
|
+
],
|
|
1197
|
+
handler: async ({ help }) => {
|
|
1198
|
+
help();
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
/**
|
|
1202
|
+
* 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
|
+
*/
|
|
1209
|
+
async runDrizzleKitCommand(options) {
|
|
1210
|
+
const rootDir = options.root;
|
|
1211
|
+
const envFiles = [".env"];
|
|
1212
|
+
if (options.env) envFiles.push(`.env.${options.env}`);
|
|
1213
|
+
await this.utils.loadEnv(rootDir, envFiles);
|
|
1214
|
+
this.log.debug(`Using project root: ${rootDir}`);
|
|
1215
|
+
const { alepha, entry } = await this.utils.loadAlephaFromServerEntryFile(rootDir, options.args);
|
|
1216
|
+
const drizzleKitProvider = alepha.inject("DrizzleKitProvider");
|
|
1217
|
+
const repositoryProvider = alepha.inject("RepositoryProvider");
|
|
1218
|
+
const accepted = /* @__PURE__ */ new Set([]);
|
|
1219
|
+
for (const primitive of repositoryProvider.getRepositories()) {
|
|
1220
|
+
const provider = primitive.provider;
|
|
1221
|
+
const providerName = provider.name;
|
|
1222
|
+
const dialect = provider.dialect;
|
|
1223
|
+
if (accepted.has(providerName)) continue;
|
|
1224
|
+
accepted.add(providerName);
|
|
1225
|
+
if (options.provider && options.provider !== providerName) {
|
|
1226
|
+
this.log.debug(`Skipping provider '${providerName}' (filter: ${options.provider})`);
|
|
1227
|
+
continue;
|
|
1228
|
+
}
|
|
1229
|
+
this.log.info("");
|
|
1230
|
+
this.log.info(options.logMessage(providerName, dialect));
|
|
1231
|
+
const drizzleConfigJsPath = await this.prepareDrizzleConfig({
|
|
1232
|
+
kit: drizzleKitProvider,
|
|
1233
|
+
provider,
|
|
1234
|
+
providerName,
|
|
1235
|
+
providerUrl: provider.url,
|
|
1236
|
+
dialect,
|
|
1237
|
+
entry,
|
|
1238
|
+
rootDir
|
|
1239
|
+
});
|
|
1240
|
+
const flags = options.commandFlags ? ` ${options.commandFlags}` : "";
|
|
1241
|
+
await this.utils.exec(`drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`, { env: { NODE_OPTIONS: "--import tsx" } });
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* 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
|
+
*/
|
|
1253
|
+
async prepareDrizzleConfig(options) {
|
|
1254
|
+
const models = Object.keys(options.kit.getModels(options.provider));
|
|
1255
|
+
const entitiesJs = this.utils.generateEntitiesJs(options.entry, options.providerName, models);
|
|
1256
|
+
const config = {
|
|
1257
|
+
schema: await this.utils.writeConfigFile("entities.js", entitiesJs, options.rootDir),
|
|
1258
|
+
out: `./migrations/${options.providerName}`,
|
|
1259
|
+
dialect: options.dialect,
|
|
1260
|
+
dbCredentials: { url: options.providerUrl }
|
|
1261
|
+
};
|
|
1262
|
+
if (options.provider.schema) config.schemaFilter = options.provider.schema;
|
|
1263
|
+
if (options.providerName === "d1") config.driver = "d1-http";
|
|
1264
|
+
if (options.providerName === "pglite") config.driver = "pglite";
|
|
1265
|
+
if (options.dialect === "sqlite") if (options.providerName === "d1") {
|
|
1266
|
+
const token = process.env.CLOUDFLARE_API_TOKEN;
|
|
1267
|
+
if (!token) throw new AlephaError("CLOUDFLARE_API_TOKEN environment variable is not set. https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit");
|
|
1268
|
+
const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
1269
|
+
if (!accountId) throw new AlephaError("CLOUDFLARE_ACCOUNT_ID environment variable is not set. https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit");
|
|
1270
|
+
const url = options.providerUrl;
|
|
1271
|
+
if (!url.startsWith("cloudflare-d1://")) throw new AlephaError("D1 provider URL must start with 'cloudflare-d1://'.");
|
|
1272
|
+
const [, databaseId] = url.replace("cloudflare-d1://", "").replace("cloudflare-d1:", "").split(":");
|
|
1273
|
+
if (!databaseId) throw new AlephaError("Database ID is missing in the D1 provider URL. Cloudflare D1 URL format: cloudflare-d1://<database_name>:<database_id>");
|
|
1274
|
+
config.dbCredentials = {
|
|
1275
|
+
accountId,
|
|
1276
|
+
databaseId,
|
|
1277
|
+
token
|
|
1278
|
+
};
|
|
1279
|
+
} else {
|
|
1280
|
+
let url = options.providerUrl;
|
|
1281
|
+
url = url.replace("sqlite://", "").replace("file://", "");
|
|
1282
|
+
url = join(options.rootDir, url);
|
|
1283
|
+
config.dbCredentials = { url };
|
|
1284
|
+
}
|
|
1285
|
+
const drizzleConfigJs = `export default ${JSON.stringify(config, null, 2)}`;
|
|
1286
|
+
return await this.utils.writeConfigFile("drizzle.config.js", drizzleConfigJs, options.rootDir);
|
|
1287
|
+
}
|
|
949
1288
|
};
|
|
950
1289
|
|
|
951
1290
|
//#endregion
|
|
@@ -1067,11 +1406,11 @@ var ViteCommands = class {
|
|
|
1067
1406
|
vercel: t.optional(t.boolean({ description: "Generate Vercel deployment configuration" })),
|
|
1068
1407
|
cloudflare: t.optional(t.boolean({ description: "Generate Cloudflare Workers configuration" })),
|
|
1069
1408
|
docker: t.optional(t.boolean({ description: "Generate Docker configuration" })),
|
|
1070
|
-
sitemap: t.optional(t.text({ description: "Generate sitemap.xml with base URL" }))
|
|
1071
|
-
prerender: t.optional(t.boolean({ description: "Pre-render static pages" }))
|
|
1409
|
+
sitemap: t.optional(t.text({ description: "Generate sitemap.xml with base URL" }))
|
|
1072
1410
|
}),
|
|
1073
1411
|
handler: async ({ flags, args, run, root }) => {
|
|
1074
1412
|
process.env.ALEPHA_BUILD_MODE = "cli";
|
|
1413
|
+
process.env.NODE_ENV = "production";
|
|
1075
1414
|
if (await this.utils.hasExpo(root)) return;
|
|
1076
1415
|
await this.utils.ensureConfig(root, {
|
|
1077
1416
|
viteConfigTs: true,
|
|
@@ -1083,7 +1422,8 @@ var ViteCommands = class {
|
|
|
1083
1422
|
const clientDir = "public";
|
|
1084
1423
|
await this.utils.ensureDependency(root, "vite", { run });
|
|
1085
1424
|
await run.rm("dist", { alias: "clean dist" });
|
|
1086
|
-
const viteAlephaBuildOptions = (await import(
|
|
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"]);
|
|
1087
1427
|
const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;
|
|
1088
1428
|
const hasServer = viteAlephaBuildOptions.serverEntry !== false;
|
|
1089
1429
|
let hasClient = false;
|
|
@@ -1091,12 +1431,14 @@ var ViteCommands = class {
|
|
|
1091
1431
|
await access(join(root, "index.html"));
|
|
1092
1432
|
hasClient = true;
|
|
1093
1433
|
} catch {}
|
|
1434
|
+
const clientOptions = typeof viteAlephaBuildOptions.client === "object" ? viteAlephaBuildOptions.client : {};
|
|
1094
1435
|
if (hasClient) await run({
|
|
1095
1436
|
name: "vite build client",
|
|
1096
1437
|
handler: () => buildClient({
|
|
1097
1438
|
silent: true,
|
|
1098
1439
|
dist: `${distDir}/${clientDir}`,
|
|
1099
|
-
stats
|
|
1440
|
+
stats,
|
|
1441
|
+
precompress: clientOptions.precompress
|
|
1100
1442
|
})
|
|
1101
1443
|
});
|
|
1102
1444
|
await run({
|
|
@@ -1124,7 +1466,7 @@ var ViteCommands = class {
|
|
|
1124
1466
|
run
|
|
1125
1467
|
});
|
|
1126
1468
|
if (hasClient) {
|
|
1127
|
-
const sitemapBaseUrl = flags.sitemap ??
|
|
1469
|
+
const sitemapBaseUrl = flags.sitemap ?? clientOptions.sitemap?.hostname;
|
|
1128
1470
|
if (sitemapBaseUrl) await run({
|
|
1129
1471
|
name: "add sitemap",
|
|
1130
1472
|
handler: async () => {
|
|
@@ -1134,12 +1476,13 @@ var ViteCommands = class {
|
|
|
1134
1476
|
}));
|
|
1135
1477
|
}
|
|
1136
1478
|
});
|
|
1137
|
-
if (
|
|
1479
|
+
if (clientOptions.prerender) await run({
|
|
1138
1480
|
name: "pre-render pages",
|
|
1139
1481
|
handler: async () => {
|
|
1140
1482
|
await prerenderPages({
|
|
1141
1483
|
dist: `${distDir}/${clientDir}`,
|
|
1142
|
-
entry: `${distDir}/index.js
|
|
1484
|
+
entry: `${distDir}/index.js`,
|
|
1485
|
+
compress: clientOptions.precompress
|
|
1143
1486
|
});
|
|
1144
1487
|
}
|
|
1145
1488
|
});
|
|
@@ -1155,10 +1498,16 @@ var ViteCommands = class {
|
|
|
1155
1498
|
})
|
|
1156
1499
|
});
|
|
1157
1500
|
}
|
|
1158
|
-
if (flags.cloudflare || viteAlephaBuildOptions.cloudflare)
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
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
|
+
});
|
|
1510
|
+
}
|
|
1162
1511
|
if (flags.docker || viteAlephaBuildOptions.docker) {
|
|
1163
1512
|
const dockerConfig = typeof viteAlephaBuildOptions.docker === "object" ? viteAlephaBuildOptions.docker : {};
|
|
1164
1513
|
await run({
|
|
@@ -1174,13 +1523,22 @@ var ViteCommands = class {
|
|
|
1174
1523
|
test = $command({
|
|
1175
1524
|
name: "test",
|
|
1176
1525
|
description: "Run tests using Vitest",
|
|
1177
|
-
|
|
1526
|
+
flags: t.object({ config: t.optional(t.string({
|
|
1527
|
+
description: "Path to Vitest config file",
|
|
1528
|
+
alias: "c"
|
|
1529
|
+
})) }),
|
|
1530
|
+
env: t.object({ VITEST_ARGS: t.optional(t.string({
|
|
1531
|
+
default: "",
|
|
1532
|
+
description: "Additional arguments to pass to Vitest. E.g., --coverage"
|
|
1533
|
+
})) }),
|
|
1534
|
+
handler: async ({ root, flags, env }) => {
|
|
1178
1535
|
await this.utils.ensureConfig(root, {
|
|
1179
1536
|
tsconfigJson: true,
|
|
1180
1537
|
viteConfigTs: true
|
|
1181
1538
|
});
|
|
1182
1539
|
await this.utils.ensureDependency(root, "vitest");
|
|
1183
|
-
|
|
1540
|
+
const config = flags.config ? `--config=${flags.config}` : "";
|
|
1541
|
+
await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);
|
|
1184
1542
|
}
|
|
1185
1543
|
});
|
|
1186
1544
|
};
|
|
@@ -1197,7 +1555,7 @@ var AlephaCliExtension = class {
|
|
|
1197
1555
|
if (!await this.fs.exists(extensionPath)) return;
|
|
1198
1556
|
const { default: Extension } = await import(extensionPath);
|
|
1199
1557
|
if (typeof Extension !== "function") return;
|
|
1200
|
-
this.alepha.
|
|
1558
|
+
this.alepha.inject(Extension, { args: [this.alepha] });
|
|
1201
1559
|
}
|
|
1202
1560
|
});
|
|
1203
1561
|
};
|
|
@@ -1205,11 +1563,13 @@ const AlephaCli = $module({
|
|
|
1205
1563
|
name: "alepha.cli",
|
|
1206
1564
|
services: [
|
|
1207
1565
|
AlephaCliExtension,
|
|
1566
|
+
BiomeCommands,
|
|
1567
|
+
ChangelogCommands,
|
|
1208
1568
|
CoreCommands,
|
|
1569
|
+
DeployCommands,
|
|
1209
1570
|
DrizzleCommands,
|
|
1210
1571
|
VerifyCommands,
|
|
1211
|
-
ViteCommands
|
|
1212
|
-
BiomeCommands
|
|
1572
|
+
ViteCommands
|
|
1213
1573
|
]
|
|
1214
1574
|
});
|
|
1215
1575
|
|
|
@@ -1251,11 +1611,10 @@ var AlephaPackageBuilderCli = class {
|
|
|
1251
1611
|
const tmpDir = join(root, "node_modules/.alepha");
|
|
1252
1612
|
await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});
|
|
1253
1613
|
await this.fs.writeFile(join(tmpDir, "module-dependencies.json"), JSON.stringify(modules, null, 2));
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
];
|
|
1614
|
+
const tsconfig = await readFile(join(root, "../../tsconfig.json"), "utf-8");
|
|
1615
|
+
const external = Object.keys(JSON.parse(tsconfig).compilerOptions.paths);
|
|
1616
|
+
external.push("bun");
|
|
1617
|
+
external.push("bun:sqlite");
|
|
1259
1618
|
await run.rm(this.dist);
|
|
1260
1619
|
const build = async (item) => {
|
|
1261
1620
|
const entries = [];
|
|
@@ -1268,7 +1627,11 @@ var AlephaPackageBuilderCli = class {
|
|
|
1268
1627
|
sourcemap: true,
|
|
1269
1628
|
fixedExtension: false,
|
|
1270
1629
|
platform: "node",
|
|
1271
|
-
external
|
|
1630
|
+
external,
|
|
1631
|
+
dts: {
|
|
1632
|
+
sourcemap: true,
|
|
1633
|
+
resolve: false
|
|
1634
|
+
}
|
|
1272
1635
|
});
|
|
1273
1636
|
if (item.native) entries.push({
|
|
1274
1637
|
entry: join(src, "index.native.ts"),
|
|
@@ -1401,5 +1764,14 @@ async function analyzeModules(srcDir, packageName) {
|
|
|
1401
1764
|
}
|
|
1402
1765
|
|
|
1403
1766
|
//#endregion
|
|
1404
|
-
|
|
1767
|
+
//#region ../../src/cli/defineConfig.ts
|
|
1768
|
+
const defineConfig = (config) => {
|
|
1769
|
+
return (alepha) => {
|
|
1770
|
+
const { commands } = config(alepha);
|
|
1771
|
+
return { ...commands };
|
|
1772
|
+
};
|
|
1773
|
+
};
|
|
1774
|
+
|
|
1775
|
+
//#endregion
|
|
1776
|
+
export { AlephaCli, AlephaCliUtils, AlephaPackageBuilderCli, BiomeCommands, ChangelogCommands, CoreCommands, DEFAULT_IGNORE, DeployCommands, DrizzleCommands, GitMessageParser, GitProvider, VerifyCommands, ViteCommands, analyzeModules, changelogOptions, defineConfig, version };
|
|
1405
1777
|
//# sourceMappingURL=index.js.map
|