@crvouga/mockingbird-service-easypost 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-EVFM6BRF.js → chunk-3QIW75OT.js} +89 -10
- package/dist/chunk-3QIW75OT.js.map +7 -0
- package/dist/{chunk-XTVSFQRN.js → chunk-LIGZRJBP.js} +2 -2
- 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-EVFM6BRF.js.map +0 -7
- /package/dist/{chunk-XTVSFQRN.js.map → chunk-LIGZRJBP.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-easypost
|
|
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
|
|
|
@@ -2357,6 +2357,50 @@ function bootAdmin(config) {
|
|
|
2357
2357
|
if (render)
|
|
2358
2358
|
await render();
|
|
2359
2359
|
}
|
|
2360
|
+
const delay = (ms) => new Promise((resolve) => {
|
|
2361
|
+
window.setTimeout(resolve, ms);
|
|
2362
|
+
});
|
|
2363
|
+
const confirmAction = async (button, pending, done, work) => {
|
|
2364
|
+
if (button.dataset.pending === "1")
|
|
2365
|
+
return;
|
|
2366
|
+
const label = button.textContent ?? "";
|
|
2367
|
+
const width = button.offsetWidth;
|
|
2368
|
+
button.dataset.pending = "1";
|
|
2369
|
+
button.classList.add("pressed");
|
|
2370
|
+
button.setAttribute("aria-busy", "true");
|
|
2371
|
+
button.style.minWidth = `${width}px`;
|
|
2372
|
+
button.textContent = pending;
|
|
2373
|
+
try {
|
|
2374
|
+
await work();
|
|
2375
|
+
button.textContent = done;
|
|
2376
|
+
await delay(1e3);
|
|
2377
|
+
} catch (error) {
|
|
2378
|
+
showError(error);
|
|
2379
|
+
} finally {
|
|
2380
|
+
button.textContent = label;
|
|
2381
|
+
button.style.minWidth = "";
|
|
2382
|
+
button.classList.remove("pressed");
|
|
2383
|
+
button.removeAttribute("aria-busy");
|
|
2384
|
+
delete button.dataset.pending;
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
document.addEventListener("click", (event) => {
|
|
2388
|
+
const target = event.target;
|
|
2389
|
+
if (!(target instanceof Element))
|
|
2390
|
+
return;
|
|
2391
|
+
const button = target.closest("button");
|
|
2392
|
+
if (!(button instanceof HTMLButtonElement) || button.dataset.pending === "1")
|
|
2393
|
+
return;
|
|
2394
|
+
button.classList.add("pressed");
|
|
2395
|
+
const token = String(Date.now());
|
|
2396
|
+
button.dataset.press = token;
|
|
2397
|
+
window.setTimeout(() => {
|
|
2398
|
+
if (button.dataset.press !== token || button.dataset.pending === "1")
|
|
2399
|
+
return;
|
|
2400
|
+
button.classList.remove("pressed");
|
|
2401
|
+
delete button.dataset.press;
|
|
2402
|
+
}, 450);
|
|
2403
|
+
});
|
|
2360
2404
|
el("namespace", HTMLSelectElement).addEventListener("change", () => {
|
|
2361
2405
|
state.namespace = el("namespace", HTMLSelectElement).value;
|
|
2362
2406
|
refresh().catch(showError);
|
|
@@ -2367,7 +2411,7 @@ function bootAdmin(config) {
|
|
|
2367
2411
|
refresh().catch(showError);
|
|
2368
2412
|
});
|
|
2369
2413
|
el("refresh", HTMLButtonElement).addEventListener("click", () => {
|
|
2370
|
-
refresh().catch(showError);
|
|
2414
|
+
confirmAction(el("refresh", HTMLButtonElement), "Refreshing...", "Updated", () => refresh()).catch(showError);
|
|
2371
2415
|
});
|
|
2372
2416
|
el("collections", HTMLElement).addEventListener("click", (event) => {
|
|
2373
2417
|
const target = event.target;
|
|
@@ -2490,10 +2534,10 @@ function bootAdmin(config) {
|
|
|
2490
2534
|
}).then(() => renderFaults()).catch(showError);
|
|
2491
2535
|
});
|
|
2492
2536
|
el("fault-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2493
|
-
api("DELETE", "/faults").then(() => renderFaults()).catch(showError);
|
|
2537
|
+
confirmAction(el("fault-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/faults").then(() => renderFaults())).catch(showError);
|
|
2494
2538
|
});
|
|
2495
2539
|
el("journal-clear", HTMLButtonElement).addEventListener("click", () => {
|
|
2496
|
-
api("DELETE", "/requests").then(() => renderJournal()).catch(showError);
|
|
2540
|
+
confirmAction(el("journal-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/requests").then(() => renderJournal())).catch(showError);
|
|
2497
2541
|
});
|
|
2498
2542
|
el("route-list", HTMLElement).addEventListener("click", (event) => {
|
|
2499
2543
|
const target = event.target;
|
|
@@ -2608,9 +2652,13 @@ function bootAdmin(config) {
|
|
|
2608
2652
|
var clientPrelude = [isRecord2, mountAdminBrand, startAdminBrand, faultPresetList, bootAdmin].map((fn) => fn.toString()).join("\n");
|
|
2609
2653
|
var adminClientSource = (config) => {
|
|
2610
2654
|
const payload = JSON.stringify(config).replace(/</g, "\\u003c");
|
|
2655
|
+
const entry = bootAdmin.name;
|
|
2656
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(entry)) {
|
|
2657
|
+
throw new Error("admin client cannot call its boot function");
|
|
2658
|
+
}
|
|
2611
2659
|
return `<script>
|
|
2612
2660
|
${clientPrelude}
|
|
2613
|
-
|
|
2661
|
+
${entry}(${payload});
|
|
2614
2662
|
</script>`;
|
|
2615
2663
|
};
|
|
2616
2664
|
|
|
@@ -2824,9 +2872,24 @@ var renderAdminDocument = (service) => {
|
|
|
2824
2872
|
.controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
2825
2873
|
label.field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--faint); }
|
|
2826
2874
|
label.field input, label.field select, .controls input[type="password"] {
|
|
2827
|
-
background: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2828
|
-
padding: 7px 8px; min-height: 36px;
|
|
2829
|
-
}
|
|
2875
|
+
background-color: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
|
|
2876
|
+
padding: 7px 8px; min-height: 36px; line-height: 1.2;
|
|
2877
|
+
}
|
|
2878
|
+
/* A native menu ignores min-height, so Preset rendered about half as tall as
|
|
2879
|
+
the text fields in the same form. Paint it like those fields. */
|
|
2880
|
+
label.field select {
|
|
2881
|
+
-webkit-appearance: none; appearance: none;
|
|
2882
|
+
padding-right: 28px;
|
|
2883
|
+
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");
|
|
2884
|
+
background-repeat: no-repeat; background-position: right 10px center; background-size: 12px 12px;
|
|
2885
|
+
}
|
|
2886
|
+
.stack > .field > input,
|
|
2887
|
+
.stack > .field > select,
|
|
2888
|
+
.stack > .field > textarea,
|
|
2889
|
+
dialog .field > input,
|
|
2890
|
+
dialog .field > select,
|
|
2891
|
+
dialog .field > textarea { width: 100%; }
|
|
2892
|
+
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger, nav.side button { cursor: pointer; }
|
|
2830
2893
|
.icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger {
|
|
2831
2894
|
border-radius: 9px; min-height: 36px; padding: 0 12px; border: 1px solid var(--line);
|
|
2832
2895
|
background: var(--bg-elev);
|
|
@@ -2834,6 +2897,14 @@ var renderAdminDocument = (service) => {
|
|
|
2834
2897
|
.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
|
|
2835
2898
|
.btn-quiet { background: transparent; }
|
|
2836
2899
|
.btn-danger { color: var(--err); }
|
|
2900
|
+
/* Held after mouseup. Clearing an empty journal changes nothing on screen,
|
|
2901
|
+
so the press itself has to stay visible. */
|
|
2902
|
+
.icon-btn:active, .btn:active, .btn-quiet:active, .btn-danger:active, nav.side button:active,
|
|
2903
|
+
.icon-btn.pressed, .btn.pressed, .btn-quiet.pressed, .btn-danger.pressed, nav.side button.pressed {
|
|
2904
|
+
background: var(--bg-inset); border-color: var(--line-strong); color: var(--ink);
|
|
2905
|
+
}
|
|
2906
|
+
.btn-danger:active, .btn-danger.pressed { background: var(--err-soft); color: var(--err); }
|
|
2907
|
+
.btn-primary:active, .btn-primary.pressed { filter: brightness(0.88); color: var(--accent-ink); }
|
|
2837
2908
|
/* minmax(0, 1fr): a 1fr column will not shrink below its content, so a long
|
|
2838
2909
|
record or the full nav row would widen the page past the viewport. */
|
|
2839
2910
|
.layout {
|
|
@@ -2922,8 +2993,16 @@ var renderAdminDocument = (service) => {
|
|
|
2922
2993
|
input, select, textarea { font-size: 16px; }
|
|
2923
2994
|
.brand, .vendor, .controls { width: 100%; }
|
|
2924
2995
|
label.field, label.field select, label.field input { flex: 1; min-width: 0; }
|
|
2925
|
-
|
|
2996
|
+
/* The layout fills the screen. A single-column grid stretches every auto
|
|
2997
|
+
row, so the tab bar grew with the leftover height and the buttons floated
|
|
2998
|
+
in the middle of it. The bar stays one row; the page below takes the rest. */
|
|
2999
|
+
.layout {
|
|
3000
|
+
grid-template-columns: minmax(0, 1fr);
|
|
3001
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
3002
|
+
align-content: start;
|
|
3003
|
+
}
|
|
2926
3004
|
nav.side {
|
|
3005
|
+
align-self: start; height: auto;
|
|
2927
3006
|
flex-direction: row; align-items: center; overflow-x: auto; min-width: 0;
|
|
2928
3007
|
border-right: 0; border-bottom: 1px solid var(--line);
|
|
2929
3008
|
padding: 8px;
|
|
@@ -3791,7 +3870,7 @@ var stateAdminRoutes = (routes) => {
|
|
|
3791
3870
|
};
|
|
3792
3871
|
|
|
3793
3872
|
// ../core/dist/version.js
|
|
3794
|
-
var PACKAGE_VERSION = true ? "1.6.
|
|
3873
|
+
var PACKAGE_VERSION = true ? "1.6.1" : UNRELEASED_VERSION;
|
|
3795
3874
|
|
|
3796
3875
|
// ../core/dist/webhooks.js
|
|
3797
3876
|
var json4 = (status, body) => new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json" } });
|
|
@@ -4896,4 +4975,4 @@ export {
|
|
|
4896
4975
|
isTrackerStatus,
|
|
4897
4976
|
EasyPostAPI
|
|
4898
4977
|
};
|
|
4899
|
-
//# sourceMappingURL=chunk-
|
|
4978
|
+
//# sourceMappingURL=chunk-3QIW75OT.js.map
|