alepha 0.14.4 → 0.15.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/README.md +44 -102
- package/dist/api/audits/index.d.ts +331 -443
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +2 -2
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +0 -113
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +2 -3
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +151 -262
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.browser.js +4 -4
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +164 -276
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +4 -4
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +265 -377
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.browser.js +1 -2
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +195 -301
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +203 -184
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js +1 -2
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cache/redis/index.js +2 -2
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/cli/index.d.ts +5900 -165
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1481 -639
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +8 -4
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +29 -25
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +563 -54
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +175 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +564 -54
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +563 -54
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +4 -4
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +89 -42
- package/dist/email/index.d.ts.map +1 -1
- package/dist/email/index.js +129 -33
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +7969 -2
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +22 -22
- package/dist/fake/index.js.map +1 -1
- package/dist/file/index.d.ts +134 -1
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +253 -1
- package/dist/file/index.js.map +1 -1
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/redis/index.d.ts.map +1 -1
- package/dist/logger/index.d.ts +1 -2
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +1 -5
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +19 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +28 -4
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/chunk-DH6iiROE.js +38 -0
- package/dist/orm/index.browser.js +9 -9
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +2821 -0
- package/dist/orm/index.bun.js.map +1 -0
- package/dist/orm/index.d.ts +318 -169
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +2086 -1776
- 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 -1
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/redis/index.bun.js +285 -0
- package/dist/redis/index.bun.js.map +1 -0
- package/dist/redis/index.d.ts +13 -31
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +18 -38
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +83 -1
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +393 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.browser.js +5 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +598 -112
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1808 -97
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1200 -175
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1268 -37
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +6 -3
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +1 -1
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +3 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +115 -13
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +321 -139
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +0 -1
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts +0 -1
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/links/index.browser.js +9 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +1 -2
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +14 -7
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +514 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4462 -4
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/proxy/index.d.ts +0 -1
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/swagger/index.d.ts +1 -2
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +1 -2
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +3 -1
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +10 -10
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +0 -1
- package/dist/thread/index.d.ts.map +1 -1
- package/dist/thread/index.js +2 -2
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/vite/index.d.ts +6315 -149
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +140 -469
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +9 -9
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +28 -28
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +9 -9
- package/dist/websocket/index.js.map +1 -1
- package/package.json +13 -18
- package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
- package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
- package/src/api/users/entities/users.ts +1 -1
- package/src/api/users/index.ts +8 -8
- package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
- package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
- package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
- package/src/api/users/services/CredentialService.ts +7 -7
- package/src/api/users/services/IdentityService.ts +4 -4
- package/src/api/users/services/RegistrationService.spec.ts +25 -27
- package/src/api/users/services/RegistrationService.ts +38 -27
- package/src/api/users/services/SessionCrudService.ts +3 -3
- package/src/api/users/services/SessionService.spec.ts +3 -3
- package/src/api/users/services/SessionService.ts +27 -18
- package/src/api/users/services/UserService.ts +7 -7
- package/src/batch/providers/BatchProvider.ts +1 -2
- package/src/cli/apps/AlephaCli.ts +2 -2
- package/src/cli/apps/AlephaPackageBuilderCli.ts +47 -20
- package/src/cli/assets/apiHelloControllerTs.ts +19 -0
- package/src/cli/assets/apiIndexTs.ts +16 -0
- package/src/cli/assets/biomeJson.ts +2 -1
- package/src/cli/assets/claudeMd.ts +308 -0
- package/src/cli/assets/dummySpecTs.ts +2 -1
- package/src/cli/assets/editorconfig.ts +2 -1
- package/src/cli/assets/mainBrowserTs.ts +4 -3
- package/src/cli/assets/mainCss.ts +24 -0
- package/src/cli/assets/mainServerTs.ts +24 -0
- package/src/cli/assets/tsconfigJson.ts +2 -1
- package/src/cli/assets/webAppRouterTs.ts +16 -0
- package/src/cli/assets/webHelloComponentTsx.ts +20 -0
- package/src/cli/assets/webIndexTs.ts +16 -0
- package/src/cli/atoms/appEntryOptions.ts +13 -0
- package/src/cli/atoms/buildOptions.ts +1 -1
- package/src/cli/atoms/changelogOptions.ts +1 -1
- package/src/cli/commands/build.ts +97 -61
- package/src/cli/commands/db.ts +21 -18
- package/src/cli/commands/deploy.ts +17 -5
- package/src/cli/commands/dev.ts +26 -47
- package/src/cli/commands/gen/env.ts +1 -1
- package/src/cli/commands/init.ts +79 -25
- package/src/cli/commands/lint.ts +9 -3
- package/src/cli/commands/test.ts +8 -2
- package/src/cli/commands/typecheck.ts +5 -1
- package/src/cli/commands/verify.ts +4 -2
- package/src/cli/defineConfig.ts +9 -0
- package/src/cli/index.ts +2 -1
- package/src/cli/providers/AppEntryProvider.ts +131 -0
- package/src/cli/providers/ViteBuildProvider.ts +82 -0
- package/src/cli/providers/ViteDevServerProvider.ts +350 -0
- package/src/cli/providers/ViteTemplateProvider.ts +27 -0
- package/src/cli/services/AlephaCliUtils.ts +72 -602
- package/src/cli/services/PackageManagerUtils.ts +308 -0
- package/src/cli/services/ProjectScaffolder.ts +329 -0
- package/src/command/helpers/Runner.ts +15 -3
- package/src/core/Alepha.ts +2 -8
- package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/index.ts +2 -0
- package/src/core/primitives/$hook.ts +6 -2
- package/src/core/primitives/$module.spec.ts +4 -0
- package/src/core/primitives/$module.ts +12 -0
- package/src/core/providers/AlsProvider.ts +1 -1
- package/src/core/providers/CodecManager.spec.ts +12 -6
- package/src/core/providers/CodecManager.ts +26 -6
- package/src/core/providers/EventManager.ts +169 -13
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +878 -0
- package/src/core/providers/KeylessJsonSchemaCodec.ts +789 -0
- package/src/core/providers/SchemaValidator.spec.ts +236 -0
- package/src/core/providers/StateManager.spec.ts +27 -16
- package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
- package/src/email/providers/LocalEmailProvider.ts +52 -15
- package/src/email/providers/NodemailerEmailProvider.ts +167 -56
- package/src/file/errors/FileError.ts +7 -0
- package/src/file/index.ts +9 -1
- package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
- package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
- package/src/mcp/errors/McpError.ts +30 -0
- package/src/mcp/index.ts +3 -0
- package/src/mcp/transports/SseMcpTransport.ts +16 -6
- package/src/orm/index.browser.ts +1 -19
- package/src/orm/index.bun.ts +77 -0
- package/src/orm/index.shared-server.ts +22 -0
- package/src/orm/index.shared.ts +15 -0
- package/src/orm/index.ts +19 -39
- package/src/orm/providers/DrizzleKitProvider.ts +3 -5
- package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
- package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
- package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
- package/src/orm/services/Repository.ts +19 -0
- package/src/redis/index.bun.ts +35 -0
- package/src/redis/providers/BunRedisProvider.ts +12 -43
- package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
- package/src/redis/providers/NodeRedisProvider.ts +16 -34
- package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
- package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
- package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
- package/src/security/index.browser.ts +5 -0
- package/src/security/index.ts +90 -7
- package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
- package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
- package/src/security/primitives/$role.ts +5 -5
- package/src/security/primitives/$serviceAccount.spec.ts +5 -5
- package/src/security/primitives/$serviceAccount.ts +3 -3
- package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
- package/src/server/auth/primitives/$auth.ts +10 -10
- package/src/server/auth/primitives/$authCredentials.ts +3 -3
- package/src/server/auth/primitives/$authGithub.ts +3 -3
- package/src/server/auth/primitives/$authGoogle.ts +3 -3
- package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
- package/src/server/cache/providers/ServerCacheProvider.ts +1 -1
- package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
- package/src/server/core/index.ts +1 -1
- package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
- package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
- package/src/server/core/providers/NodeHttpServerProvider.ts +92 -24
- package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
- package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
- package/src/server/core/providers/ServerProvider.ts +144 -24
- package/src/server/core/providers/ServerRouterProvider.ts +259 -115
- package/src/server/core/providers/ServerTimingProvider.ts +2 -2
- package/src/server/links/atoms/apiLinksAtom.ts +7 -0
- package/src/server/links/index.browser.ts +2 -0
- package/src/server/links/index.ts +3 -1
- package/src/server/links/providers/LinkProvider.ts +1 -1
- package/src/server/swagger/index.ts +1 -1
- package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
- package/src/sms/providers/LocalSmsProvider.ts +8 -7
- package/src/vite/index.ts +3 -2
- package/src/vite/tasks/buildClient.ts +0 -1
- package/src/vite/tasks/buildServer.ts +80 -22
- package/src/vite/tasks/copyAssets.ts +5 -4
- package/src/vite/tasks/generateCloudflare.ts +7 -0
- package/src/vite/tasks/generateSitemap.ts +64 -23
- package/src/vite/tasks/index.ts +0 -2
- package/src/vite/tasks/prerenderPages.ts +49 -24
- package/dist/server/security/index.browser.js +0 -13
- package/dist/server/security/index.browser.js.map +0 -1
- package/dist/server/security/index.d.ts +0 -173
- package/dist/server/security/index.d.ts.map +0 -1
- package/dist/server/security/index.js +0 -311
- package/dist/server/security/index.js.map +0 -1
- package/src/cli/assets/appRouterTs.ts +0 -9
- package/src/cli/assets/indexHtml.ts +0 -15
- package/src/cli/assets/mainTs.ts +0 -13
- package/src/cli/commands/format.ts +0 -17
- package/src/server/security/index.browser.ts +0 -10
- package/src/server/security/index.ts +0 -94
- package/src/vite/helpers/boot.ts +0 -106
- package/src/vite/plugins/viteAlephaDev.ts +0 -177
- package/src/vite/tasks/devServer.ts +0 -69
- package/src/vite/tasks/runAlepha.ts +0 -270
- /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
- /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
|
@@ -14,7 +14,7 @@ import { type ServerRequest, UnauthorizedError } from "alepha/server";
|
|
|
14
14
|
import type { OAuth2Profile } from "alepha/server/auth";
|
|
15
15
|
import { $client } from "alepha/server/links";
|
|
16
16
|
import type { UserEntity } from "../entities/users.ts";
|
|
17
|
-
import {
|
|
17
|
+
import { RealmProvider } from "../providers/RealmProvider.ts";
|
|
18
18
|
|
|
19
19
|
export class SessionService {
|
|
20
20
|
protected readonly alepha = $inject(Alepha);
|
|
@@ -22,20 +22,20 @@ export class SessionService {
|
|
|
22
22
|
protected readonly dateTimeProvider = $inject(DateTimeProvider);
|
|
23
23
|
protected readonly cryptoProvider = $inject(CryptoProvider);
|
|
24
24
|
protected readonly log = $logger();
|
|
25
|
-
protected readonly
|
|
25
|
+
protected readonly realmProvider = $inject(RealmProvider);
|
|
26
26
|
protected readonly fileController = $client<FileController>();
|
|
27
27
|
protected readonly auditService = $inject(AuditService);
|
|
28
28
|
|
|
29
29
|
public users(userRealmName?: string) {
|
|
30
|
-
return this.
|
|
30
|
+
return this.realmProvider.userRepository(userRealmName);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
public sessions(userRealmName?: string) {
|
|
34
|
-
return this.
|
|
34
|
+
return this.realmProvider.sessionRepository(userRealmName);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
public identities(userRealmName?: string) {
|
|
38
|
-
return this.
|
|
38
|
+
return this.realmProvider.identityRepository(userRealmName);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -55,7 +55,7 @@ export class SessionService {
|
|
|
55
55
|
password: string,
|
|
56
56
|
userRealmName?: string,
|
|
57
57
|
): Promise<UserEntity> {
|
|
58
|
-
const { settings, name } = this.
|
|
58
|
+
const { settings, name } = this.realmProvider.getRealm(userRealmName);
|
|
59
59
|
const isEmail = username.includes("@");
|
|
60
60
|
const isPhone = /^[+\d][\d\s()-]+$/.test(username);
|
|
61
61
|
const isUsername = !isEmail && !isPhone;
|
|
@@ -70,6 +70,25 @@ export class SessionService {
|
|
|
70
70
|
where.realm = name;
|
|
71
71
|
|
|
72
72
|
if (settings.usernameEnabled !== false && isUsername) {
|
|
73
|
+
// validate username format if regex is provided
|
|
74
|
+
if (settings.usernameRegExp) {
|
|
75
|
+
const regex = new RegExp(settings.usernameRegExp);
|
|
76
|
+
if (!regex.test(username)) {
|
|
77
|
+
this.log.warn("Username does not match required format", {
|
|
78
|
+
provider,
|
|
79
|
+
username,
|
|
80
|
+
realm: name,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
await this.auditService.recordAuth("login_failed", {
|
|
84
|
+
userRealm: name,
|
|
85
|
+
description: "Username does not match required format",
|
|
86
|
+
metadata: { provider, username },
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
throw new InvalidCredentialsError();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
73
92
|
where.username = username;
|
|
74
93
|
} else if (settings.emailEnabled !== false && isEmail) {
|
|
75
94
|
where.email = username;
|
|
@@ -237,16 +256,6 @@ export class SessionService {
|
|
|
237
256
|
userId: session.userId,
|
|
238
257
|
});
|
|
239
258
|
|
|
240
|
-
const { name } = this.userRealmProvider.getRealm(userRealmName);
|
|
241
|
-
|
|
242
|
-
await this.auditService.recordAuth("token_refresh", {
|
|
243
|
-
userId: user.id,
|
|
244
|
-
userEmail: user.email ?? undefined,
|
|
245
|
-
userRealm: name,
|
|
246
|
-
sessionId: session.id,
|
|
247
|
-
description: "Session token refreshed",
|
|
248
|
-
});
|
|
249
|
-
|
|
250
259
|
return {
|
|
251
260
|
user,
|
|
252
261
|
expiresIn: expiresAt.unix() - now.unix(),
|
|
@@ -270,7 +279,7 @@ export class SessionService {
|
|
|
270
279
|
this.log.debug("Session deleted");
|
|
271
280
|
|
|
272
281
|
if (session) {
|
|
273
|
-
const { name } = this.
|
|
282
|
+
const { name } = this.realmProvider.getRealm(userRealmName);
|
|
274
283
|
|
|
275
284
|
await this.auditService.recordAuth("logout", {
|
|
276
285
|
userId: session.userId,
|
|
@@ -292,7 +301,7 @@ export class SessionService {
|
|
|
292
301
|
email: profile.email,
|
|
293
302
|
});
|
|
294
303
|
|
|
295
|
-
const realm = this.
|
|
304
|
+
const realm = this.realmProvider.getRealm(userRealmName);
|
|
296
305
|
const identities = this.identities(userRealmName);
|
|
297
306
|
const users = this.users(userRealmName);
|
|
298
307
|
|
|
@@ -7,7 +7,7 @@ import { BadRequestError } from "alepha/server";
|
|
|
7
7
|
import { $client } from "alepha/server/links";
|
|
8
8
|
import type { UserEntity } from "../entities/users.ts";
|
|
9
9
|
import { UserNotifications } from "../notifications/UserNotifications.ts";
|
|
10
|
-
import {
|
|
10
|
+
import { RealmProvider } from "../providers/RealmProvider.ts";
|
|
11
11
|
import type { CreateUser } from "../schemas/createUserSchema.ts";
|
|
12
12
|
import type { UpdateUser } from "../schemas/updateUserSchema.ts";
|
|
13
13
|
import type { UserQuery } from "../schemas/userQuerySchema.ts";
|
|
@@ -16,11 +16,11 @@ export class UserService {
|
|
|
16
16
|
protected readonly log = $logger();
|
|
17
17
|
protected readonly verificationController = $client<VerificationController>();
|
|
18
18
|
protected readonly userNotifications = $inject(UserNotifications);
|
|
19
|
-
protected readonly
|
|
19
|
+
protected readonly realmProvider = $inject(RealmProvider);
|
|
20
20
|
protected readonly auditService = $inject(AuditService);
|
|
21
21
|
|
|
22
22
|
public users(userRealmName?: string) {
|
|
23
|
-
return this.
|
|
23
|
+
return this.realmProvider.userRepository(userRealmName);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -156,7 +156,7 @@ export class UserService {
|
|
|
156
156
|
|
|
157
157
|
this.log.info("Email verified", { email, userId: user.id, type });
|
|
158
158
|
|
|
159
|
-
const realm = this.
|
|
159
|
+
const realm = this.realmProvider.getRealm(userRealmName);
|
|
160
160
|
|
|
161
161
|
await this.auditService.recordUser("update", {
|
|
162
162
|
userId: user.id,
|
|
@@ -256,7 +256,7 @@ export class UserService {
|
|
|
256
256
|
userRealmName,
|
|
257
257
|
});
|
|
258
258
|
|
|
259
|
-
const realm = this.
|
|
259
|
+
const realm = this.realmProvider.getRealm(userRealmName);
|
|
260
260
|
|
|
261
261
|
// TODO: one query instead of 3
|
|
262
262
|
|
|
@@ -342,7 +342,7 @@ export class UserService {
|
|
|
342
342
|
const user = await this.users(userRealmName).updateById(id, data);
|
|
343
343
|
this.log.debug("User updated", { userId: id });
|
|
344
344
|
|
|
345
|
-
const realm = this.
|
|
345
|
+
const realm = this.realmProvider.getRealm(userRealmName);
|
|
346
346
|
|
|
347
347
|
// Build changes object showing what was updated
|
|
348
348
|
const changes: Record<string, { from: unknown; to: unknown }> = {};
|
|
@@ -382,7 +382,7 @@ export class UserService {
|
|
|
382
382
|
await this.users(userRealmName).deleteById(id);
|
|
383
383
|
this.log.info("User deleted", { userId: id });
|
|
384
384
|
|
|
385
|
-
const realm = this.
|
|
385
|
+
const realm = this.realmProvider.getRealm(userRealmName);
|
|
386
386
|
|
|
387
387
|
await this.auditService.recordUser("delete", {
|
|
388
388
|
userRealm: realm.name,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
1
|
import { $inject, type Alepha } from "alepha";
|
|
3
2
|
import { DateTimeProvider, type DurationLike } from "alepha/datetime";
|
|
4
3
|
import { $logger } from "alepha/logger";
|
|
@@ -188,7 +187,7 @@ export class BatchProvider {
|
|
|
188
187
|
item: TItem,
|
|
189
188
|
): string {
|
|
190
189
|
// 1. Generate unique ID
|
|
191
|
-
const id = randomUUID();
|
|
190
|
+
const id = crypto.randomUUID();
|
|
192
191
|
|
|
193
192
|
// 2. Determine the partition key (with error handling)
|
|
194
193
|
let partitionKey: string;
|
|
@@ -5,7 +5,6 @@ import { CleanCommand } from "../commands/clean.ts";
|
|
|
5
5
|
import { DbCommand } from "../commands/db.ts";
|
|
6
6
|
import { DeployCommand } from "../commands/deploy.ts";
|
|
7
7
|
import { DevCommand } from "../commands/dev.ts";
|
|
8
|
-
import { FormatCommand } from "../commands/format.ts";
|
|
9
8
|
import { GitProvider } from "../commands/gen/changelog.ts";
|
|
10
9
|
import { GenCommand } from "../commands/gen.ts";
|
|
11
10
|
import { InitCommand } from "../commands/init.ts";
|
|
@@ -14,6 +13,7 @@ import { RootCommand } from "../commands/root.ts";
|
|
|
14
13
|
import { TestCommand } from "../commands/test.ts";
|
|
15
14
|
import { TypecheckCommand } from "../commands/typecheck.ts";
|
|
16
15
|
import { VerifyCommand } from "../commands/verify.ts";
|
|
16
|
+
import { AppEntryProvider } from "../providers/AppEntryProvider.ts";
|
|
17
17
|
|
|
18
18
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
19
19
|
|
|
@@ -73,7 +73,6 @@ export const AlephaCli = $module({
|
|
|
73
73
|
DbCommand,
|
|
74
74
|
DeployCommand,
|
|
75
75
|
DevCommand,
|
|
76
|
-
FormatCommand,
|
|
77
76
|
InitCommand,
|
|
78
77
|
LintCommand,
|
|
79
78
|
RootCommand,
|
|
@@ -82,6 +81,7 @@ export const AlephaCli = $module({
|
|
|
82
81
|
VerifyCommand,
|
|
83
82
|
GenCommand,
|
|
84
83
|
// Support services
|
|
84
|
+
AppEntryProvider,
|
|
85
85
|
GitProvider,
|
|
86
86
|
],
|
|
87
87
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { access, readdir, readFile } from "node:fs/promises";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { $inject } from "alepha";
|
|
4
|
+
import { $inject, AlephaError } from "alepha";
|
|
5
5
|
import { $command } from "alepha/command";
|
|
6
6
|
import { FileSystemProvider } from "alepha/file";
|
|
7
7
|
import type { InlineConfig } from "tsdown";
|
|
@@ -11,6 +11,7 @@ interface Module {
|
|
|
11
11
|
dependencies: string[];
|
|
12
12
|
native?: boolean;
|
|
13
13
|
browser?: boolean;
|
|
14
|
+
bun?: boolean;
|
|
14
15
|
node?: boolean;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -24,13 +25,13 @@ export class AlephaPackageBuilderCli {
|
|
|
24
25
|
handler: async ({ run, root }) => {
|
|
25
26
|
const modules: Array<Module> = [];
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
-
const pkgData = JSON.parse(
|
|
28
|
+
const pkgBuffer = await this.fs.readFile("package.json");
|
|
29
|
+
const pkgData = JSON.parse(pkgBuffer.toString("utf-8"));
|
|
29
30
|
const packageName = pkgData.name as string;
|
|
30
31
|
|
|
31
32
|
await run("analyze modules", async () => {
|
|
32
33
|
modules.push(
|
|
33
|
-
...(await analyzeModules(join(root, this.src), packageName)),
|
|
34
|
+
...(await analyzeModules(this.fs.join(root, this.src), packageName)),
|
|
34
35
|
);
|
|
35
36
|
});
|
|
36
37
|
|
|
@@ -56,6 +57,10 @@ export class AlephaPackageBuilderCli {
|
|
|
56
57
|
pkgData.exports[path].browser = `./src/${item.name}/index.browser.ts`;
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
if (item.bun) {
|
|
61
|
+
pkgData.exports[path].bun = `./src/${item.name}/index.bun.ts`;
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
pkgData.exports[path].import = `./src/${item.name}/index.ts`;
|
|
60
65
|
pkgData.exports[path].default = `./src/${item.name}/index.ts`;
|
|
61
66
|
}
|
|
@@ -72,21 +77,20 @@ export class AlephaPackageBuilderCli {
|
|
|
72
77
|
|
|
73
78
|
await this.fs.writeFile("package.json", JSON.stringify(pkgData, null, 2));
|
|
74
79
|
|
|
75
|
-
const tmpDir = join(root, "node_modules/.alepha");
|
|
80
|
+
const tmpDir = this.fs.join(root, "node_modules/.alepha");
|
|
76
81
|
await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});
|
|
77
82
|
|
|
78
83
|
await this.fs.writeFile(
|
|
79
|
-
join(tmpDir, "module-dependencies.json"),
|
|
84
|
+
this.fs.join(tmpDir, "module-dependencies.json"),
|
|
80
85
|
JSON.stringify(modules, null, 2),
|
|
81
86
|
);
|
|
82
87
|
|
|
83
|
-
const
|
|
84
|
-
join(root, "../../tsconfig.json"),
|
|
85
|
-
"utf-8",
|
|
88
|
+
const tsconfigBuffer = await this.fs.readFile(
|
|
89
|
+
this.fs.join(root, "../../tsconfig.json"),
|
|
86
90
|
);
|
|
87
91
|
|
|
88
92
|
const external: string[] = Object.keys(
|
|
89
|
-
JSON.parse(
|
|
93
|
+
JSON.parse(tsconfigBuffer.toString("utf-8")).compilerOptions.paths,
|
|
90
94
|
);
|
|
91
95
|
|
|
92
96
|
external.push("bun");
|
|
@@ -96,46 +100,61 @@ export class AlephaPackageBuilderCli {
|
|
|
96
100
|
|
|
97
101
|
const build = async (item: Module) => {
|
|
98
102
|
const entries: InlineConfig[] = [];
|
|
99
|
-
const src = join(root, this.src, item.name);
|
|
100
|
-
const dest = join(root, this.dist, item.name);
|
|
103
|
+
const src = this.fs.join(root, this.src, item.name);
|
|
104
|
+
const dest = this.fs.join(root, this.dist, item.name);
|
|
101
105
|
|
|
102
106
|
entries.push({
|
|
103
|
-
entry: join(src, "index.ts"),
|
|
107
|
+
entry: this.fs.join(src, "index.ts"),
|
|
104
108
|
outDir: dest,
|
|
105
109
|
format: ["esm"],
|
|
106
110
|
sourcemap: true,
|
|
107
111
|
fixedExtension: false,
|
|
108
112
|
platform: "node", // TODO: node must be enabled only if index.node.ts exists
|
|
113
|
+
inlineOnly: false,
|
|
109
114
|
external,
|
|
110
115
|
dts: {
|
|
111
116
|
sourcemap: true,
|
|
112
|
-
resolve: false,
|
|
113
117
|
},
|
|
114
118
|
});
|
|
115
119
|
|
|
116
120
|
if (item.native) {
|
|
117
121
|
entries.push({
|
|
118
|
-
entry: join(src, "index.native.ts"),
|
|
122
|
+
entry: this.fs.join(src, "index.native.ts"),
|
|
119
123
|
outDir: dest,
|
|
120
124
|
platform: "neutral",
|
|
121
125
|
sourcemap: true,
|
|
122
126
|
dts: false,
|
|
127
|
+
inlineOnly: false,
|
|
123
128
|
external,
|
|
124
129
|
});
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
if (item.browser) {
|
|
128
133
|
entries.push({
|
|
129
|
-
entry: join(src, "index.browser.ts"),
|
|
134
|
+
entry: this.fs.join(src, "index.browser.ts"),
|
|
130
135
|
outDir: dest,
|
|
131
136
|
platform: "browser",
|
|
132
137
|
sourcemap: true,
|
|
133
138
|
dts: false,
|
|
139
|
+
inlineOnly: false,
|
|
134
140
|
external,
|
|
135
141
|
});
|
|
136
142
|
}
|
|
137
143
|
|
|
138
|
-
|
|
144
|
+
if (item.bun) {
|
|
145
|
+
entries.push({
|
|
146
|
+
entry: this.fs.join(src, "index.bun.ts"),
|
|
147
|
+
outDir: dest,
|
|
148
|
+
platform: "node",
|
|
149
|
+
sourcemap: true,
|
|
150
|
+
fixedExtension: false,
|
|
151
|
+
dts: false,
|
|
152
|
+
inlineOnly: false,
|
|
153
|
+
external,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const config = this.fs.join(
|
|
139
158
|
tmpDir,
|
|
140
159
|
`tsdown-${item.name.replace("/", "-")}.config.js`,
|
|
141
160
|
);
|
|
@@ -143,8 +162,10 @@ export class AlephaPackageBuilderCli {
|
|
|
143
162
|
config,
|
|
144
163
|
`export default ${JSON.stringify(entries, null, 2)};`,
|
|
145
164
|
);
|
|
165
|
+
|
|
166
|
+
// /!\ Warning /!\
|
|
167
|
+
// avoid to call tsdown programmatically, when we spawn 8 processes at once it 'JavaScript heap out of memory' :---)
|
|
146
168
|
await run(`npx tsdown -c=${config}`);
|
|
147
|
-
//await this.fs.rm(config);
|
|
148
169
|
};
|
|
149
170
|
|
|
150
171
|
const concurrency = Math.ceil(os.cpus().length / 2);
|
|
@@ -168,6 +189,8 @@ export class AlephaPackageBuilderCli {
|
|
|
168
189
|
});
|
|
169
190
|
}
|
|
170
191
|
|
|
192
|
+
export default AlephaPackageBuilderCli;
|
|
193
|
+
|
|
171
194
|
async function getAllFiles(dir: string): Promise<string[]> {
|
|
172
195
|
const files: string[] = [];
|
|
173
196
|
|
|
@@ -261,7 +284,9 @@ function detectCircularDependencies(modules: Module[]): void {
|
|
|
261
284
|
for (const module of modules) {
|
|
262
285
|
const cycle = hasCycle(module.name);
|
|
263
286
|
if (cycle) {
|
|
264
|
-
throw new
|
|
287
|
+
throw new AlephaError(
|
|
288
|
+
`Circular dependency detected: ${cycle.join(" -> ")}`,
|
|
289
|
+
);
|
|
265
290
|
}
|
|
266
291
|
}
|
|
267
292
|
}
|
|
@@ -287,13 +312,14 @@ export async function analyzeModules(
|
|
|
287
312
|
// This is a module
|
|
288
313
|
const dependencies = new Set<string>();
|
|
289
314
|
|
|
290
|
-
// Check for browser/node entry points
|
|
315
|
+
// Check for browser/node/bun entry points
|
|
291
316
|
const hasBrowser = await fileExists(
|
|
292
317
|
join(modulePath, "index.browser.ts"),
|
|
293
318
|
);
|
|
294
319
|
const hasNative = await fileExists(
|
|
295
320
|
join(modulePath, "index.native.ts"),
|
|
296
321
|
);
|
|
322
|
+
const hasBun = await fileExists(join(modulePath, "index.bun.ts"));
|
|
297
323
|
const hasNode = await fileExists(join(modulePath, "index.node.ts"));
|
|
298
324
|
|
|
299
325
|
// Get all .ts/.tsx files in this module
|
|
@@ -328,6 +354,7 @@ export async function analyzeModules(
|
|
|
328
354
|
|
|
329
355
|
if (hasNative) module.native = true;
|
|
330
356
|
if (hasBrowser) module.browser = true;
|
|
357
|
+
if (hasBun) module.bun = true;
|
|
331
358
|
if (hasNode) module.node = true;
|
|
332
359
|
|
|
333
360
|
modules.push(module);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const apiHelloControllerTs = () =>
|
|
2
|
+
`
|
|
3
|
+
import { t } from "alepha";
|
|
4
|
+
import { $action } from "alepha/server";
|
|
5
|
+
|
|
6
|
+
export class HelloController {
|
|
7
|
+
hello = $action({
|
|
8
|
+
path: "/hello",
|
|
9
|
+
schema: {
|
|
10
|
+
response: t.object({
|
|
11
|
+
message: t.string(),
|
|
12
|
+
}),
|
|
13
|
+
},
|
|
14
|
+
handler: () => ({
|
|
15
|
+
message: "Hello, Alepha!",
|
|
16
|
+
}),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
`.trim();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ApiIndexTsOptions {
|
|
2
|
+
appName?: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export const apiIndexTs = (options: ApiIndexTsOptions = {}) => {
|
|
6
|
+
const { appName = "app" } = options;
|
|
7
|
+
return `
|
|
8
|
+
import { $module } from "alepha";
|
|
9
|
+
import { HelloController } from "./controllers/HelloController.ts";
|
|
10
|
+
|
|
11
|
+
export const ApiModule = $module({
|
|
12
|
+
name: "${appName}.api",
|
|
13
|
+
services: [HelloController],
|
|
14
|
+
});
|
|
15
|
+
`.trim();
|
|
16
|
+
};
|