@receiz/sdk 97.0.0 → 97.2.0

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/README.md CHANGED
@@ -205,27 +205,120 @@ Receiz apps can publish durable public app-state projections without adding Supa
205
205
  import {
206
206
  RECEIZ_PUBLIC_STORE_STATE_PROJECTION_SCHEMA,
207
207
  createReceizClient,
208
+ createReceizPublicStoreStateRecord,
208
209
  } from "@receiz/sdk";
209
210
 
210
211
  const receiz = createReceizClient({ accessToken });
211
212
 
212
- await receiz.appState.publishRecord({
213
+ await receiz.appState.publishRecord(createReceizPublicStoreStateRecord({
213
214
  sourceUrl: "bjklock.receiz.app",
214
215
  externalCreatorId: "bjklock.receiz.id",
215
216
  title: "BJ Klock storefront",
216
- platform: "Receiz.app Commerce Cloud",
217
- schema: RECEIZ_PUBLIC_STORE_STATE_PROJECTION_SCHEMA,
218
217
  data: { storeStateRecord },
218
+ }));
219
+
220
+ const restored = await createReceizClient().appState.restoreByHost<{
221
+ storeStateRecord: StoreStateRecord;
222
+ }>("bjklock.receiz.app", {
223
+ schema: RECEIZ_PUBLIC_STORE_STATE_PROJECTION_SCHEMA,
224
+ state: "published",
225
+ requiredDataKey: "storeStateRecord",
219
226
  });
220
227
 
221
- const restored = await createReceizClient().appState.byHost("bjklock.receiz.app");
222
- renderStorefront(restored.record?.data?.storeStateRecord);
228
+ if (restored.ok && restored.data) renderStorefront(restored.data.storeStateRecord);
223
229
  ```
224
230
 
225
231
  `receiz.appState.publish(feed)` remains available for batch writes. `receiz.publicProof.registryFeed(feed)` remains available and aliases the same publish path for existing integrations.
232
+ Raw reads remain available through `byUrl()`, `byHost()`, `byCreator()`, `byNamespace()`, and `byId()` when an app needs the full public projection envelope instead of direct restored data.
226
233
 
227
234
  Full quickstart: `docs/app-state-public-projections.md`.
228
235
 
236
+ ## Receiz App Runtime Rails
237
+
238
+ `@receiz/sdk@97.2.0` adds the enterprise runtime rails for Commerce Cloud style apps. These helpers compose existing Receiz primitives; they do not replace proof objects, local proof memory, Connect, or the public app-state projection rail.
239
+
240
+ ```ts
241
+ import { createReceizClient } from "@receiz/sdk";
242
+
243
+ const receiz = createReceizClient({ accessToken });
244
+
245
+ const doctor = await receiz.doctor({
246
+ tenantHost: "bjklock.receiz.app",
247
+ callbackUrl: "https://bjklock.receiz.app/api/auth/receiz/callback",
248
+ scopes: ["openid", "profile", "receiz:record", "receiz:wallet.read"],
249
+ });
250
+ if (!doctor.ok) console.table(doctor.fixes);
251
+
252
+ const caps = await receiz.capabilities({ tenantHost: "bjklock.receiz.app" });
253
+ if (caps.capabilities.commerce.available) {
254
+ await receiz.commerce.oneClickCheckout({
255
+ tenantHost: "bjklock.receiz.app",
256
+ orderId: "order_123",
257
+ amountUsd: "42.00",
258
+ walletFirst: true,
259
+ cardFallback: true,
260
+ idempotencyKey: "order_123",
261
+ });
262
+ }
263
+
264
+ await receiz.appState.publish({
265
+ tenantHost: "bjklock.receiz.app",
266
+ creatorReceizId: "bjklock.receiz.id",
267
+ title: "BJ Klock storefront",
268
+ state: { storeStateRecord },
269
+ idempotencyKey: "storefront_state_1",
270
+ });
271
+
272
+ const restored = await createReceizClient().appState.resolve({
273
+ host: "bjklock.receiz.app",
274
+ requiredDataKey: "storeStateRecord",
275
+ });
276
+ ```
277
+
278
+ Additional typed surfaces:
279
+
280
+ - `receiz.customers.session()`, `customers.portal()`, `customers.orders()`, `customers.rewards()`, `customers.assets()`
281
+ - `receiz.merchants.onboard()`, `merchants.profile()`, `merchants.capabilities()`
282
+ - `receiz.commerce.refunds`, `subscriptions`, `shipping`, `tax`, `discounts`, `giftCards`, `accessPasses`, `inventory`, `fulfillment`, `payouts`
283
+ - `receiz.media.upload(file, { tenantHost, purpose, idempotencyKey })`
284
+ - `receiz.media.transform({ mediaId, resize, optimize, blurPlaceholder, altText, metadata })`
285
+ - `receiz.domains.normalizeHost()`, `tenantUrl()`, `namespace()`, `objectId()`, `resolveTenant()`
286
+ - `receiz.events.subscribe()`, `events.replay()`, `events.list()`, `events.ack()`
287
+ - `receiz.proof.query({ namespace, tenantHost, type, customerReceizId })`
288
+ - `receiz.jobs.enqueue()`, `jobs.status()`, `jobs.cancel()`, `jobs.list()`
289
+ - `receiz.permissions.grant()`, `permissions.revoke()`, `permissions.check()`, `permissions.roles()`
290
+ - `receiz.audit.append()`, `audit.query()`, `audit.export()`
291
+ - `receiz.risk.scorePayment()`, `scoreAccountRecovery()`, `velocity()`, `proofActivity()`
292
+ - `receiz.compliance.exportOrders()`, `exportTaxes()`, `exportPayouts()`, `exportCustomers()`, `exportAudit()`
293
+ - `receiz.portability.exportStore()`, `portability.importStore()`
294
+ - `receiz.search.query()`, `products()`, `pages()`, `blog()`, `orders()`, `customers()`, `proofObjects()`
295
+ - `receiz.notifications.send()`, `notifications.subscribe()`, `notifications.templates()`
296
+ - `receiz.releases.pin()`, `releases.check()`, `releases.supported()`
297
+ - `receiz.sandbox.seedStore()`, `sandbox.wallet()`, `sandbox.checkout()`
298
+ - `receiz.offline.createQueue()`, `offline.createInMemoryStorage()`, `offline.createLocalStorage()`
299
+ - CLI: `receiz doctor`, `receiz dev`, `receiz deploy-check`, `receiz seed-store`, `receiz simulate-checkout`
300
+
301
+ React apps can import optional hooks and hosted component factories from `@receiz/sdk/react`:
302
+
303
+ ```ts
304
+ import {
305
+ ReceizCheckoutButton,
306
+ ReceizIdentityButton,
307
+ ReceizMediaUploader,
308
+ useReceizAppState,
309
+ useReceizCheckout,
310
+ } from "@receiz/sdk/react";
311
+
312
+ const storefront = useReceizAppState({
313
+ resolve: {
314
+ host: "bjklock.receiz.app",
315
+ requiredDataKey: "storeStateRecord",
316
+ },
317
+ });
318
+ ```
319
+
320
+ The React subpath is UI convenience. The core SDK client remains the primitive boundary, and proof objects / local proof memory remain stronger than component state.
321
+
229
322
  ## Sports Card And Event Proof Integration
230
323
 
231
324
  ```ts
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { dirname, join, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { assertReceizAssetManifest, assertReceizProofRegisterSnapshot, assertReceizSportsCardManifest, assertReceizWebhookEvent, createReceizInMemoryProofMemoryStorage, createReceizProofMemory, projectReceizAssetManifest, projectReceizSportsCardManifest, receizProofMemoryAdditionsQuery, } from "./index.js";
5
+ import { RECEIZ_SDK_VERSION, assertReceizAssetManifest, assertReceizProofRegisterSnapshot, assertReceizSportsCardManifest, assertReceizWebhookEvent, createReceizClient, createReceizInMemoryProofMemoryStorage, createReceizProofMemory, projectReceizAssetManifest, projectReceizSportsCardManifest, receizProofMemoryAdditionsQuery, } from "./index.js";
6
6
  const moduleDir = dirname(fileURLToPath(import.meta.url));
7
7
  const packageRoot = moduleDir.endsWith(`${join("packages", "receiz-sdk", "dist")}`)
8
8
  ? dirname(moduleDir)
@@ -19,6 +19,27 @@ function printError(error, detail) {
19
19
  function readJsonFile(path) {
20
20
  return JSON.parse(readFileSync(resolve(path), "utf8"));
21
21
  }
22
+ function optionValue(args, name) {
23
+ const index = args.indexOf(name);
24
+ if (index < 0)
25
+ return undefined;
26
+ const value = args[index + 1];
27
+ return value && !value.startsWith("--") ? value : undefined;
28
+ }
29
+ function optionNumber(args, name, fallback) {
30
+ const value = optionValue(args, name);
31
+ if (!value)
32
+ return fallback;
33
+ const parsed = Number(value);
34
+ return Number.isFinite(parsed) ? parsed : fallback;
35
+ }
36
+ function optionScopes(args) {
37
+ const raw = optionValue(args, "--scopes") ?? optionValue(args, "--scope") ?? "";
38
+ return raw
39
+ .split(/[,\s]+/)
40
+ .map((scope) => scope.trim())
41
+ .filter(Boolean);
42
+ }
22
43
  async function inspectProofObject(path) {
23
44
  const value = readJsonFile(path);
24
45
  const storage = createReceizInMemoryProofMemoryStorage();
@@ -188,9 +209,14 @@ Usage:
188
209
  receiz inspect <path-to-proof-json>
189
210
  receiz conformance
190
211
  receiz init <target-dir>
212
+ receiz doctor --tenant-host <host> [--access-token <token>] [--callback-url <url>] [--scopes <csv>]
213
+ receiz dev
214
+ receiz deploy-check --tenant-host <host>
215
+ receiz seed-store --tenant-host <host> [--products <count>]
216
+ receiz simulate-checkout --amount-usd <amount>
191
217
 
192
218
  This CLI uses local Receiz SDK validators, projections, and durable proof memory.
193
- It does not make network or database calls for inspect or conformance.
219
+ It does not make network or database calls for inspect, conformance, doctor, deploy-check, seed-store, or simulate-checkout.
194
220
  `);
195
221
  }
196
222
  async function main(argv) {
@@ -229,6 +255,84 @@ async function main(argv) {
229
255
  });
230
256
  return;
231
257
  }
258
+ if (command === "doctor") {
259
+ const clientOptions = {};
260
+ const accessToken = optionValue(args, "--access-token");
261
+ const baseUrl = optionValue(args, "--base-url");
262
+ if (accessToken)
263
+ clientOptions.accessToken = accessToken;
264
+ if (baseUrl)
265
+ clientOptions.baseUrl = baseUrl;
266
+ const client = createReceizClient(clientOptions);
267
+ const doctorOptions = {};
268
+ const tenantHost = optionValue(args, "--tenant-host");
269
+ const callbackUrl = optionValue(args, "--callback-url");
270
+ const scopes = optionScopes(args);
271
+ if (tenantHost)
272
+ doctorOptions.tenantHost = tenantHost;
273
+ if (callbackUrl)
274
+ doctorOptions.callbackUrl = callbackUrl;
275
+ if (scopes.length > 0)
276
+ doctorOptions.scopes = scopes;
277
+ const report = await client.doctor(doctorOptions);
278
+ printJson({
279
+ ...report,
280
+ schema: "receiz.sdk.cli.doctor.v1",
281
+ sdkVersion: RECEIZ_SDK_VERSION,
282
+ });
283
+ if (!report.ok)
284
+ process.exitCode = 1;
285
+ return;
286
+ }
287
+ if (command === "dev") {
288
+ printJson({
289
+ ok: true,
290
+ schema: "receiz.sdk.cli.dev.v1",
291
+ sdkVersion: RECEIZ_SDK_VERSION,
292
+ networkCalls: 0,
293
+ dbCalls: 0,
294
+ message: "Use the SDK sandbox helpers for deterministic local Receiz IDs, app state, wallet balances, checkout outcomes, webhooks, and proof objects.",
295
+ commands: ["receiz seed-store", "receiz simulate-checkout", "receiz doctor", "receiz inspect"],
296
+ });
297
+ return;
298
+ }
299
+ if (command === "deploy-check") {
300
+ const tenantHost = optionValue(args, "--tenant-host");
301
+ const checks = [
302
+ { code: "tenant_host_present", ok: Boolean(tenantHost), message: "tenantHost scopes app-state, domains, commerce, permissions, search, and jobs." },
303
+ { code: "sdk_version_pinned", ok: true, message: `@receiz/sdk ${RECEIZ_SDK_VERSION}` },
304
+ { code: "network_authority_required", ok: false, level: "info", message: "Deploy check is local. Production route availability is verified by receiz.doctor() and app capability probes." },
305
+ ];
306
+ printJson({
307
+ ok: checks.every((check) => check.ok || check.level === "info"),
308
+ schema: "receiz.sdk.cli.deploy_check.v1",
309
+ tenantHost: tenantHost ?? null,
310
+ checks,
311
+ });
312
+ return;
313
+ }
314
+ if (command === "seed-store") {
315
+ const tenantHost = optionValue(args, "--tenant-host");
316
+ if (!tenantHost) {
317
+ printError("missing_tenant_host", "Usage: receiz seed-store --tenant-host <host> [--products <count>]");
318
+ process.exitCode = 1;
319
+ return;
320
+ }
321
+ const client = createReceizClient();
322
+ printJson(client.sandbox.seedStore({ tenantHost, products: optionNumber(args, "--products", 3) }));
323
+ return;
324
+ }
325
+ if (command === "simulate-checkout") {
326
+ const amountUsd = optionValue(args, "--amount-usd");
327
+ if (!amountUsd) {
328
+ printError("missing_amount_usd", "Usage: receiz simulate-checkout --amount-usd <amount>");
329
+ process.exitCode = 1;
330
+ return;
331
+ }
332
+ const client = createReceizClient();
333
+ printJson(client.sandbox.checkout({ amountUsd, outcome: optionValue(args, "--outcome") === "failure" ? "failure" : "success" }));
334
+ return;
335
+ }
232
336
  printError("unknown_command", command);
233
337
  process.exitCode = 1;
234
338
  }