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
package/dist/cli/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { $atom, $hook, $inject, $module, $use, Alepha, AlephaError, t } from "al
|
|
|
2
2
|
import { FileSystemProvider } from "alepha/file";
|
|
3
3
|
import { $command, CliProvider, EnvUtils } from "alepha/command";
|
|
4
4
|
import { $logger, ConsoleColorProvider } from "alepha/logger";
|
|
5
|
-
import {
|
|
5
|
+
import { buildClient, buildServer, copyAssets, generateCloudflare, generateDocker, generateSitemap, generateVercel, importVite, importViteReact, prerenderPages, viteAlephaSsrPreload } from "alepha/vite";
|
|
6
6
|
import { exec, spawn } from "node:child_process";
|
|
7
7
|
import { readFileSync } from "node:fs";
|
|
8
8
|
import { basename, dirname, join } from "node:path";
|
|
@@ -79,7 +79,7 @@ $atom$1[KIND] = "atom";
|
|
|
79
79
|
* Options can be overridden via vite.config.ts or CLI flags.
|
|
80
80
|
*/
|
|
81
81
|
const buildOptions = $atom$1({
|
|
82
|
-
name: "alepha.build.options",
|
|
82
|
+
name: "alepha.cli.build.options",
|
|
83
83
|
description: "Build configuration options",
|
|
84
84
|
schema: t.object({
|
|
85
85
|
stats: t.optional(t.boolean({ default: false })),
|
|
@@ -102,6 +102,180 @@ const buildOptions = $atom$1({
|
|
|
102
102
|
default: {}
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region ../../src/cli/atoms/appEntryOptions.ts
|
|
107
|
+
const appEntryOptions = $atom({
|
|
108
|
+
name: "alepha.cli.appEntry.options",
|
|
109
|
+
schema: t.object({
|
|
110
|
+
server: t.optional(t.text()),
|
|
111
|
+
browser: t.optional(t.text()),
|
|
112
|
+
style: t.optional(t.text())
|
|
113
|
+
}),
|
|
114
|
+
default: {}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region ../../src/cli/providers/AppEntryProvider.ts
|
|
119
|
+
/**
|
|
120
|
+
* Service for locating entry files in Alepha projects.
|
|
121
|
+
*
|
|
122
|
+
* Originally in alepha/vite, moved to CLI to avoid cli -> vite dependency.
|
|
123
|
+
*/
|
|
124
|
+
var AppEntryProvider = class {
|
|
125
|
+
fs = $inject(FileSystemProvider);
|
|
126
|
+
options = $use(appEntryOptions);
|
|
127
|
+
serverEntries = [
|
|
128
|
+
"main.server.ts",
|
|
129
|
+
"main.server.tsx",
|
|
130
|
+
"main.ts",
|
|
131
|
+
"main.tsx"
|
|
132
|
+
];
|
|
133
|
+
browserEntries = [
|
|
134
|
+
"main.browser.ts",
|
|
135
|
+
"main.browser.tsx",
|
|
136
|
+
"main.ts",
|
|
137
|
+
"main.tsx"
|
|
138
|
+
];
|
|
139
|
+
styleEntries = [
|
|
140
|
+
"main.css",
|
|
141
|
+
"styles.css",
|
|
142
|
+
"style.css"
|
|
143
|
+
];
|
|
144
|
+
/**
|
|
145
|
+
* Get application entry points.
|
|
146
|
+
*
|
|
147
|
+
* Server entry is required, an error is thrown if not found.
|
|
148
|
+
* Browser entry is optional.
|
|
149
|
+
*
|
|
150
|
+
* It will first check for custom entries in options, see appEntryOptions.
|
|
151
|
+
*/
|
|
152
|
+
async getAppEntry(root) {
|
|
153
|
+
const appEntry = {
|
|
154
|
+
root,
|
|
155
|
+
server: ""
|
|
156
|
+
};
|
|
157
|
+
if (this.options.server) {
|
|
158
|
+
if (!await this.fs.exists(this.fs.join(root, this.options.server))) throw new AlephaError(`Custom server entry "${this.options.server}" not found.`);
|
|
159
|
+
appEntry.server = this.options.server;
|
|
160
|
+
}
|
|
161
|
+
if (this.options.browser) {
|
|
162
|
+
if (!await this.fs.exists(this.fs.join(root, this.options.browser))) throw new AlephaError(`Custom browser entry "${this.options.browser}" not found.`);
|
|
163
|
+
appEntry.browser = this.options.browser;
|
|
164
|
+
}
|
|
165
|
+
if (this.options.style) {
|
|
166
|
+
if (!await this.fs.exists(this.fs.join(root, this.options.style))) throw new AlephaError(`Custom style entry "${this.options.style}" not found.`);
|
|
167
|
+
appEntry.style = this.options.style;
|
|
168
|
+
}
|
|
169
|
+
const srcFiles = await this.fs.ls(this.fs.join(root, "src"));
|
|
170
|
+
if (!appEntry.server) {
|
|
171
|
+
for (const entry of this.serverEntries) if (srcFiles.includes(entry)) {
|
|
172
|
+
appEntry.server = this.fs.join("src", entry);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (!appEntry.server) throw new AlephaError("No server entry found. Please, add a main.server.ts file in the src/ directory or configure a custom entry in alepha.config.ts.");
|
|
177
|
+
if (!appEntry.browser) {
|
|
178
|
+
for (const entry of this.browserEntries) if (srcFiles.includes(entry)) {
|
|
179
|
+
appEntry.browser = this.fs.join("src", entry);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (!appEntry.style) {
|
|
184
|
+
for (const entry of this.styleEntries) if (srcFiles.includes(entry)) {
|
|
185
|
+
appEntry.style = this.fs.join("src", entry);
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return appEntry;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
//#endregion
|
|
194
|
+
//#region ../../src/cli/providers/ViteTemplateProvider.ts
|
|
195
|
+
var ViteTemplateProvider = class {
|
|
196
|
+
fs = $inject(FileSystemProvider);
|
|
197
|
+
generateIndexHtml(entry) {
|
|
198
|
+
const style = entry.style;
|
|
199
|
+
const browser = entry.browser ?? entry.server;
|
|
200
|
+
return `
|
|
201
|
+
<!DOCTYPE html>
|
|
202
|
+
<html lang="en">
|
|
203
|
+
<head>
|
|
204
|
+
<meta charset="UTF-8" />
|
|
205
|
+
<title>App</title>
|
|
206
|
+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
207
|
+
${style ? `<link rel="stylesheet" href="/${style}" />` : ""}
|
|
208
|
+
</head>
|
|
209
|
+
<body>
|
|
210
|
+
<div id="root"></div>
|
|
211
|
+
<script type="module" src="/${browser}"><\/script>
|
|
212
|
+
</body>
|
|
213
|
+
</html>
|
|
214
|
+
`.trim();
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region ../../src/cli/providers/ViteBuildProvider.ts
|
|
220
|
+
var ViteBuildProvider = class {
|
|
221
|
+
alepha;
|
|
222
|
+
appEntry;
|
|
223
|
+
viteDevServer;
|
|
224
|
+
templateProvider = $inject(ViteTemplateProvider);
|
|
225
|
+
/**
|
|
226
|
+
* We need to close the Vite dev server after build is done.
|
|
227
|
+
*/
|
|
228
|
+
onReady = $hook({
|
|
229
|
+
on: "ready",
|
|
230
|
+
priority: "last",
|
|
231
|
+
handler: async () => {
|
|
232
|
+
await this.viteDevServer?.close();
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
onStop = $hook({
|
|
236
|
+
on: "stop",
|
|
237
|
+
handler: async () => {
|
|
238
|
+
await this.viteDevServer?.close();
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
async init(opts) {
|
|
242
|
+
const { createServer } = await importVite();
|
|
243
|
+
process.env.ALEPHA_CLI_IMPORT = "true";
|
|
244
|
+
process.env.NODE_ENV = "production";
|
|
245
|
+
process.env.LOG_LEVEL ??= "warn";
|
|
246
|
+
/**
|
|
247
|
+
* 01/26 Vite 7
|
|
248
|
+
* "runnerImport" doesn't work as expected here. (e.g. build docs fail)
|
|
249
|
+
* -> We still use devServer and ssrLoadModule for now.
|
|
250
|
+
* -> This is clearly a bad stuff, we need to find better way.
|
|
251
|
+
*/
|
|
252
|
+
this.viteDevServer = await createServer({
|
|
253
|
+
server: { middlewareMode: true },
|
|
254
|
+
appType: "custom",
|
|
255
|
+
logLevel: "silent"
|
|
256
|
+
});
|
|
257
|
+
await this.viteDevServer.ssrLoadModule(opts.entry.server);
|
|
258
|
+
const alepha = globalThis.__alepha;
|
|
259
|
+
if (!alepha) throw new AlephaError("Alepha instance not found after loading entry module");
|
|
260
|
+
this.alepha = alepha;
|
|
261
|
+
this.appEntry = opts.entry;
|
|
262
|
+
return alepha;
|
|
263
|
+
}
|
|
264
|
+
hasClient() {
|
|
265
|
+
if (!this.alepha) throw new AlephaError("ViteBuildProvider not initialized");
|
|
266
|
+
try {
|
|
267
|
+
this.alepha.inject("ReactServerProvider");
|
|
268
|
+
return true;
|
|
269
|
+
} catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
generateIndexHtml() {
|
|
274
|
+
if (!this.appEntry) throw new AlephaError("ViteBuildProvider not initialized");
|
|
275
|
+
return this.templateProvider.generateIndexHtml(this.appEntry);
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
|
|
105
279
|
//#endregion
|
|
106
280
|
//#region ../../src/cli/services/AlephaCliUtils.ts
|
|
107
281
|
/**
|
|
@@ -117,14 +291,15 @@ var AlephaCliUtils = class {
|
|
|
117
291
|
log = $logger();
|
|
118
292
|
fs = $inject(FileSystemProvider);
|
|
119
293
|
envUtils = $inject(EnvUtils);
|
|
294
|
+
boot = $inject(AppEntryProvider);
|
|
120
295
|
/**
|
|
121
296
|
* Execute a command with inherited stdio.
|
|
122
297
|
*/
|
|
123
298
|
async exec(command, options = {}) {
|
|
124
299
|
const root = options.root ?? process.cwd();
|
|
125
300
|
this.log.debug(`Executing command: ${command}`, { cwd: root });
|
|
126
|
-
const runExec = async (app
|
|
127
|
-
const prog = spawn(app
|
|
301
|
+
const runExec = async (app, args) => {
|
|
302
|
+
const prog = spawn(app, args, {
|
|
128
303
|
stdio: "inherit",
|
|
129
304
|
cwd: root,
|
|
130
305
|
env: {
|
|
@@ -137,14 +312,22 @@ var AlephaCliUtils = class {
|
|
|
137
312
|
}));
|
|
138
313
|
};
|
|
139
314
|
if (options.global) {
|
|
140
|
-
const [app
|
|
141
|
-
await runExec(app
|
|
315
|
+
const [app, ...args] = command.split(" ");
|
|
316
|
+
await runExec(app, args);
|
|
142
317
|
return;
|
|
143
318
|
}
|
|
144
319
|
const suffix = process.platform === "win32" ? ".cmd" : "";
|
|
145
320
|
const [app, ...args] = command.split(" ");
|
|
146
321
|
let execPath = await this.checkFileExists(root, `node_modules/.bin/${app}${suffix}`);
|
|
147
322
|
if (!execPath) execPath = await this.checkFileExists(root, `node_modules/alepha/node_modules/.bin/${app}${suffix}`);
|
|
323
|
+
if (!execPath) {
|
|
324
|
+
let parentDir = this.fs.join(root, "..");
|
|
325
|
+
for (let i = 0; i < 3; i++) {
|
|
326
|
+
execPath = await this.checkFileExists(parentDir, `node_modules/.bin/${app}${suffix}`);
|
|
327
|
+
if (execPath) break;
|
|
328
|
+
parentDir = this.fs.join(parentDir, "..");
|
|
329
|
+
}
|
|
330
|
+
}
|
|
148
331
|
if (!execPath) throw new AlephaError(`Could not find executable for command '${app}'. Make sure the package is installed.`);
|
|
149
332
|
await runExec(execPath, args);
|
|
150
333
|
}
|
|
@@ -164,7 +347,15 @@ var AlephaCliUtils = class {
|
|
|
164
347
|
*/
|
|
165
348
|
async loadAlephaFromServerEntryFile(rootDir, explicitEntry) {
|
|
166
349
|
process.env.ALEPHA_CLI_IMPORT = "true";
|
|
167
|
-
const
|
|
350
|
+
const root = rootDir ?? process.cwd();
|
|
351
|
+
let entry;
|
|
352
|
+
if (explicitEntry) {
|
|
353
|
+
entry = this.fs.join(root, explicitEntry);
|
|
354
|
+
if (!await this.fs.exists(entry)) throw new AlephaError(`Explicit server entry file "${explicitEntry}" not found.`);
|
|
355
|
+
} else {
|
|
356
|
+
const appEntry = await this.boot.getAppEntry(root);
|
|
357
|
+
entry = this.fs.join(root, appEntry.server);
|
|
358
|
+
}
|
|
168
359
|
delete global.__alepha;
|
|
169
360
|
const mod = await import(entry);
|
|
170
361
|
this.log.debug(`Load entry: ${entry}`);
|
|
@@ -283,6 +474,12 @@ var PackageManagerUtils = class {
|
|
|
283
474
|
return this.hasDependency(root, "expo");
|
|
284
475
|
}
|
|
285
476
|
/**
|
|
477
|
+
* Check if React is present in the project.
|
|
478
|
+
*/
|
|
479
|
+
async hasReact(root) {
|
|
480
|
+
return this.hasDependency(root, "react");
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
286
483
|
* Install a dependency if it's missing from the project.
|
|
287
484
|
*/
|
|
288
485
|
async ensureDependency(root, packageName, options = {}) {
|
|
@@ -293,7 +490,7 @@ var PackageManagerUtils = class {
|
|
|
293
490
|
}
|
|
294
491
|
const cmd = await this.getInstallCommand(root, packageName, dev);
|
|
295
492
|
if (options.run) await options.run(cmd, {
|
|
296
|
-
alias: `
|
|
493
|
+
alias: `add ${packageName}`,
|
|
297
494
|
root
|
|
298
495
|
});
|
|
299
496
|
else if (options.exec) {
|
|
@@ -368,17 +565,17 @@ var PackageManagerUtils = class {
|
|
|
368
565
|
await this.writePackageJson(root, content);
|
|
369
566
|
return content;
|
|
370
567
|
}
|
|
371
|
-
const packageJson
|
|
568
|
+
const packageJson = await this.readPackageJson(root);
|
|
372
569
|
const newContent = this.generatePackageJsonContent(modes);
|
|
373
|
-
packageJson
|
|
374
|
-
packageJson
|
|
375
|
-
packageJson
|
|
376
|
-
packageJson
|
|
377
|
-
Object.assign(packageJson
|
|
378
|
-
Object.assign(packageJson
|
|
379
|
-
Object.assign(packageJson
|
|
380
|
-
await this.writePackageJson(root, packageJson
|
|
381
|
-
return packageJson
|
|
570
|
+
packageJson.type = "module";
|
|
571
|
+
packageJson.dependencies ??= {};
|
|
572
|
+
packageJson.devDependencies ??= {};
|
|
573
|
+
packageJson.scripts ??= {};
|
|
574
|
+
Object.assign(packageJson.dependencies, newContent.dependencies);
|
|
575
|
+
Object.assign(packageJson.devDependencies, newContent.devDependencies);
|
|
576
|
+
Object.assign(packageJson.scripts, newContent.scripts);
|
|
577
|
+
await this.writePackageJson(root, packageJson);
|
|
578
|
+
return packageJson;
|
|
382
579
|
}
|
|
383
580
|
generatePackageJsonContent(modes) {
|
|
384
581
|
const dependencies = { alepha: `^${version}` };
|
|
@@ -390,11 +587,11 @@ var PackageManagerUtils = class {
|
|
|
390
587
|
typecheck: "alepha typecheck",
|
|
391
588
|
verify: "alepha verify"
|
|
392
589
|
};
|
|
393
|
-
if (modes.
|
|
590
|
+
if (modes.ui) {
|
|
394
591
|
dependencies["@alepha/ui"] = `^${version}`;
|
|
395
|
-
modes.
|
|
592
|
+
modes.react = true;
|
|
396
593
|
}
|
|
397
|
-
if (modes.
|
|
594
|
+
if (modes.react) {
|
|
398
595
|
dependencies["@alepha/react"] = `^${version}`;
|
|
399
596
|
dependencies.react = "^19.2.0";
|
|
400
597
|
dependencies["react-dom"] = "^19.2.0";
|
|
@@ -453,7 +650,7 @@ export const ApiModule = $module({
|
|
|
453
650
|
|
|
454
651
|
//#endregion
|
|
455
652
|
//#region ../../src/cli/assets/biomeJson.ts
|
|
456
|
-
const biomeJson = `
|
|
653
|
+
const biomeJson = () => `
|
|
457
654
|
{
|
|
458
655
|
"$schema": "https://biomejs.dev/schemas/latest/schema.json",
|
|
459
656
|
"vcs": {
|
|
@@ -549,8 +746,8 @@ ${projectName}/
|
|
|
549
746
|
│ │ ├── AppRouter.ts # Routes with $page
|
|
550
747
|
│ │ └── index.ts # Web module definition with $module
|
|
551
748
|
│ ├── main.server.ts # Server entry
|
|
552
|
-
│
|
|
553
|
-
|
|
749
|
+
│ ├── main.browser.ts # Browser entry (React only)
|
|
750
|
+
│ └── main.css # CSS entry (React only)
|
|
554
751
|
├── package.json
|
|
555
752
|
└── tsconfig.json
|
|
556
753
|
\`\`\`
|
|
@@ -595,6 +792,7 @@ This is an **Alepha** project - a convention-driven TypeScript framework for typ
|
|
|
595
792
|
- Use \`protected\` instead of \`private\` for class members
|
|
596
793
|
- Import with file extensions: \`import { User } from "./User.ts"\`
|
|
597
794
|
- Use \`t\` from Alepha for schemas (not Zod)
|
|
795
|
+
- Prefer \`t.text()\` over \`t.string()\` for user input (has default max length, auto-trim, supports lowercase option)
|
|
598
796
|
|
|
599
797
|
## Project Structure
|
|
600
798
|
${projectStructure}
|
|
@@ -792,7 +990,7 @@ test("dummy test", () => {
|
|
|
792
990
|
|
|
793
991
|
//#endregion
|
|
794
992
|
//#region ../../src/cli/assets/editorconfig.ts
|
|
795
|
-
const editorconfig = `
|
|
993
|
+
const editorconfig = () => `
|
|
796
994
|
# https://editorconfig.org
|
|
797
995
|
|
|
798
996
|
root = true
|
|
@@ -806,22 +1004,6 @@ indent_style = space
|
|
|
806
1004
|
indent_size = 2
|
|
807
1005
|
`.trim();
|
|
808
1006
|
|
|
809
|
-
//#endregion
|
|
810
|
-
//#region ../../src/cli/assets/indexHtml.ts
|
|
811
|
-
const indexHtml = (browserEntry) => `
|
|
812
|
-
<!DOCTYPE html>
|
|
813
|
-
<html lang="en">
|
|
814
|
-
<head>
|
|
815
|
-
<meta charset="UTF-8">
|
|
816
|
-
<title>App</title>
|
|
817
|
-
</head>
|
|
818
|
-
<body>
|
|
819
|
-
<div id="root"></div>
|
|
820
|
-
<script type="module" src="${browserEntry}"><\/script>
|
|
821
|
-
</body>
|
|
822
|
-
</html>
|
|
823
|
-
`.trim();
|
|
824
|
-
|
|
825
1007
|
//#endregion
|
|
826
1008
|
//#region ../../src/cli/assets/mainBrowserTs.ts
|
|
827
1009
|
const mainBrowserTs = () => `
|
|
@@ -835,6 +1017,32 @@ alepha.with(WebModule);
|
|
|
835
1017
|
run(alepha);
|
|
836
1018
|
`.trim();
|
|
837
1019
|
|
|
1020
|
+
//#endregion
|
|
1021
|
+
//#region ../../src/cli/assets/mainCss.ts
|
|
1022
|
+
const mainCss = () => `
|
|
1023
|
+
* {
|
|
1024
|
+
box-sizing: border-box;
|
|
1025
|
+
margin: 0;
|
|
1026
|
+
padding: 0;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
html,
|
|
1030
|
+
body {
|
|
1031
|
+
height: 100%;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
body {
|
|
1035
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
1036
|
+
"Helvetica Neue", Arial, sans-serif;
|
|
1037
|
+
line-height: 1.5;
|
|
1038
|
+
-webkit-font-smoothing: antialiased;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
#root {
|
|
1042
|
+
height: 100%;
|
|
1043
|
+
}
|
|
1044
|
+
`.trim();
|
|
1045
|
+
|
|
838
1046
|
//#endregion
|
|
839
1047
|
//#region ../../src/cli/assets/mainServerTs.ts
|
|
840
1048
|
const mainServerTs = (options = {}) => {
|
|
@@ -853,7 +1061,7 @@ run(alepha);
|
|
|
853
1061
|
|
|
854
1062
|
//#endregion
|
|
855
1063
|
//#region ../../src/cli/assets/tsconfigJson.ts
|
|
856
|
-
const tsconfigJson = `
|
|
1064
|
+
const tsconfigJson = () => `
|
|
857
1065
|
{
|
|
858
1066
|
"extends": "alepha/tsconfig.base"
|
|
859
1067
|
}
|
|
@@ -879,15 +1087,18 @@ export class AppRouter {
|
|
|
879
1087
|
|
|
880
1088
|
//#endregion
|
|
881
1089
|
//#region ../../src/cli/assets/webHelloComponentTsx.ts
|
|
882
|
-
const webHelloComponentTsx = () => `
|
|
1090
|
+
const webHelloComponentTsx = () => `import { useState } from "react";
|
|
1091
|
+
|
|
883
1092
|
interface Props {
|
|
884
1093
|
message: string;
|
|
885
1094
|
}
|
|
886
1095
|
|
|
887
1096
|
const Hello = (props: Props) => {
|
|
1097
|
+
const [message, setMessage] = useState(props.message);
|
|
888
1098
|
return (
|
|
889
1099
|
<div>
|
|
890
|
-
<h1>{
|
|
1100
|
+
<h1>{message}</h1>
|
|
1101
|
+
<input value={message} onChange={e => setMessage(e.target.value)} />
|
|
891
1102
|
<p>Edit this component in src/web/components/Hello.tsx</p>
|
|
892
1103
|
</div>
|
|
893
1104
|
);
|
|
@@ -942,27 +1153,30 @@ var ProjectScaffolder = class {
|
|
|
942
1153
|
*/
|
|
943
1154
|
async ensureConfig(root, opts) {
|
|
944
1155
|
const tasks = [];
|
|
1156
|
+
const force = opts.force ?? false;
|
|
945
1157
|
if (opts.packageJson) tasks.push(this.pm.ensurePackageJson(root, typeof opts.packageJson === "boolean" ? {} : opts.packageJson).then(() => {}));
|
|
946
|
-
if (opts.tsconfigJson) tasks.push(this.ensureTsConfig(root));
|
|
947
|
-
if (opts.indexHtml) tasks.push(this.ensureReactProject(root));
|
|
948
|
-
if (opts.biomeJson) tasks.push(this.ensureBiomeConfig(root));
|
|
949
|
-
if (opts.editorconfig) tasks.push(this.ensureEditorConfig(root));
|
|
950
|
-
if (opts.claudeMd) tasks.push(this.ensureClaudeMd(root, typeof opts.claudeMd === "boolean" ? {} :
|
|
1158
|
+
if (opts.tsconfigJson) tasks.push(this.ensureTsConfig(root, { force }));
|
|
1159
|
+
if (opts.indexHtml) tasks.push(this.ensureReactProject(root, { force }));
|
|
1160
|
+
if (opts.biomeJson) tasks.push(this.ensureBiomeConfig(root, { force }));
|
|
1161
|
+
if (opts.editorconfig) tasks.push(this.ensureEditorConfig(root, { force }));
|
|
1162
|
+
if (opts.claudeMd) tasks.push(this.ensureClaudeMd(root, typeof opts.claudeMd === "boolean" ? { force } : {
|
|
1163
|
+
...opts.claudeMd,
|
|
1164
|
+
force
|
|
1165
|
+
}));
|
|
951
1166
|
await Promise.all(tasks);
|
|
952
1167
|
}
|
|
953
|
-
async ensureTsConfig(root) {
|
|
954
|
-
if (await this.existsInParents(root, "tsconfig.json")) return;
|
|
955
|
-
await this.fs.writeFile(this.fs.join(root, "tsconfig.json"), tsconfigJson);
|
|
1168
|
+
async ensureTsConfig(root, opts = {}) {
|
|
1169
|
+
if (!opts.force && await this.existsInParents(root, "tsconfig.json")) return;
|
|
1170
|
+
await this.fs.writeFile(this.fs.join(root, "tsconfig.json"), tsconfigJson());
|
|
956
1171
|
}
|
|
957
|
-
async ensureBiomeConfig(root) {
|
|
958
|
-
await this.
|
|
1172
|
+
async ensureBiomeConfig(root, opts = {}) {
|
|
1173
|
+
await this.ensureFile(root, "biome.json", biomeJson(), opts.force);
|
|
959
1174
|
}
|
|
960
|
-
async ensureEditorConfig(root) {
|
|
961
|
-
await this.
|
|
1175
|
+
async ensureEditorConfig(root, opts = {}) {
|
|
1176
|
+
await this.ensureFile(root, ".editorconfig", editorconfig(), opts.force);
|
|
962
1177
|
}
|
|
963
1178
|
async ensureClaudeMd(root, options = {}) {
|
|
964
|
-
|
|
965
|
-
if (!await this.fs.exists(path)) await this.fs.writeFile(path, claudeMd(options));
|
|
1179
|
+
await this.ensureFile(root, "CLAUDE.md", claudeMd(options), options.force);
|
|
966
1180
|
}
|
|
967
1181
|
/**
|
|
968
1182
|
* Ensure src/main.server.ts exists with full API structure.
|
|
@@ -972,39 +1186,37 @@ var ProjectScaffolder = class {
|
|
|
972
1186
|
* - src/api/index.ts (API module)
|
|
973
1187
|
* - src/api/controllers/HelloController.ts (example controller)
|
|
974
1188
|
*/
|
|
975
|
-
async ensureApiProject(root) {
|
|
1189
|
+
async ensureApiProject(root, opts = {}) {
|
|
976
1190
|
const srcDir = this.fs.join(root, "src");
|
|
977
|
-
if (await this.fs.exists(srcDir)) {
|
|
1191
|
+
if (!opts.force && await this.fs.exists(srcDir)) {
|
|
978
1192
|
if ((await this.fs.ls(srcDir)).length > 0) return;
|
|
979
1193
|
}
|
|
980
1194
|
const appName = this.getAppName(root);
|
|
981
1195
|
await this.fs.mkdir(this.fs.join(root, "src/api/controllers"), { recursive: true });
|
|
982
|
-
await this.
|
|
983
|
-
await this.
|
|
984
|
-
await this.
|
|
1196
|
+
await this.ensureFile(srcDir, "main.server.ts", mainServerTs(), opts.force);
|
|
1197
|
+
await this.ensureFile(srcDir, "api/index.ts", apiIndexTs({ appName }), opts.force);
|
|
1198
|
+
await this.ensureFile(srcDir, "api/controllers/HelloController.ts", apiHelloControllerTs(), opts.force);
|
|
985
1199
|
}
|
|
986
1200
|
/**
|
|
987
1201
|
* Ensure full React project structure exists.
|
|
988
1202
|
*
|
|
989
1203
|
* Creates:
|
|
990
|
-
* - index.html
|
|
991
1204
|
* - src/main.server.ts, src/main.browser.ts
|
|
992
1205
|
* - src/api/index.ts, src/api/controllers/HelloController.ts
|
|
993
1206
|
* - src/web/index.ts, src/web/AppRouter.ts, src/web/components/Hello.tsx
|
|
994
1207
|
*/
|
|
995
|
-
async ensureReactProject(root) {
|
|
996
|
-
if (await this.fs.exists(this.fs.join(root, "index.html"))) return;
|
|
1208
|
+
async ensureReactProject(root, opts = {}) {
|
|
997
1209
|
const appName = this.getAppName(root);
|
|
998
1210
|
await this.fs.mkdir(this.fs.join(root, "src/api/controllers"), { recursive: true });
|
|
999
1211
|
await this.fs.mkdir(this.fs.join(root, "src/web/components"), { recursive: true });
|
|
1000
|
-
await this.
|
|
1001
|
-
await this.
|
|
1002
|
-
await this.
|
|
1003
|
-
await this.
|
|
1004
|
-
await this.
|
|
1005
|
-
await this.
|
|
1006
|
-
await this.
|
|
1007
|
-
await this.
|
|
1212
|
+
await this.ensureFile(root, "src/main.css", mainCss(), opts.force);
|
|
1213
|
+
await this.ensureFile(root, "src/api/index.ts", apiIndexTs({ appName }), opts.force);
|
|
1214
|
+
await this.ensureFile(root, "src/api/controllers/HelloController.ts", apiHelloControllerTs(), opts.force);
|
|
1215
|
+
await this.ensureFile(root, "src/main.server.ts", mainServerTs({ react: true }), opts.force);
|
|
1216
|
+
await this.ensureFile(root, "src/web/index.ts", webIndexTs({ appName }), opts.force);
|
|
1217
|
+
await this.ensureFile(root, "src/web/AppRouter.ts", webAppRouterTs(), opts.force);
|
|
1218
|
+
await this.ensureFile(root, "src/web/components/Hello.tsx", webHelloComponentTsx(), opts.force);
|
|
1219
|
+
await this.ensureFile(root, "src/main.browser.ts", mainBrowserTs(), opts.force);
|
|
1008
1220
|
}
|
|
1009
1221
|
/**
|
|
1010
1222
|
* Ensure test directory exists with a dummy test file.
|
|
@@ -1019,9 +1231,12 @@ var ProjectScaffolder = class {
|
|
|
1019
1231
|
}
|
|
1020
1232
|
if ((await this.fs.ls(testDir)).length === 0) await this.fs.writeFile(dummyPath, dummySpecTs());
|
|
1021
1233
|
}
|
|
1022
|
-
|
|
1234
|
+
/**
|
|
1235
|
+
* Write a file, optionally overriding if it exists.
|
|
1236
|
+
*/
|
|
1237
|
+
async ensureFile(root, relativePath, content, force) {
|
|
1023
1238
|
const fullPath = this.fs.join(root, relativePath);
|
|
1024
|
-
if (!await this.fs.exists(fullPath)) await this.fs.writeFile(fullPath, content);
|
|
1239
|
+
if (force || !await this.fs.exists(fullPath)) await this.fs.writeFile(fullPath, content);
|
|
1025
1240
|
}
|
|
1026
1241
|
/**
|
|
1027
1242
|
* Check if a file exists in the given directory or any parent directory.
|
|
@@ -1045,15 +1260,13 @@ var BuildCommand = class {
|
|
|
1045
1260
|
utils = $inject(AlephaCliUtils);
|
|
1046
1261
|
pm = $inject(PackageManagerUtils);
|
|
1047
1262
|
scaffolder = $inject(ProjectScaffolder);
|
|
1263
|
+
boot = $inject(AppEntryProvider);
|
|
1264
|
+
viteBuildProvider = $inject(ViteBuildProvider);
|
|
1048
1265
|
options = $use(buildOptions);
|
|
1049
1266
|
build = $command({
|
|
1050
1267
|
name: "build",
|
|
1051
1268
|
mode: "production",
|
|
1052
1269
|
description: "Build the project for production",
|
|
1053
|
-
args: t.optional(t.text({
|
|
1054
|
-
title: "path",
|
|
1055
|
-
description: "Filepath to build"
|
|
1056
|
-
})),
|
|
1057
1270
|
flags: t.object({
|
|
1058
1271
|
stats: t.optional(t.boolean({ description: "Generate build stats report" })),
|
|
1059
1272
|
vercel: t.optional(t.boolean({ description: "Generate Vercel deployment configuration" })),
|
|
@@ -1062,15 +1275,14 @@ var BuildCommand = class {
|
|
|
1062
1275
|
sitemap: t.optional(t.text({ description: "Generate sitemap.xml with base URL" })),
|
|
1063
1276
|
bun: t.optional(t.boolean({ description: "Prioritize .bun.ts entry files for Bun runtime" }))
|
|
1064
1277
|
}),
|
|
1065
|
-
handler: async ({ flags,
|
|
1066
|
-
process.env.ALEPHA_BUILD_MODE = "cli";
|
|
1278
|
+
handler: async ({ flags, run, root }) => {
|
|
1067
1279
|
process.env.NODE_ENV = "production";
|
|
1068
1280
|
if (await this.pm.hasExpo(root)) return;
|
|
1069
1281
|
await this.scaffolder.ensureConfig(root, { tsconfigJson: true });
|
|
1070
|
-
const entry = await boot.
|
|
1282
|
+
const entry = await this.boot.getAppEntry(root);
|
|
1071
1283
|
this.log.trace("Entry file found", { entry });
|
|
1072
1284
|
const distDir = "dist";
|
|
1073
|
-
const
|
|
1285
|
+
const publicDir = "public";
|
|
1074
1286
|
await this.pm.ensureDependency(root, "vite", {
|
|
1075
1287
|
run,
|
|
1076
1288
|
exec: (cmd, opts) => this.utils.exec(cmd, opts)
|
|
@@ -1079,36 +1291,58 @@ var BuildCommand = class {
|
|
|
1079
1291
|
const options = this.options;
|
|
1080
1292
|
await this.utils.loadEnv(root, [".env", ".env.production"]);
|
|
1081
1293
|
const stats = flags.stats ?? options.stats ?? false;
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1294
|
+
let template = "";
|
|
1295
|
+
let hasClient = false;
|
|
1296
|
+
let alepha;
|
|
1297
|
+
await run({
|
|
1298
|
+
name: "analyze app",
|
|
1299
|
+
handler: async () => {
|
|
1300
|
+
alepha = await this.viteBuildProvider.init({ entry });
|
|
1301
|
+
hasClient = this.viteBuildProvider.hasClient();
|
|
1302
|
+
if (hasClient) template = this.viteBuildProvider.generateIndexHtml();
|
|
1303
|
+
}
|
|
1091
1304
|
});
|
|
1305
|
+
if (!alepha) throw new AlephaError("Alepha instance not found");
|
|
1306
|
+
if (hasClient) {
|
|
1307
|
+
const indexHtmlPath = this.fs.join(root, "index.html");
|
|
1308
|
+
await this.fs.writeFile(indexHtmlPath, template);
|
|
1309
|
+
try {
|
|
1310
|
+
await run({
|
|
1311
|
+
name: "vite build client",
|
|
1312
|
+
handler: () => buildClient({
|
|
1313
|
+
silent: true,
|
|
1314
|
+
dist: `${distDir}/${publicDir}`,
|
|
1315
|
+
stats,
|
|
1316
|
+
precompress: true
|
|
1317
|
+
})
|
|
1318
|
+
});
|
|
1319
|
+
} finally {
|
|
1320
|
+
await this.fs.rm(indexHtmlPath);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1092
1323
|
await run({
|
|
1093
1324
|
name: "vite build server",
|
|
1094
1325
|
handler: async () => {
|
|
1095
|
-
|
|
1326
|
+
if (!alepha) throw new AlephaError("Alepha instance not found");
|
|
1327
|
+
const clientIndexPath = `${distDir}/${publicDir}/index.html`;
|
|
1096
1328
|
const clientBuilt = await this.fs.exists(clientIndexPath);
|
|
1097
1329
|
const conditions = [];
|
|
1098
1330
|
if (flags.bun) conditions.push("bun");
|
|
1099
1331
|
if (options.cloudflare) conditions.push("workerd");
|
|
1100
1332
|
await buildServer({
|
|
1101
1333
|
silent: true,
|
|
1102
|
-
entry,
|
|
1334
|
+
entry: entry.server,
|
|
1103
1335
|
distDir,
|
|
1104
|
-
clientDir: clientBuilt ?
|
|
1336
|
+
clientDir: clientBuilt ? publicDir : void 0,
|
|
1105
1337
|
stats,
|
|
1106
|
-
conditions
|
|
1338
|
+
conditions,
|
|
1339
|
+
alepha
|
|
1107
1340
|
});
|
|
1108
1341
|
if (clientBuilt) await this.fs.rm(clientIndexPath);
|
|
1109
1342
|
}
|
|
1110
1343
|
});
|
|
1111
1344
|
await copyAssets({
|
|
1345
|
+
alepha,
|
|
1112
1346
|
root,
|
|
1113
1347
|
entry: `${distDir}/index.js`,
|
|
1114
1348
|
distDir,
|
|
@@ -1116,31 +1350,24 @@ var BuildCommand = class {
|
|
|
1116
1350
|
});
|
|
1117
1351
|
if (hasClient) {
|
|
1118
1352
|
const sitemapHostname = flags.sitemap ?? options.sitemap?.hostname;
|
|
1119
|
-
if (sitemapHostname) await
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
baseUrl: sitemapHostname
|
|
1125
|
-
}));
|
|
1126
|
-
}
|
|
1353
|
+
if (sitemapHostname) await generateSitemap({
|
|
1354
|
+
alepha,
|
|
1355
|
+
baseUrl: sitemapHostname,
|
|
1356
|
+
output: `${distDir}/${publicDir}/sitemap.xml`,
|
|
1357
|
+
run
|
|
1127
1358
|
});
|
|
1128
|
-
await
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
entry: `${distDir}/index.js`,
|
|
1134
|
-
compress: true
|
|
1135
|
-
});
|
|
1136
|
-
}
|
|
1359
|
+
await prerenderPages({
|
|
1360
|
+
alepha,
|
|
1361
|
+
dist: `${distDir}/${publicDir}`,
|
|
1362
|
+
compress: true,
|
|
1363
|
+
run
|
|
1137
1364
|
});
|
|
1138
1365
|
}
|
|
1139
1366
|
if (flags.vercel || options.vercel) await run({
|
|
1140
1367
|
name: "add Vercel config",
|
|
1141
1368
|
handler: () => generateVercel({
|
|
1142
1369
|
distDir,
|
|
1143
|
-
clientDir,
|
|
1370
|
+
clientDir: publicDir,
|
|
1144
1371
|
config: options.vercel
|
|
1145
1372
|
})
|
|
1146
1373
|
});
|
|
@@ -1528,6 +1755,237 @@ var DeployCommand = class {
|
|
|
1528
1755
|
});
|
|
1529
1756
|
};
|
|
1530
1757
|
|
|
1758
|
+
//#endregion
|
|
1759
|
+
//#region ../../src/cli/providers/ViteDevServerProvider.ts
|
|
1760
|
+
/**
|
|
1761
|
+
* Vite development server with Alepha integration.
|
|
1762
|
+
*
|
|
1763
|
+
* Architecture:
|
|
1764
|
+
* - Vite runs in middleware mode (no HTTP server)
|
|
1765
|
+
* - Alepha is the HTTP server via server:onRequest event
|
|
1766
|
+
* - Request flow: Page requests → Alepha SSR, Assets → Vite middleware
|
|
1767
|
+
*
|
|
1768
|
+
* HMR Strategy:
|
|
1769
|
+
* - Browser-only changes (CSS, client components) → Vite HMR (React Fast Refresh)
|
|
1770
|
+
* - Server-only changes → Restart Alepha → Full browser reload
|
|
1771
|
+
* - Shared changes → Restart Alepha → Let Vite HMR propagate
|
|
1772
|
+
*
|
|
1773
|
+
* Features:
|
|
1774
|
+
* - Automatic .env reload detection
|
|
1775
|
+
* - Error recovery on next file change
|
|
1776
|
+
* - Optimized module invalidation (only changed files + importers)
|
|
1777
|
+
*/
|
|
1778
|
+
var ViteDevServerProvider = class {
|
|
1779
|
+
log = $logger();
|
|
1780
|
+
fs = $inject(FileSystemProvider);
|
|
1781
|
+
templateProvider = $inject(ViteTemplateProvider);
|
|
1782
|
+
server;
|
|
1783
|
+
options;
|
|
1784
|
+
alepha = null;
|
|
1785
|
+
hasError = false;
|
|
1786
|
+
changedFiles = /* @__PURE__ */ new Set();
|
|
1787
|
+
async init(options) {
|
|
1788
|
+
this.options = options;
|
|
1789
|
+
await this.createViteServer();
|
|
1790
|
+
return await this.loadAlepha(true);
|
|
1791
|
+
}
|
|
1792
|
+
async start() {
|
|
1793
|
+
await this.alepha?.start();
|
|
1794
|
+
}
|
|
1795
|
+
/**
|
|
1796
|
+
* Create the Vite server in middleware mode.
|
|
1797
|
+
*/
|
|
1798
|
+
async createViteServer() {
|
|
1799
|
+
const { createServer } = await importVite();
|
|
1800
|
+
const viteReact = await importViteReact();
|
|
1801
|
+
const plugins = [];
|
|
1802
|
+
if (viteReact) plugins.push(viteReact());
|
|
1803
|
+
plugins.push(viteAlephaSsrPreload());
|
|
1804
|
+
plugins.push(this.createHmrPlugin());
|
|
1805
|
+
this.server = await createServer({
|
|
1806
|
+
root: this.options.root,
|
|
1807
|
+
plugins,
|
|
1808
|
+
server: { middlewareMode: true },
|
|
1809
|
+
appType: "custom",
|
|
1810
|
+
customLogger: {
|
|
1811
|
+
info: () => {},
|
|
1812
|
+
warn: this.log.warn.bind(this.log),
|
|
1813
|
+
error: this.log.error.bind(this.log),
|
|
1814
|
+
warnOnce: this.log.warn.bind(this.log),
|
|
1815
|
+
clearScreen: () => {},
|
|
1816
|
+
hasWarned: false,
|
|
1817
|
+
hasErrorLogged: () => false
|
|
1818
|
+
}
|
|
1819
|
+
});
|
|
1820
|
+
this.server.restart = async () => {
|
|
1821
|
+
const startTime = Date.now();
|
|
1822
|
+
try {
|
|
1823
|
+
this.hasError = true;
|
|
1824
|
+
await this.loadAlepha(false);
|
|
1825
|
+
await this.alepha?.start();
|
|
1826
|
+
this.log.debug(`Env reloaded in ${Date.now() - startTime}ms`);
|
|
1827
|
+
this.sendBrowserReload();
|
|
1828
|
+
} catch (err) {
|
|
1829
|
+
this.hasError = true;
|
|
1830
|
+
this.log.error("Reload failed", err);
|
|
1831
|
+
this.log.warn("Waiting for file changes to retry...");
|
|
1832
|
+
this.alepha = null;
|
|
1833
|
+
}
|
|
1834
|
+
};
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Vite plugin to handle HMR for Alepha.
|
|
1838
|
+
*/
|
|
1839
|
+
createHmrPlugin() {
|
|
1840
|
+
return {
|
|
1841
|
+
name: "alepha-hmr",
|
|
1842
|
+
handleHotUpdate: async (ctx) => {
|
|
1843
|
+
if (ctx.file.includes("/.idea/")) return [];
|
|
1844
|
+
const firstModule = ctx.modules[0];
|
|
1845
|
+
const isBrowserOnly = firstModule && !firstModule._ssrModule;
|
|
1846
|
+
const isServerOnly = firstModule && !firstModule._clientModule;
|
|
1847
|
+
if (isBrowserOnly) return;
|
|
1848
|
+
const startTime = Date.now();
|
|
1849
|
+
try {
|
|
1850
|
+
this.changedFiles.add(ctx.file);
|
|
1851
|
+
await this.loadAlepha(false);
|
|
1852
|
+
await this.alepha?.start();
|
|
1853
|
+
this.log.debug(`Reloaded in ${Date.now() - startTime}ms`);
|
|
1854
|
+
if (isServerOnly) {
|
|
1855
|
+
this.sendBrowserReload();
|
|
1856
|
+
return [];
|
|
1857
|
+
}
|
|
1858
|
+
return;
|
|
1859
|
+
} catch (err) {
|
|
1860
|
+
this.hasError = true;
|
|
1861
|
+
this.log.error("Reload failed", err);
|
|
1862
|
+
this.log.warn("Waiting for file changes to retry...");
|
|
1863
|
+
this.alepha = null;
|
|
1864
|
+
return [];
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
};
|
|
1868
|
+
}
|
|
1869
|
+
/**
|
|
1870
|
+
* Send browser reload signal via custom event.
|
|
1871
|
+
* Browser listens for 'alepha:reload' and does window.location.reload()
|
|
1872
|
+
*/
|
|
1873
|
+
sendBrowserReload() {
|
|
1874
|
+
this.server.ws.send({
|
|
1875
|
+
type: "custom",
|
|
1876
|
+
event: "alepha:reload",
|
|
1877
|
+
data: {}
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
/**
|
|
1881
|
+
* Setup environment variables for dev mode.
|
|
1882
|
+
*/
|
|
1883
|
+
async setupEnvironment() {
|
|
1884
|
+
const { loadEnv } = await importVite();
|
|
1885
|
+
const env = loadEnv(process.env.NODE_ENV || "development", this.options.root, "");
|
|
1886
|
+
process.env.NODE_ENV ??= "development";
|
|
1887
|
+
process.env.VITE_ALEPHA_DEV = "true";
|
|
1888
|
+
process.env.SERVER_HOST ??= this.options.host?.toString() ?? "localhost";
|
|
1889
|
+
process.env.SERVER_PORT ??= String(this.options.port ?? (process.env.SERVER_PORT ? Number(process.env.SERVER_PORT) : 3e3));
|
|
1890
|
+
for (const [key, value] of Object.entries(env)) process.env[key] ??= value;
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Load or reload the Alepha instance.
|
|
1894
|
+
*/
|
|
1895
|
+
async loadAlepha(isInitialLoad = false) {
|
|
1896
|
+
if (this.alepha) {
|
|
1897
|
+
await this.alepha.stop().catch((err) => this.log.warn("Error stopping Alepha", err));
|
|
1898
|
+
this.alepha = null;
|
|
1899
|
+
}
|
|
1900
|
+
if (isInitialLoad || this.hasError) this.server.moduleGraph.invalidateAll();
|
|
1901
|
+
else this.invalidateModulesWithImporters();
|
|
1902
|
+
this.changedFiles.clear();
|
|
1903
|
+
const envSnapshot = { ...process.env };
|
|
1904
|
+
await this.setupEnvironment();
|
|
1905
|
+
await this.server.ssrLoadModule(this.options.entry.server);
|
|
1906
|
+
const alepha = globalThis.__alepha;
|
|
1907
|
+
if (!alepha) throw new AlephaError("Alepha instance not found after loading entry module");
|
|
1908
|
+
this.alepha = alepha;
|
|
1909
|
+
await this.setupAlepha();
|
|
1910
|
+
this.hasError = false;
|
|
1911
|
+
process.env = envSnapshot;
|
|
1912
|
+
return alepha;
|
|
1913
|
+
}
|
|
1914
|
+
hasReact() {
|
|
1915
|
+
try {
|
|
1916
|
+
this.alepha?.inject("ReactServerProvider");
|
|
1917
|
+
return true;
|
|
1918
|
+
} catch {
|
|
1919
|
+
return false;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Setup Alepha instance with Vite middleware and template.
|
|
1924
|
+
*/
|
|
1925
|
+
async setupAlepha() {
|
|
1926
|
+
if (!this.alepha || !this.hasReact()) return;
|
|
1927
|
+
const template = await this.server.transformIndexHtml("/", this.templateProvider.generateIndexHtml(this.options.entry));
|
|
1928
|
+
this.alepha.store.set("alepha.react.server.template", template);
|
|
1929
|
+
this.alepha.events.on("server:onRequest", {
|
|
1930
|
+
priority: "first",
|
|
1931
|
+
callback: async ({ request }) => {
|
|
1932
|
+
const node = request.raw.node;
|
|
1933
|
+
if (!node || this.isPageRequest(node.req)) return;
|
|
1934
|
+
if (await this.runViteMiddleware(node.req, node.res, request)) {
|
|
1935
|
+
request.reply.status = node.res.statusCode || 200;
|
|
1936
|
+
request.reply.body = null;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
/**
|
|
1942
|
+
* Check if request is for an HTML page (not an asset).
|
|
1943
|
+
*/
|
|
1944
|
+
isPageRequest(req) {
|
|
1945
|
+
const url = req.url || "/";
|
|
1946
|
+
if (url === "/" || url === "/index.html") return true;
|
|
1947
|
+
if (url.startsWith("/@") || url.startsWith("/__vite")) return false;
|
|
1948
|
+
if (/\.\w+$/.test(url.split("?")[0])) return false;
|
|
1949
|
+
return true;
|
|
1950
|
+
}
|
|
1951
|
+
/**
|
|
1952
|
+
* Run Vite middleware and detect if it handled the request.
|
|
1953
|
+
*/
|
|
1954
|
+
async runViteMiddleware(req, res, ctx) {
|
|
1955
|
+
return new Promise((resolve) => {
|
|
1956
|
+
let resolved = false;
|
|
1957
|
+
const done = (handled) => {
|
|
1958
|
+
if (resolved) return;
|
|
1959
|
+
resolved = true;
|
|
1960
|
+
if (handled) ctx.metadata.vite = true;
|
|
1961
|
+
resolve(handled);
|
|
1962
|
+
};
|
|
1963
|
+
res.on("finish", () => done(true));
|
|
1964
|
+
res.on("close", () => res.headersSent && done(true));
|
|
1965
|
+
this.server.middlewares(req, res, () => done(false));
|
|
1966
|
+
setImmediate(() => {
|
|
1967
|
+
if (res.headersSent || res.writableEnded) done(true);
|
|
1968
|
+
});
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* Invalidate modules and all their importers.
|
|
1973
|
+
*/
|
|
1974
|
+
invalidateModulesWithImporters() {
|
|
1975
|
+
const invalidated = /* @__PURE__ */ new Set();
|
|
1976
|
+
const queue = [...this.changedFiles];
|
|
1977
|
+
while (queue.length > 0) {
|
|
1978
|
+
const file = queue.pop();
|
|
1979
|
+
if (invalidated.has(file)) continue;
|
|
1980
|
+
const mod = this.server.moduleGraph.getModuleById(file);
|
|
1981
|
+
if (!mod) continue;
|
|
1982
|
+
this.server.moduleGraph.invalidateModule(mod);
|
|
1983
|
+
invalidated.add(file);
|
|
1984
|
+
for (const importer of mod.importers) if (importer.id && !invalidated.has(importer.id)) queue.push(importer.id);
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1531
1989
|
//#endregion
|
|
1532
1990
|
//#region ../../src/cli/commands/dev.ts
|
|
1533
1991
|
var DevCommand = class {
|
|
@@ -1537,6 +1995,8 @@ var DevCommand = class {
|
|
|
1537
1995
|
pm = $inject(PackageManagerUtils);
|
|
1538
1996
|
scaffolder = $inject(ProjectScaffolder);
|
|
1539
1997
|
alepha = $inject(Alepha);
|
|
1998
|
+
viteDevServer = $inject(ViteDevServerProvider);
|
|
1999
|
+
boot = $inject(AppEntryProvider);
|
|
1540
2000
|
/**
|
|
1541
2001
|
* Will run the project in watch mode.
|
|
1542
2002
|
*
|
|
@@ -1546,53 +2006,21 @@ var DevCommand = class {
|
|
|
1546
2006
|
dev = $command({
|
|
1547
2007
|
name: "dev",
|
|
1548
2008
|
description: "Run the project in development mode",
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
description: "Filepath to run"
|
|
1552
|
-
})),
|
|
1553
|
-
handler: async ({ args, root }) => {
|
|
1554
|
-
const expo = await this.pm.hasExpo(root);
|
|
2009
|
+
handler: async ({ root }) => {
|
|
2010
|
+
const [expo, react] = await Promise.all([this.pm.hasExpo(root), this.pm.hasReact(root)]);
|
|
1555
2011
|
await this.scaffolder.ensureConfig(root, { tsconfigJson: true });
|
|
1556
2012
|
if (expo) {
|
|
1557
2013
|
await this.utils.exec("expo start");
|
|
1558
2014
|
return;
|
|
1559
2015
|
}
|
|
1560
|
-
const entry = await boot.
|
|
1561
|
-
this.log.
|
|
1562
|
-
if (!await this.isFullstackProject(root)) {
|
|
1563
|
-
const exe = await this.isBunProject(root) ? "bun" : "tsx";
|
|
1564
|
-
let cmd = `${exe} --watch`;
|
|
1565
|
-
if (await this.utils.exists(root, ".env")) cmd += " --env-file=./.env";
|
|
1566
|
-
cmd += ` ${entry}`;
|
|
1567
|
-
await this.utils.exec(cmd, { global: exe === "bun" });
|
|
1568
|
-
return;
|
|
1569
|
-
}
|
|
2016
|
+
const entry = await this.boot.getAppEntry(root);
|
|
2017
|
+
this.log.debug("Entry file found", { entry });
|
|
1570
2018
|
await this.pm.ensureDependency(root, "vite", { exec: (cmd, opts) => this.utils.exec(cmd, opts) });
|
|
1571
|
-
await
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
return this.fs.exists(this.fs.join(root, "bun.lock"));
|
|
1577
|
-
}
|
|
1578
|
-
async isFullstackProject(root) {
|
|
1579
|
-
return this.fs.exists(this.fs.join(root, "index.html"));
|
|
1580
|
-
}
|
|
1581
|
-
};
|
|
1582
|
-
|
|
1583
|
-
//#endregion
|
|
1584
|
-
//#region ../../src/cli/commands/format.ts
|
|
1585
|
-
var FormatCommand = class {
|
|
1586
|
-
utils = $inject(AlephaCliUtils);
|
|
1587
|
-
pm = $inject(PackageManagerUtils);
|
|
1588
|
-
scaffolder = $inject(ProjectScaffolder);
|
|
1589
|
-
format = $command({
|
|
1590
|
-
name: "format",
|
|
1591
|
-
description: "Format the codebase using Biome",
|
|
1592
|
-
handler: async ({ root }) => {
|
|
1593
|
-
await this.scaffolder.ensureConfig(root, { biomeJson: true });
|
|
1594
|
-
await this.pm.ensureDependency(root, "@biomejs/biome", { exec: (cmd, opts) => this.utils.exec(cmd, opts) });
|
|
1595
|
-
await this.utils.exec("biome format --fix");
|
|
2019
|
+
await this.viteDevServer.init({
|
|
2020
|
+
root,
|
|
2021
|
+
entry
|
|
2022
|
+
});
|
|
2023
|
+
await this.viteDevServer.start();
|
|
1596
2024
|
}
|
|
1597
2025
|
});
|
|
1598
2026
|
};
|
|
@@ -1627,7 +2055,7 @@ const DEFAULT_IGNORE = [
|
|
|
1627
2055
|
* ```
|
|
1628
2056
|
*/
|
|
1629
2057
|
const changelogOptions = $atom({
|
|
1630
|
-
name: "alepha.changelog",
|
|
2058
|
+
name: "alepha.cli.changelog.options",
|
|
1631
2059
|
schema: t.object({ ignore: t.optional(t.array(t.string())) }),
|
|
1632
2060
|
default: { ignore: DEFAULT_IGNORE }
|
|
1633
2061
|
});
|
|
@@ -1835,7 +2263,7 @@ var GenEnvCommand = class {
|
|
|
1835
2263
|
if (value.description) dotEnvFile += `# ${value.description.split("\n").join("\n# ")}\n`;
|
|
1836
2264
|
if (value.required && !value.default) dotEnvFile += `# (required)\n`;
|
|
1837
2265
|
if (value.enum) dotEnvFile += `# Possible values: ${value.enum.join(", ")}\n`;
|
|
1838
|
-
dotEnvFile +=
|
|
2266
|
+
dotEnvFile += `#${key}=${value.default || ""}\n\n`;
|
|
1839
2267
|
}
|
|
1840
2268
|
if (flags.out) await this.fs.writeFile(this.fs.join(root, flags.out), dotEnvFile);
|
|
1841
2269
|
else this.log.info(dotEnvFile);
|
|
@@ -1935,35 +2363,41 @@ var InitCommand = class {
|
|
|
1935
2363
|
pnpm: t.optional(t.boolean({ description: "Use pnpm package manager" })),
|
|
1936
2364
|
npm: t.optional(t.boolean({ description: "Use npm package manager" })),
|
|
1937
2365
|
bun: t.optional(t.boolean({ description: "Use Bun package manager" })),
|
|
1938
|
-
|
|
2366
|
+
react: t.optional(t.boolean({
|
|
1939
2367
|
aliases: ["r"],
|
|
1940
2368
|
description: "Include Alepha React dependencies"
|
|
1941
2369
|
})),
|
|
1942
|
-
|
|
1943
|
-
test: t.optional(t.boolean({ description: "Include Vitest and create test directory" }))
|
|
2370
|
+
ui: t.optional(t.boolean({ description: "Include Alepha UI dependencies" })),
|
|
2371
|
+
test: t.optional(t.boolean({ description: "Include Vitest and create test directory" })),
|
|
2372
|
+
force: t.optional(t.boolean({
|
|
2373
|
+
aliases: ["f"],
|
|
2374
|
+
description: "Override existing files"
|
|
2375
|
+
}))
|
|
1944
2376
|
}),
|
|
1945
2377
|
handler: async ({ run, flags, root, args }) => {
|
|
1946
|
-
if (flags.
|
|
2378
|
+
if (flags.react) flags.ui = true;
|
|
1947
2379
|
if (args) {
|
|
1948
2380
|
root = this.fs.join(root, args);
|
|
1949
2381
|
await this.fs.mkdir(root);
|
|
1950
2382
|
}
|
|
1951
2383
|
const isExpo = await this.pm.hasExpo(root);
|
|
2384
|
+
const force = !!flags.force;
|
|
1952
2385
|
await run({
|
|
1953
2386
|
name: "ensuring configuration files",
|
|
1954
2387
|
handler: async () => {
|
|
1955
2388
|
await this.scaffolder.ensureConfig(root, {
|
|
2389
|
+
force,
|
|
1956
2390
|
tsconfigJson: true,
|
|
1957
2391
|
packageJson: flags,
|
|
1958
2392
|
biomeJson: true,
|
|
1959
2393
|
editorconfig: true,
|
|
1960
|
-
indexHtml: !!flags.
|
|
2394
|
+
indexHtml: !!flags.react && !isExpo,
|
|
1961
2395
|
claudeMd: flags.agent ? {
|
|
1962
|
-
react: !!flags.
|
|
1963
|
-
ui: !!flags.
|
|
2396
|
+
react: !!flags.react,
|
|
2397
|
+
ui: !!flags.ui
|
|
1964
2398
|
} : false
|
|
1965
2399
|
});
|
|
1966
|
-
if (!flags.
|
|
2400
|
+
if (!flags.react) await this.scaffolder.ensureApiProject(root, { force });
|
|
1967
2401
|
}
|
|
1968
2402
|
});
|
|
1969
2403
|
const pmName = await this.pm.getPackageManager(root, flags);
|
|
@@ -2009,7 +2443,7 @@ var LintCommand = class {
|
|
|
2009
2443
|
handler: async ({ root }) => {
|
|
2010
2444
|
await this.scaffolder.ensureConfig(root, { biomeJson: true });
|
|
2011
2445
|
await this.pm.ensureDependency(root, "@biomejs/biome", { exec: (cmd, opts) => this.utils.exec(cmd, opts) });
|
|
2012
|
-
await this.utils.exec("biome check --
|
|
2446
|
+
await this.utils.exec("biome check --fix");
|
|
2013
2447
|
}
|
|
2014
2448
|
});
|
|
2015
2449
|
};
|
|
@@ -2162,7 +2596,6 @@ const AlephaCli = $module({
|
|
|
2162
2596
|
DbCommand,
|
|
2163
2597
|
DeployCommand,
|
|
2164
2598
|
DevCommand,
|
|
2165
|
-
FormatCommand,
|
|
2166
2599
|
InitCommand,
|
|
2167
2600
|
LintCommand,
|
|
2168
2601
|
RootCommand,
|
|
@@ -2170,6 +2603,7 @@ const AlephaCli = $module({
|
|
|
2170
2603
|
TypecheckCommand,
|
|
2171
2604
|
VerifyCommand,
|
|
2172
2605
|
GenCommand,
|
|
2606
|
+
AppEntryProvider,
|
|
2173
2607
|
GitProvider
|
|
2174
2608
|
]
|
|
2175
2609
|
});
|
|
@@ -2232,6 +2666,7 @@ var AlephaPackageBuilderCli = class {
|
|
|
2232
2666
|
sourcemap: true,
|
|
2233
2667
|
fixedExtension: false,
|
|
2234
2668
|
platform: "node",
|
|
2669
|
+
inlineOnly: false,
|
|
2235
2670
|
external,
|
|
2236
2671
|
dts: { sourcemap: true }
|
|
2237
2672
|
});
|
|
@@ -2241,6 +2676,7 @@ var AlephaPackageBuilderCli = class {
|
|
|
2241
2676
|
platform: "neutral",
|
|
2242
2677
|
sourcemap: true,
|
|
2243
2678
|
dts: false,
|
|
2679
|
+
inlineOnly: false,
|
|
2244
2680
|
external
|
|
2245
2681
|
});
|
|
2246
2682
|
if (item.browser) entries.push({
|
|
@@ -2249,6 +2685,7 @@ var AlephaPackageBuilderCli = class {
|
|
|
2249
2685
|
platform: "browser",
|
|
2250
2686
|
sourcemap: true,
|
|
2251
2687
|
dts: false,
|
|
2688
|
+
inlineOnly: false,
|
|
2252
2689
|
external
|
|
2253
2690
|
});
|
|
2254
2691
|
if (item.bun) entries.push({
|
|
@@ -2258,6 +2695,7 @@ var AlephaPackageBuilderCli = class {
|
|
|
2258
2695
|
sourcemap: true,
|
|
2259
2696
|
fixedExtension: false,
|
|
2260
2697
|
dts: false,
|
|
2698
|
+
inlineOnly: false,
|
|
2261
2699
|
external
|
|
2262
2700
|
});
|
|
2263
2701
|
const config = this.fs.join(tmpDir, `tsdown-${item.name.replace("/", "-")}.config.js`);
|
|
@@ -2281,6 +2719,7 @@ var AlephaPackageBuilderCli = class {
|
|
|
2281
2719
|
}
|
|
2282
2720
|
});
|
|
2283
2721
|
};
|
|
2722
|
+
var AlephaPackageBuilderCli_default = AlephaPackageBuilderCli;
|
|
2284
2723
|
async function getAllFiles(dir) {
|
|
2285
2724
|
const files = [];
|
|
2286
2725
|
async function scan(currentDir) {
|
|
@@ -2384,6 +2823,7 @@ const defineConfig = (runConfig) => {
|
|
|
2384
2823
|
if (config.services) for (const it of config.services) alepha.with(it);
|
|
2385
2824
|
if (config.env) for (const [key, value] of Object.entries(config.env)) process.env[key] = String(value);
|
|
2386
2825
|
if (config.build) alepha.set(buildOptions, config.build);
|
|
2826
|
+
if (config.entry) alepha.set(appEntryOptions, config.entry);
|
|
2387
2827
|
return { ...config.commands };
|
|
2388
2828
|
};
|
|
2389
2829
|
};
|
|
@@ -2393,5 +2833,5 @@ const defineConfig = (runConfig) => {
|
|
|
2393
2833
|
const defineAlephaConfig = defineConfig;
|
|
2394
2834
|
|
|
2395
2835
|
//#endregion
|
|
2396
|
-
export { AlephaCli, AlephaCliUtils, AlephaPackageBuilderCli, BuildCommand, ChangelogCommand, CleanCommand, DEFAULT_IGNORE, DbCommand, DeployCommand, DevCommand,
|
|
2836
|
+
export { AlephaCli, AlephaCliUtils, AlephaPackageBuilderCli_default as AlephaPackageBuilderCli, AppEntryProvider, BuildCommand, ChangelogCommand, CleanCommand, DEFAULT_IGNORE, DbCommand, DeployCommand, DevCommand, GitMessageParser, GitProvider, InitCommand, LintCommand, OpenApiCommand, RootCommand, TestCommand, TypecheckCommand, VerifyCommand, analyzeModules, changelogOptions, defineAlephaConfig, defineConfig, version };
|
|
2397
2837
|
//# sourceMappingURL=index.js.map
|