@elysiumjs/styx 0.5.0 → 0.6.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.
@@ -1,172 +0,0 @@
1
- // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- import type { PromptObject } from 'prompts';
16
-
17
- import { join } from 'node:path';
18
-
19
- import { Command, CommandArgumentType } from '@elysiumjs/core';
20
- import prompts from 'prompts';
21
- import { pascal, snake } from 'radash';
22
- import formatter from 'string-template';
23
-
24
- import { getModulePath, parseProjectConfig } from '../config';
25
- import { getRootPath } from '../utils';
26
-
27
- /**
28
- * Maker class for creating Elysium.js commands.
29
- * @author Axel Nana <axel.nana@workbud.com>
30
- */
31
- export class MakeCommandCommand extends Command {
32
- public static readonly command: string = 'make:command';
33
- public static readonly description: string = 'Creates a new command.';
34
-
35
- @Command.arg({
36
- description: 'The name of the command to create',
37
- type: CommandArgumentType.STRING
38
- })
39
- private name?: string;
40
-
41
- @Command.arg({
42
- description: 'The module where the command will be created',
43
- type: CommandArgumentType.STRING
44
- })
45
- private module?: string;
46
-
47
- @Command.arg({
48
- description: 'The command to create',
49
- type: CommandArgumentType.STRING
50
- })
51
- private command?: string;
52
-
53
- @Command.arg({
54
- description: 'The description of the command',
55
- type: CommandArgumentType.STRING
56
- })
57
- private description?: string;
58
-
59
- public async run(): Promise<void> {
60
- if (!this.command || !this.name) {
61
- return this.setup();
62
- }
63
-
64
- const config = await parseProjectConfig();
65
-
66
- const answers: Record<string, any> = {
67
- module: this.module,
68
- name: this.name,
69
- command: this.command,
70
- description: this.description
71
- };
72
-
73
- if (!answers.module && !config.mono) {
74
- const module = await prompts({
75
- type: 'select',
76
- name: 'module',
77
- message: 'Module:',
78
- choices: Object.keys(config.modules ?? {}).map((moduleName) => ({
79
- title: moduleName,
80
- value: moduleName
81
- }))
82
- });
83
-
84
- answers.module = module.module;
85
- }
86
-
87
- return this.build(answers);
88
- }
89
-
90
- private async setup(): Promise<void> {
91
- const config = await parseProjectConfig();
92
-
93
- const items: PromptObject[] = [
94
- {
95
- type() {
96
- return config.mono ? null : 'select';
97
- },
98
- name: 'module',
99
- message: 'Module:',
100
- choices() {
101
- return Object.keys(config.modules ?? {}).map((moduleName) => ({
102
- title: moduleName,
103
- value: moduleName
104
- }));
105
- }
106
- },
107
- {
108
- type: 'text',
109
- name: 'command',
110
- message: 'Command Name:',
111
- initial: 'user:say',
112
- validate(value: string) {
113
- if (value.length < 1) {
114
- return 'Command name cannot be empty';
115
- }
116
-
117
- return true;
118
- }
119
- },
120
- {
121
- type: 'text',
122
- name: 'description',
123
- message: 'Command Description:',
124
- initial: 'Say something',
125
- validate(value: string) {
126
- if (value.length < 1) {
127
- return 'Command description cannot be empty';
128
- }
129
-
130
- return true;
131
- }
132
- }
133
- ];
134
-
135
- const answers = await prompts(items, {
136
- onCancel: () => {
137
- this.error('Operation cancelled.');
138
- process.exit(0);
139
- }
140
- });
141
-
142
- answers.name = pascal(answers.command.replaceAll(':', '_'));
143
-
144
- return this.build(answers);
145
- }
146
-
147
- private async build(answers: Record<string, any>): Promise<void> {
148
- if (!answers.name) {
149
- this.error('Operation cancelled.');
150
- return;
151
- }
152
-
153
- if (!answers.name.endsWith('Command')) {
154
- answers.name += 'Command';
155
- }
156
-
157
- // Get stub file
158
- const stubFile = Bun.file(join(getRootPath(), 'stubs/command.stub'));
159
-
160
- // Format the stub content
161
- const stub = formatter(await stubFile.text(), answers);
162
-
163
- const path = answers.module ? await getModulePath(answers.module) : './src';
164
-
165
- // Write to file
166
- const name = snake(answers.name.replace('Command', ''));
167
- const file = Bun.file(`${path}/commands/${name}.command.ts`);
168
- await file.write(stub);
169
-
170
- this.success(`Command ${this.bold(file.name!)} created successfully.`);
171
- }
172
- }
@@ -1,277 +0,0 @@
1
- // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- import type { PromptObject } from 'prompts';
16
-
17
- import { join } from 'node:path';
18
-
19
- import { Command, CommandArgumentType } from '@elysiumjs/core';
20
- import prompts from 'prompts';
21
- import { snake } from 'radash';
22
- import formatter from 'string-template';
23
-
24
- import { getModulePath, parseProjectConfig } from '../config';
25
- import { getRootPath } from '../utils';
26
-
27
- /**
28
- * Maker class for creating Elysium.js controllers.
29
- * @author Axel Nana <axel.nana@workbud.com>
30
- */
31
- export class MakeControllerCommand extends Command {
32
- public static readonly command: string = 'make:controller';
33
- public static readonly description: string = 'Creates a new controller.';
34
-
35
- @Command.arg({
36
- description: 'The name of the controller to create',
37
- type: CommandArgumentType.STRING
38
- })
39
- private name?: string;
40
-
41
- @Command.arg({
42
- description: 'The module where the controller will be created',
43
- type: CommandArgumentType.STRING
44
- })
45
- private module?: string;
46
-
47
- @Command.arg({
48
- description: 'Whether to create a HTTP controller',
49
- type: CommandArgumentType.BOOLEAN,
50
- default: false
51
- })
52
- private http: boolean = false;
53
-
54
- @Command.arg({
55
- description: 'Whether to create a WAMP controller',
56
- type: CommandArgumentType.BOOLEAN,
57
- default: false
58
- })
59
- private wamp: boolean = false;
60
-
61
- @Command.arg({
62
- description: 'Whether to create a WebSocket controller',
63
- type: CommandArgumentType.BOOLEAN,
64
- default: false
65
- })
66
- private ws: boolean = false;
67
-
68
- @Command.arg({
69
- description: 'Whether to create a SERVER scope controller',
70
- type: CommandArgumentType.BOOLEAN,
71
- default: false
72
- })
73
- private server: boolean = false;
74
-
75
- @Command.arg({
76
- description: 'Whether to create a REQUEST scope controller',
77
- type: CommandArgumentType.BOOLEAN,
78
- default: false
79
- })
80
- private request: boolean = false;
81
-
82
- @Command.arg({
83
- description: 'The path or URL of the controller',
84
- type: CommandArgumentType.STRING
85
- })
86
- private path: string = '/users';
87
-
88
- @Command.arg({
89
- description: 'The realm of the controller (only applicable to WAMP controllers)',
90
- type: CommandArgumentType.STRING
91
- })
92
- private realm?: string;
93
-
94
- public async run(): Promise<void> {
95
- if (!this.name) {
96
- return this.setup();
97
- }
98
-
99
- const config = await parseProjectConfig();
100
-
101
- const answers: Record<string, any> = {
102
- module: this.module,
103
- type: 'http',
104
- scope: 'SERVER',
105
- name: this.name,
106
- path: this.path,
107
- realm: this.realm ?? 'realm1'
108
- };
109
-
110
- if (!answers.module && !config.mono) {
111
- const module = await prompts({
112
- type: 'select',
113
- name: 'module',
114
- message: 'Module:',
115
- choices: Object.keys(config.modules ?? {}).map((moduleName) => ({
116
- title: moduleName,
117
- value: moduleName
118
- }))
119
- });
120
-
121
- answers.module = module.module;
122
- }
123
-
124
- if (this.http) {
125
- answers.type = 'http';
126
- } else if (this.wamp) {
127
- answers.type = 'wamp';
128
- } else if (this.ws) {
129
- answers.type = 'ws';
130
- }
131
-
132
- if (this.server) {
133
- answers.scope = 'SERVER';
134
- } else if (this.request) {
135
- answers.scope = 'REQUEST';
136
- }
137
-
138
- return this.build(answers);
139
- }
140
-
141
- private async setup(): Promise<void> {
142
- let mode: 'http' | 'wamp' | 'ws' = 'http';
143
-
144
- const config = await parseProjectConfig();
145
-
146
- const items: PromptObject[] = [
147
- {
148
- type() {
149
- return config.mono ? null : 'select';
150
- },
151
- name: 'module',
152
- message: 'Module:',
153
- choices() {
154
- return Object.keys(config.modules ?? {}).map((moduleName) => ({
155
- title: moduleName,
156
- value: moduleName
157
- }));
158
- }
159
- },
160
- {
161
- type: 'select',
162
- name: 'type',
163
- message: 'Controller Type:',
164
- choices: [
165
- { title: 'HTTP', value: 'http' },
166
- { title: 'WAMP', value: 'wamp' },
167
- { title: 'WebSocket', value: 'ws' }
168
- ]
169
- },
170
- {
171
- type: 'text',
172
- name: 'name',
173
- message: 'Controller Name:',
174
- initial: 'UserController',
175
- validate: (value: string) => {
176
- if (value.length < 1) {
177
- return 'Controller name cannot be empty';
178
- }
179
-
180
- return true;
181
- }
182
- },
183
- {
184
- type: 'text',
185
- name: 'path',
186
- message(_prev, values) {
187
- mode = values.type;
188
- return values.type === 'wamp' ? 'Controller URL' : 'Controller Path:';
189
- },
190
- initial(_prev, values) {
191
- return values.type === 'wamp' ? 'ws://localhost:8000' : '/users';
192
- },
193
- validate(value) {
194
- if (mode === 'wamp') {
195
- return value.match(/^wss?:\/\//) ? true : 'The URL must start with ws:// or wss://';
196
- }
197
-
198
- if (value[0] !== '/') {
199
- return 'The path must start with a slash (/)';
200
- }
201
-
202
- return true;
203
- }
204
- },
205
- {
206
- type(_prev, values) {
207
- return values.type === 'http' ? 'select' : null;
208
- },
209
- name: 'scope',
210
- message: 'Controller Scope:',
211
- choices: [
212
- {
213
- title: 'SERVER',
214
- value: 'SERVER',
215
- description:
216
- 'An unique instance of the controller is created for the entire lifecycle of the server.'
217
- },
218
- {
219
- title: 'REQUEST',
220
- value: 'REQUEST',
221
- description: 'An instance of the controller is created for each request.'
222
- }
223
- ]
224
- },
225
- {
226
- type(_prev, values) {
227
- return values.type === 'wamp' ? 'text' : null;
228
- },
229
- name: 'realm',
230
- message: 'Controller Realm:',
231
- initial: 'realm1',
232
- validate(value) {
233
- if (value.length < 1) {
234
- return 'Realm name cannot be empty';
235
- }
236
-
237
- return true;
238
- }
239
- }
240
- ];
241
-
242
- const answers = await prompts(items, {
243
- onCancel: () => {
244
- this.error('Operation cancelled.');
245
- process.exit(0);
246
- }
247
- });
248
-
249
- return this.build(answers);
250
- }
251
-
252
- private async build(answers: Record<string, any>): Promise<void> {
253
- if (!answers.type || !answers.name || !answers.path) {
254
- this.error('Operation cancelled.');
255
- return;
256
- }
257
-
258
- if (!answers.name.endsWith('Controller')) {
259
- answers.name += 'Controller';
260
- }
261
-
262
- // Get stub file
263
- const stubFile = Bun.file(join(getRootPath(), `stubs/${answers.type}.controller.stub`));
264
-
265
- // Format the stub content
266
- const stub = formatter(await stubFile.text(), answers);
267
-
268
- const path = answers.module ? await getModulePath(answers.module) : './src';
269
-
270
- // Write to file
271
- const name = snake(answers.name.replace('Controller', ''));
272
- const file = Bun.file(`${path}/controllers/${answers.type}/${name}.controller.ts`);
273
- await file.write(stub);
274
-
275
- this.success(`Controller ${this.bold(file.name!)} created successfully.`);
276
- }
277
- }
@@ -1,183 +0,0 @@
1
- // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- import type { PromptObject } from 'prompts';
16
-
17
- import { join } from 'node:path';
18
-
19
- import { Command, CommandArgumentType } from '@elysiumjs/core';
20
- import prompts from 'prompts';
21
- import { snake } from 'radash';
22
- import formatter from 'string-template';
23
-
24
- import { getModulePath, parseProjectConfig } from '../config';
25
- import { getRootPath } from '../utils';
26
-
27
- /**
28
- * Maker class for creating Elysium.js jobs.
29
- * @author Axel Nana <axel.nana@workbud.com>
30
- */
31
- export class MakeJobCommand extends Command {
32
- public static readonly command: string = 'make:job';
33
- public static readonly description: string = 'Creates a new job.';
34
-
35
- @Command.arg({
36
- description: 'The name of the job to create',
37
- type: CommandArgumentType.STRING
38
- })
39
- private name?: string;
40
-
41
- @Command.arg({
42
- description: 'The module where the job will be created',
43
- type: CommandArgumentType.STRING
44
- })
45
- private module?: string;
46
-
47
- @Command.arg({
48
- description: 'The alias of the job to create',
49
- type: CommandArgumentType.STRING
50
- })
51
- private alias?: string;
52
-
53
- @Command.arg({
54
- description: 'The name of the queue where the job will be dispatched',
55
- type: CommandArgumentType.STRING,
56
- default: 'default'
57
- })
58
- private queue: string = 'default';
59
-
60
- public async run(): Promise<void> {
61
- if (!this.name) {
62
- return this.setup();
63
- }
64
-
65
- const config = await parseProjectConfig();
66
-
67
- const answers: Record<string, any> = {
68
- module: this.module,
69
- name: this.name,
70
- alias: this.alias,
71
- queue: this.queue ?? 'default'
72
- };
73
-
74
- if (!answers.module && !config.mono) {
75
- const module = await prompts({
76
- type: 'select',
77
- name: 'module',
78
- message: 'Module:',
79
- choices: Object.keys(config.modules ?? {}).map((moduleName) => ({
80
- title: moduleName,
81
- value: moduleName
82
- }))
83
- });
84
-
85
- answers.module = module.module;
86
- }
87
-
88
- return this.build(answers);
89
- }
90
-
91
- private async setup(): Promise<void> {
92
- const config = await parseProjectConfig();
93
-
94
- const items: PromptObject[] = [
95
- {
96
- type() {
97
- return config.mono ? null : 'select';
98
- },
99
- name: 'module',
100
- message: 'Module:',
101
- choices() {
102
- return Object.keys(config.modules ?? {}).map((moduleName) => ({
103
- title: moduleName,
104
- value: moduleName
105
- }));
106
- }
107
- },
108
- {
109
- type: 'text',
110
- name: 'name',
111
- message: 'Job Name:',
112
- initial: 'SendEmailJob',
113
- validate(value: string) {
114
- if (value.length < 1) {
115
- return 'Job name cannot be empty';
116
- }
117
-
118
- return true;
119
- }
120
- },
121
- {
122
- type: 'text',
123
- name: 'alias',
124
- message: 'Job Alias:',
125
- initial(_, values) {
126
- return values.name;
127
- },
128
- validate(value: string) {
129
- if (value.length < 1) {
130
- return 'Job alias cannot be empty';
131
- }
132
-
133
- return true;
134
- }
135
- },
136
- {
137
- type: 'text',
138
- name: 'queue',
139
- message: 'Job Queue:',
140
- initial: 'default'
141
- }
142
- ];
143
-
144
- const answers = await prompts(items, {
145
- onCancel: () => {
146
- this.error('Operation cancelled.');
147
- process.exit(0);
148
- }
149
- });
150
-
151
- return this.build(answers);
152
- }
153
-
154
- private async build(answers: Record<string, any>): Promise<void> {
155
- if (!answers.name) {
156
- this.error('Operation cancelled.');
157
- return;
158
- }
159
-
160
- if (!answers.name.endsWith('Job')) {
161
- answers.name += 'Job';
162
- }
163
-
164
- if (!answers.alias) {
165
- answers.alias = answers.name;
166
- }
167
-
168
- // Get stub file
169
- const stubFile = Bun.file(join(getRootPath(), 'stubs/job.stub'));
170
-
171
- // Format the stub content
172
- const stub = formatter(await stubFile.text(), answers);
173
-
174
- const path = answers.module ? await getModulePath(answers.module) : './src';
175
-
176
- // Write to file
177
- const name = snake(answers.name.replace('Job', ''));
178
- const file = Bun.file(`${path}/jobs/${name}.job.ts`);
179
- await file.write(stub);
180
-
181
- this.success(`Job ${this.bold(file.name!)} created successfully.`);
182
- }
183
- }