@intranefr/superbackend 1.7.7 → 1.7.8

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.
Files changed (119) hide show
  1. package/.beads/.br_history/issues.20260314_212352_900045509.jsonl +0 -0
  2. package/.beads/.br_history/issues.20260314_212352_900045509.jsonl.meta.json +1 -0
  3. package/.beads/.br_history/issues.20260314_212353_087140743.jsonl +1 -0
  4. package/.beads/.br_history/issues.20260314_212353_087140743.jsonl.meta.json +1 -0
  5. package/.beads/.br_history/issues.20260314_212353_285881504.jsonl +2 -0
  6. package/.beads/.br_history/issues.20260314_212353_285881504.jsonl.meta.json +1 -0
  7. package/.beads/.br_history/issues.20260314_212353_473915419.jsonl +3 -0
  8. package/.beads/.br_history/issues.20260314_212353_473915419.jsonl.meta.json +1 -0
  9. package/.beads/.br_history/issues.20260314_212353_659476307.jsonl +4 -0
  10. package/.beads/.br_history/issues.20260314_212353_659476307.jsonl.meta.json +1 -0
  11. package/.beads/.br_history/issues.20260314_212353_869998925.jsonl +5 -0
  12. package/.beads/.br_history/issues.20260314_212353_869998925.jsonl.meta.json +1 -0
  13. package/.beads/.br_history/issues.20260314_212354_054785029.jsonl +6 -0
  14. package/.beads/.br_history/issues.20260314_212354_054785029.jsonl.meta.json +1 -0
  15. package/.beads/.br_history/issues.20260314_213336_175893691.jsonl +7 -0
  16. package/.beads/.br_history/issues.20260314_213336_175893691.jsonl.meta.json +1 -0
  17. package/.beads/.br_history/issues.20260314_213336_338509797.jsonl +7 -0
  18. package/.beads/.br_history/issues.20260314_213336_338509797.jsonl.meta.json +1 -0
  19. package/.beads/.br_history/issues.20260314_213336_515443192.jsonl +7 -0
  20. package/.beads/.br_history/issues.20260314_213336_515443192.jsonl.meta.json +1 -0
  21. package/.beads/.br_history/issues.20260314_213336_676417592.jsonl +7 -0
  22. package/.beads/.br_history/issues.20260314_213336_676417592.jsonl.meta.json +1 -0
  23. package/.beads/.br_history/issues.20260314_213336_839182422.jsonl +7 -0
  24. package/.beads/.br_history/issues.20260314_213336_839182422.jsonl.meta.json +1 -0
  25. package/.beads/.br_history/issues.20260314_213337_004349113.jsonl +7 -0
  26. package/.beads/.br_history/issues.20260314_213337_004349113.jsonl.meta.json +1 -0
  27. package/.beads/.br_history/issues.20260314_213337_179824080.jsonl +7 -0
  28. package/.beads/.br_history/issues.20260314_213337_179824080.jsonl.meta.json +1 -0
  29. package/.beads/.br_history/issues.20260314_213701_705075332.jsonl +7 -0
  30. package/.beads/.br_history/issues.20260314_213701_705075332.jsonl.meta.json +1 -0
  31. package/.beads/.br_history/issues.20260314_213706_783128702.jsonl +8 -0
  32. package/.beads/.br_history/issues.20260314_213706_783128702.jsonl.meta.json +1 -0
  33. package/.beads/config.yaml +4 -0
  34. package/.beads/issues.jsonl +8 -0
  35. package/.beads/metadata.json +4 -0
  36. package/.env.example +8 -0
  37. package/autochangelog/.env.example +36 -0
  38. package/autochangelog/README.md +412 -0
  39. package/autochangelog/config/database.js +27 -0
  40. package/autochangelog/package.json +47 -0
  41. package/autochangelog/public/landing.html +581 -0
  42. package/autochangelog/server.js +104 -0
  43. package/autochangelog/src/app.js +181 -0
  44. package/autochangelog/src/config/database.js +26 -0
  45. package/autochangelog/src/controllers/auth.js +488 -0
  46. package/autochangelog/src/controllers/changelog.js +682 -0
  47. package/autochangelog/src/controllers/project.js +580 -0
  48. package/autochangelog/src/controllers/repository.js +780 -0
  49. package/autochangelog/src/middleware/auth.js +386 -0
  50. package/autochangelog/src/models/Changelog.js +443 -0
  51. package/autochangelog/src/models/Project.js +226 -0
  52. package/autochangelog/src/models/Repository.js +366 -0
  53. package/autochangelog/src/models/User.js +223 -0
  54. package/autochangelog/src/routes/auth.routes.js +32 -0
  55. package/autochangelog/src/routes/changelog.routes.js +42 -0
  56. package/autochangelog/src/routes/github-auth.routes.js +102 -0
  57. package/autochangelog/src/routes/project.routes.js +50 -0
  58. package/autochangelog/src/routes/repository.routes.js +54 -0
  59. package/autochangelog/src/services/changelog.js +722 -0
  60. package/autochangelog/src/services/github.js +243 -0
  61. package/autochangelog/utils/logger.js +77 -0
  62. package/autochangelog/views/404.ejs +18 -0
  63. package/autochangelog/views/dashboard.ejs +596 -0
  64. package/autochangelog/views/index.ejs +231 -0
  65. package/autochangelog/views/layouts/main.ejs +44 -0
  66. package/autochangelog/views/login.ejs +104 -0
  67. package/autochangelog/views/partials/footer.ejs +20 -0
  68. package/autochangelog/views/partials/navbar.ejs +51 -0
  69. package/autochangelog/views/register.ejs +109 -0
  70. package/autochangelog-cli/README.md +266 -0
  71. package/autochangelog-cli/bin/autochangelog +120 -0
  72. package/autochangelog-cli/package.json +46 -0
  73. package/autochangelog-cli/src/cli/commands/auth.js +291 -0
  74. package/autochangelog-cli/src/cli/commands/changelog.js +619 -0
  75. package/autochangelog-cli/src/cli/commands/project.js +427 -0
  76. package/autochangelog-cli/src/cli/commands/repo.js +557 -0
  77. package/autochangelog-cli/src/cli/commands/stats.js +706 -0
  78. package/autochangelog-cli/src/cli/utils/config.js +277 -0
  79. package/autochangelog-cli/src/cli/utils/errors.js +307 -0
  80. package/autochangelog-cli/src/cli/utils/logger.js +75 -0
  81. package/autochangelog-cli/src/cli/utils/output.js +357 -0
  82. package/package.json +8 -3
  83. package/plugins/supercli/README.md +108 -0
  84. package/plugins/supercli/plugin.json +123 -0
  85. package/server.js +1 -1
  86. package/src/cli/api.js +380 -0
  87. package/src/cli/direct/agent-utils.js +61 -0
  88. package/src/cli/direct/cli-utils.js +112 -0
  89. package/src/cli/direct/data-seeding.js +307 -0
  90. package/src/cli/direct/db-admin.js +84 -0
  91. package/src/cli/direct/db-advanced.js +372 -0
  92. package/src/cli/direct/db-utils.js +558 -0
  93. package/src/cli/direct/help.js +195 -0
  94. package/src/cli/direct/migration.js +107 -0
  95. package/src/cli/direct/rbac-advanced.js +132 -0
  96. package/src/cli/direct/resources-additional.js +400 -0
  97. package/src/cli/direct/resources-cms-advanced.js +173 -0
  98. package/src/cli/direct/resources-cms.js +247 -0
  99. package/src/cli/direct/resources-core.js +253 -0
  100. package/src/cli/direct/resources-execution.js +367 -0
  101. package/src/cli/direct/resources-health.js +152 -0
  102. package/src/cli/direct/resources-integrations.js +182 -0
  103. package/src/cli/direct/resources-logs.js +204 -0
  104. package/src/cli/direct/resources-org-rbac.js +187 -0
  105. package/src/cli/direct/resources-system.js +236 -0
  106. package/src/cli/direct.js +556 -0
  107. package/src/controllers/admin.controller.js +4 -0
  108. package/src/controllers/auth.controller.js +148 -1
  109. package/src/controllers/waitingList.controller.js +130 -1
  110. package/src/models/RbacRole.js +1 -1
  111. package/src/models/User.js +39 -5
  112. package/src/routes/auth.routes.js +6 -0
  113. package/src/routes/waitingList.routes.js +12 -2
  114. package/src/routes/waitingListAdmin.routes.js +3 -0
  115. package/src/services/email.service.js +1 -0
  116. package/src/services/github.service.js +255 -0
  117. package/src/services/rateLimiter.service.js +29 -1
  118. package/src/services/waitingListJson.service.js +32 -3
  119. package/views/admin-waiting-list.ejs +386 -3
