@crvouga/mockingbird-service-resend 1.6.0 → 1.6.1
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 +9 -1
- package/dist/{chunk-LUMU355N.js → chunk-FVK4CBNZ.js} +2 -2
- package/dist/{chunk-ZNHU32UM.js → chunk-RUK2K5Y6.js} +89 -10
- package/dist/chunk-RUK2K5Y6.js.map +7 -0
- package/dist/cli.js +2 -2
- package/dist/index.js +1 -1
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-ZNHU32UM.js.map +0 -7
- /package/dist/{chunk-LUMU355N.js.map → chunk-FVK4CBNZ.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-resend
|
|
2
2
|
|
|
3
|
-
## 1.6.
|
|
3
|
+
## 1.6.1 (2026-09-30)
|
|
4
|
+
|
|
5
|
+
### Fixes and improvements
|
|
6
|
+
|
|
7
|
+
- keep admin buttons pressed until the action finishes ([0aabfcb](https://github.com/crvouga/mockingbird/commit/0aabfcb5f392aa51e193f9c3f817d5877d92bc6a))
|
|
8
|
+
- size admin select fields like the text inputs beside them ([0fb3ef2](https://github.com/crvouga/mockingbird/commit/0fb3ef2ddbf43376c93a2ae6d87c6c9bf890dafc))
|
|
9
|
+
- keep admin section tabs wired when boot is renamed ([4eda25e](https://github.com/crvouga/mockingbird/commit/4eda25eacd59da048d196f7cc8369d7a02b47bfc))
|
|
10
|
+
|
|
11
|
+
## 1.6.0 (2026-09-29)
|
|
4
12
|
|
|
5
13
|
### Features
|
|
6
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRuntime
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RUK2K5Y6.js";
|
|
4
4
|
|
|
5
5
|
// ../../adapters/node/dist/cli.js
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
@@ -370,4 +370,4 @@ export {
|
|
|
370
370
|
createServer2 as createServer,
|
|
371
371
|
serveTarget
|
|
372
372
|
};
|
|
373
|
-
//# sourceMappingURL=chunk-
|
|
373
|
+
//# sourceMappingURL=chunk-FVK4CBNZ.js.map
|
|
@@ -2442,6 +2442,50 @@ function bootAdmin(config) {
|
|
|
2442
2442
|
if (render)
|
|
2443
2443
|
await render();
|
|
2444
2444
|
}
|
|
2445
|
+
const delay = (ms) => new Promise((resolve) => {
|
|
2446
|
+
window.setTimeout(resolve, ms);
|
|
2447
|
+
});
|
|
2448
|
+
const confirmAction = async (button, pending, done, work) => {
|
|
2449
|
+
if (button.dataset.pending === "1")
|
|
2450
|
+
return;
|
|
2451
|
+
const label = button.textContent ?? "";
|
|
2452
|
+
const width = button.offsetWidth;
|
|
2453
|
+
button.dataset.pending = "1";
|
|
2454
|
+
button.classList.add("pressed");
|
|
2455
|
+
button.setAttribute("aria-busy", "true");
|
|
2456
|
+
button.style.minWidth = `${width}px`;
|
|
2457
|
+
button.textContent = pending;
|
|
2458
|
+
try {
|
|
2459
|
+
await work();
|
|
2460
|
+
button.textContent = done;
|
|
2461
|
+
await delay(1e3);
|
|
2462
|
+
} catch (error2) {
|
|
2463
|
+
showError(error2);
|
|
2464
|
+
} finally {
|
|
2465
|
+
button.textContent = label;
|
|
2466
|
+
button.style.minWidth = "";
|
|
2467
|
+
button.classList.remove("pressed");
|
|
2468
|
+
button.removeAttribute("aria-busy");
|
|
2469
|
+
delete button.dataset.pending;
|
|
2470
|
+
}
|
|
2471
|
+
};
|
|
2472
|
+
document.addEventListener("click", (event) => {
|
|
2473
|
+
const target = event.target;
|
|
2474
|
+
if (!(target instanceof Element))
|
|
2475
|
+
return;
|
|
2476
|
+
const button = target.closest("button");
|
|
2477
|
+
if (!(button instanceof HTMLButtonElement) || button.dataset.pending === "1")
|
|
2478
|
+
return;
|
|
2479
|
+
button.classList.add("pressed");
|
|
2480
|
+
const token = String(Date.now());
|
|
2481
|
+
button.dataset.press = token;
|
|
2482
|
+
window.setTimeout(() => {
|
|
2483
|
+
if (button.dataset.press !== token || button.dataset.pending === "1")
|
|
2484
|
+
return;
|
|
2485
|
+
button.classList.remove("pressed");
|
|
2486
|
+
delete button.dataset.press;
|
|
2487
|
+
}, 450);
|
|
2488
|
+
});
|
|
2445
2489
|
el("namespace", HTMLSelectElement).addEventListener("change", () => {
|
|
2446
2490
|
state.namespace = el("namespace", HTMLSelectElement).value;
|
|
2447
2491
|
refresh().catch(showError);
|
|
@@ -2452,7 +2496,7 @@ function bootAdmin(config) {
|
|
|
2452
2496
|
refresh().catch(showError);
|
|
2453
2497
|
});
|
|
2454
2498
|
el("refresh", HTMLButtonElement).addEventListener("click", () => {
|
|
2455
|
-
refresh().catch(showError);
|
|
2499
|
+
confirmAction(el("refresh", HTMLButtonElement), "Refreshing...", "Updated", () => refresh()).catch(showError);
|
|
2456
2500
|
});
|
|
2457
2501
|
el("collections", HTMLElement).addEventListener("click", (event) => {
|
|
2458
2502
|
const target = event.target;
|
|
@@ -2575,10 +2619,10 @@ function bootAdmin(config) {
|
|
|
2575
2619
|
}).then(() => renderFaults()).catch(showError);
|
|
2576
2620
|
});
|
|
2577
2621
|
el("fault-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2578
|
-
api("DELETE", "/faults").then(() => renderFaults()).catch(showError);
|
|
2622
|
+
confirmAction(el("fault-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/faults").then(() => renderFaults())).catch(showError);
|
|
2579
2623
|
});
|
|
2580
2624
|
el("journal-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2581
|
-
api("DELETE", "/requests").then(() => renderJournal()).catch(showError);
|
|
2625
|
+
confirmAction(el("journal-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/requests").then(() => renderJournal())).catch(showError);
|
|
2582
2626
|
});
|
|
2583
2627
|
el("route-list", HTMLElement).addEventListener("click", (event) => {
|
|
2584
2628
|
const target = event.target;
|
|
@@ -2693,9 +2737,13 @@ function bootAdmin(config) {
|
|
|
2693
2737
|
var clientPrelude = [isRecord2, mountAdminBrand, startAdminBrand, faultPresetList, bootAdmin].map((fn) => fn.toString()).join("\n");
|
|
2694
2738
|
var adminClientSource = (config) => {
|
|
2695
2739
|
const payload = JSON.stringify(config).replace(/</g, "\\u003c");
|
|
2740
|
+
const entry = bootAdmin.name;
|
|
2741
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(entry)) {
|
|
2742
|
+
throw new Error("admin client cannot call its boot function");
|
|
2743
|
+
}
|
|
2696
2744
|
return `<script>
|
|
2697
2745
|
${clientPrelude}
|
|
2698
|
-
|
|
2746
|
+
${entry}(${payload});
|
|
2699
2747
|
</script>`;
|
|
2700
2748
|
};
|
|
2701
2749
|
|
|
@@ -2909,9 +2957,24 @@ var renderAdminDocument = (service) => {
|
|
|
2909
2957
|
.controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
2910
2958
|
label.field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--faint); }
|
|
2911
2959
|
label.field input, label.field select, .controls input[type="password"] {
|
|
2912
|
-
background: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2913
|
-
padding: 7px 8px; min-height: 36px;
|
|
2914
|
-
}
|
|
2960
|
+
background-color: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2961
|
+
padding: 7px 8px; min-height: 36px; line-height: 1.2;
|
|
2962
|
+
}
|
|
2963
|
+
/* A native menu ignores min-height, so Preset rendered about half as tall as
|
|
2964
|
+
the text fields in the same form. Paint it like those fields. */
|
|
2965
|
+
label.field select {
|
|
2966
|
+
-webkit-appearance: none; appearance: none;
|
|
2967
|
+
padding-right: 28px;
|
|
2968
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='%2371717a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M2.5 4.5 6 8l3.5-3.5'/%3E%3C/svg%3E");
|
|
2969
|
+
background-repeat: no-repeat; background-position: right 10px center; background-size: 12px 12px;
|
|
2970
|
+
}
|
|
2971
|
+
.stack > .field > input,
|
|
2972
|
+
.stack > .field > select,
|
|
2973
|
+
.stack > .field > textarea,
|
|
2974
|
+
dialog .field > input,
|
|
2975
|
+
dialog .field > select,
|
|
2976
|
+
dialog .field > textarea { width: 100%; }
|
|
2977
|
+
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger, nav.side button { cursor: pointer; }
|
|
2915
2978
|
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger {
|
|
2916
2979
|
border-radius: 9px; min-height: 36px; padding: 0 12px; border: 1px solid var(--line);
|
|
2917
2980
|
background: var(--bg-elev);
|
|
@@ -2919,6 +2982,14 @@ var renderAdminDocument = (service) => {
|
|
|
2919
2982
|
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
|
|
2920
2983
|
.btn-quiet { background: transparent; }
|
|
2921
2984
|
.btn-danger { color: var(--err); }
|
|
2985
|
+
/* Held after mouseup. Clearing an empty journal changes nothing on screen,
|
|
2986
|
+
so the press itself has to stay visible. */
|
|
2987
|
+
.icon-btn:active, .btn:active, .btn-quiet:active, .btn-danger:active, nav.side button:active,
|
|
2988
|
+
.icon-btn.pressed, .btn.pressed, .btn-quiet.pressed, .btn-danger.pressed, nav.side button.pressed {
|
|
2989
|
+
background: var(--bg-inset); border-color: var(--line-strong); color: var(--ink);
|
|
2990
|
+
}
|
|
2991
|
+
.btn-danger:active, .btn-danger.pressed { background: var(--err-soft); color: var(--err); }
|
|
2992
|
+
.btn-primary:active, .btn-primary.pressed { filter: brightness(0.88); color: var(--accent-ink); }
|
|
2922
2993
|
/* minmax(0, 1fr): a 1fr column will not shrink below its content, so a long
|
|
2923
2994
|
record or the full nav row would widen the page past the viewport. */
|
|
2924
2995
|
.layout {
|
|
@@ -3007,8 +3078,16 @@ var renderAdminDocument = (service) => {
|
|
|
3007
3078
|
input, select, textarea { font-size: 16px; }
|
|
3008
3079
|
.brand, .vendor, .controls { width: 100%; }
|
|
3009
3080
|
label.field, label.field select, label.field input { flex: 1; min-width: 0; }
|
|
3010
|
-
|
|
3081
|
+
/* The layout fills the screen. A single-column grid stretches every auto
|
|
3082
|
+
row, so the tab bar grew with the leftover height and the buttons floated
|
|
3083
|
+
in the middle of it. The bar stays one row; the page below takes the rest. */
|
|
3084
|
+
.layout {
|
|
3085
|
+
grid-template-columns: minmax(0, 1fr);
|
|
3086
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
3087
|
+
align-content: start;
|
|
3088
|
+
}
|
|
3011
3089
|
nav.side {
|
|
3090
|
+
align-self: start; height: auto;
|
|
3012
3091
|
flex-direction: row; align-items: center; overflow-x: auto; min-width: 0;
|
|
3013
3092
|
border-right: 0; border-bottom: 1px solid var(--line);
|
|
3014
3093
|
padding: 8px;
|
|
@@ -3876,7 +3955,7 @@ var stateAdminRoutes = (routes) => {
|
|
|
3876
3955
|
};
|
|
3877
3956
|
|
|
3878
3957
|
// ../core/dist/version.js
|
|
3879
|
-
var PACKAGE_VERSION = true ? "1.6.
|
|
3958
|
+
var PACKAGE_VERSION = true ? "1.6.1" : UNRELEASED_VERSION;
|
|
3880
3959
|
|
|
3881
3960
|
// ../core/dist/signing.js
|
|
3882
3961
|
var encoder = new TextEncoder();
|
|
@@ -5592,4 +5671,4 @@ export {
|
|
|
5592
5671
|
bareAddress,
|
|
5593
5672
|
ResendAPI
|
|
5594
5673
|
};
|
|
5595
|
-
//# sourceMappingURL=chunk-
|
|
5674
|
+
//# sourceMappingURL=chunk-RUK2K5Y6.js.map
|