@receiz/sdk 96.2.0 → 97.1.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
@@ -201,34 +201,89 @@ Full quickstart: `docs/public-proof-rendering.md`.
201
201
 
202
202
  Receiz apps can publish durable public app-state projections without adding Supabase, Redis, Vercel KV, Shopify, or a custom database. Writes require delegated Connect/OIDC access with `receiz:record`; reads are public when the projection is public.
203
203
 
204
+ ```ts
205
+ import {
206
+ RECEIZ_PUBLIC_STORE_STATE_PROJECTION_SCHEMA,
207
+ createReceizClient,
208
+ createReceizPublicStoreStateRecord,
209
+ } from "@receiz/sdk";
210
+
211
+ const receiz = createReceizClient({ accessToken });
212
+
213
+ await receiz.appState.publishRecord(createReceizPublicStoreStateRecord({
214
+ sourceUrl: "bjklock.receiz.app",
215
+ externalCreatorId: "bjklock.receiz.id",
216
+ title: "BJ Klock storefront",
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",
226
+ });
227
+
228
+ if (restored.ok && restored.data) renderStorefront(restored.data.storeStateRecord);
229
+ ```
230
+
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.
233
+
234
+ Full quickstart: `docs/app-state-public-projections.md`.
235
+
236
+ ## Receiz App Runtime Rails
237
+
238
+ `@receiz/sdk@97.1.0` adds typed 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
+
204
240
  ```ts
205
241
  import { createReceizClient } from "@receiz/sdk";
206
242
 
207
243
  const receiz = createReceizClient({ accessToken });
208
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
+
209
264
  await receiz.appState.publish({
210
- schema: "receiz.app.public_store_state_registry_feed.v1",
211
- records: [
212
- {
213
- id: "store_state_id:bjklock.receiz.app",
214
- sourceUrl: "https://bjklock.receiz.app",
215
- externalCreatorId: "bjklock.receiz.id",
216
- title: "BJ Klock storefront",
217
- state: "published",
218
- platform: "Receiz.app Commerce Cloud",
219
- schema: "receiz.app.public_store_state_projection.v1",
220
- data: { storeStateRecord },
221
- },
222
- ],
265
+ tenantHost: "bjklock.receiz.app",
266
+ creatorReceizId: "bjklock.receiz.id",
267
+ title: "BJ Klock storefront",
268
+ state: { storeStateRecord },
269
+ idempotencyKey: "storefront_state_1",
223
270
  });
224
271
 
225
- const restored = await createReceizClient().appState.byUrl("https://bjklock.receiz.app/");
226
- renderStorefront(restored.record?.data?.storeStateRecord);
272
+ const restored = await createReceizClient().appState.resolve({
273
+ host: "bjklock.receiz.app",
274
+ requiredDataKey: "storeStateRecord",
275
+ });
227
276
  ```
228
277
 
229
- `receiz.publicProof.registryFeed(feed)` remains available and aliases the same publish path for existing integrations.
278
+ Additional typed surfaces:
230
279
 
231
- Full quickstart: `docs/app-state-public-projections.md`.
280
+ - `receiz.media.upload(file, { tenantHost, purpose, idempotencyKey })`
281
+ - `receiz.domains.normalizeHost()`, `tenantUrl()`, `namespace()`, `objectId()`, `resolveTenant()`
282
+ - `receiz.events.subscribe({ tenantHost, types, webhookUrl, idempotencyKey })`
283
+ - `receiz.proof.query({ namespace, tenantHost, type, customerReceizId })`
284
+ - `receiz.jobs.enqueue({ tenantHost, kind, payload, idempotencyKey })`
285
+ - `receiz.sandbox.seedStore()`, `sandbox.wallet()`, `sandbox.checkout()`
286
+ - CLI: `receiz doctor`, `receiz dev`, `receiz deploy-check`, `receiz seed-store`, `receiz simulate-checkout`
232
287
 
233
288
  ## Sports Card And Event Proof Integration
234
289
 
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
  }