@onroad/core 4.0.0-alpha.3 → 4.0.0-alpha.31

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 (67) hide show
  1. package/README.md +409 -7
  2. package/dist/OnRoadExpress.d.ts.map +1 -1
  3. package/dist/OnRoadExpress.js +18 -5
  4. package/dist/OnRoadExpress.js.map +1 -1
  5. package/dist/core/AbstractController.d.ts +10 -0
  6. package/dist/core/AbstractController.d.ts.map +1 -1
  7. package/dist/core/AbstractController.js +48 -1
  8. package/dist/core/AbstractController.js.map +1 -1
  9. package/dist/core/AbstractService.d.ts +5 -0
  10. package/dist/core/AbstractService.d.ts.map +1 -1
  11. package/dist/core/AbstractService.js +36 -0
  12. package/dist/core/AbstractService.js.map +1 -1
  13. package/dist/core/SequelizeRepository.d.ts +4 -1
  14. package/dist/core/SequelizeRepository.d.ts.map +1 -1
  15. package/dist/core/SequelizeRepository.js +22 -1
  16. package/dist/core/SequelizeRepository.js.map +1 -1
  17. package/dist/database/ConnectionManager.d.ts +2 -0
  18. package/dist/database/ConnectionManager.d.ts.map +1 -1
  19. package/dist/database/ConnectionManager.js +12 -1
  20. package/dist/database/ConnectionManager.js.map +1 -1
  21. package/dist/dev/DevServer.d.ts +67 -0
  22. package/dist/dev/DevServer.d.ts.map +1 -0
  23. package/dist/dev/DevServer.js +496 -0
  24. package/dist/dev/DevServer.js.map +1 -0
  25. package/dist/dev/DevToolsController.d.ts +45 -0
  26. package/dist/dev/DevToolsController.d.ts.map +1 -0
  27. package/dist/dev/DevToolsController.js +426 -0
  28. package/dist/dev/DevToolsController.js.map +1 -0
  29. package/dist/dev/DevToolsPlugin.d.ts +10 -0
  30. package/dist/dev/DevToolsPlugin.d.ts.map +1 -0
  31. package/dist/dev/DevToolsPlugin.js +23 -0
  32. package/dist/dev/DevToolsPlugin.js.map +1 -0
  33. package/dist/dev/MigrationCLI.d.ts +19 -0
  34. package/dist/dev/MigrationCLI.d.ts.map +1 -0
  35. package/dist/dev/MigrationCLI.js +140 -0
  36. package/dist/dev/MigrationCLI.js.map +1 -0
  37. package/dist/dev/index.d.ts +8 -0
  38. package/dist/dev/index.d.ts.map +1 -0
  39. package/dist/dev/index.js +5 -0
  40. package/dist/dev/index.js.map +1 -0
  41. package/dist/entity/EntityRegistry.d.ts +26 -0
  42. package/dist/entity/EntityRegistry.d.ts.map +1 -1
  43. package/dist/entity/EntityRegistry.js +140 -4
  44. package/dist/entity/EntityRegistry.js.map +1 -1
  45. package/dist/entity/decorators.d.ts +1 -0
  46. package/dist/entity/decorators.d.ts.map +1 -1
  47. package/dist/entity/decorators.js.map +1 -1
  48. package/dist/filters/builtins/JwtFilter.d.ts +6 -3
  49. package/dist/filters/builtins/JwtFilter.d.ts.map +1 -1
  50. package/dist/filters/builtins/JwtFilter.js +29 -4
  51. package/dist/filters/builtins/JwtFilter.js.map +1 -1
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +2 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/storage/GCSStorageProvider.d.ts +15 -0
  57. package/dist/storage/GCSStorageProvider.d.ts.map +1 -0
  58. package/dist/storage/GCSStorageProvider.js +58 -0
  59. package/dist/storage/GCSStorageProvider.js.map +1 -0
  60. package/dist/storage/StorageProvider.d.ts +28 -0
  61. package/dist/storage/StorageProvider.d.ts.map +1 -1
  62. package/dist/storage/StorageProvider.js.map +1 -1
  63. package/dist/storage/index.d.ts +2 -1
  64. package/dist/storage/index.d.ts.map +1 -1
  65. package/dist/storage/index.js +1 -0
  66. package/dist/storage/index.js.map +1 -1
  67. package/package.json +11 -1
