From 08c28301f2798b83eabee6fbe04cfaac974fd595 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Mon, 2 Mar 2026 14:03:10 +0100 Subject: [PATCH 1/2] feat: deployment info panel in dashboard Signals tab Surface deployed commit SHA, drift from main, commit diff, and remote branches in the Signals panel. Health endpoints now report the deploy SHA instead of hardcoded 1.0.0. Co-Authored-By: Claude Opus 4.6 --- __tests__/integration/app.test.js | 4 +- __tests__/smoke/server.test.js | 2 +- src/app.js | 6 +- src/dashboard.js | 122 ++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 6 deletions(-) diff --git a/__tests__/integration/app.test.js b/__tests__/integration/app.test.js index 86f7918..b0992dd 100644 --- a/__tests__/integration/app.test.js +++ b/__tests__/integration/app.test.js @@ -322,7 +322,7 @@ describe('app', () => { expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith( - expect.objectContaining({ status: 'healthy', version: '1.0.0' }) + expect.objectContaining({ status: 'healthy', version: expect.any(String) }) ); expect(mockRes.json).toHaveBeenCalledWith( expect.objectContaining({ queue: expect.any(Object) }) @@ -407,7 +407,7 @@ describe('app', () => { expect(res.writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/json' }); const body = JSON.parse(res.end.mock.calls[0][0]); expect(body.status).toBe('healthy'); - expect(body.version).toBe('1.0.0'); + expect(typeof body.version).toBe('string'); expect(body.queue).toBeDefined(); expect(body.timestamp).toBeDefined(); }); diff --git a/__tests__/smoke/server.test.js b/__tests__/smoke/server.test.js index fd408e9..fad0d32 100644 --- a/__tests__/smoke/server.test.js +++ b/__tests__/smoke/server.test.js @@ -121,7 +121,7 @@ describe('server boot', () => { if (res.status === 200) { const data = JSON.parse(res.body); expect(data.status).toBe('healthy'); - expect(data.version).toBe('1.0.0'); + expect(typeof data.version).toBe('string'); expect(data.queue).toBeDefined(); } else { // Routes not registered — Probot v14 doesn't always provide getRouter diff --git a/src/app.js b/src/app.js index dba9d43..69e4757 100644 --- a/src/app.js +++ b/src/app.js @@ -1,6 +1,6 @@ import path from 'path'; import { fileURLToPath } from 'url'; -import { createDashboardHandler } from './dashboard.js'; +import { createDashboardHandler, DEPLOY_SHA } from './dashboard.js'; import { getConfig } from './config.js'; import { getLogger, setLogger } from './logger.js'; import { configureRepository } from './repository.js'; @@ -51,7 +51,7 @@ function createCustomRoutesHandler() { const healthData = { status: 'healthy', timestamp: new Date().toISOString(), - version: '1.0.0', + version: DEPLOY_SHA || '1.0.0', queue: defaultQueue.stats() }; if (_taskStore) { @@ -617,7 +617,7 @@ function registerApp(app, { getRouter, addHandler } = {}) { const healthData = { status: 'healthy', timestamp: new Date().toISOString(), - version: '1.0.0', + version: DEPLOY_SHA || '1.0.0', queue: defaultQueue.stats() }; if (_taskStore) { diff --git a/src/dashboard.js b/src/dashboard.js index cc760fb..1f8e14d 100644 --- a/src/dashboard.js +++ b/src/dashboard.js @@ -1,3 +1,4 @@ +import { execFileSync } from 'child_process'; import { getConfig } from './config.js'; import { getLogger } from './logger.js'; import { analyzeOrganizationRepositories, synchronizeAllRepositories, generateOrganizationAnalysisReport } from './organization.js'; @@ -406,6 +407,113 @@ function renderReviewsPartial() { return rows; } +// ── Deployment partial ─────────────────────────────────────────────── + +async function renderDeploymentPartial() { + const config = getConfig(); + const org = config?.organization; + + // Local deploy info always renders — no API needed + const startedAgo = timeAgo(DEPLOY_TIME); + let html = '
' + + '
Deployed SHA
' + + '
' + esc(DEPLOY_SHA) + '
' + + '
started ' + esc(startedAgo) + ' ago
'; + + // API-dependent section + let mainSha = null; + let behindBy = 0; + let branches = []; + try { + const octokit = await getOctokit(); + const selfRepo = config?.selfRepoName || 'temper'; + + // Get main branch HEAD + const { data: mainBranch } = await octokit.repos.getBranch({ owner: org, repo: selfRepo, branch: 'main' }); + mainSha = mainBranch.commit.sha.slice(0, 7); + const mainShaFull = mainBranch.commit.sha; + + // Compare to find drift + let compareData = null; + if (DEPLOY_SHA_FULL !== 'unknown') { + try { + const { data } = await octokit.repos.compareCommits({ owner: org, repo: selfRepo, base: DEPLOY_SHA_FULL, head: mainShaFull }); + compareData = data; + behindBy = data.ahead_by || 0; + } catch (cmpErr) { + if (cmpErr.status === 404) { + compareData = { error: 'Deployed SHA not found in repo history (force-pushed?)' }; + } else { throw cmpErr; } + } + } + + // Main HEAD card + const driftBadge = behindBy > 0 ? badge('warn', behindBy + ' behind') : badge('ok', 'up to date'); + html += '
Main HEAD
' + + '
' + esc(mainSha) + '
' + + '
' + driftBadge + '
'; + + // Branch count + const { data: branchList } = await octokit.repos.listBranches({ owner: org, repo: selfRepo, per_page: 100 }); + branches = branchList; + html += '
Branches
' + + '
' + branches.length + '
' + + '
remote
'; + + html += '
'; // close stat-grid + + // Commits table (when behind) + if (compareData && !compareData.error && behindBy > 0) { + const commits = (compareData.commits || []).slice(-10).reverse(); + html += '
Commits on main since deploy (' + behindBy + ')
' + + '
' + + '' + + ''; + for (const c of commits) { + const sha7 = c.sha.slice(0, 7); + const msg = (c.commit.message || '').split('\n')[0]; + const author = c.commit.author?.name || c.author?.login || ''; + const age = timeAgo(c.commit.author?.date); + html += '' + + '' + + '' + + '' + + '' + + ''; + } + html += '
SHAMessageAuthorAge
' + esc(sha7) + '' + esc(msg.length > 72 ? msg.slice(0, 72) + '...' : msg) + '' + esc(author) + '' + esc(age) + '
'; + } else if (compareData && compareData.error) { + html += '
' + esc(compareData.error) + '
'; + } + + // Branch list table + if (branches.length > 0) { + html += '
Remote Branches
' + + '
' + + '' + + ''; + for (const b of branches) { + const sha7 = b.commit.sha.slice(0, 7); + const badges = []; + if (b.name === 'main') badges.push(badge('info', 'default')); + if (b.commit.sha === DEPLOY_SHA_FULL) badges.push(badge('ok', 'deployed')); + html += '' + + '' + + '' + + '' + + ''; + } + html += '
BranchLast CommitInfo
' + esc(b.name) + '' + esc(sha7) + '' + (badges.length ? badges.join(' ') : '') + '
'; + } + } catch (err) { + html += ''; // close stat-grid in case API failed mid-render + getLogger().warn({ err }, 'Deployment partial API error'); + html += '
Could not fetch remote info: ' + esc(err.message) + '
'; + } + + return html; +} + // ── Full reviews partial (for dedicated Reviews tab) ───────────────── function reviewAssessmentBadge(a) { @@ -571,6 +679,11 @@ const CLIENT_JS = readFileSync(join(dashModuleDir, 'dashboard-client.js'), 'utf8 const HTMX_JS = readFileSync(join(dashModuleDir, 'htmx.min.js'), 'utf8'); const IDIOMORPH_JS = readFileSync(join(dashModuleDir, 'idiomorph-ext.min.js'), 'utf8'); +// ── Deploy info (captured once at startup) ────────────────────────── +export const DEPLOY_SHA = (() => { try { return execFileSync('git', ['rev-parse', '--short', 'HEAD'], { cwd: dashModuleDir, encoding: 'utf8' }).trim(); } catch { return 'unknown'; } })(); +const DEPLOY_SHA_FULL = (() => { try { return execFileSync('git', ['rev-parse', 'HEAD'], { cwd: dashModuleDir, encoding: 'utf8' }).trim(); } catch { return 'unknown'; } })(); +const DEPLOY_TIME = new Date().toISOString(); + // ── CSS ────────────────────────────────────────────────────────────── const CSS = ` *{margin:0;padding:0;box-sizing:border-box} @@ -1067,6 +1180,10 @@ function renderDashboardPage() { '
' + '
' + '
' + + '
Deployment
' + + '
' + + '
' + + '
' + '
Active Pull Requests
' + '
' + '
' + @@ -1231,6 +1348,11 @@ export function createDashboardHandler() { catch (err) { getLogger().error({err},'Dashboard issues error'); sendHtml(res, 200, renderError(err)); } return true; } + if (req.method === 'GET' && path === '/dashboard/partials/deployment') { + try { sendHtml(res, 200, await renderDeploymentPartial()); } + catch (err) { getLogger().error({err},'Dashboard deployment error'); sendHtml(res, 200, renderError(err)); } + return true; + } // AI Reviews partial (compact, for Signals panel if still used) if (req.method === 'GET' && path === '/dashboard/partials/reviews') { From b5113076437cbf3e167031e00c11a8ac6331dbb3 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Mon, 2 Mar 2026 14:19:02 +0100 Subject: [PATCH 2/2] fix: add better-sqlite3 to pnpm lockfile and Bazel deps The pnpm-lock.yaml was never regenerated after better-sqlite3 was added to package.json, so Bazel CI (which uses npm_translate_lock on the pnpm lockfile) couldn't resolve the module. Also adds the dep to src/BUILD.bazel and allows its native build scripts in pnpm config. Co-Authored-By: Claude Opus 4.6 --- package.json | 2 +- pnpm-lock.yaml | 228 ++++++++++++++++++++++++++++++++++++++++++++++++ src/BUILD.bazel | 1 + 3 files changed, 230 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c8a4d2c..8a7c3e5 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,6 @@ "provenance": true }, "pnpm": { - "onlyBuiltDependencies": [] + "onlyBuiltDependencies": ["better-sqlite3"] } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92f202e..05b25e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@octokit/rest': specifier: ^22.0.1 version: 22.0.1 + better-sqlite3: + specifier: ^11.10.0 + version: 11.10.0 helmet: specifier: ^8.1.0 version: 8.1.0 @@ -1099,6 +1102,9 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.9.18: resolution: {integrity: sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==} hasBin: true @@ -1106,10 +1112,19 @@ packages: before-after-hook@4.0.0: resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + better-sqlite3@11.10.0: + resolution: {integrity: sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + bottleneck@2.19.5: resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} @@ -1131,6 +1146,9 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1158,6 +1176,9 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -1220,6 +1241,10 @@ packages: supports-color: optional: true + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dedent@1.7.1: resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} peerDependencies: @@ -1228,6 +1253,10 @@ packages: babel-plugin-macros: optional: true + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1235,6 +1264,10 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -1326,6 +1359,10 @@ packages: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1365,6 +1402,9 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1388,6 +1428,9 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1415,6 +1458,9 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1463,6 +1509,9 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore-by-default@1.0.1: resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} @@ -1493,6 +1542,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -1806,18 +1858,32 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-abi@3.87.0: + resolution: {integrity: sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==} + engines: {node: '>=10'} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -1944,6 +2010,12 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1987,9 +2059,17 @@ packages: quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -2053,6 +2133,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-stable-stringify@2.5.0: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} @@ -2080,6 +2163,12 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} @@ -2120,6 +2209,9 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2132,6 +2224,10 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2156,6 +2252,13 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -2185,6 +2288,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -2238,6 +2344,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} @@ -3701,12 +3810,29 @@ snapshots: balanced-match@1.0.2: {} + base64-js@1.5.1: {} + baseline-browser-mapping@2.9.18: {} before-after-hook@4.0.0: {} + better-sqlite3@11.10.0: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + binary-extensions@2.3.0: {} + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + bottleneck@2.19.5: {} brace-expansion@1.1.12: @@ -3732,6 +3858,11 @@ snapshots: buffer-from@1.1.2: {} + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + callsites@3.1.0: {} camelcase@5.3.1: {} @@ -3759,6 +3890,8 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chownr@1.1.4: {} + ci-info@3.9.0: {} ci-info@4.3.1: {} @@ -3820,12 +3953,20 @@ snapshots: optionalDependencies: supports-color: 5.5.0 + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + dedent@1.7.1: {} + deep-extend@0.6.0: {} + deep-is@0.1.4: {} deepmerge@4.3.1: {} + detect-libc@2.1.2: {} + detect-newline@3.1.0: {} diff-sequences@29.6.3: {} @@ -3940,6 +4081,8 @@ snapshots: exit@0.1.2: {} + expand-template@2.0.3: {} + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -3983,6 +4126,8 @@ snapshots: dependencies: flat-cache: 3.2.0 + file-uri-to-path@1.0.0: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -4007,6 +4152,8 @@ snapshots: flatted@3.3.3: {} + fs-constants@1.0.0: {} + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -4022,6 +4169,8 @@ snapshots: get-stream@6.0.1: {} + github-from-package@0.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4063,6 +4212,8 @@ snapshots: human-signals@2.1.0: {} + ieee754@1.2.1: {} + ignore-by-default@1.0.1: {} ignore@5.3.2: {} @@ -4088,6 +4239,8 @@ snapshots: inherits@2.0.4: {} + ini@1.3.8: {} + is-arrayish@0.2.1: {} is-binary-path@2.1.0: @@ -4583,16 +4736,26 @@ snapshots: mimic-fn@2.1.0: {} + mimic-response@3.1.0: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 minimist@1.2.8: {} + mkdirp-classic@0.5.3: {} + ms@2.1.3: {} + napi-build-utils@2.0.0: {} + natural-compare@1.4.0: {} + node-abi@3.87.0: + dependencies: + semver: 7.7.4 + node-int64@0.4.0: {} node-releases@2.0.27: {} @@ -4742,6 +4905,21 @@ snapshots: dependencies: find-up: 4.1.0 + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.87.0 + pump: 3.0.3 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + prelude-ls@1.2.1: {} pretty-format@29.7.0: @@ -4804,8 +4982,21 @@ snapshots: quick-format-unescaped@4.0.4: {} + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + react-is@18.3.1: {} + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -4861,6 +5052,8 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-buffer@5.2.1: {} + safe-stable-stringify@2.5.0: {} secure-json-parse@4.1.0: {} @@ -4877,6 +5070,14 @@ snapshots: signal-exit@3.0.7: {} + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + simple-update-notifier@2.0.0: dependencies: semver: 7.7.4 @@ -4915,6 +5116,10 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -4923,6 +5128,8 @@ snapshots: strip-final-newline@2.0.0: {} + strip-json-comments@2.0.1: {} + strip-json-comments@3.1.1: {} strip-json-comments@5.0.3: {} @@ -4941,6 +5148,21 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.3 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 @@ -4965,6 +5187,10 @@ snapshots: tslib@2.8.1: {} + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -5004,6 +5230,8 @@ snapshots: dependencies: punycode: 2.3.1 + util-deprecate@1.0.2: {} + v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.31 diff --git a/src/BUILD.bazel b/src/BUILD.bazel index b299c79..31556d3 100644 --- a/src/BUILD.bazel +++ b/src/BUILD.bazel @@ -10,6 +10,7 @@ js_library( "//:node_modules/js-yaml", "//:node_modules/helmet", "//:node_modules/pino", + "//:node_modules/better-sqlite3", ], visibility = ["//visibility:public"], )