alepha 0.14.0 → 0.14.2
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 +3 -3
- package/dist/api/audits/index.d.ts +80 -1
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +80 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +236 -157
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +21 -1
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +451 -4
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.d.ts +252 -249
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +4 -0
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +128 -128
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.js.map +1 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cli/index.d.ts +304 -115
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +650 -531
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +210 -13
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +306 -69
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +7 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +7 -6
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.js.map +1 -1
- package/dist/fake/index.js.map +1 -1
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js.map +1 -1
- package/dist/lock/redis/index.js.map +1 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.browser.js +26 -5
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.d.ts +294 -215
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +522 -523
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/redis/index.js +2 -4
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/redis/index.d.ts +400 -29
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +412 -21
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.js.map +1 -1
- package/dist/router/index.js.map +1 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +155 -155
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/cookies/index.browser.js.map +1 -1
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +0 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/helmet/index.d.ts +4 -1
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/helmet/index.js.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/security/index.d.ts +9 -9
- package/dist/server/security/index.js.map +1 -1
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.js.map +1 -1
- package/dist/topic/redis/index.js +3 -3
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/vite/index.js +9 -6
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +7 -7
- package/dist/websocket/index.js.map +1 -1
- package/package.json +3 -3
- package/src/api/users/index.ts +4 -0
- package/src/cli/apps/AlephaCli.ts +36 -14
- package/src/cli/apps/AlephaPackageBuilderCli.ts +5 -1
- package/src/cli/assets/appRouterTs.ts +1 -1
- package/src/cli/atoms/changelogOptions.ts +45 -0
- package/src/cli/commands/{ViteCommands.ts → build.ts} +4 -93
- package/src/cli/commands/changelog.ts +244 -0
- package/src/cli/commands/clean.ts +14 -0
- package/src/cli/commands/{DrizzleCommands.ts → db.ts} +37 -124
- package/src/cli/commands/deploy.ts +118 -0
- package/src/cli/commands/dev.ts +57 -0
- package/src/cli/commands/format.ts +17 -0
- package/src/cli/commands/{CoreCommands.ts → init.ts} +2 -40
- package/src/cli/commands/lint.ts +17 -0
- package/src/cli/commands/root.ts +32 -0
- package/src/cli/commands/run.ts +24 -0
- package/src/cli/commands/test.ts +42 -0
- package/src/cli/commands/typecheck.ts +19 -0
- package/src/cli/commands/{VerifyCommands.ts → verify.ts} +1 -13
- package/src/cli/defineConfig.ts +24 -0
- package/src/cli/index.ts +17 -5
- package/src/cli/services/AlephaCliUtils.ts +4 -21
- package/src/cli/services/GitMessageParser.ts +77 -0
- package/src/command/helpers/EnvUtils.ts +37 -0
- package/src/command/index.ts +3 -1
- package/src/command/primitives/$command.ts +172 -6
- package/src/command/providers/CliProvider.ts +424 -91
- package/src/core/Alepha.ts +8 -5
- package/src/file/providers/NodeFileSystemProvider.ts +3 -1
- package/src/orm/index.browser.ts +1 -1
- package/src/orm/index.ts +18 -10
- package/src/orm/interfaces/PgQueryWhere.ts +1 -26
- package/src/orm/providers/{PostgresTypeProvider.ts → DatabaseTypeProvider.ts} +25 -3
- package/src/orm/providers/drivers/BunPostgresProvider.ts +225 -0
- package/src/orm/providers/drivers/BunSqliteProvider.ts +180 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +25 -0
- package/src/orm/providers/drivers/NodePostgresProvider.ts +0 -25
- package/src/orm/services/QueryManager.ts +10 -125
- package/src/queue/redis/providers/RedisQueueProvider.ts +2 -7
- package/src/redis/index.ts +65 -3
- package/src/redis/providers/BunRedisProvider.ts +304 -0
- package/src/redis/providers/BunRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/NodeRedisProvider.ts +280 -0
- package/src/redis/providers/NodeRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/RedisProvider.ts +134 -140
- package/src/redis/providers/RedisSubscriberProvider.ts +58 -49
- package/src/server/core/providers/BunHttpServerProvider.ts +0 -3
- package/src/server/core/providers/ServerBodyParserProvider.ts +3 -1
- package/src/server/core/providers/ServerProvider.ts +7 -4
- package/src/server/multipart/providers/ServerMultipartProvider.ts +3 -1
- package/src/server/proxy/providers/ServerProxyProvider.ts +1 -1
- package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
- package/src/vite/tasks/buildServer.ts +1 -0
- package/src/cli/commands/BiomeCommands.ts +0 -29
- package/src/cli/commands/ChangelogCommands.ts +0 -389
- package/src/orm/services/PgJsonQueryManager.ts +0 -511
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import { $logger } from "alepha/logger";
|
|
17
17
|
import { CommandError } from "../errors/CommandError.ts";
|
|
18
18
|
import { Asker } from "../helpers/Asker.ts";
|
|
19
|
+
import { EnvUtils } from "../helpers/EnvUtils.ts";
|
|
19
20
|
import { Runner } from "../helpers/Runner.ts";
|
|
20
21
|
import {
|
|
21
22
|
$command,
|
|
@@ -81,6 +82,7 @@ export class CliProvider {
|
|
|
81
82
|
protected readonly log = $logger();
|
|
82
83
|
protected readonly runner = $inject(Runner);
|
|
83
84
|
protected readonly asker = $inject(Asker);
|
|
85
|
+
protected readonly envUtils = $inject(EnvUtils);
|
|
84
86
|
|
|
85
87
|
protected readonly options = $use(cliOptions);
|
|
86
88
|
|
|
@@ -111,8 +113,12 @@ export class CliProvider {
|
|
|
111
113
|
on: "ready",
|
|
112
114
|
handler: async () => {
|
|
113
115
|
const argv = [...this.argv];
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
|
|
117
|
+
// Extract positional arguments (potential command path)
|
|
118
|
+
const positionalArgs = argv.filter((arg) => !arg.startsWith("-"));
|
|
119
|
+
|
|
120
|
+
// Resolve command using the new resolution logic
|
|
121
|
+
const { command, consumedArgs } = this.resolveCommand(positionalArgs);
|
|
116
122
|
|
|
117
123
|
const globalFlags = this.parseFlags(
|
|
118
124
|
argv,
|
|
@@ -128,74 +134,199 @@ export class CliProvider {
|
|
|
128
134
|
}
|
|
129
135
|
|
|
130
136
|
if (!command) {
|
|
131
|
-
//
|
|
137
|
+
// Check if there's a root command (name === "")
|
|
132
138
|
const rootCommand = this.findCommand("");
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
139
|
+
|
|
140
|
+
// If we have positional args but no matching command, show error
|
|
141
|
+
const commandName = positionalArgs[0] ?? "";
|
|
142
|
+
if (commandName !== "" && !rootCommand?.options.args) {
|
|
143
|
+
this.log.error(`Unknown command: '${commandName}'`);
|
|
144
|
+
this.printHelp();
|
|
140
145
|
return;
|
|
141
146
|
}
|
|
142
|
-
}
|
|
143
147
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
command.name === "",
|
|
149
|
-
command.flags,
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
await this.alepha.context.run(async () => {
|
|
153
|
-
this.log.debug(`Executing command '${command.name}'...`, {
|
|
154
|
-
flags: commandFlags,
|
|
155
|
-
args: commandArgs,
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
const runner = this.runner;
|
|
159
|
-
|
|
160
|
-
// Start command session for pretty print
|
|
161
|
-
runner.startCommand(this.name, command.name);
|
|
162
|
-
|
|
163
|
-
const args = {
|
|
164
|
-
flags: commandFlags,
|
|
165
|
-
args: commandArgs,
|
|
166
|
-
run: runner.run,
|
|
167
|
-
ask: this.asker.ask,
|
|
168
|
-
fs,
|
|
169
|
-
glob,
|
|
170
|
-
root: process.cwd(),
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// Execute pre-hooks
|
|
174
|
-
const preHooks = this.findPreHooks(command.name);
|
|
175
|
-
for (const hook of preHooks) {
|
|
176
|
-
this.log.debug(`Executing pre-hook for '${command.name}'...`);
|
|
177
|
-
await hook.options.handler(args as CommandHandlerArgs<TObject>);
|
|
148
|
+
// Execute root command if it exists
|
|
149
|
+
if (rootCommand) {
|
|
150
|
+
await this.executeCommand(rootCommand, argv, true);
|
|
151
|
+
return;
|
|
178
152
|
}
|
|
179
153
|
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
// Execute post-hooks
|
|
184
|
-
const postHooks = this.findPostHooks(command.name);
|
|
185
|
-
for (const hook of postHooks) {
|
|
186
|
-
this.log.debug(`Executing post-hook for '${command.name}'...`);
|
|
187
|
-
await hook.options.handler(args as CommandHandlerArgs<TObject>);
|
|
188
|
-
}
|
|
154
|
+
// No command found and no root command
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
189
157
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
158
|
+
// Remove consumed command path args from argv for argument parsing
|
|
159
|
+
const remainingArgv = this.removeConsumedArgs(argv, consumedArgs);
|
|
193
160
|
|
|
194
|
-
|
|
195
|
-
|
|
161
|
+
// Since we've removed the command path, treat it like a root command for parsing
|
|
162
|
+
await this.executeCommand(command, remainingArgv, true);
|
|
196
163
|
},
|
|
197
164
|
});
|
|
198
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Execute a command with the given argv.
|
|
168
|
+
*/
|
|
169
|
+
protected async executeCommand(
|
|
170
|
+
command: CommandPrimitive<TObject>,
|
|
171
|
+
argv: string[],
|
|
172
|
+
isRootCommand: boolean,
|
|
173
|
+
): Promise<void> {
|
|
174
|
+
const root = process.cwd();
|
|
175
|
+
|
|
176
|
+
// Handle --mode flag if command has mode option enabled
|
|
177
|
+
let modeValue: string | undefined;
|
|
178
|
+
if (command.options.mode) {
|
|
179
|
+
modeValue = this.parseModeFlag(argv);
|
|
180
|
+
// Use default mode if not provided and mode is a string
|
|
181
|
+
if (modeValue === undefined && typeof command.options.mode === "string") {
|
|
182
|
+
modeValue = command.options.mode;
|
|
183
|
+
}
|
|
184
|
+
await this.loadModeEnv(root, modeValue);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const commandFlags = this.parseCommandFlags(argv, command.flags);
|
|
188
|
+
const commandArgs = this.parseCommandArgs(
|
|
189
|
+
argv,
|
|
190
|
+
command.options.args,
|
|
191
|
+
isRootCommand,
|
|
192
|
+
command.flags,
|
|
193
|
+
);
|
|
194
|
+
const commandEnv = this.parseCommandEnv(command.env, command.name);
|
|
195
|
+
|
|
196
|
+
await this.alepha.context.run(async () => {
|
|
197
|
+
this.log.debug(`Executing command '${command.name}'...`, {
|
|
198
|
+
flags: commandFlags,
|
|
199
|
+
args: commandArgs,
|
|
200
|
+
mode: modeValue,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const runner = this.runner;
|
|
204
|
+
|
|
205
|
+
// Start command session for pretty print
|
|
206
|
+
runner.startCommand(this.name, command.name);
|
|
207
|
+
|
|
208
|
+
const args = {
|
|
209
|
+
flags: commandFlags,
|
|
210
|
+
args: commandArgs,
|
|
211
|
+
env: commandEnv,
|
|
212
|
+
run: runner.run,
|
|
213
|
+
ask: this.asker.ask,
|
|
214
|
+
fs,
|
|
215
|
+
glob,
|
|
216
|
+
root,
|
|
217
|
+
help: () => this.printHelp(command),
|
|
218
|
+
mode: modeValue,
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Execute pre-hooks
|
|
222
|
+
const preHooks = this.findPreHooks(command.name);
|
|
223
|
+
for (const hook of preHooks) {
|
|
224
|
+
this.log.debug(`Executing pre-hook for '${command.name}'...`);
|
|
225
|
+
await hook.options.handler(args as CommandHandlerArgs<TObject>);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Execute main command
|
|
229
|
+
await command.options.handler(args as CommandHandlerArgs<TObject>);
|
|
230
|
+
|
|
231
|
+
// Execute post-hooks
|
|
232
|
+
const postHooks = this.findPostHooks(command.name);
|
|
233
|
+
for (const hook of postHooks) {
|
|
234
|
+
this.log.debug(`Executing post-hook for '${command.name}'...`);
|
|
235
|
+
await hook.options.handler(args as CommandHandlerArgs<TObject>);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (command.options.summary !== false) {
|
|
239
|
+
runner.summary();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this.log.debug(`Command '${command.name}' executed successfully.`);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Remove consumed command path arguments from argv.
|
|
248
|
+
*/
|
|
249
|
+
protected removeConsumedArgs(
|
|
250
|
+
argv: string[],
|
|
251
|
+
consumedArgs: string[],
|
|
252
|
+
): string[] {
|
|
253
|
+
const result: string[] = [];
|
|
254
|
+
let consumedIndex = 0;
|
|
255
|
+
|
|
256
|
+
for (const arg of argv) {
|
|
257
|
+
if (arg.startsWith("-")) {
|
|
258
|
+
result.push(arg);
|
|
259
|
+
} else if (
|
|
260
|
+
consumedIndex < consumedArgs.length &&
|
|
261
|
+
arg === consumedArgs[consumedIndex]
|
|
262
|
+
) {
|
|
263
|
+
consumedIndex++;
|
|
264
|
+
// Skip this arg, it's part of the command path
|
|
265
|
+
} else {
|
|
266
|
+
result.push(arg);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Resolve a command from positional arguments.
|
|
275
|
+
*
|
|
276
|
+
* Supports:
|
|
277
|
+
* 1. Space-separated subcommands: `deploy vercel` -> finds deploy command, then vercel child
|
|
278
|
+
* 2. Colon notation (backwards compat): `deploy:vercel` -> finds command with name "deploy:vercel"
|
|
279
|
+
* 3. Simple commands: `build` -> finds command with name "build"
|
|
280
|
+
*/
|
|
281
|
+
protected resolveCommand(positionalArgs: string[]): {
|
|
282
|
+
command: CommandPrimitive<TObject> | undefined;
|
|
283
|
+
consumedArgs: string[];
|
|
284
|
+
} {
|
|
285
|
+
if (positionalArgs.length === 0) {
|
|
286
|
+
return { command: undefined, consumedArgs: [] };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const firstArg = positionalArgs[0];
|
|
290
|
+
|
|
291
|
+
// First, try colon notation for backwards compatibility (e.g., "deploy:vercel")
|
|
292
|
+
if (firstArg.includes(":")) {
|
|
293
|
+
const command = this.findCommand(firstArg);
|
|
294
|
+
if (command) {
|
|
295
|
+
return { command, consumedArgs: [firstArg] };
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Try to find command with space-separated subcommand path
|
|
300
|
+
let currentCommand = this.findCommand(firstArg);
|
|
301
|
+
const consumedArgs: string[] = [];
|
|
302
|
+
|
|
303
|
+
if (!currentCommand) {
|
|
304
|
+
return { command: undefined, consumedArgs: [] };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
consumedArgs.push(firstArg);
|
|
308
|
+
|
|
309
|
+
// Walk through remaining args to find nested subcommands
|
|
310
|
+
for (let i = 1; i < positionalArgs.length; i++) {
|
|
311
|
+
const arg = positionalArgs[i];
|
|
312
|
+
|
|
313
|
+
if (!currentCommand.hasChildren) {
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const childCommand = currentCommand.findChild(arg);
|
|
318
|
+
if (childCommand) {
|
|
319
|
+
currentCommand = childCommand;
|
|
320
|
+
consumedArgs.push(arg);
|
|
321
|
+
} else {
|
|
322
|
+
// No matching child, stop here
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return { command: currentCommand, consumedArgs };
|
|
328
|
+
}
|
|
329
|
+
|
|
199
330
|
public get commands(): CommandPrimitive<any>[] {
|
|
200
331
|
return this.alepha.primitives($command);
|
|
201
332
|
}
|
|
@@ -221,35 +352,13 @@ export class CliProvider {
|
|
|
221
352
|
}
|
|
222
353
|
|
|
223
354
|
/**
|
|
224
|
-
* Get
|
|
355
|
+
* Get global flags (help only, root command flags are NOT global).
|
|
225
356
|
*/
|
|
226
357
|
protected getAllGlobalFlags(): Record<
|
|
227
358
|
string,
|
|
228
359
|
{ aliases: string[]; description?: string; schema: TSchema }
|
|
229
360
|
> {
|
|
230
|
-
|
|
231
|
-
const allGlobalFlags: Record<
|
|
232
|
-
string,
|
|
233
|
-
{ aliases: string[]; description?: string; schema: TSchema }
|
|
234
|
-
> = { ...this.globalFlags };
|
|
235
|
-
|
|
236
|
-
if (rootCommand) {
|
|
237
|
-
// Add root command flags to global flags
|
|
238
|
-
for (const [key, value] of Object.entries(rootCommand.flags.properties)) {
|
|
239
|
-
allGlobalFlags[key] = {
|
|
240
|
-
aliases: [
|
|
241
|
-
key,
|
|
242
|
-
...((value as any).aliases ??
|
|
243
|
-
((value as any).alias ? [(value as any).alias] : undefined) ??
|
|
244
|
-
[]),
|
|
245
|
-
],
|
|
246
|
-
description: (value as any).description,
|
|
247
|
-
schema: value as TSchema,
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return allGlobalFlags;
|
|
361
|
+
return { ...this.globalFlags };
|
|
253
362
|
}
|
|
254
363
|
|
|
255
364
|
protected parseCommandFlags(
|
|
@@ -292,6 +401,87 @@ export class CliProvider {
|
|
|
292
401
|
}
|
|
293
402
|
}
|
|
294
403
|
|
|
404
|
+
protected parseCommandEnv(
|
|
405
|
+
schema: TObject,
|
|
406
|
+
commandName: string,
|
|
407
|
+
): Record<string, any> {
|
|
408
|
+
const result: Record<string, any> = {};
|
|
409
|
+
const missing: string[] = [];
|
|
410
|
+
|
|
411
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
412
|
+
const value = process.env[key];
|
|
413
|
+
|
|
414
|
+
if (value !== undefined) {
|
|
415
|
+
result[key] = value;
|
|
416
|
+
} else if (t.schema.isOptional(propSchema)) {
|
|
417
|
+
// Check for default value
|
|
418
|
+
if ("default" in propSchema) {
|
|
419
|
+
result[key] = propSchema.default;
|
|
420
|
+
}
|
|
421
|
+
} else {
|
|
422
|
+
missing.push(key);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (missing.length > 0) {
|
|
427
|
+
const vars = missing.join(", ");
|
|
428
|
+
throw new CommandError(
|
|
429
|
+
`Missing required environment variable${missing.length > 1 ? "s" : ""}: ${vars}`,
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
try {
|
|
434
|
+
return this.alepha.codec.decode(schema, result);
|
|
435
|
+
} catch (error) {
|
|
436
|
+
if (error instanceof TypeBoxError) {
|
|
437
|
+
throw new CommandError(
|
|
438
|
+
`Invalid environment variable: ${error.cause.instancePath || "env"} ${error.cause.message}`,
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
throw error;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Parse --mode or -m flag from argv.
|
|
447
|
+
*/
|
|
448
|
+
protected parseModeFlag(argv: string[]): string | undefined {
|
|
449
|
+
for (let i = 0; i < argv.length; i++) {
|
|
450
|
+
const arg = argv[i];
|
|
451
|
+
|
|
452
|
+
// Handle --mode=value or -m=value
|
|
453
|
+
if (arg.startsWith("--mode=") || arg.startsWith("-m=")) {
|
|
454
|
+
return arg.split("=")[1];
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Handle --mode value or -m value
|
|
458
|
+
if (arg === "--mode" || arg === "-m") {
|
|
459
|
+
const nextArg = argv[i + 1];
|
|
460
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
461
|
+
return nextArg;
|
|
462
|
+
}
|
|
463
|
+
throw new CommandError("Flag --mode requires a value.");
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return undefined;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Load environment files based on mode.
|
|
472
|
+
*/
|
|
473
|
+
protected async loadModeEnv(
|
|
474
|
+
root: string,
|
|
475
|
+
mode: string | undefined,
|
|
476
|
+
): Promise<void> {
|
|
477
|
+
const envFiles = [".env"];
|
|
478
|
+
if (mode) {
|
|
479
|
+
envFiles.push(`.env.${mode}`);
|
|
480
|
+
}
|
|
481
|
+
this.log.debug(`Loading env files: ${envFiles.join(", ")}`);
|
|
482
|
+
await this.envUtils.loadEnv(root, envFiles);
|
|
483
|
+
}
|
|
484
|
+
|
|
295
485
|
protected parseFlags(
|
|
296
486
|
argv: string[],
|
|
297
487
|
flagDefs: { key: string; aliases: string[]; schema: TSchema }[],
|
|
@@ -522,8 +712,12 @@ export class CliProvider {
|
|
|
522
712
|
|
|
523
713
|
if (command?.name) {
|
|
524
714
|
// Command-specific help
|
|
525
|
-
const
|
|
526
|
-
const
|
|
715
|
+
const hasChildren = command.hasChildren;
|
|
716
|
+
const argsUsage = hasChildren
|
|
717
|
+
? " <command>"
|
|
718
|
+
: this.generateArgsUsage(command.options.args);
|
|
719
|
+
const commandPath = this.getCommandPath(command);
|
|
720
|
+
const usage = `${cliName} ${commandPath}${argsUsage}`.trim();
|
|
527
721
|
this.log.info(`Usage: \`${usage}\``);
|
|
528
722
|
|
|
529
723
|
if (command.options.description) {
|
|
@@ -531,6 +725,25 @@ export class CliProvider {
|
|
|
531
725
|
this.log.info(`\t${command.options.description}`);
|
|
532
726
|
}
|
|
533
727
|
|
|
728
|
+
// Show subcommands if this is a parent command
|
|
729
|
+
if (hasChildren) {
|
|
730
|
+
this.log.info("");
|
|
731
|
+
this.log.info("Commands:");
|
|
732
|
+
const maxSubCmdLength = this.getMaxChildCmdLength(command.children);
|
|
733
|
+
|
|
734
|
+
for (const child of command.children) {
|
|
735
|
+
if (child.options.hide) {
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
const childArgsUsage = this.generateArgsUsage(child.options.args);
|
|
739
|
+
const cmdStr = [child.name, ...child.aliases].join(", ");
|
|
740
|
+
const fullCmdStr = `${cmdStr}${childArgsUsage}`;
|
|
741
|
+
this.log.info(
|
|
742
|
+
` ${cliName} ${command.name} ${fullCmdStr.padEnd(maxSubCmdLength)} # ${child.options.description ?? ""}`,
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
534
747
|
this.log.info("");
|
|
535
748
|
this.log.info("Flags:");
|
|
536
749
|
|
|
@@ -541,6 +754,19 @@ export class CliProvider {
|
|
|
541
754
|
aliases: (value as any).alias ?? [key],
|
|
542
755
|
description: (value as any).description,
|
|
543
756
|
})),
|
|
757
|
+
// Add --mode flag if command has mode option enabled
|
|
758
|
+
...(command.options.mode
|
|
759
|
+
? [
|
|
760
|
+
{
|
|
761
|
+
key: "mode",
|
|
762
|
+
aliases: ["m", "mode"],
|
|
763
|
+
description:
|
|
764
|
+
typeof command.options.mode === "string"
|
|
765
|
+
? `Environment mode - loads .env.{mode} (default: ${command.options.mode})`
|
|
766
|
+
: "Environment mode (e.g., production, staging) - loads .env.{mode}",
|
|
767
|
+
},
|
|
768
|
+
]
|
|
769
|
+
: []),
|
|
544
770
|
...Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({
|
|
545
771
|
key,
|
|
546
772
|
...value,
|
|
@@ -556,21 +782,42 @@ export class CliProvider {
|
|
|
556
782
|
` ${flagStr.padEnd(maxFlagLength)} # ${description ?? ""}`,
|
|
557
783
|
);
|
|
558
784
|
}
|
|
785
|
+
|
|
786
|
+
// Show environment variables if defined
|
|
787
|
+
const envVars = Object.entries(command.env.properties);
|
|
788
|
+
if (envVars.length > 0) {
|
|
789
|
+
this.log.info("");
|
|
790
|
+
this.log.info("Env:");
|
|
791
|
+
const maxEnvLength = Math.max(...envVars.map(([key]) => key.length));
|
|
792
|
+
for (const [key, schema] of envVars) {
|
|
793
|
+
const isOptional = t.schema.isOptional(schema as TSchema);
|
|
794
|
+
const description = (schema as any).description ?? "";
|
|
795
|
+
const optionalStr = isOptional ? " (optional)" : "";
|
|
796
|
+
this.log.info(
|
|
797
|
+
` ${key.padEnd(maxEnvLength)} # ${description}${optionalStr}`,
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
559
801
|
} else {
|
|
560
802
|
// general help
|
|
561
803
|
this.log.info(this.description || "Available commands:");
|
|
562
804
|
this.log.info("");
|
|
563
805
|
this.log.info("Commands:");
|
|
564
|
-
const maxCmdLength = this.getMaxCmdLength(this.commands);
|
|
565
806
|
|
|
566
|
-
|
|
807
|
+
// Get top-level commands (commands that are not children of other commands)
|
|
808
|
+
const topLevelCommands = this.getTopLevelCommands();
|
|
809
|
+
const maxCmdLength = this.getMaxCmdLength(topLevelCommands);
|
|
810
|
+
|
|
811
|
+
for (const command of topLevelCommands) {
|
|
567
812
|
// skip root command and hooks in list
|
|
568
813
|
if (command.name === "" || command.options.hide) {
|
|
569
814
|
continue;
|
|
570
815
|
}
|
|
571
816
|
|
|
572
817
|
const cmdStr = [command.name, ...command.aliases].join(", ");
|
|
573
|
-
const argsUsage =
|
|
818
|
+
const argsUsage = command.hasChildren
|
|
819
|
+
? " <command>"
|
|
820
|
+
: this.generateArgsUsage(command.options.args);
|
|
574
821
|
const fullCmdStr = `${cmdStr}${argsUsage}`;
|
|
575
822
|
this.log.info(
|
|
576
823
|
` ${cliName} ${fullCmdStr.padEnd(maxCmdLength)} # ${command.options.description ?? ""}`,
|
|
@@ -579,7 +826,26 @@ export class CliProvider {
|
|
|
579
826
|
|
|
580
827
|
this.log.info("");
|
|
581
828
|
this.log.info("Flags:");
|
|
582
|
-
|
|
829
|
+
|
|
830
|
+
// In general help, also show root command flags
|
|
831
|
+
const rootCommand = this.commands.find((cmd) => cmd.name === "");
|
|
832
|
+
const rootFlags = rootCommand
|
|
833
|
+
? Object.entries(rootCommand.flags.properties).map(([key, value]) => ({
|
|
834
|
+
key,
|
|
835
|
+
aliases: [
|
|
836
|
+
key,
|
|
837
|
+
...((value as any).aliases ??
|
|
838
|
+
((value as any).alias ? [(value as any).alias] : undefined) ??
|
|
839
|
+
[]),
|
|
840
|
+
],
|
|
841
|
+
description: (value as any).description,
|
|
842
|
+
}))
|
|
843
|
+
: [];
|
|
844
|
+
|
|
845
|
+
const globalFlags = [
|
|
846
|
+
...rootFlags,
|
|
847
|
+
...Object.values(this.getAllGlobalFlags()),
|
|
848
|
+
];
|
|
583
849
|
const maxFlagLength = this.getMaxFlagLength(globalFlags);
|
|
584
850
|
for (const { aliases, description } of globalFlags) {
|
|
585
851
|
const flagStr = aliases
|
|
@@ -593,13 +859,80 @@ export class CliProvider {
|
|
|
593
859
|
this.log.info(""); // Newline
|
|
594
860
|
}
|
|
595
861
|
|
|
596
|
-
|
|
862
|
+
/**
|
|
863
|
+
* Get the full command path (e.g., "deploy vercel" for a child command).
|
|
864
|
+
*/
|
|
865
|
+
protected getCommandPath(command: CommandPrimitive<any>): string {
|
|
866
|
+
const path: string[] = [command.name];
|
|
867
|
+
let current = command;
|
|
868
|
+
|
|
869
|
+
// Walk up the tree to find parents
|
|
870
|
+
while (true) {
|
|
871
|
+
const parent = this.findParentCommand(current);
|
|
872
|
+
if (!parent) break;
|
|
873
|
+
path.unshift(parent.name);
|
|
874
|
+
current = parent;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
return path.join(" ");
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* Find the parent command of a given command.
|
|
882
|
+
*/
|
|
883
|
+
protected findParentCommand(
|
|
884
|
+
command: CommandPrimitive<any>,
|
|
885
|
+
): CommandPrimitive<any> | undefined {
|
|
886
|
+
for (const cmd of this.commands) {
|
|
887
|
+
if (cmd.children.includes(command)) {
|
|
888
|
+
return cmd;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
return undefined;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Get top-level commands (commands that are not children of other commands).
|
|
896
|
+
*/
|
|
897
|
+
protected getTopLevelCommands(): CommandPrimitive<any>[] {
|
|
898
|
+
const allChildren = new Set<CommandPrimitive<any>>();
|
|
899
|
+
|
|
900
|
+
// Collect all children
|
|
901
|
+
for (const command of this.commands) {
|
|
902
|
+
for (const child of command.children) {
|
|
903
|
+
allChildren.add(child);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// Return commands that are not children
|
|
908
|
+
return this.commands.filter((cmd) => !allChildren.has(cmd));
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* Get max length for child command display.
|
|
913
|
+
*/
|
|
914
|
+
protected getMaxChildCmdLength(children: CommandPrimitive<any>[]): number {
|
|
915
|
+
return Math.max(
|
|
916
|
+
...children
|
|
917
|
+
.filter((c) => !c.options.hide)
|
|
918
|
+
.map((c) => {
|
|
919
|
+
const cmdStr = [c.name, ...c.aliases].join(", ");
|
|
920
|
+
const argsUsage = this.generateArgsUsage(c.options.args);
|
|
921
|
+
return `${cmdStr}${argsUsage}`.length;
|
|
922
|
+
}),
|
|
923
|
+
0,
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
protected getMaxCmdLength(commands: CommandPrimitive[]): number {
|
|
597
928
|
return Math.max(
|
|
598
929
|
...commands
|
|
599
930
|
.filter((c) => !c.options.hide && c.name !== "")
|
|
600
931
|
.map((c) => {
|
|
601
932
|
const cmdStr = [c.name, ...c.aliases].join(", ");
|
|
602
|
-
const argsUsage =
|
|
933
|
+
const argsUsage = c.hasChildren
|
|
934
|
+
? " <command>"
|
|
935
|
+
: this.generateArgsUsage(c.options.args);
|
|
603
936
|
return `${cmdStr}${argsUsage}`.length;
|
|
604
937
|
}),
|
|
605
938
|
);
|
package/src/core/Alepha.ts
CHANGED
|
@@ -165,11 +165,14 @@ export class Alepha {
|
|
|
165
165
|
...state.env,
|
|
166
166
|
...process.env,
|
|
167
167
|
};
|
|
168
|
+
}
|
|
168
169
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
// force production mode when building with vite
|
|
171
|
+
if (process.env.NODE_ENV === "production") {
|
|
172
|
+
state.env ??= {};
|
|
173
|
+
Object.assign(state.env, {
|
|
174
|
+
NODE_ENV: "production",
|
|
175
|
+
});
|
|
173
176
|
}
|
|
174
177
|
|
|
175
178
|
const alepha = new Alepha(state);
|
|
@@ -1016,7 +1019,7 @@ export interface Env {
|
|
|
1016
1019
|
/**
|
|
1017
1020
|
* Optional environment variable that indicates the current environment.
|
|
1018
1021
|
*/
|
|
1019
|
-
NODE_ENV?:
|
|
1022
|
+
NODE_ENV?: string;
|
|
1020
1023
|
|
|
1021
1024
|
/**
|
|
1022
1025
|
* Optional name of the application.
|
|
@@ -548,7 +548,9 @@ export class NodeFileSystemProvider implements FileSystemProvider {
|
|
|
548
548
|
const stream = new PassThrough();
|
|
549
549
|
|
|
550
550
|
fetch(url)
|
|
551
|
-
.then((res) =>
|
|
551
|
+
.then((res) =>
|
|
552
|
+
Readable.fromWeb(res.body as unknown as NodeWebStream).pipe(stream),
|
|
553
|
+
)
|
|
552
554
|
.catch((err) => stream.destroy(err));
|
|
553
555
|
|
|
554
556
|
return stream;
|
package/src/orm/index.browser.ts
CHANGED
|
@@ -16,7 +16,7 @@ export * from "./interfaces/FilterOperators.ts";
|
|
|
16
16
|
export * from "./interfaces/PgQuery.ts";
|
|
17
17
|
export * from "./interfaces/PgQueryWhere.ts";
|
|
18
18
|
export * from "./primitives/$entity.ts";
|
|
19
|
-
export * from "./providers/
|
|
19
|
+
export * from "./providers/DatabaseTypeProvider.ts";
|
|
20
20
|
export * from "./schemas/legacyIdSchema.ts";
|
|
21
21
|
|
|
22
22
|
// ---------------------------------------------------------------------------------------------------------------------
|