@tokenoftrust/storefront-runner 2.4.64 → 2.4.66

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.
@@ -1,7 +1,6 @@
1
1
  export { getOrdersViewModel } from "./orders";
2
2
  export { getProductsViewModel } from "./products";
3
3
  export { getCustomersViewModel } from "./customers";
4
- export { getFulfillmentViewModel } from "./fulfillment";
5
4
  export { getReportingViewModel } from "./reporting";
6
5
  export { getSettingsViewModel } from "./settings";
7
6
  export { getCheckoutSettingsViewModel } from "./checkoutSettings";
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * Daily batch desk. Queues, evidence, and commands are a pure projection of the
3
- * commerce contract. The test adapter is not a carrier and does not buy postage.
4
- * Print payload and tracking links are owner-only. Public events and the desk
5
- * log never carry a destination.
3
+ * commerce contract. Print payload and tracking links are owner-only. Public
4
+ * events and the desk log never carry a destination.
6
5
  */
7
6
  import {
8
7
  actorMayCommand,
@@ -224,25 +223,6 @@ export interface WorkspaceCommand {
224
223
  quantityInvalid: boolean;
225
224
  lineId: boolean;
226
225
  exception: string | null;
227
- accountConfigured: boolean | null;
228
- }
229
-
230
- export interface WorkspaceHttpRequest {
231
- method: string;
232
- url: string;
233
- body: string | null;
234
- }
235
-
236
- export interface WorkspaceHttpResponse {
237
- status: number;
238
- contentType: string;
239
- body: string;
240
- }
241
-
242
- export interface TestFulfillmentAdapter {
243
- readonly livePurchase: false;
244
- state(): WorkspaceState;
245
- handle(request: WorkspaceHttpRequest): WorkspaceHttpResponse;
246
226
  }
247
227
 
248
228
  export function defaultWorkspaceQuery(): WorkspaceQuery {
@@ -842,17 +822,6 @@ export function applyWorkspaceCommand(input: WorkspaceState, command: WorkspaceC
842
822
  ids.map((orderId) => blankResult(command.command, orderId, "refused", "partial-shipment")),
843
823
  );
844
824
  }
845
- if (command.command === "set-carrier-account") {
846
- const carrierReason = explicitCarrierReason(command.carrier);
847
- if (carrierReason) return finishCommand(state, command.actorName, [blankResult(command.command, "", "refused", carrierReason)]);
848
- if (command.accountConfigured === null) {
849
- return finishCommand(state, command.actorName, [blankResult(command.command, "", "refused", "carrier-account")]);
850
- }
851
- state.carrierAccountConfigured = command.accountConfigured;
852
- return finishCommand(state, command.actorName, [
853
- blankResult(command.command, "", "admitted", command.accountConfigured ? "configured" : "missing"),
854
- ]);
855
- }
856
825
  if (command.orderIds.length === 0) {
857
826
  return finishCommand(state, command.actorName, [blankResult(command.command, "", "refused", "empty-batch")]);
858
827
  }
@@ -883,7 +852,6 @@ const COMMANDS = new Set([
883
852
  "pick-batch",
884
853
  "packing-slip",
885
854
  "record-exception",
886
- "set-carrier-account",
887
855
  "refund",
888
856
  "return",
889
857
  ]);
@@ -922,8 +890,6 @@ export function parseWorkspaceCommand(params: URLSearchParams): { ok: true; comm
922
890
  else quantity = Number(raw);
923
891
  }
924
892
  }
925
- const configuredRaw = params.get("configured");
926
- const accountConfigured = configuredRaw === "1" ? true : configuredRaw === "0" ? false : null;
927
893
  const carrierRaw = params.get("carrier");
928
894
  const purchaseRaw = params.get("purchaseKey");
