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
|
@@ -45,6 +45,13 @@ export async function generateCloudflare(
|
|
|
45
45
|
main: "./main.cloudflare.js",
|
|
46
46
|
compatibility_flags: ["nodejs_compat"],
|
|
47
47
|
compatibility_date: "2025-11-17",
|
|
48
|
+
no_bundle: true,
|
|
49
|
+
rules: [
|
|
50
|
+
{
|
|
51
|
+
type: "ESModule",
|
|
52
|
+
globs: ["index.js", "server/*.js"],
|
|
53
|
+
},
|
|
54
|
+
],
|
|
48
55
|
...opts.config,
|
|
49
56
|
};
|
|
50
57
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
1
2
|
import type { Alepha } from "alepha";
|
|
2
|
-
import { importAlepha } from "../helpers/importAlepha.ts";
|
|
3
3
|
|
|
4
4
|
export interface GenerateSitemapOptions {
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Alepha instance to use for generating the sitemap.
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
alepha: Alepha;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Base URL for the sitemap (e.g., "https://example.com").
|
|
@@ -13,52 +13,93 @@ export interface GenerateSitemapOptions {
|
|
|
13
13
|
baseUrl: string;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Output file path for the sitemap. If provided, writes the sitemap to disk.
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
output?: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Add Runner for logging (@see Alepha CLI)
|
|
22
|
+
*/
|
|
23
|
+
run?: (opts: {
|
|
24
|
+
name: string;
|
|
25
|
+
handler: () => Promise<void>;
|
|
26
|
+
}) => Promise<string>;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
/**
|
|
22
30
|
* Generate sitemap.xml from Alepha page primitives.
|
|
23
31
|
*
|
|
24
|
-
*
|
|
25
|
-
* queries all page primitives, and generates a sitemap.xml
|
|
32
|
+
* Queries all page primitives and generates a sitemap.xml
|
|
26
33
|
* containing URLs for all accessible pages.
|
|
27
34
|
*/
|
|
28
35
|
export async function generateSitemap(
|
|
29
36
|
opts: GenerateSitemapOptions,
|
|
30
37
|
): Promise<string> {
|
|
31
|
-
const
|
|
38
|
+
const pages = getSitemapPages(opts.alepha);
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
// Nothing to generate
|
|
41
|
+
if (pages.length === 0) {
|
|
42
|
+
return "";
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
let result = "";
|
|
46
|
+
|
|
47
|
+
const fn = async () => {
|
|
48
|
+
result = generateSitemapFromPages(pages, opts.baseUrl);
|
|
49
|
+
if (opts.output) {
|
|
50
|
+
await writeFile(opts.output, result);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (opts.run) {
|
|
55
|
+
await opts.run({
|
|
56
|
+
name: "generate sitemap",
|
|
57
|
+
handler: fn,
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
await fn();
|
|
40
61
|
}
|
|
41
62
|
|
|
42
|
-
return
|
|
63
|
+
return result;
|
|
43
64
|
}
|
|
44
65
|
|
|
45
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Get all pages that should be included in the sitemap.
|
|
68
|
+
*/
|
|
69
|
+
function getSitemapPages(alepha: Alepha): any[] {
|
|
46
70
|
const pages = alepha.primitives("page") as any[];
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
for (const page of pages) {
|
|
71
|
+
return pages.filter((page) => {
|
|
50
72
|
const options = page.options;
|
|
51
|
-
|
|
52
73
|
// Skip pages with children (parent pages that can't be rendered directly)
|
|
53
74
|
if (options.children) {
|
|
54
|
-
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
// Include pages without parameters or static pages with entries
|
|
78
|
+
if (!options.schema?.params) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (
|
|
82
|
+
options.static &&
|
|
83
|
+
typeof options.static === "object" &&
|
|
84
|
+
options.static.entries
|
|
85
|
+
) {
|
|
86
|
+
return true;
|
|
55
87
|
}
|
|
88
|
+
return false;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function generateSitemapFromPages(pages: any[], baseUrl: string): string {
|
|
93
|
+
const urls: string[] = [];
|
|
94
|
+
const normalizedBaseUrl = baseUrl.replace(/\/$/, "");
|
|
95
|
+
|
|
96
|
+
for (const page of pages) {
|
|
97
|
+
const options = page.options;
|
|
56
98
|
|
|
57
|
-
// Only include static pages or pages without parameters
|
|
58
99
|
if (!options.schema?.params) {
|
|
59
100
|
// Simple page without parameters
|
|
60
101
|
const path = options.path || "";
|
|
61
|
-
const url = `${
|
|
102
|
+
const url = `${normalizedBaseUrl}${path === "" ? "/" : path}`;
|
|
62
103
|
urls.push(url);
|
|
63
104
|
} else if (
|
|
64
105
|
options.static &&
|
|
@@ -71,7 +112,7 @@ function generateSitemapFromAlepha(alepha: Alepha, baseUrl: string): string {
|
|
|
71
112
|
options.path || "",
|
|
72
113
|
entry.params || {},
|
|
73
114
|
);
|
|
74
|
-
const url = `${
|
|
115
|
+
const url = `${normalizedBaseUrl}${path}`;
|
|
75
116
|
urls.push(url);
|
|
76
117
|
}
|
|
77
118
|
}
|
package/src/vite/tasks/index.ts
CHANGED
|
@@ -13,11 +13,9 @@
|
|
|
13
13
|
export * from "./buildClient.ts";
|
|
14
14
|
export * from "./buildServer.ts";
|
|
15
15
|
export * from "./copyAssets.ts";
|
|
16
|
-
export * from "./devServer.ts";
|
|
17
16
|
export * from "./generateCloudflare.ts";
|
|
18
17
|
export * from "./generateDocker.ts";
|
|
19
18
|
export * from "./generateExternals.ts";
|
|
20
19
|
export * from "./generateSitemap.ts";
|
|
21
20
|
export * from "./generateVercel.ts";
|
|
22
21
|
export * from "./prerenderPages.ts";
|
|
23
|
-
export * from "./runAlepha.ts";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
2
|
import type { Alepha } from "alepha";
|
|
3
|
-
import { importAlepha } from "../helpers/importAlepha.ts";
|
|
4
3
|
import {
|
|
5
4
|
compressFile,
|
|
6
5
|
type ViteCompressOptions,
|
|
@@ -8,9 +7,9 @@ import {
|
|
|
8
7
|
|
|
9
8
|
export interface PrerenderPagesOptions {
|
|
10
9
|
/**
|
|
11
|
-
*
|
|
10
|
+
* Alepha instance to use for pre-rendering.
|
|
12
11
|
*/
|
|
13
|
-
|
|
12
|
+
alepha: Alepha;
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Client dist directory for output files.
|
|
@@ -21,6 +20,14 @@ export interface PrerenderPagesOptions {
|
|
|
21
20
|
* Optional compression options.
|
|
22
21
|
*/
|
|
23
22
|
compress?: ViteCompressOptions | boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Add Runner for logging (@see Alepha CLI)
|
|
26
|
+
*/
|
|
27
|
+
run?: (opts: {
|
|
28
|
+
name: string;
|
|
29
|
+
handler: () => Promise<void>;
|
|
30
|
+
}) => Promise<string>;
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
export interface PrerenderPagesResult {
|
|
@@ -33,45 +40,63 @@ export interface PrerenderPagesResult {
|
|
|
33
40
|
/**
|
|
34
41
|
* Pre-render static pages defined in the Alepha application.
|
|
35
42
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* `static.entries` configuration.
|
|
43
|
+
* Queries all page primitives with `static: true` and generates
|
|
44
|
+
* static HTML files for each page. Supports pages with parameterized
|
|
45
|
+
* routes via `static.entries` configuration.
|
|
40
46
|
*/
|
|
41
47
|
export async function prerenderPages(
|
|
42
48
|
opts: PrerenderPagesOptions,
|
|
43
49
|
): Promise<PrerenderPagesResult> {
|
|
44
|
-
const alepha =
|
|
50
|
+
const alepha = opts.alepha;
|
|
51
|
+
const pages = getStaticPages(alepha);
|
|
45
52
|
|
|
46
|
-
|
|
53
|
+
// Nothing to pre-render
|
|
54
|
+
if (pages.length === 0) {
|
|
55
|
+
return { count: 0 };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let result: PrerenderPagesResult = { count: 0 };
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
(alepha
|
|
60
|
+
const fn = async () => {
|
|
61
|
+
// TODO: running configure here is a temporary workaround
|
|
62
|
+
if (!alepha.isConfigured()) {
|
|
63
|
+
await alepha.events.emit("configure", alepha);
|
|
64
|
+
}
|
|
65
|
+
result = await prerenderFromAlepha(pages, opts.dist, opts.compress);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
if (opts.run) {
|
|
69
|
+
await opts.run({
|
|
70
|
+
name: "pre-render pages",
|
|
71
|
+
handler: fn,
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
await fn();
|
|
51
75
|
}
|
|
52
76
|
|
|
53
|
-
return
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get all static pages from the Alepha instance.
|
|
82
|
+
*/
|
|
83
|
+
function getStaticPages(alepha: Alepha): any[] {
|
|
84
|
+
const pages = alepha.primitives("page") as any[];
|
|
85
|
+
return pages.filter((page) => {
|
|
86
|
+
const options = page.options;
|
|
87
|
+
return options.static && !options.children;
|
|
88
|
+
});
|
|
54
89
|
}
|
|
55
90
|
|
|
56
91
|
async function prerenderFromAlepha(
|
|
57
|
-
|
|
92
|
+
pages: any[],
|
|
58
93
|
dist: string,
|
|
59
94
|
compress?: ViteCompressOptions | boolean,
|
|
60
95
|
): Promise<PrerenderPagesResult> {
|
|
61
96
|
let count = 0;
|
|
62
|
-
const pages = alepha.primitives("page") as any[];
|
|
63
97
|
|
|
64
98
|
for (const page of pages) {
|
|
65
99
|
const options = page.options;
|
|
66
|
-
|
|
67
|
-
if (options.children) {
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!options.static) {
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
100
|
const config = typeof options.static === "object" ? options.static : {};
|
|
76
101
|
|
|
77
102
|
if (!options.schema?.params) {
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { $module } from "alepha";
|
|
2
|
-
import { AlephaSecurity } from "alepha/security";
|
|
3
|
-
import { AlephaServer } from "alepha/server";
|
|
4
|
-
|
|
5
|
-
//#region ../../src/server/security/index.browser.ts
|
|
6
|
-
const AlephaServerSecurity = $module({
|
|
7
|
-
name: "alepha.server.security",
|
|
8
|
-
services: [AlephaServer, AlephaSecurity]
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
//#endregion
|
|
12
|
-
export { AlephaServerSecurity };
|
|
13
|
-
//# sourceMappingURL=index.browser.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.browser.js","names":[],"sources":["../../../src/server/security/index.browser.ts"],"sourcesContent":["import { $module } from \"alepha\";\nimport { AlephaSecurity } from \"alepha/security\";\nimport { AlephaServer } from \"alepha/server\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaServerSecurity = $module({\n name: \"alepha.server.security\",\n services: [AlephaServer, AlephaSecurity],\n});\n"],"mappings":";;;;;AAMA,MAAa,uBAAuB,QAAQ;CAC1C,MAAM;CACN,UAAU,CAAC,cAAc,eAAe;CACzC,CAAC"}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import * as alepha5 from "alepha";
|
|
2
|
-
import { Alepha, KIND, Primitive } from "alepha";
|
|
3
|
-
import { JwtProvider, Permission, SecurityProvider, UserAccount, UserAccountToken } from "alepha/security";
|
|
4
|
-
import { FetchOptions, ServerRequest, ServerRouterProvider } from "alepha/server";
|
|
5
|
-
import * as alepha_logger0 from "alepha/logger";
|
|
6
|
-
|
|
7
|
-
//#region ../../src/server/security/providers/ServerBasicAuthProvider.d.ts
|
|
8
|
-
interface BasicAuthOptions {
|
|
9
|
-
username: string;
|
|
10
|
-
password: string;
|
|
11
|
-
}
|
|
12
|
-
interface BasicAuthPrimitiveConfig extends BasicAuthOptions {
|
|
13
|
-
/** Name identifier for this basic auth (default: property key) */
|
|
14
|
-
name?: string;
|
|
15
|
-
/** Path patterns to match (supports wildcards like /devtools/*) */
|
|
16
|
-
paths?: string[];
|
|
17
|
-
}
|
|
18
|
-
declare class ServerBasicAuthProvider {
|
|
19
|
-
protected readonly alepha: Alepha;
|
|
20
|
-
protected readonly log: alepha_logger0.Logger;
|
|
21
|
-
protected readonly routerProvider: ServerRouterProvider;
|
|
22
|
-
protected readonly realm = "Secure Area";
|
|
23
|
-
/**
|
|
24
|
-
* Registered basic auth primitives with their configurations
|
|
25
|
-
*/
|
|
26
|
-
readonly registeredAuths: BasicAuthPrimitiveConfig[];
|
|
27
|
-
/**
|
|
28
|
-
* Register a basic auth configuration (called by primitives)
|
|
29
|
-
*/
|
|
30
|
-
registerAuth(config: BasicAuthPrimitiveConfig): void;
|
|
31
|
-
readonly onStart: alepha5.HookPrimitive<"start">;
|
|
32
|
-
/**
|
|
33
|
-
* Hook into server:onRequest to check basic auth
|
|
34
|
-
*/
|
|
35
|
-
readonly onRequest: alepha5.HookPrimitive<"server:onRequest">;
|
|
36
|
-
/**
|
|
37
|
-
* Hook into action:onRequest to check basic auth for actions
|
|
38
|
-
*/
|
|
39
|
-
readonly onActionRequest: alepha5.HookPrimitive<"action:onRequest">;
|
|
40
|
-
/**
|
|
41
|
-
* Check basic authentication
|
|
42
|
-
*/
|
|
43
|
-
checkAuth(request: ServerRequest, options: BasicAuthOptions): void;
|
|
44
|
-
/**
|
|
45
|
-
* Performs a timing-safe comparison of credentials to prevent timing attacks.
|
|
46
|
-
* Always compares both username and password to avoid leaking which one is wrong.
|
|
47
|
-
*/
|
|
48
|
-
protected timingSafeCredentialCheck(inputUsername: string, inputPassword: string, expectedUsername: string, expectedPassword: string): boolean;
|
|
49
|
-
/**
|
|
50
|
-
* Compares two buffers in constant time, handling different lengths safely.
|
|
51
|
-
* Returns 1 if equal, 0 if not equal.
|
|
52
|
-
*/
|
|
53
|
-
protected safeCompare(input: Buffer, expected: Buffer): number;
|
|
54
|
-
/**
|
|
55
|
-
* Send WWW-Authenticate header
|
|
56
|
-
*/
|
|
57
|
-
protected sendAuthRequired(request: ServerRequest): void;
|
|
58
|
-
}
|
|
59
|
-
declare const isBasicAuth: (value: unknown) => value is {
|
|
60
|
-
basic: BasicAuthOptions;
|
|
61
|
-
};
|
|
62
|
-
//#endregion
|
|
63
|
-
//#region ../../src/server/security/providers/ServerSecurityProvider.d.ts
|
|
64
|
-
declare class ServerSecurityProvider {
|
|
65
|
-
protected readonly log: alepha_logger0.Logger;
|
|
66
|
-
protected readonly securityProvider: SecurityProvider;
|
|
67
|
-
protected readonly jwtProvider: JwtProvider;
|
|
68
|
-
protected readonly alepha: Alepha;
|
|
69
|
-
protected readonly onConfigure: alepha5.HookPrimitive<"configure">;
|
|
70
|
-
protected readonly onActionRequest: alepha5.HookPrimitive<"action:onRequest">;
|
|
71
|
-
protected readonly onRequest: alepha5.HookPrimitive<"server:onRequest">;
|
|
72
|
-
protected check(user: UserAccountToken, secure: ServerRouteSecure): void;
|
|
73
|
-
/**
|
|
74
|
-
* Get the user account token for a local action call.
|
|
75
|
-
* There are three possible sources for the user:
|
|
76
|
-
* - `options.user`: the user passed in the options
|
|
77
|
-
* - `"system"`: the system user from the state (you MUST set state `server.security.system.user`)
|
|
78
|
-
* - `"context"`: the user from the request context (you MUST be in an HTTP request context)
|
|
79
|
-
*
|
|
80
|
-
* Priority order: `options.user` > `"system"` > `"context"`.
|
|
81
|
-
*
|
|
82
|
-
* In testing environment, if no user is provided, a test user is created based on the SecurityProvider's roles.
|
|
83
|
-
*/
|
|
84
|
-
protected createUserFromLocalFunctionContext(options: {
|
|
85
|
-
user?: UserAccountToken | "system" | "context";
|
|
86
|
-
}, permission?: Permission): UserAccountToken;
|
|
87
|
-
protected createTestUser(): UserAccountToken;
|
|
88
|
-
protected readonly onClientRequest: alepha5.HookPrimitive<"client:onRequest">;
|
|
89
|
-
}
|
|
90
|
-
type ServerRouteSecure = {
|
|
91
|
-
realm?: string;
|
|
92
|
-
basic?: BasicAuthOptions;
|
|
93
|
-
};
|
|
94
|
-
//#endregion
|
|
95
|
-
//#region ../../src/server/security/primitives/$basicAuth.d.ts
|
|
96
|
-
/**
|
|
97
|
-
* Declares HTTP Basic Authentication for server routes.
|
|
98
|
-
* This primitive provides methods to protect routes with username/password authentication.
|
|
99
|
-
*/
|
|
100
|
-
declare const $basicAuth: {
|
|
101
|
-
(options: BasicAuthPrimitiveConfig): AbstractBasicAuthPrimitive;
|
|
102
|
-
[KIND]: typeof BasicAuthPrimitive;
|
|
103
|
-
};
|
|
104
|
-
interface AbstractBasicAuthPrimitive {
|
|
105
|
-
readonly name: string;
|
|
106
|
-
readonly options: BasicAuthPrimitiveConfig;
|
|
107
|
-
check(request: ServerRequest, options?: BasicAuthOptions): void;
|
|
108
|
-
}
|
|
109
|
-
declare class BasicAuthPrimitive extends Primitive<BasicAuthPrimitiveConfig> implements AbstractBasicAuthPrimitive {
|
|
110
|
-
protected readonly serverBasicAuthProvider: ServerBasicAuthProvider;
|
|
111
|
-
get name(): string;
|
|
112
|
-
protected onInit(): void;
|
|
113
|
-
/**
|
|
114
|
-
* Checks basic auth for the given request using this primitive's configuration.
|
|
115
|
-
*/
|
|
116
|
-
check(request: ServerRequest, options?: BasicAuthOptions): void;
|
|
117
|
-
}
|
|
118
|
-
//#endregion
|
|
119
|
-
//#region ../../src/server/security/index.d.ts
|
|
120
|
-
declare module "alepha" {
|
|
121
|
-
interface State {
|
|
122
|
-
/**
|
|
123
|
-
* Real (or fake) user account, used for internal actions.
|
|
124
|
-
*
|
|
125
|
-
* If you define this, you assume that all actions are executed by this user by default.
|
|
126
|
-
* > To force a different user, you need to pass it explicitly in the options.
|
|
127
|
-
*/
|
|
128
|
-
"alepha.server.security.system.user"?: UserAccountToken;
|
|
129
|
-
/**
|
|
130
|
-
* The authenticated user account attached to the server request state.
|
|
131
|
-
*
|
|
132
|
-
* @internal
|
|
133
|
-
*/
|
|
134
|
-
"alepha.server.request.user"?: UserAccount;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
declare module "alepha/server" {
|
|
138
|
-
interface ServerRequest<TConfig> {
|
|
139
|
-
user?: UserAccountToken;
|
|
140
|
-
}
|
|
141
|
-
interface ServerActionRequest<TConfig> {
|
|
142
|
-
user: UserAccountToken;
|
|
143
|
-
}
|
|
144
|
-
interface ServerRoute {
|
|
145
|
-
/**
|
|
146
|
-
* If true, the route will be protected by the security provider.
|
|
147
|
-
* All actions are secure by default, but you can disable it for specific actions.
|
|
148
|
-
*/
|
|
149
|
-
secure?: boolean | ServerRouteSecure;
|
|
150
|
-
}
|
|
151
|
-
interface ClientRequestOptions extends FetchOptions {
|
|
152
|
-
/**
|
|
153
|
-
* Forward user from the previous request.
|
|
154
|
-
* If "system", use system user. @see {ServerSecurityProvider.localSystemUser}
|
|
155
|
-
* If "context", use the user from the current context (e.g. request).
|
|
156
|
-
*
|
|
157
|
-
* @default "system" if provided, else "context" if available.
|
|
158
|
-
*/
|
|
159
|
-
user?: UserAccountToken | "system" | "context";
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Plugin for Alepha Server that provides security features. Based on the Alepha Security module.
|
|
164
|
-
*
|
|
165
|
-
* By default, all $action will be guarded by a permission check.
|
|
166
|
-
*
|
|
167
|
-
* @see {@link ServerSecurityProvider}
|
|
168
|
-
* @module alepha.server.security
|
|
169
|
-
*/
|
|
170
|
-
declare const AlephaServerSecurity: alepha5.Service<alepha5.Module>;
|
|
171
|
-
//#endregion
|
|
172
|
-
export { $basicAuth, AbstractBasicAuthPrimitive, AlephaServerSecurity, BasicAuthOptions, BasicAuthPrimitive, BasicAuthPrimitiveConfig, ServerBasicAuthProvider, ServerRouteSecure, ServerSecurityProvider, isBasicAuth };
|
|
173
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/server/security/providers/ServerBasicAuthProvider.ts","../../../src/server/security/providers/ServerSecurityProvider.ts","../../../src/server/security/primitives/$basicAuth.ts","../../../src/server/security/index.ts"],"sourcesContent":[],"mappings":"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"}
|