@veloxts/cli 0.6.31 → 0.6.52
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/CHANGELOG.md +252 -0
- package/dist/cli.js +2 -0
- package/dist/commands/schedule.d.ts +14 -0
- package/dist/commands/schedule.js +324 -0
- package/dist/generators/generators/event.d.ts +35 -0
- package/dist/generators/generators/event.js +99 -0
- package/dist/generators/generators/index.d.ts +5 -0
- package/dist/generators/generators/index.js +15 -0
- package/dist/generators/generators/job.d.ts +36 -0
- package/dist/generators/generators/job.js +98 -0
- package/dist/generators/generators/mail.d.ts +36 -0
- package/dist/generators/generators/mail.js +90 -0
- package/dist/generators/generators/storage.d.ts +35 -0
- package/dist/generators/generators/storage.js +104 -0
- package/dist/generators/generators/task.d.ts +36 -0
- package/dist/generators/generators/task.js +99 -0
- package/dist/generators/templates/event.d.ts +21 -0
- package/dist/generators/templates/event.js +410 -0
- package/dist/generators/templates/job.d.ts +23 -0
- package/dist/generators/templates/job.js +352 -0
- package/dist/generators/templates/mail.d.ts +21 -0
- package/dist/generators/templates/mail.js +411 -0
- package/dist/generators/templates/storage.d.ts +23 -0
- package/dist/generators/templates/storage.js +556 -0
- package/dist/generators/templates/task.d.ts +33 -0
- package/dist/generators/templates/task.js +189 -0
- package/package.json +8 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,257 @@
|
|
|
1
1
|
# @veloxts/cli
|
|
2
2
|
|
|
3
|
+
## 0.6.52
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat(mcp): smart CLI resolution with fallbacks
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @veloxts/auth@0.6.52
|
|
10
|
+
- @veloxts/core@0.6.52
|
|
11
|
+
- @veloxts/orm@0.6.52
|
|
12
|
+
- @veloxts/router@0.6.52
|
|
13
|
+
- @veloxts/validation@0.6.52
|
|
14
|
+
|
|
15
|
+
## 0.6.51
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- fix(web): configure @vinxi/server-functions for RSC server actions
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
- @veloxts/auth@0.6.51
|
|
22
|
+
- @veloxts/core@0.6.51
|
|
23
|
+
- @veloxts/orm@0.6.51
|
|
24
|
+
- @veloxts/router@0.6.51
|
|
25
|
+
- @veloxts/validation@0.6.51
|
|
26
|
+
|
|
27
|
+
## 0.6.50
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- lint fixed
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @veloxts/auth@0.6.50
|
|
34
|
+
- @veloxts/core@0.6.50
|
|
35
|
+
- @veloxts/orm@0.6.50
|
|
36
|
+
- @veloxts/router@0.6.50
|
|
37
|
+
- @veloxts/validation@0.6.50
|
|
38
|
+
|
|
39
|
+
## 0.6.49
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- feat(create): add client import lint script for RSC templates
|
|
44
|
+
- Updated dependencies
|
|
45
|
+
- @veloxts/auth@0.6.49
|
|
46
|
+
- @veloxts/core@0.6.49
|
|
47
|
+
- @veloxts/orm@0.6.49
|
|
48
|
+
- @veloxts/router@0.6.49
|
|
49
|
+
- @veloxts/validation@0.6.49
|
|
50
|
+
|
|
51
|
+
## 0.6.48
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- fix(web): remove server-only guards incompatible with Vite SS
|
|
56
|
+
- Updated dependencies
|
|
57
|
+
- @veloxts/auth@0.6.48
|
|
58
|
+
- @veloxts/core@0.6.48
|
|
59
|
+
- @veloxts/orm@0.6.48
|
|
60
|
+
- @veloxts/router@0.6.48
|
|
61
|
+
- @veloxts/validation@0.6.48
|
|
62
|
+
|
|
63
|
+
## 0.6.47
|
|
64
|
+
|
|
65
|
+
### Patch Changes
|
|
66
|
+
|
|
67
|
+
- fix(web): use /adapters for createH3ApiHandler to avoid server-only
|
|
68
|
+
- Updated dependencies
|
|
69
|
+
- @veloxts/auth@0.6.47
|
|
70
|
+
- @veloxts/core@0.6.47
|
|
71
|
+
- @veloxts/orm@0.6.47
|
|
72
|
+
- @veloxts/router@0.6.47
|
|
73
|
+
- @veloxts/validation@0.6.47
|
|
74
|
+
|
|
75
|
+
## 0.6.46
|
|
76
|
+
|
|
77
|
+
### Patch Changes
|
|
78
|
+
|
|
79
|
+
- fix(web): remove transitive server-only import from main entry
|
|
80
|
+
- Updated dependencies
|
|
81
|
+
- @veloxts/auth@0.6.46
|
|
82
|
+
- @veloxts/core@0.6.46
|
|
83
|
+
- @veloxts/orm@0.6.46
|
|
84
|
+
- @veloxts/router@0.6.46
|
|
85
|
+
- @veloxts/validation@0.6.46
|
|
86
|
+
|
|
87
|
+
## 0.6.45
|
|
88
|
+
|
|
89
|
+
### Patch Changes
|
|
90
|
+
|
|
91
|
+
- fix(web): remove server-only guard from main entry for Vinxi compat
|
|
92
|
+
- Updated dependencies
|
|
93
|
+
- @veloxts/auth@0.6.45
|
|
94
|
+
- @veloxts/core@0.6.45
|
|
95
|
+
- @veloxts/orm@0.6.45
|
|
96
|
+
- @veloxts/router@0.6.45
|
|
97
|
+
- @veloxts/validation@0.6.45
|
|
98
|
+
|
|
99
|
+
## 0.6.44
|
|
100
|
+
|
|
101
|
+
### Patch Changes
|
|
102
|
+
|
|
103
|
+
- refactor(web): implement proper RSC server/client separation
|
|
104
|
+
- Updated dependencies
|
|
105
|
+
- @veloxts/auth@0.6.44
|
|
106
|
+
- @veloxts/core@0.6.44
|
|
107
|
+
- @veloxts/orm@0.6.44
|
|
108
|
+
- @veloxts/router@0.6.44
|
|
109
|
+
- @veloxts/validation@0.6.44
|
|
110
|
+
|
|
111
|
+
## 0.6.43
|
|
112
|
+
|
|
113
|
+
### Patch Changes
|
|
114
|
+
|
|
115
|
+
- fix(web): exclude native modules from Vite dependency optimization
|
|
116
|
+
- Updated dependencies
|
|
117
|
+
- @veloxts/auth@0.6.43
|
|
118
|
+
- @veloxts/core@0.6.43
|
|
119
|
+
- @veloxts/orm@0.6.43
|
|
120
|
+
- @veloxts/router@0.6.43
|
|
121
|
+
- @veloxts/validation@0.6.43
|
|
122
|
+
|
|
123
|
+
## 0.6.42
|
|
124
|
+
|
|
125
|
+
### Patch Changes
|
|
126
|
+
|
|
127
|
+
- fix(web): enable tsconfig path aliases for Vite/Vinxi + docs(web): add @public/@internal JSDoc annotations to server actions
|
|
128
|
+
- Updated dependencies
|
|
129
|
+
- @veloxts/auth@0.6.42
|
|
130
|
+
- @veloxts/core@0.6.42
|
|
131
|
+
- @veloxts/orm@0.6.42
|
|
132
|
+
- @veloxts/router@0.6.42
|
|
133
|
+
- @veloxts/validation@0.6.42
|
|
134
|
+
|
|
135
|
+
## 0.6.41
|
|
136
|
+
|
|
137
|
+
### Patch Changes
|
|
138
|
+
|
|
139
|
+
- feat(web): add authAction helper for procedure bridge authentication
|
|
140
|
+
- Updated dependencies
|
|
141
|
+
- @veloxts/auth@0.6.41
|
|
142
|
+
- @veloxts/core@0.6.41
|
|
143
|
+
- @veloxts/orm@0.6.41
|
|
144
|
+
- @veloxts/router@0.6.41
|
|
145
|
+
- @veloxts/validation@0.6.41
|
|
146
|
+
|
|
147
|
+
## 0.6.40
|
|
148
|
+
|
|
149
|
+
### Patch Changes
|
|
150
|
+
|
|
151
|
+
- feat(create): consolidate template styles with unified dark mode design
|
|
152
|
+
- Updated dependencies
|
|
153
|
+
- @veloxts/auth@0.6.40
|
|
154
|
+
- @veloxts/core@0.6.40
|
|
155
|
+
- @veloxts/orm@0.6.40
|
|
156
|
+
- @veloxts/router@0.6.40
|
|
157
|
+
- @veloxts/validation@0.6.40
|
|
158
|
+
|
|
159
|
+
## 0.6.39
|
|
160
|
+
|
|
161
|
+
### Patch Changes
|
|
162
|
+
|
|
163
|
+
- fix RSC client hydration with split layout architecture
|
|
164
|
+
- Updated dependencies
|
|
165
|
+
- @veloxts/auth@0.6.39
|
|
166
|
+
- @veloxts/core@0.6.39
|
|
167
|
+
- @veloxts/orm@0.6.39
|
|
168
|
+
- @veloxts/router@0.6.39
|
|
169
|
+
- @veloxts/validation@0.6.39
|
|
170
|
+
|
|
171
|
+
## 0.6.38
|
|
172
|
+
|
|
173
|
+
### Patch Changes
|
|
174
|
+
|
|
175
|
+
- fix client hydration for RSC templates
|
|
176
|
+
- Updated dependencies
|
|
177
|
+
- @veloxts/auth@0.6.38
|
|
178
|
+
- @veloxts/core@0.6.38
|
|
179
|
+
- @veloxts/orm@0.6.38
|
|
180
|
+
- @veloxts/router@0.6.38
|
|
181
|
+
- @veloxts/validation@0.6.38
|
|
182
|
+
|
|
183
|
+
## 0.6.37
|
|
184
|
+
|
|
185
|
+
### Patch Changes
|
|
186
|
+
|
|
187
|
+
- feat(web): add validated() helper for secure server actions & add rsc-auth template with validated()
|
|
188
|
+
- Updated dependencies
|
|
189
|
+
- @veloxts/auth@0.6.37
|
|
190
|
+
- @veloxts/core@0.6.37
|
|
191
|
+
- @veloxts/orm@0.6.37
|
|
192
|
+
- @veloxts/router@0.6.37
|
|
193
|
+
- @veloxts/validation@0.6.37
|
|
194
|
+
|
|
195
|
+
## 0.6.36
|
|
196
|
+
|
|
197
|
+
### Patch Changes
|
|
198
|
+
|
|
199
|
+
- Gap Remediation Plan
|
|
200
|
+
- Updated dependencies
|
|
201
|
+
- @veloxts/auth@0.6.36
|
|
202
|
+
- @veloxts/core@0.6.36
|
|
203
|
+
- @veloxts/orm@0.6.36
|
|
204
|
+
- @veloxts/router@0.6.36
|
|
205
|
+
- @veloxts/validation@0.6.36
|
|
206
|
+
|
|
207
|
+
## 0.6.35
|
|
208
|
+
|
|
209
|
+
### Patch Changes
|
|
210
|
+
|
|
211
|
+
- proper auth template testing in verify-publis
|
|
212
|
+
- Updated dependencies
|
|
213
|
+
- @veloxts/auth@0.6.35
|
|
214
|
+
- @veloxts/core@0.6.35
|
|
215
|
+
- @veloxts/orm@0.6.35
|
|
216
|
+
- @veloxts/router@0.6.35
|
|
217
|
+
- @veloxts/validation@0.6.35
|
|
218
|
+
|
|
219
|
+
## 0.6.34
|
|
220
|
+
|
|
221
|
+
### Patch Changes
|
|
222
|
+
|
|
223
|
+
- update PostgreSQL adapter for Prisma 7 API
|
|
224
|
+
- Updated dependencies
|
|
225
|
+
- @veloxts/auth@0.6.34
|
|
226
|
+
- @veloxts/core@0.6.34
|
|
227
|
+
- @veloxts/orm@0.6.34
|
|
228
|
+
- @veloxts/router@0.6.34
|
|
229
|
+
- @veloxts/validation@0.6.34
|
|
230
|
+
|
|
231
|
+
## 0.6.33
|
|
232
|
+
|
|
233
|
+
### Patch Changes
|
|
234
|
+
|
|
235
|
+
- changed claude.md instruction, added prisma config
|
|
236
|
+
- Updated dependencies
|
|
237
|
+
- @veloxts/auth@0.6.33
|
|
238
|
+
- @veloxts/core@0.6.33
|
|
239
|
+
- @veloxts/orm@0.6.33
|
|
240
|
+
- @veloxts/router@0.6.33
|
|
241
|
+
- @veloxts/validation@0.6.33
|
|
242
|
+
|
|
243
|
+
## 0.6.32
|
|
244
|
+
|
|
245
|
+
### Patch Changes
|
|
246
|
+
|
|
247
|
+
- Introducing new Ecosystem Expansion packages: cache, queue, mail, storage, scheduler, events. Do not use yet
|
|
248
|
+
- Updated dependencies
|
|
249
|
+
- @veloxts/auth@0.6.32
|
|
250
|
+
- @veloxts/core@0.6.32
|
|
251
|
+
- @veloxts/orm@0.6.32
|
|
252
|
+
- @veloxts/router@0.6.32
|
|
253
|
+
- @veloxts/validation@0.6.32
|
|
254
|
+
|
|
3
255
|
## 0.6.31
|
|
4
256
|
|
|
5
257
|
### Patch Changes
|
package/dist/cli.js
CHANGED
|
@@ -15,6 +15,7 @@ import { createIntrospectCommand } from './commands/introspect.js';
|
|
|
15
15
|
import { createMakeCommand } from './commands/make.js';
|
|
16
16
|
import { createMigrateCommand } from './commands/migrate.js';
|
|
17
17
|
import { createProceduresCommand } from './commands/procedures.js';
|
|
18
|
+
import { createScheduleCommand } from './commands/schedule.js';
|
|
18
19
|
import { createTenantCommand } from './commands/tenant.js';
|
|
19
20
|
import { CLI_VERSION } from './index.js';
|
|
20
21
|
/**
|
|
@@ -34,6 +35,7 @@ function createCLI() {
|
|
|
34
35
|
program.addCommand(createMakeCommand());
|
|
35
36
|
program.addCommand(createMigrateCommand());
|
|
36
37
|
program.addCommand(createProceduresCommand());
|
|
38
|
+
program.addCommand(createScheduleCommand());
|
|
37
39
|
program.addCommand(createTenantCommand());
|
|
38
40
|
return program;
|
|
39
41
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schedule command - Task scheduling commands
|
|
3
|
+
*
|
|
4
|
+
* Provides subcommands for managing scheduled tasks:
|
|
5
|
+
* - schedule:run - Run due scheduled tasks
|
|
6
|
+
* - schedule:list - List all scheduled tasks
|
|
7
|
+
* - schedule:test - Run a specific task immediately
|
|
8
|
+
* - schedule:work - Start the scheduler daemon
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
/**
|
|
12
|
+
* Create the schedule command with subcommands
|
|
13
|
+
*/
|
|
14
|
+
export declare function createScheduleCommand(): Command;
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schedule command - Task scheduling commands
|
|
3
|
+
*
|
|
4
|
+
* Provides subcommands for managing scheduled tasks:
|
|
5
|
+
* - schedule:run - Run due scheduled tasks
|
|
6
|
+
* - schedule:list - List all scheduled tasks
|
|
7
|
+
* - schedule:test - Run a specific task immediately
|
|
8
|
+
* - schedule:work - Start the scheduler daemon
|
|
9
|
+
*/
|
|
10
|
+
import * as p from '@clack/prompts';
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import pc from 'picocolors';
|
|
13
|
+
import { error, info, step, success, warning } from '../utils/output.js';
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Helper Functions
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Format a cron expression to human-readable text
|
|
19
|
+
*/
|
|
20
|
+
function formatCronExpression(cron) {
|
|
21
|
+
const parts = cron.split(' ');
|
|
22
|
+
if (parts.length !== 5)
|
|
23
|
+
return cron;
|
|
24
|
+
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
|
|
25
|
+
// Common patterns
|
|
26
|
+
if (cron === '* * * * *')
|
|
27
|
+
return 'Every minute';
|
|
28
|
+
if (cron === '0 * * * *')
|
|
29
|
+
return 'Every hour';
|
|
30
|
+
if (cron === '0 0 * * *')
|
|
31
|
+
return 'Daily at midnight';
|
|
32
|
+
if (cron === '0 0 * * 0')
|
|
33
|
+
return 'Weekly on Sunday';
|
|
34
|
+
if (cron === '0 0 1 * *')
|
|
35
|
+
return 'Monthly on the 1st';
|
|
36
|
+
// Every N minutes
|
|
37
|
+
if (minute.startsWith('*/') && hour === '*') {
|
|
38
|
+
return `Every ${minute.slice(2)} minutes`;
|
|
39
|
+
}
|
|
40
|
+
// Every N hours
|
|
41
|
+
if (minute === '0' && hour.startsWith('*/')) {
|
|
42
|
+
return `Every ${hour.slice(2)} hours`;
|
|
43
|
+
}
|
|
44
|
+
// Daily at specific time
|
|
45
|
+
if (minute !== '*' && hour !== '*' && dayOfMonth === '*' && month === '*' && dayOfWeek === '*') {
|
|
46
|
+
return `Daily at ${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`;
|
|
47
|
+
}
|
|
48
|
+
return cron;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Load the schedule from the project
|
|
52
|
+
*/
|
|
53
|
+
async function loadSchedule() {
|
|
54
|
+
// Try to load the schedule from common locations
|
|
55
|
+
const possiblePaths = [
|
|
56
|
+
'./src/schedule.ts',
|
|
57
|
+
'./src/schedule.js',
|
|
58
|
+
'./schedule.ts',
|
|
59
|
+
'./schedule.js',
|
|
60
|
+
'./src/config/schedule.ts',
|
|
61
|
+
'./src/config/schedule.js',
|
|
62
|
+
];
|
|
63
|
+
for (const schedulePath of possiblePaths) {
|
|
64
|
+
try {
|
|
65
|
+
// Dynamic import of the schedule file
|
|
66
|
+
const scheduleModule = await import(schedulePath);
|
|
67
|
+
const schedule = scheduleModule.schedule || scheduleModule.default;
|
|
68
|
+
if (Array.isArray(schedule)) {
|
|
69
|
+
return schedule.map((task) => ({
|
|
70
|
+
name: task.name,
|
|
71
|
+
description: task.description,
|
|
72
|
+
cronExpression: task.cronExpression,
|
|
73
|
+
timezone: task.timezone || 'UTC',
|
|
74
|
+
enabled: task.enabled !== false,
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Try next path
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// Commands
|
|
86
|
+
// ============================================================================
|
|
87
|
+
/**
|
|
88
|
+
* Create the schedule:run command
|
|
89
|
+
*/
|
|
90
|
+
function createScheduleRunCommand() {
|
|
91
|
+
return new Command('run')
|
|
92
|
+
.description('Run all due scheduled tasks')
|
|
93
|
+
.option('--json', 'Output as JSON', false)
|
|
94
|
+
.action(async (options) => {
|
|
95
|
+
if (!options.json) {
|
|
96
|
+
p.intro(pc.bgCyan(pc.black(' schedule:run ')));
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const tasks = await loadSchedule();
|
|
100
|
+
if (tasks.length === 0) {
|
|
101
|
+
if (options.json) {
|
|
102
|
+
console.log(JSON.stringify({ error: 'No schedule found', tasks: [] }));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
warning('No schedule found. Create a schedule file at src/schedule.ts');
|
|
106
|
+
p.outro(pc.yellow('No tasks to run'));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// In a real implementation, this would:
|
|
110
|
+
// 1. Load the scheduler manager
|
|
111
|
+
// 2. Check which tasks are due
|
|
112
|
+
// 3. Execute due tasks
|
|
113
|
+
// 4. Report results
|
|
114
|
+
if (options.json) {
|
|
115
|
+
console.log(JSON.stringify({
|
|
116
|
+
message: 'Schedule run complete',
|
|
117
|
+
tasksChecked: tasks.length,
|
|
118
|
+
tasksRun: 0,
|
|
119
|
+
}));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
info(`Checked ${tasks.length} scheduled tasks`);
|
|
123
|
+
step('No tasks due at this time');
|
|
124
|
+
p.outro(pc.green('Schedule run complete'));
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
128
|
+
if (options.json) {
|
|
129
|
+
console.log(JSON.stringify({ error: message }));
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
error(`Failed to run schedule: ${message}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create the schedule:list command
|
|
139
|
+
*/
|
|
140
|
+
function createScheduleListCommand() {
|
|
141
|
+
return new Command('list')
|
|
142
|
+
.description('List all scheduled tasks')
|
|
143
|
+
.option('--json', 'Output as JSON', false)
|
|
144
|
+
.action(async (options) => {
|
|
145
|
+
if (!options.json) {
|
|
146
|
+
p.intro(pc.bgCyan(pc.black(' schedule:list ')));
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const tasks = await loadSchedule();
|
|
150
|
+
if (tasks.length === 0) {
|
|
151
|
+
if (options.json) {
|
|
152
|
+
console.log(JSON.stringify({ tasks: [] }));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
warning('No schedule found. Create a schedule file at src/schedule.ts');
|
|
156
|
+
p.outro(pc.yellow('No scheduled tasks'));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (options.json) {
|
|
160
|
+
console.log(JSON.stringify({ tasks }));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// Display as table
|
|
164
|
+
info(`Found ${tasks.length} scheduled task${tasks.length === 1 ? '' : 's'}:\n`);
|
|
165
|
+
const maxNameLen = Math.max(...tasks.map((t) => t.name.length), 4);
|
|
166
|
+
const maxCronLen = Math.max(...tasks.map((t) => t.cronExpression.length), 10);
|
|
167
|
+
// Header
|
|
168
|
+
const header = ` ${pc.bold('Name'.padEnd(maxNameLen))} ${pc.bold('Expression'.padEnd(maxCronLen))} ${pc.bold('Schedule')}`;
|
|
169
|
+
console.log(header);
|
|
170
|
+
console.log(` ${'-'.repeat(maxNameLen + maxCronLen + 30)}`);
|
|
171
|
+
// Rows
|
|
172
|
+
for (const task of tasks) {
|
|
173
|
+
const status = task.enabled ? pc.green('enabled') : pc.dim('disabled');
|
|
174
|
+
const schedule = formatCronExpression(task.cronExpression);
|
|
175
|
+
console.log(` ${task.name.padEnd(maxNameLen)} ${task.cronExpression.padEnd(maxCronLen)} ${schedule} ${status}`);
|
|
176
|
+
}
|
|
177
|
+
console.log('');
|
|
178
|
+
p.outro(pc.green('Schedule list complete'));
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
182
|
+
if (options.json) {
|
|
183
|
+
console.log(JSON.stringify({ error: message }));
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
error(`Failed to list schedule: ${message}`);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Create the schedule:test command
|
|
193
|
+
*/
|
|
194
|
+
function createScheduleTestCommand() {
|
|
195
|
+
return new Command('test')
|
|
196
|
+
.description('Run a specific scheduled task immediately')
|
|
197
|
+
.argument('<name>', 'Task name to run')
|
|
198
|
+
.option('--json', 'Output as JSON', false)
|
|
199
|
+
.action(async (name, options) => {
|
|
200
|
+
if (!options.json) {
|
|
201
|
+
p.intro(pc.bgCyan(pc.black(' schedule:test ')));
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
const tasks = await loadSchedule();
|
|
205
|
+
const task = tasks.find((t) => t.name === name);
|
|
206
|
+
if (!task) {
|
|
207
|
+
if (options.json) {
|
|
208
|
+
console.log(JSON.stringify({ error: `Task not found: ${name}` }));
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
error(`Task not found: ${name}`);
|
|
212
|
+
info('Available tasks:');
|
|
213
|
+
for (const t of tasks) {
|
|
214
|
+
console.log(` - ${t.name}`);
|
|
215
|
+
}
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
if (!options.json) {
|
|
219
|
+
step(`Running task: ${task.name}`);
|
|
220
|
+
info(`Cron: ${task.cronExpression}`);
|
|
221
|
+
info(`Timezone: ${task.timezone}`);
|
|
222
|
+
}
|
|
223
|
+
// In a real implementation, this would:
|
|
224
|
+
// 1. Load the scheduler manager
|
|
225
|
+
// 2. Find the task
|
|
226
|
+
// 3. Execute it immediately
|
|
227
|
+
// 4. Report results
|
|
228
|
+
if (options.json) {
|
|
229
|
+
console.log(JSON.stringify({
|
|
230
|
+
task: name,
|
|
231
|
+
status: 'completed',
|
|
232
|
+
duration: 0,
|
|
233
|
+
}));
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
success(`Task ${task.name} executed successfully`);
|
|
237
|
+
p.outro(pc.green('Test complete'));
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
241
|
+
if (options.json) {
|
|
242
|
+
console.log(JSON.stringify({ error: message }));
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
error(`Failed to run task: ${message}`);
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Create the schedule:work command
|
|
252
|
+
*/
|
|
253
|
+
function createScheduleWorkCommand() {
|
|
254
|
+
return new Command('work')
|
|
255
|
+
.description('Start the scheduler daemon (keeps running)')
|
|
256
|
+
.option('--json', 'Output as JSON', false)
|
|
257
|
+
.action(async (options) => {
|
|
258
|
+
if (!options.json) {
|
|
259
|
+
p.intro(pc.bgCyan(pc.black(' schedule:work ')));
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
const tasks = await loadSchedule();
|
|
263
|
+
if (tasks.length === 0) {
|
|
264
|
+
if (options.json) {
|
|
265
|
+
console.log(JSON.stringify({ error: 'No schedule found' }));
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
warning('No schedule found. Create a schedule file at src/schedule.ts');
|
|
269
|
+
process.exit(1);
|
|
270
|
+
}
|
|
271
|
+
if (!options.json) {
|
|
272
|
+
success(`Loaded ${tasks.length} scheduled task${tasks.length === 1 ? '' : 's'}`);
|
|
273
|
+
info('Scheduler is running. Press Ctrl+C to stop.\n');
|
|
274
|
+
// List tasks
|
|
275
|
+
for (const task of tasks) {
|
|
276
|
+
const schedule = formatCronExpression(task.cronExpression);
|
|
277
|
+
console.log(` ${pc.cyan(task.name)}: ${schedule}`);
|
|
278
|
+
}
|
|
279
|
+
console.log('');
|
|
280
|
+
}
|
|
281
|
+
// In a real implementation, this would:
|
|
282
|
+
// 1. Create and start the scheduler
|
|
283
|
+
// 2. Keep the process running
|
|
284
|
+
// 3. Handle graceful shutdown on SIGINT/SIGTERM
|
|
285
|
+
// For now, just keep the process alive
|
|
286
|
+
await new Promise((resolve) => {
|
|
287
|
+
const shutdown = () => {
|
|
288
|
+
if (!options.json) {
|
|
289
|
+
console.log('\n');
|
|
290
|
+
info('Shutting down scheduler...');
|
|
291
|
+
success('Scheduler stopped gracefully');
|
|
292
|
+
}
|
|
293
|
+
resolve();
|
|
294
|
+
};
|
|
295
|
+
process.on('SIGINT', shutdown);
|
|
296
|
+
process.on('SIGTERM', shutdown);
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
301
|
+
if (options.json) {
|
|
302
|
+
console.log(JSON.stringify({ error: message }));
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
305
|
+
error(`Failed to start scheduler: ${message}`);
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
// ============================================================================
|
|
311
|
+
// Main Command
|
|
312
|
+
// ============================================================================
|
|
313
|
+
/**
|
|
314
|
+
* Create the schedule command with subcommands
|
|
315
|
+
*/
|
|
316
|
+
export function createScheduleCommand() {
|
|
317
|
+
const schedule = new Command('schedule')
|
|
318
|
+
.description('Task scheduling commands')
|
|
319
|
+
.addCommand(createScheduleRunCommand())
|
|
320
|
+
.addCommand(createScheduleListCommand())
|
|
321
|
+
.addCommand(createScheduleTestCommand())
|
|
322
|
+
.addCommand(createScheduleWorkCommand());
|
|
323
|
+
return schedule;
|
|
324
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Generator
|
|
3
|
+
*
|
|
4
|
+
* Scaffolds event-related files for VeloxTS applications.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* velox make event <name> [options]
|
|
8
|
+
*
|
|
9
|
+
* Examples:
|
|
10
|
+
* velox make event user-registered # Broadcastable event
|
|
11
|
+
* velox make event order-created --listener # Event listener
|
|
12
|
+
* velox make event notifications --channel # Channel with authorization
|
|
13
|
+
*/
|
|
14
|
+
import { BaseGenerator } from '../base.js';
|
|
15
|
+
import { type EventOptions } from '../templates/event.js';
|
|
16
|
+
import type { GeneratorConfig, GeneratorMetadata, GeneratorOption, GeneratorOutput } from '../types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Event generator - creates event-related files
|
|
19
|
+
*/
|
|
20
|
+
export declare class EventGenerator extends BaseGenerator<EventOptions> {
|
|
21
|
+
readonly metadata: GeneratorMetadata;
|
|
22
|
+
readonly options: ReadonlyArray<GeneratorOption>;
|
|
23
|
+
/**
|
|
24
|
+
* Validate and transform raw options
|
|
25
|
+
*/
|
|
26
|
+
validateOptions(raw: Record<string, unknown>): EventOptions;
|
|
27
|
+
/**
|
|
28
|
+
* Generate event files
|
|
29
|
+
*/
|
|
30
|
+
generate(config: GeneratorConfig<EventOptions>): Promise<GeneratorOutput>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Factory function for creating an EventGenerator instance
|
|
34
|
+
*/
|
|
35
|
+
export declare function createEventGenerator(): EventGenerator;
|