929
895
  return {
@@ -938,66 +904,6 @@ export function parseWorkspaceCommand(params: URLSearchParams): { ok: true; comm
938
904
  quantityInvalid,
939
905
  lineId: params.has("lineId"),
940
906
  exception: params.get("exception"),
941
- accountConfigured,
942
- },
943
- };
944
- }
945
-
946
- export function handleWorkspaceRequest(
947
- state: WorkspaceState,
948
- request: WorkspaceHttpRequest,
949
- ): { state: WorkspaceState; response: WorkspaceHttpResponse } {
950
- let url: URL;
951
- try {
952
- url = new URL(request.url, "http://127.0.0.1");
953
- } catch {
954
- return { state, response: { status: 400, contentType: "text/plain; charset=utf-8", body: "bad url" } };
955
- }
956
- if (url.pathname !== SCRAPPY_FULFILLMENT_PATH) {
957
- return { state, response: { status: 404, contentType: "text/plain; charset=utf-8", body: "not found" } };
958
- }
959
- const method = request.method.toUpperCase();
960
- if (method === "GET") {
961
- const view = projectWorkspace(state, parseWorkspaceQuery(url.searchParams));
962
- return {
963
- state,
964
- response: { status: 200, contentType: "text/html; charset=utf-8", body: renderFulfillmentDocument(view) },
965
- };
966
- }
967
- if (method === "POST") {
968
- const params = new URLSearchParams(request.body ?? "");
969
- const parsed = parseWorkspaceCommand(params);
970
- if (!parsed.ok) {
971
- return {
972
- state,
973
- response: {
974
- status: 400,
975
- contentType: "text/html; charset=utf-8",
976
- body: `<!doctype html><p data-command-error="${esc(parsed.error)}">Unknown command.</p>`,
977
- },
978
- };
979
- }
980
- const next = applyWorkspaceCommand(state, parsed.command);
981
- const query = parseWorkspaceQuery(params);
982
- query.cursor = null;
983
- const view = projectWorkspace(next, query);
984
- return {
985
- state: next,
986
- response: { status: 200, contentType: "text/html; charset=utf-8", body: renderFulfillmentDocument(view) },
987
- };
988
- }
989
- return { state, response: { status: 405, contentType: "text/plain; charset=utf-8", body: "method" } };
990
- }
991
-
992
- export function createTestFulfillmentAdapter(tenantId = "synthetic-tenant", stage: CommerceStage = "preview"): TestFulfillmentAdapter {
993
- let state = initialWorkspaceState(tenantId, stage);
994
- return {
995
- livePurchase: false,
996
- state: () => state,
997
- handle(request) {
998
- const outcome = handleWorkspaceRequest(state, request);
999
- state = outcome.state;
1000
- return outcome.response;
1001
907
  },
1002
908
  };
1003
909
  }
@@ -1041,10 +947,6 @@ function hiddenFields(view: FulfillmentViewModel, command: string, extras: Array
1041
947
  .join("");
1042
948
  }
1043
949
 
1044
- function resultItem(result: WorkspaceResult): string {
1045
- return `<li data-result-order="${esc(result.orderId)}" data-result-command="${esc(result.command)}" data-result-status="${result.status}" data-result-reason="${esc(result.reason)}" data-cost-minor="${result.costMinor ?? ""}" data-purchase-id="${esc(result.purchaseId ?? "")}" data-live-purchase="false" data-release-reservation="${result.releaseReservation ? "true" : "false"}" data-restock="false" data-blind-repurchase="false">${esc(result.command)} ${esc(result.orderId)} ${result.status} ${esc(result.reason)}</li>`;
1046
- }
1047
-
1048
950
  function orderActions(view: FulfillmentViewModel, order: WorkspaceOrderView, action: string): string {
1049
951
  const purchaseExtras: Array<[string, string]> = [["orderId", order.id]];
1050
952
  if (order.purchaseKey !== null) purchaseExtras.push(["purchaseKey", order.purchaseKey]);
@@ -1075,10 +977,6 @@ export function renderFulfillmentWorkspace(view: FulfillmentViewModel): string {
1075
977
  return `<a data-queue-link="${queue}" href="${esc(href(view, { queue, cursor: null }))}">${esc(label)}${count}</a>`;
1076
978
  })
1077
979
  .join("");
1078
- const actorLinks = ACTOR_SPECS.map(
1079
- (spec) =>
1080
- `<a data-actor-link="${spec.name}" href="${esc(href(view, { actorName: spec.name, cursor: null }))}">${esc(spec.name)}</a>`,
1081
- ).join("");
1082
980
  const action = esc(href(view, { cursor: null }));
