Correções de bugs, layout de cards e webhook test funcional
- Pipeline cancel/approve/reject corrigido com busca bidirecional - Secrets injetados no executor via cleanEnv - Versionamento automático ao atualizar agentes - writeJsonAsync com log de erro - Removido asyncHandler.js (código morto) - Restaurado permissionMode padrão bypassPermissions - Ícones dos cards alinhados à direita com wrapper - Botão Editar convertido para ícone nos cards - Webhook test agora dispara execução real do agente/pipeline - Corrigido App.navigateTo no teste de webhook
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from 'fs';
|
||||
import { writeFile, rename } from 'fs/promises';
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
@@ -35,6 +36,13 @@ function writeJson(path, data) {
|
||||
renameSync(tmpPath, path);
|
||||
}
|
||||
|
||||
async function writeJsonAsync(path, data) {
|
||||
ensureDir();
|
||||
const tmpPath = path + '.tmp';
|
||||
await writeFile(tmpPath, JSON.stringify(data, null, 2), 'utf8');
|
||||
await rename(tmpPath, path);
|
||||
}
|
||||
|
||||
function clone(v) {
|
||||
return structuredClone(v);
|
||||
}
|
||||
@@ -57,7 +65,7 @@ function createStore(filePath) {
|
||||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
if (dirty) {
|
||||
writeJson(filePath, mem);
|
||||
writeJsonAsync(filePath, mem).catch((e) => console.error(`[db] Erro ao salvar ${filePath}:`, e.message));
|
||||
dirty = false;
|
||||
}
|
||||
}, DEBOUNCE_MS);
|
||||
@@ -75,6 +83,20 @@ function createStore(filePath) {
|
||||
return item ? clone(item) : null;
|
||||
},
|
||||
|
||||
findById(id) {
|
||||
return store.getById(id);
|
||||
},
|
||||
|
||||
count() {
|
||||
boot();
|
||||
return mem.length;
|
||||
},
|
||||
|
||||
filter(predicate) {
|
||||
boot();
|
||||
return mem.filter(predicate).map((item) => clone(item));
|
||||
},
|
||||
|
||||
create(data) {
|
||||
boot();
|
||||
const item = {
|
||||
@@ -110,7 +132,8 @@ function createStore(filePath) {
|
||||
},
|
||||
|
||||
save(items) {
|
||||
mem = Array.isArray(items) ? items : mem;
|
||||
if (!Array.isArray(items)) return;
|
||||
mem = items;
|
||||
touch();
|
||||
},
|
||||
|
||||
@@ -186,6 +209,21 @@ function createSettingsStore(filePath) {
|
||||
return store;
|
||||
}
|
||||
|
||||
const locks = new Map();
|
||||
|
||||
export async function withLock(key, fn) {
|
||||
while (locks.has(key)) await locks.get(key);
|
||||
let resolve;
|
||||
const promise = new Promise((r) => { resolve = r; });
|
||||
locks.set(key, promise);
|
||||
try {
|
||||
return await fn();
|
||||
} finally {
|
||||
locks.delete(key);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
export function flushAllStores() {
|
||||
for (const s of allStores) s.flush();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user