djs-next 1.0.0-dev.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.
Potentially problematic release.
This version of djs-next might be problematic. Click here for more details.
- package/README.md +219 -0
- package/assets/djs-next.png +0 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +344 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +321 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.d.mts +109 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.js +919 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +885 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -0
- package/src/cli.ts +203 -0
- package/src/client.ts +283 -0
- package/src/handlers/commandHandler.ts +139 -0
- package/src/handlers/componentHandler.ts +31 -0
- package/src/handlers/eventHandler.ts +37 -0
- package/src/handlers/taskHandler.ts +38 -0
- package/src/handlers/utils.ts +25 -0
- package/src/index.ts +7 -0
- package/src/plugins/dnxt.ts +379 -0
- package/src/templates/cjs.ts +49 -0
- package/src/templates/esm.ts +43 -0
- package/src/templates/ts.ts +47 -0
- package/src/test/client.test.ts +8 -0
- package/src/types.ts +69 -0
- package/src/utils/configLoader.ts +27 -0
- package/src/utils/i18n.ts +57 -0
- package/src/utils/paginate.ts +71 -0
- package/tsconfig.json +16 -0
- package/tsup.config.ts +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/djs-next.png" alt="djs-next logo" width="300" />
|
|
3
|
+
<h1>djs-next</h1>
|
|
4
|
+
<p><b>Discord Bots at Next.</b></p>
|
|
5
|
+
<p>A hyper-modern, production-ready framework for Discord.js featuring file-based routing, native DNXT developer tools, Hot Module Replacement (HMR), and built-in safety nets.</p>
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.org/package/djs-next)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<br />
|
|
12
|
+
|
|
13
|
+
## ⨠Features
|
|
14
|
+
|
|
15
|
+
- š **Next.js File-Based Routing**: Auto-loads commands, events, components, and tasks natively. Supports Regex dynamic routes (e.g., `[id].ts` for components).
|
|
16
|
+
- š ļø **Native Developer Tools (`dnxt`)**: A comprehensive, built-in developer suite. Live JS evaluation, module reloading, remote shell execution, and advanced block pagination!
|
|
17
|
+
- š **Hot Module Replacement (HMR)**: Live-reload your commands, events, and logic on save without ever dropping your Discord Gateway connection.
|
|
18
|
+
- šļø **Strict Database Interop**: The entire framework `<DB>` generic safely propagates your ORM (Prisma, Mongoose, Supabase) universally without global ambient overrides.
|
|
19
|
+
- š **Localization (i18n)**: Out-of-the-box native string translations.
|
|
20
|
+
- š”ļø **Middleware Routing**: Global `beforeExecute` hooks for overarching permission checks and analytics.
|
|
21
|
+
- š¦ **Built-in Safety**: The interaction core automatically resolves `cooldowns`, `userPermissions`, `developerOnly`, and `guildOnly` rules before execution.
|
|
22
|
+
|
|
23
|
+
## š¦ Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install djs-next discord.js dotenv
|
|
27
|
+
```
|
|
28
|
+
*(Or use `pnpm`, `yarn`, or `bun`)*
|
|
29
|
+
|
|
30
|
+
## š Quick Start
|
|
31
|
+
|
|
32
|
+
The fastest way to start building is to use our powerful scaffolding tool. Open your terminal and run:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx djs-next init
|
|
36
|
+
```
|
|
37
|
+
This interactive CLI will instantly bootstrap a fully-configured **TypeScript**, **ESModule**, or **CommonJS** repository!
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## š» Manual Setup
|
|
42
|
+
|
|
43
|
+
If you prefer to start manually, here's how to bootstrap `djs-next`:
|
|
44
|
+
|
|
45
|
+
### 1. The Entry Point (`index.js`)
|
|
46
|
+
```javascript
|
|
47
|
+
require('dotenv').config();
|
|
48
|
+
const { GatewayIntentBits } = require('discord.js');
|
|
49
|
+
const { DJSNextClient } = require('djs-next');
|
|
50
|
+
const { PrismaClient } = require('@prisma/client'); // Optional Database
|
|
51
|
+
|
|
52
|
+
const db = new PrismaClient();
|
|
53
|
+
|
|
54
|
+
const client = new DJSNextClient({
|
|
55
|
+
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
|
|
56
|
+
developers: ['YOUR_DISCORD_ID'] // Required for Developer Tools
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Attach your database for global framework availability
|
|
60
|
+
client.db = db;
|
|
61
|
+
|
|
62
|
+
// Enable Hot-Module Reloading (HMR) for dev
|
|
63
|
+
client.enableHMR();
|
|
64
|
+
|
|
65
|
+
// Enable the Native Developer Tools (Prefix must be exactly 'dnxt' or 'nxt')
|
|
66
|
+
client.enableDevTools('nxt');
|
|
67
|
+
|
|
68
|
+
// Boot!
|
|
69
|
+
client.start(process.env.DISCORD_TOKEN);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 2. Creating a Command
|
|
73
|
+
Drop a file into `src/commands/ping.js`. The framework reads it and registers it instantly!
|
|
74
|
+
```javascript
|
|
75
|
+
/** @type {import('djs-next').FileCommand} */
|
|
76
|
+
module.exports = {
|
|
77
|
+
description: 'Replies with Pong!',
|
|
78
|
+
cooldown: 5, // Automatically intercepts spammers
|
|
79
|
+
execute: async (interaction, client) => {
|
|
80
|
+
// client.db is strongly typed as your database (via JSDoc/TS config)
|
|
81
|
+
await interaction.reply('Pong! š');
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 3. Dynamic Component Routing
|
|
87
|
+
Have a button with a custom ID like `ban_user_12345`? You don't need a massive switch statement. Just create `src/components/ban_user_[id].js`:
|
|
88
|
+
```javascript
|
|
89
|
+
/** @type {import('djs-next').FileComponent} */
|
|
90
|
+
module.exports = {
|
|
91
|
+
// Matches "ban_user_12345" and extracts the param dynamically!
|
|
92
|
+
customId: 'ban_user_[id]',
|
|
93
|
+
execute: async (interaction, client, params) => {
|
|
94
|
+
const targetId = params.id; // '12345'
|
|
95
|
+
await interaction.reply(`Banning user ${targetId}...`);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## šļø Database Integrations
|
|
103
|
+
|
|
104
|
+
Because `djs-next` uses a global `<DB>` generic, you can natively bind any popular database (like MongoDB Atlas, Supabase, Prisma, or PostgreSQL) directly into the framework core. It will propagate 100% type-safety to all your commands and events.
|
|
105
|
+
|
|
106
|
+
### MongoDB Atlas (using Mongoose)
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
// index.js
|
|
110
|
+
require('dotenv').config();
|
|
111
|
+
const mongoose = require('mongoose');
|
|
112
|
+
const { DJSNextClient } = require('djs-next');
|
|
113
|
+
const { GatewayIntentBits } = require('discord.js');
|
|
114
|
+
|
|
115
|
+
// Connect to Atlas
|
|
116
|
+
mongoose.connect(process.env.MONGO_URI);
|
|
117
|
+
|
|
118
|
+
// Initialize DJSNext
|
|
119
|
+
const client = new DJSNextClient({
|
|
120
|
+
intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages ]
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
client.db = mongoose;
|
|
124
|
+
client.start(process.env.TOKEN);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
// src/commands/profile.js
|
|
129
|
+
const UserSchema = require('../models/User.js');
|
|
130
|
+
|
|
131
|
+
/** @type {import('djs-next').FileCommand} */
|
|
132
|
+
module.exports = {
|
|
133
|
+
description: 'View your profile',
|
|
134
|
+
execute: async (interaction, client) => {
|
|
135
|
+
// client.db is your connected Mongoose instance
|
|
136
|
+
const user = await UserSchema.findOne({ discordId: interaction.user.id });
|
|
137
|
+
await interaction.reply(`You have ${user.coins} coins!`);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Supabase (PostgreSQL)
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
// index.js
|
|
146
|
+
require('dotenv').config();
|
|
147
|
+
const { createClient } = require('@supabase/supabase-js');
|
|
148
|
+
const { DJSNextClient } = require('djs-next');
|
|
149
|
+
const { GatewayIntentBits } = require('discord.js');
|
|
150
|
+
|
|
151
|
+
const supabase = createClient('https://xyz.supabase.co', process.env.SUPABASE_KEY);
|
|
152
|
+
|
|
153
|
+
const client = new DJSNextClient({
|
|
154
|
+
intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages ]
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
client.db = supabase;
|
|
158
|
+
client.start(process.env.TOKEN);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
// src/commands/leaderboard.js
|
|
163
|
+
/** @type {import('djs-next').FileCommand} */
|
|
164
|
+
module.exports = {
|
|
165
|
+
description: 'View the leaderboard',
|
|
166
|
+
execute: async (interaction, client) => {
|
|
167
|
+
// client.db is your Supabase client
|
|
168
|
+
const { data, error } = await client.db.from('users').select('*').order('level', { ascending: false });
|
|
169
|
+
await interaction.reply(`Top user is: ${data[0].username}`);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## š ļø The Developer Suite (`dnxt`)
|
|
177
|
+
|
|
178
|
+
`djs-next` comes with a hyper-advanced, native developer suite. By providing your Discord User ID in the `developers` array and calling `client.enableDevTools('nxt')` (or `'dnxt'`), you can execute backend logic live directly from Discord!
|
|
179
|
+
|
|
180
|
+
***(Make sure your bot has the `MessageContent` Intent enabled!)***
|
|
181
|
+
|
|
182
|
+
| Command | Action |
|
|
183
|
+
| --- | --- |
|
|
184
|
+
| `dnxt js <code>` | Evaluates Javascript live with pagination, async resolution, and timer tracing. |
|
|
185
|
+
| `dnxt sh <cmd>` | Executes raw shell/terminal code on your host machine (e.g., `dnxt sh npm run build`). |
|
|
186
|
+
| `dnxt git <cmd>` | Executes standard git workflows (e.g., `dnxt git pull`). |
|
|
187
|
+
| `dnxt su <id> <cmd>`| Triggers a mock message command mimicking another user's execution perspective. |
|
|
188
|
+
| `dnxt reload <target>` | Hot-swaps the internal cache. (e.g., `dnxt reload commands`, `dnxt reload all`). |
|
|
189
|
+
| `dnxt source <cmd>` | Directly `fs.readFileSync`s the underlying source code of an active command! |
|
|
190
|
+
| `dnxt debug <cmd>` | Executes Javascript while explicitly tracking the Node.js V8 Heap Memory Delta. |
|
|
191
|
+
| `dnxt tasks` | Views all running background `setInterval` tasks in the framework. |
|
|
192
|
+
| `dnxt cancel <task>` | Forcefully kills a background interval process. |
|
|
193
|
+
| `dnxt sync` | Manually forces a global Discord Slash Command synchronization. |
|
|
194
|
+
| `dnxt sql <query>` | Attempts to execute a raw SQL query against your `client.db` connection. |
|
|
195
|
+
| `dnxt vc` | Dumps VoiceChannel state and Voice Debugger information. |
|
|
196
|
+
| `dnxt` | Displays the Developer Dashboard tracking System RAM, Node Host status, and Process uptime. |
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## āļø Configuration (`djs-next.config.js`)
|
|
201
|
+
|
|
202
|
+
At the root of your project, you can drop a config file to heavily control how `djs-next` acts:
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
module.exports = {
|
|
206
|
+
devGuildId: 'YOUR_TESTING_SERVER_ID',
|
|
207
|
+
defaultLocale: 'en-US',
|
|
208
|
+
directories: {
|
|
209
|
+
commands: 'src/commands',
|
|
210
|
+
events: 'src/events',
|
|
211
|
+
components: 'src/components',
|
|
212
|
+
tasks: 'src/tasks',
|
|
213
|
+
locales: 'src/locales'
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## š License
|
|
219
|
+
Released under the [MIT License](LICENSE).
|
|
Binary file
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/cli.ts
|
|
27
|
+
var import_fs = __toESM(require("fs"));
|
|
28
|
+
var import_path = __toESM(require("path"));
|
|
29
|
+
var import_prompts = require("@inquirer/prompts");
|
|
30
|
+
|
|
31
|
+
// src/templates/ts.ts
|
|
32
|
+
var tsTemplates = {
|
|
33
|
+
index: `import { DJSNextClient, GatewayIntentBits } from 'djs-next';
|
|
34
|
+
import 'dotenv/config';
|
|
35
|
+
|
|
36
|
+
const client = new DJSNextClient({
|
|
37
|
+
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
|
38
|
+
commandsDir: './src/commands',
|
|
39
|
+
eventsDir: './src/events',
|
|
40
|
+
componentsDir: './src/components',
|
|
41
|
+
tasksDir: './src/tasks',
|
|
42
|
+
clientId: process.env.CLIENT_ID
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
client.start(process.env.DISCORD_TOKEN!);
|
|
46
|
+
`,
|
|
47
|
+
ping: `import { FileCommand } from 'djs-next';
|
|
48
|
+
|
|
49
|
+
export const command: FileCommand = {
|
|
50
|
+
description: 'Replies with Pong!',
|
|
51
|
+
execute: async (interaction) => {
|
|
52
|
+
await interaction.reply('Pong!');
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
`,
|
|
56
|
+
ready: `import { DJSNextEvent, Events } from 'djs-next';
|
|
57
|
+
|
|
58
|
+
export const event: DJSNextEvent<Events.ClientReady> = {
|
|
59
|
+
name: Events.ClientReady,
|
|
60
|
+
once: true,
|
|
61
|
+
execute: (client) => {
|
|
62
|
+
console.log('Ready! Logged in as ' + client.user?.tag);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
`,
|
|
66
|
+
healthcheck: `import { FileTask } from 'djs-next';
|
|
67
|
+
|
|
68
|
+
export const task: FileTask = {
|
|
69
|
+
interval: 60000,
|
|
70
|
+
execute: async (client) => {
|
|
71
|
+
console.log('[Task] Healthcheck completed.');
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
`
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// src/templates/esm.ts
|
|
78
|
+
var esmTemplates = {
|
|
79
|
+
index: `import { DJSNextClient, GatewayIntentBits } from 'djs-next';
|
|
80
|
+
import 'dotenv/config';
|
|
81
|
+
|
|
82
|
+
const client = new DJSNextClient({
|
|
83
|
+
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
|
84
|
+
commandsDir: './src/commands',
|
|
85
|
+
eventsDir: './src/events',
|
|
86
|
+
componentsDir: './src/components',
|
|
87
|
+
tasksDir: './src/tasks',
|
|
88
|
+
clientId: process.env.CLIENT_ID
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
client.start(process.env.DISCORD_TOKEN);
|
|
92
|
+
`,
|
|
93
|
+
ping: `export const command = {
|
|
94
|
+
description: 'Replies with Pong!',
|
|
95
|
+
execute: async (interaction) => {
|
|
96
|
+
await interaction.reply('Pong!');
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
`,
|
|
100
|
+
ready: `import { Events } from 'djs-next';
|
|
101
|
+
|
|
102
|
+
export const event = {
|
|
103
|
+
name: Events.ClientReady,
|
|
104
|
+
once: true,
|
|
105
|
+
execute: (client) => {
|
|
106
|
+
console.log('Ready! Logged in as ' + client.user?.tag);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
`,
|
|
110
|
+
healthcheck: `export const task = {
|
|
111
|
+
interval: 60000,
|
|
112
|
+
execute: async (client) => {
|
|
113
|
+
console.log('[Task] Healthcheck completed.');
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
`
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// src/templates/cjs.ts
|
|
120
|
+
var cjsTemplates = {
|
|
121
|
+
index: `const { DJSNextClient, GatewayIntentBits } = require('djs-next');
|
|
122
|
+
require('dotenv/config');
|
|
123
|
+
|
|
124
|
+
const client = new DJSNextClient({
|
|
125
|
+
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
|
|
126
|
+
commandsDir: './src/commands',
|
|
127
|
+
eventsDir: './src/events',
|
|
128
|
+
componentsDir: './src/components',
|
|
129
|
+
tasksDir: './src/tasks',
|
|
130
|
+
clientId: process.env.CLIENT_ID
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
client.start(process.env.DISCORD_TOKEN);
|
|
134
|
+
`,
|
|
135
|
+
ping: `module.exports = {
|
|
136
|
+
command: {
|
|
137
|
+
description: 'Replies with Pong!',
|
|
138
|
+
execute: async (interaction) => {
|
|
139
|
+
await interaction.reply('Pong!');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
`,
|
|
144
|
+
ready: `const { Events } = require('djs-next');
|
|
145
|
+
|
|
146
|
+
module.exports = {
|
|
147
|
+
event: {
|
|
148
|
+
name: Events.ClientReady,
|
|
149
|
+
once: true,
|
|
150
|
+
execute: (client) => {
|
|
151
|
+
console.log('Ready! Logged in as ' + client.user?.tag);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
`,
|
|
156
|
+
healthcheck: `module.exports = {
|
|
157
|
+
task: {
|
|
158
|
+
interval: 60000,
|
|
159
|
+
execute: async (client) => {
|
|
160
|
+
console.log('[Task] Healthcheck completed.');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
`
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/cli.ts
|
|
168
|
+
var import_picocolors = __toESM(require("picocolors"));
|
|
169
|
+
var import_child_process = require("child_process");
|
|
170
|
+
async function main() {
|
|
171
|
+
console.log(import_picocolors.default.bold(import_picocolors.default.blue("\n\u{1F680} Welcome to djs-next!\n")));
|
|
172
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
173
|
+
let pm = "npm";
|
|
174
|
+
if (userAgent.startsWith("yarn")) pm = "yarn";
|
|
175
|
+
else if (userAgent.startsWith("pnpm")) pm = "pnpm";
|
|
176
|
+
else if (userAgent.startsWith("bun")) pm = "bun";
|
|
177
|
+
const args = process.argv.slice(2);
|
|
178
|
+
let projectName = args[0] || "";
|
|
179
|
+
if (!projectName || projectName === "init") {
|
|
180
|
+
projectName = await (0, import_prompts.input)({
|
|
181
|
+
message: "What is your project named?",
|
|
182
|
+
default: "my-bot",
|
|
183
|
+
validate: (value) => value.trim().length > 0 || "Project name is required"
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const language = await (0, import_prompts.select)({
|
|
187
|
+
message: "Would you like to use TypeScript or JavaScript?",
|
|
188
|
+
choices: [
|
|
189
|
+
{ name: "TypeScript", value: "ts" },
|
|
190
|
+
{ name: "JavaScript", value: "js" }
|
|
191
|
+
],
|
|
192
|
+
default: "ts"
|
|
193
|
+
});
|
|
194
|
+
const moduleSystem = await (0, import_prompts.select)({
|
|
195
|
+
message: "Would you like to use ES Modules or CommonJS?",
|
|
196
|
+
choices: [
|
|
197
|
+
{ name: "ES Modules (import/export)", value: "esm" },
|
|
198
|
+
{ name: "CommonJS (require/module.exports)", value: "cjs" }
|
|
199
|
+
],
|
|
200
|
+
default: "esm"
|
|
201
|
+
});
|
|
202
|
+
const botToken = await (0, import_prompts.password)({
|
|
203
|
+
message: "What is your Discord Bot Token? (Leave empty to skip)",
|
|
204
|
+
mask: true
|
|
205
|
+
});
|
|
206
|
+
const clientId = await (0, import_prompts.input)({
|
|
207
|
+
message: "What is your Discord Client ID? (Leave empty to skip)"
|
|
208
|
+
});
|
|
209
|
+
const targetPath = import_path.default.resolve(process.cwd(), projectName);
|
|
210
|
+
if (import_fs.default.existsSync(targetPath)) {
|
|
211
|
+
console.error(import_picocolors.default.red(`
|
|
212
|
+
Directory "${projectName}" already exists.`));
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
console.log(import_picocolors.default.cyan(`
|
|
216
|
+
Scaffolding project in ${targetPath}...`));
|
|
217
|
+
import_fs.default.mkdirSync(targetPath, { recursive: true });
|
|
218
|
+
const isTS = language === "ts";
|
|
219
|
+
const isESM = moduleSystem === "esm";
|
|
220
|
+
const ext = isTS ? "ts" : "js";
|
|
221
|
+
let devScript = isTS ? "tsx watch src/index.ts" : "node --watch src/index.js";
|
|
222
|
+
let startScript = isTS ? "node dist/index.js" : "node src/index.js";
|
|
223
|
+
if (pm === "bun") {
|
|
224
|
+
devScript = `bun run --watch src/index.${ext}`;
|
|
225
|
+
startScript = `bun src/index.${ext}`;
|
|
226
|
+
}
|
|
227
|
+
const packageJson = {
|
|
228
|
+
name: projectName.toLowerCase().replace(/\\s+/g, "-"),
|
|
229
|
+
version: "1.0.0",
|
|
230
|
+
main: isTS ? "dist/index.js" : "src/index.js",
|
|
231
|
+
type: isESM ? "module" : "commonjs",
|
|
232
|
+
scripts: {
|
|
233
|
+
"dev": devScript,
|
|
234
|
+
"start": startScript
|
|
235
|
+
},
|
|
236
|
+
dependencies: {
|
|
237
|
+
"discord.js": "latest",
|
|
238
|
+
"djs-next": "latest",
|
|
239
|
+
"dotenv": "latest"
|
|
240
|
+
},
|
|
241
|
+
devDependencies: {}
|
|
242
|
+
};
|
|
243
|
+
if (isTS) {
|
|
244
|
+
packageJson.scripts.build = "tsc";
|
|
245
|
+
packageJson.devDependencies = {
|
|
246
|
+
"typescript": "latest",
|
|
247
|
+
"@types/node": "latest",
|
|
248
|
+
"tsx": "latest"
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
import_fs.default.writeFileSync(import_path.default.join(targetPath, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
252
|
+
if (isTS) {
|
|
253
|
+
const tsconfig = {
|
|
254
|
+
compilerOptions: {
|
|
255
|
+
target: "ES2022",
|
|
256
|
+
module: isESM ? "NodeNext" : "CommonJS",
|
|
257
|
+
moduleResolution: isESM ? "NodeNext" : "Node",
|
|
258
|
+
strict: true,
|
|
259
|
+
esModuleInterop: true,
|
|
260
|
+
outDir: "./dist",
|
|
261
|
+
types: ["node"],
|
|
262
|
+
ignoreDeprecations: "5.0"
|
|
263
|
+
},
|
|
264
|
+
include: ["src/**/*"]
|
|
265
|
+
};
|
|
266
|
+
import_fs.default.writeFileSync(import_path.default.join(targetPath, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
267
|
+
}
|
|
268
|
+
import_fs.default.writeFileSync(import_path.default.join(targetPath, ".env"), `DISCORD_TOKEN=${botToken || "your_token_here"}
|
|
269
|
+
CLIENT_ID=${clientId || "your_client_id_here"}
|
|
270
|
+
`);
|
|
271
|
+
import_fs.default.writeFileSync(import_path.default.join(targetPath, ".gitignore"), `node_modules/
|
|
272
|
+
dist/
|
|
273
|
+
.env
|
|
274
|
+
.DS_Store
|
|
275
|
+
`);
|
|
276
|
+
const srcDir = import_path.default.join(targetPath, "src");
|
|
277
|
+
import_fs.default.mkdirSync(srcDir, { recursive: true });
|
|
278
|
+
import_fs.default.mkdirSync(import_path.default.join(srcDir, "commands"), { recursive: true });
|
|
279
|
+
import_fs.default.mkdirSync(import_path.default.join(srcDir, "events"), { recursive: true });
|
|
280
|
+
import_fs.default.mkdirSync(import_path.default.join(srcDir, "components", "buttons"), { recursive: true });
|
|
281
|
+
import_fs.default.mkdirSync(import_path.default.join(srcDir, "tasks"), { recursive: true });
|
|
282
|
+
if (isTS) {
|
|
283
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, `index.${ext}`), tsTemplates.index);
|
|
284
|
+
} else if (isESM) {
|
|
285
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, `index.${ext}`), esmTemplates.index);
|
|
286
|
+
} else {
|
|
287
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "index.js"), cjsTemplates.index);
|
|
288
|
+
}
|
|
289
|
+
if (isTS) {
|
|
290
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "commands", "ping.ts"), tsTemplates.ping);
|
|
291
|
+
} else if (isESM) {
|
|
292
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "commands", "ping.js"), esmTemplates.ping);
|
|
293
|
+
} else {
|
|
294
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "commands", "ping.js"), cjsTemplates.ping);
|
|
295
|
+
}
|
|
296
|
+
if (isTS) {
|
|
297
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "events", "ready.ts"), tsTemplates.ready);
|
|
298
|
+
} else if (isESM) {
|
|
299
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "events", "ready.js"), esmTemplates.ready);
|
|
300
|
+
} else {
|
|
301
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "events", "ready.js"), cjsTemplates.ready);
|
|
302
|
+
}
|
|
303
|
+
if (isTS) {
|
|
304
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "tasks", "healthcheck.ts"), tsTemplates.healthcheck);
|
|
305
|
+
} else if (isESM) {
|
|
306
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "tasks", "healthcheck.js"), esmTemplates.healthcheck);
|
|
307
|
+
} else {
|
|
308
|
+
import_fs.default.writeFileSync(import_path.default.join(srcDir, "tasks", "healthcheck.js"), cjsTemplates.healthcheck);
|
|
309
|
+
}
|
|
310
|
+
console.log(import_picocolors.default.cyan(`
|
|
311
|
+
Installing dependencies with ${pm}...`));
|
|
312
|
+
try {
|
|
313
|
+
(0, import_child_process.execSync)(`${pm} install`, { cwd: targetPath, stdio: "inherit" });
|
|
314
|
+
} catch (error) {
|
|
315
|
+
console.error(import_picocolors.default.red(`
|
|
316
|
+
Failed to install dependencies. Please run '${pm} install' manually.`));
|
|
317
|
+
}
|
|
318
|
+
console.log(import_picocolors.default.green(import_picocolors.default.bold(`
|
|
319
|
+
Success! Created ${projectName} at ${targetPath}`)));
|
|
320
|
+
console.log(`
|
|
321
|
+
Inside that directory, you can run several commands:`);
|
|
322
|
+
console.log(import_picocolors.default.cyan(`
|
|
323
|
+
${pm} run dev`));
|
|
324
|
+
console.log(` Starts the development server with hot-reloading.`);
|
|
325
|
+
if (isTS) {
|
|
326
|
+
console.log(import_picocolors.default.cyan(`
|
|
327
|
+
${pm} run build`));
|
|
328
|
+
console.log(` Compiles the TypeScript app into JavaScript.`);
|
|
329
|
+
}
|
|
330
|
+
console.log(import_picocolors.default.cyan(`
|
|
331
|
+
${pm} start`));
|
|
332
|
+
console.log(` Starts the production server.`);
|
|
333
|
+
console.log(`
|
|
334
|
+
We suggest that you begin by typing:
|
|
335
|
+
`);
|
|
336
|
+
console.log(import_picocolors.default.cyan(` cd ${projectName}`));
|
|
337
|
+
console.log(import_picocolors.default.cyan(` ${pm} run dev
|
|
338
|
+
`));
|
|
339
|
+
}
|
|
340
|
+
main().catch((err) => {
|
|
341
|
+
console.error(import_picocolors.default.red("An unexpected error occurred:"), err);
|
|
342
|
+
process.exit(1);
|
|
343
|
+
});
|
|
344
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/templates/ts.ts","../src/templates/esm.ts","../src/templates/cjs.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'fs';\nimport path from 'path';\nimport { input, select, password } from '@inquirer/prompts';\nimport { spawnSync } from 'child_process';\nimport { tsTemplates } from './templates/ts.js';\nimport { esmTemplates } from './templates/esm.js';\nimport { cjsTemplates } from './templates/cjs.js';\nimport pc from 'picocolors';\nimport { execSync } from 'child_process';\n\nasync function main() {\n console.log(pc.bold(pc.blue('\\nš Welcome to djs-next!\\n')));\n\n const userAgent = process.env.npm_config_user_agent || '';\n let pm = 'npm';\n if (userAgent.startsWith('yarn')) pm = 'yarn';\n else if (userAgent.startsWith('pnpm')) pm = 'pnpm';\n else if (userAgent.startsWith('bun')) pm = 'bun';\n\n const args = process.argv.slice(2);\n let projectName = args[0] || '';\n\n if (!projectName || projectName === 'init') {\n projectName = await input({\n message: 'What is your project named?',\n default: 'my-bot',\n validate: (value) => value.trim().length > 0 || 'Project name is required'\n });\n }\n\n const language = await select({\n message: 'Would you like to use TypeScript or JavaScript?',\n choices: [\n { name: 'TypeScript', value: 'ts' },\n { name: 'JavaScript', value: 'js' }\n ],\n default: 'ts'\n });\n\n const moduleSystem = await select({\n message: 'Would you like to use ES Modules or CommonJS?',\n choices: [\n { name: 'ES Modules (import/export)', value: 'esm' },\n { name: 'CommonJS (require/module.exports)', value: 'cjs' }\n ],\n default: 'esm'\n });\n\n const botToken = await password({\n message: 'What is your Discord Bot Token? (Leave empty to skip)',\n mask: true\n });\n\n const clientId = await input({\n message: 'What is your Discord Client ID? (Leave empty to skip)'\n });\n\n const targetPath = path.resolve(process.cwd(), projectName);\n\n if (fs.existsSync(targetPath)) {\n console.error(pc.red(`\\nDirectory \"${projectName}\" already exists.`));\n process.exit(1);\n }\n\n console.log(pc.cyan(`\\nScaffolding project in ${targetPath}...`));\n fs.mkdirSync(targetPath, { recursive: true });\n\n const isTS = language === 'ts';\n const isESM = moduleSystem === 'esm';\n const ext = isTS ? 'ts' : 'js';\n\n let devScript = isTS ? \"tsx watch src/index.ts\" : \"node --watch src/index.js\";\n let startScript = isTS ? \"node dist/index.js\" : \"node src/index.js\";\n \n if (pm === 'bun') {\n devScript = `bun run --watch src/index.${ext}`;\n startScript = `bun src/index.${ext}`;\n }\n\n const packageJson: any = {\n name: projectName.toLowerCase().replace(/\\\\s+/g, '-'),\n version: \"1.0.0\",\n main: isTS ? \"dist/index.js\" : \"src/index.js\",\n type: isESM ? \"module\" : \"commonjs\",\n scripts: {\n \"dev\": devScript,\n \"start\": startScript\n },\n dependencies: {\n \"discord.js\": \"latest\",\n \"djs-next\": \"latest\",\n \"dotenv\": \"latest\"\n },\n devDependencies: {}\n };\n\n if (isTS) {\n packageJson.scripts.build = \"tsc\";\n packageJson.devDependencies = {\n \"typescript\": \"latest\",\n \"@types/node\": \"latest\",\n \"tsx\": \"latest\"\n };\n }\n\n fs.writeFileSync(path.join(targetPath, 'package.json'), JSON.stringify(packageJson, null, 2));\n\n if (isTS) {\n const tsconfig = {\n compilerOptions: {\n target: \"ES2022\",\n module: isESM ? \"NodeNext\" : \"CommonJS\",\n moduleResolution: isESM ? \"NodeNext\" : \"Node\",\n strict: true,\n esModuleInterop: true,\n outDir: \"./dist\",\n types: [\"node\"],\n ignoreDeprecations: \"5.0\"\n },\n include: [\"src/**/*\"]\n };\n fs.writeFileSync(path.join(targetPath, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));\n }\n\n fs.writeFileSync(path.join(targetPath, '.env'), `DISCORD_TOKEN=${botToken || 'your_token_here'}\nCLIENT_ID=${clientId || 'your_client_id_here'}\n`);\n fs.writeFileSync(path.join(targetPath, '.gitignore'), `node_modules/\ndist/\n.env\n.DS_Store\n`);\n\n const srcDir = path.join(targetPath, 'src');\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(path.join(srcDir, 'commands'), { recursive: true });\n fs.mkdirSync(path.join(srcDir, 'events'), { recursive: true });\n fs.mkdirSync(path.join(srcDir, 'components', 'buttons'), { recursive: true });\n fs.mkdirSync(path.join(srcDir, 'tasks'), { recursive: true });\n\n // Index File\n if (isTS) {\n fs.writeFileSync(path.join(srcDir, `index.${ext}`), tsTemplates.index);\n } else if (isESM) {\n fs.writeFileSync(path.join(srcDir, `index.${ext}`), esmTemplates.index);\n } else {\n fs.writeFileSync(path.join(srcDir, 'index.js'), cjsTemplates.index);\n }\n\n // Ping Command\n if (isTS) {\n fs.writeFileSync(path.join(srcDir, 'commands', 'ping.ts'), tsTemplates.ping);\n } else if (isESM) {\n fs.writeFileSync(path.join(srcDir, 'commands', 'ping.js'), esmTemplates.ping);\n } else {\n fs.writeFileSync(path.join(srcDir, 'commands', 'ping.js'), cjsTemplates.ping);\n }\n\n // Ready Event\n if (isTS) {\n fs.writeFileSync(path.join(srcDir, 'events', 'ready.ts'), tsTemplates.ready);\n } else if (isESM) {\n fs.writeFileSync(path.join(srcDir, 'events', 'ready.js'), esmTemplates.ready);\n } else {\n fs.writeFileSync(path.join(srcDir, 'events', 'ready.js'), cjsTemplates.ready);\n }\n\n // Healthcheck Task\n if (isTS) {\n fs.writeFileSync(path.join(srcDir, 'tasks', 'healthcheck.ts'), tsTemplates.healthcheck);\n } else if (isESM) {\n fs.writeFileSync(path.join(srcDir, 'tasks', 'healthcheck.js'), esmTemplates.healthcheck);\n } else {\n fs.writeFileSync(path.join(srcDir, 'tasks', 'healthcheck.js'), cjsTemplates.healthcheck);\n }\n\n console.log(pc.cyan(`\\nInstalling dependencies with ${pm}...`));\n try {\n execSync(`${pm} install`, { cwd: targetPath, stdio: 'inherit' });\n } catch (error) {\n console.error(pc.red(`\\nFailed to install dependencies. Please run '${pm} install' manually.`));\n }\n\n console.log(pc.green(pc.bold(`\\nSuccess! Created ${projectName} at ${targetPath}`)));\n console.log(`\\nInside that directory, you can run several commands:`);\n console.log(pc.cyan(`\\n ${pm} run dev`));\n console.log(` Starts the development server with hot-reloading.`);\n if (isTS) {\n console.log(pc.cyan(`\\n ${pm} run build`));\n console.log(` Compiles the TypeScript app into JavaScript.`);\n }\n console.log(pc.cyan(`\\n ${pm} start`));\n console.log(` Starts the production server.`);\n console.log(`\\nWe suggest that you begin by typing:\\n`);\n console.log(pc.cyan(` cd ${projectName}`));\n console.log(pc.cyan(` ${pm} run dev\\n`));\n}\n\nmain().catch((err) => {\n console.error(pc.red('An unexpected error occurred:'), err);\n process.exit(1);\n});\n","export const tsTemplates = {\n index: `import { DJSNextClient, GatewayIntentBits } from 'djs-next';\nimport 'dotenv/config';\n\nconst client = new DJSNextClient({\n intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],\n commandsDir: './src/commands',\n eventsDir: './src/events',\n componentsDir: './src/components',\n tasksDir: './src/tasks',\n clientId: process.env.CLIENT_ID\n});\n\nclient.start(process.env.DISCORD_TOKEN!);\n`,\n\n ping: `import { FileCommand } from 'djs-next';\n\nexport const command: FileCommand = {\n description: 'Replies with Pong!',\n execute: async (interaction) => {\n await interaction.reply('Pong!');\n }\n};\n`,\n\n ready: `import { DJSNextEvent, Events } from 'djs-next';\n\nexport const event: DJSNextEvent<Events.ClientReady> = {\n name: Events.ClientReady,\n once: true,\n execute: (client) => {\n console.log('Ready! Logged in as ' + client.user?.tag);\n }\n};\n`,\n\n healthcheck: `import { FileTask } from 'djs-next';\n\nexport const task: FileTask = {\n interval: 60000,\n execute: async (client) => {\n console.log('[Task] Healthcheck completed.');\n }\n};\n`\n};\n","export const esmTemplates = {\n index: `import { DJSNextClient, GatewayIntentBits } from 'djs-next';\nimport 'dotenv/config';\n\nconst client = new DJSNextClient({\n intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],\n commandsDir: './src/commands',\n eventsDir: './src/events',\n componentsDir: './src/components',\n tasksDir: './src/tasks',\n clientId: process.env.CLIENT_ID\n});\n\nclient.start(process.env.DISCORD_TOKEN);\n`,\n\n ping: `export const command = {\n description: 'Replies with Pong!',\n execute: async (interaction) => {\n await interaction.reply('Pong!');\n }\n};\n`,\n\n ready: `import { Events } from 'djs-next';\n\nexport const event = {\n name: Events.ClientReady,\n once: true,\n execute: (client) => {\n console.log('Ready! Logged in as ' + client.user?.tag);\n }\n};\n`,\n\n healthcheck: `export const task = {\n interval: 60000,\n execute: async (client) => {\n console.log('[Task] Healthcheck completed.');\n }\n};\n`\n};\n","export const cjsTemplates = {\n index: `const { DJSNextClient, GatewayIntentBits } = require('djs-next');\nrequire('dotenv/config');\n\nconst client = new DJSNextClient({\n intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],\n commandsDir: './src/commands',\n eventsDir: './src/events',\n componentsDir: './src/components',\n tasksDir: './src/tasks',\n clientId: process.env.CLIENT_ID\n});\n\nclient.start(process.env.DISCORD_TOKEN);\n`,\n\n ping: `module.exports = {\n command: {\n description: 'Replies with Pong!',\n execute: async (interaction) => {\n await interaction.reply('Pong!');\n }\n }\n};\n`,\n\n ready: `const { Events } = require('djs-next');\n\nmodule.exports = {\n event: {\n name: Events.ClientReady,\n once: true,\n execute: (client) => {\n console.log('Ready! Logged in as ' + client.user?.tag);\n }\n }\n};\n`,\n\n healthcheck: `module.exports = {\n task: {\n interval: 60000,\n execute: async (client) => {\n console.log('[Task] Healthcheck completed.');\n }\n }\n};\n`\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,gBAAe;AACf,kBAAiB;AACjB,qBAAwC;;;ACHjC,IAAM,cAAc;AAAA,EACzB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUN,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASf;;;AC9CO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQN,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOf;;;AC1CO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUN,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaP,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASf;;;AHxCA,wBAAe;AACf,2BAAyB;AAEzB,eAAe,OAAO;AACpB,UAAQ,IAAI,kBAAAA,QAAG,KAAK,kBAAAA,QAAG,KAAK,oCAA6B,CAAC,CAAC;AAE3D,QAAM,YAAY,QAAQ,IAAI,yBAAyB;AACvD,MAAI,KAAK;AACT,MAAI,UAAU,WAAW,MAAM,EAAG,MAAK;AAAA,WAC9B,UAAU,WAAW,MAAM,EAAG,MAAK;AAAA,WACnC,UAAU,WAAW,KAAK,EAAG,MAAK;AAE3C,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,MAAI,cAAc,KAAK,CAAC,KAAK;AAE7B,MAAI,CAAC,eAAe,gBAAgB,QAAQ;AAC1C,kBAAc,UAAM,sBAAM;AAAA,MACxB,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,UAAU,MAAM,KAAK,EAAE,SAAS,KAAK;AAAA,IAClD,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,UAAM,uBAAO;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,cAAc,OAAO,KAAK;AAAA,MAClC,EAAE,MAAM,cAAc,OAAO,KAAK;AAAA,IACpC;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AAED,QAAM,eAAe,UAAM,uBAAO;AAAA,IAChC,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,8BAA8B,OAAO,MAAM;AAAA,MACnD,EAAE,MAAM,qCAAqC,OAAO,MAAM;AAAA,IAC5D;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AAED,QAAM,WAAW,UAAM,yBAAS;AAAA,IAC9B,SAAS;AAAA,IACT,MAAM;AAAA,EACR,CAAC;AAED,QAAM,WAAW,UAAM,sBAAM;AAAA,IAC3B,SAAS;AAAA,EACX,CAAC;AAED,QAAM,aAAa,YAAAC,QAAK,QAAQ,QAAQ,IAAI,GAAG,WAAW;AAE1D,MAAI,UAAAC,QAAG,WAAW,UAAU,GAAG;AAC7B,YAAQ,MAAM,kBAAAF,QAAG,IAAI;AAAA,aAAgB,WAAW,mBAAmB,CAAC;AACpE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,kBAAAA,QAAG,KAAK;AAAA,yBAA4B,UAAU,KAAK,CAAC;AAChE,YAAAE,QAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAE5C,QAAM,OAAO,aAAa;AAC1B,QAAM,QAAQ,iBAAiB;AAC/B,QAAM,MAAM,OAAO,OAAO;AAE1B,MAAI,YAAY,OAAO,2BAA2B;AAClD,MAAI,cAAc,OAAO,uBAAuB;AAEhD,MAAI,OAAO,OAAO;AAChB,gBAAY,6BAA6B,GAAG;AAC5C,kBAAc,iBAAiB,GAAG;AAAA,EACpC;AAEA,QAAM,cAAmB;AAAA,IACvB,MAAM,YAAY,YAAY,EAAE,QAAQ,SAAS,GAAG;AAAA,IACpD,SAAS;AAAA,IACT,MAAM,OAAO,kBAAkB;AAAA,IAC/B,MAAM,QAAQ,WAAW;AAAA,IACzB,SAAS;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,IACA,cAAc;AAAA,MACZ,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU;AAAA,IACZ;AAAA,IACA,iBAAiB,CAAC;AAAA,EACpB;AAEA,MAAI,MAAM;AACR,gBAAY,QAAQ,QAAQ;AAC5B,gBAAY,kBAAkB;AAAA,MAC5B,cAAc;AAAA,MACd,eAAe;AAAA,MACf,OAAO;AAAA,IACT;AAAA,EACF;AAEA,YAAAA,QAAG,cAAc,YAAAD,QAAK,KAAK,YAAY,cAAc,GAAG,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAE5F,MAAI,MAAM;AACR,UAAM,WAAW;AAAA,MACf,iBAAiB;AAAA,QACf,QAAQ;AAAA,QACR,QAAQ,QAAQ,aAAa;AAAA,QAC7B,kBAAkB,QAAQ,aAAa;AAAA,QACvC,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,OAAO,CAAC,MAAM;AAAA,QACd,oBAAoB;AAAA,MACtB;AAAA,MACA,SAAS,CAAC,UAAU;AAAA,IACtB;AACA,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,YAAY,eAAe,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,EAC5F;AAEA,YAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,YAAY,MAAM,GAAG,iBAAiB,YAAY,iBAAiB;AAAA,YACpF,YAAY,qBAAqB;AAAA,CAC5C;AACC,YAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,YAAY,YAAY,GAAG;AAAA;AAAA;AAAA;AAAA,CAIvD;AAEC,QAAM,SAAS,YAAAA,QAAK,KAAK,YAAY,KAAK;AAC1C,YAAAC,QAAG,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACxC,YAAAA,QAAG,UAAU,YAAAD,QAAK,KAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/D,YAAAC,QAAG,UAAU,YAAAD,QAAK,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC7D,YAAAC,QAAG,UAAU,YAAAD,QAAK,KAAK,QAAQ,cAAc,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5E,YAAAC,QAAG,UAAU,YAAAD,QAAK,KAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAG5D,MAAI,MAAM;AACR,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,SAAS,GAAG,EAAE,GAAG,YAAY,KAAK;AAAA,EACvE,WAAW,OAAO;AAChB,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,SAAS,GAAG,EAAE,GAAG,aAAa,KAAK;AAAA,EACxE,OAAO;AACL,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,UAAU,GAAG,aAAa,KAAK;AAAA,EACpE;AAGA,MAAI,MAAM;AACR,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,YAAY,SAAS,GAAG,YAAY,IAAI;AAAA,EAC7E,WAAW,OAAO;AAChB,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,YAAY,SAAS,GAAG,aAAa,IAAI;AAAA,EAC9E,OAAO;AACL,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,YAAY,SAAS,GAAG,aAAa,IAAI;AAAA,EAC9E;AAGA,MAAI,MAAM;AACR,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,UAAU,UAAU,GAAG,YAAY,KAAK;AAAA,EAC7E,WAAW,OAAO;AAChB,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,UAAU,UAAU,GAAG,aAAa,KAAK;AAAA,EAC9E,OAAO;AACL,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,UAAU,UAAU,GAAG,aAAa,KAAK;AAAA,EAC9E;AAGA,MAAI,MAAM;AACR,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,SAAS,gBAAgB,GAAG,YAAY,WAAW;AAAA,EACxF,WAAW,OAAO;AAChB,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,SAAS,gBAAgB,GAAG,aAAa,WAAW;AAAA,EACzF,OAAO;AACL,cAAAC,QAAG,cAAc,YAAAD,QAAK,KAAK,QAAQ,SAAS,gBAAgB,GAAG,aAAa,WAAW;AAAA,EACzF;AAEA,UAAQ,IAAI,kBAAAD,QAAG,KAAK;AAAA,+BAAkC,EAAE,KAAK,CAAC;AAC9D,MAAI;AACF,uCAAS,GAAG,EAAE,YAAY,EAAE,KAAK,YAAY,OAAO,UAAU,CAAC;AAAA,EACjE,SAAS,OAAO;AACd,YAAQ,MAAM,kBAAAA,QAAG,IAAI;AAAA,8CAAiD,EAAE,qBAAqB,CAAC;AAAA,EAChG;AAEA,UAAQ,IAAI,kBAAAA,QAAG,MAAM,kBAAAA,QAAG,KAAK;AAAA,mBAAsB,WAAW,OAAO,UAAU,EAAE,CAAC,CAAC;AACnF,UAAQ,IAAI;AAAA,qDAAwD;AACpE,UAAQ,IAAI,kBAAAA,QAAG,KAAK;AAAA,IAAO,EAAE,UAAU,CAAC;AACxC,UAAQ,IAAI,uDAAuD;AACnE,MAAI,MAAM;AACR,YAAQ,IAAI,kBAAAA,QAAG,KAAK;AAAA,IAAO,EAAE,YAAY,CAAC;AAC1C,YAAQ,IAAI,kDAAkD;AAAA,EAChE;AACA,UAAQ,IAAI,kBAAAA,QAAG,KAAK;AAAA,IAAO,EAAE,QAAQ,CAAC;AACtC,UAAQ,IAAI,mCAAmC;AAC/C,UAAQ,IAAI;AAAA;AAAA,CAA0C;AACtD,UAAQ,IAAI,kBAAAA,QAAG,KAAK,QAAQ,WAAW,EAAE,CAAC;AAC1C,UAAQ,IAAI,kBAAAA,QAAG,KAAK,KAAK,EAAE;AAAA,CAAY,CAAC;AAC1C;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,kBAAAA,QAAG,IAAI,+BAA+B,GAAG,GAAG;AAC1D,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["pc","path","fs"]}
|