1083
981
  const rows = view.orders
1084
982
  .map((order) => {
@@ -1134,12 +1032,11 @@ export function renderFulfillmentWorkspace(view: FulfillmentViewModel): string {
1134
1032
  ? `<a data-page-next href="${esc(href(view, { cursor: view.nextCursor }))}">Next page</a>`
1135
1033
  : "";
1136
1034
  const account = view.carrierAccountConfigured ? "configured" : "missing";
1137
- return `<div data-scrappy-batch data-target-tenant="${esc(view.targetTenant)}" data-test-adapter="1" data-live-purchase="false" data-carrier-account="${account}" data-prohibited-carrier="USPS" data-adult-signature-required="true" data-partial-shipment="unavailable" data-returns="unavailable" data-blind-repurchase="false" data-actor="${esc(view.actorName)}" data-actor-role="${esc(view.actorRole)}" data-storewide-ready="${view.storewide.ready}" data-storewide-held="${view.storewide.held}" data-storewide-in-progress="${view.storewide.in_progress}" data-storewide-shipped="${view.storewide.shipped}" data-filter-count="${view.filterCount}" data-page-count="${view.pageCount}" data-queue="${esc(view.queue)}">
1035
+ return `<div data-scrappy-batch data-target-tenant="${esc(view.targetTenant)}" data-live-purchase="false" data-carrier-account="${account}" data-prohibited-carrier="USPS" data-adult-signature-required="true" data-partial-shipment="unavailable" data-returns="unavailable" data-blind-repurchase="false" data-actor="${esc(view.actorName)}" data-actor-role="${esc(view.actorRole)}" data-storewide-ready="${view.storewide.ready}" data-storewide-held="${view.storewide.held}" data-storewide-in-progress="${view.storewide.in_progress}" data-storewide-shipped="${view.storewide.shipped}" data-filter-count="${view.filterCount}" data-page-count="${view.pageCount}" data-queue="${esc(view.queue)}">
1138
1036
  <h2 id="fulfillment-title">Daily batch</h2>
1139
- <p>This desk reads the test adapter. Not a live label purchase. Carrier account is configuration. USPS is prohibited. Adult signature is required. Shipment is the whole order. Partial shipment is not available. Returns are not automated.</p>
1037
+ <p>Not a live label purchase. Carrier account is configuration. USPS is prohibited. Adult signature is required. Shipment is the whole order. Partial shipment is not available. Returns are not automated.</p>
1140
1038
  <p data-carrier-account-text>${view.carrierAccountConfigured ? "Carrier account: configured." : "Carrier account: not configured. Do not choose a carrier."}</p>
1141
1039
  <p><a data-refresh href="${esc(href(view))}">Refresh</a></p>
1142
- <nav data-actor-switch>${actorLinks}</nav>
1143
1040
  <nav data-queue-switch>${queueLinks}</nav>
1144
1041
  <form method="get" action="${SCRAPPY_FULFILLMENT_PATH}">
1145
1042
  <input type="hidden" name="actor" value="${esc(view.actorName)}">
@@ -1164,12 +1061,5 @@ export function renderFulfillmentWorkspace(view: FulfillmentViewModel): string {
1164
1061
  ${next}
1165
1062
  <section data-pick-list><h3>Pick list</h3><ul>${pickItems}</ul></section>
1166
1063
  ${details}
1167
- <ol data-last-results>${view.lastResults.map(resultItem).join("")}</ol>
1168
- <section data-public-events>${view.events.map((event) => `<pre>${esc(JSON.stringify(event))}</pre>`).join("")}</section>
1169
- <pre data-adapter-log>${esc(view.log.join("\n"))}</pre>
1170
1064
  </div>`;
1171
1065
  }
1172
-
1173
- export function renderFulfillmentDocument(view: FulfillmentViewModel): string {
1174
- return `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Daily batch</title></head><body><section id="fulfillment" data-admin-panel data-agent-scope="fulfillment">${renderFulfillmentWorkspace(view)}</section></body></html>`;
1175
- }
@@ -66,9 +66,7 @@ export class CommerceAlarmDispatcher {
66
66
  }
67
67
 
68
68
  export async function getReliableDispatcher(): Promise<CommerceAlarmDispatcher | Response> {
69
- const scheduler = await readEnv("SCRAPPY_COMMERCE_SCHEDULER");
70
- if (scheduler !== COMMERCE_SCHEDULER) return json({ error: "commerce scheduler not configured" }, 503);
71
69
  const d1 = await readD1("STOREFRONT_APPS_DB");
72
70
  if (!d1) return json({ error: "commerce scheduler not configured" }, 503);
73
- return new CommerceAlarmDispatcher(fromD1(d1), scheduler);
71
+ return new CommerceAlarmDispatcher(fromD1(d1), COMMERCE_SCHEDULER);
74
72
  }
@@ -11,7 +11,6 @@
11
11
  import type { APIContext } from "astro";
12
12
  import { requireAdminApiEntry } from "@/lib/auth/adminApiGuard";
13
13
  import { workerCommit } from "@/lib/activity/workerCommit";
14
- import { readEnv } from "@/lib/env";
15
14
  import {
16
15
  COMMERCE_SCHEDULER,
17
16
  actorMayCommand,
@@ -107,8 +106,7 @@ export function admitAdminReplay(input: {
107
106
  export async function GET(context: APIContext): Promise<Response> {
108
107
  const access = await requireAdminApiEntry(context, { requireOwner: true });
109
108
  if (!access.ok) return json({ ok: false, reason: access.reason }, access.status);
110
- const scheduler = await readEnv("SCRAPPY_COMMERCE_SCHEDULER");
111
- return json({ ok: true, report: projectAdminReadiness({ scheduler, deployedSha: workerCommit() }) });
109
+ return json({ ok: true, report: projectAdminReadiness({ scheduler: COMMERCE_SCHEDULER, deployedSha: workerCommit() }) });
112
110
  }
113
111
 
114
112
  export async function POST(context: APIContext): Promise<Response> {
@@ -133,13 +131,12 @@ export async function POST(context: APIContext): Promise<Response> {
133
131
  if (!OPAQUE.test(record.orderId) || !OPAQUE.test(record.sourceEventId)) return json({ ok: false, reason: "refused" }, 400);
134
132
  const decision = admitAdminReplay({ tenantId: context.locals.tenant.tenant_id, stage, kind });
135
133
  if (!decision.admitted) return json({ ok: false, reason: decision.reason }, 403);
136
- const scheduler = await readEnv("SCRAPPY_COMMERCE_SCHEDULER");
137
134
  return json({
138
135
  ok: true,
139
136
  admitted: true,
140
137
  durableWrite: false,
141
138
  command: "reconcile",
142
139
  reason: decision.reason,
143
- report: projectAdminReadiness({ scheduler, deployedSha: workerCommit() }),
140
+ report: projectAdminReadiness({ scheduler: COMMERCE_SCHEDULER, deployedSha: workerCommit() }),
144
141
  });
145
142
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenoftrust/storefront-runner",
3
- "version": "2.4.64",
3
+ "version": "2.4.66",
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",
@@ -1,19 +0,0 @@
1
- import type { AdminTenantEnvelope } from "../../envelope";
2
- import { memoizeByEnvelope } from "../../memoizeByEnvelope";
3
- import {
4
- defaultWorkspaceQuery,
5
- initialWorkspaceState,
6
- projectWorkspace,
7
- type FulfillmentViewModel,
8
- } from "../../viewmodels/fulfillment";
9
-
10
- /** Initial test-adapter snapshot. Not a seeded queue and not a live order feed. */
11
- export function readTestAdapterSnapshot(targetTenant: string): FulfillmentViewModel {
12
- return projectWorkspace(initialWorkspaceState(targetTenant), defaultWorkspaceQuery());
13
- }
14
-
15
- function computeFulfillmentViewModel(envelope: AdminTenantEnvelope): FulfillmentViewModel {
16
- return readTestAdapterSnapshot(envelope.targetTenant);
17
- }
18
-
19
- export const getFulfillmentViewModel = memoizeByEnvelope(computeFulfillmentViewModel);