alepha 0.13.0 → 0.13.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/dist/api-jobs/index.d.ts +26 -26
- package/dist/api-users/index.d.ts +1 -1
- package/dist/cli/{dist-Sz2EXvQX.cjs → dist-Dl9Vl7Ur.js} +17 -13
- package/dist/cli/{dist-BBPjuQ56.js.map → dist-Dl9Vl7Ur.js.map} +1 -1
- package/dist/cli/index.d.ts +3 -11
- package/dist/cli/index.js +106 -74
- package/dist/cli/index.js.map +1 -1
- package/dist/email/index.js +71 -73
- package/dist/email/index.js.map +1 -1
- package/dist/orm/index.d.ts +1 -1
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/index.d.ts +4 -4
- package/dist/retry/index.d.ts +1 -1
- package/dist/retry/index.js +2 -2
- package/dist/retry/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/security/index.d.ts +28 -28
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server-health/index.d.ts +17 -17
- package/dist/server-metrics/index.js +170 -174
- package/dist/server-metrics/index.js.map +1 -1
- package/dist/server-security/index.d.ts +9 -9
- package/dist/vite/index.js +4 -5
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts +7 -7
- package/package.json +52 -103
- package/src/cli/apps/AlephaPackageBuilderCli.ts +7 -2
- package/src/cli/assets/appRouterTs.ts +9 -0
- package/src/cli/assets/indexHtml.ts +2 -1
- package/src/cli/assets/mainBrowserTs.ts +10 -0
- package/src/cli/commands/CoreCommands.ts +6 -5
- package/src/cli/commands/DrizzleCommands.ts +65 -57
- package/src/cli/commands/VerifyCommands.ts +1 -1
- package/src/cli/services/ProjectUtils.ts +44 -38
- package/src/orm/providers/DrizzleKitProvider.ts +1 -1
- package/src/retry/descriptors/$retry.ts +5 -3
- package/src/server/providers/NodeHttpServerProvider.ts +1 -1
- package/src/vite/helpers/boot.ts +3 -3
- package/dist/api-files/index.cjs +0 -1293
- package/dist/api-files/index.cjs.map +0 -1
- package/dist/api-files/index.d.cts +0 -829
- package/dist/api-jobs/index.cjs +0 -274
- package/dist/api-jobs/index.cjs.map +0 -1
- package/dist/api-jobs/index.d.cts +0 -654
- package/dist/api-notifications/index.cjs +0 -380
- package/dist/api-notifications/index.cjs.map +0 -1
- package/dist/api-notifications/index.d.cts +0 -289
- package/dist/api-parameters/index.cjs +0 -66
- package/dist/api-parameters/index.cjs.map +0 -1
- package/dist/api-parameters/index.d.cts +0 -84
- package/dist/api-users/index.cjs +0 -6009
- package/dist/api-users/index.cjs.map +0 -1
- package/dist/api-users/index.d.cts +0 -4740
- package/dist/api-verifications/index.cjs +0 -407
- package/dist/api-verifications/index.cjs.map +0 -1
- package/dist/api-verifications/index.d.cts +0 -207
- package/dist/batch/index.cjs +0 -408
- package/dist/batch/index.cjs.map +0 -1
- package/dist/batch/index.d.cts +0 -330
- package/dist/bin/index.cjs +0 -17
- package/dist/bin/index.cjs.map +0 -1
- package/dist/bin/index.d.cts +0 -1
- package/dist/bucket/index.cjs +0 -303
- package/dist/bucket/index.cjs.map +0 -1
- package/dist/bucket/index.d.cts +0 -355
- package/dist/cache/index.cjs +0 -241
- package/dist/cache/index.cjs.map +0 -1
- package/dist/cache/index.d.cts +0 -202
- package/dist/cache-redis/index.cjs +0 -84
- package/dist/cache-redis/index.cjs.map +0 -1
- package/dist/cache-redis/index.d.cts +0 -40
- package/dist/cli/chunk-DSlc6foC.cjs +0 -43
- package/dist/cli/dist-BBPjuQ56.js +0 -2778
- package/dist/cli/dist-Sz2EXvQX.cjs.map +0 -1
- package/dist/cli/index.cjs +0 -1241
- package/dist/cli/index.cjs.map +0 -1
- package/dist/cli/index.d.cts +0 -422
- package/dist/command/index.cjs +0 -693
- package/dist/command/index.cjs.map +0 -1
- package/dist/command/index.d.cts +0 -340
- package/dist/core/index.cjs +0 -2264
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.d.cts +0 -1927
- package/dist/datetime/index.cjs +0 -318
- package/dist/datetime/index.cjs.map +0 -1
- package/dist/datetime/index.d.cts +0 -145
- package/dist/email/index.cjs +0 -10874
- package/dist/email/index.cjs.map +0 -1
- package/dist/email/index.d.cts +0 -186
- package/dist/fake/index.cjs +0 -34641
- package/dist/fake/index.cjs.map +0 -1
- package/dist/fake/index.d.cts +0 -74
- package/dist/file/index.cjs +0 -1212
- package/dist/file/index.cjs.map +0 -1
- package/dist/file/index.d.cts +0 -698
- package/dist/lock/index.cjs +0 -226
- package/dist/lock/index.cjs.map +0 -1
- package/dist/lock/index.d.cts +0 -361
- package/dist/lock-redis/index.cjs +0 -113
- package/dist/lock-redis/index.cjs.map +0 -1
- package/dist/lock-redis/index.d.cts +0 -24
- package/dist/logger/index.cjs +0 -521
- package/dist/logger/index.cjs.map +0 -1
- package/dist/logger/index.d.cts +0 -281
- package/dist/orm/index.cjs +0 -2986
- package/dist/orm/index.cjs.map +0 -1
- package/dist/orm/index.d.cts +0 -2213
- package/dist/queue/index.cjs +0 -1044
- package/dist/queue/index.cjs.map +0 -1
- package/dist/queue/index.d.cts +0 -1265
- package/dist/queue-redis/index.cjs +0 -873
- package/dist/queue-redis/index.cjs.map +0 -1
- package/dist/queue-redis/index.d.cts +0 -82
- package/dist/redis/index.cjs +0 -153
- package/dist/redis/index.cjs.map +0 -1
- package/dist/redis/index.d.cts +0 -82
- package/dist/retry/index.cjs +0 -146
- package/dist/retry/index.cjs.map +0 -1
- package/dist/retry/index.d.cts +0 -172
- package/dist/router/index.cjs +0 -111
- package/dist/router/index.cjs.map +0 -1
- package/dist/router/index.d.cts +0 -46
- package/dist/scheduler/index.cjs +0 -576
- package/dist/scheduler/index.cjs.map +0 -1
- package/dist/scheduler/index.d.cts +0 -145
- package/dist/security/index.cjs +0 -2402
- package/dist/security/index.cjs.map +0 -1
- package/dist/security/index.d.cts +0 -598
- package/dist/server/index.cjs +0 -1680
- package/dist/server/index.cjs.map +0 -1
- package/dist/server/index.d.cts +0 -810
- package/dist/server-auth/index.cjs +0 -3146
- package/dist/server-auth/index.cjs.map +0 -1
- package/dist/server-auth/index.d.cts +0 -1164
- package/dist/server-cache/index.cjs +0 -252
- package/dist/server-cache/index.cjs.map +0 -1
- package/dist/server-cache/index.d.cts +0 -164
- package/dist/server-compress/index.cjs +0 -141
- package/dist/server-compress/index.cjs.map +0 -1
- package/dist/server-compress/index.d.cts +0 -38
- package/dist/server-cookies/index.cjs +0 -234
- package/dist/server-cookies/index.cjs.map +0 -1
- package/dist/server-cookies/index.d.cts +0 -144
- package/dist/server-cors/index.cjs +0 -201
- package/dist/server-cors/index.cjs.map +0 -1
- package/dist/server-cors/index.d.cts +0 -140
- package/dist/server-health/index.cjs +0 -62
- package/dist/server-health/index.cjs.map +0 -1
- package/dist/server-health/index.d.cts +0 -58
- package/dist/server-helmet/index.cjs +0 -131
- package/dist/server-helmet/index.cjs.map +0 -1
- package/dist/server-helmet/index.d.cts +0 -97
- package/dist/server-links/index.cjs +0 -992
- package/dist/server-links/index.cjs.map +0 -1
- package/dist/server-links/index.d.cts +0 -513
- package/dist/server-metrics/index.cjs +0 -4535
- package/dist/server-metrics/index.cjs.map +0 -1
- package/dist/server-metrics/index.d.cts +0 -35
- package/dist/server-multipart/index.cjs +0 -237
- package/dist/server-multipart/index.cjs.map +0 -1
- package/dist/server-multipart/index.d.cts +0 -50
- package/dist/server-proxy/index.cjs +0 -186
- package/dist/server-proxy/index.cjs.map +0 -1
- package/dist/server-proxy/index.d.cts +0 -234
- package/dist/server-rate-limit/index.cjs +0 -241
- package/dist/server-rate-limit/index.cjs.map +0 -1
- package/dist/server-rate-limit/index.d.cts +0 -183
- package/dist/server-security/index.cjs +0 -316
- package/dist/server-security/index.cjs.map +0 -1
- package/dist/server-security/index.d.cts +0 -173
- package/dist/server-static/index.cjs +0 -170
- package/dist/server-static/index.cjs.map +0 -1
- package/dist/server-static/index.d.cts +0 -121
- package/dist/server-swagger/index.cjs +0 -1021
- package/dist/server-swagger/index.cjs.map +0 -1
- package/dist/server-swagger/index.d.cts +0 -382
- package/dist/sms/index.cjs +0 -221
- package/dist/sms/index.cjs.map +0 -1
- package/dist/sms/index.d.cts +0 -130
- package/dist/thread/index.cjs +0 -350
- package/dist/thread/index.cjs.map +0 -1
- package/dist/thread/index.d.cts +0 -260
- package/dist/topic/index.cjs +0 -282
- package/dist/topic/index.cjs.map +0 -1
- package/dist/topic/index.d.cts +0 -523
- package/dist/topic-redis/index.cjs +0 -71
- package/dist/topic-redis/index.cjs.map +0 -1
- package/dist/topic-redis/index.d.cts +0 -42
- package/dist/vite/index.cjs +0 -1077
- package/dist/vite/index.cjs.map +0 -1
- package/dist/vite/index.d.cts +0 -542
- package/dist/websocket/index.cjs +0 -1117
- package/dist/websocket/index.cjs.map +0 -1
- package/dist/websocket/index.d.cts +0 -861
package/dist/cli/index.cjs
DELETED
|
@@ -1,1241 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-DSlc6foC.cjs');
|
|
2
|
-
let alepha = require("alepha");
|
|
3
|
-
let alepha_command = require("alepha/command");
|
|
4
|
-
let alepha_logger = require("alepha/logger");
|
|
5
|
-
let node_child_process = require("node:child_process");
|
|
6
|
-
let node_fs_promises = require("node:fs/promises");
|
|
7
|
-
let node_path = require("node:path");
|
|
8
|
-
let alepha_file = require("alepha/file");
|
|
9
|
-
let alepha_vite = require("alepha/vite");
|
|
10
|
-
let tsx_esm_api = require("tsx/esm/api");
|
|
11
|
-
let node_fs = require("node:fs");
|
|
12
|
-
let node_module = require("node:module");
|
|
13
|
-
let node_os = require("node:os");
|
|
14
|
-
node_os = require_chunk.__toESM(node_os);
|
|
15
|
-
|
|
16
|
-
//#region src/cli/services/ProcessRunner.ts
|
|
17
|
-
/**
|
|
18
|
-
* Service for running external processes with logging support.
|
|
19
|
-
*
|
|
20
|
-
* This service wraps Node.js child_process functionality and provides:
|
|
21
|
-
* - Automatic logging of executed commands
|
|
22
|
-
* - Promise-based execution
|
|
23
|
-
* - Inherited stdio for seamless output
|
|
24
|
-
* - Working directory context
|
|
25
|
-
* - Config file management in node_modules/.alepha
|
|
26
|
-
*/
|
|
27
|
-
var ProcessRunner = class {
|
|
28
|
-
log = (0, alepha_logger.$logger)();
|
|
29
|
-
/**
|
|
30
|
-
* Execute a command using npx with inherited stdio.
|
|
31
|
-
*
|
|
32
|
-
* @param command - The command to execute (will be passed to npx)
|
|
33
|
-
* @param env - Optional environment variables to set for the command
|
|
34
|
-
* @returns Promise that resolves when the process exits
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* const runner = alepha.inject(ProcessRunner);
|
|
39
|
-
* await runner.exec("tsx watch src/index.ts");
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
async exec(command, env = {}) {
|
|
43
|
-
this.log.debug(`Executing command: npx ${command}`, { cwd: process.cwd() });
|
|
44
|
-
const prog = (0, node_child_process.spawn)("npx", command.split(" "), {
|
|
45
|
-
stdio: "inherit",
|
|
46
|
-
cwd: process.cwd(),
|
|
47
|
-
env: {
|
|
48
|
-
...process.env,
|
|
49
|
-
...env,
|
|
50
|
-
NODE_OPTIONS: "--import tsx"
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
await new Promise((resolve) => prog.on("exit", () => {
|
|
54
|
-
resolve();
|
|
55
|
-
}));
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Write a configuration file to node_modules/.alepha directory.
|
|
59
|
-
*
|
|
60
|
-
* Creates the .alepha directory if it doesn't exist and writes the file with the given content.
|
|
61
|
-
*
|
|
62
|
-
* @param name - The name of the config file to create
|
|
63
|
-
* @param content - The content to write to the file
|
|
64
|
-
* @param root - The root directory (defaults to process.cwd())
|
|
65
|
-
* @returns The absolute path to the created file
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* const runner = alepha.inject(ProcessRunner);
|
|
70
|
-
* const configPath = await runner.writeConfigFile("biome.json", biomeConfig);
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
async writeConfigFile(name, content, root = process.cwd()) {
|
|
74
|
-
const dir = (0, node_path.join)(root, "node_modules", ".alepha");
|
|
75
|
-
await (0, node_fs_promises.mkdir)(dir, { recursive: true }).catch(() => null);
|
|
76
|
-
const path = (0, node_path.join)(dir, name);
|
|
77
|
-
await (0, node_fs_promises.writeFile)(path, content);
|
|
78
|
-
this.log.debug(`Config file written: ${path}`);
|
|
79
|
-
return path;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
//#endregion
|
|
84
|
-
//#region src/cli/assets/biomeJson.ts
|
|
85
|
-
const biomeJson = `
|
|
86
|
-
{
|
|
87
|
-
"$schema": "https://biomejs.dev/schemas/latest/schema.json",
|
|
88
|
-
"vcs": {
|
|
89
|
-
"enabled": true,
|
|
90
|
-
"clientKind": "git"
|
|
91
|
-
},
|
|
92
|
-
"files": {
|
|
93
|
-
"ignoreUnknown": true,
|
|
94
|
-
"includes": ["**", "!node_modules", "!dist"]
|
|
95
|
-
},
|
|
96
|
-
"formatter": {
|
|
97
|
-
"enabled": true,
|
|
98
|
-
"indentStyle": "space"
|
|
99
|
-
},
|
|
100
|
-
"linter": {
|
|
101
|
-
"enabled": true,
|
|
102
|
-
"rules": {
|
|
103
|
-
"recommended": true
|
|
104
|
-
},
|
|
105
|
-
"domains": {
|
|
106
|
-
"react": "recommended"
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
"assist": {
|
|
110
|
-
"actions": {
|
|
111
|
-
"source": {
|
|
112
|
-
"organizeImports": "on"
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
`.trim();
|
|
118
|
-
|
|
119
|
-
//#endregion
|
|
120
|
-
//#region src/cli/assets/indexHtml.ts
|
|
121
|
-
const indexHtml = (browserEntry = "/src/main.tsx") => `
|
|
122
|
-
<!DOCTYPE html>
|
|
123
|
-
<html lang="en">
|
|
124
|
-
<head>
|
|
125
|
-
<meta charset="UTF-8">
|
|
126
|
-
<title>App</title>
|
|
127
|
-
</head>
|
|
128
|
-
<body>
|
|
129
|
-
<script type="module" src="${browserEntry}"><\/script>
|
|
130
|
-
</body>
|
|
131
|
-
</html>
|
|
132
|
-
`.trim();
|
|
133
|
-
|
|
134
|
-
//#endregion
|
|
135
|
-
//#region src/cli/assets/tsconfigJson.ts
|
|
136
|
-
const tsconfigJson = `
|
|
137
|
-
{
|
|
138
|
-
"extends": "alepha/tsconfig.base"
|
|
139
|
-
}
|
|
140
|
-
`.trim();
|
|
141
|
-
|
|
142
|
-
//#endregion
|
|
143
|
-
//#region src/cli/assets/viteConfigTs.ts
|
|
144
|
-
const viteConfigTs = (serverEntry) => `
|
|
145
|
-
import { viteAlepha } from "alepha/vite";
|
|
146
|
-
|
|
147
|
-
export default {
|
|
148
|
-
plugins: [
|
|
149
|
-
viteAlepha(${serverEntry ? `{ serverEntry: "${serverEntry}" }` : ""}),
|
|
150
|
-
],
|
|
151
|
-
test: {
|
|
152
|
-
globals: true,
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
`.trim();
|
|
156
|
-
|
|
157
|
-
//#endregion
|
|
158
|
-
//#region src/cli/version.ts
|
|
159
|
-
const packageJson = JSON.parse((0, node_fs.readFileSync)(new URL("../../package.json", require("url").pathToFileURL(__filename).href), "utf-8"));
|
|
160
|
-
const version = packageJson.version;
|
|
161
|
-
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region src/cli/services/ProjectUtils.ts
|
|
164
|
-
/**
|
|
165
|
-
* Utility service for common project operations used by CLI commands.
|
|
166
|
-
*
|
|
167
|
-
* This service provides helper methods for:
|
|
168
|
-
* - Project configuration file management (tsconfig.json, package.json, etc.)
|
|
169
|
-
* - Package manager setup (Yarn, npm, pnpm)
|
|
170
|
-
* - Sample project downloading
|
|
171
|
-
* - Drizzle ORM/Kit utilities
|
|
172
|
-
* - Alepha instance loading
|
|
173
|
-
*/
|
|
174
|
-
var ProjectUtils = class {
|
|
175
|
-
log = (0, alepha_logger.$logger)();
|
|
176
|
-
runner = (0, alepha.$inject)(ProcessRunner);
|
|
177
|
-
fs = (0, alepha.$inject)(alepha_file.FileSystemProvider);
|
|
178
|
-
/**
|
|
179
|
-
* Ensure Yarn is configured in the project directory.
|
|
180
|
-
*
|
|
181
|
-
* Creates a .yarnrc.yml file with node-modules linker if it doesn't exist.
|
|
182
|
-
*
|
|
183
|
-
* @param root - The root directory of the project
|
|
184
|
-
*/
|
|
185
|
-
async ensureYarn(root) {
|
|
186
|
-
const yarnrcPath = (0, node_path.join)(root, ".yarnrc.yml");
|
|
187
|
-
try {
|
|
188
|
-
await (0, node_fs_promises.access)(yarnrcPath);
|
|
189
|
-
} catch {
|
|
190
|
-
await (0, node_fs_promises.writeFile)(yarnrcPath, "nodeLinker: node-modules");
|
|
191
|
-
}
|
|
192
|
-
const npmLockPath = (0, node_path.join)(root, "package-lock.json");
|
|
193
|
-
const pnpmLockPath = (0, node_path.join)(root, "pnpm-lock.yaml");
|
|
194
|
-
await this.fs.rm(npmLockPath, { force: true });
|
|
195
|
-
await this.fs.rm(pnpmLockPath, { force: true });
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Generate package.json content with Alepha dependencies.
|
|
199
|
-
*
|
|
200
|
-
* @param modes - Configuration for which dependencies to include
|
|
201
|
-
* @returns Package.json partial with dependencies, devDependencies, and scripts
|
|
202
|
-
*/
|
|
203
|
-
generatePackageJsonContent(modes) {
|
|
204
|
-
const dependencies = { alepha: `^${version}` };
|
|
205
|
-
const devDependencies = {};
|
|
206
|
-
if (modes.react) {
|
|
207
|
-
dependencies["@alepha/react"] = `^${version}`;
|
|
208
|
-
dependencies.react = "19.1.0";
|
|
209
|
-
devDependencies["@types/react"] = "19.1.0";
|
|
210
|
-
}
|
|
211
|
-
return {
|
|
212
|
-
type: "module",
|
|
213
|
-
dependencies,
|
|
214
|
-
devDependencies,
|
|
215
|
-
scripts: {
|
|
216
|
-
dev: "alepha dev",
|
|
217
|
-
build: "alepha build"
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Ensure package.json exists and has correct configuration.
|
|
223
|
-
*
|
|
224
|
-
* Creates a new package.json if none exists, or updates an existing one to:
|
|
225
|
-
* - Set "type": "module"
|
|
226
|
-
* - Add Alepha dependencies
|
|
227
|
-
* - Add standard scripts
|
|
228
|
-
*
|
|
229
|
-
* @param root - The root directory of the project
|
|
230
|
-
* @param modes - Configuration for which dependencies to include
|
|
231
|
-
*/
|
|
232
|
-
async ensurePackageJson(root, modes) {
|
|
233
|
-
const packageJsonPath = (0, node_path.join)(root, "package.json");
|
|
234
|
-
try {
|
|
235
|
-
await (0, node_fs_promises.access)(packageJsonPath);
|
|
236
|
-
} catch (error) {
|
|
237
|
-
await (0, node_fs_promises.writeFile)(packageJsonPath, JSON.stringify(this.generatePackageJsonContent(modes), null, 2));
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
const content = await (0, node_fs_promises.readFile)(packageJsonPath, "utf8");
|
|
241
|
-
const packageJson$1 = JSON.parse(content);
|
|
242
|
-
const newPackageJson = this.generatePackageJsonContent(modes);
|
|
243
|
-
packageJson$1.type = "module";
|
|
244
|
-
packageJson$1.dependencies ??= {};
|
|
245
|
-
packageJson$1.devDependencies ??= {};
|
|
246
|
-
packageJson$1.scripts ??= {};
|
|
247
|
-
Object.assign(packageJson$1.dependencies, newPackageJson.dependencies);
|
|
248
|
-
Object.assign(packageJson$1.devDependencies, newPackageJson.devDependencies);
|
|
249
|
-
Object.assign(packageJson$1.scripts, newPackageJson.scripts);
|
|
250
|
-
await (0, node_fs_promises.writeFile)(packageJsonPath, JSON.stringify(packageJson$1, null, 2));
|
|
251
|
-
}
|
|
252
|
-
async ensureConfig(root, opts) {
|
|
253
|
-
const tasks = [];
|
|
254
|
-
if (opts.packageJson) tasks.push(this.ensurePackageJson(root, typeof opts.packageJson === "boolean" ? {} : opts.packageJson));
|
|
255
|
-
if (opts.tsconfigJson) tasks.push(this.ensureTsConfig(root));
|
|
256
|
-
if (opts.viteConfigTs) tasks.push(this.ensureViteConfig(root));
|
|
257
|
-
if (opts.indexHtml) tasks.push(this.ensureIndexHtml(root));
|
|
258
|
-
if (opts.biomeJson) tasks.push(this.ensureBiomeConfig(root));
|
|
259
|
-
await Promise.all(tasks);
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Ensure package.json exists and is configured as ES module.
|
|
263
|
-
*
|
|
264
|
-
* Similar to ensurePackageJson but only validates/sets the "type": "module" field.
|
|
265
|
-
* Throws an error if no package.json exists.
|
|
266
|
-
*
|
|
267
|
-
* @param root - The root directory of the project
|
|
268
|
-
* @throws {AlephaError} If no package.json is found
|
|
269
|
-
*/
|
|
270
|
-
async ensurePackageJsonModule(root) {
|
|
271
|
-
const packageJsonPath = (0, node_path.join)(root, "package.json");
|
|
272
|
-
try {
|
|
273
|
-
await (0, node_fs_promises.access)(packageJsonPath);
|
|
274
|
-
} catch (error) {
|
|
275
|
-
throw new alepha.AlephaError("No package.json found in project root. Run 'npx alepha init' to create one.");
|
|
276
|
-
}
|
|
277
|
-
const content = await (0, node_fs_promises.readFile)(packageJsonPath, "utf8");
|
|
278
|
-
const packageJson$1 = JSON.parse(content);
|
|
279
|
-
if (!packageJson$1.type || packageJson$1.type !== "module") {
|
|
280
|
-
packageJson$1.type = "module";
|
|
281
|
-
await (0, node_fs_promises.writeFile)(packageJsonPath, JSON.stringify(packageJson$1, null, 2));
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Ensure tsconfig.json exists in the project.
|
|
286
|
-
*
|
|
287
|
-
* Creates a standard Alepha tsconfig.json if none exists.
|
|
288
|
-
*
|
|
289
|
-
* @param root - The root directory of the project
|
|
290
|
-
*/
|
|
291
|
-
async ensureTsConfig(root) {
|
|
292
|
-
await this.ensureFileExists(root, "tsconfig.json", tsconfigJson, true);
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Ensure vite.config.ts exists in the project.
|
|
296
|
-
*
|
|
297
|
-
* Creates a standard Alepha vite.config.ts if none exists.
|
|
298
|
-
*/
|
|
299
|
-
async ensureViteConfig(root) {
|
|
300
|
-
await this.ensureFileExists(root, "vite.config.ts", viteConfigTs(), false);
|
|
301
|
-
}
|
|
302
|
-
async ensureFileExists(root, name, content, checkParentDirectories = false) {
|
|
303
|
-
const configPath = (0, node_path.join)(root, name);
|
|
304
|
-
if (!checkParentDirectories) try {
|
|
305
|
-
await (0, node_fs_promises.access)(configPath);
|
|
306
|
-
return;
|
|
307
|
-
} catch {
|
|
308
|
-
await (0, node_fs_promises.writeFile)(configPath, content);
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
let found = false;
|
|
312
|
-
let currentDir = root;
|
|
313
|
-
const maxIterations = 10;
|
|
314
|
-
let level = 0;
|
|
315
|
-
while (level < maxIterations) {
|
|
316
|
-
try {
|
|
317
|
-
await (0, node_fs_promises.access)((0, node_path.join)(currentDir, name));
|
|
318
|
-
found = true;
|
|
319
|
-
break;
|
|
320
|
-
} catch {
|
|
321
|
-
const parentDir = (0, node_path.join)(currentDir, "..");
|
|
322
|
-
if (parentDir === currentDir) break;
|
|
323
|
-
currentDir = parentDir;
|
|
324
|
-
}
|
|
325
|
-
level += 1;
|
|
326
|
-
}
|
|
327
|
-
if (!found) await (0, node_fs_promises.writeFile)(configPath, content);
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Get the path to Biome configuration file.
|
|
331
|
-
*
|
|
332
|
-
* Looks for an existing biome.json in the project root, or creates one if it doesn't exist.
|
|
333
|
-
*/
|
|
334
|
-
async ensureBiomeConfig(root) {
|
|
335
|
-
await this.ensureFileExists(root, "biome.json", biomeJson, true);
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Get the path to Vite configuration file.
|
|
339
|
-
*
|
|
340
|
-
* Looks for an existing vite.config.ts in the project root, or creates one if it doesn't exist.
|
|
341
|
-
*
|
|
342
|
-
* @param root - The root directory of the project (defaults to process.cwd())
|
|
343
|
-
* @param serverEntry - Optional path to the server entry file to include in the config
|
|
344
|
-
* @returns Absolute path to the vite.config.ts file
|
|
345
|
-
*/
|
|
346
|
-
async getViteConfigPath(root, serverEntry) {
|
|
347
|
-
try {
|
|
348
|
-
const viteConfigPath = (0, node_path.join)(root, "vite.config.ts");
|
|
349
|
-
await (0, node_fs_promises.access)(viteConfigPath);
|
|
350
|
-
return viteConfigPath;
|
|
351
|
-
} catch {
|
|
352
|
-
return this.runner.writeConfigFile("vite.config.ts", viteConfigTs(serverEntry));
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Load Alepha instance from a server entry file.
|
|
357
|
-
*
|
|
358
|
-
* Dynamically imports the server entry file and extracts the Alepha instance.
|
|
359
|
-
* Skips the automatic start process.
|
|
360
|
-
*
|
|
361
|
-
* @param rootDir - The root directory of the project
|
|
362
|
-
* @param explicitEntry - Optional explicit path to the entry file
|
|
363
|
-
* @returns Object containing the Alepha instance and the entry file path
|
|
364
|
-
* @throws {AlephaError} If the Alepha instance cannot be found
|
|
365
|
-
*/
|
|
366
|
-
async loadAlephaFromServerEntryFile(rootDir, explicitEntry) {
|
|
367
|
-
process.env.ALEPHA_CLI_IMPORT = "true";
|
|
368
|
-
const entry = await alepha_vite.boot.getServerEntry(rootDir, explicitEntry);
|
|
369
|
-
const mod = await (0, tsx_esm_api.tsImport)(entry, { parentURL: require("url").pathToFileURL(__filename).href });
|
|
370
|
-
this.log.debug(`Load entry: ${entry}`);
|
|
371
|
-
if (mod.default instanceof alepha.Alepha) return {
|
|
372
|
-
alepha: mod.default,
|
|
373
|
-
entry
|
|
374
|
-
};
|
|
375
|
-
const g = global;
|
|
376
|
-
if (g.__alepha) return {
|
|
377
|
-
alepha: g.__alepha,
|
|
378
|
-
entry
|
|
379
|
-
};
|
|
380
|
-
throw new alepha.AlephaError(`Could not find Alepha instance in entry file: ${entry}`);
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Get DrizzleKitProvider from an Alepha instance.
|
|
384
|
-
*
|
|
385
|
-
* Searches the Alepha registry for the DrizzleKitProvider instance.
|
|
386
|
-
*
|
|
387
|
-
* @param alepha - The Alepha instance to search
|
|
388
|
-
* @returns The DrizzleKitProvider instance
|
|
389
|
-
*/
|
|
390
|
-
getKitFromAlepha(alepha$1) {
|
|
391
|
-
return alepha$1["registry"].values().find((it) => it.instance.constructor.name === "DrizzleKitProvider")?.instance;
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Generate JavaScript code for Drizzle entities export.
|
|
395
|
-
*
|
|
396
|
-
* Creates a temporary entities.js file that imports from the entry file
|
|
397
|
-
* and exports database models for Drizzle Kit to process.
|
|
398
|
-
*
|
|
399
|
-
* @param entry - Path to the server entry file
|
|
400
|
-
* @param provider - Name of the database provider
|
|
401
|
-
* @param models - Array of model names to export
|
|
402
|
-
* @returns JavaScript code as a string
|
|
403
|
-
*/
|
|
404
|
-
generateEntitiesJs(entry, provider, models = []) {
|
|
405
|
-
return `
|
|
406
|
-
import "${entry}";
|
|
407
|
-
import { DrizzleKitProvider, Repository } from "alepha/orm";
|
|
408
|
-
|
|
409
|
-
const alepha = globalThis.__alepha;
|
|
410
|
-
const kit = alepha.inject(DrizzleKitProvider);
|
|
411
|
-
const provider = alepha.services(Repository).find((it) => it.provider.name === "${provider}").provider;
|
|
412
|
-
const models = kit.getModels(provider);
|
|
413
|
-
|
|
414
|
-
${models.map((it) => `export const ${it} = models["${it}"];`).join("\n")}
|
|
415
|
-
|
|
416
|
-
`.trim();
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Prepare Drizzle configuration files for a database provider.
|
|
420
|
-
*
|
|
421
|
-
* Creates temporary entities.js and drizzle.config.js files needed
|
|
422
|
-
* for Drizzle Kit commands to run properly.
|
|
423
|
-
*
|
|
424
|
-
* @param options - Configuration options including kit, provider info, and paths
|
|
425
|
-
* @returns Path to the generated drizzle.config.js file
|
|
426
|
-
*/
|
|
427
|
-
async prepareDrizzleConfig(options) {
|
|
428
|
-
const models = Object.keys(options.kit.getModels(options.provider));
|
|
429
|
-
const entitiesJs = this.generateEntitiesJs(options.entry, options.providerName, models);
|
|
430
|
-
const config = {
|
|
431
|
-
schema: await this.runner.writeConfigFile("entities.js", entitiesJs, options.rootDir),
|
|
432
|
-
out: `./migrations/${options.providerName}`,
|
|
433
|
-
dialect: options.dialect,
|
|
434
|
-
dbCredentials: { url: options.providerUrl }
|
|
435
|
-
};
|
|
436
|
-
if (options.providerName === "pglite") config.driver = "pglite";
|
|
437
|
-
const drizzleConfigJs = `export default ${JSON.stringify(config, null, 2)}`;
|
|
438
|
-
return await this.runner.writeConfigFile("drizzle.config.js", drizzleConfigJs, options.rootDir);
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* Run a drizzle-kit command for all database providers in an Alepha instance.
|
|
442
|
-
*
|
|
443
|
-
* Iterates through all repository providers, prepares Drizzle config for each,
|
|
444
|
-
* and executes the specified drizzle-kit command.
|
|
445
|
-
*
|
|
446
|
-
* @param options - Configuration including command to run, flags, and logging
|
|
447
|
-
*/
|
|
448
|
-
async runDrizzleKitCommand(options) {
|
|
449
|
-
const rootDir = options.root;
|
|
450
|
-
this.log.debug(`Using project root: ${rootDir}`);
|
|
451
|
-
const { alepha: alepha$1, entry } = await this.loadAlephaFromServerEntryFile(rootDir, options.args);
|
|
452
|
-
const kit = this.getKitFromAlepha(alepha$1);
|
|
453
|
-
const repositoryProvider = alepha$1.inject("RepositoryProvider");
|
|
454
|
-
const accepted = /* @__PURE__ */ new Set([]);
|
|
455
|
-
for (const descriptor of repositoryProvider.getRepositories()) {
|
|
456
|
-
const provider = descriptor.provider;
|
|
457
|
-
const providerName = provider.name;
|
|
458
|
-
const dialect = provider.dialect;
|
|
459
|
-
if (accepted.has(providerName)) continue;
|
|
460
|
-
accepted.add(providerName);
|
|
461
|
-
if (options.provider && options.provider !== providerName) {
|
|
462
|
-
this.log.debug(`Skipping provider '${providerName}' (filter: ${options.provider})`);
|
|
463
|
-
continue;
|
|
464
|
-
}
|
|
465
|
-
this.log.info("");
|
|
466
|
-
this.log.info(options.logMessage(providerName, dialect));
|
|
467
|
-
const drizzleConfigJsPath = await this.prepareDrizzleConfig({
|
|
468
|
-
kit,
|
|
469
|
-
provider,
|
|
470
|
-
providerName,
|
|
471
|
-
providerUrl: provider.url,
|
|
472
|
-
dialect,
|
|
473
|
-
entry,
|
|
474
|
-
rootDir
|
|
475
|
-
});
|
|
476
|
-
const flags = options.commandFlags ? ` ${options.commandFlags}` : "";
|
|
477
|
-
await this.runner.exec(`drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
async getPackageManager(root) {
|
|
481
|
-
if (await this.fs.exists((0, node_path.join)(root, "yarn.lock"))) return "yarn";
|
|
482
|
-
else if (await this.fs.exists((0, node_path.join)(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
483
|
-
else return "npm";
|
|
484
|
-
}
|
|
485
|
-
async ensureIndexHtml(root) {
|
|
486
|
-
if (await this.fs.exists((0, node_path.join)(root, "index.html"))) return;
|
|
487
|
-
const entry = await alepha_vite.boot.getServerEntry(root).catch(() => null);
|
|
488
|
-
await this.fs.writeFile((0, node_path.join)(root, "index.html"), indexHtml(entry ? entry.replace(root, "") : void 0));
|
|
489
|
-
}
|
|
490
|
-
async hasDir(root, dirName) {
|
|
491
|
-
return this.fs.exists((0, node_path.join)(root, dirName));
|
|
492
|
-
}
|
|
493
|
-
async readPackageJson(root) {
|
|
494
|
-
const packageJson$1 = await this.fs.createFile({ path: (0, node_path.join)(root, "package.json") }).text();
|
|
495
|
-
return JSON.parse(packageJson$1);
|
|
496
|
-
}
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
//#endregion
|
|
500
|
-
//#region src/cli/commands/BiomeCommands.ts
|
|
501
|
-
var BiomeCommands = class {
|
|
502
|
-
log = (0, alepha_logger.$logger)();
|
|
503
|
-
runner = (0, alepha.$inject)(ProcessRunner);
|
|
504
|
-
utils = (0, alepha.$inject)(ProjectUtils);
|
|
505
|
-
format = (0, alepha_command.$command)({
|
|
506
|
-
name: "format",
|
|
507
|
-
description: "Format the codebase using Biome",
|
|
508
|
-
handler: async ({ root }) => {
|
|
509
|
-
await this.utils.ensureConfig(root, { biomeJson: true });
|
|
510
|
-
await this.runner.exec(`biome format --fix`);
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
lint = (0, alepha_command.$command)({
|
|
514
|
-
name: "lint",
|
|
515
|
-
description: "Run linter across the codebase using Biome",
|
|
516
|
-
handler: async ({ root }) => {
|
|
517
|
-
await this.utils.ensureConfig(root, { biomeJson: true });
|
|
518
|
-
await this.runner.exec(`biome check --formatter-enabled=false --fix`);
|
|
519
|
-
}
|
|
520
|
-
});
|
|
521
|
-
};
|
|
522
|
-
|
|
523
|
-
//#endregion
|
|
524
|
-
//#region src/cli/commands/CoreCommands.ts
|
|
525
|
-
var CoreCommands = class {
|
|
526
|
-
log = (0, alepha_logger.$logger)();
|
|
527
|
-
cli = (0, alepha.$inject)(alepha_command.CliProvider);
|
|
528
|
-
utils = (0, alepha.$inject)(ProjectUtils);
|
|
529
|
-
/**
|
|
530
|
-
* Called when no command is provided
|
|
531
|
-
*/
|
|
532
|
-
root = (0, alepha_command.$command)({
|
|
533
|
-
root: true,
|
|
534
|
-
flags: alepha.t.object({ version: alepha.t.optional(alepha.t.boolean({
|
|
535
|
-
description: "Show Alepha CLI version",
|
|
536
|
-
aliases: ["v"]
|
|
537
|
-
})) }),
|
|
538
|
-
handler: async ({ flags }) => {
|
|
539
|
-
if (flags.version) {
|
|
540
|
-
this.log.info(version);
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
this.cli.printHelp();
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
/**
|
|
547
|
-
* Clean the project, removing the "dist" directory
|
|
548
|
-
*/
|
|
549
|
-
clean = (0, alepha_command.$command)({
|
|
550
|
-
name: "clean",
|
|
551
|
-
description: "Clean the project",
|
|
552
|
-
handler: async ({ run }) => {
|
|
553
|
-
await run.rm("./dist");
|
|
554
|
-
}
|
|
555
|
-
});
|
|
556
|
-
/**
|
|
557
|
-
* Ensure the project has the necessary Alepha configuration files.
|
|
558
|
-
* Add the correct dependencies to package.json and install them.
|
|
559
|
-
*/
|
|
560
|
-
init = (0, alepha_command.$command)({
|
|
561
|
-
name: "init",
|
|
562
|
-
description: "Add missing Alepha configuration files to the project",
|
|
563
|
-
flags: alepha.t.object({
|
|
564
|
-
yarn: alepha.t.optional(alepha.t.boolean({ description: "Use Yarn package manager" })),
|
|
565
|
-
api: alepha.t.optional(alepha.t.boolean({ description: "Include Alepha Server dependencies" })),
|
|
566
|
-
react: alepha.t.optional(alepha.t.boolean({ description: "Include Alepha React dependencies" })),
|
|
567
|
-
orm: alepha.t.optional(alepha.t.boolean({ description: "Include Alepha ORM dependencies" }))
|
|
568
|
-
}),
|
|
569
|
-
handler: async ({ run, flags, root }) => {
|
|
570
|
-
await run({
|
|
571
|
-
name: "Ensuring configuration files",
|
|
572
|
-
handler: async () => {
|
|
573
|
-
await this.utils.ensureConfig(root, {
|
|
574
|
-
tsconfigJson: true,
|
|
575
|
-
packageJson: flags,
|
|
576
|
-
indexHtml: !!flags.react
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
});
|
|
580
|
-
const guessedPm = await this.utils.getPackageManager(root);
|
|
581
|
-
if (flags.yarn || guessedPm === "yarn") {
|
|
582
|
-
await this.utils.ensureYarn(root);
|
|
583
|
-
await run("yarn install", { alias: "Installing dependencies with Yarn" });
|
|
584
|
-
} else await run("npm install", { alias: "Installing dependencies with npm" });
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
//#endregion
|
|
590
|
-
//#region src/cli/commands/DrizzleCommands.ts
|
|
591
|
-
const drizzleCommandFlags = alepha.t.object({ provider: alepha.t.optional(alepha.t.text({ description: "Database provider name to target (e.g., 'postgres', 'sqlite')" })) });
|
|
592
|
-
var DrizzleCommands = class {
|
|
593
|
-
log = (0, alepha_logger.$logger)();
|
|
594
|
-
runner = (0, alepha.$inject)(ProcessRunner);
|
|
595
|
-
utils = (0, alepha.$inject)(ProjectUtils);
|
|
596
|
-
/**
|
|
597
|
-
* Check if database migrations are up to date.
|
|
598
|
-
*/
|
|
599
|
-
check = (0, alepha_command.$command)({
|
|
600
|
-
name: "db:migrate:check",
|
|
601
|
-
description: "Check if database migration files are up to date",
|
|
602
|
-
args: alepha.t.optional(alepha.t.text({
|
|
603
|
-
title: "path",
|
|
604
|
-
description: "Path to the Alepha server entry file"
|
|
605
|
-
})),
|
|
606
|
-
flags: drizzleCommandFlags,
|
|
607
|
-
handler: async ({ args, flags, root }) => {
|
|
608
|
-
const rootDir = root;
|
|
609
|
-
this.log.debug(`Using project root: ${rootDir}`);
|
|
610
|
-
const { alepha: alepha$1 } = await this.utils.loadAlephaFromServerEntryFile(rootDir, args);
|
|
611
|
-
const models = [];
|
|
612
|
-
const repositories = alepha$1.descriptors("repository");
|
|
613
|
-
const kit = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("drizzle-kit/api");
|
|
614
|
-
const migrationDir = (0, node_path.join)(rootDir, "migrations");
|
|
615
|
-
const journalFile = await (0, node_fs_promises.readFile)(`${migrationDir}/meta/_journal.json`, "utf-8").catch(() => null);
|
|
616
|
-
if (!journalFile) {
|
|
617
|
-
this.log.info(`No migration journal found.`);
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
const journal = JSON.parse(journalFile);
|
|
621
|
-
const lastMigration = journal.entries[journal.entries.length - 1];
|
|
622
|
-
const lastSnapshot = JSON.parse(await (0, node_fs_promises.readFile)(`${migrationDir}/meta/${String(lastMigration.idx).padStart(4, "0")}_snapshot.json`, "utf-8"));
|
|
623
|
-
for (const repository of repositories) if (!models.includes(repository.table)) models.push(repository.table);
|
|
624
|
-
const now = kit.generateDrizzleJson(models, lastSnapshot.id);
|
|
625
|
-
const migrationStatements = await new Promise((resolve) => {
|
|
626
|
-
(async () => {
|
|
627
|
-
const timer = setTimeout(() => {
|
|
628
|
-
resolve([{ message: "Migration generation timed out." }]);
|
|
629
|
-
}, 5e3);
|
|
630
|
-
const statements = await kit.generateMigration(lastSnapshot, now);
|
|
631
|
-
clearTimeout(timer);
|
|
632
|
-
resolve(statements);
|
|
633
|
-
})();
|
|
634
|
-
});
|
|
635
|
-
if (migrationStatements.length === 0) {
|
|
636
|
-
this.log.info("No changes detected.");
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
this.log.info("");
|
|
640
|
-
this.log.info("Detected migration statements:");
|
|
641
|
-
this.log.info("");
|
|
642
|
-
for (const stmt of migrationStatements) this.log.info(stmt);
|
|
643
|
-
this.log.info("");
|
|
644
|
-
this.log.info(`At least ${migrationStatements.length} change(s) detected.`);
|
|
645
|
-
this.log.info("Please, run 'alepha db:generate' to update the migration files.");
|
|
646
|
-
this.log.info("");
|
|
647
|
-
throw new alepha.AlephaError("Database migrations are not up to date.");
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
/**
|
|
651
|
-
* Generate database migration files
|
|
652
|
-
*
|
|
653
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
654
|
-
* - Retrieves all repository descriptors to gather database models.
|
|
655
|
-
* - Creates temporary entity definitions based on the current database schema.
|
|
656
|
-
* - Writes these definitions to a temporary schema file. (node_modules/.db/entities.ts)
|
|
657
|
-
* - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.
|
|
658
|
-
*/
|
|
659
|
-
generate = (0, alepha_command.$command)({
|
|
660
|
-
name: "db:generate",
|
|
661
|
-
description: "Generate migration files based on current database schema",
|
|
662
|
-
summary: false,
|
|
663
|
-
args: alepha.t.optional(alepha.t.text({
|
|
664
|
-
title: "path",
|
|
665
|
-
description: "Path to the Alepha server entry file"
|
|
666
|
-
})),
|
|
667
|
-
flags: alepha.t.extend(drizzleCommandFlags, { custom: alepha.t.optional(alepha.t.text({ description: "Custom migration name for drizzle-kit generate --custom" })) }),
|
|
668
|
-
handler: async ({ args, flags, root }) => {
|
|
669
|
-
const commandFlags = flags.custom ? `--custom=${flags.custom}` : void 0;
|
|
670
|
-
await this.utils.runDrizzleKitCommand({
|
|
671
|
-
root,
|
|
672
|
-
args,
|
|
673
|
-
command: "generate",
|
|
674
|
-
commandFlags,
|
|
675
|
-
provider: flags.provider,
|
|
676
|
-
logMessage: (providerName, dialect) => `Generate '${providerName}' migrations (${dialect}) ...`
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
/**
|
|
681
|
-
* Push database schema changes directly to the database
|
|
682
|
-
*
|
|
683
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
684
|
-
* - Retrieves all repository descriptors to gather database models.
|
|
685
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
686
|
-
* - Invokes Drizzle Kit's push command to apply schema changes directly.
|
|
687
|
-
*/
|
|
688
|
-
push = (0, alepha_command.$command)({
|
|
689
|
-
name: "db:push",
|
|
690
|
-
description: "Push database schema changes directly to the database",
|
|
691
|
-
summary: false,
|
|
692
|
-
args: alepha.t.optional(alepha.t.text({
|
|
693
|
-
title: "path",
|
|
694
|
-
description: "Path to the Alepha server entry file"
|
|
695
|
-
})),
|
|
696
|
-
flags: drizzleCommandFlags,
|
|
697
|
-
handler: async ({ root, args, flags }) => {
|
|
698
|
-
await this.utils.runDrizzleKitCommand({
|
|
699
|
-
root,
|
|
700
|
-
args,
|
|
701
|
-
command: "push",
|
|
702
|
-
provider: flags.provider,
|
|
703
|
-
logMessage: (providerName, dialect) => `Push '${providerName}' schema (${dialect}) ...`
|
|
704
|
-
});
|
|
705
|
-
}
|
|
706
|
-
});
|
|
707
|
-
/**
|
|
708
|
-
* Apply pending database migrations
|
|
709
|
-
*
|
|
710
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
711
|
-
* - Retrieves all repository descriptors to gather database models.
|
|
712
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
713
|
-
* - Invokes Drizzle Kit's migrate command to apply pending migrations.
|
|
714
|
-
*/
|
|
715
|
-
migrate = (0, alepha_command.$command)({
|
|
716
|
-
name: "db:migrate",
|
|
717
|
-
description: "Apply pending database migrations",
|
|
718
|
-
summary: false,
|
|
719
|
-
args: alepha.t.optional(alepha.t.text({
|
|
720
|
-
title: "path",
|
|
721
|
-
description: "Path to the Alepha server entry file"
|
|
722
|
-
})),
|
|
723
|
-
flags: drizzleCommandFlags,
|
|
724
|
-
handler: async ({ root, args, flags }) => {
|
|
725
|
-
await this.utils.runDrizzleKitCommand({
|
|
726
|
-
root,
|
|
727
|
-
args,
|
|
728
|
-
command: "migrate",
|
|
729
|
-
provider: flags.provider,
|
|
730
|
-
logMessage: (providerName, dialect) => `Migrate '${providerName}' database (${dialect}) ...`
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
});
|
|
734
|
-
/**
|
|
735
|
-
* Launch Drizzle Studio database browser
|
|
736
|
-
*
|
|
737
|
-
* - Loads the Alepha instance from the specified entry file.
|
|
738
|
-
* - Retrieves all repository descriptors to gather database models.
|
|
739
|
-
* - Creates temporary entity definitions and Drizzle config.
|
|
740
|
-
* - Invokes Drizzle Kit's studio command to launch the web-based database browser.
|
|
741
|
-
*/
|
|
742
|
-
studio = (0, alepha_command.$command)({
|
|
743
|
-
name: "db:studio",
|
|
744
|
-
description: "Launch Drizzle Studio database browser",
|
|
745
|
-
summary: false,
|
|
746
|
-
args: alepha.t.optional(alepha.t.text({
|
|
747
|
-
title: "path",
|
|
748
|
-
description: "Path to the Alepha server entry file"
|
|
749
|
-
})),
|
|
750
|
-
flags: drizzleCommandFlags,
|
|
751
|
-
handler: async ({ root, args, flags }) => {
|
|
752
|
-
await this.utils.runDrizzleKitCommand({
|
|
753
|
-
root,
|
|
754
|
-
args,
|
|
755
|
-
command: "studio",
|
|
756
|
-
provider: flags.provider,
|
|
757
|
-
logMessage: (providerName, dialect) => `Launch Studio for '${providerName}' (${dialect}) ...`
|
|
758
|
-
});
|
|
759
|
-
}
|
|
760
|
-
});
|
|
761
|
-
/**
|
|
762
|
-
* Drop database schema (development only)
|
|
763
|
-
*
|
|
764
|
-
* @experimental
|
|
765
|
-
*/
|
|
766
|
-
drop = (0, alepha_command.$command)({
|
|
767
|
-
name: "db:drop",
|
|
768
|
-
description: "Drop database schema (development only)",
|
|
769
|
-
summary: false,
|
|
770
|
-
args: alepha.t.optional(alepha.t.text({
|
|
771
|
-
title: "path",
|
|
772
|
-
description: "Path to the Alepha server entry file"
|
|
773
|
-
})),
|
|
774
|
-
flags: drizzleCommandFlags,
|
|
775
|
-
handler: async ({ flags }) => {
|
|
776
|
-
this.log.warn("db:drop is not yet implemented");
|
|
777
|
-
if (flags.provider) this.log.info(`Provider filter: ${flags.provider}`);
|
|
778
|
-
}
|
|
779
|
-
});
|
|
780
|
-
/**
|
|
781
|
-
* Seed database with initial data
|
|
782
|
-
*
|
|
783
|
-
* @experimental
|
|
784
|
-
*/
|
|
785
|
-
seed = (0, alepha_command.$command)({
|
|
786
|
-
name: "db:seed",
|
|
787
|
-
description: "Seed database with initial data",
|
|
788
|
-
summary: false,
|
|
789
|
-
args: alepha.t.optional(alepha.t.text({
|
|
790
|
-
title: "path",
|
|
791
|
-
description: "Path to the Alepha server entry file"
|
|
792
|
-
})),
|
|
793
|
-
flags: drizzleCommandFlags,
|
|
794
|
-
handler: async ({ flags }) => {
|
|
795
|
-
this.log.warn("db:seed is not yet implemented");
|
|
796
|
-
if (flags.provider) this.log.info(`Provider filter: ${flags.provider}`);
|
|
797
|
-
}
|
|
798
|
-
});
|
|
799
|
-
/**
|
|
800
|
-
* Show pending database migrations status
|
|
801
|
-
*
|
|
802
|
-
* @experimental
|
|
803
|
-
*/
|
|
804
|
-
status = (0, alepha_command.$command)({
|
|
805
|
-
name: "db:status",
|
|
806
|
-
description: "Show pending database migrations status",
|
|
807
|
-
summary: false,
|
|
808
|
-
args: alepha.t.optional(alepha.t.text({
|
|
809
|
-
title: "path",
|
|
810
|
-
description: "Path to the Alepha server entry file"
|
|
811
|
-
})),
|
|
812
|
-
flags: drizzleCommandFlags,
|
|
813
|
-
handler: async ({ flags }) => {
|
|
814
|
-
this.log.warn("db:status is not yet implemented");
|
|
815
|
-
if (flags.provider) this.log.info(`Provider filter: ${flags.provider}`);
|
|
816
|
-
}
|
|
817
|
-
});
|
|
818
|
-
};
|
|
819
|
-
|
|
820
|
-
//#endregion
|
|
821
|
-
//#region src/cli/commands/VerifyCommands.ts
|
|
822
|
-
var VerifyCommands = class {
|
|
823
|
-
processRunner = (0, alepha.$inject)(ProcessRunner);
|
|
824
|
-
utils = (0, alepha.$inject)(ProjectUtils);
|
|
825
|
-
/**
|
|
826
|
-
* Run a series of verification commands to ensure code quality and correctness.
|
|
827
|
-
*
|
|
828
|
-
* This command runs the following checks in order:
|
|
829
|
-
* - Clean the project
|
|
830
|
-
* - Format the code
|
|
831
|
-
* - Lint the code
|
|
832
|
-
* - Run tests (if Vitest is a dev dependency)
|
|
833
|
-
* - Check database migrations (if a migrations directory exists)
|
|
834
|
-
* - Type check the code
|
|
835
|
-
* - Build the project
|
|
836
|
-
* - Clean the project again
|
|
837
|
-
*/
|
|
838
|
-
verify = (0, alepha_command.$command)({
|
|
839
|
-
name: "verify",
|
|
840
|
-
description: "Verify the Alepha project",
|
|
841
|
-
handler: async ({ root, run }) => {
|
|
842
|
-
await run("alepha clean");
|
|
843
|
-
await run("alepha format");
|
|
844
|
-
await run("alepha lint");
|
|
845
|
-
await run("alepha typecheck");
|
|
846
|
-
if ((await this.utils.readPackageJson(root)).devDependencies?.vitest) await run("alepha test");
|
|
847
|
-
if (await this.utils.hasDir(root, "migrations")) await run("alepha db:migrate:check");
|
|
848
|
-
await run("alepha build");
|
|
849
|
-
await run("alepha clean");
|
|
850
|
-
}
|
|
851
|
-
});
|
|
852
|
-
/**
|
|
853
|
-
* Run TypeScript type checking across the codebase with no emit.
|
|
854
|
-
*/
|
|
855
|
-
typecheck = (0, alepha_command.$command)({
|
|
856
|
-
name: "typecheck",
|
|
857
|
-
description: "Check TypeScript types across the codebase",
|
|
858
|
-
handler: async () => {
|
|
859
|
-
await this.processRunner.exec("tsc --noEmit");
|
|
860
|
-
}
|
|
861
|
-
});
|
|
862
|
-
};
|
|
863
|
-
|
|
864
|
-
//#endregion
|
|
865
|
-
//#region src/cli/commands/ViteCommands.ts
|
|
866
|
-
var ViteCommands = class {
|
|
867
|
-
log = (0, alepha_logger.$logger)();
|
|
868
|
-
runner = (0, alepha.$inject)(ProcessRunner);
|
|
869
|
-
utils = (0, alepha.$inject)(ProjectUtils);
|
|
870
|
-
env = (0, alepha.$env)(alepha.t.object({ VITEST_ARGS: alepha.t.string({ default: "" }) }));
|
|
871
|
-
run = (0, alepha_command.$command)({
|
|
872
|
-
name: "run",
|
|
873
|
-
description: "Run a TypeScript file directly",
|
|
874
|
-
flags: alepha.t.object({ watch: alepha.t.optional(alepha.t.boolean({
|
|
875
|
-
description: "Watch file for changes",
|
|
876
|
-
alias: "w"
|
|
877
|
-
})) }),
|
|
878
|
-
summary: false,
|
|
879
|
-
args: alepha.t.text({
|
|
880
|
-
title: "path",
|
|
881
|
-
description: "Filepath to run"
|
|
882
|
-
}),
|
|
883
|
-
handler: async ({ args, flags, root }) => {
|
|
884
|
-
await this.utils.ensureTsConfig(root);
|
|
885
|
-
await this.runner.exec(`tsx ${flags.watch ? "watch " : ""}${args}`);
|
|
886
|
-
}
|
|
887
|
-
});
|
|
888
|
-
/**
|
|
889
|
-
* Will run the project in watch mode.
|
|
890
|
-
*
|
|
891
|
-
* - If an index.html file is found in the project root, it will run Vite in dev mode.
|
|
892
|
-
* - Otherwise, it will look for a server entry file and run it with tsx in watch mode.
|
|
893
|
-
*/
|
|
894
|
-
dev = (0, alepha_command.$command)({
|
|
895
|
-
name: "dev",
|
|
896
|
-
description: "Run the project in development mode",
|
|
897
|
-
args: alepha.t.optional(alepha.t.text({
|
|
898
|
-
title: "path",
|
|
899
|
-
description: "Filepath to run"
|
|
900
|
-
})),
|
|
901
|
-
handler: async ({ args, root }) => {
|
|
902
|
-
await this.utils.ensureConfig(root, {
|
|
903
|
-
viteConfigTs: true,
|
|
904
|
-
tsconfigJson: true
|
|
905
|
-
});
|
|
906
|
-
const entry = await alepha_vite.boot.getServerEntry(root, args);
|
|
907
|
-
this.log.trace("Entry file found", { entry });
|
|
908
|
-
try {
|
|
909
|
-
await (0, node_fs_promises.access)((0, node_path.join)(root, "index.html"));
|
|
910
|
-
} catch {
|
|
911
|
-
this.log.trace("No index.html found, running entry file with tsx");
|
|
912
|
-
await this.runner.exec(`tsx watch ${entry}`);
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
915
|
-
await this.runner.exec(`vite`);
|
|
916
|
-
}
|
|
917
|
-
});
|
|
918
|
-
build = (0, alepha_command.$command)({
|
|
919
|
-
name: "build",
|
|
920
|
-
description: "Build the project for production",
|
|
921
|
-
args: alepha.t.optional(alepha.t.text({
|
|
922
|
-
title: "path",
|
|
923
|
-
description: "Filepath to build"
|
|
924
|
-
})),
|
|
925
|
-
flags: alepha.t.object({
|
|
926
|
-
stats: alepha.t.optional(alepha.t.boolean({ description: "Generate build stats report" })),
|
|
927
|
-
vercel: alepha.t.optional(alepha.t.boolean({ description: "Generate Vercel deployment configuration" })),
|
|
928
|
-
cloudflare: alepha.t.optional(alepha.t.boolean({ description: "Generate Cloudflare Workers configuration" })),
|
|
929
|
-
docker: alepha.t.optional(alepha.t.boolean({ description: "Generate Docker configuration" })),
|
|
930
|
-
sitemap: alepha.t.optional(alepha.t.text({ description: "Generate sitemap.xml with base URL" })),
|
|
931
|
-
prerender: alepha.t.optional(alepha.t.boolean({ description: "Pre-render static pages" }))
|
|
932
|
-
}),
|
|
933
|
-
handler: async ({ flags, args, run, root }) => {
|
|
934
|
-
process.env.ALEPHA_BUILD_MODE = "cli";
|
|
935
|
-
await this.utils.ensureConfig(root, {
|
|
936
|
-
viteConfigTs: true,
|
|
937
|
-
tsconfigJson: true
|
|
938
|
-
});
|
|
939
|
-
const entry = await alepha_vite.boot.getServerEntry(root, args);
|
|
940
|
-
this.log.trace("Entry file found", { entry });
|
|
941
|
-
const distDir = "dist";
|
|
942
|
-
const clientDir = "public";
|
|
943
|
-
await run.rm("dist", { alias: "clean dist" });
|
|
944
|
-
const viteAlephaBuildOptions = (await import((0, node_path.join)(root, "vite.config.ts")))?.default?.plugins.find((it) => !!it[alepha.OPTIONS])?.[alepha.OPTIONS] ?? {};
|
|
945
|
-
const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;
|
|
946
|
-
let hasClient = false;
|
|
947
|
-
try {
|
|
948
|
-
await (0, node_fs_promises.access)((0, node_path.join)(root, "index.html"));
|
|
949
|
-
hasClient = true;
|
|
950
|
-
} catch {}
|
|
951
|
-
if (hasClient) await run({
|
|
952
|
-
name: "vite build client",
|
|
953
|
-
handler: () => (0, alepha_vite.buildClient)({
|
|
954
|
-
silent: true,
|
|
955
|
-
dist: `${distDir}/${clientDir}`,
|
|
956
|
-
stats
|
|
957
|
-
})
|
|
958
|
-
});
|
|
959
|
-
await run({
|
|
960
|
-
name: "vite build server",
|
|
961
|
-
handler: async () => {
|
|
962
|
-
let clientBuilt = false;
|
|
963
|
-
try {
|
|
964
|
-
await (0, node_fs_promises.readFile)(`${distDir}/${clientDir}/index.html`, "utf-8");
|
|
965
|
-
clientBuilt = true;
|
|
966
|
-
} catch {}
|
|
967
|
-
await (0, alepha_vite.buildServer)({
|
|
968
|
-
silent: true,
|
|
969
|
-
entry,
|
|
970
|
-
distDir,
|
|
971
|
-
clientDir: clientBuilt ? clientDir : void 0,
|
|
972
|
-
stats
|
|
973
|
-
});
|
|
974
|
-
if (clientBuilt) await (0, node_fs_promises.unlink)(`${distDir}/${clientDir}/index.html`);
|
|
975
|
-
}
|
|
976
|
-
});
|
|
977
|
-
await run({
|
|
978
|
-
name: "copy assets",
|
|
979
|
-
handler: () => (0, alepha_vite.copyAssets)({
|
|
980
|
-
entry: `${distDir}/index.js`,
|
|
981
|
-
distDir
|
|
982
|
-
})
|
|
983
|
-
});
|
|
984
|
-
if (hasClient) {
|
|
985
|
-
const sitemapBaseUrl = flags.sitemap ?? (typeof viteAlephaBuildOptions.client === "object" ? viteAlephaBuildOptions.client.sitemap?.hostname : void 0);
|
|
986
|
-
if (sitemapBaseUrl) await run({
|
|
987
|
-
name: "add sitemap",
|
|
988
|
-
handler: async () => {
|
|
989
|
-
await (0, node_fs_promises.writeFile)(`${distDir}/${clientDir}/sitemap.xml`, await (0, alepha_vite.generateSitemap)({
|
|
990
|
-
entry: `${distDir}/index.js`,
|
|
991
|
-
baseUrl: sitemapBaseUrl
|
|
992
|
-
}));
|
|
993
|
-
}
|
|
994
|
-
});
|
|
995
|
-
if (flags.prerender ?? (typeof viteAlephaBuildOptions.client === "object" ? viteAlephaBuildOptions.client.prerender : false)) await run({
|
|
996
|
-
name: "pre-render pages",
|
|
997
|
-
handler: async () => {
|
|
998
|
-
await (0, alepha_vite.prerenderPages)({
|
|
999
|
-
dist: `${distDir}/${clientDir}`,
|
|
1000
|
-
entry: `${distDir}/index.js`
|
|
1001
|
-
});
|
|
1002
|
-
}
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1005
|
-
if (flags.vercel || viteAlephaBuildOptions.vercel) {
|
|
1006
|
-
const config = typeof viteAlephaBuildOptions.vercel === "object" ? viteAlephaBuildOptions.vercel : {};
|
|
1007
|
-
await run({
|
|
1008
|
-
name: "add Vercel config",
|
|
1009
|
-
handler: () => (0, alepha_vite.generateVercel)({
|
|
1010
|
-
distDir,
|
|
1011
|
-
clientDir,
|
|
1012
|
-
config
|
|
1013
|
-
})
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
if (flags.cloudflare || viteAlephaBuildOptions.cloudflare) await run({
|
|
1017
|
-
name: "add Cloudflare config",
|
|
1018
|
-
handler: () => (0, alepha_vite.generateCloudflare)({ distDir })
|
|
1019
|
-
});
|
|
1020
|
-
if (flags.docker || viteAlephaBuildOptions.docker) {
|
|
1021
|
-
const dockerConfig = typeof viteAlephaBuildOptions.docker === "object" ? viteAlephaBuildOptions.docker : {};
|
|
1022
|
-
await run({
|
|
1023
|
-
name: "add Docker config",
|
|
1024
|
-
handler: () => (0, alepha_vite.generateDocker)({
|
|
1025
|
-
distDir,
|
|
1026
|
-
...dockerConfig
|
|
1027
|
-
})
|
|
1028
|
-
});
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
});
|
|
1032
|
-
test = (0, alepha_command.$command)({
|
|
1033
|
-
name: "test",
|
|
1034
|
-
description: "Run tests using Vitest",
|
|
1035
|
-
handler: async ({ root }) => {
|
|
1036
|
-
await this.utils.ensureConfig(root, {
|
|
1037
|
-
tsconfigJson: true,
|
|
1038
|
-
viteConfigTs: true
|
|
1039
|
-
});
|
|
1040
|
-
try {
|
|
1041
|
-
await Promise.resolve().then(() => require("./dist-Sz2EXvQX.cjs"));
|
|
1042
|
-
} catch {
|
|
1043
|
-
this.log.error("Vitest is not installed. Please install it with `npm install -D vitest` or `yarn add -D vitest`.");
|
|
1044
|
-
process.exit(1);
|
|
1045
|
-
}
|
|
1046
|
-
await this.runner.exec(`vitest run ${this.env.VITEST_ARGS}`);
|
|
1047
|
-
}
|
|
1048
|
-
});
|
|
1049
|
-
};
|
|
1050
|
-
|
|
1051
|
-
//#endregion
|
|
1052
|
-
//#region src/cli/apps/AlephaCli.ts
|
|
1053
|
-
const AlephaCli = (0, alepha.$module)({
|
|
1054
|
-
name: "alepha.cli",
|
|
1055
|
-
services: [
|
|
1056
|
-
ProcessRunner,
|
|
1057
|
-
CoreCommands,
|
|
1058
|
-
DrizzleCommands,
|
|
1059
|
-
VerifyCommands,
|
|
1060
|
-
ViteCommands,
|
|
1061
|
-
BiomeCommands
|
|
1062
|
-
]
|
|
1063
|
-
});
|
|
1064
|
-
|
|
1065
|
-
//#endregion
|
|
1066
|
-
//#region src/cli/apps/AlephaPackageBuilderCli.ts
|
|
1067
|
-
var AlephaPackageBuilderCli = class {
|
|
1068
|
-
src = "src";
|
|
1069
|
-
dist = "dist";
|
|
1070
|
-
fs = (0, alepha.$inject)(alepha_file.FileSystemProvider);
|
|
1071
|
-
make = (0, alepha_command.$command)({
|
|
1072
|
-
root: true,
|
|
1073
|
-
handler: async ({ run, root }) => {
|
|
1074
|
-
const modules = [];
|
|
1075
|
-
const pkg = await (0, node_fs_promises.readFile)("package.json", "utf-8");
|
|
1076
|
-
const pkgData = JSON.parse(pkg);
|
|
1077
|
-
const packageName = pkgData.name;
|
|
1078
|
-
await run("analyze modules", async () => {
|
|
1079
|
-
modules.push(...await analyzeModules((0, node_path.join)(root, this.src), packageName));
|
|
1080
|
-
});
|
|
1081
|
-
pkgData.exports = {};
|
|
1082
|
-
for (const item of modules) {
|
|
1083
|
-
const path = item.name === "core" ? "." : `./${item.name.replace("-", "/")}`;
|
|
1084
|
-
pkgData.exports[path] = {};
|
|
1085
|
-
pkgData.exports[path].types = `./src/${item.name}/index.ts`;
|
|
1086
|
-
if (item.browser) pkgData.exports[path].browser = `./src/${item.name}/index.browser.ts`;
|
|
1087
|
-
pkgData.exports[path].import = `./src/${item.name}/index.ts`;
|
|
1088
|
-
pkgData.exports[path].require = `./src/${item.name}/index.ts`;
|
|
1089
|
-
}
|
|
1090
|
-
if (packageName === "alepha") {
|
|
1091
|
-
pkgData.exports["./tsconfig.base"] = "./tsconfig.base.json";
|
|
1092
|
-
pkgData.exports["./package.json"] = "./package.json";
|
|
1093
|
-
}
|
|
1094
|
-
if (packageName === "@alepha/ui") pkgData.exports["./styles"] = "./styles.css";
|
|
1095
|
-
await this.fs.writeFile("package.json", JSON.stringify(pkgData, null, 2));
|
|
1096
|
-
const tmpDir = (0, node_path.join)(root, "node_modules/.alepha");
|
|
1097
|
-
await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});
|
|
1098
|
-
await this.fs.writeFile((0, node_path.join)(tmpDir, "module-dependencies.json"), JSON.stringify(modules, null, 2));
|
|
1099
|
-
const external = ["alepha", ...modules.map((item) => `alepha/${item.name}`)];
|
|
1100
|
-
await run.rm(this.dist);
|
|
1101
|
-
const build = async (item) => {
|
|
1102
|
-
const entries = [];
|
|
1103
|
-
const src = (0, node_path.join)(root, this.src, item.name);
|
|
1104
|
-
const dest = (0, node_path.join)(root, this.dist, item.name);
|
|
1105
|
-
entries.push({
|
|
1106
|
-
entry: (0, node_path.join)(src, "index.ts"),
|
|
1107
|
-
outDir: dest,
|
|
1108
|
-
format: ["esm", "cjs"],
|
|
1109
|
-
sourcemap: true,
|
|
1110
|
-
fixedExtension: false,
|
|
1111
|
-
platform: "node",
|
|
1112
|
-
external
|
|
1113
|
-
});
|
|
1114
|
-
if (item.browser) entries.push({
|
|
1115
|
-
entry: (0, node_path.join)(src, "index.browser.ts"),
|
|
1116
|
-
outDir: dest,
|
|
1117
|
-
platform: "browser",
|
|
1118
|
-
sourcemap: true,
|
|
1119
|
-
dts: false,
|
|
1120
|
-
external
|
|
1121
|
-
});
|
|
1122
|
-
const config = (0, node_path.join)(tmpDir, `tsdown-${item.name}.config.js`);
|
|
1123
|
-
await this.fs.writeFile(config, `export default ${JSON.stringify(entries, null, 2)};`);
|
|
1124
|
-
await run(`npx tsdown -c=${config}`);
|
|
1125
|
-
await this.fs.rm(config);
|
|
1126
|
-
};
|
|
1127
|
-
const concurrency = Math.ceil(node_os.cpus().length / 2);
|
|
1128
|
-
const queue = modules.slice();
|
|
1129
|
-
const workers = [];
|
|
1130
|
-
for (let i = 0; i < concurrency; i++) {
|
|
1131
|
-
const worker = (async () => {
|
|
1132
|
-
while (queue.length > 0) {
|
|
1133
|
-
const item = queue.shift();
|
|
1134
|
-
if (item) await build(item);
|
|
1135
|
-
else await new Promise((r) => setTimeout(r, 100));
|
|
1136
|
-
}
|
|
1137
|
-
})();
|
|
1138
|
-
workers.push(worker);
|
|
1139
|
-
}
|
|
1140
|
-
await Promise.all(workers);
|
|
1141
|
-
}
|
|
1142
|
-
});
|
|
1143
|
-
};
|
|
1144
|
-
async function getAllFiles(dir) {
|
|
1145
|
-
const files = [];
|
|
1146
|
-
async function scan(currentDir) {
|
|
1147
|
-
const entries = await (0, node_fs_promises.readdir)(currentDir, { withFileTypes: true });
|
|
1148
|
-
for (const entry of entries) {
|
|
1149
|
-
const fullPath = (0, node_path.join)(currentDir, entry.name);
|
|
1150
|
-
if (entry.isDirectory()) await scan(fullPath);
|
|
1151
|
-
else if (entry.isFile() && /\.(ts|tsx)$/.test(entry.name)) files.push(fullPath);
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
await scan(dir);
|
|
1155
|
-
return files;
|
|
1156
|
-
}
|
|
1157
|
-
function removeComments(content) {
|
|
1158
|
-
let cleaned = content.replace(/\/\/.*$/gm, "");
|
|
1159
|
-
cleaned = cleaned.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
1160
|
-
return cleaned;
|
|
1161
|
-
}
|
|
1162
|
-
function extractAlephaDependencies(content, packageName, moduleName) {
|
|
1163
|
-
const deps = /* @__PURE__ */ new Set();
|
|
1164
|
-
const cleanedContent = removeComments(content);
|
|
1165
|
-
const importRegex = new RegExp(`from "${packageName}/([a-zA-Z0-9_/]+)";`, "g");
|
|
1166
|
-
const matches = cleanedContent.matchAll(importRegex);
|
|
1167
|
-
for (const match of matches) deps.add(match[1]);
|
|
1168
|
-
return Array.from(deps);
|
|
1169
|
-
}
|
|
1170
|
-
async function fileExists(path) {
|
|
1171
|
-
try {
|
|
1172
|
-
await (0, node_fs_promises.access)(path);
|
|
1173
|
-
return true;
|
|
1174
|
-
} catch {
|
|
1175
|
-
return false;
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
function detectCircularDependencies(modules) {
|
|
1179
|
-
const moduleMap = new Map(modules.map((m) => [m.name, m.dependencies]));
|
|
1180
|
-
function hasCycle(moduleName, visited = /* @__PURE__ */ new Set(), path = []) {
|
|
1181
|
-
if (visited.has(moduleName)) {
|
|
1182
|
-
const cycleStart = path.indexOf(moduleName);
|
|
1183
|
-
return [...path.slice(cycleStart), moduleName];
|
|
1184
|
-
}
|
|
1185
|
-
const deps = moduleMap.get(moduleName);
|
|
1186
|
-
if (!deps) return null;
|
|
1187
|
-
visited.add(moduleName);
|
|
1188
|
-
path.push(moduleName);
|
|
1189
|
-
for (const dep of deps) {
|
|
1190
|
-
const cycle = hasCycle(dep, new Set(visited), [...path]);
|
|
1191
|
-
if (cycle) return cycle;
|
|
1192
|
-
}
|
|
1193
|
-
return null;
|
|
1194
|
-
}
|
|
1195
|
-
for (const module$1 of modules) {
|
|
1196
|
-
const cycle = hasCycle(module$1.name);
|
|
1197
|
-
if (cycle) throw new Error(`Circular dependency detected: ${cycle.join(" -> ")}`);
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
async function analyzeModules(srcDir, packageName) {
|
|
1201
|
-
const modules = [];
|
|
1202
|
-
const entries = await (0, node_fs_promises.readdir)(srcDir, { withFileTypes: true });
|
|
1203
|
-
for (const entry of entries) if (entry.isDirectory()) {
|
|
1204
|
-
const moduleName = entry.name;
|
|
1205
|
-
const modulePath = (0, node_path.join)(srcDir, moduleName);
|
|
1206
|
-
const dependencies = /* @__PURE__ */ new Set();
|
|
1207
|
-
const hasBrowser = await fileExists((0, node_path.join)(modulePath, "index.browser.ts"));
|
|
1208
|
-
const hasNode = await fileExists((0, node_path.join)(modulePath, "index.node.ts"));
|
|
1209
|
-
const files = await getAllFiles(modulePath);
|
|
1210
|
-
for (const file of files) {
|
|
1211
|
-
const deps = extractAlephaDependencies(await (0, node_fs_promises.readFile)(file, "utf-8"), packageName, moduleName);
|
|
1212
|
-
for (const dep of deps) {
|
|
1213
|
-
if (dep.endsWith(".ts")) throw new Error(`Invalid dependency '${dep}' in module '${moduleName}'. Do not include file extensions in Alepha module imports.`);
|
|
1214
|
-
if (dep.includes("-")) throw new Error(`Invalid dependency '${dep}' in module '${moduleName}'. Use '/' instead of '-' in Alepha module imports.`);
|
|
1215
|
-
dependencies.add(dep);
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
const module$1 = {
|
|
1219
|
-
name: moduleName,
|
|
1220
|
-
dependencies: Array.from(dependencies)
|
|
1221
|
-
};
|
|
1222
|
-
if (hasBrowser) module$1.browser = true;
|
|
1223
|
-
if (hasNode) module$1.node = true;
|
|
1224
|
-
modules.push(module$1);
|
|
1225
|
-
}
|
|
1226
|
-
detectCircularDependencies(modules);
|
|
1227
|
-
return modules;
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
//#endregion
|
|
1231
|
-
exports.AlephaCli = AlephaCli;
|
|
1232
|
-
exports.AlephaPackageBuilderCli = AlephaPackageBuilderCli;
|
|
1233
|
-
exports.BiomeCommands = BiomeCommands;
|
|
1234
|
-
exports.CoreCommands = CoreCommands;
|
|
1235
|
-
exports.DrizzleCommands = DrizzleCommands;
|
|
1236
|
-
exports.ProjectUtils = ProjectUtils;
|
|
1237
|
-
exports.VerifyCommands = VerifyCommands;
|
|
1238
|
-
exports.ViteCommands = ViteCommands;
|
|
1239
|
-
exports.analyzeModules = analyzeModules;
|
|
1240
|
-
exports.version = version;
|
|
1241
|
-
//# sourceMappingURL=index.cjs.map
|