alepha 0.15.3 → 0.15.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -11
- package/dist/api/audits/index.d.ts +335 -335
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +11 -3
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +3 -3
- package/dist/api/files/index.js +4 -3
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +198 -155
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +103 -5
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +198 -198
- package/dist/api/keys/index.d.ts.map +1 -1
- package/dist/api/keys/index.js +3 -3
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.browser.js +1 -0
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +3 -3
- package/dist/api/notifications/index.js +4 -3
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +263 -263
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +41 -30
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.d.ts +383 -77
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +284 -72
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +131 -131
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +3 -3
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/batch/index.d.ts +3 -3
- package/dist/batch/index.js +3 -3
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +3 -3
- package/dist/bucket/index.js +6 -6
- package/dist/bucket/index.js.map +1 -1
- package/dist/cache/core/index.d.ts +3 -3
- package/dist/cache/core/index.js +3 -3
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cli/index.d.ts +5612 -20
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +122 -91
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +11 -4
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +8 -6
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +4 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +3 -3
- package/dist/datetime/index.js +3 -3
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +16 -16
- package/dist/email/index.d.ts.map +1 -1
- package/dist/email/index.js +10562 -10
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +3 -3
- package/dist/fake/index.js +3 -3
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +9 -4
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +12 -4
- package/dist/lock/core/index.js.map +1 -1
- package/dist/logger/index.d.ts +3 -3
- package/dist/logger/index.js +6 -3
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +3 -3
- package/dist/mcp/index.js +3 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.d.ts +12 -12
- package/dist/orm/index.js +4 -4
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +3 -3
- package/dist/queue/core/index.js +3 -3
- package/dist/queue/core/index.js.map +1 -1
- package/dist/react/auth/index.browser.js +2 -1
- package/dist/react/auth/index.browser.js.map +1 -1
- package/dist/react/auth/index.d.ts +3 -3
- package/dist/react/auth/index.js +5 -4
- package/dist/react/auth/index.js.map +1 -1
- package/dist/react/core/index.d.ts +6 -6
- package/dist/react/core/index.js +3 -3
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +3 -3
- package/dist/react/form/index.js +3 -3
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/head/index.d.ts +3 -3
- package/dist/react/head/index.js +3 -3
- package/dist/react/head/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +3 -3
- package/dist/react/i18n/index.js +3 -3
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.css +337 -0
- package/dist/react/intro/index.css.map +1 -0
- package/dist/react/intro/index.d.ts +10 -0
- package/dist/react/intro/index.d.ts.map +1 -0
- package/dist/react/intro/index.js +222 -0
- package/dist/react/intro/index.js.map +1 -0
- package/dist/react/router/index.browser.js +2 -2
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +11 -1
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +21 -11
- package/dist/react/router/index.js.map +1 -1
- package/dist/redis/index.d.ts +22 -22
- package/dist/redis/index.js +3 -3
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts +3 -3
- package/dist/retry/index.js +3 -3
- package/dist/retry/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +16 -4
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +45 -7
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/security/index.js +5 -5
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +3 -3
- package/dist/server/auth/index.js +3 -3
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +3 -3
- package/dist/server/cache/index.js +3 -3
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +3 -3
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +4 -3
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/cookies/index.d.ts +3 -3
- package/dist/server/cookies/index.js +3 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +14 -25
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +13 -29
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +3 -3
- package/dist/server/cors/index.js +3 -3
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/health/index.d.ts +20 -20
- package/dist/server/health/index.js +3 -3
- package/dist/server/health/index.js.map +1 -1
- package/dist/server/helmet/index.d.ts +3 -3
- package/dist/server/helmet/index.js +3 -3
- package/dist/server/helmet/index.js.map +1 -1
- package/dist/server/links/index.d.ts +42 -42
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +4 -4
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +3 -3
- package/dist/server/metrics/index.js +3 -3
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts +3 -3
- package/dist/server/multipart/index.js +3 -3
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts +3 -3
- package/dist/server/proxy/index.js +3 -3
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts +3 -3
- package/dist/server/rate-limit/index.js +3 -3
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.d.ts +3 -3
- package/dist/server/static/index.js +6 -6
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +3 -3
- package/dist/server/swagger/index.js +6 -6
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +3 -3
- package/dist/sms/index.js +6 -6
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.d.ts +3 -3
- package/dist/system/index.js +3 -3
- package/dist/system/index.js.map +1 -1
- package/dist/thread/index.d.ts +3 -3
- package/dist/thread/index.js +3 -3
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.d.ts +3 -3
- package/dist/topic/core/index.js +3 -3
- package/dist/topic/core/index.js.map +1 -1
- package/dist/vite/index.d.ts +6286 -4
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +28 -2
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts +37 -37
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +3 -3
- package/dist/websocket/index.js.map +1 -1
- package/package.json +12 -4
- package/src/api/audits/controllers/AdminAuditController.ts +8 -0
- package/src/api/audits/index.ts +3 -3
- package/src/api/files/controllers/AdminFileStatsController.ts +1 -0
- package/src/api/files/index.ts +3 -3
- package/src/api/jobs/controllers/AdminJobController.ts +18 -2
- package/src/api/jobs/index.ts +4 -3
- package/src/api/jobs/services/JobAudits.spec.ts +89 -0
- package/src/api/jobs/services/JobAudits.ts +101 -0
- package/src/api/keys/index.ts +3 -3
- package/src/api/notifications/controllers/AdminNotificationController.ts +1 -0
- package/src/api/notifications/index.ts +3 -3
- package/src/api/parameters/controllers/AdminConfigController.ts +10 -0
- package/src/api/parameters/index.ts +5 -3
- package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1 -1
- package/src/api/users/__tests__/ApiKeys.spec.ts +1 -1
- package/src/api/users/__tests__/EmailVerification.spec.ts +16 -1
- package/src/api/users/__tests__/PasswordReset.spec.ts +11 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +10 -0
- package/src/api/users/controllers/AdminIdentityController.ts +3 -0
- package/src/api/users/controllers/AdminSessionController.ts +3 -0
- package/src/api/users/controllers/AdminUserController.ts +5 -0
- package/src/api/users/index.ts +8 -9
- package/src/api/users/primitives/$realm.ts +117 -19
- package/src/api/users/providers/RealmProvider.ts +15 -7
- package/src/api/users/services/CredentialService.spec.ts +11 -0
- package/src/api/users/services/CredentialService.ts +47 -24
- package/src/api/users/services/IdentityService.ts +12 -4
- package/src/api/users/services/RegistrationService.spec.ts +11 -0
- package/src/api/users/services/RegistrationService.ts +33 -12
- package/src/api/users/services/SessionService.ts +83 -12
- package/src/api/users/services/UserAudits.ts +47 -0
- package/src/api/users/services/UserFiles.ts +19 -0
- package/src/api/users/services/UserJobs.spec.ts +107 -0
- package/src/api/users/services/UserJobs.ts +62 -0
- package/src/api/users/services/UserParameters.ts +23 -0
- package/src/api/users/services/UserService.ts +34 -17
- package/src/api/verifications/index.ts +3 -3
- package/src/batch/index.ts +3 -3
- package/src/bucket/index.ts +3 -3
- package/src/cache/core/index.ts +3 -3
- package/src/cli/commands/build.ts +1 -0
- package/src/cli/commands/db.ts +9 -0
- package/src/cli/commands/init.spec.ts +2 -17
- package/src/cli/commands/init.ts +37 -1
- package/src/cli/providers/ViteDevServerProvider.ts +36 -2
- package/src/cli/services/AlephaCliUtils.ts +17 -0
- package/src/cli/services/PackageManagerUtils.ts +15 -1
- package/src/cli/services/ProjectScaffolder.ts +8 -13
- package/src/cli/templates/agentMd.ts +2 -25
- package/src/cli/templates/apiAppSecurityTs.ts +37 -2
- package/src/cli/templates/mainCss.ts +2 -32
- package/src/cli/templates/webAppRouterTs.ts +5 -5
- package/src/cli/templates/webHomeComponentTsx.ts +10 -0
- package/src/command/helpers/Runner.ts +14 -1
- package/src/command/index.ts +3 -3
- package/src/core/helpers/primitive.ts +0 -5
- package/src/core/index.ts +3 -3
- package/src/datetime/index.ts +3 -3
- package/src/email/index.ts +3 -3
- package/src/email/index.workerd.ts +36 -0
- package/src/email/providers/LocalEmailProvider.ts +2 -2
- package/src/email/providers/WorkermailerEmailProvider.ts +221 -0
- package/src/fake/index.ts +3 -3
- package/src/lock/core/index.ts +3 -3
- package/src/lock/core/primitives/$lock.ts +13 -1
- package/src/logger/index.ts +3 -3
- package/src/logger/providers/PrettyFormatterProvider.ts +7 -0
- package/src/mcp/index.ts +3 -3
- package/src/orm/index.ts +3 -3
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
- package/src/queue/core/index.ts +3 -3
- package/src/react/auth/index.ts +3 -3
- package/src/react/auth/services/ReactAuth.ts +3 -1
- package/src/react/core/index.ts +3 -3
- package/src/react/form/index.ts +3 -3
- package/src/react/head/index.ts +3 -3
- package/src/react/i18n/index.ts +3 -3
- package/src/react/intro/components/GettingStarted.css +334 -0
- package/src/react/intro/components/GettingStarted.tsx +276 -0
- package/src/react/intro/index.ts +1 -0
- package/src/react/router/atoms/ssrManifestAtom.ts +7 -0
- package/src/react/router/index.browser.ts +2 -0
- package/src/react/router/index.ts +2 -0
- package/src/react/router/providers/ReactServerProvider.ts +14 -4
- package/src/react/router/providers/SSRManifestProvider.ts +7 -0
- package/src/redis/index.ts +3 -3
- package/src/retry/index.ts +3 -3
- package/src/router/index.ts +3 -3
- package/src/scheduler/index.ts +3 -3
- package/src/scheduler/index.workerd.ts +43 -0
- package/src/scheduler/providers/CronProvider.ts +53 -6
- package/src/scheduler/providers/WorkerdCronProvider.ts +102 -0
- package/src/security/index.ts +3 -3
- package/src/security/providers/JwtProvider.ts +2 -2
- package/src/server/auth/index.ts +3 -3
- package/src/server/cache/index.ts +3 -3
- package/src/server/compress/index.ts +3 -3
- package/src/server/compress/providers/ServerCompressProvider.ts +6 -0
- package/src/server/cookies/index.ts +3 -3
- package/src/server/core/index.ts +3 -3
- package/src/server/core/primitives/$action.spec.ts +3 -2
- package/src/server/core/primitives/$action.ts +6 -2
- package/src/server/core/providers/NodeHttpServerProvider.ts +2 -15
- package/src/server/core/providers/ServerProvider.ts +4 -2
- package/src/server/core/providers/ServerRouterProvider.ts +5 -27
- package/src/server/cors/index.ts +3 -3
- package/src/server/health/index.ts +3 -3
- package/src/server/helmet/index.ts +3 -3
- package/src/server/links/index.ts +3 -3
- package/src/server/links/providers/ServerLinksProvider.spec.ts +332 -0
- package/src/server/links/providers/ServerLinksProvider.ts +1 -1
- package/src/server/metrics/index.ts +3 -3
- package/src/server/multipart/index.ts +3 -3
- package/src/server/proxy/index.ts +3 -3
- package/src/server/rate-limit/index.ts +3 -3
- package/src/server/static/index.ts +3 -3
- package/src/server/swagger/index.ts +3 -3
- package/src/sms/index.ts +3 -3
- package/src/system/index.ts +3 -3
- package/src/thread/index.ts +3 -3
- package/src/topic/core/index.ts +3 -3
- package/src/vite/tasks/generateCloudflare.ts +38 -2
- package/src/websocket/index.ts +3 -3
- package/src/cli/templates/webHelloComponentTsx.ts +0 -30
- /package/src/api/users/{notifications → services}/UserNotifications.ts +0 -0
package/src/cli/commands/db.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
import { FileSystemProvider } from "alepha/system";
|
|
10
10
|
import { AppEntryProvider } from "../providers/AppEntryProvider.ts";
|
|
11
11
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
12
|
+
import { PackageManagerUtils } from "../services/PackageManagerUtils.ts";
|
|
12
13
|
|
|
13
14
|
const drizzleCommandFlags = t.object({
|
|
14
15
|
provider: t.optional(
|
|
@@ -29,6 +30,7 @@ export class DbCommand {
|
|
|
29
30
|
protected readonly log = $logger();
|
|
30
31
|
protected readonly fs = $inject(FileSystemProvider);
|
|
31
32
|
protected readonly utils = $inject(AlephaCliUtils);
|
|
33
|
+
protected readonly pm = $inject(PackageManagerUtils);
|
|
32
34
|
protected readonly entryProvider = $inject(AppEntryProvider);
|
|
33
35
|
|
|
34
36
|
/**
|
|
@@ -316,6 +318,13 @@ export class DbCommand {
|
|
|
316
318
|
this.log.info("");
|
|
317
319
|
this.log.info(options.logMessage(providerName, dialect));
|
|
318
320
|
|
|
321
|
+
if (dialect === "sqlite") {
|
|
322
|
+
await this.pm.ensureDependency(options.root, "better-sqlite3", {
|
|
323
|
+
dev: true,
|
|
324
|
+
exec: (cmd, opts) => this.utils.exec(cmd, opts),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
319
328
|
const drizzleConfigJsPath = await this.prepareDrizzleConfig({
|
|
320
329
|
kit: drizzleKitProvider,
|
|
321
330
|
provider,
|
|
@@ -316,7 +316,7 @@ describe("alepha init", () => {
|
|
|
316
316
|
|
|
317
317
|
expect(fs.wasWritten("/project/src/web/index.ts")).toBe(true);
|
|
318
318
|
expect(fs.wasWritten("/project/src/web/AppRouter.ts")).toBe(true);
|
|
319
|
-
expect(fs.wasWritten("/project/src/web/components/
|
|
319
|
+
expect(fs.wasWritten("/project/src/web/components/Home.tsx")).toBe(true);
|
|
320
320
|
});
|
|
321
321
|
|
|
322
322
|
it("should create main.browser.ts for client-side entry", async () => {
|
|
@@ -331,28 +331,13 @@ describe("alepha init", () => {
|
|
|
331
331
|
).toBe(true);
|
|
332
332
|
});
|
|
333
333
|
|
|
334
|
-
it("should create main.css
|
|
334
|
+
it("should create main.css", async () => {
|
|
335
335
|
const { fs, cli, cmd, json } = createTestEnv();
|
|
336
336
|
await setupProject(fs, json);
|
|
337
337
|
|
|
338
338
|
await cli.run(cmd.init, { argv: "--react", root: "/project" });
|
|
339
339
|
|
|
340
340
|
expect(fs.wasWritten("/project/src/main.css")).toBe(true);
|
|
341
|
-
expect(fs.wasWrittenMatching("/project/src/main.css", /box-sizing/)).toBe(
|
|
342
|
-
true,
|
|
343
|
-
);
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
it("should create main.css with @alepha/ui import when --ui", async () => {
|
|
347
|
-
const { fs, cli, cmd, json } = createTestEnv();
|
|
348
|
-
await setupProject(fs, json);
|
|
349
|
-
|
|
350
|
-
await cli.run(cmd.init, { argv: "--react --ui", root: "/project" });
|
|
351
|
-
|
|
352
|
-
expect(fs.wasWritten("/project/src/main.css")).toBe(true);
|
|
353
|
-
expect(
|
|
354
|
-
fs.wasWrittenMatching("/project/src/main.css", /@alepha\/ui\/styles/),
|
|
355
|
-
).toBe(true);
|
|
356
341
|
});
|
|
357
342
|
|
|
358
343
|
it("should not create api structure without --api flag", async () => {
|
package/src/cli/commands/init.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { $inject, t } from "alepha";
|
|
2
2
|
import { $command } from "alepha/command";
|
|
3
|
+
import { $logger, ConsoleColorProvider } from "alepha/logger";
|
|
3
4
|
import { FileSystemProvider } from "alepha/system";
|
|
4
5
|
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
5
6
|
import { PackageManagerUtils } from "../services/PackageManagerUtils.ts";
|
|
6
7
|
import { ProjectScaffolder } from "../services/ProjectScaffolder.ts";
|
|
7
8
|
|
|
8
9
|
export class InitCommand {
|
|
10
|
+
protected readonly log = $logger();
|
|
11
|
+
protected readonly colors = $inject(ConsoleColorProvider);
|
|
9
12
|
protected readonly utils = $inject(AlephaCliUtils);
|
|
10
13
|
protected readonly pm = $inject(PackageManagerUtils);
|
|
11
14
|
protected readonly scaffolder = $inject(ProjectScaffolder);
|
|
@@ -106,6 +109,11 @@ export class InitCommand {
|
|
|
106
109
|
|
|
107
110
|
const isExpo = await this.pm.hasExpo(root);
|
|
108
111
|
|
|
112
|
+
// Get git email for admin auto-promotion (if auth enabled)
|
|
113
|
+
const adminEmail = flags.auth
|
|
114
|
+
? await this.utils.getGitEmail()
|
|
115
|
+
: undefined;
|
|
116
|
+
|
|
109
117
|
const force = !!flags.force;
|
|
110
118
|
|
|
111
119
|
await run({
|
|
@@ -113,9 +121,9 @@ export class InitCommand {
|
|
|
113
121
|
handler: async () => {
|
|
114
122
|
await this.scaffolder.ensureConfig(root, {
|
|
115
123
|
force,
|
|
116
|
-
tsconfigJson: !workspace.config.tsconfigJson,
|
|
117
124
|
packageJson: { ...flags, isPackage: workspace.isPackage },
|
|
118
125
|
// Skip workspace-level configs if they exist at workspace root
|
|
126
|
+
tsconfigJson: !workspace.config.tsconfigJson,
|
|
119
127
|
biomeJson: !workspace.config.biomeJson,
|
|
120
128
|
editorconfig: !workspace.config.editorconfig,
|
|
121
129
|
agentMd: agentType
|
|
@@ -132,6 +140,7 @@ export class InitCommand {
|
|
|
132
140
|
if (flags.api) {
|
|
133
141
|
await this.scaffolder.ensureApiProject(root, {
|
|
134
142
|
auth: !!flags.auth,
|
|
143
|
+
adminEmail,
|
|
135
144
|
force,
|
|
136
145
|
});
|
|
137
146
|
}
|
|
@@ -196,6 +205,33 @@ export class InitCommand {
|
|
|
196
205
|
});
|
|
197
206
|
}
|
|
198
207
|
}
|
|
208
|
+
|
|
209
|
+
run.end();
|
|
210
|
+
|
|
211
|
+
// Success message
|
|
212
|
+
const projectName = args || ".";
|
|
213
|
+
const pmRun = pmName === "npm" ? "npm run" : pmName;
|
|
214
|
+
const c = this.colors;
|
|
215
|
+
|
|
216
|
+
this.log.info("");
|
|
217
|
+
this.log.info(` ${c.set("GREEN", "✓")} Project ready!`);
|
|
218
|
+
this.log.info("");
|
|
219
|
+
this.log.info(
|
|
220
|
+
` ${c.set("GREY_DARK", "$")} cd ${c.set("CYAN", projectName)}`,
|
|
221
|
+
);
|
|
222
|
+
this.log.info(
|
|
223
|
+
` ${c.set("GREY_DARK", "$")} ${c.set("CYAN", `${pmRun} dev`)}`,
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
if (adminEmail) {
|
|
227
|
+
this.log.info("");
|
|
228
|
+
this.log.info(` Admin email: ${c.set("GREEN", adminEmail)}`);
|
|
229
|
+
this.log.info(
|
|
230
|
+
` ${c.set("GREY_DARK", "(from git config, change in src/api/AppSecurity.ts)")}`,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
this.log.info("");
|
|
199
235
|
},
|
|
200
236
|
});
|
|
201
237
|
}
|
|
@@ -219,6 +219,9 @@ export class ViteDevServerProvider {
|
|
|
219
219
|
);
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
// expose Vite server to Alepha for Logger SSR Fix stack traces
|
|
223
|
+
alepha.store.set("alepha.vite.server" as any, this.server);
|
|
224
|
+
|
|
222
225
|
this.alepha = alepha;
|
|
223
226
|
await this.setupAlepha();
|
|
224
227
|
|
|
@@ -245,6 +248,11 @@ export class ViteDevServerProvider {
|
|
|
245
248
|
return;
|
|
246
249
|
}
|
|
247
250
|
|
|
251
|
+
// Generate dev head content using Vite's transformIndexHtml
|
|
252
|
+
// This lets Vite and all plugins (React, etc.) inject their scripts
|
|
253
|
+
const devHead = await this.generateDevHead();
|
|
254
|
+
this.alepha.store.set("alepha.react.ssr.manifest" as any, { devHead });
|
|
255
|
+
|
|
248
256
|
this.alepha.events.on("server:onRequest", {
|
|
249
257
|
priority: "first",
|
|
250
258
|
callback: async ({ request }) => {
|
|
@@ -264,6 +272,32 @@ export class ViteDevServerProvider {
|
|
|
264
272
|
});
|
|
265
273
|
}
|
|
266
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Generate dev head content by transforming a minimal HTML through Vite.
|
|
277
|
+
* This lets Vite and all plugins inject their scripts (HMR client, React Fast Refresh, etc.).
|
|
278
|
+
*/
|
|
279
|
+
protected async generateDevHead(): Promise<string> {
|
|
280
|
+
const { browser, style } = this.options.entry;
|
|
281
|
+
|
|
282
|
+
// Build minimal HTML with entry points
|
|
283
|
+
const scripts: string[] = [];
|
|
284
|
+
if (style) {
|
|
285
|
+
scripts.push(`<link rel="stylesheet" href="/${style}">`);
|
|
286
|
+
}
|
|
287
|
+
if (browser) {
|
|
288
|
+
scripts.push(`<script type="module" src="/${browser}"></script>`);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const minimalHtml = `<!DOCTYPE html><html><head>${scripts.join("\n")}</head><body></body></html>`;
|
|
292
|
+
|
|
293
|
+
// Transform through Vite to inject all plugin scripts
|
|
294
|
+
const transformed = await this.server.transformIndexHtml("/", minimalHtml);
|
|
295
|
+
|
|
296
|
+
// Extract head content
|
|
297
|
+
const headMatch = transformed.match(/<head>([\s\S]*?)<\/head>/i);
|
|
298
|
+
return headMatch?.[1]?.trim() ?? "";
|
|
299
|
+
}
|
|
300
|
+
|
|
267
301
|
/**
|
|
268
302
|
* Check if request is for an HTML page (not an asset).
|
|
269
303
|
*/
|
|
@@ -312,8 +346,8 @@ export class ViteDevServerProvider {
|
|
|
312
346
|
const originalEnd = res.end.bind(res);
|
|
313
347
|
|
|
314
348
|
const guardedCall = <T>(fn: (...args: any[]) => T, ...args: any[]): T => {
|
|
315
|
-
if (resolved &&
|
|
316
|
-
// Vite
|
|
349
|
+
if (resolved && ctx.metadata.vite) {
|
|
350
|
+
// Vite already handled this request, ignore late writes from framework
|
|
317
351
|
return undefined as T;
|
|
318
352
|
}
|
|
319
353
|
return fn(...args);
|
|
@@ -161,4 +161,21 @@ ${models.map((it: string) => `export const ${it} = models["${it}"];`).join("\n")
|
|
|
161
161
|
return "unknown";
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get the user's email from git config.
|
|
167
|
+
*
|
|
168
|
+
* @returns The git user email or undefined if not configured
|
|
169
|
+
*/
|
|
170
|
+
public async getGitEmail(): Promise<string | undefined> {
|
|
171
|
+
try {
|
|
172
|
+
const result = await this.shell.run("git config user.email", {
|
|
173
|
+
capture: true,
|
|
174
|
+
});
|
|
175
|
+
const email = result.trim();
|
|
176
|
+
return email || undefined;
|
|
177
|
+
} catch {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
164
181
|
}
|
|
@@ -48,6 +48,7 @@ export class PackageManagerUtils {
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Detect the package manager used in the project.
|
|
51
|
+
* Checks current directory first, then workspace root if in a monorepo.
|
|
51
52
|
*/
|
|
52
53
|
public async getPackageManager(
|
|
53
54
|
root: string,
|
|
@@ -55,10 +56,21 @@ export class PackageManagerUtils {
|
|
|
55
56
|
): Promise<"yarn" | "pnpm" | "npm" | "bun"> {
|
|
56
57
|
if (pm) return pm;
|
|
57
58
|
if (this.alepha.isBun()) return "bun";
|
|
59
|
+
|
|
60
|
+
// Check current directory first
|
|
58
61
|
if (await this.fs.exists(this.fs.join(root, "bun.lock"))) return "bun";
|
|
59
62
|
if (await this.fs.exists(this.fs.join(root, "yarn.lock"))) return "yarn";
|
|
60
63
|
if (await this.fs.exists(this.fs.join(root, "pnpm-lock.yaml")))
|
|
61
64
|
return "pnpm";
|
|
65
|
+
if (await this.fs.exists(this.fs.join(root, "package-lock.json")))
|
|
66
|
+
return "npm";
|
|
67
|
+
|
|
68
|
+
// Check workspace root (for monorepo packages like apps/blog)
|
|
69
|
+
const workspace = await this.getWorkspaceContext(root);
|
|
70
|
+
if (workspace.packageManager) {
|
|
71
|
+
return workspace.packageManager;
|
|
72
|
+
}
|
|
73
|
+
|
|
62
74
|
return "npm";
|
|
63
75
|
}
|
|
64
76
|
|
|
@@ -358,7 +370,9 @@ export class PackageManagerUtils {
|
|
|
358
370
|
alepha: `^${version}`,
|
|
359
371
|
};
|
|
360
372
|
|
|
361
|
-
const devDependencies: Record<string, string> = {
|
|
373
|
+
const devDependencies: Record<string, string> = {
|
|
374
|
+
vite: alephaDeps.vite,
|
|
375
|
+
};
|
|
362
376
|
|
|
363
377
|
// Add biome/vitest only if not a workspace package (workspace root has them)
|
|
364
378
|
if (!modes.isPackage) {
|
|
@@ -19,7 +19,7 @@ import { mainCss } from "../templates/mainCss.ts";
|
|
|
19
19
|
import { mainServerTs } from "../templates/mainServerTs.ts";
|
|
20
20
|
import { tsconfigJson } from "../templates/tsconfigJson.ts";
|
|
21
21
|
import { webAppRouterTs } from "../templates/webAppRouterTs.ts";
|
|
22
|
-
import {
|
|
22
|
+
import { webHomeComponentTsx } from "../templates/webHomeComponentTsx.ts";
|
|
23
23
|
import { webIndexTs } from "../templates/webIndexTs.ts";
|
|
24
24
|
import { AlephaCliUtils } from "./AlephaCliUtils.ts";
|
|
25
25
|
import {
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
* - Project structure (src/api, src/web)
|
|
35
35
|
* - Configuration files (tsconfig, biome, editorconfig)
|
|
36
36
|
* - Entry points (main.server.ts, main.browser.ts)
|
|
37
|
-
* - Example code (HelloController,
|
|
37
|
+
* - Example code (HelloController, Home component)
|
|
38
38
|
*/
|
|
39
39
|
export class ProjectScaffolder {
|
|
40
40
|
protected readonly log = $logger();
|
|
@@ -228,7 +228,7 @@ export class ProjectScaffolder {
|
|
|
228
228
|
*/
|
|
229
229
|
public async ensureApiProject(
|
|
230
230
|
root: string,
|
|
231
|
-
opts: { auth?: boolean; force?: boolean } = {},
|
|
231
|
+
opts: { auth?: boolean; adminEmail?: string; force?: boolean } = {},
|
|
232
232
|
): Promise<void> {
|
|
233
233
|
const appName = this.getAppName(root);
|
|
234
234
|
|
|
@@ -256,7 +256,7 @@ export class ProjectScaffolder {
|
|
|
256
256
|
await this.ensureFile(
|
|
257
257
|
root,
|
|
258
258
|
"src/api/AppSecurity.ts",
|
|
259
|
-
apiAppSecurityTs(),
|
|
259
|
+
apiAppSecurityTs({ adminEmail: opts.adminEmail }),
|
|
260
260
|
opts.force,
|
|
261
261
|
);
|
|
262
262
|
}
|
|
@@ -272,7 +272,7 @@ export class ProjectScaffolder {
|
|
|
272
272
|
* Creates:
|
|
273
273
|
* - src/main.browser.ts
|
|
274
274
|
* - src/main.css
|
|
275
|
-
* - src/web/index.ts, src/web/AppRouter.ts, src/web/components/
|
|
275
|
+
* - src/web/index.ts, src/web/AppRouter.ts, src/web/components/Home.tsx
|
|
276
276
|
*/
|
|
277
277
|
public async ensureWebProject(
|
|
278
278
|
root: string,
|
|
@@ -292,12 +292,7 @@ export class ProjectScaffolder {
|
|
|
292
292
|
});
|
|
293
293
|
|
|
294
294
|
// src/main.css
|
|
295
|
-
await this.ensureFile(
|
|
296
|
-
root,
|
|
297
|
-
"src/main.css",
|
|
298
|
-
mainCss({ ui: opts.ui }),
|
|
299
|
-
opts.force,
|
|
300
|
-
);
|
|
295
|
+
await this.ensureFile(root, "src/main.css", mainCss(), opts.force);
|
|
301
296
|
|
|
302
297
|
// Web structure
|
|
303
298
|
await this.ensureFile(
|
|
@@ -319,8 +314,8 @@ export class ProjectScaffolder {
|
|
|
319
314
|
);
|
|
320
315
|
await this.ensureFile(
|
|
321
316
|
root,
|
|
322
|
-
"src/web/components/
|
|
323
|
-
|
|
317
|
+
"src/web/components/Home.tsx",
|
|
318
|
+
webHomeComponentTsx(),
|
|
324
319
|
opts.force,
|
|
325
320
|
);
|
|
326
321
|
await this.ensureFile(
|
|
@@ -27,6 +27,7 @@ This file provides guidance to AI coding assistants when working with this Aleph
|
|
|
27
27
|
|
|
28
28
|
### Pages with \`$page\`
|
|
29
29
|
\`\`\`tsx
|
|
30
|
+
import { t } from "alepha";
|
|
30
31
|
import { $page } from "alepha/react/router";
|
|
31
32
|
import { $client } from "alepha/server/links";
|
|
32
33
|
import type { UserController } from "./UserController.ts";
|
|
@@ -196,31 +197,6 @@ class AppRouter {
|
|
|
196
197
|
}
|
|
197
198
|
\`\`\`
|
|
198
199
|
|
|
199
|
-
### Modules with \`$module\`
|
|
200
|
-
\`\`\`typescript
|
|
201
|
-
// src/api/index.ts - Groups all API services
|
|
202
|
-
import { $module } from "alepha";
|
|
203
|
-
|
|
204
|
-
export const ApiModule = $module({
|
|
205
|
-
name: "app.api",
|
|
206
|
-
services: [
|
|
207
|
-
UserController,
|
|
208
|
-
OrderController,
|
|
209
|
-
UserService,
|
|
210
|
-
],
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// src/web/index.ts - Groups all web services (React only)
|
|
214
|
-
export const WebModule = $module({
|
|
215
|
-
name: "app.web",
|
|
216
|
-
services: [AppRouter, Toaster],
|
|
217
|
-
register(alepha) {
|
|
218
|
-
// Optional: configure additional services
|
|
219
|
-
alepha.with(SomeLibrary);
|
|
220
|
-
},
|
|
221
|
-
});
|
|
222
|
-
\`\`\`
|
|
223
|
-
|
|
224
200
|
### Environment Variables
|
|
225
201
|
\`\`\`typescript
|
|
226
202
|
import { $env, t } from "alepha";
|
|
@@ -268,6 +244,7 @@ describe("UserService", () => {
|
|
|
268
244
|
it("should create user", async () => {
|
|
269
245
|
const alepha = Alepha.create().with(UserService);
|
|
270
246
|
const service = alepha.inject(UserService);
|
|
247
|
+
await alepha.start();
|
|
271
248
|
|
|
272
249
|
const user = await service.create({ email: "test@example.com" });
|
|
273
250
|
expect(user.email).toBe("test@example.com");
|
|
@@ -1,10 +1,45 @@
|
|
|
1
|
-
export const apiAppSecurityTs = () => {
|
|
1
|
+
export const apiAppSecurityTs = (opts: { adminEmail?: string } = {}) => {
|
|
2
|
+
const adminEmailsValue = opts.adminEmail ? `["${opts.adminEmail}"]` : "[]";
|
|
3
|
+
|
|
2
4
|
return `
|
|
3
5
|
import { $realm } from "alepha/api/users";
|
|
4
6
|
|
|
5
7
|
export class AppSecurity {
|
|
6
8
|
users = $realm({
|
|
7
|
-
|
|
9
|
+
settings: {
|
|
10
|
+
// Auto-promote these users to admin on login
|
|
11
|
+
adminEmails: ${adminEmailsValue},
|
|
12
|
+
adminUsernames: [],
|
|
13
|
+
|
|
14
|
+
// Registration & login options
|
|
15
|
+
registrationAllowed: true,
|
|
16
|
+
emailEnabled: true,
|
|
17
|
+
emailRequired: true,
|
|
18
|
+
usernameEnabled: false,
|
|
19
|
+
usernameRequired: false,
|
|
20
|
+
phoneEnabled: false,
|
|
21
|
+
phoneRequired: false,
|
|
22
|
+
|
|
23
|
+
// Verification (requires notifications feature)
|
|
24
|
+
verifyEmailRequired: false,
|
|
25
|
+
verifyPhoneRequired: false,
|
|
26
|
+
resetPasswordAllowed: false,
|
|
27
|
+
},
|
|
28
|
+
features: {
|
|
29
|
+
// Enable additional features
|
|
30
|
+
notifications: false,
|
|
31
|
+
audits: false,
|
|
32
|
+
apiKeys: false,
|
|
33
|
+
jobs: false,
|
|
34
|
+
files: false,
|
|
35
|
+
parameters: false,
|
|
36
|
+
},
|
|
37
|
+
identities: {
|
|
38
|
+
// Enable authentication providers
|
|
39
|
+
credentials: true,
|
|
40
|
+
// google: true,
|
|
41
|
+
// github: true,
|
|
42
|
+
},
|
|
8
43
|
});
|
|
9
44
|
}
|
|
10
45
|
`.trim();
|
|
@@ -1,33 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
ui
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const mainCss = (options: MainCssOptions = {}) => {
|
|
6
|
-
if (options.ui) {
|
|
7
|
-
return `@import "@alepha/ui/styles";`;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return `
|
|
11
|
-
* {
|
|
12
|
-
box-sizing: border-box;
|
|
13
|
-
margin: 0;
|
|
14
|
-
padding: 0;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
html,
|
|
18
|
-
body {
|
|
19
|
-
height: 100%;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
body {
|
|
23
|
-
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
24
|
-
"Helvetica Neue", Arial, sans-serif;
|
|
25
|
-
line-height: 1.5;
|
|
26
|
-
-webkit-font-smoothing: antialiased;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
#root {
|
|
30
|
-
height: 100%;
|
|
31
|
-
}
|
|
32
|
-
`.trim();
|
|
1
|
+
export const mainCss = () => {
|
|
2
|
+
return `@import "@alepha/ui/styles";`;
|
|
33
3
|
};
|
|
@@ -47,22 +47,22 @@ export const webAppRouterTs = (options: {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
classMembers.push(` layout = $page({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
parent: this.ui.root,
|
|
51
|
+
children: () => [this.home],
|
|
52
|
+
});`);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// Home page - with or without loader
|
|
56
56
|
if (options.api) {
|
|
57
57
|
classMembers.push(` home = $page({
|
|
58
58
|
path: "/",
|
|
59
|
-
lazy: () => import("./components/
|
|
59
|
+
lazy: () => import("./components/Home.tsx"),
|
|
60
60
|
loader: () => this.api.hello(),
|
|
61
61
|
});`);
|
|
62
62
|
} else {
|
|
63
63
|
classMembers.push(` home = $page({
|
|
64
64
|
path: "/",
|
|
65
|
-
lazy: () => import("./components/
|
|
65
|
+
lazy: () => import("./components/Home.tsx"),
|
|
66
66
|
});`);
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -34,11 +34,19 @@ export interface RunnerMethod {
|
|
|
34
34
|
): Promise<string>;
|
|
35
35
|
rm: (glob: string | string[], options?: RunOptions) => Promise<string>;
|
|
36
36
|
cp: (source: string, dest: string, options?: RunOptions) => Promise<string>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Ends the runner and prints a summary of executed tasks.
|
|
40
|
+
*
|
|
41
|
+
* > This is automatically called at the end of command execution.
|
|
42
|
+
* > But can be called manually if needed to print more stuff before the command ends.
|
|
43
|
+
*/
|
|
44
|
+
end: () => void;
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
export class Runner {
|
|
40
48
|
protected readonly log = $logger();
|
|
41
|
-
protected
|
|
49
|
+
protected timers: Timer[] = [];
|
|
42
50
|
protected readonly startTime: number = Date.now();
|
|
43
51
|
protected readonly prettyPrint = $inject(PrettyPrint);
|
|
44
52
|
protected readonly alepha = $inject(Alepha);
|
|
@@ -149,6 +157,8 @@ export class Runner {
|
|
|
149
157
|
);
|
|
150
158
|
};
|
|
151
159
|
|
|
160
|
+
runFn.end = () => this.end();
|
|
161
|
+
|
|
152
162
|
return runFn;
|
|
153
163
|
}
|
|
154
164
|
|
|
@@ -189,6 +199,9 @@ export class Runner {
|
|
|
189
199
|
const totalTime = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
190
200
|
this.log.info(`Total time: ${totalTime}s`);
|
|
191
201
|
this.log.info(``);
|
|
202
|
+
|
|
203
|
+
// clear timers after rendering
|
|
204
|
+
this.timers = [];
|
|
192
205
|
}
|
|
193
206
|
|
|
194
207
|
protected async executeTask(task: Task): Promise<string> {
|
package/src/command/index.ts
CHANGED
|
@@ -19,9 +19,9 @@ export * from "./providers/CliProvider.ts";
|
|
|
19
19
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* |
|
|
23
|
-
*
|
|
24
|
-
* |
|
|
22
|
+
* | Stability | Since | Runtime |
|
|
23
|
+
* |-----------|-------|---------|
|
|
24
|
+
* | 3 - stable | 0.6.0 | node, bun|
|
|
25
25
|
*
|
|
26
26
|
* Declarative CLI command framework.
|
|
27
27
|
*
|
|
@@ -47,11 +47,6 @@ export abstract class Primitive<T extends object = {}> {
|
|
|
47
47
|
|
|
48
48
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
49
49
|
|
|
50
|
-
export type PrimitiveFactory<TPrimitive extends Primitive = Primitive> = {
|
|
51
|
-
(options: TPrimitive["options"]): TPrimitive;
|
|
52
|
-
[KIND]: InstantiableClass<TPrimitive>;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
50
|
export type PrimitiveFactoryLike<T extends object = any> = {
|
|
56
51
|
(options: T): any;
|
|
57
52
|
[KIND]: any;
|
package/src/core/index.ts
CHANGED
|
@@ -23,9 +23,9 @@ export * from "./index.shared.ts";
|
|
|
23
23
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* |
|
|
27
|
-
*
|
|
28
|
-
* |
|
|
26
|
+
* | Stability | Since | Runtime |
|
|
27
|
+
* |-----------|-------|---------|
|
|
28
|
+
* | 3 - stable | 0.1.0 | node, bun, workerd, browser, expo|
|
|
29
29
|
*
|
|
30
30
|
* Foundation of the entire framework with dependency injection and lifecycle management.
|
|
31
31
|
*
|
package/src/datetime/index.ts
CHANGED
|
@@ -8,9 +8,9 @@ export * from "./providers/DateTimeProvider.ts";
|
|
|
8
8
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* |
|
|
12
|
-
*
|
|
13
|
-
* |
|
|
11
|
+
* | Stability | Since | Runtime |
|
|
12
|
+
* |-----------|-------|---------|
|
|
13
|
+
* | 3 - stable | 0.10.0 | node, bun, workerd, browser, expo|
|
|
14
14
|
*
|
|
15
15
|
* Date and time operations.
|
|
16
16
|
*
|
package/src/email/index.ts
CHANGED
|
@@ -36,9 +36,9 @@ declare module "alepha" {
|
|
|
36
36
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* |
|
|
40
|
-
*
|
|
41
|
-
* |
|
|
39
|
+
* | Stability | Since | Runtime |
|
|
40
|
+
* |-----------|-------|---------|
|
|
41
|
+
* | 3 - stable | 0.4.0 | node, bun, workerd|
|
|
42
42
|
*
|
|
43
43
|
* Email delivery with template support.
|
|
44
44
|
*
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { $module } from "alepha";
|
|
2
|
+
import { $email } from "./primitives/$email.ts";
|
|
3
|
+
import { EmailProvider } from "./providers/EmailProvider.ts";
|
|
4
|
+
import { MemoryEmailProvider } from "./providers/MemoryEmailProvider.ts";
|
|
5
|
+
import { WorkermailerEmailProvider } from "./providers/WorkermailerEmailProvider.ts";
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
export * from "./errors/EmailError.ts";
|
|
10
|
+
export * from "./primitives/$email.ts";
|
|
11
|
+
export * from "./providers/EmailProvider.ts";
|
|
12
|
+
export * from "./providers/MemoryEmailProvider.ts";
|
|
13
|
+
export * from "./providers/WorkermailerEmailProvider.ts";
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
export const AlephaEmail = $module({
|
|
18
|
+
name: "alepha.email",
|
|
19
|
+
primitives: [$email],
|
|
20
|
+
services: [EmailProvider, MemoryEmailProvider, WorkermailerEmailProvider],
|
|
21
|
+
register: (alepha) => {
|
|
22
|
+
if (alepha.env.EMAIL_HOST) {
|
|
23
|
+
alepha.with({
|
|
24
|
+
optional: true,
|
|
25
|
+
provide: EmailProvider,
|
|
26
|
+
use: WorkermailerEmailProvider,
|
|
27
|
+
});
|
|
28
|
+
} else {
|
|
29
|
+
alepha.with({
|
|
30
|
+
optional: true,
|
|
31
|
+
provide: EmailProvider,
|
|
32
|
+
use: MemoryEmailProvider,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|