@crvouga/mockingbird-service-cognito 1.5.1 → 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 CHANGED
@@ -1,14 +1,24 @@
1
1
  # Changelog — @crvouga/mockingbird-service-cognito
2
2
 
3
- ## 1.5.1 (2026-09-30)
3
+ ## 1.6.1 (2026-09-30)
4
4
 
5
5
  ### Fixes and improvements
6
6
 
7
- - keep hosted pages inside narrow hosts and popups ([6512323](https://github.com/crvouga/mockingbird/commit/6512323198cb00b99005f3d2cfa5b9f1e6e321a7))
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)
12
+
13
+ ### Features
8
14
 
9
- ### Dependencies
15
+ - boot Bolt over Socket Mode ([01322df](https://github.com/crvouga/mockingbird/commit/01322df315c66b1f2f5b53094cbbeeeef6d3ae6c))
10
16
 
11
- - `@crvouga/mockingbird-service-sqlite`
17
+ ## 1.5.1 (2026-09-29)
18
+
19
+ ### Fixes and improvements
20
+
21
+ - keep hosted pages inside narrow hosts and popups ([6512323](https://github.com/crvouga/mockingbird/commit/6512323198cb00b99005f3d2cfa5b9f1e6e321a7))
12
22
 
13
23
  ## 1.5.0 (2026-09-29)
14
24
 
@@ -1940,6 +1940,50 @@ function bootAdmin(config) {
1940
1940
  if (render)
1941
1941
  await render();
1942
1942
  }
1943
+ const delay = (ms) => new Promise((resolve) => {
1944
+ window.setTimeout(resolve, ms);
1945
+ });
1946
+ const confirmAction = async (button, pending, done, work) => {
1947
+ if (button.dataset.pending === "1")
1948
+ return;
1949
+ const label = button.textContent ?? "";
1950
+ const width = button.offsetWidth;
1951
+ button.dataset.pending = "1";
1952
+ button.classList.add("pressed");
1953
+ button.setAttribute("aria-busy", "true");
1954
+ button.style.minWidth = `${width}px`;
1955
+ button.textContent = pending;
1956
+ try {
1957
+ await work();
1958
+ button.textContent = done;
1959
+ await delay(1e3);
1960
+ } catch (error) {
1961
+ showError(error);
1962
+ } finally {
1963
+ button.textContent = label;
1964
+ button.style.minWidth = "";
1965
+ button.classList.remove("pressed");
1966
+ button.removeAttribute("aria-busy");
1967
+ delete button.dataset.pending;
1968
+ }
1969
+ };
1970
+ document.addEventListener("click", (event) => {
1971
+ const target = event.target;
1972
+ if (!(target instanceof Element))
1973
+ return;
1974
+ const button = target.closest("button");
1975
+ if (!(button instanceof HTMLButtonElement) || button.dataset.pending === "1")
1976
+ return;
1977
+ button.classList.add("pressed");
1978
+ const token = String(Date.now());
1979
+ button.dataset.press = token;
1980
+ window.setTimeout(() => {
1981
+ if (button.dataset.press !== token || button.dataset.pending === "1")
1982
+ return;
1983
+ button.classList.remove("pressed");
1984
+ delete button.dataset.press;
1985
+ }, 450);
1986
+ });
1943
1987
  el("namespace", HTMLSelectElement).addEventListener("change", () => {
1944
1988
  state.namespace = el("namespace", HTMLSelectElement).value;
1945
1989
  refresh().catch(showError);
@@ -1950,7 +1994,7 @@ function bootAdmin(config) {
1950
1994
  refresh().catch(showError);
1951
1995
  });
1952
1996
  el("refresh", HTMLButtonElement).addEventListener("click", () => {
1953
- refresh().catch(showError);
1997
+ confirmAction(el("refresh", HTMLButtonElement), "Refreshing...", "Updated", () => refresh()).catch(showError);
1954
1998
  });
1955
1999
  el("collections", HTMLElement).addEventListener("click", (event) => {
1956
2000
  const target = event.target;
@@ -2073,10 +2117,10 @@ function bootAdmin(config) {
2073
2117
  }).then(() => renderFaults()).catch(showError);
2074
2118
  });
2075
2119
  el("fault-clear", HTMLButtonElement).addEventListener("click", () => {
2076
- api("DELETE", "/faults").then(() => renderFaults()).catch(showError);
2120
+ confirmAction(el("fault-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/faults").then(() => renderFaults())).catch(showError);
2077
2121
  });
2078
2122
  el("journal-clear", HTMLButtonElement).addEventListener("click", () => {
2079
- api("DELETE", "/requests").then(() => renderJournal()).catch(showError);
2123
+ confirmAction(el("journal-clear", HTMLButtonElement), "Clearing...", "Cleared", () => api("DELETE", "/requests").then(() => renderJournal())).catch(showError);
2080
2124
  });
2081
2125
  el("route-list", HTMLElement).addEventListener("click", (event) => {
2082
2126
  const target = event.target;
@@ -2191,9 +2235,13 @@ function bootAdmin(config) {
2191
2235
  var clientPrelude = [isRecord2, mountAdminBrand, startAdminBrand, faultPresetList, bootAdmin].map((fn) => fn.toString()).join("\n");
2192
2236
  var adminClientSource = (config) => {
2193
2237
  const payload = JSON.stringify(config).replace(/</g, "\\u003c");
2238
+ const entry = bootAdmin.name;
2239
+ if (!/^[A-Za-z_$][\w$]*$/.test(entry)) {
2240
+ throw new Error("admin client cannot call its boot function");
2241
+ }
2194
2242
  return `<script>
2195
2243
  ${clientPrelude}
2196
- bootAdmin(${payload});
2244
+ ${entry}(${payload});
2197
2245
  </script>`;
2198
2246
  };
2199
2247
 
@@ -2407,9 +2455,24 @@ var renderAdminDocument = (service) => {
2407
2455
  .controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
2408
2456
  label.field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--faint); }
2409
2457
  label.field input, label.field select, .controls input[type="password"] {
2410
- background: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
2411
- padding: 7px 8px; min-height: 36px;
2412
- }
2458
+ background-color: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;
2459
+ padding: 7px 8px; min-height: 36px; line-height: 1.2;
2460
+ }
2461
+ /* A native menu ignores min-height, so Preset rendered about half as tall as
2462
+ the text fields in the same form. Paint it like those fields. */
2463
+ label.field select {
2464
+ -webkit-appearance: none; appearance: none;
2465
+ padding-right: 28px;
2466
+ 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");
2467
+ background-repeat: no-repeat; background-position: right 10px center; background-size: 12px 12px;
2468
+ }
2469
+ .stack > .field > input,
2470
+ .stack > .field > select,
2471
+ .stack > .field > textarea,
2472
+ dialog .field > input,
2473
+ dialog .field > select,
2474
+ dialog .field > textarea { width: 100%; }
2475
+ .icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger, nav.side button { cursor: pointer; }
2413
2476
  .icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger {
2414
2477
  border-radius: 9px; min-height: 36px; padding: 0 12px; border: 1px solid var(--line);
2415
2478
  background: var(--bg-elev);
@@ -2417,6 +2480,14 @@ var renderAdminDocument = (service) => {
2417
2480
  .btn-primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
2418
2481
  .btn-quiet { background: transparent; }
2419
2482
  .btn-danger { color: var(--err); }
2483
+ /* Held after mouseup. Clearing an empty journal changes nothing on screen,
2484
+ so the press itself has to stay visible. */
2485
+ .icon-btn:active, .btn:active, .btn-quiet:active, .btn-danger:active, nav.side button:active,
2486
+ .icon-btn.pressed, .btn.pressed, .btn-quiet.pressed, .btn-danger.pressed, nav.side button.pressed {
2487
+ background: var(--bg-inset); border-color: var(--line-strong); color: var(--ink);
2488
+ }
2489
+ .btn-danger:active, .btn-danger.pressed { background: var(--err-soft); color: var(--err); }
2490
+ .btn-primary:active, .btn-primary.pressed { filter: brightness(0.88); color: var(--accent-ink); }
2420
2491
  /* minmax(0, 1fr): a 1fr column will not shrink below its content, so a long
2421
2492
  record or the full nav row would widen the page past the viewport. */
2422
2493
  .layout {
@@ -2505,8 +2576,16 @@ var renderAdminDocument = (service) => {
2505
2576
  input, select, textarea { font-size: 16px; }
2506
2577
  .brand, .vendor, .controls { width: 100%; }
2507
2578
  label.field, label.field select, label.field input { flex: 1; min-width: 0; }
2508
- .layout { grid-template-columns: minmax(0, 1fr); }
2579
+ /* The layout fills the screen. A single-column grid stretches every auto
2580
+ row, so the tab bar grew with the leftover height and the buttons floated
2581
+ in the middle of it. The bar stays one row; the page below takes the rest. */
2582
+ .layout {
2583
+ grid-template-columns: minmax(0, 1fr);
2584
+ grid-template-rows: auto minmax(0, 1fr);
2585
+ align-content: start;
2586
+ }
2509
2587
  nav.side {
2588
+ align-self: start; height: auto;
2510
2589
  flex-direction: row; align-items: center; overflow-x: auto; min-width: 0;
2511
2590
  border-right: 0; border-bottom: 1px solid var(--line);
2512
2591
  padding: 8px;
@@ -3604,7 +3683,7 @@ var stateAdminRoutes = (routes) => {
3604
3683
  };
3605
3684
 
3606
3685
  // ../core/dist/version.js
3607
- var PACKAGE_VERSION = true ? "1.5.1" : UNRELEASED_VERSION;
3686
+ var PACKAGE_VERSION = true ? "1.6.1" : UNRELEASED_VERSION;
3608
3687
 
3609
3688
  // ../core/dist/webhooks.js
3610
3689
  var json4 = (status, body) => new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json" } });
@@ -4884,4 +4963,4 @@ export {
4884
4963
  accessKeyCredential,
4885
4964
  CognitoAPI
4886
4965
  };
4887
- //# sourceMappingURL=chunk-DNTF6HMV.js.map
4966
+ //# sourceMappingURL=chunk-7M34ZH6D.js.map