@@ -0,0 +1,426 @@
1
+ import { exec } from "child_process";
2
+ import { promisify } from "util";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ const execAsync = promisify(exec);
6
+ /**
7
+ * Standalone route-handler class for the dev console.
8
+ * Routes are mounted directly by DevToolsPlugin (not via the DI container).
9
+ */
10
+ export class DevToolsController {
11
+ config;
12
+ currentRestore = {
13
+ status: "idle",
14
+ step: "",
15
+ };
16
+ constructor(config) {
17
+ this.config = config;
18
+ }
19
+ // --- Route handlers (arrow fns to preserve `this`) ---
20
+ checkGcloudAuth = async (_req, res) => {
21
+ try {
22
+ await execAsync("gcloud auth print-access-token", { timeout: 10_000 });
23
+ const { stdout } = await execAsync("gcloud config get-value account", {
24
+ timeout: 5_000,
25
+ });
26
+ res.json({ authenticated: true, account: stdout.trim() });
27
+ }
28
+ catch {
29
+ res.json({ authenticated: false, account: null });
30
+ }
31
+ };
32
+ listDatabases = async (_req, res) => {
33
+ const { projectId, instanceId, serviceName } = this.config;
34
+ try {
35
+ const { stdout } = await execAsync("gcloud sql databases list --instance=" +
36
+ instanceId +
37
+ " --project=" +
38
+ projectId +
39
+ ' --format="json"', { timeout: 30_000 });
40
+ const allDbs = JSON.parse(stdout)
41
+ .map((d) => d.name)
42
+ .filter((n) => !["postgres", "template0", "template1", "cloudsqladmin"].includes(n));
43
+ // Extract tenant databases matching _{serviceName} suffix
44
+ const suffix = "_" + serviceName;
45
+ const tenantDbs = allDbs
46
+ .filter((name) => name.endsWith(suffix))
47
+ .map((name) => ({
48
+ database: name,
49
+ tenant: name.slice(0, name.length - suffix.length),
50
+ }))
51
+ .sort((a, b) => a.tenant.localeCompare(b.tenant));
52
+ // Include any remaining databases as "other"
53
+ const matched = new Set(tenantDbs.map((t) => t.database));
54
+ const otherDbs = allDbs.filter((n) => !matched.has(n));
55
+ res.json({ success: true, serviceName, tenantDbs, otherDbs });
56
+ }
57
+ catch (error) {
58
+ res.status(500).json({ success: false, error: error.message });
59
+ }
60
+ };
61
+ exportAndRestore = async (req, res) => {
62
+ const { database, tenant, dropExisting } = req.body;
63
+ if (!database) {
64
+ res.status(400).json({ success: false, error: "Selecione um tenant/banco." });
65
+ return;
66
+ }
67
+ if (this.currentRestore.status === "running") {
68
+ res
69
+ .status(409)
70
+ .json({ success: false, error: "Já existe um restore em andamento." });
71
+ return;
72
+ }
73
+ this.currentRestore = {
74
+ status: "running",
75
+ step: "Iniciando...",
76
+ tenant: tenant || database,
77
+ };
78
+ res.json({ success: true, message: "Restore iniciado.", database, tenant });
79
+ this.runRestore(database, !!dropExisting).catch((err) => {
80
+ this.currentRestore = {
81
+ status: "error",
82
+ step: "Falhou",
83
+ error: err.message,
84
+ tenant: tenant || database,
85
+ };
86
+ });
87
+ };
88
+ restoreStatus = async (_req, res) => {
89
+ res.json(this.currentRestore);
90
+ };
91
+ downloadLocalBackup = async (_req, res) => {
92
+ const { localDb } = this.config;
93
+ const ts = new Date().toISOString().replace(/[:.]/g, "-");
94
+ const filename = "local_backup_" + localDb.database + "_" + ts + ".sql";
95
+ const filePath = path.join("/tmp", filename);
96
+ try {
97
+ const cmd = 'PGPASSWORD="' +
98
+ localDb.password +
99
+ '" pg_dump -h ' +
100
+ localDb.host +
101
+ " -p " +
102
+ localDb.port +
103
+ " -U " +
104
+ localDb.user +
105
+ " -d " +
106
+ localDb.database +
107
+ " -F p > " +
108
+ filePath;
109
+ await execAsync(cmd, { timeout: 120_000 });
110
+ res.download(filePath, filename, () => {
111
+ if (fs.existsSync(filePath))
112
+ fs.unlinkSync(filePath);
113
+ });
114
+ }
115
+ catch (error) {
116
+ res.status(500).json({ success: false, error: error.message });
117
+ }
118
+ };
119
+ renderDashboard = async (_req, res) => {
120
+ res.send(this.buildHTML());
121
+ };
122
+ // --- Background restore pipeline ---
123
+ async runRestore(sourceDb, dropExisting) {
124
+ const { projectId, instanceId, bucketName, localDb } = this.config;
125
+ const tempFileName = "restore_" + sourceDb + "_" + Date.now() + ".sql";
126
+ const gcsPath = "gs://" + bucketName + "/" + tempFileName;
127
+ const localPath = path.join("/tmp", tempFileName);
128
+ try {
129
+ // 1 — Export from Cloud SQL to GCS
130
+ this.currentRestore.step = "Exportando " + sourceDb + " do Cloud SQL...";
131
+ await execAsync("gcloud sql export sql " +
132
+ instanceId +
133
+ " " +
134
+ gcsPath +
135
+ " --database=" +
136
+ sourceDb +
137
+ " --project=" +
138
+ projectId +
139
+ " --quiet", { timeout: 600_000 });
140
+ // 2 — Download from GCS
141
+ this.currentRestore.step = "Baixando dump do GCS...";
142
+ await execAsync("gcloud storage cp " + gcsPath + " " + localPath, {
143
+ timeout: 300_000,
144
+ });
145
+ // 3 — Cleanup GCS (fire-and-forget)
146
+ execAsync("gcloud storage rm " + gcsPath).catch(() => { });
147
+ // 4 — Drop + recreate local DB using pg Node.js client (avoids psql binary issues)
148
+ if (dropExisting) {
149
+ this.currentRestore.step = "Recriando banco local...";
150
+ const { default: pg } = await import("pg");
151
+ const pgClient = new pg.Client({
152
+ host: localDb.host,
153
+ port: localDb.port,
154
+ user: localDb.user,
155
+ password: localDb.password,
156
+ database: "postgres",
157
+ ssl: false,
158
+ });
159
+ try {
160
+ await pgClient.connect();
161
+ await pgClient.query("DROP DATABASE IF EXISTS \"" + localDb.database + "\" WITH (FORCE)");
162
+ await pgClient.query("CREATE DATABASE \"" + localDb.database + "\" WITH OWNER \"" + localDb.user + "\"");
163
+ }
164
+ finally {
165
+ await pgClient.end();
166
+ }
167
+ }
168
+ // 5 — Restore SQL dump
169
+ // Use docker exec if containerName is configured (avoids host psql issues),
170
+ // otherwise fall back to host psql
171
+ this.currentRestore.step = "Restaurando dump no banco local...";
172
+ if (localDb.containerName) {
173
+ const containerSqlPath = "/tmp/" + tempFileName;
174
+ await execAsync("docker cp " + localPath + " " + localDb.containerName + ":" + containerSqlPath, { timeout: 30_000 });
175
+ await execAsync("docker exec " +
176
+ localDb.containerName +
177
+ " psql -U " +
178
+ localDb.user +
179
+ " -d " +
180
+ localDb.database +
181
+ " -f " +
182
+ containerSqlPath, { timeout: 600_000 });
183
+ execAsync("docker exec " + localDb.containerName + " rm -f " + containerSqlPath).catch(() => { });
184
+ }
185
+ else {
186
+ await execAsync('PGPASSWORD="' +
187
+ localDb.password +
188
+ '" psql -h ' +
189
+ localDb.host +
190
+ " -p " +
191
+ localDb.port +
192
+ " -U " +
193
+ localDb.user +
194
+ " -d " +
195
+ localDb.database +
196
+ " -f " +
197
+ localPath, { timeout: 600_000 });
198
+ }
199
+ // 6 — Run migrations
200
+ if (this.config.onAfterRestore) {
201
+ this.currentRestore.step = "Rodando migrations...";
202
+ await this.config.onAfterRestore();
203
+ }
204
+ // Mark done and schedule process restart so Sequelize reconnects to fresh DB
205
+ this.currentRestore = {
206
+ ...this.currentRestore,
207
+ status: "done",
208
+ step: "Restore completo! Reiniciando servidor...",
209
+ };
210
+ setTimeout(() => process.exit(0), 2000);
211
+ }
212
+ catch (error) {
213
+ this.currentRestore = {
214
+ ...this.currentRestore,
215
+ status: "error",
216
+ step: "Falhou",
217
+ error: error.message,
218
+ };
219
+ }
220
+ finally {
221
+ if (fs.existsSync(localPath))
222
+ fs.unlinkSync(localPath);
223
+ }
224
+ }
225
+ // --- Dashboard HTML (string concat to avoid template-literal nesting) ---
226
+ buildHTML() {
227
+ var cfg = this.config;
228
+ var css = "* { box-sizing: border-box; margin: 0; padding: 0; }" +
229
+ 'body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; padding: 20px; background: #0f172a; color: #e2e8f0; min-height: 100vh; }' +
230
+ ".container { max-width: 720px; margin: 0 auto; }" +
231
+ "h1 { font-size: 24px; margin-bottom: 4px; color: #38bdf8; }" +
232
+ ".subtitle { color: #94a3b8; margin-bottom: 24px; font-size: 13px; }" +
233
+ ".card { background: #1e293b; border: 1px solid #334155; border-radius: 10px; padding: 20px; margin-bottom: 16px; }" +
234
+ ".card h2 { font-size: 15px; color: #94a3b8; margin-bottom: 12px; text-transform: uppercase; letter-spacing: 0.5px; }" +
235
+ ".badge { display: inline-block; padding: 3px 10px; border-radius: 9999px; font-size: 12px; font-weight: 600; }" +
236
+ ".badge-ok { background: #065f46; color: #34d399; }" +
237
+ ".badge-err { background: #7f1d1d; color: #fca5a5; }" +
238
+ ".badge-warn { background: #78350f; color: #fbbf24; }" +
239
+ ".info-grid { display: grid; grid-template-columns: 120px 1fr; gap: 6px 12px; font-size: 13px; margin: 12px 0; }" +
240
+ ".info-grid dt { color: #64748b; }" +
241
+ '.info-grid dd { color: #cbd5e1; font-family: "SF Mono", Monaco, monospace; }' +
242
+ ".btn { border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 600; transition: all 0.15s; }" +
243
+ ".btn:disabled { opacity: 0.5; cursor: not-allowed; }" +
244
+ ".btn-primary { background: #2563eb; color: white; }" +
245
+ ".btn-primary:hover:not(:disabled) { background: #1d4ed8; }" +
246
+ ".btn-outline { background: transparent; border: 1px solid #475569; color: #cbd5e1; }" +
247
+ ".btn-outline:hover:not(:disabled) { background: #334155; }" +
248
+ ".btn-sm { padding: 6px 14px; font-size: 12px; }" +
249
+ ".tenant-list { list-style: none; margin: 0; padding: 0; }" +
250
+ ".tenant-item { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; " +
251
+ "background: #0f172a; border: 1px solid #334155; border-radius: 8px; margin-bottom: 8px; cursor: pointer; transition: all 0.15s; }" +
252
+ ".tenant-item:hover { border-color: #2563eb; background: #1a2744; }" +
253
+ ".tenant-item.selected { border-color: #2563eb; background: #1e3a5f; box-shadow: 0 0 0 1px #2563eb; }" +
254
+ ".tenant-name { font-size: 15px; font-weight: 600; color: #e2e8f0; }" +
255
+ ".tenant-db { font-size: 12px; color: #64748b; font-family: 'SF Mono', Monaco, monospace; margin-top: 2px; }" +
256
+ ".tenant-check { width: 20px; height: 20px; border-radius: 50%; border: 2px solid #475569; " +
257
+ "display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: all 0.15s; }" +
258
+ ".tenant-item.selected .tenant-check { border-color: #2563eb; background: #2563eb; }" +
259
+ ".tenant-item.selected .tenant-check::after { content: ''; display: block; width: 6px; height: 6px; " +
260
+ "background: white; border-radius: 50%; }" +
261
+ ".loading-tenants { text-align: center; padding: 20px; color: #64748b; font-size: 13px; }" +
262
+ ".selected-tenant-banner { display: none; padding: 10px 16px; background: #1e3a5f; border: 1px solid #2563eb; " +
263
+ "border-radius: 8px; margin-bottom: 12px; font-size: 13px; color: #93c5fd; }" +
264
+ ".selected-tenant-banner.active { display: flex; align-items: center; gap: 8px; }" +
265
+ ".selected-tenant-banner strong { color: #e2e8f0; }" +
266
+ ".progress { margin-top: 16px; padding: 14px; background: #0f172a; border-radius: 8px; border: 1px solid #334155; display: none; }" +
267
+ ".progress.active { display: block; }" +
268
+ ".progress .step { color: #38bdf8; font-weight: 600; font-size: 13px; }" +
269
+ ".progress .substep { color: #64748b; font-size: 12px; margin-top: 4px; }" +
270
+ ".progress-bar { height: 4px; background: #334155; border-radius: 2px; margin-top: 10px; overflow: hidden; }" +
271
+ ".progress-bar-fill { height: 100%; background: #2563eb; border-radius: 2px; transition: width 0.5s; }" +
272
+ ".actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 12px; }" +
273
+ ".checkbox-label { font-size: 13px; color: #94a3b8; display: flex; align-items: center; gap: 6px; cursor: pointer; }" +
274
+ ".row { display: flex; gap: 8px; align-items: center; }" +
275
+ ".separator { border-top: 1px solid #334155; margin: 16px 0; }" +
276
+ ".empty-msg { color: #64748b; font-size: 13px; text-align: center; padding: 16px; }" +
277
+ ".section-label { font-size: 12px; color: #64748b; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }";
278
+ var body = '<div class="container">' +
279
+ "<h1>OnRoad Dev Console</h1>" +
280
+ '<p class="subtitle">' + cfg.serviceName + ' — Restaurar banco de produção para desenvolver localmente</p>' +
281
+ // Auth card
282
+ '<div class="card"><h2>Cloud SDK</h2>' +
283
+ '<div class="row">' +
284
+ '<span id="auth-badge" class="badge badge-warn">verificando...</span>' +
285
+ '<span id="auth-account" style="font-size:13px; color:#94a3b8;"></span>' +
286
+ "</div></div>" +
287
+ // Local DB card
288
+ '<div class="card"><h2>Banco Local</h2>' +
289
+ '<dl class="info-grid">' +
290
+ "<dt>Host</dt><dd>" + cfg.localDb.host + ":" + cfg.localDb.port + "</dd>" +
291
+ "<dt>Database</dt><dd>" + cfg.localDb.database + "</dd>" +
292
+ "<dt>User</dt><dd>" + cfg.localDb.user + "</dd>" +
293
+ "</dl>" +
294
+ '<a href="/dev/db/backup/local" class="btn btn-outline btn-sm">Exportar SQL Local</a>' +
295
+ "</div>" +
296
+ // Tenant selection card
297
+ '<div class="card"><h2>Selecionar Tenant</h2>' +
298
+ '<p style="font-size:13px; color:#64748b; margin-bottom:12px;">' +
299
+ 'Instância <strong style="color:#cbd5e1;">' + cfg.instanceId + "</strong> " +
300
+ '— serviço <strong style="color:#38bdf8;">' + cfg.serviceName + "</strong></p>" +
301
+ '<div id="tenant-loading" class="loading-tenants">Carregando tenants...</div>' +
302
+ '<ul class="tenant-list" id="tenant-list"></ul>' +
303
+ '<div id="tenant-empty" class="empty-msg" style="display:none;">Nenhum banco encontrado para o serviço "' + cfg.serviceName + '"</div>' +
304
+ '<button onclick="loadTenants()" class="btn btn-outline btn-sm" style="margin-top:8px;" id="btn-refresh">Atualizar lista</button>' +
305
+ "</div>" +
306
+ // Restore card
307
+ '<div class="card"><h2>Restaurar</h2>' +
308
+ '<div id="selected-banner" class="selected-tenant-banner">' +
309
+ 'Tenant selecionado: <strong id="banner-tenant"></strong> ' +
310
+ '— banco: <strong id="banner-db"></strong>' +
311
+ "</div>" +
312
+ '<div id="no-selection" style="font-size:13px; color:#64748b;">Selecione um tenant acima para restaurar.</div>' +
313
+ '<div class="actions">' +
314
+ '<label class="checkbox-label"><input type="checkbox" id="drop-check" checked> Limpar banco local antes de restaurar</label>' +
315
+ "</div>" +
316
+ '<div class="actions">' +
317
+ '<button onclick="startRestore()" class="btn btn-primary" id="btn-restore" disabled>Restaurar Agora</button>' +
318
+ "</div>" +
319
+ '<div class="progress" id="progress">' +
320
+ '<div class="step" id="progress-step">Preparando...</div>' +
321
+ '<div class="substep" id="progress-substep"></div>' +
322
+ '<div class="progress-bar"><div class="progress-bar-fill" id="progress-fill" style="width:0%"></div></div>' +
323
+ "</div></div>" +
324
+ "</div>";
325
+ var js = "var selectedTenant=null;var selectedDb=null;" +
326
+ "function showAuthCmd(el){" +
327
+ "var cmd='gcloud auth login';" +
328
+ "var code=document.createElement('code');" +
329
+ "code.textContent=cmd;" +
330
+ "code.style.cssText='cursor:pointer;background:#334155;padding:2px 8px;border-radius:4px;font-size:12px;color:#38bdf8;margin-left:4px';" +
331
+ "code.title='Clique para copiar';" +
332
+ "code.onclick=function(){navigator.clipboard.writeText(cmd);code.style.color='#34d399';code.textContent='copiado!';setTimeout(function(){code.style.color='#38bdf8';code.textContent=cmd;},1500);};" +
333
+ "el.textContent='Execute: ';el.appendChild(code);}" +
334
+ // Auth check
335
+ "async function checkAuth(){" +
336
+ 'var b=document.getElementById("auth-badge"),a=document.getElementById("auth-account");' +
337
+ 'try{var r=await fetch("/dev/db/auth/status");var d=await r.json();' +
338
+ 'if(d.authenticated){b.className="badge badge-ok";b.textContent="autenticado";a.textContent=d.account;loadTenants();}' +
339
+ 'else{b.className="badge badge-err";b.textContent="não autenticado";showAuthCmd(a);' +
340
+ 'document.getElementById("tenant-loading").textContent="Autentique no gcloud primeiro.";}}' +
341
+ 'catch(e){b.className="badge badge-err";b.textContent="erro";}}' +
342
+ "checkAuth();" +
343
+ // Load tenants
344
+ "async function loadTenants(){" +
345
+ 'var list=document.getElementById("tenant-list");' +
346
+ 'var loading=document.getElementById("tenant-loading");' +
347
+ 'var empty=document.getElementById("tenant-empty");' +
348
+ "loading.style.display='block';list.innerHTML='';empty.style.display='none';" +
349
+ 'try{var r=await fetch("/dev/db/databases");var d=await r.json();' +
350
+ "loading.style.display='none';" +
351
+ "if(!d.success){list.innerHTML='<li class=\"empty-msg\">Erro: '+d.error+'</li>';return;}" +
352
+ "if(d.tenantDbs.length===0){empty.style.display='block';return;}" +
353
+ "d.tenantDbs.forEach(function(t){" +
354
+ "var li=document.createElement('li');" +
355
+ "li.className='tenant-item';" +
356
+ "if(selectedDb===t.database)li.className+=' selected';" +
357
+ "li.onclick=function(){selectTenant(t.tenant,t.database);};" +
358
+ "li.innerHTML='<div><div class=\"tenant-name\">'+t.tenant+'</div>" +
359
+ "<div class=\"tenant-db\">'+t.database+'</div></div>" +
360
+ "<div class=\"tenant-check\"></div>';" +
361
+ "list.appendChild(li);});" +
362
+ // Other databases
363
+ "if(d.otherDbs&&d.otherDbs.length>0){" +
364
+ "var sep=document.createElement('li');" +
365
+ "sep.className='section-label';sep.style.marginTop='12px';" +
366
+ "sep.textContent='Outros bancos (sem tenant)';list.appendChild(sep);" +
367
+ "d.otherDbs.forEach(function(db){" +
368
+ "var li=document.createElement('li');li.className='tenant-item';" +
369
+ "if(selectedDb===db)li.className+=' selected';" +
370
+ "li.onclick=function(){selectTenant(db,db);};" +
371
+ "li.innerHTML='<div><div class=\"tenant-name\">'+db+'</div>" +
372
+ "<div class=\"tenant-db\">banco avulso</div></div>" +
373
+ "<div class=\"tenant-check\"></div>';" +
374
+ "list.appendChild(li);});}" +
375
+ '}catch(e){loading.style.display="none";list.innerHTML="<li class=\'empty-msg\'>Erro: "+e.message+"</li>";}}' +
376
+ // Select tenant
377
+ "function selectTenant(tenant,db){" +
378
+ "selectedTenant=tenant;selectedDb=db;" +
379
+ "document.querySelectorAll('.tenant-item').forEach(function(el){el.classList.remove('selected');});" +
380
+ "event.currentTarget.classList.add('selected');" +
381
+ 'var banner=document.getElementById("selected-banner");' +
382
+ 'var noSel=document.getElementById("no-selection");' +
383
+ 'document.getElementById("banner-tenant").textContent=tenant;' +
384
+ 'document.getElementById("banner-db").textContent=db;' +
385
+ "banner.classList.add('active');noSel.style.display='none';" +
386
+ 'document.getElementById("btn-restore").disabled=false;}' +
387
+ // Restore
388
+ "var pollId=null;" +
389
+ "async function startRestore(){" +
390
+ "if(!selectedDb){alert('Selecione um tenant primeiro.');return;}" +
391
+ 'var drop=document.getElementById("drop-check").checked;' +
392
+ 'var btn=document.getElementById("btn-restore");' +
393
+ "if(!confirm('Restaurar tenant \"'+selectedTenant+'\" ('+selectedDb+') para o banco local?'+(drop?' O banco local será APAGADO primeiro.':'')))return;" +
394
+ 'btn.disabled=true;document.getElementById("progress").classList.add("active");' +
395
+ 'document.getElementById("progress-fill").style.width="5%";' +
396
+ 'document.getElementById("progress-fill").style.background="#2563eb";' +
397
+ 'document.getElementById("progress-step").style.color="#38bdf8";' +
398
+ 'document.getElementById("progress-substep").textContent="Tenant: "+selectedTenant;' +
399
+ 'try{var r=await fetch("/dev/db/restore",{method:"POST",headers:{"Content-Type":"application/json"},' +
400
+ "body:JSON.stringify({database:selectedDb,tenant:selectedTenant,dropExisting:drop})});var d=await r.json();" +
401
+ 'if(!d.success){alert("Erro: "+d.error);btn.disabled=false;return;}' +
402
+ "pollId=setInterval(pollStatus,2000);" +
403
+ '}catch(e){alert("Falha: "+e.message);btn.disabled=false;}}' +
404
+ // Poll status
405
+ "async function pollStatus(){" +
406
+ 'try{var r=await fetch("/dev/db/restore/status");var d=await r.json();' +
407
+ 'var s=document.getElementById("progress-step");var sub=document.getElementById("progress-substep");' +
408
+ 'var fill=document.getElementById("progress-fill");var btn=document.getElementById("btn-restore");' +
409
+ "s.textContent=d.step;" +
410
+ "if(d.tenant){sub.textContent='Tenant: '+d.tenant;}" +
411
+ 'if(d.status==="running"){var m={"Exportando":20,"Baixando":40,"Recriando":55,"Restaurando":70,"Rodando":90};' +
412
+ "var pct=10;for(var k in m){if(d.step.indexOf(k)>=0)pct=m[k];}fill.style.width=pct+'%';}" +
413
+ 'else if(d.status==="done"){fill.style.width="100%";fill.style.background="#22c55e";' +
414
+ 's.style.color="#22c55e";sub.textContent="Tenant "+d.tenant+" restaurado com sucesso!";clearInterval(pollId);btn.disabled=false;}' +
415
+ 'else if(d.status==="error"){fill.style.width="100%";fill.style.background="#ef4444";' +
416
+ 's.style.color="#ef4444";sub.textContent=d.error||"Erro desconhecido";clearInterval(pollId);btn.disabled=false;}' +
417
+ "}catch(e){}}";
418
+ return ('<!DOCTYPE html><html lang="pt-br"><head><meta charset="UTF-8">' +
419
+ "<title>OnRoad Dev Console — " + cfg.serviceName + "</title>" +
420
+ '<meta name="viewport" content="width=device-width, initial-scale=1">' +
421
+ "<style>" + css + "</style></head>" +
422
+ "<body>" + body +
423
+ "<script>" + js + "</script></body></html>");
424
+ }
425
+ }
426
+ //# sourceMappingURL=DevToolsController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevToolsController.js","sourceRoot":"","sources":["../../src/dev/DevToolsController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { OnRoadExpress } from "../OnRoadExpress.js";
2
+ import type { OnRoadPlugin } from "../plugins/OnRoadPlugin.js";
3
+ import type { DevToolsConfig } from "./DevToolsController.js";
4
+ export declare class DevToolsPlugin implements OnRoadPlugin {
5
+ name: string;
6
+ private config;
7
+ constructor(config: DevToolsConfig);
8
+ install(app: OnRoadExpress): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=DevToolsPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevToolsPlugin.d.ts","sourceRoot":"","sources":["../../src/dev/DevToolsPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAE7D,qBAAa,cAAe,YAAW,YAAY;IACjD,IAAI,SAAmB;IAEvB,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,cAAc;IAI5B,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBjD"}
@@ -0,0 +1,23 @@
1
+ import { DevToolsController } from "./DevToolsController.js";
2
+ export class DevToolsPlugin {
3
+ name = "DevToolsPlugin";
4
+ config;
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ async install(app) {
9
+ if (process.env.NODE_ENV === "production" && !process.env.FORCE_DEV_TOOLS) {
10
+ return;
11
+ }
12
+ const ctrl = new DevToolsController(this.config);
13
+ const express = app.app;
14
+ express.get("/dev/db/dashboard", ctrl.renderDashboard);
15
+ express.get("/dev/db/auth/status", ctrl.checkGcloudAuth);
16
+ express.get("/dev/db/databases", ctrl.listDatabases);
17
+ express.get("/dev/db/backup/local", ctrl.downloadLocalBackup);
18
+ express.post("/dev/db/restore", ctrl.exportAndRestore);
19
+ express.get("/dev/db/restore/status", ctrl.restoreStatus);
20
+ app.logger.info("[DevToolsPlugin] Dev console available at /dev/db/dashboard");
21
+ }
22
+ }
23
+ //# sourceMappingURL=DevToolsPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevToolsPlugin.js","sourceRoot":"","sources":["../../src/dev/DevToolsPlugin.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAG5D,MAAM,OAAO,cAAc;IACzB,IAAI,GAAG,gBAAgB,CAAA;IAEf,MAAM,CAAgB;IAE9B,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAkB;QAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;YAC1E,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAChD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAA;QAEvB,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;QACtD,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;QACpD,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAA;QAC7D,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACtD,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;QAEzD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAA;IAChF,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import type { SequelizeConnectionManager } from "../database/SequelizeConnectionManager.js";
2
+ export interface MigrationCLIConfig {
3
+ migrationsPath: string;
4
+ connection: SequelizeConnectionManager;
5
+ tenant?: string;
6
+ }
7
+ export declare class MigrationCLI {
8
+ private readonly migrationsPath;
9
+ private readonly connection;
10
+ private readonly tenant;
11
+ constructor(config: MigrationCLIConfig);
12
+ run(args?: string[]): Promise<void>;
13
+ create(name: string): void;
14
+ up(steps?: number): Promise<void>;
15
+ down(steps?: number): Promise<void>;
16
+ status(): Promise<void>;
17
+ private getRunner;
18
+ }
19
+ //# sourceMappingURL=MigrationCLI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationCLI.d.ts","sourceRoot":"","sources":["../../src/dev/MigrationCLI.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAA;AAI3F,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,0BAA0B,CAAA;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;gBAEnB,MAAM,EAAE,kBAAkB;IAMhC,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAuChE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBpB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjC,IAAI,CAAC,KAAK,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;YA8Bf,SAAS;CAGxB"}