@elysiumjs/styx 0.4.0 → 0.5.0
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 +25 -14
- package/package.json +11 -12
- package/src/commands/make_command.ts +7 -2
- package/src/commands/make_controller.ts +7 -2
- package/src/commands/make_job.ts +7 -2
- package/src/commands/make_middleware.ts +7 -2
- package/src/commands/make_model.ts +21 -11
- package/src/commands/make_repository.ts +6 -1
- package/src/commands/make_service.ts +6 -1
- package/src/commands/make_validator.ts +6 -1
- package/src/commands/migration_generate.ts +29 -18
- package/src/commands/migration_run.ts +15 -7
- package/src/commands/module_new.ts +112 -0
- package/src/commands/module_rename.ts +78 -0
- package/src/config.ts +7 -5
- package/src/styx.ts +54 -0
- package/src/utils.ts +126 -1
- package/styx.js +60 -60
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @elysiumjs/styx
|
|
2
2
|
|
|
3
|
-
CLI tool for Elysium.
|
|
3
|
+
CLI tool for Elysium.js framework.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -10,34 +10,45 @@ bun install @elysiumjs/styx
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
The `styx` command needs to be run
|
|
13
|
+
The `styx` command needs to be run inside an Elysium.js project.
|
|
14
14
|
|
|
15
15
|
To create new items:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
bun styx
|
|
19
|
-
bun styx
|
|
20
|
-
bun styx
|
|
21
|
-
bun styx
|
|
22
|
-
bun styx
|
|
18
|
+
bun styx make:command [options]
|
|
19
|
+
bun styx make:controller [options]
|
|
20
|
+
bun styx make:job [options]
|
|
21
|
+
bun styx make:middleware [options]
|
|
22
|
+
bun styx make:model [options]
|
|
23
|
+
bun styx make:repository [options]
|
|
24
|
+
bun styx make:service [options]
|
|
25
|
+
bun styx make:validator [options]
|
|
23
26
|
```
|
|
24
27
|
|
|
25
|
-
To
|
|
28
|
+
To manage migrations:
|
|
26
29
|
|
|
27
30
|
```bash
|
|
28
|
-
bun styx
|
|
31
|
+
bun styx migration:generate [options]
|
|
32
|
+
bun styx migration:run [options]
|
|
29
33
|
```
|
|
30
34
|
|
|
31
|
-
To
|
|
35
|
+
To manage modules:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
bun styx module:new [options]
|
|
39
|
+
bun styx module:rename [options]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
To start the Elysium.js project:
|
|
32
43
|
|
|
33
44
|
```bash
|
|
34
|
-
bun styx
|
|
45
|
+
bun styx serve
|
|
35
46
|
```
|
|
36
47
|
|
|
37
|
-
To
|
|
48
|
+
To execute a custom command:
|
|
38
49
|
|
|
39
50
|
```bash
|
|
40
|
-
bun styx
|
|
51
|
+
bun styx <command>
|
|
41
52
|
```
|
|
42
53
|
|
|
43
54
|
To show all available commands:
|
|
@@ -60,4 +71,4 @@ Feel free to open issues for any bugs or questions you may have. Pull requests a
|
|
|
60
71
|
|
|
61
72
|
## License
|
|
62
73
|
|
|
63
|
-
This project is licensed under the Apache License, Version 2.0. See the [LICENSE](
|
|
74
|
+
This project is licensed under the Apache License, Version 2.0. See the [LICENSE](https://github.com/workbud/elysium/blob/main/LICENSE) file for more information.
|
package/package.json
CHANGED
|
@@ -1,39 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elysiumjs/styx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"description": "The CLI tool for the Elysium framework.",
|
|
5
|
+
"description": "The CLI tool for the Elysium.js framework.",
|
|
6
6
|
"private": false,
|
|
7
|
-
"author":
|
|
8
|
-
"name": "Axel Nana",
|
|
9
|
-
"email": "axel.nana@workbud.com"
|
|
10
|
-
},
|
|
7
|
+
"author": "Workbud Technologies Inc.",
|
|
11
8
|
"repository": {
|
|
12
9
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/
|
|
10
|
+
"url": "https://github.com/workbud/elysium"
|
|
14
11
|
},
|
|
15
|
-
"homepage": "https://github.com/
|
|
12
|
+
"homepage": "https://github.com/workbud/elysium",
|
|
16
13
|
"scripts": {
|
|
17
14
|
"format": "prettier --write \"./src/**/*.ts\"",
|
|
18
|
-
"build": "bun build
|
|
15
|
+
"build": "bun build ./src/styx.ts --outdir=./ --root ./src --target bun --minify -e @elysiumjs/core -e reflect-metadata",
|
|
16
|
+
"prepublishOnly": "bun run build"
|
|
19
17
|
},
|
|
20
18
|
"keywords": [
|
|
21
19
|
"elysium",
|
|
22
20
|
"framework",
|
|
23
21
|
"web",
|
|
24
22
|
"api",
|
|
25
|
-
"typescript"
|
|
23
|
+
"typescript",
|
|
24
|
+
"cli"
|
|
26
25
|
],
|
|
27
26
|
"type": "module",
|
|
28
27
|
"bin": {
|
|
29
28
|
"styx": "./styx.js"
|
|
30
29
|
},
|
|
31
30
|
"devDependencies": {
|
|
32
|
-
"@ianvs/prettier-plugin-sort-imports": "^4.4.
|
|
31
|
+
"@ianvs/prettier-plugin-sort-imports": "^4.4.2",
|
|
33
32
|
"@types/bun": "latest",
|
|
34
33
|
"@types/prompts": "^2.4.9",
|
|
35
34
|
"@types/string-template": "^1.0.6",
|
|
36
|
-
"type-fest": "^4.
|
|
35
|
+
"type-fest": "^4.41.0",
|
|
37
36
|
"prompts": "^2.4.2",
|
|
38
37
|
"radash": "^12.1.0",
|
|
39
38
|
"string-template": "^1.0.0"
|
|
@@ -25,7 +25,7 @@ import { getModulePath, parseProjectConfig } from '../config';
|
|
|
25
25
|
import { getRootPath } from '../utils';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Maker class for creating Elysium commands.
|
|
28
|
+
* Maker class for creating Elysium.js commands.
|
|
29
29
|
* @author Axel Nana <axel.nana@workbud.com>
|
|
30
30
|
*/
|
|
31
31
|
export class MakeCommandCommand extends Command {
|
|
@@ -132,7 +132,12 @@ export class MakeCommandCommand extends Command {
|
|
|
132
132
|
}
|
|
133
133
|
];
|
|
134
134
|
|
|
135
|
-
const answers = await prompts(items
|
|
135
|
+
const answers = await prompts(items, {
|
|
136
|
+
onCancel: () => {
|
|
137
|
+
this.error('Operation cancelled.');
|
|
138
|
+
process.exit(0);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
136
141
|
|
|
137
142
|
answers.name = pascal(answers.command.replaceAll(':', '_'));
|
|
138
143
|
|
|
@@ -25,7 +25,7 @@ import { getModulePath, parseProjectConfig } from '../config';
|
|
|
25
25
|
import { getRootPath } from '../utils';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Maker class for creating Elysium controllers.
|
|
28
|
+
* Maker class for creating Elysium.js controllers.
|
|
29
29
|
* @author Axel Nana <axel.nana@workbud.com>
|
|
30
30
|
*/
|
|
31
31
|
export class MakeControllerCommand extends Command {
|
|
@@ -239,7 +239,12 @@ export class MakeControllerCommand extends Command {
|
|
|
239
239
|
}
|
|
240
240
|
];
|
|
241
241
|
|
|
242
|
-
const answers = await prompts(items
|
|
242
|
+
const answers = await prompts(items, {
|
|
243
|
+
onCancel: () => {
|
|
244
|
+
this.error('Operation cancelled.');
|
|
245
|
+
process.exit(0);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
243
248
|
|
|
244
249
|
return this.build(answers);
|
|
245
250
|
}
|
package/src/commands/make_job.ts
CHANGED
|
@@ -25,7 +25,7 @@ import { getModulePath, parseProjectConfig } from '../config';
|
|
|
25
25
|
import { getRootPath } from '../utils';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Maker class for creating Elysium jobs.
|
|
28
|
+
* Maker class for creating Elysium.js jobs.
|
|
29
29
|
* @author Axel Nana <axel.nana@workbud.com>
|
|
30
30
|
*/
|
|
31
31
|
export class MakeJobCommand extends Command {
|
|
@@ -141,7 +141,12 @@ export class MakeJobCommand extends Command {
|
|
|
141
141
|
}
|
|
142
142
|
];
|
|
143
143
|
|
|
144
|
-
const answers = await prompts(items
|
|
144
|
+
const answers = await prompts(items, {
|
|
145
|
+
onCancel: () => {
|
|
146
|
+
this.error('Operation cancelled.');
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
145
150
|
|
|
146
151
|
return this.build(answers);
|
|
147
152
|
}
|
|
@@ -25,7 +25,7 @@ import { getModulePath, parseProjectConfig } from '../config';
|
|
|
25
25
|
import { getRootPath } from '../utils';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Maker class for creating Elysium middlewares.
|
|
28
|
+
* Maker class for creating Elysium.js middlewares.
|
|
29
29
|
* @author Axel Nana <axel.nana@workbud.com>
|
|
30
30
|
*/
|
|
31
31
|
export class MakeMiddlewareCommand extends Command {
|
|
@@ -105,7 +105,12 @@ export class MakeMiddlewareCommand extends Command {
|
|
|
105
105
|
}
|
|
106
106
|
];
|
|
107
107
|
|
|
108
|
-
const answers = await prompts(items
|
|
108
|
+
const answers = await prompts(items, {
|
|
109
|
+
onCancel: () => {
|
|
110
|
+
this.error('Operation cancelled.');
|
|
111
|
+
process.exit(0);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
109
114
|
|
|
110
115
|
return this.build(answers);
|
|
111
116
|
}
|
|
@@ -25,7 +25,7 @@ import { getModulePath, parseProjectConfig } from '../config';
|
|
|
25
25
|
import { getRootPath } from '../utils';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Maker command for creating Elysium models.
|
|
28
|
+
* Maker command for creating Elysium.js models.
|
|
29
29
|
* @author Axel Nana <axel.nana@workbud.com>
|
|
30
30
|
*/
|
|
31
31
|
export class MakeModelCommand extends Command {
|
|
@@ -74,15 +74,20 @@ export class MakeModelCommand extends Command {
|
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
if (!answers.module && !config.mono) {
|
|
77
|
-
const module = await prompts(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
77
|
+
const module = await prompts(
|
|
78
|
+
{
|
|
79
|
+
type: 'select',
|
|
80
|
+
name: 'module',
|
|
81
|
+
message: 'Module:',
|
|
82
|
+
choices: Object.keys(config.modules ?? {}).map((moduleName) => ({
|
|
83
|
+
title: moduleName,
|
|
84
|
+
value: moduleName
|
|
85
|
+
}))
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
onCancel: () => process.exit(1)
|
|
89
|
+
}
|
|
90
|
+
);
|
|
86
91
|
|
|
87
92
|
answers.module = module.module;
|
|
88
93
|
}
|
|
@@ -160,7 +165,12 @@ export class MakeModelCommand extends Command {
|
|
|
160
165
|
}
|
|
161
166
|
];
|
|
162
167
|
|
|
163
|
-
const answers = await prompts(items
|
|
168
|
+
const answers = await prompts(items, {
|
|
169
|
+
onCancel: () => {
|
|
170
|
+
this.error('Operation cancelled.');
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
164
174
|
|
|
165
175
|
return this.build(answers);
|
|
166
176
|
}
|
|
@@ -179,7 +179,12 @@ export class MakeRepositoryCommand extends Command {
|
|
|
179
179
|
}
|
|
180
180
|
];
|
|
181
181
|
|
|
182
|
-
const answers = await prompts(items
|
|
182
|
+
const answers = await prompts(items, {
|
|
183
|
+
onCancel: () => {
|
|
184
|
+
this.error('Operation cancelled.');
|
|
185
|
+
process.exit(0);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
183
188
|
|
|
184
189
|
return this.build(answers);
|
|
185
190
|
}
|
|
@@ -159,7 +159,12 @@ export class MakeServiceCommand extends Command {
|
|
|
159
159
|
}
|
|
160
160
|
];
|
|
161
161
|
|
|
162
|
-
const answers = await prompts(items
|
|
162
|
+
const answers = await prompts(items, {
|
|
163
|
+
onCancel: () => {
|
|
164
|
+
this.error('Operation cancelled.');
|
|
165
|
+
process.exit(0);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
163
168
|
|
|
164
169
|
return this.build(answers);
|
|
165
170
|
}
|
|
@@ -105,7 +105,12 @@ export class MakeValidatorCommand extends Command {
|
|
|
105
105
|
}
|
|
106
106
|
];
|
|
107
107
|
|
|
108
|
-
const answers = await prompts(items
|
|
108
|
+
const answers = await prompts(items, {
|
|
109
|
+
onCancel: () => {
|
|
110
|
+
this.error('Operation cancelled.');
|
|
111
|
+
process.exit(0);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
109
114
|
|
|
110
115
|
return this.build(answers);
|
|
111
116
|
}
|
|
@@ -17,6 +17,8 @@ import { exists } from 'node:fs/promises';
|
|
|
17
17
|
import { Command, CommandArgumentType } from '@elysiumjs/core';
|
|
18
18
|
import prompts from 'prompts';
|
|
19
19
|
|
|
20
|
+
import { getProjectPath } from '../utils';
|
|
21
|
+
|
|
20
22
|
/**
|
|
21
23
|
* Generates migration files.
|
|
22
24
|
* @author Axel Nana <axel.nana@workbud.com>
|
|
@@ -33,37 +35,46 @@ export class MigrationGenerateCommand extends Command {
|
|
|
33
35
|
|
|
34
36
|
public async run(): Promise<void> {
|
|
35
37
|
if (!this.name) {
|
|
36
|
-
const answers = await prompts(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
const answers = await prompts(
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
type: 'text',
|
|
42
|
+
name: 'name',
|
|
43
|
+
message: 'Migration Name:',
|
|
44
|
+
initial: 'create_users_table',
|
|
45
|
+
validate(value: string) {
|
|
46
|
+
if (value.length < 1) {
|
|
47
|
+
return 'Migration name cannot be empty';
|
|
48
|
+
}
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
{
|
|
55
|
+
onCancel: () => {
|
|
56
|
+
this.error('Operation cancelled.');
|
|
57
|
+
process.exit(0);
|
|
48
58
|
}
|
|
49
59
|
}
|
|
50
|
-
|
|
60
|
+
);
|
|
51
61
|
|
|
52
62
|
this.name = answers.name;
|
|
53
63
|
}
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
const projectRoot = getProjectPath();
|
|
66
|
+
let schemaPath = `${projectRoot}/src/database/schemas`;
|
|
67
|
+
if (await exists(`${projectRoot}/src/database/schema.ts`)) {
|
|
68
|
+
schemaPath = `${projectRoot}/src/database/schema.ts`;
|
|
58
69
|
}
|
|
59
70
|
|
|
60
|
-
await Bun.$`bunx --bun drizzle-kit generate --dialect postgresql --schema ${schemaPath} --out
|
|
71
|
+
await Bun.$`bunx --bun drizzle-kit generate --dialect postgresql --schema ${schemaPath} --out ${projectRoot}/src/database/migrations --prefix timestamp --name ${this.name}`;
|
|
61
72
|
|
|
62
|
-
const sqlFiles = new Bun.Glob(`${
|
|
73
|
+
const sqlFiles = new Bun.Glob(`${projectRoot}/src/database/migrations/**/*.sql`).scan();
|
|
63
74
|
for await (const path of sqlFiles) {
|
|
64
75
|
const file = Bun.file(path);
|
|
65
76
|
const content = await file.text();
|
|
66
|
-
await file.write(content.replace(/"public"
|
|
77
|
+
await file.write(content.replace(/"public"\./gm, ''));
|
|
67
78
|
}
|
|
68
79
|
}
|
|
69
80
|
}
|
|
@@ -69,14 +69,22 @@ export class MigrationRunCommand extends Command {
|
|
|
69
69
|
) AS schema_exists;`;
|
|
70
70
|
|
|
71
71
|
if (!schema_exists) {
|
|
72
|
-
const answers = await prompts(
|
|
72
|
+
const answers = await prompts(
|
|
73
|
+
[
|
|
74
|
+
{
|
|
75
|
+
type: 'confirm',
|
|
76
|
+
name: 'create',
|
|
77
|
+
message: `Schema ${this.tenant} does not exist. Do you want to create it?`,
|
|
78
|
+
initial: true
|
|
79
|
+
}
|
|
80
|
+
],
|
|
73
81
|
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
onCancel: () => {
|
|
83
|
+
this.error('Operation cancelled.');
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
78
86
|
}
|
|
79
|
-
|
|
87
|
+
);
|
|
80
88
|
|
|
81
89
|
if (answers.create) {
|
|
82
90
|
await sql`CREATE SCHEMA ${sql(this.tenant)};`;
|
|
@@ -91,7 +99,7 @@ export class MigrationRunCommand extends Command {
|
|
|
91
99
|
const [{ table_exists }] = await sql`SELECT EXISTS (
|
|
92
100
|
SELECT *
|
|
93
101
|
FROM information_schema.tables
|
|
94
|
-
WHERE table_name = 'elysium_migrations'
|
|
102
|
+
WHERE table_name = 'elysium_migrations'
|
|
95
103
|
AND table_schema = ${this.tenant}
|
|
96
104
|
) AS table_exists;`;
|
|
97
105
|
|
|
@@ -0,0 +1,112 @@
|
|
|
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 { exists, rmdir } from 'node:fs/promises';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
|
|
18
|
+
import { Command, CommandArgumentType } from '@elysiumjs/core';
|
|
19
|
+
import prompts from 'prompts';
|
|
20
|
+
import { snake } from 'radash';
|
|
21
|
+
|
|
22
|
+
import { parseProjectConfig } from '../config';
|
|
23
|
+
import { createModule, getProjectPath } from '../utils';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Command for creating Elysium.js modules.
|
|
27
|
+
* @author Axel Nana <axel.nana@workbud.com>
|
|
28
|
+
*/
|
|
29
|
+
export class ModuleNewCommand extends Command {
|
|
30
|
+
public static readonly command: string = 'module:new';
|
|
31
|
+
public static readonly description: string = 'Creates a new module.';
|
|
32
|
+
|
|
33
|
+
@Command.arg({
|
|
34
|
+
description: 'The name of the module to create',
|
|
35
|
+
type: CommandArgumentType.STRING
|
|
36
|
+
})
|
|
37
|
+
private name?: string;
|
|
38
|
+
|
|
39
|
+
private module?: string;
|
|
40
|
+
private convert: boolean = false;
|
|
41
|
+
|
|
42
|
+
public override async run(): Promise<void> {
|
|
43
|
+
const config = await parseProjectConfig();
|
|
44
|
+
|
|
45
|
+
// 1. Prompt for new module name if not provided
|
|
46
|
+
if (!this.name) {
|
|
47
|
+
const name = await prompts(
|
|
48
|
+
{
|
|
49
|
+
type: 'text',
|
|
50
|
+
name: 'name',
|
|
51
|
+
message: 'New module name:',
|
|
52
|
+
initial: 'module',
|
|
53
|
+
validate(value) {
|
|
54
|
+
return value.length > 0 ? true : 'Module name cannot be empty';
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
onCancel: () => process.exit(0)
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
this.name = snake(name.name);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 2. If mono-module, prompt for conversion and current module name
|
|
66
|
+
if (config.mono) {
|
|
67
|
+
const { module, convert } = await prompts(
|
|
68
|
+
[
|
|
69
|
+
{
|
|
70
|
+
type: 'confirm',
|
|
71
|
+
name: 'convert',
|
|
72
|
+
message:
|
|
73
|
+
'This project is a mono-module project. Do you want to convert it to a multi-module project?',
|
|
74
|
+
initial: false
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: (convert) => (convert ? 'text' : null),
|
|
78
|
+
name: 'module',
|
|
79
|
+
message: 'Current module name:',
|
|
80
|
+
initial: 'main',
|
|
81
|
+
validate(value) {
|
|
82
|
+
return value.length > 0 ? true : 'Module name cannot be empty';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
{
|
|
87
|
+
onCancel: () => process.exit(0)
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
if (!convert) return this.error('Operation cancelled. The project is left unchanged.');
|
|
92
|
+
|
|
93
|
+
this.module = snake(module as string);
|
|
94
|
+
this.convert = convert;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 3. If multi-module conversion is enabled, convert the project to a multi-module project
|
|
98
|
+
if (this.convert) {
|
|
99
|
+
const modulesDir = join(getProjectPath(), 'src', 'modules');
|
|
100
|
+
if (await exists(modulesDir)) await rmdir(modulesDir, { recursive: true });
|
|
101
|
+
|
|
102
|
+
await createModule(this.module!, 'root');
|
|
103
|
+
|
|
104
|
+
this.success(`Project converted to multi-module.`);
|
|
105
|
+
this.success(`Module '${this.module}' created.`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 4. Create the new module
|
|
109
|
+
await createModule(this.name);
|
|
110
|
+
this.success(`Module '${this.name}' created.`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
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 { Command, CommandArgumentType } from '@elysiumjs/core';
|
|
16
|
+
import prompts from 'prompts';
|
|
17
|
+
|
|
18
|
+
import { parseProjectConfig } from '../config';
|
|
19
|
+
import { createModule } from '../utils';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Command for renaming Elysium.js modules.
|
|
23
|
+
* @author Axel Nana <axel.nana@workbud.com>
|
|
24
|
+
*/
|
|
25
|
+
export class ModuleRenameCommand extends Command {
|
|
26
|
+
public static readonly command: string = 'module:rename';
|
|
27
|
+
public static readonly description: string = 'Renames a module.';
|
|
28
|
+
|
|
29
|
+
@Command.arg({
|
|
30
|
+
description: 'The module to rename',
|
|
31
|
+
type: CommandArgumentType.STRING
|
|
32
|
+
})
|
|
33
|
+
private module?: string;
|
|
34
|
+
|
|
35
|
+
@Command.arg({
|
|
36
|
+
description: 'The new name of the module',
|
|
37
|
+
type: CommandArgumentType.STRING
|
|
38
|
+
})
|
|
39
|
+
private name?: string;
|
|
40
|
+
|
|
41
|
+
public override async run(): Promise<void> {
|
|
42
|
+
const config = await parseProjectConfig();
|
|
43
|
+
|
|
44
|
+
if (config.mono) {
|
|
45
|
+
return this.error('This operation is not supported for mono-module projects.');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!this.module) {
|
|
49
|
+
const { module } = await prompts({
|
|
50
|
+
type: 'text',
|
|
51
|
+
name: 'module',
|
|
52
|
+
message: 'Module to rename:',
|
|
53
|
+
validate: (value) => value.length > 0
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
this.module = module as string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!this.name) {
|
|
60
|
+
const { name } = await prompts({
|
|
61
|
+
type: 'text',
|
|
62
|
+
name: 'name',
|
|
63
|
+
message: 'New module name:',
|
|
64
|
+
initial: this.module,
|
|
65
|
+
validate: (value) => value.length > 0
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
this.name = name as string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (this.module === this.name) {
|
|
72
|
+
return this.info('Module name is the same as the current name.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
await createModule(this.name!, this.module!);
|
|
76
|
+
this.success(`Module '${this.module}' renamed to '${this.name}'.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
|
|
17
|
+
import { getProjectPath } from './utils';
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Describes the Elysium project's configuration.
|
|
@@ -44,12 +46,12 @@ export interface ProjectConfig {
|
|
|
44
46
|
* @returns The Elysium project's configuration.
|
|
45
47
|
*/
|
|
46
48
|
export const parseProjectConfig = async (): Promise<ProjectConfig> => {
|
|
47
|
-
const
|
|
48
|
-
if (!
|
|
49
|
+
const file = Bun.file(join(getProjectPath(), '.elysiumrc'));
|
|
50
|
+
if (!file.exists()) {
|
|
49
51
|
throw new Error('Elysium config file not found.');
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
return
|
|
54
|
+
return file.json();
|
|
53
55
|
};
|
|
54
56
|
|
|
55
57
|
/**
|
|
@@ -58,7 +60,7 @@ export const parseProjectConfig = async (): Promise<ProjectConfig> => {
|
|
|
58
60
|
* @param config The Elysium project's configuration.
|
|
59
61
|
*/
|
|
60
62
|
export const writeProjectConfig = async (config: ProjectConfig) => {
|
|
61
|
-
const file = Bun.file(
|
|
63
|
+
const file = Bun.file(join(getProjectPath(), '.elysiumrc'));
|
|
62
64
|
await file.write(JSON.stringify(config, null, 2));
|
|
63
65
|
};
|
|
64
66
|
|