@tokenoftrust/storefront-runner 2.4.84 → 2.4.85

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.
@@ -81,8 +81,8 @@ lib/admin/
81
81
  testable source of truth for what the floating Ask button emits — the full
82
82
  tenant envelope, active tab, selected record id (if any), role +
83
83
  permissions (derived from `isStaff`), active filters, and evidence context.
84
- `admin.astro`'s `is:inline` script mirrors this logic in plain JS (inline
85
- scripts can't import modules) and emits it on Ask-button click as
84
+ The processed `adminShell.ts` client imports this builder and emits its
85
+ result on Ask-button click as
86
86
  `window.__toTAdminAsk` and a `tot:admin-ask` `CustomEvent` — **dev-inspectable
87
87
  only, no chat backend yet.** The envelope changes whenever the active tab
88
88
  changes (kept current by `setAskContext`) and is rebuilt fresh on click so a
@@ -117,6 +117,6 @@ const orders = getOrdersViewModel({
117
117
  - **Tabs/pages → lib, never lib → tabs/pages.** Nothing under `lib/admin/**`
118
118
  imports from `components/admin/**` or `pages/admin.astro`. Tab components
119
119
  and `admin.astro` are free to import from here (`admin.astro` already does,
120
- for `resolveAdminTenantMode` and the Ask-envelope logic it mirrors inline).
120
+ for `resolveAdminTenantMode` and the shared shell configuration).
121
121
  - Gaps in these contracts should go back to the workstream board as a
122
122
  decision, not get patched from a tab's unit.
@@ -4,7 +4,7 @@
4
4
  * the tablists. Imported from a processed `<script>` in admin.astro (ADR 0013):
5
5
  * type-checked, bundled, tree-shaken, and its bundle hash is in the enforced
6
6
  * CSP. The Ask envelope is built with the shared, unit-tested
7
- * `buildAskEnvelope` (ai/askEnvelope) instead of a hand-copied inline mirror.
7
+ * `buildAskEnvelope` (ai/askEnvelope).
8
8
  *
9
9
  * There is no chat backend yet — the Ask envelope is emitted for dev inspection
10
10
  * only (window.__toTAdminAsk + a "tot:admin-ask" CustomEvent), never sent over
@@ -12,33 +12,23 @@
12
12
  */
13
13
  import { buildAskEnvelope, type AskEnvelope } from "./ai/askEnvelope";
14
14
 
15
- const TAB_IDS = [
16
- "orders",
17
- "products",
18
- "subscriptions",
19
- "customers",
20
- "fulfillment",
21
- "reporting",
22
- "ai-workflows",
23
- "blog",
24
- "publish",
25
- "integrations",
26
- "settings",
27
- ] as const;
28
-
29
- const ASK_CONTEXTS: Record<string, string> = {
30
- orders: "Orders",
31
- products: "Products",
32
- subscriptions: "Subscriptions",
33
- customers: "Customers",
34
- fulfillment: "Fulfillment",
35
- reporting: "Reporting",
36
- "ai-workflows": "AI Workflows",
37
- blog: "Blog",
38
- publish: "Publish",
39
- integrations: "Integrations",
40
- settings: "Settings",
41
- };
15
+ /** Static shell data shared by server-rendered navigation and browser startup. */
16
+ export const ADMIN_SHELL_CONFIG = {
17
+ workAreas: [
18
+ { id: "orders", label: "Orders", icon: "i-file" },
19
+ { id: "products", label: "Products", icon: "i-box" },
20
+ { id: "subscriptions", label: "Subscriptions", icon: "i-refresh" },
21
+ { id: "customers", label: "Customers", icon: "i-users" },
22
+ { id: "fulfillment", label: "Fulfillment", icon: "i-truck" },
23
+ { id: "reporting", label: "Reporting", icon: "i-chart" },
24
+ { id: "ai-workflows", label: "AI Workflows", icon: "i-workflows" },
25
+ { id: "blog", label: "Blog", icon: "i-file" },
26
+ { id: "publish", label: "Publish", icon: "i-export" },
27
+ { id: "integrations", label: "Integrations", icon: "i-workflows" },
28
+ { id: "settings", label: "Settings", icon: "i-gear" },
29
+ ],
30
+ defaultTabs: { staff: "orders", merchant: "settings" },
31
+ } as const;
42
32
 
43
33
  declare global {
44
34
  interface Window {
@@ -47,11 +37,13 @@ declare global {
47
37
  }
48
38
 
49
39
  export function initAdminShell(): void {
50
- const tabSet = new Set<string>(TAB_IDS);
51
- const tabHashPattern = new RegExp(`^#(${TAB_IDS.join("|")})$`);
40
+ const tabIds = ADMIN_SHELL_CONFIG.workAreas.map(({ id }) => id);
41
+ const tabSet = new Set<string>(tabIds);
42
+ const tabHashPattern = new RegExp(`^#(${tabIds.join("|")})$`);
52
43
  const canViewInternalGuide =
53
44
  document.documentElement.dataset.internalAdminGuide === "true";
54
- const defaultTab = canViewInternalGuide ? "orders" : "settings";
45
+ const defaultTab =
46
+ ADMIN_SHELL_CONFIG.defaultTabs[canViewInternalGuide ? "staff" : "merchant"];
55
47
 
56
48
  const buildAskEnvelopeForTab = (id: string): AskEnvelope => {
57
49
  const root = document.documentElement.dataset;
@@ -74,7 +66,9 @@ export function initAdminShell(): void {
74
66
  };
75
67
 
76
68
  const setAskContext = (id: string): void => {
77
- const label = ASK_CONTEXTS[id] ?? "Storefront";
69
+ const label =
70
+ ADMIN_SHELL_CONFIG.workAreas.find((area) => area.id === id)?.label ??
71
+ "Storefront";
78
72
  const askButton = document.querySelector<HTMLElement>("[data-admin-ask]");
79
73
  const askContext = document.querySelector<HTMLElement>(
80
74
  "[data-admin-ask-context]",
@@ -196,7 +190,7 @@ export function initAdminShell(): void {
196
190
  // normalized away to #settings for merchant viewers.
197
191
  const hashTab = window.location.hash.slice(1).split("?")[0] ?? "";
198
192
  if (!canViewInternalGuide && !tabSet.has(hashTab)) {
199
- history.replaceState(null, "", "#settings");
193
+ history.replaceState(null, "", `#${defaultTab}`);
200
194
  }
201
195
  if (scroll) requestAnimationFrame(() => scrollToHashTarget(panelId));
202
196
  return;
@@ -229,12 +223,6 @@ export function initAdminShell(): void {
229
223
  const envelope = buildAskEnvelopeForTab(activeTab);
230
224
  window.__toTAdminAsk = envelope;
231
225
  document.dispatchEvent(new CustomEvent("tot:admin-ask", { detail: envelope }));
232
- if (
233
- window.location.hostname === "localhost" ||
234
- window.location.hostname === "127.0.0.1"
235
- ) {
236
- console.debug("[admin:ask]", envelope);
237
- }
238
226
  });
239
227
 
240
228
  document.addEventListener("click", (event) => {
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * The floating `Ask` button's context envelope (baseline §Horizontal AI
3
3
  * Concepts / Ask; ai-evidence-substrate item a). PURE + no I/O so it is
4
- * unit-testable and reusable from both the inline admin.astro script (via a
5
- * plain-object mirror, since `is:inline` scripts cannot import modules) and
4
+ * unit-testable and reusable from the processed adminShell.ts client and
6
5
  * any future server-side Ask route. There is no chat backend yet — today
7
- * this is emitted for dev inspection only (see admin.astro's `data-admin-ask`
6
+ * this is emitted for dev inspection only (see adminShell.ts's `data-admin-ask`
8
7
  * click handler), never sent over the network.
9
8
  */
10
9
  import type { AdminTenantEnvelope } from "../envelope";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenoftrust/storefront-runner",
3
- "version": "2.4.84",
3
+ "version": "2.4.85",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
6
6
  "packageManager": "pnpm@11.9.0",