@@ -0,0 +1,372 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Advanced database utilities for data analysis and manipulation
5
+ */
6
+
7
+ const mongoose = require("mongoose");
8
+
9
+ const collectionStats = {
10
+ async execute(options, context) {
11
+ const db = context.db;
12
+ const collectionName = options.key;
13
+
14
+ if (!collectionName) throw new Error("--key (collection name) is required");
15
+
16
+ const collection = db.collection(collectionName);
17
+ const stats = await collection.stats();
18
+ const indexes = await collection.indexes();
19
+
20
+ return {
21
+ collection: collectionName,
22
+ count: stats.count,
23
+ size: stats.size,
24
+ storageSize: stats.storageSize,
25
+ totalIndexSize: stats.totalIndexSize,
26
+ avgObjSize: stats.avgObjSize,
27
+ indexes: indexes.length,
28
+ capped: stats.capped,
29
+ max: stats.max,
30
+ };
31
+ },
32
+ };
33
+
34
+ const topCollections = {
35
+ async execute(options, context) {
36
+ if (options.command && options.command !== "execute") return;
37
+ const db = context.db;
38
+ const limit = parseInt(options.value) || 10;
39
+ const collections = await db.listCollections().toArray();
40
+ const stats = [];
41
+
42
+ for (const coll of collections) {
43
+ const count = await db.collection(coll.name).countDocuments();
44
+ stats.push({ name: coll.name, count });
45
+ }
46
+
47
+ return {
48
+ topCollections: stats.slice(0, limit),
49
+ totalCollections: collections.length,
50
+ };
51
+ },
52
+ };
53
+
54
+ const emptyCollections = {
55
+ async execute(options, context) {
56
+ if (options.command && options.command !== "execute") return;
57
+ const db = context.db;
58
+ const collections = await db.listCollections().toArray();
59
+ const empty = [];
60
+
61
+ for (const coll of collections) {
62
+ const count = await db.collection(coll.name).countDocuments();
63
+ if (count === 0) empty.push(coll.name);
64
+ }
65
+
66
+ return {
67
+ emptyCollections: empty,
68
+ totalEmpty: empty.length,
69
+ totalCollections: collections.length,
70
+ };
71
+ },
72
+ };
73
+
74
+ const findLargeDocuments = {
75
+ async execute(options, context) {
76
+ const db = context.db;
77
+ const collectionName = options.key;
78
+ const threshold = parseInt(options.value) || 1024 * 1024; // 1MB default
79
+
80
+ if (!collectionName) throw new Error("--key (collection name) is required");
81
+
82
+ const collection = db.collection(collectionName);
83
+ const docs = await collection.find({}).toArray();
84
+ const large = [];
85
+
86
+ for (const doc of docs) {
87
+ const size = Buffer.byteLength(JSON.stringify(doc), "utf8");
88
+ if (size > threshold) {
89
+ large.push({
90
+ _id: doc._id,
91
+ size,
92
+ sizeFormatted: (size / 1024).toFixed(2) + " KB",
93
+ });
94
+ }
95
+ }
96
+
97
+ large.sort((a, b) => b.size - a.size);
98
+ return {
99
+ collection: collectionName,
100
+ threshold,
101
+ largeDocuments: large.slice(0, 50),
102
+ };
103
+ },
104
+ };
105
+
106
+ const analyzeFieldTypes = {
107
+ async execute(options, context) {
108
+ const db = context.db;
109
+ const collectionName = options.key;
110
+ const fieldName = options.value;
111
+
112
+ if (!collectionName) throw new Error("--key (collection name) is required");
113
+ if (!fieldName) throw new Error("--value (field name) is required");
114
+
115
+ const collection = db.collection(collectionName);
116
+ const docs = await collection
117
+ .find({ [fieldName]: { $exists: true } })
118
+ .toArray();
119
+
120
+ const types = {};
121
+ for (const doc of docs) {
122
+ const val = doc[fieldName];
123
+ const type =
124
+ val === null ? "null" : Array.isArray(val) ? "array" : typeof val;
125
+ types[type] = (types[type] || 0) + 1;
126
+ }
127
+
128
+ return {
129
+ collection: collectionName,
130
+ fieldName,
131
+ totalDocs: docs.length,
132
+ typeDistribution: types,
133
+ };
134
+ },
135
+ };
136
+
137
+ const findNullFields = {
138
+ async execute(options, context) {
139
+ const db = context.db;
140
+ const collectionName = options.key;
141
+ const fieldName = options.value;
142
+
143
+ if (!collectionName) throw new Error("--key (collection name) is required");
144
+ if (!fieldName) throw new Error("--value (field name) is required");
145
+
146
+ const collection = db.collection(collectionName);
147
+ const count = await collection.countDocuments({
148
+ $or: [{ [fieldName]: null }, { [fieldName]: { $exists: false } }],
149
+ });
150
+ const total = await collection.countDocuments({});
151
+
152
+ return {
153
+ collection: collectionName,
154
+ fieldName,
155
+ nullCount: count,
156
+ totalCount: total,
157
+ percentage: ((count / total) * 100).toFixed(2) + "%",
158
+ };
159
+ },
160
+ };
161
+
162
+ const fillNullFields = {
163
+ async execute(options, context) {
164
+ const db = context.db;
165
+ const collectionName = options.key;
166
+ const fieldName = options.value;
167
+ const fillValue = options.description;
168
+
169
+ if (!collectionName) throw new Error("--key (collection name) is required");
170
+ if (!fieldName) throw new Error("--value (field name) is required");
171
+ if (fillValue === undefined)
172
+ throw new Error("--description (fill value) is required");
173
+
174
+ let parsedValue;
175
+ try {
176
+ parsedValue = JSON.parse(fillValue);
177
+ } catch (e) {
178
+ parsedValue = fillValue;
179
+ }
180
+
181
+ const collection = db.collection(collectionName);
182
+ const result = await collection.updateMany(
183
+ { [fieldName]: null },
184
+ { $set: { [fieldName]: parsedValue } },
185
+ );
186
+
187
+ return {
188
+ collection: collectionName,
189
+ fieldName,
190
+ updatedCount: result.modifiedCount,
191
+ fillValue: parsedValue,
192
+ };
193
+ },
194
+ };
195
+
196
+ const removeField = {
197
+ async execute(options, context) {
198
+ const db = context.db;
199
+ const collectionName = options.key;
200
+ const fieldName = options.value;
201
+
202
+ if (!collectionName) throw new Error("--key (collection name) is required");
203
+ if (!fieldName) throw new Error("--value (field name) is required");
204
+
205
+ const collection = db.collection(collectionName);
206
+ const result = await collection.updateMany(
207
+ {},
208
+ { $unset: { [fieldName]: "" } },
209
+ );
210
+
211
+ return {
212
+ collection: collectionName,
213
+ fieldName,
214
+ updatedCount: result.modifiedCount,
215
+ };
216
+ },
217
+ };
218
+
219
+ const renameField = {
220
+ async execute(options, context) {
221
+ const db = context.db;
222
+ const collectionName = options.key;
223
+ const parts = (options.value || "").split(":");
224
+ const oldName = parts[0];
225
+ const newName = parts[1];
226
+
227
+ if (!collectionName) throw new Error("--key (collection name) is required");
228
+ if (!oldName || !newName)
229
+ throw new Error('--value must be "oldName:newName"');
230
+
231
+ const collection = db.collection(collectionName);
232
+ const result = await collection.updateMany(
233
+ {},
234
+ { $rename: { [oldName]: newName } },
235
+ );
236
+
237
+ return {
238
+ collection: collectionName,
239
+ oldName,
240
+ newName,
241
+ updatedCount: result.modifiedCount,
242
+ };
243
+ },
244
+ };
245
+
246
+ const convertFieldTypes = {
247
+ async execute(options, context) {
248
+ const db = context.db;
249
+ const collectionName = options.key;
250
+ const fieldName = options.value;
251
+ const targetType = options.description;
252
+
253
+ if (!collectionName) throw new Error("--key (collection name) is required");
254
+ if (!fieldName) throw new Error("--value (field name) is required");
255
+ if (!targetType) throw new Error("--description (target type) is required");
256
+
257
+ const collection = db.collection(collectionName);
258
+ const docs = await collection
259
+ .find({ [fieldName]: { $exists: true } })
260
+ .toArray();
261
+ let convertedCount = 0;
262
+
263
+ for (const doc of docs) {
264
+ const val = doc[fieldName];
265
+ let newVal = val;
266
+
267
+ try {
268
+ if (targetType === "string") newVal = String(val);
269
+ else if (targetType === "number") newVal = Number(val);
270
+ else if (targetType === "boolean") newVal = Boolean(val);
271
+ else if (targetType === "date") newVal = new Date(val);
272
+ else if (targetType === "array")
273
+ newVal = Array.isArray(val) ? val : [val];
274
+
275
+ if (newVal !== val) {
276
+ await collection.updateOne(
277
+ { _id: doc._id },
278
+ { $set: { [fieldName]: newVal } },
279
+ );
280
+ convertedCount++;
281
+ }
282
+ } catch (e) {
283
+ // Skip conversion errors
284
+ }
285
+ }
286
+
287
+ return {
288
+ collection: collectionName,
289
+ fieldName,
290
+ targetType,
291
+ convertedCount,
292
+ };
293
+ },
294
+ };
295
+
296
+ const sampleDocuments = {
297
+ async execute(options, context) {
298
+ const db = context.db;
299
+ const collectionName = options.key;
300
+ const sampleSize = parseInt(options.value) || 10;
301
+
302
+ if (!collectionName) throw new Error("--key (collection name) is required");
303
+
304
+ const collection = db.collection(collectionName);
305
+ const sample = await collection
306
+ .aggregate([{ $sample: { size: sampleSize } }])
307
+ .toArray();
308
+
309
+ return { collection: collectionName, sampleSize: sample.length, sample };
310
+ },
311
+ };
312
+
313
+ const distinctValues = {
314
+ async execute(options, context) {
315
+ const db = context.db;
316
+ const collectionName = options.key;
317
+ const fieldName = options.value;
318
+
319
+ if (!collectionName) throw new Error("--key (collection name) is required");
320
+ if (!fieldName) throw new Error("--value (field name) is required");
321
+
322
+ const collection = db.collection(collectionName);
323
+ const distinct = await collection.distinct(fieldName);
324
+
325
+ return {
326
+ collection: collectionName,
327
+ fieldName,
328
+ distinctCount: distinct.length,
329
+ distinctValues: distinct.slice(0, 100),
330
+ };
331
+ },
332
+ };
333
+
334
+ const fieldCardinality = {
335
+ async execute(options, context) {
336
+ const db = context.db;
337
+ const collectionName = options.key;
338
+ const fieldName = options.value;
339
+
340
+ if (!collectionName) throw new Error("--key (collection name) is required");
341
+ if (!fieldName) throw new Error("--value (field name) is required");
342
+
343
+ const collection = db.collection(collectionName);
344
+ const total = await collection.countDocuments({});
345
+ const distinct = await collection.distinct(fieldName);
346
+
347
+ return {
348
+ collection: collectionName,
349
+ fieldName,
350
+ totalDocuments: total,
351
+ distinctValues: distinct.length,
352
+ cardinality:
353
+ total > 0 ? ((distinct.length / total) * 100).toFixed(2) + "%" : "0%",
354
+ };
355
+ },
356
+ };
357
+
358
+ module.exports = {
359
+ collectionStats,
360
+ topCollections,
361
+ emptyCollections,
362
+ findLargeDocuments,
363
+ analyzeFieldTypes,
364
+ findNullFields,
365
+ fillNullFields,
366
+ removeField,
367
+ renameField,
368
+ convertFieldTypes,
369
+ sampleDocuments,
370
+ distinctValues,
371
+ fieldCardinality,
372
+ };