alepha 0.15.0 → 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 +43 -98
- package/dist/api/audits/index.d.ts +240 -240
- 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 +185 -185
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +2 -2
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +245 -245
- 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 +74 -74
- 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 +221 -221
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +1632 -1631
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +26 -34
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +132 -132
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.d.ts +122 -122
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/bucket/index.d.ts +163 -163
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/cache/core/index.d.ts +46 -46
- 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 +5933 -201
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +609 -169
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +296 -296
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +19 -19
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +268 -79
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +768 -694
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +268 -79
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +268 -79
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +44 -44
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/email/index.d.ts +25 -25
- package/dist/email/index.d.ts.map +1 -1
- package/dist/fake/index.d.ts +5409 -5409
- 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 +435 -435
- package/dist/file/index.d.ts.map +1 -1
- package/dist/lock/core/index.d.ts +208 -208
- 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 +24 -24
- 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 +216 -198
- 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/index.browser.js +9 -9
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +83 -76
- package/dist/orm/index.bun.js.map +1 -1
- package/dist/orm/index.d.ts +961 -960
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +88 -81
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +244 -244
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/redis/index.d.ts +105 -105
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/retry/index.d.ts +69 -69
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/router/index.d.ts +6 -6
- package/dist/router/index.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +108 -26
- 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.d.ts +532 -209
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1422 -11
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1296 -271
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1249 -18
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +56 -56
- package/dist/server/cache/index.d.ts.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/cookies/index.d.ts +6 -6
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/core/index.d.ts +196 -186
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +43 -27
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +11 -11
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/helmet/index.d.ts +2 -2
- 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 +83 -83
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +13 -5
- 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 +6 -6
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/proxy/index.d.ts +102 -102
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.d.ts +16 -16
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/static/index.d.ts +44 -44
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/swagger/index.d.ts +47 -47
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/sms/index.d.ts +11 -11
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +3 -3
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +71 -71
- 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 +318 -318
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/redis/index.d.ts +6 -6
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/vite/index.d.ts +2324 -1719
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +123 -475
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +3 -3
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +275 -275
- 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 +9 -9
- package/src/api/users/services/SessionService.ts +0 -10
- package/src/cli/apps/AlephaCli.ts +2 -2
- package/src/cli/apps/AlephaPackageBuilderCli.ts +9 -1
- package/src/cli/assets/apiHelloControllerTs.ts +2 -1
- package/src/cli/assets/biomeJson.ts +2 -1
- package/src/cli/assets/claudeMd.ts +9 -4
- package/src/cli/assets/dummySpecTs.ts +2 -1
- package/src/cli/assets/editorconfig.ts +2 -1
- package/src/cli/assets/mainBrowserTs.ts +2 -1
- package/src/cli/assets/mainCss.ts +24 -0
- package/src/cli/assets/tsconfigJson.ts +2 -1
- package/src/cli/assets/webAppRouterTs.ts +2 -1
- package/src/cli/assets/webHelloComponentTsx.ts +6 -2
- 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 +63 -47
- package/src/cli/commands/dev.ts +16 -33
- package/src/cli/commands/gen/env.ts +1 -1
- package/src/cli/commands/init.ts +17 -8
- package/src/cli/commands/lint.ts +1 -1
- 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 +33 -2
- package/src/cli/services/PackageManagerUtils.ts +13 -6
- package/src/cli/services/ProjectScaffolder.ts +72 -49
- package/src/core/Alepha.ts +2 -8
- package/src/core/primitives/$module.ts +12 -0
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +257 -0
- package/src/core/providers/KeylessJsonSchemaCodec.ts +396 -14
- package/src/core/providers/SchemaValidator.spec.ts +236 -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/providers/DrizzleKitProvider.ts +3 -5
- package/src/orm/services/Repository.ts +11 -0
- 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 +71 -22
- package/src/server/core/providers/ServerLoggerProvider.ts +2 -2
- package/src/server/core/providers/ServerProvider.ts +9 -12
- package/src/server/links/atoms/apiLinksAtom.ts +7 -0
- package/src/server/links/index.browser.ts +2 -0
- package/src/server/links/index.ts +2 -0
- package/src/vite/index.ts +3 -2
- package/src/vite/tasks/buildClient.ts +0 -1
- package/src/vite/tasks/buildServer.ts +68 -21
- package/src/vite/tasks/copyAssets.ts +5 -4
- 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/src/cli/assets/indexHtml.ts +0 -15
- package/src/cli/commands/format.ts +0 -23
- package/src/vite/helpers/boot.ts +0 -117
- package/src/vite/plugins/viteAlephaDev.ts +0 -177
- package/src/vite/tasks/devServer.ts +0 -71
- package/src/vite/tasks/runAlepha.ts +0 -270
- /package/dist/orm/{chunk-DtkW-qnP.js → chunk-DH6iiROE.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile, rm, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { AlephaError } from "alepha";
|
|
3
|
+
import { type Alepha, AlephaError } from "alepha";
|
|
4
4
|
import type * as vite from "vite";
|
|
5
5
|
import type { UserConfig } from "vite";
|
|
6
6
|
import { analyzer as viteAnalyzer } from "vite-bundle-analyzer";
|
|
@@ -27,11 +27,6 @@ export interface BuildServerOptions {
|
|
|
27
27
|
*/
|
|
28
28
|
clientDir?: string;
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
* Override Vite config options.
|
|
32
|
-
*/
|
|
33
|
-
config?: UserConfig;
|
|
34
|
-
|
|
35
30
|
/**
|
|
36
31
|
* If true, generate build stats report.
|
|
37
32
|
*/
|
|
@@ -48,6 +43,11 @@ export interface BuildServerOptions {
|
|
|
48
43
|
* Add more entry point conditions for SSR module resolution (e.g., "bun").
|
|
49
44
|
*/
|
|
50
45
|
conditions?: string[];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Alepha instance to set SSR manifest for pre-rendering.
|
|
49
|
+
*/
|
|
50
|
+
alepha: Alepha;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export interface BuildServerResult {
|
|
@@ -55,6 +55,15 @@ export interface BuildServerResult {
|
|
|
55
55
|
* The filename of the built server entry (e.g., "abc123.js").
|
|
56
56
|
*/
|
|
57
57
|
entryFile: string;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* SSR manifest data for module preloading.
|
|
61
|
+
* Can be used to set in alepha store for pre-rendering.
|
|
62
|
+
*/
|
|
63
|
+
manifest?: {
|
|
64
|
+
client?: Record<string, any>;
|
|
65
|
+
preload?: Record<string, string>;
|
|
66
|
+
};
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
/**
|
|
@@ -67,7 +76,7 @@ export interface BuildServerResult {
|
|
|
67
76
|
export async function buildServer(
|
|
68
77
|
opts: BuildServerOptions,
|
|
69
78
|
): Promise<BuildServerResult> {
|
|
70
|
-
const { build: viteBuild,
|
|
79
|
+
const { build: viteBuild, resolveConfig } = await importVite();
|
|
71
80
|
const plugins: any[] = [];
|
|
72
81
|
|
|
73
82
|
const viteReact = await importViteReact();
|
|
@@ -93,6 +102,7 @@ export async function buildServer(
|
|
|
93
102
|
conditions.unshift(...opts.conditions);
|
|
94
103
|
}
|
|
95
104
|
|
|
105
|
+
// note: we still can override this config via config file (vite.config.ts)
|
|
96
106
|
const viteBuildServerConfig: UserConfig = {
|
|
97
107
|
mode: "production",
|
|
98
108
|
logLevel: opts.silent ? "silent" : undefined,
|
|
@@ -121,24 +131,32 @@ export async function buildServer(
|
|
|
121
131
|
},
|
|
122
132
|
},
|
|
123
133
|
esbuild: { legalComments: "none", keepNames: true },
|
|
124
|
-
customLogger: logger,
|
|
134
|
+
customLogger: logger, // mock logger to avoid noisy output
|
|
125
135
|
plugins,
|
|
126
136
|
};
|
|
127
137
|
|
|
138
|
+
// create inline config by merging alepha built-in + extended config
|
|
139
|
+
|
|
128
140
|
let result: vite.Rollup.RollupOutput | vite.Rollup.RollupOutput[];
|
|
129
141
|
try {
|
|
130
|
-
result = (await viteBuild(
|
|
131
|
-
|
|
132
|
-
|
|
142
|
+
result = (await viteBuild(viteBuildServerConfig)) as
|
|
143
|
+
| vite.Rollup.RollupOutput
|
|
144
|
+
| vite.Rollup.RollupOutput[];
|
|
133
145
|
} catch (error) {
|
|
134
|
-
//
|
|
146
|
+
// flush buffered logs on failure so user can see what happened
|
|
135
147
|
logger?.flush();
|
|
136
148
|
throw error;
|
|
137
149
|
}
|
|
138
150
|
|
|
139
|
-
//
|
|
140
|
-
const resolvedConfig = (
|
|
141
|
-
|
|
151
|
+
// resolve final config to read externals
|
|
152
|
+
const resolvedConfig = await resolveConfig(viteBuildServerConfig, "build");
|
|
153
|
+
|
|
154
|
+
// extract resolved config to get externals
|
|
155
|
+
const externals: string[] = [];
|
|
156
|
+
|
|
157
|
+
if (Array.isArray(resolvedConfig?.ssr?.external)) {
|
|
158
|
+
externals.push(...resolvedConfig.ssr.external);
|
|
159
|
+
}
|
|
142
160
|
|
|
143
161
|
// Generate package.json with externals
|
|
144
162
|
await generateExternals({
|
|
@@ -161,21 +179,29 @@ export async function buildServer(
|
|
|
161
179
|
// Embed SSR manifests if client was built
|
|
162
180
|
// This bundles all manifest data into index.js for serverless deployments
|
|
163
181
|
let manifest = "";
|
|
182
|
+
let manifestData:
|
|
183
|
+
| { client?: Record<string, any>; preload?: Record<string, string> }
|
|
184
|
+
| undefined;
|
|
185
|
+
|
|
164
186
|
if (opts.clientDir) {
|
|
165
187
|
const viteDir = `${opts.distDir}/${opts.clientDir}/.vite`;
|
|
166
|
-
const ssrManifest = await loadJsonFile(`${viteDir}/ssr-manifest.json`);
|
|
167
188
|
const clientManifest = await loadJsonFile(`${viteDir}/manifest.json`);
|
|
168
189
|
const preloadManifest = await loadJsonFile(
|
|
169
190
|
`${viteDir}/preload-manifest.json`,
|
|
170
191
|
);
|
|
171
192
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
193
|
+
// Strip unused fields from client manifest to reduce bundle size
|
|
194
|
+
const strippedClientManifest = stripClientManifest(clientManifest);
|
|
195
|
+
|
|
196
|
+
manifestData = {
|
|
197
|
+
client: strippedClientManifest,
|
|
175
198
|
preload: preloadManifest,
|
|
176
199
|
};
|
|
177
200
|
|
|
178
|
-
manifest = `__alepha.set("alepha.react.ssr.manifest", ${JSON.stringify(
|
|
201
|
+
manifest = `__alepha.set("alepha.react.ssr.manifest", ${JSON.stringify(manifestData)});\n`;
|
|
202
|
+
|
|
203
|
+
// Set manifest in alepha store for pre-rendering
|
|
204
|
+
opts.alepha.store.set("alepha.react.ssr.manifest" as any, manifestData);
|
|
179
205
|
|
|
180
206
|
// Remove .vite directory - no longer needed at runtime
|
|
181
207
|
await rm(viteDir, { recursive: true, force: true });
|
|
@@ -191,7 +217,7 @@ export async function buildServer(
|
|
|
191
217
|
`${warning}\n${template}${manifest}import './server/${entryFile}';\n`.trim(),
|
|
192
218
|
);
|
|
193
219
|
|
|
194
|
-
return { entryFile };
|
|
220
|
+
return { entryFile, manifest: manifestData };
|
|
195
221
|
}
|
|
196
222
|
|
|
197
223
|
/**
|
|
@@ -206,6 +232,27 @@ async function loadJsonFile(path: string): Promise<any> {
|
|
|
206
232
|
}
|
|
207
233
|
}
|
|
208
234
|
|
|
235
|
+
/**
|
|
236
|
+
* Strip unused fields from client manifest to reduce bundle size.
|
|
237
|
+
* Only keeps: file, isEntry, imports, css
|
|
238
|
+
*/
|
|
239
|
+
function stripClientManifest(
|
|
240
|
+
manifest: Record<string, any> | undefined,
|
|
241
|
+
): Record<string, any> | undefined {
|
|
242
|
+
if (!manifest) return undefined;
|
|
243
|
+
|
|
244
|
+
const stripped: Record<string, any> = {};
|
|
245
|
+
for (const [key, entry] of Object.entries(manifest)) {
|
|
246
|
+
stripped[key] = {
|
|
247
|
+
file: entry.file,
|
|
248
|
+
...(entry.isEntry && { isEntry: entry.isEntry }),
|
|
249
|
+
...(entry.imports?.length && { imports: entry.imports }),
|
|
250
|
+
...(entry.css?.length && { css: entry.css }),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
return stripped;
|
|
254
|
+
}
|
|
255
|
+
|
|
209
256
|
/**
|
|
210
257
|
* Extract entry filename from Vite build result.
|
|
211
258
|
*/
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { cp, mkdir } from "node:fs/promises";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import type { Alepha } from "alepha";
|
|
5
5
|
|
|
6
6
|
export interface CopyAssetsOptions {
|
|
7
|
+
alepha: Alepha;
|
|
7
8
|
/**
|
|
8
9
|
* Entry point for the built Alepha application.
|
|
9
10
|
*/
|
|
@@ -17,7 +18,7 @@ export interface CopyAssetsOptions {
|
|
|
17
18
|
/**
|
|
18
19
|
* @default process.cwd()
|
|
19
20
|
*/
|
|
20
|
-
root
|
|
21
|
+
root: string;
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Add Runner for logging (@see Alepha CLI)
|
|
@@ -38,8 +39,8 @@ export interface CopyAssetsOptions {
|
|
|
38
39
|
* Used by modules like AlephaServerSwagger to distribute UI files.
|
|
39
40
|
*/
|
|
40
41
|
export async function copyAssets(opts: CopyAssetsOptions): Promise<void> {
|
|
41
|
-
const root = opts.root
|
|
42
|
-
const alepha =
|
|
42
|
+
const root = opts.root;
|
|
43
|
+
const alepha = opts.alepha;
|
|
43
44
|
const assets = alepha.store.get("alepha.build.assets");
|
|
44
45
|
|
|
45
46
|
if (!assets || assets.length === 0) {
|
|
@@ -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,15 +0,0 @@
|
|
|
1
|
-
export const indexHtml = (
|
|
2
|
-
browserEntry: string,
|
|
3
|
-
) => `
|
|
4
|
-
<!DOCTYPE html>
|
|
5
|
-
<html lang="en">
|
|
6
|
-
<head>
|
|
7
|
-
<meta charset="UTF-8">
|
|
8
|
-
<title>App</title>
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
11
|
-
<div id="root"></div>
|
|
12
|
-
<script type="module" src="${browserEntry}"></script>
|
|
13
|
-
</body>
|
|
14
|
-
</html>
|
|
15
|
-
`.trim();
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { $inject } from "alepha";
|
|
2
|
-
import { $command } from "alepha/command";
|
|
3
|
-
import { AlephaCliUtils } from "../services/AlephaCliUtils.ts";
|
|
4
|
-
import { PackageManagerUtils } from "../services/PackageManagerUtils.ts";
|
|
5
|
-
import { ProjectScaffolder } from "../services/ProjectScaffolder.ts";
|
|
6
|
-
|
|
7
|
-
export class FormatCommand {
|
|
8
|
-
protected readonly utils = $inject(AlephaCliUtils);
|
|
9
|
-
protected readonly pm = $inject(PackageManagerUtils);
|
|
10
|
-
protected readonly scaffolder = $inject(ProjectScaffolder);
|
|
11
|
-
|
|
12
|
-
public readonly format = $command({
|
|
13
|
-
name: "format",
|
|
14
|
-
description: "Format the codebase using Biome",
|
|
15
|
-
handler: async ({ root }) => {
|
|
16
|
-
await this.scaffolder.ensureConfig(root, { biomeJson: true });
|
|
17
|
-
await this.pm.ensureDependency(root, "@biomejs/biome", {
|
|
18
|
-
exec: (cmd, opts) => this.utils.exec(cmd, opts),
|
|
19
|
-
});
|
|
20
|
-
await this.utils.exec("biome format --fix");
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
}
|
package/src/vite/helpers/boot.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { access, readdir, readFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { AlephaError } from "alepha";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Remember:
|
|
7
|
-
* At first, functions was inside alepha/vite package, but it's now used in alepha too.
|
|
8
|
-
* For avoiding cli -> vite, all code moved here.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Server entry files in priority order.
|
|
13
|
-
* main.server.ts is preferred over main.ts for consistency.
|
|
14
|
-
*/
|
|
15
|
-
const SERVER_ENTRIES = [
|
|
16
|
-
"main.server.ts",
|
|
17
|
-
"main.server.tsx",
|
|
18
|
-
"main.ts",
|
|
19
|
-
"main.tsx",
|
|
20
|
-
] as const;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Find browser/client entry file path.
|
|
24
|
-
*/
|
|
25
|
-
const getClientEntry = async (
|
|
26
|
-
root = process.cwd(),
|
|
27
|
-
): Promise<string | undefined> => {
|
|
28
|
-
const indexPath = join(root, "index.html");
|
|
29
|
-
try {
|
|
30
|
-
const html = await readFile(indexPath, "utf8");
|
|
31
|
-
return extractFirstModuleScriptSrc(html).replace(/\\/g, "/");
|
|
32
|
-
} catch {
|
|
33
|
-
return undefined;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Find server entry file path.
|
|
39
|
-
*
|
|
40
|
-
* Optimized to use a single readdir() call instead of multiple access() calls.
|
|
41
|
-
*/
|
|
42
|
-
const getServerEntry = async (
|
|
43
|
-
root = process.cwd(),
|
|
44
|
-
explicitEntry?: string,
|
|
45
|
-
): Promise<string> => {
|
|
46
|
-
if (explicitEntry) {
|
|
47
|
-
const explicitPath = join(root, explicitEntry);
|
|
48
|
-
try {
|
|
49
|
-
await access(explicitPath);
|
|
50
|
-
return explicitPath;
|
|
51
|
-
} catch {
|
|
52
|
-
throw new AlephaError(
|
|
53
|
-
`Explicit server entry file "${explicitEntry}" not found.`,
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Single IO: read src/ directory listing
|
|
59
|
-
const srcDir = join(root, "src");
|
|
60
|
-
try {
|
|
61
|
-
const files = new Set(await readdir(srcDir));
|
|
62
|
-
|
|
63
|
-
// Find first matching entry in priority order
|
|
64
|
-
for (const entry of SERVER_ENTRIES) {
|
|
65
|
-
if (files.has(entry)) {
|
|
66
|
-
return join(srcDir, entry).replace(/\\/g, "/");
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
} catch {
|
|
70
|
-
// src/ directory doesn't exist, fall through to client entry
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Fallback: try client entry from index.html
|
|
74
|
-
const clientEntry = await getClientEntry(root);
|
|
75
|
-
if (clientEntry) {
|
|
76
|
-
return clientEntry;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const fullPaths = SERVER_ENTRIES.map((e) => `src/${e}`);
|
|
80
|
-
throw new AlephaError(
|
|
81
|
-
`Could not find a server entry file. Supported entries: ${fullPaths.join(", ")}`,
|
|
82
|
-
);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Extract first module script src from HTML.
|
|
87
|
-
*/
|
|
88
|
-
function extractFirstModuleScriptSrc(html: string): string {
|
|
89
|
-
const scriptRegex = /<script\b[^>]*>[\s\S]*?<\/script>/gi;
|
|
90
|
-
let match: RegExpExecArray | null = scriptRegex.exec(html);
|
|
91
|
-
|
|
92
|
-
while (match) {
|
|
93
|
-
const tag = match[0];
|
|
94
|
-
|
|
95
|
-
// Check for type="module"
|
|
96
|
-
if (/type=["']module["']/i.test(tag)) {
|
|
97
|
-
// Extract the src value
|
|
98
|
-
const srcMatch = tag.match(/\bsrc=["']([^"']+)["']/i);
|
|
99
|
-
const entry = srcMatch?.[1];
|
|
100
|
-
if (entry) {
|
|
101
|
-
if (entry.startsWith("/")) {
|
|
102
|
-
return entry.substring(1); // Remove leading slash
|
|
103
|
-
}
|
|
104
|
-
return entry;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
match = scriptRegex.exec(html);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
throw new AlephaError(`No module script found in the provided HTML.`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export const boot = {
|
|
115
|
-
getClientEntry,
|
|
116
|
-
getServerEntry,
|
|
117
|
-
};
|