@crvouga/mockingbird-service-postgres 3.13.0 → 3.14.0
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/CHANGELOG.md +7 -1
- package/DISCOVERY.md +29 -0
- package/dist/admin.js +1 -1
- package/dist/admin.js.map +2 -2
- package/dist/index.js +1 -1
- package/dist/wire/cli.js +52 -5
- package/dist/wire/cli.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32501,7 +32501,7 @@ function analyzeSchema(sql, options = {}) {
|
|
|
32501
32501
|
const diagnosticLimit = bounded(options.maxDiagnostics, 100, 1e3);
|
|
32502
32502
|
const report = {
|
|
32503
32503
|
engine: "mockingbird-postgres",
|
|
32504
|
-
version: true ? "3.
|
|
32504
|
+
version: true ? "3.14.0" : "source-tree",
|
|
32505
32505
|
statements: 0,
|
|
32506
32506
|
accepted: 0,
|
|
32507
32507
|
compatible: null,
|
package/dist/wire/cli.js
CHANGED
|
@@ -2649,9 +2649,7 @@ data: ${JSON.stringify(data)}
|
|
|
2649
2649
|
async handle(request, path, namespace, body, admin) {
|
|
2650
2650
|
const route = path.slice("/fleet".length), method = request.method;
|
|
2651
2651
|
if (path === "/ui")
|
|
2652
|
-
return new Response(fleetConsole(this.ctx.config.adminPrefix ?? "/__admin"), {
|
|
2653
|
-
headers: { "content-type": "text/html; charset=utf-8" }
|
|
2654
|
-
});
|
|
2652
|
+
return new Response(fleetConsole(this.ctx.config.adminPrefix ?? "/__admin", this.ctx.dashboard?.()), { headers: { "content-type": "text/html; charset=utf-8" } });
|
|
2655
2653
|
if (route === "" && method === "GET")
|
|
2656
2654
|
return Response.json({
|
|
2657
2655
|
...this.capability(),
|
|
@@ -3621,7 +3619,8 @@ data: ${JSON.stringify(data)}
|
|
|
3621
3619
|
clearInterval(this.expiryTimer);
|
|
3622
3620
|
}
|
|
3623
3621
|
};
|
|
3624
|
-
var
|
|
3622
|
+
var escapeAttribute = (value) => value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
3623
|
+
var fleetConsole = (prefix, dashboard) => `<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Mockingbird Fleet</title><style>body{font:16px system-ui;max-width:1000px;margin:3rem auto;padding:1rem;background:#10151b;color:#e0e9f2}input,select,button{padding:.7rem;margin:.3rem;background:#233142;color:inherit;border:1px solid #60768b;border-radius:5px}pre{white-space:pre-wrap;overflow-wrap:anywhere}a{color:#9fdbff}</style><h1>Mockingbird Fleet</h1>${dashboard ? `<p id="dashboard">Every emulator's admin UI and the notifications UI are on the <a href="${escapeAttribute(dashboard)}">dashboard</a>.</p>` : ""}<label>Admin key <input id="key" type="password" autocomplete="off"></label><label>Namespace <input id="ns" value="default"></label><button id="refresh">Refresh</button><section id="children"></section><label>Action <select id="action"><option value="snapshots">Capture checkpoint</option><option value="reset">Reset namespace</option></select></label><button id="run">Run</button><h2>Lifecycle and operations</h2><pre id="result"></pre><script type="module">const base=${JSON.stringify(`${prefix}/fleet`)};const key=document.querySelector('#key'),ns=document.querySelector('#ns'),result=document.querySelector('#result');async function api(path,method='GET',body){const r=await fetch(base+path,{method,headers:{'content-type':'application/json','x-mockingbird-admin-key':key.value},...(body?{body:JSON.stringify(body)}:{})});const data=await r.json();result.textContent=JSON.stringify(data,null,2);return data}document.querySelector('#refresh').onclick=async()=>{const data=await api('');const host=document.querySelector('#children');host.replaceChildren();for(const [name,child]of Object.entries(data.manifest?.services??{})){const link=document.createElement('a');link.href=child.adminUrl;link.textContent=name+' ('+child.protocol+') ';host.append(link)}await api('/operations?namespace='+encodeURIComponent(ns.value))};document.querySelector('#run').onclick=()=>api('/namespaces/'+encodeURIComponent(ns.value)+'/'+document.querySelector('#action').value,'POST',{});</script></html>`;
|
|
3625
3624
|
|
|
3626
3625
|
// ../../adapters/node/dist/fleet-preflight.js
|
|
3627
3626
|
import { readFile, realpath } from "node:fs/promises";
|
|
@@ -3685,6 +3684,28 @@ var fleet_config_schema_default = {
|
|
|
3685
3684
|
}
|
|
3686
3685
|
}
|
|
3687
3686
|
},
|
|
3687
|
+
dashboard: {
|
|
3688
|
+
description: "Serve the dashboard (every emulator's admin UI and the notifications UI) next to the fleet. Honored by mockingbird-fleet serve.",
|
|
3689
|
+
anyOf: [
|
|
3690
|
+
{
|
|
3691
|
+
type: "boolean"
|
|
3692
|
+
},
|
|
3693
|
+
{
|
|
3694
|
+
type: "object",
|
|
3695
|
+
additionalProperties: false,
|
|
3696
|
+
properties: {
|
|
3697
|
+
port: {
|
|
3698
|
+
type: "integer",
|
|
3699
|
+
minimum: 0,
|
|
3700
|
+
maximum: 65535
|
|
3701
|
+
},
|
|
3702
|
+
host: {
|
|
3703
|
+
type: "string"
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
]
|
|
3708
|
+
},
|
|
3688
3709
|
cors: {
|
|
3689
3710
|
type: "object",
|
|
3690
3711
|
required: ["origins"],
|
|
@@ -3969,6 +3990,7 @@ async function preflightFleet(config, options2) {
|
|
|
3969
3990
|
throw new Error("protected archive policy requires a protected repository; configure its protector before startup");
|
|
3970
3991
|
resolveAdminPrefix(config.adminPrefix);
|
|
3971
3992
|
normalizeBootControls(config.adminControls);
|
|
3993
|
+
validateDashboard(config.dashboard);
|
|
3972
3994
|
if (config.idBase !== void 0)
|
|
3973
3995
|
normalizeIdBase(config.idBase, "idBase");
|
|
3974
3996
|
const targets = /* @__PURE__ */ new Map();
|
|
@@ -4044,7 +4066,7 @@ async function preflightFleet(config, options2) {
|
|
|
4044
4066
|
break;
|
|
4045
4067
|
}
|
|
4046
4068
|
}
|
|
4047
|
-
targets.set(name2, { ...target, packageVersion: packageVersion ?? "3.
|
|
4069
|
+
targets.set(name2, { ...target, packageVersion: packageVersion ?? "3.14.0" });
|
|
4048
4070
|
} catch (error) {
|
|
4049
4071
|
throw new Error(`service ${name2}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
4050
4072
|
}
|
|
@@ -4129,6 +4151,22 @@ function validateFleetPolicies(options2) {
|
|
|
4129
4151
|
if (duration !== void 0 && (!Number.isSafeInteger(duration) || duration < 1))
|
|
4130
4152
|
throw new Error("hook deadlines must be positive integer milliseconds");
|
|
4131
4153
|
}
|
|
4154
|
+
function validateDashboard(value) {
|
|
4155
|
+
if (value === void 0 || typeof value === "boolean")
|
|
4156
|
+
return;
|
|
4157
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
4158
|
+
throw new Error("dashboard: expected true, false or { port, host }");
|
|
4159
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
4160
|
+
if (key === "port") {
|
|
4161
|
+
if (!Number.isInteger(entry) || entry < 0 || entry > 65535)
|
|
4162
|
+
throw new Error("dashboard.port: expected an integer from 0 to 65535");
|
|
4163
|
+
} else if (key === "host") {
|
|
4164
|
+
if (typeof entry !== "string" || !entry)
|
|
4165
|
+
throw new Error("dashboard.host: expected a host");
|
|
4166
|
+
} else
|
|
4167
|
+
throw new Error(`dashboard.${key}: unknown key; expected port or host`);
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4132
4170
|
|
|
4133
4171
|
// ../../adapters/node/dist/serve.js
|
|
4134
4172
|
import { createServer } from "node:http";
|
|
@@ -4584,6 +4622,7 @@ async function startFleet(config, options2) {
|
|
|
4584
4622
|
const checkpoints = /* @__PURE__ */ new Map();
|
|
4585
4623
|
let supervisor;
|
|
4586
4624
|
let management;
|
|
4625
|
+
let dashboard;
|
|
4587
4626
|
let manifest;
|
|
4588
4627
|
const privateConnections = () => Object.fromEntries([...children].map(([name2, child]) => [
|
|
4589
4628
|
name2,
|
|
@@ -4651,6 +4690,7 @@ async function startFleet(config, options2) {
|
|
|
4651
4690
|
}
|
|
4652
4691
|
}
|
|
4653
4692
|
const cleanup = await Promise.allSettled([
|
|
4693
|
+
dashboard?.close(),
|
|
4654
4694
|
supervisor?.close(),
|
|
4655
4695
|
removeOwned(options2.readyFile, id),
|
|
4656
4696
|
removeOwned(options2.connectionsFile, id)
|
|
@@ -5017,6 +5057,7 @@ async function startFleet(config, options2) {
|
|
|
5017
5057
|
clock,
|
|
5018
5058
|
transaction,
|
|
5019
5059
|
manifest: () => manifest,
|
|
5060
|
+
dashboard: () => dashboard?.url,
|
|
5020
5061
|
publish,
|
|
5021
5062
|
recovery,
|
|
5022
5063
|
controlling
|
|
@@ -5080,6 +5121,10 @@ async function startFleet(config, options2) {
|
|
|
5080
5121
|
}
|
|
5081
5122
|
}
|
|
5082
5123
|
await management.startPolicies();
|
|
5124
|
+
if (options2.dashboard) {
|
|
5125
|
+
dashboard = await options2.dashboard({ manifest, config });
|
|
5126
|
+
manifest.dashboard = dashboard.url;
|
|
5127
|
+
}
|
|
5083
5128
|
await publish();
|
|
5084
5129
|
if (manifest.state === "ready")
|
|
5085
5130
|
options2.onReady?.(manifest);
|
|
@@ -5911,6 +5956,8 @@ var serveCommand = (target) => ({
|
|
|
5911
5956
|
const adminKey2 = config.adminKey ?? asString(values["admin-key"]) ?? process.env.MOCKINGBIRD_ADMIN_KEY;
|
|
5912
5957
|
if (adminKey2 !== void 0)
|
|
5913
5958
|
config.adminKey = adminKey2;
|
|
5959
|
+
if (config.dashboard)
|
|
5960
|
+
console.error(`${configPath}: "dashboard" is served by mockingbird-fleet (npx @crvouga/mockingbird-fleet serve --config ${configPath}); a service's own serve command starts the fleet without it`);
|
|
5914
5961
|
const adminControls = await resolveServeControls(values, process.env, config.adminControls);
|
|
5915
5962
|
if (adminControls !== void 0)
|
|
5916
5963
|
config.adminControls = adminControls;
|