@chimerai/cli 0.2.73
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/LICENSE +21 -0
- package/README.md +293 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +317 -0
- package/dist/commands/add.d.ts +11 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +2126 -0
- package/dist/commands/create.d.ts +12 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +1703 -0
- package/dist/commands/deploy.d.ts +11 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +219 -0
- package/dist/commands/dev.d.ts +17 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +206 -0
- package/dist/commands/doctor.d.ts +11 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +728 -0
- package/dist/commands/generate.d.ts +19 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +429 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +269 -0
- package/dist/commands/list.d.ts +12 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +328 -0
- package/dist/commands/migrate.d.ts +14 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +197 -0
- package/dist/commands/plugin.d.ts +10 -0
- package/dist/commands/plugin.d.ts.map +1 -0
- package/dist/commands/plugin.js +239 -0
- package/dist/commands/remove.d.ts +11 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +472 -0
- package/dist/commands/secret.d.ts +12 -0
- package/dist/commands/secret.d.ts.map +1 -0
- package/dist/commands/secret.js +102 -0
- package/dist/commands/setup.d.ts +9 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +788 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +211 -0
- package/dist/commands/use.d.ts +9 -0
- package/dist/commands/use.d.ts.map +1 -0
- package/dist/commands/use.js +51 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/license.d.ts +55 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +258 -0
- package/dist/scanner.d.ts +31 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +113 -0
- package/dist/schema-manager.d.ts +26 -0
- package/dist/schema-manager.d.ts.map +1 -0
- package/dist/schema-manager.js +132 -0
- package/dist/templates/admin.d.ts +49 -0
- package/dist/templates/admin.d.ts.map +1 -0
- package/dist/templates/admin.js +1358 -0
- package/dist/templates/ai-routes.d.ts +17 -0
- package/dist/templates/ai-routes.d.ts.map +1 -0
- package/dist/templates/ai-routes.js +1130 -0
- package/dist/templates/ai-service-tools.d.ts +22 -0
- package/dist/templates/ai-service-tools.d.ts.map +1 -0
- package/dist/templates/ai-service-tools.js +1424 -0
- package/dist/templates/ai-service.d.ts +66 -0
- package/dist/templates/ai-service.d.ts.map +1 -0
- package/dist/templates/ai-service.js +2202 -0
- package/dist/templates/api-routes.d.ts +108 -0
- package/dist/templates/api-routes.d.ts.map +1 -0
- package/dist/templates/api-routes.js +1219 -0
- package/dist/templates/auth.d.ts +48 -0
- package/dist/templates/auth.d.ts.map +1 -0
- package/dist/templates/auth.js +381 -0
- package/dist/templates/billing.d.ts +44 -0
- package/dist/templates/billing.d.ts.map +1 -0
- package/dist/templates/billing.js +551 -0
- package/dist/templates/chat.d.ts +63 -0
- package/dist/templates/chat.d.ts.map +1 -0
- package/dist/templates/chat.js +1979 -0
- package/dist/templates/components.d.ts +22 -0
- package/dist/templates/components.d.ts.map +1 -0
- package/dist/templates/components.js +672 -0
- package/dist/templates/config.d.ts +6 -0
- package/dist/templates/config.d.ts.map +1 -0
- package/dist/templates/config.js +86 -0
- package/dist/templates/docker.d.ts +25 -0
- package/dist/templates/docker.d.ts.map +1 -0
- package/dist/templates/docker.js +165 -0
- package/dist/templates/gdpr.d.ts +16 -0
- package/dist/templates/gdpr.d.ts.map +1 -0
- package/dist/templates/gdpr.js +259 -0
- package/dist/templates/index.d.ts +77 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +339 -0
- package/dist/templates/layout.d.ts +67 -0
- package/dist/templates/layout.d.ts.map +1 -0
- package/dist/templates/layout.js +670 -0
- package/dist/templates/mfa.d.ts +23 -0
- package/dist/templates/mfa.d.ts.map +1 -0
- package/dist/templates/mfa.js +353 -0
- package/dist/templates/middleware.d.ts +12 -0
- package/dist/templates/middleware.d.ts.map +1 -0
- package/dist/templates/middleware.js +116 -0
- package/dist/templates/prisma.d.ts +35 -0
- package/dist/templates/prisma.d.ts.map +1 -0
- package/dist/templates/prisma.js +724 -0
- package/dist/templates/provider-routes.d.ts +21 -0
- package/dist/templates/provider-routes.d.ts.map +1 -0
- package/dist/templates/provider-routes.js +1203 -0
- package/dist/templates/rag.d.ts +48 -0
- package/dist/templates/rag.d.ts.map +1 -0
- package/dist/templates/rag.js +532 -0
- package/dist/templates/widget.d.ts +64 -0
- package/dist/templates/widget.d.ts.map +1 -0
- package/dist/templates/widget.js +1360 -0
- package/dist/utils/provider-db.d.ts +63 -0
- package/dist/utils/provider-db.d.ts.map +1 -0
- package/dist/utils/provider-db.js +300 -0
- package/dist/utils.d.ts +78 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +330 -0
- package/package.json +60 -0
package/dist/license.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ChimerAI License & Edition Management
|
|
4
|
+
*
|
|
5
|
+
* Drei Tiers: free < enterprise < enterprise-pro
|
|
6
|
+
* License keys werden via Lemon Squeezy ausgegeben und lokal gespeichert.
|
|
7
|
+
*
|
|
8
|
+
* Key-Präfixe (Konvention):
|
|
9
|
+
* ls_live_ent_... → Enterprise
|
|
10
|
+
* ls_live_entpro_... → Enterprise Pro
|
|
11
|
+
* chi_ent_... → Enterprise (interner Test-Key)
|
|
12
|
+
* chi_entpro_... → Enterprise Pro (interner Test-Key)
|
|
13
|
+
*/
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.ENTERPRISE_PRO_COMPONENTS = exports.ENTERPRISE_COMPONENTS = exports.FREE_COMPONENTS = void 0;
|
|
19
|
+
exports.getRequiredEdition = getRequiredEdition;
|
|
20
|
+
exports.readLicense = readLicense;
|
|
21
|
+
exports.writeLicense = writeLicense;
|
|
22
|
+
exports.clearLicense = clearLicense;
|
|
23
|
+
exports.getEdition = getEdition;
|
|
24
|
+
exports.verifyLicenseToken = verifyLicenseToken;
|
|
25
|
+
exports.activateLicenseOnline = activateLicenseOnline;
|
|
26
|
+
exports.isEnterpriseOrHigher = isEnterpriseOrHigher;
|
|
27
|
+
exports.isEnterpriseProEdition = isEnterpriseProEdition;
|
|
28
|
+
exports.assertComponentAccess = assertComponentAccess;
|
|
29
|
+
exports.printLicenseStatus = printLicenseStatus;
|
|
30
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
31
|
+
const path_1 = __importDefault(require("path"));
|
|
32
|
+
const os_1 = __importDefault(require("os"));
|
|
33
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
34
|
+
const jose_1 = require("jose");
|
|
35
|
+
// ─── JWT Public Key (Ed25519) ─────────────────────────────────────────────────
|
|
36
|
+
// Private key lives only in Cloudflare Worker secret — never in binary.
|
|
37
|
+
// Public key is safe to embed: it can verify, but NOT sign.
|
|
38
|
+
const PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
39
|
+
MCowBQYDK2VwAyEAJVKs6IZX5OqyVSxaKpLK6leRpKHVAZF5nUUB6B9BqdI=
|
|
40
|
+
-----END PUBLIC KEY-----`;
|
|
41
|
+
const ACTIVATE_ENDPOINT = 'https://chimerai-activate-worker.chimerai.workers.dev/activate';
|
|
42
|
+
const LICENSE_DIR = path_1.default.join(os_1.default.homedir(), '.chimerai');
|
|
43
|
+
const LICENSE_PATH = path_1.default.join(LICENSE_DIR, 'license.json');
|
|
44
|
+
// ─── Tier-Hierarchie ─────────────────────────────────────────────────────────
|
|
45
|
+
// enterprise-pro ⊇ enterprise ⊇ free
|
|
46
|
+
// Ein höherer Tier hat immer Zugriff auf alle Features darunter.
|
|
47
|
+
const TIER_LEVEL = {
|
|
48
|
+
free: 0,
|
|
49
|
+
enterprise: 1,
|
|
50
|
+
'enterprise-pro': 2,
|
|
51
|
+
};
|
|
52
|
+
function meetsRequirement(actual, required) {
|
|
53
|
+
return TIER_LEVEL[actual] >= TIER_LEVEL[required];
|
|
54
|
+
}
|
|
55
|
+
// ─── Komponenten-Definitionen ─────────────────────────────────────────────────
|
|
56
|
+
/** Free-Komponenten — immer verfügbar, kein Gate */
|
|
57
|
+
exports.FREE_COMPONENTS = new Set([
|
|
58
|
+
'chat-ui',
|
|
59
|
+
'chat-widget',
|
|
60
|
+
'ai-chat',
|
|
61
|
+
'rag',
|
|
62
|
+
'model-providers',
|
|
63
|
+
'prompt-management',
|
|
64
|
+
]);
|
|
65
|
+
/** Enterprise-Komponenten (Enterprise + Enterprise Pro) */
|
|
66
|
+
exports.ENTERPRISE_COMPONENTS = {
|
|
67
|
+
auth: 'NextAuth Authentication + Session Management',
|
|
68
|
+
billing: 'Stripe Billing & Subscriptions',
|
|
69
|
+
'admin-dashboard': 'Admin Dashboard Overview',
|
|
70
|
+
'users-table': 'User Management CRUD',
|
|
71
|
+
'roles-table': 'Role Management CRUD',
|
|
72
|
+
gdpr: 'GDPR Compliance (Export, Deletion, Consent)',
|
|
73
|
+
mfa: 'Multi-Factor Authentication (TOTP)',
|
|
74
|
+
'audit-log': 'Audit Logging for Compliance',
|
|
75
|
+
analytics: 'API Usage Analytics',
|
|
76
|
+
sentry: 'Error Tracking & Monitoring',
|
|
77
|
+
};
|
|
78
|
+
/** Enterprise Pro-Komponenten (nur Enterprise Pro) */
|
|
79
|
+
exports.ENTERPRISE_PRO_COMPONENTS = {
|
|
80
|
+
webhooks: 'Webhook Dispatch with HMAC Signing',
|
|
81
|
+
theming: 'Dynamic Theme Engine',
|
|
82
|
+
guardrails: 'AI Content Safety & PII Detection',
|
|
83
|
+
'ai-tools': 'AI Tools (Web Search, NLP, Vision)',
|
|
84
|
+
};
|
|
85
|
+
// ─── Hilfsfunktionen ─────────────────────────────────────────────────────────
|
|
86
|
+
function getRequiredEdition(component) {
|
|
87
|
+
if (exports.FREE_COMPONENTS.has(component))
|
|
88
|
+
return 'free';
|
|
89
|
+
if (exports.ENTERPRISE_COMPONENTS[component])
|
|
90
|
+
return 'enterprise';
|
|
91
|
+
if (exports.ENTERPRISE_PRO_COMPONENTS[component])
|
|
92
|
+
return 'enterprise-pro';
|
|
93
|
+
return null; // Unbekannte Komponente — wird anderswo behandelt
|
|
94
|
+
}
|
|
95
|
+
// ─── License File I/O ─────────────────────────────────────────────────────────
|
|
96
|
+
function readLicense() {
|
|
97
|
+
try {
|
|
98
|
+
if (!fs_extra_1.default.existsSync(LICENSE_PATH))
|
|
99
|
+
return null;
|
|
100
|
+
const raw = fs_extra_1.default.readFileSync(LICENSE_PATH, 'utf-8');
|
|
101
|
+
return JSON.parse(raw);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function writeLicense(license) {
|
|
108
|
+
fs_extra_1.default.ensureDirSync(LICENSE_DIR);
|
|
109
|
+
fs_extra_1.default.writeFileSync(LICENSE_PATH, JSON.stringify(license, null, 2));
|
|
110
|
+
}
|
|
111
|
+
function clearLicense() {
|
|
112
|
+
if (fs_extra_1.default.existsSync(LICENSE_PATH)) {
|
|
113
|
+
fs_extra_1.default.removeSync(LICENSE_PATH);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ─── Edition Detection ────────────────────────────────────────────────────────
|
|
117
|
+
function getEdition() {
|
|
118
|
+
const license = readLicense();
|
|
119
|
+
if (!license)
|
|
120
|
+
return 'free';
|
|
121
|
+
if (license.edition !== 'enterprise' && license.edition !== 'enterprise-pro')
|
|
122
|
+
return 'free';
|
|
123
|
+
// If we have a JWT token, we trust only the locally cached edition
|
|
124
|
+
// (full async JWT verification happens in verifyLicenseToken)
|
|
125
|
+
// For sync gate checks we trust the stored edition — JWT is verified on activate
|
|
126
|
+
if (license.validUntil) {
|
|
127
|
+
const expiry = new Date(license.validUntil);
|
|
128
|
+
if (expiry < new Date())
|
|
129
|
+
return 'free';
|
|
130
|
+
}
|
|
131
|
+
return license.edition;
|
|
132
|
+
}
|
|
133
|
+
/** Verifies the JWT signature of a stored license token (async). */
|
|
134
|
+
async function verifyLicenseToken(token) {
|
|
135
|
+
try {
|
|
136
|
+
const publicKey = await (0, jose_1.importSPKI)(PUBLIC_KEY_PEM, 'EdDSA');
|
|
137
|
+
const { payload } = await (0, jose_1.jwtVerify)(token, publicKey, { issuer: 'chimerai.dev' });
|
|
138
|
+
const edition = payload['edition'];
|
|
139
|
+
const email = payload['email'] ?? '';
|
|
140
|
+
if (edition !== 'enterprise' && edition !== 'enterprise-pro')
|
|
141
|
+
return null;
|
|
142
|
+
return { edition, email };
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** Activates a license key by calling the chimerai.dev API. Returns error string or null on success. */
|
|
149
|
+
async function activateLicenseOnline(key) {
|
|
150
|
+
try {
|
|
151
|
+
const res = await fetch(ACTIVATE_ENDPOINT, {
|
|
152
|
+
method: 'POST',
|
|
153
|
+
headers: { 'Content-Type': 'application/json' },
|
|
154
|
+
body: JSON.stringify({ key, instance: os_1.default.hostname() }),
|
|
155
|
+
});
|
|
156
|
+
const data = (await res.json());
|
|
157
|
+
if (!res.ok || data['error']) {
|
|
158
|
+
return { error: String(data['error'] ?? 'Activation failed') };
|
|
159
|
+
}
|
|
160
|
+
const token = String(data['token'] ?? '');
|
|
161
|
+
const edition = String(data['edition'] ?? '');
|
|
162
|
+
const email = String(data['email'] ?? '');
|
|
163
|
+
// Verify JWT signature before trusting it
|
|
164
|
+
const publicKey = await (0, jose_1.importSPKI)(PUBLIC_KEY_PEM, 'EdDSA');
|
|
165
|
+
await (0, jose_1.jwtVerify)(token, publicKey, { issuer: 'chimerai.dev' });
|
|
166
|
+
return { edition, email, token };
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
170
|
+
if (msg.includes('fetch') || msg.includes('ENOTFOUND') || msg.includes('network')) {
|
|
171
|
+
return { error: 'Network error — check your internet connection.' };
|
|
172
|
+
}
|
|
173
|
+
return { error: `Activation failed: ${msg}` };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function isEnterpriseOrHigher() {
|
|
177
|
+
return meetsRequirement(getEdition(), 'enterprise');
|
|
178
|
+
}
|
|
179
|
+
function isEnterpriseProEdition() {
|
|
180
|
+
return getEdition() === 'enterprise-pro';
|
|
181
|
+
}
|
|
182
|
+
// ─── Feature Gate ─────────────────────────────────────────────────────────────
|
|
183
|
+
/**
|
|
184
|
+
* Prüft ob eine Komponente in der aktuellen Edition zugänglich ist.
|
|
185
|
+
* Gibt kontextuelle Upsell-Meldung aus und beendet den Prozess wenn nicht.
|
|
186
|
+
*/
|
|
187
|
+
function assertComponentAccess(component) {
|
|
188
|
+
const required = getRequiredEdition(component);
|
|
189
|
+
// Unbekannte Komponente — wird anderswo behandelt
|
|
190
|
+
if (required === null)
|
|
191
|
+
return;
|
|
192
|
+
// Free — immer erlaubt
|
|
193
|
+
if (required === 'free')
|
|
194
|
+
return;
|
|
195
|
+
const actual = getEdition();
|
|
196
|
+
// Zugriff erlaubt
|
|
197
|
+
if (meetsRequirement(actual, required))
|
|
198
|
+
return;
|
|
199
|
+
// --- Blockiert: kontextuelle Upsell-Meldung ---
|
|
200
|
+
if (actual === 'enterprise' && required === 'enterprise-pro') {
|
|
201
|
+
// Enterprise-Kunde will Enterprise-Pro-Feature
|
|
202
|
+
console.log(chalk_1.default.red(`\n 🔒 "${component}" is an Enterprise Pro feature.\n`));
|
|
203
|
+
console.log(chalk_1.default.bold(' Exclusive to ChimerAI Enterprise Pro:\n'));
|
|
204
|
+
for (const [name, desc] of Object.entries(exports.ENTERPRISE_PRO_COMPONENTS)) {
|
|
205
|
+
console.log(` ${chalk_1.default.yellow('•')} ${chalk_1.default.white(name.padEnd(22))} ${chalk_1.default.gray(desc)}`);
|
|
206
|
+
}
|
|
207
|
+
console.log(chalk_1.default.bold('\n You have Enterprise — upgrade to unlock these features:'));
|
|
208
|
+
console.log(chalk_1.default.bold('\n → Upgrade: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise-pro'));
|
|
209
|
+
console.log(chalk_1.default.bold(' → Contact: ') + chalk_1.default.cyan('sales@chimerai.dev\n'));
|
|
210
|
+
throw new Error(`"${component}" requires an Enterprise Pro license.`);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
// Free-Kunde will Enterprise- oder Enterprise-Pro-Feature
|
|
214
|
+
const isEntPro = required === 'enterprise-pro';
|
|
215
|
+
console.log(chalk_1.default.red(`\n 🔒 "${component}" is an ${isEntPro ? 'Enterprise Pro' : 'Enterprise'} feature.\n`));
|
|
216
|
+
console.log(chalk_1.default.bold(' 🏢 ChimerAI Enterprise:\n'));
|
|
217
|
+
for (const [name, desc] of Object.entries(exports.ENTERPRISE_COMPONENTS)) {
|
|
218
|
+
console.log(` ${chalk_1.default.green('•')} ${chalk_1.default.white(name.padEnd(22))} ${chalk_1.default.gray(desc)}`);
|
|
219
|
+
}
|
|
220
|
+
console.log(chalk_1.default.bold('\n 🚀 ChimerAI Enterprise Pro:\n'));
|
|
221
|
+
for (const [name, desc] of Object.entries(exports.ENTERPRISE_PRO_COMPONENTS)) {
|
|
222
|
+
console.log(` ${chalk_1.default.yellow('•')} ${chalk_1.default.white(name.padEnd(22))} ${chalk_1.default.gray(desc)}`);
|
|
223
|
+
}
|
|
224
|
+
console.log(chalk_1.default.bold('\n → Enterprise: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise'));
|
|
225
|
+
console.log(chalk_1.default.bold(' → Enterprise Pro: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise-pro'));
|
|
226
|
+
console.log(chalk_1.default.bold(' → Activate: ') + chalk_1.default.white('chimerai activate <LICENSE-KEY>'));
|
|
227
|
+
console.log(chalk_1.default.bold(' → Contact: ') + chalk_1.default.cyan('sales@chimerai.dev\n'));
|
|
228
|
+
throw new Error(isEntPro
|
|
229
|
+
? `"${component}" requires an Enterprise Pro license.`
|
|
230
|
+
: `"${component}" requires an Enterprise license.`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// ─── License Info (für chimerai license) ─────────────────────────────────────
|
|
234
|
+
const EDITION_LABELS = {
|
|
235
|
+
free: 'Free',
|
|
236
|
+
enterprise: 'Enterprise',
|
|
237
|
+
'enterprise-pro': 'Enterprise Pro',
|
|
238
|
+
};
|
|
239
|
+
function printLicenseStatus() {
|
|
240
|
+
const license = readLicense();
|
|
241
|
+
const edition = getEdition();
|
|
242
|
+
if (!license || edition === 'free') {
|
|
243
|
+
console.log(chalk_1.default.bold.yellow('\n 📋 Edition: ') + chalk_1.default.white('Free'));
|
|
244
|
+
console.log(chalk_1.default.gray(' No license key activated.'));
|
|
245
|
+
console.log(chalk_1.default.gray(' Enterprise: ') + chalk_1.default.cyan('https://chimerai.dev/enterprise'));
|
|
246
|
+
console.log(chalk_1.default.gray(' Activate with: ') + chalk_1.default.white('chimerai activate <KEY>\n'));
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const expiry = license.validUntil
|
|
250
|
+
? new Date(license.validUntil).toLocaleDateString('de-AT')
|
|
251
|
+
: 'unbegrenzt';
|
|
252
|
+
const color = edition === 'enterprise-pro' ? chalk_1.default.bold.magenta : chalk_1.default.bold.green;
|
|
253
|
+
console.log(color('\n 📋 Edition: ') + chalk_1.default.white(`${EDITION_LABELS[edition]} ✅`));
|
|
254
|
+
if (license.email)
|
|
255
|
+
console.log(chalk_1.default.gray(` Licensed to: ${license.email}`));
|
|
256
|
+
console.log(chalk_1.default.gray(` Valid until: ${expiry}`));
|
|
257
|
+
console.log(chalk_1.default.gray(` Activated: ${new Date(license.activatedAt).toLocaleDateString('en-US')}\n`));
|
|
258
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Scanner - PHASE 3.1
|
|
3
|
+
* Analyzes existing Next.js projects to detect configuration, frameworks, and installed components
|
|
4
|
+
* Used by `add` and `dev` commands to make intelligent decisions
|
|
5
|
+
*/
|
|
6
|
+
export interface ProjectInfo {
|
|
7
|
+
hasPackageJson: boolean;
|
|
8
|
+
packageManager: 'pnpm' | 'npm' | 'yarn' | 'bun' | 'unknown';
|
|
9
|
+
nextVersion: string | null;
|
|
10
|
+
hasAppRouter: boolean;
|
|
11
|
+
hasPagesRouter: boolean;
|
|
12
|
+
hasPrisma: boolean;
|
|
13
|
+
prismaProvider: 'postgresql' | 'mysql' | 'sqlite' | null;
|
|
14
|
+
prismaModels: string[];
|
|
15
|
+
hasNextAuth: boolean;
|
|
16
|
+
hasClerk: boolean;
|
|
17
|
+
hasSupabaseAuth: boolean;
|
|
18
|
+
hasShadcn: boolean;
|
|
19
|
+
hasTailwind: boolean;
|
|
20
|
+
hasChakra: boolean;
|
|
21
|
+
installedComponents: string[];
|
|
22
|
+
hasStripe: boolean;
|
|
23
|
+
hasLemonSqueezy: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Scan project for framework, dependencies, and installed components
|
|
27
|
+
* @param targetDir - Project root directory
|
|
28
|
+
* @returns ProjectInfo with detailed project configuration
|
|
29
|
+
*/
|
|
30
|
+
export declare function scanProject(targetDir: string): Promise<ProjectInfo>;
|
|
31
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,WAAW;IAE1B,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAG5D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IAGxB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IACzD,YAAY,EAAE,MAAM,EAAE,CAAC;IAGvB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IAGzB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IAGnB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAG9B,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA0GzE"}
|
package/dist/scanner.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project Scanner - PHASE 3.1
|
|
4
|
+
* Analyzes existing Next.js projects to detect configuration, frameworks, and installed components
|
|
5
|
+
* Used by `add` and `dev` commands to make intelligent decisions
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.scanProject = scanProject;
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
14
|
+
/**
|
|
15
|
+
* Scan project for framework, dependencies, and installed components
|
|
16
|
+
* @param targetDir - Project root directory
|
|
17
|
+
* @returns ProjectInfo with detailed project configuration
|
|
18
|
+
*/
|
|
19
|
+
async function scanProject(targetDir) {
|
|
20
|
+
const info = {
|
|
21
|
+
hasPackageJson: false,
|
|
22
|
+
packageManager: 'unknown',
|
|
23
|
+
nextVersion: null,
|
|
24
|
+
hasAppRouter: false,
|
|
25
|
+
hasPagesRouter: false,
|
|
26
|
+
hasPrisma: false,
|
|
27
|
+
prismaProvider: null,
|
|
28
|
+
prismaModels: [],
|
|
29
|
+
hasNextAuth: false,
|
|
30
|
+
hasClerk: false,
|
|
31
|
+
hasSupabaseAuth: false,
|
|
32
|
+
hasShadcn: false,
|
|
33
|
+
hasTailwind: false,
|
|
34
|
+
hasChakra: false,
|
|
35
|
+
installedComponents: [],
|
|
36
|
+
hasStripe: false,
|
|
37
|
+
hasLemonSqueezy: false,
|
|
38
|
+
};
|
|
39
|
+
// 1. Check package.json
|
|
40
|
+
const pkgPath = path_1.default.join(targetDir, 'package.json');
|
|
41
|
+
if (await fs_extra_1.default.pathExists(pkgPath)) {
|
|
42
|
+
info.hasPackageJson = true;
|
|
43
|
+
const pkg = await fs_extra_1.default.readJson(pkgPath);
|
|
44
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
45
|
+
// Package Manager detection
|
|
46
|
+
if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pnpm-lock.yaml'))) {
|
|
47
|
+
info.packageManager = 'pnpm';
|
|
48
|
+
}
|
|
49
|
+
else if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'yarn.lock'))) {
|
|
50
|
+
info.packageManager = 'yarn';
|
|
51
|
+
}
|
|
52
|
+
else if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'bun.lockb'))) {
|
|
53
|
+
info.packageManager = 'bun';
|
|
54
|
+
}
|
|
55
|
+
else if (await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'package-lock.json'))) {
|
|
56
|
+
info.packageManager = 'npm';
|
|
57
|
+
}
|
|
58
|
+
// Framework
|
|
59
|
+
info.nextVersion = allDeps['next'] || null;
|
|
60
|
+
// Auth systems
|
|
61
|
+
info.hasNextAuth = !!allDeps['next-auth'];
|
|
62
|
+
info.hasClerk = !!allDeps['@clerk/nextjs'];
|
|
63
|
+
info.hasSupabaseAuth = !!allDeps['@supabase/auth-helpers-nextjs'];
|
|
64
|
+
// UI frameworks
|
|
65
|
+
info.hasTailwind = !!allDeps['tailwindcss'];
|
|
66
|
+
info.hasShadcn =
|
|
67
|
+
!!allDeps['@radix-ui/react-dialog'] || !!allDeps['class-variance-authority'];
|
|
68
|
+
info.hasChakra = !!allDeps['@chakra-ui/react'];
|
|
69
|
+
// Billing
|
|
70
|
+
info.hasStripe = !!allDeps['stripe'];
|
|
71
|
+
info.hasLemonSqueezy = !!allDeps['@lemonsqueezy/lemonsqueezy.js'];
|
|
72
|
+
}
|
|
73
|
+
// 2. Check directory structure for routing
|
|
74
|
+
info.hasAppRouter = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'app'));
|
|
75
|
+
info.hasPagesRouter = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pages'));
|
|
76
|
+
// 3. Check Prisma configuration
|
|
77
|
+
const schemaPath = path_1.default.join(targetDir, 'prisma', 'schema.prisma');
|
|
78
|
+
if (await fs_extra_1.default.pathExists(schemaPath)) {
|
|
79
|
+
info.hasPrisma = true;
|
|
80
|
+
const schema = await fs_extra_1.default.readFile(schemaPath, 'utf-8');
|
|
81
|
+
// Detect database provider
|
|
82
|
+
const providerMatch = schema.match(/provider\s*=\s*"(postgresql|mysql|sqlite)"/);
|
|
83
|
+
if (providerMatch) {
|
|
84
|
+
info.prismaProvider = providerMatch[1];
|
|
85
|
+
}
|
|
86
|
+
// Extract all model names
|
|
87
|
+
const modelMatches = schema.matchAll(/^model\s+(\w+)\s*\{/gm);
|
|
88
|
+
for (const match of modelMatches) {
|
|
89
|
+
info.prismaModels.push(match[1]);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// 4. Check installed ChimerAI components
|
|
93
|
+
// Map component names to key files that indicate their presence
|
|
94
|
+
const componentChecks = {
|
|
95
|
+
'auth': ['lib/auth.ts', 'app/api/auth/[...nextauth]/route.ts'],
|
|
96
|
+
'billing': ['lib/stripe.ts', 'app/billing/page.tsx'],
|
|
97
|
+
'chat-ui': ['app/chat/page.tsx', 'components/StreamingChat.tsx'],
|
|
98
|
+
'rbac': ['app/admin/users/page.tsx', 'lib/permissions.ts'],
|
|
99
|
+
'mfa': ['app/api/auth/mfa/setup/route.ts'],
|
|
100
|
+
'gdpr': ['app/api/gdpr/consent/route.ts'],
|
|
101
|
+
'webhooks': ['app/api/webhooks/route.ts'],
|
|
102
|
+
'audit-log': ['lib/audit-log.ts'],
|
|
103
|
+
'analytics': ['lib/analytics.ts'],
|
|
104
|
+
'admin': ['app/admin/page.tsx'],
|
|
105
|
+
};
|
|
106
|
+
for (const [name, files] of Object.entries(componentChecks)) {
|
|
107
|
+
const hasAny = await Promise.all(files.map((f) => fs_extra_1.default.pathExists(path_1.default.join(targetDir, f))));
|
|
108
|
+
if (hasAny.some(Boolean)) {
|
|
109
|
+
info.installedComponents.push(name);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return info;
|
|
113
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Manager - PHASE 3.2
|
|
3
|
+
* Manages Prisma schema extensions without overwriting existing configurations
|
|
4
|
+
* Prevents duplicate models and intelligently merges schema changes
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Extend Prisma schema with new models/enums without overwriting existing ones
|
|
8
|
+
* @param schemaPath - Path to prisma/schema.prisma
|
|
9
|
+
* @param newModels - Prisma model definitions to add
|
|
10
|
+
* @param newEnums - Optional Prisma enum definitions to add
|
|
11
|
+
*/
|
|
12
|
+
export declare function extendPrismaSchema(schemaPath: string, newModels: string, newEnums?: string): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Get all model names from a Prisma schema
|
|
15
|
+
* @param schemaPath - Path to prisma/schema.prisma
|
|
16
|
+
* @returns Array of model names
|
|
17
|
+
*/
|
|
18
|
+
export declare function getPrismaModels(schemaPath: string): Promise<string[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a specific model exists in schema
|
|
21
|
+
* @param schemaPath - Path to prisma/schema.prisma
|
|
22
|
+
* @param modelName - Model name to check
|
|
23
|
+
* @returns true if model exists
|
|
24
|
+
*/
|
|
25
|
+
export declare function modelExists(schemaPath: string, modelName: string): Promise<boolean>;
|
|
26
|
+
//# sourceMappingURL=schema-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-manager.d.ts","sourceRoot":"","sources":["../src/schema-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA+Ff;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ3E;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGzF"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Schema Manager - PHASE 3.2
|
|
4
|
+
* Manages Prisma schema extensions without overwriting existing configurations
|
|
5
|
+
* Prevents duplicate models and intelligently merges schema changes
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.extendPrismaSchema = extendPrismaSchema;
|
|
12
|
+
exports.getPrismaModels = getPrismaModels;
|
|
13
|
+
exports.modelExists = modelExists;
|
|
14
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
15
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
16
|
+
/**
|
|
17
|
+
* Extend Prisma schema with new models/enums without overwriting existing ones
|
|
18
|
+
* @param schemaPath - Path to prisma/schema.prisma
|
|
19
|
+
* @param newModels - Prisma model definitions to add
|
|
20
|
+
* @param newEnums - Optional Prisma enum definitions to add
|
|
21
|
+
*/
|
|
22
|
+
async function extendPrismaSchema(schemaPath, newModels, newEnums) {
|
|
23
|
+
if (!(await fs_extra_1.default.pathExists(schemaPath))) {
|
|
24
|
+
throw new Error(`Prisma schema not found at ${schemaPath}`);
|
|
25
|
+
}
|
|
26
|
+
let schema = await fs_extra_1.default.readFile(schemaPath, 'utf-8');
|
|
27
|
+
// 1. Extract model names from both existing and new schemas
|
|
28
|
+
const existingModels = [...schema.matchAll(/^model\s+(\w+)\s*\{/gm)].map((m) => m[1]);
|
|
29
|
+
const newModelNames = [...newModels.matchAll(/^model\s+(\w+)\s*\{/gm)].map((m) => m[1]);
|
|
30
|
+
// 2. Check for duplicates
|
|
31
|
+
const duplicates = newModelNames.filter((m) => existingModels.includes(m));
|
|
32
|
+
let modelsToAdd = newModels;
|
|
33
|
+
if (duplicates.length > 0) {
|
|
34
|
+
console.log(chalk_1.default.yellow(`⚠️ Models already exist: ${duplicates.join(', ')} - skipping duplicates`));
|
|
35
|
+
// Remove duplicate models from the new schema
|
|
36
|
+
// Use brace-counting instead of regex to handle nested braces in @default("{}")
|
|
37
|
+
for (const dup of duplicates) {
|
|
38
|
+
const modelStart = modelsToAdd.search(new RegExp(`model\\s+${dup}\\s*\\{`));
|
|
39
|
+
if (modelStart === -1)
|
|
40
|
+
continue;
|
|
41
|
+
const braceStart = modelsToAdd.indexOf('{', modelStart);
|
|
42
|
+
let depth = 0;
|
|
43
|
+
let braceEnd = braceStart;
|
|
44
|
+
for (let i = braceStart; i < modelsToAdd.length; i++) {
|
|
45
|
+
if (modelsToAdd[i] === '{')
|
|
46
|
+
depth++;
|
|
47
|
+
if (modelsToAdd[i] === '}')
|
|
48
|
+
depth--;
|
|
49
|
+
if (depth === 0) {
|
|
50
|
+
braceEnd = i;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
modelsToAdd = (modelsToAdd.slice(0, modelStart) + modelsToAdd.slice(braceEnd + 1)).trim();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// 3. Extract existing enums
|
|
58
|
+
const existingEnums = [...schema.matchAll(/^enum\s+(\w+)\s*\{/gm)].map((m) => m[1]);
|
|
59
|
+
const newEnumNames = newEnums
|
|
60
|
+
? [...newEnums.matchAll(/^enum\s+(\w+)\s*\{/gm)].map((m) => m[1])
|
|
61
|
+
: [];
|
|
62
|
+
const duplicateEnums = newEnumNames.filter((e) => existingEnums.includes(e));
|
|
63
|
+
let enumsToAdd = newEnums || '';
|
|
64
|
+
if (duplicateEnums.length > 0) {
|
|
65
|
+
console.log(chalk_1.default.yellow(`⚠️ Enums already exist: ${duplicateEnums.join(', ')} - skipping duplicates`));
|
|
66
|
+
// Remove duplicate enums using brace-counting
|
|
67
|
+
for (const dup of duplicateEnums) {
|
|
68
|
+
const enumStart = enumsToAdd.search(new RegExp(`enum\\s+${dup}\\s*\\{`));
|
|
69
|
+
if (enumStart === -1)
|
|
70
|
+
continue;
|
|
71
|
+
const braceStart = enumsToAdd.indexOf('{', enumStart);
|
|
72
|
+
let depth = 0;
|
|
73
|
+
let braceEnd = braceStart;
|
|
74
|
+
for (let i = braceStart; i < enumsToAdd.length; i++) {
|
|
75
|
+
if (enumsToAdd[i] === '{')
|
|
76
|
+
depth++;
|
|
77
|
+
if (enumsToAdd[i] === '}')
|
|
78
|
+
depth--;
|
|
79
|
+
if (depth === 0) {
|
|
80
|
+
braceEnd = i;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
enumsToAdd = (enumsToAdd.slice(0, enumStart) + enumsToAdd.slice(braceEnd + 1)).trim();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// 4. Add enums at beginning (before models)
|
|
88
|
+
if (enumsToAdd.trim()) {
|
|
89
|
+
// Find where models start
|
|
90
|
+
const firstModelIndex = schema.search(/^model\s+/m);
|
|
91
|
+
if (firstModelIndex !== -1) {
|
|
92
|
+
schema =
|
|
93
|
+
schema.slice(0, firstModelIndex) +
|
|
94
|
+
'\n' +
|
|
95
|
+
enumsToAdd +
|
|
96
|
+
'\n\n' +
|
|
97
|
+
schema.slice(firstModelIndex);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
schema += '\n\n' + enumsToAdd;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// 5. Add models at end
|
|
104
|
+
if (modelsToAdd.trim()) {
|
|
105
|
+
schema += '\n\n// Added by chimerai\n' + modelsToAdd;
|
|
106
|
+
}
|
|
107
|
+
// 6. Write updated schema
|
|
108
|
+
await fs_extra_1.default.writeFile(schemaPath, schema.trim() + '\n');
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get all model names from a Prisma schema
|
|
112
|
+
* @param schemaPath - Path to prisma/schema.prisma
|
|
113
|
+
* @returns Array of model names
|
|
114
|
+
*/
|
|
115
|
+
async function getPrismaModels(schemaPath) {
|
|
116
|
+
if (!(await fs_extra_1.default.pathExists(schemaPath))) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
const schema = await fs_extra_1.default.readFile(schemaPath, 'utf-8');
|
|
120
|
+
const models = [...schema.matchAll(/^model\s+(\w+)\s*\{/gm)].map((m) => m[1]);
|
|
121
|
+
return models;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Check if a specific model exists in schema
|
|
125
|
+
* @param schemaPath - Path to prisma/schema.prisma
|
|
126
|
+
* @param modelName - Model name to check
|
|
127
|
+
* @returns true if model exists
|
|
128
|
+
*/
|
|
129
|
+
async function modelExists(schemaPath, modelName) {
|
|
130
|
+
const models = await getPrismaModels(schemaPath);
|
|
131
|
+
return models.includes(modelName);
|
|
132
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin panel component templates
|
|
3
|
+
* Generates admin dashboard, users management page, roles management page, and admin layout guard
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generates the admin layout with session check and admin role guard.
|
|
7
|
+
* Redirects unauthenticated users to sign-in, unauthorized users to dashboard.
|
|
8
|
+
* @returns TypeScript/JSX content for app/admin/layout.tsx
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateAdminLayout(): string;
|
|
11
|
+
/**
|
|
12
|
+
* Generates the main admin dashboard
|
|
13
|
+
* Shows cards linking to RBAC, AI configuration, and system management sections
|
|
14
|
+
* @returns TypeScript/JSX content for app/admin/page.tsx
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateAdminDashboardPage(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Generates the admin users management page
|
|
19
|
+
* Displays user list with search, create/edit/delete functionality
|
|
20
|
+
* @returns TypeScript/JSX content for app/admin/users/page.tsx
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateAdminUsersPage(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Generates the admin roles management page
|
|
25
|
+
* Allows CRUD operations on roles and permission assignment
|
|
26
|
+
* @returns TypeScript/JSX content for app/admin/roles/page.tsx
|
|
27
|
+
*/
|
|
28
|
+
export declare function generateAdminRolesPage(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Generates the admin settings page
|
|
31
|
+
* Functional page for system configuration with save/reset
|
|
32
|
+
* @returns TypeScript/JSX content for app/admin/settings/page.tsx
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateAdminSettingsPage(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Generates the admin activity logs page
|
|
37
|
+
* Full audit log table with filters for action, user, and date range
|
|
38
|
+
* @returns TypeScript/JSX content for app/admin/logs/page.tsx
|
|
39
|
+
*/
|
|
40
|
+
export declare function generateAdminLogsPage(): string;
|
|
41
|
+
/**
|
|
42
|
+
* Generates the audit log helper utility.
|
|
43
|
+
* Provides logAuditAction() for recording actions across the app.
|
|
44
|
+
* @returns TypeScript content for lib/audit.ts
|
|
45
|
+
*/
|
|
46
|
+
export declare function generatePermissionsLib(): string;
|
|
47
|
+
export declare function generateRequirePermissionLib(): string;
|
|
48
|
+
export declare function generateAuditLogHelper(): string;
|
|
49
|
+
//# sourceMappingURL=admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/templates/admin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA6G5C;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAmEnD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAuU/C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA+Q/C;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA4LlD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA6K9C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAgE/C;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CA+DrD;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAqC/C"}
|