alepha 0.14.0 → 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 +417 -338
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +80 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +236 -157
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.d.ts +21 -1
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +451 -4
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +833 -830
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/cli/index.d.ts +212 -29
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +320 -219
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +206 -9
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +306 -69
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js.map +1 -1
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js.map +1 -1
- package/dist/orm/index.d.ts +180 -126
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +486 -512
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/redis/index.js +2 -4
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/redis/index.d.ts +400 -29
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +412 -21
- package/dist/redis/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/security/index.d.ts +28 -28
- package/dist/security/index.d.ts.map +1 -1
- package/dist/server/auth/index.d.ts +155 -155
- package/dist/server/core/index.d.ts +0 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/health/index.d.ts +17 -17
- package/dist/server/helmet/index.d.ts +4 -1
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/topic/redis/index.js +3 -3
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/vite/index.js +9 -6
- package/dist/vite/index.js.map +1 -1
- package/package.json +3 -3
- package/src/cli/apps/AlephaCli.ts +8 -3
- package/src/cli/apps/AlephaPackageBuilderCli.ts +3 -0
- package/src/cli/atoms/changelogOptions.ts +45 -0
- package/src/cli/commands/ChangelogCommands.ts +187 -317
- package/src/cli/commands/DeployCommands.ts +118 -0
- package/src/cli/commands/DrizzleCommands.ts +28 -8
- package/src/cli/commands/ViteCommands.ts +23 -9
- package/src/cli/defineConfig.ts +15 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/services/AlephaCliUtils.ts +4 -21
- package/src/cli/services/GitMessageParser.ts +77 -0
- package/src/command/helpers/EnvUtils.ts +37 -0
- package/src/command/index.ts +3 -1
- package/src/command/primitives/$command.ts +172 -6
- package/src/command/providers/CliProvider.ts +424 -91
- package/src/core/Alepha.ts +1 -1
- package/src/file/providers/NodeFileSystemProvider.ts +3 -1
- package/src/orm/index.ts +8 -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/DatabaseProvider.ts +25 -0
- package/src/orm/providers/drivers/NodePostgresProvider.ts +0 -25
- package/src/orm/services/QueryManager.ts +10 -125
- package/src/queue/redis/providers/RedisQueueProvider.ts +2 -7
- package/src/redis/index.ts +65 -3
- package/src/redis/providers/BunRedisProvider.ts +304 -0
- package/src/redis/providers/BunRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/NodeRedisProvider.ts +280 -0
- package/src/redis/providers/NodeRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/RedisProvider.ts +134 -140
- package/src/redis/providers/RedisSubscriberProvider.ts +58 -49
- package/src/server/core/providers/BunHttpServerProvider.ts +0 -3
- package/src/server/core/providers/ServerBodyParserProvider.ts +3 -1
- package/src/server/core/providers/ServerProvider.ts +7 -4
- package/src/server/multipart/providers/ServerMultipartProvider.ts +3 -1
- package/src/server/proxy/providers/ServerProxyProvider.ts +1 -1
- package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
- package/src/vite/tasks/buildServer.ts +1 -0
- package/src/orm/services/PgJsonQueryManager.ts +0 -511
package/dist/cli/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
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";
|
|
4
4
|
import { FileSystemProvider } from "alepha/file";
|
|
5
|
-
import { $command, CliProvider } from "alepha/command";
|
|
5
|
+
import { $command, CliProvider, EnvUtils } from "alepha/command";
|
|
6
6
|
import { $logger } from "alepha/logger";
|
|
7
7
|
import { exec, spawn } from "node:child_process";
|
|
8
8
|
import { access, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
|
|
@@ -173,6 +173,7 @@ const version = packageJson.version;
|
|
|
173
173
|
var AlephaCliUtils = class {
|
|
174
174
|
log = $logger();
|
|
175
175
|
fs = $inject(FileSystemProvider);
|
|
176
|
+
envUtils = $inject(EnvUtils);
|
|
176
177
|
/**
|
|
177
178
|
* Execute a command using npx with inherited stdio.
|
|
178
179
|
*
|
|
@@ -461,23 +462,8 @@ ${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
|
|
|
461
462
|
* Reads the .env file in the specified root directory and sets
|
|
462
463
|
* the environment variables in process.env.
|
|
463
464
|
*/
|
|
464
|
-
async
|
|
465
|
-
|
|
466
|
-
const envPath = join(root, file);
|
|
467
|
-
try {
|
|
468
|
-
const lines = (await readFile(envPath, "utf8")).split("\n");
|
|
469
|
-
for (const line of lines) {
|
|
470
|
-
const [key, ...rest] = line.split("=");
|
|
471
|
-
if (key) {
|
|
472
|
-
const value = rest.join("=");
|
|
473
|
-
process.env[key.trim()] = value.trim();
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
this.log.debug(`Loaded environment variables from ${envPath}`);
|
|
477
|
-
} catch {
|
|
478
|
-
this.log.debug(`No ${file} file found at ${envPath}, skipping load.`);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
465
|
+
async loadEnv(root, files = [".env"]) {
|
|
466
|
+
await this.envUtils.loadEnv(root, files);
|
|
481
467
|
}
|
|
482
468
|
async getPackageManager(root, flags) {
|
|
483
469
|
if (flags?.yarn) return "yarn";
|
|
@@ -626,8 +612,11 @@ var BiomeCommands = class {
|
|
|
626
612
|
};
|
|
627
613
|
|
|
628
614
|
//#endregion
|
|
629
|
-
//#region ../../src/cli/
|
|
630
|
-
|
|
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
|
+
*/
|
|
631
620
|
const DEFAULT_IGNORE = [
|
|
632
621
|
"project",
|
|
633
622
|
"release",
|
|
@@ -639,213 +628,206 @@ const DEFAULT_IGNORE = [
|
|
|
639
628
|
"test",
|
|
640
629
|
"style"
|
|
641
630
|
];
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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");
|
|
656
689
|
return {
|
|
657
690
|
hash: hash.substring(0, 8),
|
|
658
691
|
type: type.toLowerCase(),
|
|
659
|
-
scope
|
|
692
|
+
scope,
|
|
660
693
|
description: description.trim(),
|
|
661
694
|
breaking
|
|
662
695
|
};
|
|
663
696
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
scope: module,
|
|
678
|
-
description: description.trim(),
|
|
679
|
-
breaking
|
|
680
|
-
};
|
|
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;
|
|
681
710
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
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}\`)`;
|
|
693
732
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
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");
|
|
702
754
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
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;
|
|
707
777
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
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;
|
|
712
783
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
return JSON.parse(await readFile(pkgPath, "utf8")).changelog ?? {};
|
|
719
|
-
} catch {
|
|
720
|
-
return {};
|
|
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;
|
|
721
789
|
}
|
|
722
|
-
}
|
|
723
|
-
var ChangelogCommands = class {
|
|
724
790
|
changelog = $command({
|
|
725
791
|
name: "changelog",
|
|
726
|
-
description: "Generate
|
|
792
|
+
description: "Generate changelog from conventional commits (outputs to stdout)",
|
|
727
793
|
flags: t.object({
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
description: "
|
|
794
|
+
from: t.optional(t.string({
|
|
795
|
+
aliases: ["f"],
|
|
796
|
+
description: "Starting ref (default: latest tag)"
|
|
731
797
|
})),
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
description: "
|
|
735
|
-
})),
|
|
736
|
-
output: t.optional(t.string({
|
|
737
|
-
when: ["--output", "-o"],
|
|
738
|
-
description: "Output file path (defaults to CHANGELOG.md, use - for stdout)"
|
|
739
|
-
})),
|
|
740
|
-
limit: t.optional(t.number({
|
|
741
|
-
when: ["--limit", "-l"],
|
|
742
|
-
description: "Limit number of versions to include"
|
|
798
|
+
to: t.optional(t.string({
|
|
799
|
+
aliases: ["t"],
|
|
800
|
+
description: "Ending ref (default: HEAD)"
|
|
743
801
|
}))
|
|
744
802
|
}),
|
|
745
|
-
handler: async ({ flags,
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
const commitsOutput = await git(`log ${latestTag}..HEAD --oneline`);
|
|
756
|
-
if (!commitsOutput.trim()) {
|
|
757
|
-
console.log("No unreleased changes since", latestTag);
|
|
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");
|
|
758
813
|
return;
|
|
759
814
|
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
763
|
-
features: [],
|
|
764
|
-
fixes: [],
|
|
765
|
-
docs: [],
|
|
766
|
-
improvements: [],
|
|
767
|
-
breaking: []
|
|
768
|
-
};
|
|
769
|
-
for (const line of commitsOutput.trim().split("\n")) {
|
|
770
|
-
if (!line.trim()) continue;
|
|
771
|
-
const commit = parseCommit(line, config);
|
|
772
|
-
if (!commit) continue;
|
|
773
|
-
if (commit.breaking) entry.breaking.push(commit);
|
|
774
|
-
switch (commit.type) {
|
|
775
|
-
case "feat":
|
|
776
|
-
entry.features.push(commit);
|
|
777
|
-
break;
|
|
778
|
-
case "fix":
|
|
779
|
-
entry.fixes.push(commit);
|
|
780
|
-
break;
|
|
781
|
-
case "docs":
|
|
782
|
-
entry.docs.push(commit);
|
|
783
|
-
break;
|
|
784
|
-
case "refactor":
|
|
785
|
-
case "perf":
|
|
786
|
-
case "improve":
|
|
787
|
-
entry.improvements.push(commit);
|
|
788
|
-
break;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
if (!(entry.features.length > 0 || entry.fixes.length > 0 || entry.breaking.length > 0)) {
|
|
792
|
-
console.log("No public changes since", latestTag);
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
795
|
-
console.log(`## [Unreleased] - since ${latestTag}\n`);
|
|
796
|
-
console.log(formatEntry(entry));
|
|
797
|
-
return;
|
|
815
|
+
fromRef = latestTag;
|
|
816
|
+
this.log.debug("Using latest tag", { from: fromRef });
|
|
798
817
|
}
|
|
799
|
-
const
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
const commitsOutput = await git(`log ${prevTag ? `${prevTag}..${tag}` : tag} --oneline`);
|
|
806
|
-
const entry = {
|
|
807
|
-
version: tag,
|
|
808
|
-
date,
|
|
809
|
-
features: [],
|
|
810
|
-
fixes: [],
|
|
811
|
-
docs: [],
|
|
812
|
-
improvements: [],
|
|
813
|
-
breaking: []
|
|
814
|
-
};
|
|
815
|
-
for (const line of commitsOutput.trim().split("\n")) {
|
|
816
|
-
if (!line.trim()) continue;
|
|
817
|
-
const commit = parseCommit(line, config);
|
|
818
|
-
if (!commit) continue;
|
|
819
|
-
if (commit.breaking) entry.breaking.push(commit);
|
|
820
|
-
switch (commit.type) {
|
|
821
|
-
case "feat":
|
|
822
|
-
entry.features.push(commit);
|
|
823
|
-
break;
|
|
824
|
-
case "fix":
|
|
825
|
-
entry.fixes.push(commit);
|
|
826
|
-
break;
|
|
827
|
-
case "docs":
|
|
828
|
-
entry.docs.push(commit);
|
|
829
|
-
break;
|
|
830
|
-
case "refactor":
|
|
831
|
-
case "perf":
|
|
832
|
-
case "improve":
|
|
833
|
-
entry.improvements.push(commit);
|
|
834
|
-
break;
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
if (entry.features.length > 0 || entry.fixes.length > 0 || entry.breaking.length > 0) entries.push(entry);
|
|
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;
|
|
838
824
|
}
|
|
839
|
-
|
|
840
|
-
|
|
825
|
+
const entry = this.parseCommits(commitsOutput);
|
|
826
|
+
if (!this.hasChanges(entry)) {
|
|
827
|
+
process.stdout.write(`No public changes in range ${fromRef}..${toRef}\n`);
|
|
841
828
|
return;
|
|
842
829
|
}
|
|
843
|
-
|
|
844
|
-
if (flags.release) output = formatEntry(entries[0]);
|
|
845
|
-
else output = generateChangelog(entries);
|
|
846
|
-
const outputPath = flags.output ?? "CHANGELOG.md";
|
|
847
|
-
if (outputPath === "-") console.log(output);
|
|
848
|
-
else await run(`Writing ${outputPath}`, () => writeFile(join(root, outputPath), output, "utf8"));
|
|
830
|
+
process.stdout.write(this.formatEntry(entry));
|
|
849
831
|
}
|
|
850
832
|
});
|
|
851
833
|
};
|
|
@@ -933,6 +915,87 @@ var CoreCommands = class {
|
|
|
933
915
|
});
|
|
934
916
|
};
|
|
935
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
|
+
|
|
936
999
|
//#endregion
|
|
937
1000
|
//#region ../../src/cli/commands/DrizzleCommands.ts
|
|
938
1001
|
const drizzleCommandFlags = t.object({
|
|
@@ -946,7 +1009,7 @@ var DrizzleCommands = class {
|
|
|
946
1009
|
* Check if database migrations are up to date.
|
|
947
1010
|
*/
|
|
948
1011
|
check = $command({
|
|
949
|
-
name: "
|
|
1012
|
+
name: "check-migrations",
|
|
950
1013
|
description: "Check if database migration files are up to date",
|
|
951
1014
|
args: t.optional(t.text({
|
|
952
1015
|
title: "path",
|
|
@@ -1013,7 +1076,7 @@ var DrizzleCommands = class {
|
|
|
1013
1076
|
* - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.
|
|
1014
1077
|
*/
|
|
1015
1078
|
generate = $command({
|
|
1016
|
-
name: "
|
|
1079
|
+
name: "generate",
|
|
1017
1080
|
description: "Generate migration files based on current database schema",
|
|
1018
1081
|
summary: false,
|
|
1019
1082
|
args: t.optional(t.text({
|
|
@@ -1043,7 +1106,7 @@ var DrizzleCommands = class {
|
|
|
1043
1106
|
* - Invokes Drizzle Kit's push command to apply schema changes directly.
|
|
1044
1107
|
*/
|
|
1045
1108
|
push = $command({
|
|
1046
|
-
name: "
|
|
1109
|
+
name: "push",
|
|
1047
1110
|
description: "Push database schema changes directly to the database",
|
|
1048
1111
|
summary: false,
|
|
1049
1112
|
args: t.optional(t.text({
|
|
@@ -1071,7 +1134,7 @@ var DrizzleCommands = class {
|
|
|
1071
1134
|
* - Invokes Drizzle Kit's migrate command to apply pending migrations.
|
|
1072
1135
|
*/
|
|
1073
1136
|
migrate = $command({
|
|
1074
|
-
name: "
|
|
1137
|
+
name: "migrate",
|
|
1075
1138
|
description: "Apply pending database migrations",
|
|
1076
1139
|
summary: false,
|
|
1077
1140
|
args: t.optional(t.text({
|
|
@@ -1099,7 +1162,7 @@ var DrizzleCommands = class {
|
|
|
1099
1162
|
* - Invokes Drizzle Kit's studio command to launch the web-based database browser.
|
|
1100
1163
|
*/
|
|
1101
1164
|
studio = $command({
|
|
1102
|
-
name: "
|
|
1165
|
+
name: "studio",
|
|
1103
1166
|
description: "Launch Drizzle Studio database browser",
|
|
1104
1167
|
summary: false,
|
|
1105
1168
|
args: t.optional(t.text({
|
|
@@ -1119,6 +1182,23 @@ var DrizzleCommands = class {
|
|
|
1119
1182
|
}
|
|
1120
1183
|
});
|
|
1121
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
|
+
/**
|
|
1122
1202
|
* Run a drizzle-kit command for all database providers in an Alepha instance.
|
|
1123
1203
|
*
|
|
1124
1204
|
* Iterates through all repository providers, prepares Drizzle config for each,
|
|
@@ -1130,7 +1210,7 @@ var DrizzleCommands = class {
|
|
|
1130
1210
|
const rootDir = options.root;
|
|
1131
1211
|
const envFiles = [".env"];
|
|
1132
1212
|
if (options.env) envFiles.push(`.env.${options.env}`);
|
|
1133
|
-
await this.utils.
|
|
1213
|
+
await this.utils.loadEnv(rootDir, envFiles);
|
|
1134
1214
|
this.log.debug(`Using project root: ${rootDir}`);
|
|
1135
1215
|
const { alepha, entry } = await this.utils.loadAlephaFromServerEntryFile(rootDir, options.args);
|
|
1136
1216
|
const drizzleKitProvider = alepha.inject("DrizzleKitProvider");
|
|
@@ -1179,6 +1259,7 @@ var DrizzleCommands = class {
|
|
|
1179
1259
|
dialect: options.dialect,
|
|
1180
1260
|
dbCredentials: { url: options.providerUrl }
|
|
1181
1261
|
};
|
|
1262
|
+
if (options.provider.schema) config.schemaFilter = options.provider.schema;
|
|
1182
1263
|
if (options.providerName === "d1") config.driver = "d1-http";
|
|
1183
1264
|
if (options.providerName === "pglite") config.driver = "pglite";
|
|
1184
1265
|
if (options.dialect === "sqlite") if (options.providerName === "d1") {
|
|
@@ -1325,8 +1406,7 @@ var ViteCommands = class {
|
|
|
1325
1406
|
vercel: t.optional(t.boolean({ description: "Generate Vercel deployment configuration" })),
|
|
1326
1407
|
cloudflare: t.optional(t.boolean({ description: "Generate Cloudflare Workers configuration" })),
|
|
1327
1408
|
docker: t.optional(t.boolean({ description: "Generate Docker configuration" })),
|
|
1328
|
-
sitemap: t.optional(t.text({ description: "Generate sitemap.xml with base URL" }))
|
|
1329
|
-
prerender: t.optional(t.boolean({ description: "Pre-render static pages" }))
|
|
1409
|
+
sitemap: t.optional(t.text({ description: "Generate sitemap.xml with base URL" }))
|
|
1330
1410
|
}),
|
|
1331
1411
|
handler: async ({ flags, args, run, root }) => {
|
|
1332
1412
|
process.env.ALEPHA_BUILD_MODE = "cli";
|
|
@@ -1343,7 +1423,7 @@ var ViteCommands = class {
|
|
|
1343
1423
|
await this.utils.ensureDependency(root, "vite", { run });
|
|
1344
1424
|
await run.rm("dist", { alias: "clean dist" });
|
|
1345
1425
|
const viteAlephaBuildOptions = (await createRequire(import.meta.url)("vite").resolveConfig({}, "build", "production")).plugins.find((it) => it.name === "alepha:build")?.[OPTIONS] || {};
|
|
1346
|
-
await this.utils.
|
|
1426
|
+
await this.utils.loadEnv(root, [".env", ".env.production"]);
|
|
1347
1427
|
const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;
|
|
1348
1428
|
const hasServer = viteAlephaBuildOptions.serverEntry !== false;
|
|
1349
1429
|
let hasClient = false;
|
|
@@ -1396,7 +1476,7 @@ var ViteCommands = class {
|
|
|
1396
1476
|
}));
|
|
1397
1477
|
}
|
|
1398
1478
|
});
|
|
1399
|
-
if (
|
|
1479
|
+
if (clientOptions.prerender) await run({
|
|
1400
1480
|
name: "pre-render pages",
|
|
1401
1481
|
handler: async () => {
|
|
1402
1482
|
await prerenderPages({
|
|
@@ -1443,13 +1523,22 @@ var ViteCommands = class {
|
|
|
1443
1523
|
test = $command({
|
|
1444
1524
|
name: "test",
|
|
1445
1525
|
description: "Run tests using Vitest",
|
|
1446
|
-
|
|
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 }) => {
|
|
1447
1535
|
await this.utils.ensureConfig(root, {
|
|
1448
1536
|
tsconfigJson: true,
|
|
1449
1537
|
viteConfigTs: true
|
|
1450
1538
|
});
|
|
1451
1539
|
await this.utils.ensureDependency(root, "vitest");
|
|
1452
|
-
|
|
1540
|
+
const config = flags.config ? `--config=${flags.config}` : "";
|
|
1541
|
+
await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);
|
|
1453
1542
|
}
|
|
1454
1543
|
});
|
|
1455
1544
|
};
|
|
@@ -1466,7 +1555,7 @@ var AlephaCliExtension = class {
|
|
|
1466
1555
|
if (!await this.fs.exists(extensionPath)) return;
|
|
1467
1556
|
const { default: Extension } = await import(extensionPath);
|
|
1468
1557
|
if (typeof Extension !== "function") return;
|
|
1469
|
-
this.alepha.
|
|
1558
|
+
this.alepha.inject(Extension, { args: [this.alepha] });
|
|
1470
1559
|
}
|
|
1471
1560
|
});
|
|
1472
1561
|
};
|
|
@@ -1474,12 +1563,13 @@ const AlephaCli = $module({
|
|
|
1474
1563
|
name: "alepha.cli",
|
|
1475
1564
|
services: [
|
|
1476
1565
|
AlephaCliExtension,
|
|
1566
|
+
BiomeCommands,
|
|
1477
1567
|
ChangelogCommands,
|
|
1478
1568
|
CoreCommands,
|
|
1569
|
+
DeployCommands,
|
|
1479
1570
|
DrizzleCommands,
|
|
1480
1571
|
VerifyCommands,
|
|
1481
|
-
ViteCommands
|
|
1482
|
-
BiomeCommands
|
|
1572
|
+
ViteCommands
|
|
1483
1573
|
]
|
|
1484
1574
|
});
|
|
1485
1575
|
|
|
@@ -1523,6 +1613,8 @@ var AlephaPackageBuilderCli = class {
|
|
|
1523
1613
|
await this.fs.writeFile(join(tmpDir, "module-dependencies.json"), JSON.stringify(modules, null, 2));
|
|
1524
1614
|
const tsconfig = await readFile(join(root, "../../tsconfig.json"), "utf-8");
|
|
1525
1615
|
const external = Object.keys(JSON.parse(tsconfig).compilerOptions.paths);
|
|
1616
|
+
external.push("bun");
|
|
1617
|
+
external.push("bun:sqlite");
|
|
1526
1618
|
await run.rm(this.dist);
|
|
1527
1619
|
const build = async (item) => {
|
|
1528
1620
|
const entries = [];
|
|
@@ -1672,5 +1764,14 @@ async function analyzeModules(srcDir, packageName) {
|
|
|
1672
1764
|
}
|
|
1673
1765
|
|
|
1674
1766
|
//#endregion
|
|
1675
|
-
|
|
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 };
|
|
1676
1777
|
//# sourceMappingURL=index.js.map
|