@intranefr/superbackend 1.7.7 → 1.7.9
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/.beads/.br_history/issues.20260314_212352_900045509.jsonl +0 -0
- package/.beads/.br_history/issues.20260314_212352_900045509.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_212353_087140743.jsonl +1 -0
- package/.beads/.br_history/issues.20260314_212353_087140743.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_212353_285881504.jsonl +2 -0
- package/.beads/.br_history/issues.20260314_212353_285881504.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_212353_473915419.jsonl +3 -0
- package/.beads/.br_history/issues.20260314_212353_473915419.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_212353_659476307.jsonl +4 -0
- package/.beads/.br_history/issues.20260314_212353_659476307.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_212353_869998925.jsonl +5 -0
- package/.beads/.br_history/issues.20260314_212353_869998925.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_212354_054785029.jsonl +6 -0
- package/.beads/.br_history/issues.20260314_212354_054785029.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213336_175893691.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213336_175893691.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213336_338509797.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213336_338509797.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213336_515443192.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213336_515443192.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213336_676417592.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213336_676417592.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213336_839182422.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213336_839182422.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213337_004349113.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213337_004349113.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213337_179824080.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213337_179824080.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213701_705075332.jsonl +7 -0
- package/.beads/.br_history/issues.20260314_213701_705075332.jsonl.meta.json +1 -0
- package/.beads/.br_history/issues.20260314_213706_783128702.jsonl +8 -0
- package/.beads/.br_history/issues.20260314_213706_783128702.jsonl.meta.json +1 -0
- package/.beads/config.yaml +4 -0
- package/.beads/issues.jsonl +8 -0
- package/.beads/metadata.json +4 -0
- package/.env.example +8 -0
- package/autochangelog/.env.example +36 -0
- package/autochangelog/README.md +412 -0
- package/autochangelog/config/database.js +27 -0
- package/autochangelog/package.json +47 -0
- package/autochangelog/public/landing.html +581 -0
- package/autochangelog/server.js +104 -0
- package/autochangelog/src/app.js +181 -0
- package/autochangelog/src/config/database.js +26 -0
- package/autochangelog/src/controllers/auth.js +488 -0
- package/autochangelog/src/controllers/changelog.js +682 -0
- package/autochangelog/src/controllers/project.js +580 -0
- package/autochangelog/src/controllers/repository.js +780 -0
- package/autochangelog/src/middleware/auth.js +386 -0
- package/autochangelog/src/models/Changelog.js +443 -0
- package/autochangelog/src/models/Project.js +226 -0
- package/autochangelog/src/models/Repository.js +366 -0
- package/autochangelog/src/models/User.js +223 -0
- package/autochangelog/src/routes/auth.routes.js +32 -0
- package/autochangelog/src/routes/changelog.routes.js +42 -0
- package/autochangelog/src/routes/github-auth.routes.js +102 -0
- package/autochangelog/src/routes/project.routes.js +50 -0
- package/autochangelog/src/routes/repository.routes.js +54 -0
- package/autochangelog/src/services/changelog.js +722 -0
- package/autochangelog/src/services/github.js +243 -0
- package/autochangelog/utils/logger.js +77 -0
- package/autochangelog/views/404.ejs +18 -0
- package/autochangelog/views/dashboard.ejs +596 -0
- package/autochangelog/views/index.ejs +231 -0
- package/autochangelog/views/layouts/main.ejs +44 -0
- package/autochangelog/views/login.ejs +104 -0
- package/autochangelog/views/partials/footer.ejs +20 -0
- package/autochangelog/views/partials/navbar.ejs +51 -0
- package/autochangelog/views/register.ejs +109 -0
- package/autochangelog-cli/README.md +266 -0
- package/autochangelog-cli/bin/autochangelog +120 -0
- package/autochangelog-cli/package.json +46 -0
- package/autochangelog-cli/src/cli/commands/auth.js +291 -0
- package/autochangelog-cli/src/cli/commands/changelog.js +619 -0
- package/autochangelog-cli/src/cli/commands/project.js +427 -0
- package/autochangelog-cli/src/cli/commands/repo.js +557 -0
- package/autochangelog-cli/src/cli/commands/stats.js +706 -0
- package/autochangelog-cli/src/cli/utils/config.js +277 -0
- package/autochangelog-cli/src/cli/utils/errors.js +307 -0
- package/autochangelog-cli/src/cli/utils/logger.js +75 -0
- package/autochangelog-cli/src/cli/utils/output.js +357 -0
- package/package.json +8 -3
- package/plugins/supercli/README.md +108 -0
- package/plugins/supercli/plugin.json +123 -0
- package/server.js +1 -1
- package/src/cli/api.js +380 -0
- package/src/cli/direct/agent-utils.js +61 -0
- package/src/cli/direct/cli-utils.js +112 -0
- package/src/cli/direct/data-seeding.js +307 -0
- package/src/cli/direct/db-admin.js +84 -0
- package/src/cli/direct/db-advanced.js +372 -0
- package/src/cli/direct/db-utils.js +558 -0
- package/src/cli/direct/help.js +195 -0
- package/src/cli/direct/migration.js +107 -0
- package/src/cli/direct/rbac-advanced.js +132 -0
- package/src/cli/direct/resources-additional.js +400 -0
- package/src/cli/direct/resources-cms-advanced.js +173 -0
- package/src/cli/direct/resources-cms.js +247 -0
- package/src/cli/direct/resources-core.js +253 -0
- package/src/cli/direct/resources-execution.js +367 -0
- package/src/cli/direct/resources-health.js +152 -0
- package/src/cli/direct/resources-integrations.js +182 -0
- package/src/cli/direct/resources-logs.js +204 -0
- package/src/cli/direct/resources-org-rbac.js +187 -0
- package/src/cli/direct/resources-system.js +236 -0
- package/src/cli/direct.js +556 -0
- package/src/controllers/admin.controller.js +4 -0
- package/src/controllers/auth.controller.js +148 -1
- package/src/controllers/waitingList.controller.js +130 -1
- package/src/models/RbacRole.js +1 -1
- package/src/models/User.js +39 -5
- package/src/routes/auth.routes.js +6 -0
- package/src/routes/waitingList.routes.js +12 -2
- package/src/routes/waitingListAdmin.routes.js +3 -0
- package/src/services/email.service.js +1 -0
- package/src/services/github.service.js +255 -0
- package/src/services/rateLimiter.service.js +29 -1
- package/src/services/waitingListJson.service.js +32 -3
- package/views/admin-waiting-list.ejs +386 -3
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CMS & Content handlers: blog-posts, pages, assets, forms, i18n, markdowns
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const mongoose = require('mongoose');
|
|
8
|
+
|
|
9
|
+
const blogPosts = {
|
|
10
|
+
async execute(options) {
|
|
11
|
+
const BlogPost = mongoose.model('BlogPost');
|
|
12
|
+
switch (options.command) {
|
|
13
|
+
case 'list': {
|
|
14
|
+
const posts = await BlogPost.find().lean();
|
|
15
|
+
return { items: posts, count: posts.length };
|
|
16
|
+
}
|
|
17
|
+
case 'get': {
|
|
18
|
+
if (!options.id) throw new Error('Post ID is required');
|
|
19
|
+
const post = await BlogPost.findById(options.id).lean();
|
|
20
|
+
if (!post) throw new Error('Post not found');
|
|
21
|
+
return post;
|
|
22
|
+
}
|
|
23
|
+
case 'create': {
|
|
24
|
+
if (!options.name) throw new Error('--name (title) is required');
|
|
25
|
+
const post = await BlogPost.create({
|
|
26
|
+
title: options.name,
|
|
27
|
+
content: options.description || '',
|
|
28
|
+
status: 'draft',
|
|
29
|
+
});
|
|
30
|
+
return post;
|
|
31
|
+
}
|
|
32
|
+
case 'update': {
|
|
33
|
+
if (!options.id) throw new Error('Post ID is required');
|
|
34
|
+
const updateData = {};
|
|
35
|
+
if (options.name) updateData.title = options.name;
|
|
36
|
+
if (options.description) updateData.content = options.description;
|
|
37
|
+
const post = await BlogPost.findByIdAndUpdate(options.id, updateData, { new: true });
|
|
38
|
+
if (!post) throw new Error('Post not found');
|
|
39
|
+
return post;
|
|
40
|
+
}
|
|
41
|
+
case 'delete': {
|
|
42
|
+
if (!options.id) throw new Error('Post ID is required');
|
|
43
|
+
const post = await BlogPost.findByIdAndDelete(options.id);
|
|
44
|
+
if (!post) throw new Error('Post not found');
|
|
45
|
+
return { success: true, id: options.id };
|
|
46
|
+
}
|
|
47
|
+
case 'publish': {
|
|
48
|
+
if (!options.id) throw new Error('Post ID is required');
|
|
49
|
+
const post = await BlogPost.findByIdAndUpdate(
|
|
50
|
+
options.id,
|
|
51
|
+
{ status: 'published', publishedAt: new Date() },
|
|
52
|
+
{ new: true }
|
|
53
|
+
);
|
|
54
|
+
if (!post) throw new Error('Post not found');
|
|
55
|
+
return post;
|
|
56
|
+
}
|
|
57
|
+
case 'unpublish': {
|
|
58
|
+
if (!options.id) throw new Error('Post ID is required');
|
|
59
|
+
const post = await BlogPost.findByIdAndUpdate(options.id, { status: 'draft' }, { new: true });
|
|
60
|
+
if (!post) throw new Error('Post not found');
|
|
61
|
+
return post;
|
|
62
|
+
}
|
|
63
|
+
default:
|
|
64
|
+
throw new Error(`Unknown blog-posts command: ${options.command}`);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const pages = {
|
|
70
|
+
async execute(options) {
|
|
71
|
+
const Page = mongoose.model('Page');
|
|
72
|
+
switch (options.command) {
|
|
73
|
+
case 'list': {
|
|
74
|
+
const pages = await Page.find().lean();
|
|
75
|
+
return { items: pages, count: pages.length };
|
|
76
|
+
}
|
|
77
|
+
case 'get': {
|
|
78
|
+
if (!options.id) throw new Error('Page ID is required');
|
|
79
|
+
const page = await Page.findById(options.id).lean();
|
|
80
|
+
if (!page) throw new Error('Page not found');
|
|
81
|
+
return page;
|
|
82
|
+
}
|
|
83
|
+
case 'create': {
|
|
84
|
+
if (!options.name) throw new Error('--name (slug) is required');
|
|
85
|
+
const page = await Page.create({
|
|
86
|
+
slug: options.name,
|
|
87
|
+
title: options.description || options.name,
|
|
88
|
+
content: options.value || '',
|
|
89
|
+
});
|
|
90
|
+
return page;
|
|
91
|
+
}
|
|
92
|
+
case 'update': {
|
|
93
|
+
if (!options.id) throw new Error('Page ID is required');
|
|
94
|
+
const updateData = {};
|
|
95
|
+
if (options.name) updateData.slug = options.name;
|
|
96
|
+
if (options.description) updateData.title = options.description;
|
|
97
|
+
if (options.value) updateData.content = options.value;
|
|
98
|
+
const page = await Page.findByIdAndUpdate(options.id, updateData, { new: true });
|
|
99
|
+
if (!page) throw new Error('Page not found');
|
|
100
|
+
return page;
|
|
101
|
+
}
|
|
102
|
+
case 'delete': {
|
|
103
|
+
if (!options.id) throw new Error('Page ID is required');
|
|
104
|
+
const page = await Page.findByIdAndDelete(options.id);
|
|
105
|
+
if (!page) throw new Error('Page not found');
|
|
106
|
+
return { success: true, id: options.id };
|
|
107
|
+
}
|
|
108
|
+
default:
|
|
109
|
+
throw new Error(`Unknown pages command: ${options.command}`);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const assets = {
|
|
115
|
+
async execute(options) {
|
|
116
|
+
const Asset = mongoose.model('Asset');
|
|
117
|
+
switch (options.command) {
|
|
118
|
+
case 'list': {
|
|
119
|
+
const limit = parseInt(options.value) || 50;
|
|
120
|
+
const assets = await Asset.find().sort({ createdAt: -1 }).limit(limit).lean();
|
|
121
|
+
return { items: assets, count: assets.length };
|
|
122
|
+
}
|
|
123
|
+
case 'get': {
|
|
124
|
+
if (!options.id) throw new Error('Asset ID is required');
|
|
125
|
+
const asset = await Asset.findById(options.id).lean();
|
|
126
|
+
if (!asset) throw new Error('Asset not found');
|
|
127
|
+
return asset;
|
|
128
|
+
}
|
|
129
|
+
case 'delete': {
|
|
130
|
+
if (!options.id) throw new Error('Asset ID is required');
|
|
131
|
+
const asset = await Asset.findByIdAndDelete(options.id);
|
|
132
|
+
if (!asset) throw new Error('Asset not found');
|
|
133
|
+
return { success: true, id: options.id };
|
|
134
|
+
}
|
|
135
|
+
case 'clear': {
|
|
136
|
+
await Asset.deleteMany({});
|
|
137
|
+
return { success: true, message: 'All assets cleared' };
|
|
138
|
+
}
|
|
139
|
+
default:
|
|
140
|
+
throw new Error(`Unknown assets command: ${options.command}`);
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const forms = {
|
|
146
|
+
async execute(options) {
|
|
147
|
+
const FormSubmission = mongoose.model('FormSubmission');
|
|
148
|
+
switch (options.command) {
|
|
149
|
+
case 'list': {
|
|
150
|
+
const limit = parseInt(options.value) || 50;
|
|
151
|
+
const submissions = await FormSubmission.find().sort({ createdAt: -1 }).limit(limit).lean();
|
|
152
|
+
return { items: submissions, count: submissions.length };
|
|
153
|
+
}
|
|
154
|
+
case 'get': {
|
|
155
|
+
if (!options.id) throw new Error('Submission ID is required');
|
|
156
|
+
const submission = await FormSubmission.findById(options.id).lean();
|
|
157
|
+
if (!submission) throw new Error('Submission not found');
|
|
158
|
+
return submission;
|
|
159
|
+
}
|
|
160
|
+
case 'delete': {
|
|
161
|
+
if (!options.id) throw new Error('Submission ID is required');
|
|
162
|
+
const submission = await FormSubmission.findByIdAndDelete(options.id);
|
|
163
|
+
if (!submission) throw new Error('Submission not found');
|
|
164
|
+
return { success: true, id: options.id };
|
|
165
|
+
}
|
|
166
|
+
case 'clear': {
|
|
167
|
+
await FormSubmission.deleteMany({});
|
|
168
|
+
return { success: true, message: 'All form submissions cleared' };
|
|
169
|
+
}
|
|
170
|
+
default:
|
|
171
|
+
throw new Error(`Unknown forms command: ${options.command}`);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const i18n = {
|
|
177
|
+
async execute(options) {
|
|
178
|
+
const I18nEntry = mongoose.model('I18nEntry');
|
|
179
|
+
switch (options.command) {
|
|
180
|
+
case 'list': {
|
|
181
|
+
const limit = parseInt(options.value) || 50;
|
|
182
|
+
const entries = await I18nEntry.find().sort({ createdAt: -1 }).limit(limit).lean();
|
|
183
|
+
return { items: entries, count: entries.length };
|
|
184
|
+
}
|
|
185
|
+
case 'get': {
|
|
186
|
+
if (!options.id) throw new Error('I18n entry ID is required');
|
|
187
|
+
const entry = await I18nEntry.findById(options.id).lean();
|
|
188
|
+
if (!entry) throw new Error('I18n entry not found');
|
|
189
|
+
return entry;
|
|
190
|
+
}
|
|
191
|
+
case 'create': {
|
|
192
|
+
if (!options.key) throw new Error('--key is required');
|
|
193
|
+
if (!options.value) throw new Error('--value is required');
|
|
194
|
+
const entry = await I18nEntry.create({
|
|
195
|
+
key: options.key,
|
|
196
|
+
values: { en: options.value },
|
|
197
|
+
locale: 'en',
|
|
198
|
+
});
|
|
199
|
+
return entry;
|
|
200
|
+
}
|
|
201
|
+
case 'delete': {
|
|
202
|
+
if (!options.id) throw new Error('I18n entry ID is required');
|
|
203
|
+
const entry = await I18nEntry.findByIdAndDelete(options.id);
|
|
204
|
+
if (!entry) throw new Error('I18n entry not found');
|
|
205
|
+
return { success: true, id: options.id };
|
|
206
|
+
}
|
|
207
|
+
default:
|
|
208
|
+
throw new Error(`Unknown i18n command: ${options.command}`);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const markdowns = {
|
|
214
|
+
async execute(options) {
|
|
215
|
+
const Markdown = mongoose.model('Markdown');
|
|
216
|
+
switch (options.command) {
|
|
217
|
+
case 'list': {
|
|
218
|
+
const markdowns = await Markdown.find().lean();
|
|
219
|
+
return { items: markdowns, count: markdowns.length };
|
|
220
|
+
}
|
|
221
|
+
case 'get': {
|
|
222
|
+
if (!options.id) throw new Error('Markdown ID is required');
|
|
223
|
+
const markdown = await Markdown.findById(options.id).lean();
|
|
224
|
+
if (!markdown) throw new Error('Markdown not found');
|
|
225
|
+
return markdown;
|
|
226
|
+
}
|
|
227
|
+
case 'create': {
|
|
228
|
+
if (!options.name) throw new Error('--name (slug) is required');
|
|
229
|
+
const markdown = await Markdown.create({
|
|
230
|
+
slug: options.name,
|
|
231
|
+
content: options.value || '',
|
|
232
|
+
});
|
|
233
|
+
return markdown;
|
|
234
|
+
}
|
|
235
|
+
case 'delete': {
|
|
236
|
+
if (!options.id) throw new Error('Markdown ID is required');
|
|
237
|
+
const markdown = await Markdown.findByIdAndDelete(options.id);
|
|
238
|
+
if (!markdown) throw new Error('Markdown not found');
|
|
239
|
+
return { success: true, id: options.id };
|
|
240
|
+
}
|
|
241
|
+
default:
|
|
242
|
+
throw new Error(`Unknown markdowns command: ${options.command}`);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
module.exports = { blogPosts, pages, assets, forms, i18n, markdowns };
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Core resource handlers: agents, settings, users, json-configs
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const mongoose = require("mongoose");
|
|
8
|
+
|
|
9
|
+
const agents = {
|
|
10
|
+
async execute(options) {
|
|
11
|
+
const Agent = mongoose.model("Agent");
|
|
12
|
+
switch (options.command) {
|
|
13
|
+
case "list": {
|
|
14
|
+
const agents = await Agent.find().lean();
|
|
15
|
+
return { items: agents, count: agents.length };
|
|
16
|
+
}
|
|
17
|
+
case "get": {
|
|
18
|
+
if (!options.id) throw new Error("Agent ID is required");
|
|
19
|
+
const agent = await Agent.findById(options.id).lean();
|
|
20
|
+
if (!agent) throw new Error("Agent not found");
|
|
21
|
+
return agent;
|
|
22
|
+
}
|
|
23
|
+
case "create": {
|
|
24
|
+
if (!options.name) throw new Error("--name is required");
|
|
25
|
+
if (!options.model) throw new Error("--model is required");
|
|
26
|
+
if (!options.key) throw new Error("--key (providerKey) is required");
|
|
27
|
+
const agent = await Agent.create({
|
|
28
|
+
name: options.name,
|
|
29
|
+
model: options.model,
|
|
30
|
+
providerKey: options.key,
|
|
31
|
+
systemPrompt: options.description || "",
|
|
32
|
+
});
|
|
33
|
+
return agent;
|
|
34
|
+
}
|
|
35
|
+
case "update": {
|
|
36
|
+
if (!options.id) throw new Error("Agent ID is required");
|
|
37
|
+
const updateData = {};
|
|
38
|
+
if (options.name) updateData.name = options.name;
|
|
39
|
+
if (options.model) updateData.model = options.model;
|
|
40
|
+
if (options.description) updateData.systemPrompt = options.description;
|
|
41
|
+
const agent = await Agent.findByIdAndUpdate(options.id, updateData, {
|
|
42
|
+
new: true,
|
|
43
|
+
});
|
|
44
|
+
if (!agent) throw new Error("Agent not found");
|
|
45
|
+
return agent;
|
|
46
|
+
}
|
|
47
|
+
case "delete": {
|
|
48
|
+
if (!options.id) throw new Error("Agent ID is required");
|
|
49
|
+
const agent = await Agent.findByIdAndDelete(options.id);
|
|
50
|
+
if (!agent) throw new Error("Agent not found");
|
|
51
|
+
return { success: true, id: options.id };
|
|
52
|
+
}
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Unknown agents command: ${options.command}`);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const settings = {
|
|
60
|
+
async execute(options) {
|
|
61
|
+
const GlobalSetting = mongoose.model("GlobalSetting");
|
|
62
|
+
switch (options.command) {
|
|
63
|
+
case "list": {
|
|
64
|
+
const settings = await GlobalSetting.find().lean();
|
|
65
|
+
return { items: settings, count: settings.length };
|
|
66
|
+
}
|
|
67
|
+
case "get": {
|
|
68
|
+
if (!options.key) throw new Error("--key is required");
|
|
69
|
+
const setting = await GlobalSetting.findOne({
|
|
70
|
+
key: options.key,
|
|
71
|
+
}).lean();
|
|
72
|
+
if (!setting) throw new Error("Setting not found");
|
|
73
|
+
return setting;
|
|
74
|
+
}
|
|
75
|
+
case "create": {
|
|
76
|
+
if (!options.key) throw new Error("--key is required");
|
|
77
|
+
if (options.value === undefined) throw new Error("--value is required");
|
|
78
|
+
let parsedValue = options.value;
|
|
79
|
+
try {
|
|
80
|
+
parsedValue = JSON.parse(options.value);
|
|
81
|
+
} catch (e) {}
|
|
82
|
+
const setting = await GlobalSetting.create({
|
|
83
|
+
key: options.key,
|
|
84
|
+
value: parsedValue,
|
|
85
|
+
description: options.description || "",
|
|
86
|
+
});
|
|
87
|
+
return setting;
|
|
88
|
+
}
|
|
89
|
+
case "update": {
|
|
90
|
+
if (!options.key) throw new Error("--key is required");
|
|
91
|
+
const updateData = {};
|
|
92
|
+
if (options.value !== undefined) {
|
|
93
|
+
try {
|
|
94
|
+
updateData.value = JSON.parse(options.value);
|
|
95
|
+
} catch (e) {
|
|
96
|
+
updateData.value = options.value;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (options.description) updateData.description = options.description;
|
|
100
|
+
const setting = await GlobalSetting.findOneAndUpdate(
|
|
101
|
+
{ key: options.key },
|
|
102
|
+
updateData,
|
|
103
|
+
{ new: true },
|
|
104
|
+
);
|
|
105
|
+
if (!setting) throw new Error("Setting not found");
|
|
106
|
+
return setting;
|
|
107
|
+
}
|
|
108
|
+
case "delete": {
|
|
109
|
+
if (!options.key) throw new Error("--key is required");
|
|
110
|
+
const setting = await GlobalSetting.findOneAndDelete({
|
|
111
|
+
key: options.key,
|
|
112
|
+
});
|
|
113
|
+
if (!setting) throw new Error("Setting not found");
|
|
114
|
+
return { success: true, key: options.key };
|
|
115
|
+
}
|
|
116
|
+
default:
|
|
117
|
+
throw new Error(`Unknown settings command: ${options.command}`);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const users = {
|
|
123
|
+
async execute(options) {
|
|
124
|
+
const User = mongoose.model("User");
|
|
125
|
+
switch (options.command) {
|
|
126
|
+
case "list": {
|
|
127
|
+
const users = await User.find().select("-password").lean();
|
|
128
|
+
return { items: users, count: users.length };
|
|
129
|
+
}
|
|
130
|
+
case "get": {
|
|
131
|
+
if (!options.id) throw new Error("User ID is required");
|
|
132
|
+
const user = await User.findById(options.id).select("-password").lean();
|
|
133
|
+
if (!user) throw new Error("User not found");
|
|
134
|
+
return user;
|
|
135
|
+
}
|
|
136
|
+
case "create": {
|
|
137
|
+
if (!options.email) throw new Error("--email is required");
|
|
138
|
+
if (!options.password) throw new Error("--password is required");
|
|
139
|
+
const bcrypt = require("bcryptjs");
|
|
140
|
+
const passwordHash = await bcrypt.hash(options.password, 10);
|
|
141
|
+
const user = await User.create({
|
|
142
|
+
email: options.email,
|
|
143
|
+
passwordHash: passwordHash,
|
|
144
|
+
role: options.role || "user",
|
|
145
|
+
});
|
|
146
|
+
return { _id: user._id, email: user.email, role: user.role };
|
|
147
|
+
}
|
|
148
|
+
case "update": {
|
|
149
|
+
if (!options.id) throw new Error("User ID is required");
|
|
150
|
+
const updateData = {};
|
|
151
|
+
if (options.email) updateData.email = options.email;
|
|
152
|
+
if (options.password) updateData.password = options.password;
|
|
153
|
+
if (options.role) updateData.role = options.role;
|
|
154
|
+
const user = await User.findByIdAndUpdate(options.id, updateData, {
|
|
155
|
+
new: true,
|
|
156
|
+
});
|
|
157
|
+
if (!user) throw new Error("User not found");
|
|
158
|
+
return { _id: user._id, email: user.email, role: user.role };
|
|
159
|
+
}
|
|
160
|
+
case "delete": {
|
|
161
|
+
if (!options.id) throw new Error("User ID is required");
|
|
162
|
+
const user = await User.findByIdAndDelete(options.id);
|
|
163
|
+
if (!user) throw new Error("User not found");
|
|
164
|
+
return { success: true, id: options.id };
|
|
165
|
+
}
|
|
166
|
+
case "disable": {
|
|
167
|
+
if (!options.id) throw new Error("User ID is required");
|
|
168
|
+
const user = await User.findByIdAndUpdate(
|
|
169
|
+
options.id,
|
|
170
|
+
{ disabled: true },
|
|
171
|
+
{ new: true },
|
|
172
|
+
);
|
|
173
|
+
if (!user) throw new Error("User not found");
|
|
174
|
+
return { success: true, id: options.id, disabled: true };
|
|
175
|
+
}
|
|
176
|
+
case "enable": {
|
|
177
|
+
if (!options.id) throw new Error("User ID is required");
|
|
178
|
+
const user = await User.findByIdAndUpdate(
|
|
179
|
+
options.id,
|
|
180
|
+
{ disabled: false },
|
|
181
|
+
{ new: true },
|
|
182
|
+
);
|
|
183
|
+
if (!user) throw new Error("User not found");
|
|
184
|
+
return { success: true, id: options.id, disabled: false };
|
|
185
|
+
}
|
|
186
|
+
default:
|
|
187
|
+
throw new Error(`Unknown users command: ${options.command}`);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const jsonConfigs = {
|
|
193
|
+
async execute(options) {
|
|
194
|
+
const JsonConfig = mongoose.model("JsonConfig");
|
|
195
|
+
switch (options.command) {
|
|
196
|
+
case "list": {
|
|
197
|
+
const configs = await JsonConfig.find().lean();
|
|
198
|
+
return { items: configs, count: configs.length };
|
|
199
|
+
}
|
|
200
|
+
case "get": {
|
|
201
|
+
if (!options.alias) throw new Error("--alias is required");
|
|
202
|
+
const config = await JsonConfig.findOne({
|
|
203
|
+
alias: options.alias,
|
|
204
|
+
}).lean();
|
|
205
|
+
if (!config) throw new Error("Config not found");
|
|
206
|
+
return config;
|
|
207
|
+
}
|
|
208
|
+
case "create": {
|
|
209
|
+
if (!options.alias) throw new Error("--alias is required");
|
|
210
|
+
if (!options.json) throw new Error("--json is required");
|
|
211
|
+
let parsedJson;
|
|
212
|
+
try {
|
|
213
|
+
parsedJson = JSON.parse(options.json);
|
|
214
|
+
} catch (e) {
|
|
215
|
+
throw new Error("--json must be valid JSON");
|
|
216
|
+
}
|
|
217
|
+
const config = await JsonConfig.create({
|
|
218
|
+
alias: options.alias,
|
|
219
|
+
jsonRaw: options.json,
|
|
220
|
+
});
|
|
221
|
+
return config;
|
|
222
|
+
}
|
|
223
|
+
case "update": {
|
|
224
|
+
if (!options.alias) throw new Error("--alias is required");
|
|
225
|
+
if (!options.json) throw new Error("--json is required");
|
|
226
|
+
try {
|
|
227
|
+
JSON.parse(options.json);
|
|
228
|
+
} catch (e) {
|
|
229
|
+
throw new Error("--json must be valid JSON");
|
|
230
|
+
}
|
|
231
|
+
const config = await JsonConfig.findOneAndUpdate(
|
|
232
|
+
{ alias: options.alias },
|
|
233
|
+
{ jsonRaw: options.json },
|
|
234
|
+
{ new: true },
|
|
235
|
+
);
|
|
236
|
+
if (!config) throw new Error("Config not found");
|
|
237
|
+
return config;
|
|
238
|
+
}
|
|
239
|
+
case "delete": {
|
|
240
|
+
if (!options.alias) throw new Error("--alias is required");
|
|
241
|
+
const config = await JsonConfig.findOneAndDelete({
|
|
242
|
+
alias: options.alias,
|
|
243
|
+
});
|
|
244
|
+
if (!config) throw new Error("Config not found");
|
|
245
|
+
return { success: true, alias: options.alias };
|
|
246
|
+
}
|
|
247
|
+
default:
|
|
248
|
+
throw new Error(`Unknown json-configs command: ${options.command}`);
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
module.exports = { agents, settings, users, jsonConfigs };
|