generator-discord 1.2.7 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/index.d.ts +4 -3
- package/app/index.d.ts.map +1 -0
- package/app/index.js +90 -91
- package/app/index.js.map +1 -1
- package/package.json +12 -8
- package/src/index.ts +66 -36
- package/test/generator.test.ts +70 -56
- /package/templates/python/{bot.py → main.py} +0 -0
package/app/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import Generator from 'yeoman-generator';
|
|
3
3
|
type BotType = 'typescript' | 'javascript' | 'python' | 'rust';
|
|
4
4
|
interface Answers {
|
|
@@ -9,12 +9,13 @@ interface Answers {
|
|
|
9
9
|
}
|
|
10
10
|
export default class DiscordGenerator extends Generator {
|
|
11
11
|
private answers;
|
|
12
|
-
constructor(args: string | string[], options:
|
|
12
|
+
constructor(args: string | string[], options: Record<string, unknown>);
|
|
13
13
|
prompting(): Promise<void>;
|
|
14
14
|
logo(): void;
|
|
15
15
|
writing(): void;
|
|
16
16
|
install(): Promise<void>;
|
|
17
17
|
end(): Promise<void>;
|
|
18
|
-
_replaceWords(content: Buffer, answers: Answers): string;
|
|
18
|
+
_replaceWords(content: string | Buffer, answers: Answers): string;
|
|
19
19
|
}
|
|
20
20
|
export {};
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,SAAS,MAAM,kBAAkB,CAAC;AAYzC,KAAK,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE/D,UAAU,OAAO;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;CACtB;AA0BD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,SAAS;IACtD,OAAO,CAAC,OAAO,CAA0B;gBAE7B,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI/D,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDhC,IAAI,IAAI,IAAI;IAYZ,OAAO,IAAI,IAAI;IAuBT,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBxB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB1B,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM;CAWjE"}
|
package/app/index.js
CHANGED
|
@@ -1,74 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const yeoman_generator_1 = __importDefault(require("yeoman-generator"));
|
|
16
|
-
const path_1 = __importDefault(require("path"));
|
|
1
|
+
import Generator from 'yeoman-generator';
|
|
2
|
+
import path from 'path';
|
|
17
3
|
const TEMPLATE_DIR = '../templates/';
|
|
18
4
|
const USER_DIR = '.';
|
|
19
5
|
const BOT_NAME = /<%= bot-name %>/g;
|
|
20
6
|
const BOT_TOKEN = /<%= bot-token %>/g;
|
|
21
7
|
// needed for rust
|
|
22
8
|
const BOT_NAME_RUST = /bot_name/g;
|
|
23
|
-
|
|
9
|
+
const botNameValidation = {
|
|
10
|
+
typescript: {
|
|
11
|
+
regex: new RegExp('^(?:@[a-z0-9-*~][a-z0-9-*._~]*/)?[a-z0-9-~][a-z0-9-._~]*$'),
|
|
12
|
+
errorMessage: 'Invalid bot name. Please use only lowercase letters, numbers, and hyphens. Must start with a letter.'
|
|
13
|
+
},
|
|
14
|
+
javascript: {
|
|
15
|
+
regex: new RegExp('^(?:@[a-z0-9-*~][a-z0-9-*._~]*/)?[a-z0-9-~][a-z0-9-._~]*$'),
|
|
16
|
+
errorMessage: 'Invalid bot name. Please use only lowercase letters, numbers, and hyphens. Must start with a letter.'
|
|
17
|
+
},
|
|
18
|
+
python: {
|
|
19
|
+
regex: new RegExp('^[a-zA-Z0-9_]+$'),
|
|
20
|
+
errorMessage: 'Invalid bot name. Please use only letters, numbers, and underscores. Must start with a letter.'
|
|
21
|
+
},
|
|
22
|
+
rust: {
|
|
23
|
+
regex: new RegExp('/^[a-z][a-z0-9_-]*$/'),
|
|
24
|
+
errorMessage: 'Invalid bot name. Please use only lowercase letters, numbers, underscores, and hyphens. Must start with a letter.'
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
export default class DiscordGenerator extends Generator {
|
|
28
|
+
answers = {};
|
|
24
29
|
constructor(args, options) {
|
|
25
30
|
super(args, options);
|
|
26
|
-
this.answers = {};
|
|
27
31
|
}
|
|
28
|
-
prompting() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
async prompting() {
|
|
33
|
+
this.logo();
|
|
34
|
+
const askBotType = await this.prompt({
|
|
35
|
+
type: 'list',
|
|
36
|
+
name: 'botType',
|
|
37
|
+
message: 'The type of Discord Bot you want to create.',
|
|
38
|
+
choices: [
|
|
32
39
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
message: 'Your Discord Bot name:',
|
|
36
|
-
default: 'my-bot',
|
|
37
|
-
validate: (input) => new RegExp('^(?:@[a-z0-9-*~][a-z0-9-*._~]*/)?[a-z0-9-~][a-z0-9-._~]*$').test(input)
|
|
38
|
-
? true
|
|
39
|
-
: 'Invalid bot name. Please use only lowercase letters, numbers, and hyphens. Must start with a letter.'
|
|
40
|
+
name: 'New Discord Bot (TypeScript)',
|
|
41
|
+
value: 'typescript'
|
|
40
42
|
},
|
|
41
43
|
{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
message: 'The type of Discord Bot you want to create.',
|
|
45
|
-
choices: [
|
|
46
|
-
{
|
|
47
|
-
name: 'New Discord Bot (TypeScript)',
|
|
48
|
-
value: 'typescript'
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
name: 'New Discord Bot (JavaScript)',
|
|
52
|
-
value: 'javascript'
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'New Discord Bot (Python)',
|
|
56
|
-
value: 'python'
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: 'New Discord Bot (Rust)',
|
|
60
|
-
value: 'rust'
|
|
61
|
-
},
|
|
62
|
-
]
|
|
44
|
+
name: 'New Discord Bot (JavaScript)',
|
|
45
|
+
value: 'javascript'
|
|
63
46
|
},
|
|
64
47
|
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
48
|
+
name: 'New Discord Bot (Python)',
|
|
49
|
+
value: 'python'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'New Discord Bot (Rust)',
|
|
53
|
+
value: 'rust'
|
|
54
|
+
},
|
|
55
|
+
]
|
|
71
56
|
});
|
|
57
|
+
this.answers = await this.prompt([
|
|
58
|
+
{
|
|
59
|
+
type: 'input',
|
|
60
|
+
name: 'botName',
|
|
61
|
+
message: 'Your Discord Bot name:',
|
|
62
|
+
default: 'my-bot',
|
|
63
|
+
validate: (input) => botNameValidation[askBotType.botType].regex.test(input) ? true : botNameValidation[askBotType.botType].errorMessage
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'input',
|
|
67
|
+
name: 'botToken',
|
|
68
|
+
message: 'Your Discord Bot Token. (Enter to leave blank)',
|
|
69
|
+
default: 'your-bot-token'
|
|
70
|
+
}
|
|
71
|
+
]);
|
|
72
|
+
this.answers.botType = askBotType.botType;
|
|
72
73
|
}
|
|
73
74
|
logo() {
|
|
74
75
|
this.log(' \x1b[36m_____ _ _ \x1b[31m_');
|
|
@@ -82,8 +83,9 @@ class DiscordGenerator extends yeoman_generator_1.default {
|
|
|
82
83
|
this.log('\x1b[0m');
|
|
83
84
|
}
|
|
84
85
|
writing() {
|
|
85
|
-
|
|
86
|
+
const currentUrl = new URL('.', import.meta.url).pathname;
|
|
86
87
|
const paths = ['.'];
|
|
88
|
+
this.sourceRoot(path.join(currentUrl, TEMPLATE_DIR + this.answers.botType));
|
|
87
89
|
// iterate over all files
|
|
88
90
|
for (let i = 0, len = paths.length; i < len; i++) {
|
|
89
91
|
const path = paths[i];
|
|
@@ -92,43 +94,41 @@ class DiscordGenerator extends yeoman_generator_1.default {
|
|
|
92
94
|
});
|
|
93
95
|
}
|
|
94
96
|
}
|
|
95
|
-
install() {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
async install() {
|
|
98
|
+
this.log('');
|
|
99
|
+
if (this.answers.botType === 'typescript' || this.answers.botType === 'javascript') {
|
|
100
|
+
const options = { cwd: this.destinationPath(USER_DIR, this.answers.botName) };
|
|
101
|
+
if (this.answers.botType === 'typescript' || this.answers.botType === 'javascript' && !this.args.includes('skip-install')) {
|
|
100
102
|
this.log('Installing dependencies...');
|
|
101
|
-
this.
|
|
102
|
-
if (this.answers.botType === 'typescript') {
|
|
103
|
-
this.log('Building your Discord Bot...');
|
|
104
|
-
this.spawnCommandSync('npm', ['run', 'build'], options);
|
|
105
|
-
}
|
|
103
|
+
await this.spawn('npm', ['install'], options);
|
|
106
104
|
}
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
end() {
|
|
111
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
-
const answer = yield this.prompt({
|
|
113
|
-
type: 'list',
|
|
114
|
-
name: 'openWithCode',
|
|
115
|
-
message: 'Do you want to open your Discord Bot with \x1b[36mVisual Studio Code\x1b[0m?',
|
|
116
|
-
choices: [
|
|
117
|
-
{
|
|
118
|
-
name: 'open with `code`',
|
|
119
|
-
value: true
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: 'skip',
|
|
123
|
-
value: false
|
|
124
|
-
}
|
|
125
|
-
]
|
|
126
|
-
});
|
|
127
|
-
this.log('');
|
|
128
|
-
if (answer && answer.openWithCode) {
|
|
129
|
-
this.spawnCommand('code', [this.destinationPath(USER_DIR, this.answers.botName)]);
|
|
105
|
+
if (this.answers.botType === 'typescript' && !this.args.includes('skip-build')) {
|
|
106
|
+
this.log('Building your Discord Bot...');
|
|
107
|
+
await this.spawn('npm', ['run', 'build'], options);
|
|
130
108
|
}
|
|
109
|
+
}
|
|
110
|
+
this.log('Your Discord Bot \'\x1b[32m' + this.answers.botName + '\x1b[0m\' has been created!');
|
|
111
|
+
}
|
|
112
|
+
async end() {
|
|
113
|
+
const answer = await this.prompt({
|
|
114
|
+
type: 'list',
|
|
115
|
+
name: 'openWithCode',
|
|
116
|
+
message: 'Do you want to open your Discord Bot with \x1b[36mVisual Studio Code\x1b[0m?',
|
|
117
|
+
choices: [
|
|
118
|
+
{
|
|
119
|
+
name: 'open with `code`',
|
|
120
|
+
value: true
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'skip',
|
|
124
|
+
value: false
|
|
125
|
+
}
|
|
126
|
+
]
|
|
131
127
|
});
|
|
128
|
+
this.log('');
|
|
129
|
+
if (answer && answer.openWithCode) {
|
|
130
|
+
this.spawn('code', [this.destinationPath(USER_DIR, this.answers.botName)]);
|
|
131
|
+
}
|
|
132
132
|
}
|
|
133
133
|
_replaceWords(content, answers) {
|
|
134
134
|
if (answers.botType === 'rust') {
|
|
@@ -141,5 +141,4 @@ class DiscordGenerator extends yeoman_generator_1.default {
|
|
|
141
141
|
.replace(BOT_NAME, answers.botName);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
exports.default = DiscordGenerator;
|
|
145
144
|
//# sourceMappingURL=index.js.map
|
package/app/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generator-discord",
|
|
3
3
|
"displayName": "Generator-Discord",
|
|
4
|
-
"version": "1.
|
|
5
|
-
"
|
|
4
|
+
"version": "1.3.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": "./app/index.js",
|
|
6
7
|
"description": "Yeoman generator for Discord.js",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=16.0.0"
|
|
10
|
+
},
|
|
7
11
|
"keywords": [
|
|
8
12
|
"yeoman-generator",
|
|
9
13
|
"discord.js",
|
|
@@ -15,7 +19,7 @@
|
|
|
15
19
|
"watch": "tsc -w",
|
|
16
20
|
"test": "vitest run",
|
|
17
21
|
"lint": "eslint src test --ext .ts",
|
|
18
|
-
"
|
|
22
|
+
"lint:fix": "eslint src test --ext .ts --fix",
|
|
19
23
|
"clean": "npx rimraf app && npx rimraf node_modules"
|
|
20
24
|
},
|
|
21
25
|
"files": [
|
|
@@ -36,14 +40,14 @@
|
|
|
36
40
|
},
|
|
37
41
|
"homepage": "https://github.com/emilkrebs/Generator-Discord",
|
|
38
42
|
"dependencies": {
|
|
39
|
-
"yeoman-generator": "^
|
|
43
|
+
"yeoman-generator": "^7.0.0"
|
|
40
44
|
},
|
|
41
45
|
"devDependencies": {
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
43
|
-
"@typescript-eslint/parser": "^6.
|
|
44
|
-
"eslint": "^8.
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
|
47
|
+
"@typescript-eslint/parser": "^6.9.0",
|
|
48
|
+
"eslint": "^8.52.0",
|
|
45
49
|
"typescript": "^5.2.2",
|
|
46
50
|
"vitest": "^0.34.6",
|
|
47
|
-
"yeoman-test": "^
|
|
51
|
+
"yeoman-test": "^8.1.0"
|
|
48
52
|
}
|
|
49
53
|
}
|
package/src/index.ts
CHANGED
|
@@ -19,49 +19,73 @@ interface Answers {
|
|
|
19
19
|
openWithCode: boolean;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
interface BotNameValidation {
|
|
23
|
+
regex: RegExp;
|
|
24
|
+
errorMessage: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const botNameValidation: Record<BotType, BotNameValidation> = {
|
|
28
|
+
typescript: {
|
|
29
|
+
regex: new RegExp('^(?:@[a-z0-9-*~][a-z0-9-*._~]*/)?[a-z0-9-~][a-z0-9-._~]*$'),
|
|
30
|
+
errorMessage: 'Invalid bot name. Please use only lowercase letters, numbers, and hyphens. Must start with a letter.'
|
|
31
|
+
},
|
|
32
|
+
javascript: {
|
|
33
|
+
regex: new RegExp('^(?:@[a-z0-9-*~][a-z0-9-*._~]*/)?[a-z0-9-~][a-z0-9-._~]*$'),
|
|
34
|
+
errorMessage: 'Invalid bot name. Please use only lowercase letters, numbers, and hyphens. Must start with a letter.'
|
|
35
|
+
},
|
|
36
|
+
python: {
|
|
37
|
+
regex: new RegExp('^[a-zA-Z0-9_]+$'),
|
|
38
|
+
errorMessage: 'Invalid bot name. Please use only letters, numbers, and underscores. Must start with a letter.'
|
|
39
|
+
},
|
|
40
|
+
rust: {
|
|
41
|
+
regex: new RegExp('/^[a-z][a-z0-9_-]*$/'),
|
|
42
|
+
errorMessage: 'Invalid bot name. Please use only lowercase letters, numbers, underscores, and hyphens. Must start with a letter.'
|
|
43
|
+
}
|
|
44
|
+
};
|
|
22
45
|
|
|
23
46
|
export default class DiscordGenerator extends Generator {
|
|
24
47
|
private answers: Answers = {} as Answers;
|
|
25
48
|
|
|
26
|
-
constructor(args: string | string[], options:
|
|
49
|
+
constructor(args: string | string[], options: Record<string, unknown>) {
|
|
27
50
|
super(args, options);
|
|
28
51
|
}
|
|
29
52
|
|
|
30
53
|
async prompting(): Promise<void> {
|
|
31
54
|
this.logo();
|
|
55
|
+
|
|
56
|
+
const askBotType = await this.prompt({
|
|
57
|
+
type: 'list',
|
|
58
|
+
name: 'botType',
|
|
59
|
+
message: 'The type of Discord Bot you want to create.',
|
|
60
|
+
choices: [
|
|
61
|
+
{
|
|
62
|
+
name: 'New Discord Bot (TypeScript)',
|
|
63
|
+
value: 'typescript'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'New Discord Bot (JavaScript)',
|
|
67
|
+
value: 'javascript'
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'New Discord Bot (Python)',
|
|
71
|
+
value: 'python'
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'New Discord Bot (Rust)',
|
|
75
|
+
value: 'rust'
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
}) as { botType: BotType };
|
|
79
|
+
|
|
80
|
+
|
|
32
81
|
this.answers = await this.prompt([
|
|
33
82
|
{
|
|
34
83
|
type: 'input',
|
|
35
84
|
name: 'botName',
|
|
36
85
|
message: 'Your Discord Bot name:',
|
|
37
86
|
default: 'my-bot',
|
|
38
|
-
validate: (input: string): boolean | string =>
|
|
39
|
-
|
|
40
|
-
? true
|
|
41
|
-
: 'Invalid bot name. Please use only lowercase letters, numbers, and hyphens. Must start with a letter.'
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
type: 'list',
|
|
45
|
-
name: 'botType',
|
|
46
|
-
message: 'The type of Discord Bot you want to create.',
|
|
47
|
-
choices: [
|
|
48
|
-
{
|
|
49
|
-
name: 'New Discord Bot (TypeScript)',
|
|
50
|
-
value: 'typescript'
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: 'New Discord Bot (JavaScript)',
|
|
54
|
-
value: 'javascript'
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
name: 'New Discord Bot (Python)',
|
|
58
|
-
value: 'python'
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'New Discord Bot (Rust)',
|
|
62
|
-
value: 'rust'
|
|
63
|
-
},
|
|
64
|
-
]
|
|
87
|
+
validate: (input: string): boolean | string =>
|
|
88
|
+
botNameValidation[askBotType.botType].regex.test(input) ? true : botNameValidation[askBotType.botType].errorMessage
|
|
65
89
|
},
|
|
66
90
|
{
|
|
67
91
|
type: 'input',
|
|
@@ -70,6 +94,8 @@ export default class DiscordGenerator extends Generator {
|
|
|
70
94
|
default: 'your-bot-token'
|
|
71
95
|
}
|
|
72
96
|
]);
|
|
97
|
+
|
|
98
|
+
this.answers.botType = askBotType.botType;
|
|
73
99
|
}
|
|
74
100
|
|
|
75
101
|
logo(): void {
|
|
@@ -85,9 +111,11 @@ export default class DiscordGenerator extends Generator {
|
|
|
85
111
|
}
|
|
86
112
|
|
|
87
113
|
writing(): void {
|
|
88
|
-
|
|
114
|
+
const currentUrl = new URL('.', import.meta.url).pathname;
|
|
89
115
|
const paths = ['.'];
|
|
90
116
|
|
|
117
|
+
this.sourceRoot(path.join(currentUrl, TEMPLATE_DIR + this.answers.botType));
|
|
118
|
+
|
|
91
119
|
// iterate over all files
|
|
92
120
|
for (let i = 0, len = paths.length; i < len; i++) {
|
|
93
121
|
const path = paths[i];
|
|
@@ -99,7 +127,7 @@ export default class DiscordGenerator extends Generator {
|
|
|
99
127
|
path
|
|
100
128
|
),
|
|
101
129
|
{
|
|
102
|
-
process: (content) => this._replaceWords(content, this.answers)
|
|
130
|
+
process: (content: string | Buffer) => this._replaceWords(content, this.answers)
|
|
103
131
|
}
|
|
104
132
|
);
|
|
105
133
|
}
|
|
@@ -110,12 +138,14 @@ export default class DiscordGenerator extends Generator {
|
|
|
110
138
|
if (this.answers.botType === 'typescript' || this.answers.botType === 'javascript') {
|
|
111
139
|
const options = { cwd: this.destinationPath(USER_DIR, this.answers.botName) };
|
|
112
140
|
|
|
113
|
-
this.
|
|
114
|
-
|
|
141
|
+
if(this.answers.botType === 'typescript' || this.answers.botType === 'javascript' && !this.args.includes('skip-install')) {
|
|
142
|
+
this.log('Installing dependencies...');
|
|
143
|
+
await this.spawn('npm', ['install'], options);
|
|
144
|
+
}
|
|
115
145
|
|
|
116
|
-
if (this.answers.botType === 'typescript') {
|
|
146
|
+
if (this.answers.botType === 'typescript' && !this.args.includes('skip-build')) {
|
|
117
147
|
this.log('Building your Discord Bot...');
|
|
118
|
-
this.
|
|
148
|
+
await this.spawn('npm', ['run', 'build'], options);
|
|
119
149
|
}
|
|
120
150
|
}
|
|
121
151
|
|
|
@@ -141,14 +171,14 @@ export default class DiscordGenerator extends Generator {
|
|
|
141
171
|
});
|
|
142
172
|
this.log('');
|
|
143
173
|
if (answer && answer.openWithCode) {
|
|
144
|
-
this.
|
|
174
|
+
this.spawn('code', [this.destinationPath(
|
|
145
175
|
USER_DIR,
|
|
146
176
|
this.answers.botName
|
|
147
177
|
)]);
|
|
148
178
|
}
|
|
149
179
|
}
|
|
150
180
|
|
|
151
|
-
_replaceWords(content: Buffer, answers: Answers): string {
|
|
181
|
+
_replaceWords(content: string | Buffer, answers: Answers): string {
|
|
152
182
|
if (answers.botType === 'rust') {
|
|
153
183
|
return content.toString()
|
|
154
184
|
.replace(BOT_TOKEN, answers.botToken)
|
package/test/generator.test.ts
CHANGED
|
@@ -1,78 +1,79 @@
|
|
|
1
1
|
import { describe, test } from 'vitest';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { createHelpers } from 'yeoman-test';
|
|
4
|
-
import {EOL} from 'os';
|
|
5
4
|
|
|
6
|
-
const
|
|
7
|
-
|
|
5
|
+
const currentUrl = new URL('../', import.meta.url).pathname;
|
|
6
|
+
|
|
7
|
+
const defaultAnswers = {
|
|
8
|
+
botName: 'test-bot',
|
|
8
9
|
botType: 'typescript',
|
|
9
10
|
botToken: 'xxx',
|
|
10
11
|
openWithCode: false,
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
botName
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
context.targetDirectory = path.join(__dirname, '../test-temp'); // generate in test-temp
|
|
24
|
-
context.cleanTestDirectory(true); // clean-up test-temp
|
|
25
|
-
await context.onGenerator(generator => generator.destinationRoot(context.targetDirectory, false))
|
|
26
|
-
.withAnswers(typescriptAnswers)
|
|
14
|
+
describe('Check yeoman generator works', () => {
|
|
15
|
+
const targetRoot = path.join(currentUrl, defaultAnswers.botName) + '/';
|
|
16
|
+
|
|
17
|
+
test('Should produce TypeScript files', async () => {
|
|
18
|
+
const context = createHelpers({}).run(path.join(currentUrl, './app'));
|
|
19
|
+
context.targetDirectory = targetRoot;
|
|
20
|
+
context.cleanTestDirectory(true);
|
|
21
|
+
await context
|
|
22
|
+
.withAnswers(defaultAnswers)
|
|
23
|
+
.withArguments(['skip-install', 'skip-build'])
|
|
27
24
|
.then((result) => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
const files = [
|
|
26
|
+
targetRoot + 'config.json',
|
|
27
|
+
targetRoot + 'src/index.ts',
|
|
28
|
+
targetRoot + 'tsconfig.json',
|
|
29
|
+
targetRoot + 'package.json',
|
|
30
|
+
];
|
|
31
|
+
result.assertFile(files);
|
|
32
|
+
result.assertJsonFileContent(targetRoot + 'config.json', CONFIG_JSON_EXPECTED);
|
|
32
33
|
});
|
|
33
|
-
context.cleanup();
|
|
34
|
+
context.cleanup();
|
|
34
35
|
}, 120_000);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
context
|
|
38
|
-
context.
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
|
|
37
|
+
test('Should produce Python files', async () => {
|
|
38
|
+
const context = createHelpers({}).run(path.join(currentUrl, './app'));
|
|
39
|
+
context.targetDirectory = targetRoot;
|
|
40
|
+
context.cleanTestDirectory(true);
|
|
41
|
+
await context
|
|
42
|
+
.withAnswers({...defaultAnswers, botType: 'python'})
|
|
41
43
|
.then((result) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const files = [
|
|
45
|
+
targetRoot + 'main.py',
|
|
46
|
+
targetRoot + 'requirements.txt',
|
|
47
|
+
];
|
|
48
|
+
result.assertFile(files);
|
|
49
|
+
result.assertFileContent(targetRoot + 'main.py', PYTHON_BOT_EXPECTED);
|
|
44
50
|
});
|
|
45
|
-
context.cleanup();
|
|
51
|
+
context.cleanup();
|
|
46
52
|
}, 120_000);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
context
|
|
50
|
-
context.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
botType: 'rust',
|
|
55
|
-
})
|
|
53
|
+
|
|
54
|
+
test('Should produce Rust files', async () => {
|
|
55
|
+
const context = createHelpers({}).run(path.join(currentUrl, './app'));
|
|
56
|
+
context.targetDirectory = targetRoot;
|
|
57
|
+
context.cleanTestDirectory(true);
|
|
58
|
+
await context
|
|
59
|
+
.withAnswers({...defaultAnswers, botType: 'rust'})
|
|
56
60
|
.then((result) => {
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
const files = [
|
|
62
|
+
targetRoot + 'src/main.rs',
|
|
63
|
+
targetRoot + 'Cargo.toml',
|
|
64
|
+
];
|
|
65
|
+
result.assertFile(files);
|
|
66
|
+
result.assertFileContent(targetRoot + 'Cargo.toml', CARGO_TOML_EXPECTED);
|
|
59
67
|
});
|
|
60
|
-
context.cleanup();
|
|
61
|
-
}
|
|
62
|
-
, 120_000);
|
|
68
|
+
context.cleanup();
|
|
69
|
+
}, 120_000);
|
|
63
70
|
});
|
|
64
71
|
|
|
72
|
+
const CONFIG_JSON_EXPECTED: Record<string, string> = {
|
|
73
|
+
'token':'xxx'
|
|
74
|
+
};
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
return str.replace(/\r?\n/g, EOL);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// norminlize end of line
|
|
71
|
-
const CONFIG_JSON_EXPECTED = normilizeEOL(`{
|
|
72
|
-
"token":"xxx"
|
|
73
|
-
}`);
|
|
74
|
-
|
|
75
|
-
const BOT_PY_EXPECTED = normilizeEOL(`import discord
|
|
76
|
+
const PYTHON_BOT_EXPECTED = `import discord
|
|
76
77
|
|
|
77
78
|
intents = discord.Intents.default()
|
|
78
79
|
intents.message_content = True
|
|
@@ -91,4 +92,17 @@ async def on_message(message):
|
|
|
91
92
|
if message.content.startswith('!ping'):
|
|
92
93
|
await message.channel.send('Pong!')
|
|
93
94
|
|
|
94
|
-
client.run('
|
|
95
|
+
client.run('xxx')
|
|
96
|
+
`;
|
|
97
|
+
|
|
98
|
+
const CARGO_TOML_EXPECTED = `[package]
|
|
99
|
+
name = "test-bot"
|
|
100
|
+
version = "0.1.0"
|
|
101
|
+
edition = "2021"
|
|
102
|
+
|
|
103
|
+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
104
|
+
|
|
105
|
+
[dependencies]
|
|
106
|
+
serenity = { version = "0.11.6", default-features = false, features = ["client", "gateway", "rustls_backend", "model"] }
|
|
107
|
+
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
|
108
|
+
`;
|
|
File without changes
|