@simpleapps-com/augur-server 0.2.5 → 0.2.6

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/dist/index.d.ts CHANGED
@@ -200,6 +200,8 @@ interface ItemActionsConfig {
200
200
  redisTtl?: number;
201
201
  /** Redis TTL for rarely-changing data in seconds. Default: 28800 (8 hours). */
202
202
  longRedisTtl?: number;
203
+ /** Sort category children by sequenceNo. Default: true. */
204
+ sortChildren?: boolean;
203
205
  }
204
206
  interface ItemActions {
205
207
  itemCategoryLookup: (path: string) => Promise<unknown>;
@@ -210,6 +212,7 @@ interface ItemActions {
210
212
  getInvMastDoc: (params: {
211
213
  invMastUid?: number;
212
214
  itemId?: string;
215
+ includePricing?: "Y" | "N";
213
216
  }) => Promise<TInvMastDoc>;
214
217
  getStock: (invMastUid: number) => Promise<TStockData[]>;
215
218
  getStockCompanySummary: (invMastUid: number) => Promise<Record<string, number>>;
package/dist/index.js CHANGED
@@ -239,8 +239,13 @@ function createItemActions(api, config = {}) {
239
239
  edgeCache = 1,
240
240
  longEdgeCache = 8,
241
241
  redisTtl = 3600,
242
- longRedisTtl = 28800
242
+ longRedisTtl = 28800,
243
+ sortChildren = true
243
244
  } = config;
245
+ function sortCategoryChildren(children) {
246
+ if (!sortChildren) return children;
247
+ return [...children].sort((a, b) => a.sequenceNo - b.sequenceNo);
248
+ }
244
249
  async function itemCategoryLookup(path) {
245
250
  return withServerCache(
246
251
  cachePrefix,
@@ -257,7 +262,7 @@ function createItemActions(api, config = {}) {
257
262
  );
258
263
  }
259
264
  async function getItemCategory(uid, options) {
260
- return withServerCache(
265
+ const category = await withServerCache(
261
266
  cachePrefix,
262
267
  redisTtl,
263
268
  "items.categories.get",
@@ -271,6 +276,10 @@ function createItemActions(api, config = {}) {
271
276
  uid,
272
277
  options
273
278
  );
279
+ return {
280
+ ...category,
281
+ children: sortCategoryChildren(category.children)
282
+ };
274
283
  }
275
284
  async function getCategoryItems(uid, filters) {
276
285
  return withServerCache(
@@ -324,12 +333,17 @@ function createItemActions(api, config = {}) {
324
333
  async () => {
325
334
  const response = await api.items.invMast.doc.list(
326
335
  params.invMastUid ?? 0,
327
- { itemId: params.itemId, edgeCache: 4 }
336
+ {
337
+ itemId: params.itemId,
338
+ includePricing: params.includePricing,
339
+ edgeCache: 4
340
+ }
328
341
  );
329
342
  return response.data;
330
343
  },
331
344
  params.invMastUid,
332
- params.itemId
345
+ params.itemId,
346
+ params.includePricing
333
347
  );
334
348
  }
335
349
  async function getStock(invMastUid) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/environment.ts","../src/cache/redis-client.ts","../src/sdk-call.ts","../src/cache/with-cache.ts","../src/actions/pricing.ts","../src/actions/items.ts","../src/actions/commerce.ts","../src/actions/orders.ts","../src/actions/search.ts","../src/actions/shipping.ts","../src/actions/joomla.ts"],"sourcesContent":["/**\n * Environment detection that works across server, client, and containers.\n *\n * Priority:\n * 1. DEPLOYMENT_ENV (\"dev\" → staging, \"live\" → production)\n * 2. Server-side NODE_ENV fallback\n * 3. Client-side hostname detection\n */\nfunction getEnvironment(): \"development\" | \"staging\" | \"production\" {\n const deploymentEnv = process.env.DEPLOYMENT_ENV;\n if (deploymentEnv === \"dev\") return \"staging\";\n if (deploymentEnv === \"live\") return \"production\";\n\n if (typeof window === \"undefined\") {\n if (process.env.NODE_ENV === \"development\") return \"development\";\n return \"production\";\n }\n\n const host = window.location.hostname;\n if (host.includes(\"localhost\") || host.includes(\"127.0.0.1\"))\n return \"development\";\n if (host.includes(\"agr-hosting.dev\")) return \"staging\";\n return \"production\";\n}\n\nexport const env = getEnvironment();\nexport const isDev = env === \"development\";\nexport const isStaging = env === \"staging\";\nexport const isProduction = env === \"production\";\n","import type Redis from \"ioredis\";\nimport { isDev, isStaging } from \"../environment\";\n\nconst CIRCUIT_BREAKER_THRESHOLD = 5;\nconst CIRCUIT_BREAKER_RESET_MS = 60_000;\n\ninterface RedisGlobalState {\n client: Redis | null;\n consecutiveFailures: number;\n circuitOpenUntil: number;\n}\n\nconst g = globalThis as unknown as { __redisState?: RedisGlobalState };\nif (!g.__redisState) {\n g.__redisState = {\n client: null,\n consecutiveFailures: 0,\n circuitOpenUntil: 0,\n };\n}\nconst state = g.__redisState;\n\nconst debugEnabled = isDev || isStaging;\n\nfunction log(...args: unknown[]) {\n if (debugEnabled) {\n console.log(\"[Redis]\", ...args);\n }\n}\n\nfunction isCircuitOpen(): boolean {\n if (state.circuitOpenUntil === 0) return false;\n if (Date.now() >= state.circuitOpenUntil) {\n state.circuitOpenUntil = 0;\n state.consecutiveFailures = 0;\n log(\"Circuit breaker reset -- retrying Redis\");\n return false;\n }\n return true;\n}\n\nfunction recordFailure() {\n state.consecutiveFailures++;\n if (state.consecutiveFailures >= CIRCUIT_BREAKER_THRESHOLD) {\n state.circuitOpenUntil = Date.now() + CIRCUIT_BREAKER_RESET_MS;\n log(\n `Circuit breaker OPEN -- skipping Redis for ${CIRCUIT_BREAKER_RESET_MS / 1000}s`,\n );\n }\n}\n\nfunction recordSuccess() {\n state.consecutiveFailures = 0;\n}\n\nfunction getRedisUrl(): string | undefined {\n const containerRedis = process.env.REDIS_SERVERS;\n if (containerRedis) return `redis://${containerRedis}`;\n\n if (isDev) return process.env.REDIS_URL_DEV;\n if (isStaging) return process.env.REDIS_URL_STAGING;\n return process.env.REDIS_URL_PROD;\n}\n\nasync function getClient(): Promise<Redis | null> {\n if (state.client) return state.client;\n\n const url = getRedisUrl();\n if (!url) {\n log(\"No REDIS_URL -- cache disabled\");\n return null;\n }\n\n try {\n // Dynamic import so the built ESM output doesn't use esbuild's __require\n // shim, which breaks in pure ESM environments (Next.js 16 + Turbopack).\n // ioredis is CJS-only; Node wraps its module.exports as { default }.\n const { default: IORedis } = await import(\"ioredis\");\n\n state.client = new IORedis(url, {\n maxRetriesPerRequest: 1,\n connectTimeout: 3000,\n lazyConnect: true,\n enableOfflineQueue: false,\n });\n\n state.client.on(\"error\", (err: Error) => {\n log(\"Connection error:\", err.message);\n recordFailure();\n });\n\n state.client.on(\"connect\", () => log(\"Connected\"));\n\n state.client.connect().catch(() => {\n /* handled by error event */\n });\n\n return state.client;\n } catch {\n log(\"Failed to create client (ioredis not installed?)\");\n return null;\n }\n}\n\nexport async function cacheGet(key: string): Promise<string | null> {\n if (isCircuitOpen()) return null;\n\n const client = await getClient();\n if (!client) return null;\n\n try {\n const value = await client.get(key);\n recordSuccess();\n return value;\n } catch {\n recordFailure();\n return null;\n }\n}\n\nexport async function cacheSet(\n key: string,\n value: string,\n ttlSeconds: number,\n): Promise<void> {\n if (isCircuitOpen()) return;\n\n const client = await getClient();\n if (!client) return;\n\n try {\n await client.setex(key, ttlSeconds, value);\n recordSuccess();\n } catch {\n recordFailure();\n }\n}\n\nexport function getCircuitState(): \"closed\" | \"open\" {\n return isCircuitOpen() ? \"open\" : \"closed\";\n}\n\nexport function isRedisConnected(): boolean {\n return state.client?.status === \"ready\";\n}\n","/**\n * Calls an Augur SDK method, forwarding all arguments with full type safety.\n *\n * With augur-api >= 0.9.6, SDK methods properly declare their `CacheParams`\n * option (including `edgeCache`), so this wrapper preserves both parameter\n * and return-type inference end-to-end.\n *\n * @example\n * ```ts\n * const result = await sdkCall(\n * augurServices.items.invMast.get,\n * invMastUid,\n * { edgeCache: 4 },\n * );\n * ```\n */\nexport async function sdkCall<TArgs extends unknown[], TResult>(\n method: (...args: TArgs) => Promise<TResult>,\n ...args: TArgs\n): Promise<TResult> {\n return method(...args);\n}\n","import { cacheGet, cacheSet } from \"./redis-client\";\n\n/**\n * FNV-1a 32-bit hash. Same implementation as augur-hooks/cache-helper\n * so cache keys are identical across client and server.\n */\nfunction fnv1a(str: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16).padStart(8, \"0\");\n}\n\n/**\n * JSON.stringify with sorted object keys for deterministic cache keys.\n * Same implementation as augur-hooks/stable-stringify.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || value === undefined) return JSON.stringify(value);\n if (typeof value !== \"object\") return JSON.stringify(value);\n if (Array.isArray(value)) {\n return `[${value.map(stableStringify).join(\",\")}]`;\n }\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const entries = keys.map(\n (key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`,\n );\n return `{${entries.join(\",\")}}`;\n}\n\n/**\n * Server-side cache wrapper using augur-server's Redis client.\n *\n * Uses the same cache key format as augur-hooks' `withCache`:\n * `${prefix}sdk:${methodPath}:${fnv1a(stableStringify(keyArgs))}`\n *\n * This means server-side cached data can be read by client-side hooks\n * (and vice versa) when using the same prefix and method path.\n *\n * @param prefix Cache key prefix (e.g. \"ampro:\"). Empty string if none.\n * @param redisTtl Redis TTL in seconds. 0 or undefined = skip caching.\n * @param methodPath Dot-separated SDK method path (e.g. \"pricing.priceEngine.get\").\n * @param fn The async function to cache.\n * @param keyArgs Values to hash for the cache key.\n */\nexport async function withServerCache<T>(\n prefix: string,\n redisTtl: number | undefined,\n methodPath: string,\n fn: () => Promise<T>,\n ...keyArgs: unknown[]\n): Promise<T> {\n if (!redisTtl) return fn();\n\n const key = `${prefix}sdk:${methodPath}:${fnv1a(stableStringify(keyArgs))}`;\n\n try {\n const cached = await cacheGet(key);\n if (cached != null) return JSON.parse(cached) as T;\n } catch {\n /* Redis read error — fall through to SDK call */\n }\n\n const result = await fn();\n\n try {\n cacheSet(key, JSON.stringify(result), redisTtl).catch(() => {});\n /* v8 ignore next 3 -- defensive guard for non-serializable data */\n } catch {\n /* Non-serializable or write error — skip caching */\n }\n\n return result;\n}\n","import type { TPriceData, TTax, TTaxItem } from \"@simpleapps-com/augur-utils\";\nimport { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by pricing actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface PricingApiClient {\n pricing: {\n priceEngine: {\n get: (params: Record<string, unknown>) => Promise<{ data: TPriceData }>;\n };\n taxEngine: {\n create: (params: Record<string, unknown>) => Promise<{ data: TTax }>;\n };\n };\n}\n\nexport interface PricingActionsConfig {\n /** Default customer ID when none is provided by the caller. */\n defaultCustomerId?: string | number;\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 2 (hours). */\n edgeCache?: number;\n /** Redis TTL for price lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n /** Redis TTL for tax lookups in seconds. Default: 1800 (30 min). */\n taxRedisTtl?: number;\n}\n\nexport interface PricingActions {\n getItemPrice: (\n itemId: string,\n customerId?: string | number,\n quantity?: number,\n ) => Promise<TPriceData>;\n\n batchGetItemPrices: (\n itemIds: string[],\n customerId?: string | number,\n quantity?: number,\n ) => Promise<Record<string, TPriceData>>;\n\n getTaxEstimate: (\n customerId: string | number,\n postalCode: string,\n items: TTaxItem[],\n ) => Promise<TTax>;\n}\n\nfunction resolveCustomerId(\n explicit: string | number | undefined,\n fallback: string | number | undefined,\n): number {\n const raw = explicit ?? fallback;\n const num = Number(raw);\n return num > 0 ? num : 0;\n}\n\n/**\n * Creates server-side pricing actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/pricing-actions.ts\n * import { createPricingActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const pricingActions = createPricingActions(getAugurClient(), {\n * defaultCustomerId: process.env.NEXT_PUBLIC_DEFAULT_CUSTOMER_ID,\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const price = await pricingActions.getItemPrice(\"ITEM-1\");\n * const prices = await pricingActions.batchGetItemPrices([\"ITEM-1\", \"ITEM-2\"]);\n * ```\n */\nexport function createPricingActions(\n api: PricingApiClient,\n config: PricingActionsConfig = {},\n): PricingActions {\n const {\n defaultCustomerId,\n cachePrefix = \"\",\n edgeCache = 2,\n redisTtl = 3600,\n taxRedisTtl = 1800,\n } = config;\n\n async function getItemPrice(\n itemId: string,\n customerId?: string | number,\n quantity = 1,\n ): Promise<TPriceData> {\n const custId = resolveCustomerId(customerId, defaultCustomerId);\n const params = { customerId: custId, itemId, quantity, edgeCache };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"pricing.priceEngine.get\",\n async () => {\n const response = await api.pricing.priceEngine.get(params);\n return response.data;\n },\n params,\n );\n }\n\n async function batchGetItemPrices(\n itemIds: string[],\n customerId?: string | number,\n quantity = 1,\n ): Promise<Record<string, TPriceData>> {\n const results = await Promise.all(\n itemIds.map((id) => getItemPrice(id, customerId, quantity)\n .then((data) => [id, data] as const)\n .catch(() => [id, null] as const)),\n );\n\n const out: Record<string, TPriceData> = {};\n for (const [id, data] of results) {\n if (data) out[id] = data;\n }\n return out;\n }\n\n async function getTaxEstimate(\n customerId: string | number,\n postalCode: string,\n items: TTaxItem[],\n ): Promise<TTax> {\n const custId = resolveCustomerId(customerId, defaultCustomerId);\n const params = { customerId: custId, postalCode, items };\n\n return withServerCache(\n cachePrefix,\n taxRedisTtl,\n \"pricing.taxEngine.create\",\n async () => {\n const response = await api.pricing.taxEngine.create(params);\n return response.data;\n },\n params,\n );\n }\n\n return { getItemPrice, batchGetItemPrices, getTaxEstimate };\n}\n","import type {\n TAttribute,\n TCategory,\n TInvMast,\n TInvMastDoc,\n TItemAccessory,\n TStock,\n TStockData,\n} from \"@simpleapps-com/augur-utils\";\nimport { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by item actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface ItemsApiClient {\n items: {\n categories: {\n get: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TCategory }>;\n lookup: {\n get: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n items: {\n list: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n attributes: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: { attributes: TAttribute[] } }>;\n };\n };\n invMast: {\n get: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TInvMast }>;\n doc: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TInvMastDoc }>;\n };\n stock: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TStock }>;\n };\n faq: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n invSub: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n invAccessory: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TItemAccessory[] }>;\n };\n similar: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n };\n };\n}\n\nexport interface ItemActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value for most calls. Default: 1 (hour). */\n edgeCache?: number;\n /** CDN edge cache for rarely-changing data like FAQs. Default: 8 (hours). */\n longEdgeCache?: number;\n /** Redis TTL for most calls in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n /** Redis TTL for rarely-changing data in seconds. Default: 28800 (8 hours). */\n longRedisTtl?: number;\n}\n\nexport interface ItemActions {\n // Category operations\n itemCategoryLookup: (path: string) => Promise<unknown>;\n getItemCategory: (\n uid: number,\n options?: Record<string, unknown>,\n ) => Promise<TCategory>;\n getCategoryItems: (\n uid: number,\n filters: Record<string, unknown>,\n ) => Promise<unknown>;\n getItemAttributes: (categoryUid: number) => Promise<TAttribute[]>;\n\n // Inventory operations\n getInvMast: (uid: number) => Promise<TInvMast>;\n getInvMastDoc: (params: {\n invMastUid?: number;\n itemId?: string;\n }) => Promise<TInvMastDoc>;\n getStock: (invMastUid: number) => Promise<TStockData[]>;\n getStockCompanySummary: (\n invMastUid: number,\n ) => Promise<Record<string, number>>;\n\n // Item extras\n getItemFaqs: (invMastUid: number) => Promise<unknown[]>;\n getItemSubstitutes: (invMastUid: number) => Promise<unknown[]>;\n getItemAccessories: (invMastUid: number) => Promise<TItemAccessory[]>;\n getSimilarItems: (invMastUid: number) => Promise<unknown[]>;\n\n // Batch operations\n batchGetInvMastDocs: (\n params: { invMastUid?: number; itemId?: string }[],\n ) => Promise<Record<string, TInvMastDoc>>;\n batchGetStockData: (\n invMastUids: number[],\n ) => Promise<Record<number, TStockData[]>>;\n}\n\n/**\n * Creates server-side item actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/item-actions.ts\n * import { createItemActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const itemActions = createItemActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const category = await itemActions.getItemCategory(123);\n * const doc = await itemActions.getInvMastDoc({ itemId: \"ITEM-1\" });\n * ```\n */\nexport function createItemActions(\n api: ItemsApiClient,\n config: ItemActionsConfig = {},\n): ItemActions {\n const {\n cachePrefix = \"\",\n edgeCache = 1,\n longEdgeCache = 8,\n redisTtl = 3600,\n longRedisTtl = 28800,\n } = config;\n\n // ---------------------------------------------------------------------------\n // Category operations\n // ---------------------------------------------------------------------------\n\n async function itemCategoryLookup(path: string): Promise<unknown> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.lookup.get\",\n async () => {\n const response = await api.items.categories.lookup.get({\n path,\n edgeCache,\n });\n return response.data;\n },\n path,\n );\n }\n\n async function getItemCategory(\n uid: number,\n options?: Record<string, unknown>,\n ): Promise<TCategory> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.get\",\n async () => {\n const response = await api.items.categories.get(uid, {\n ...options,\n edgeCache,\n });\n return response.data;\n },\n uid,\n options,\n );\n }\n\n async function getCategoryItems(\n uid: number,\n filters: Record<string, unknown>,\n ): Promise<unknown> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.items.list\",\n async () => {\n const response = await api.items.categories.items.list({\n ...filters,\n itemCategoryUid: uid,\n edgeCache,\n });\n return response.data;\n },\n uid,\n filters,\n );\n }\n\n async function getItemAttributes(\n categoryUid: number,\n ): Promise<TAttribute[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.attributes.list\",\n async () => {\n const response = await api.items.categories.attributes.list(\n categoryUid,\n { edgeCache },\n );\n return response.data.attributes;\n },\n categoryUid,\n );\n }\n\n // ---------------------------------------------------------------------------\n // Inventory operations\n // ---------------------------------------------------------------------------\n\n async function getInvMast(uid: number): Promise<TInvMast> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.get\",\n async () => {\n const response = await api.items.invMast.get(uid, { edgeCache: 4 });\n return response.data;\n },\n uid,\n );\n }\n\n async function getInvMastDoc(params: {\n invMastUid?: number;\n itemId?: string;\n }): Promise<TInvMastDoc> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.doc.list\",\n async () => {\n const response = await api.items.invMast.doc.list(\n params.invMastUid ?? 0,\n { itemId: params.itemId, edgeCache: 4 },\n );\n return response.data;\n },\n params.invMastUid,\n params.itemId,\n );\n }\n\n async function getStock(invMastUid: number): Promise<TStockData[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.stock.list\",\n async () => {\n const response = await api.items.invMast.stock.list(invMastUid, {\n edgeCache,\n });\n return response.data?.stockData;\n },\n invMastUid,\n );\n }\n\n async function getStockCompanySummary(\n invMastUid: number,\n ): Promise<Record<string, number>> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.stock.list.companySummary\",\n async () => {\n const response = await api.items.invMast.stock.list(invMastUid, {\n edgeCache,\n });\n return response.data?.companySummary;\n },\n invMastUid,\n );\n }\n\n // ---------------------------------------------------------------------------\n // Item extras\n // ---------------------------------------------------------------------------\n\n async function getItemFaqs(invMastUid: number): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n longRedisTtl,\n \"items.invMast.faq.list\",\n async () => {\n const response = await api.items.invMast.faq.list(invMastUid, {\n edgeCache: longEdgeCache,\n });\n return response.data;\n },\n invMastUid,\n );\n }\n\n async function getItemSubstitutes(invMastUid: number): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n longRedisTtl,\n \"items.invMast.invSub.list\",\n async () => {\n const response = await api.items.invMast.invSub.list(invMastUid, {\n edgeCache: longEdgeCache,\n });\n return response.data;\n },\n invMastUid,\n );\n }\n\n async function getItemAccessories(\n invMastUid: number,\n ): Promise<TItemAccessory[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.invAccessory.list\",\n async () => {\n const response = await api.items.invMast.invAccessory.list(\n invMastUid,\n { edgeCache },\n );\n return response.data;\n },\n invMastUid,\n );\n }\n\n async function getSimilarItems(invMastUid: number): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n longRedisTtl,\n \"items.invMast.similar.list\",\n async () => {\n const response = await api.items.invMast.similar.list(invMastUid, {\n edgeCache: longEdgeCache,\n });\n return response.data;\n },\n invMastUid,\n );\n }\n\n // ---------------------------------------------------------------------------\n // Batch operations\n // ---------------------------------------------------------------------------\n\n async function batchGetInvMastDocs(\n params: { invMastUid?: number; itemId?: string }[],\n ): Promise<Record<string, TInvMastDoc>> {\n const results = await Promise.all(\n params.map((p) =>\n getInvMastDoc(p)\n .then((data) => [p.itemId ?? String(p.invMastUid), data] as const)\n .catch(() => [p.itemId ?? String(p.invMastUid), undefined] as const),\n ),\n );\n\n const out: Record<string, TInvMastDoc> = {};\n for (const [key, data] of results) {\n if (data) out[key] = data;\n }\n return out;\n }\n\n async function batchGetStockData(\n invMastUids: number[],\n ): Promise<Record<number, TStockData[]>> {\n const results = await Promise.all(\n invMastUids.map((uid) =>\n getStock(uid)\n .then((data) => [uid, data] as const)\n .catch(() => [uid, undefined] as const),\n ),\n );\n\n const out: Record<number, TStockData[]> = {};\n for (const [uid, data] of results) {\n if (data) out[uid] = data;\n }\n return out;\n }\n\n return {\n itemCategoryLookup,\n getItemCategory,\n getCategoryItems,\n getItemAttributes,\n getInvMast,\n getInvMastDoc,\n getStock,\n getStockCompanySummary,\n getItemFaqs,\n getItemSubstitutes,\n getItemAccessories,\n getSimilarItems,\n batchGetInvMastDocs,\n batchGetStockData,\n };\n}\n","import type { TCartLine, TCartLookUp } from \"@simpleapps-com/augur-utils\";\n\n/**\n * The subset of augur-api used by commerce actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface CommerceApiClient {\n commerce: {\n cartHdr: {\n lookup: {\n get: (\n params: Record<string, unknown>,\n ) => Promise<{ data: TCartLookUp }>;\n };\n alsoBought: {\n get: (\n cartHdrUid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n };\n cartLine: {\n get: (cartHdrUid: number) => Promise<{ data: TCartLine[] }>;\n add: {\n create: (\n cartHdrUid: number,\n params: Record<string, unknown>,\n ) => Promise<{ data: unknown }>;\n };\n update: {\n create: (\n cartHdrUid: number,\n params: Record<string, unknown>,\n ) => Promise<{ data: unknown }>;\n };\n delete: (cartHdrUid: number) => Promise<{ data: unknown }>;\n };\n checkout: {\n create: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n };\n}\n\nexport interface CommerceActionsConfig {\n defaultContactId?: string | number;\n defaultCustomerId?: string | number;\n /** Optional UOM conversion function. E.g. (uom) => uom === \"EA\" ? \"EACH\" : uom */\n convertUnitOfMeasure?: (uom: string) => string;\n}\n\nexport interface CommerceActions {\n cartHdrLookup: (params: {\n userId?: string | number;\n cartToken?: string;\n contactId?: string | number;\n customerId?: string | number;\n }) => Promise<TCartLookUp>;\n\n getCartLines: (cartHdrUid: number) => Promise<TCartLine[]>;\n\n addToCart: (\n cartHdrUid: number,\n items: {\n itemId: string;\n quantity: number;\n unitOfMeasure: string;\n }[],\n ) => Promise<unknown>;\n\n updateCartLines: (\n cartHdrUid: number,\n lines: {\n lineNo: number;\n quantity: number;\n unitOfMeasure: string;\n }[],\n ) => Promise<unknown>;\n\n deleteCartItems: (cartHdrUid: number) => Promise<void>;\n\n getCartAlsoBought: (cartHdrUid: number) => Promise<unknown[]>;\n\n checkoutOrder: (\n cartHdrUid: number,\n data: Record<string, unknown>,\n ) => Promise<unknown>;\n}\n\n/**\n * Creates server-side commerce actions for cart operations.\n *\n * Unlike pricing actions, commerce actions do NOT use caching because\n * cart operations are real-time and must always reflect current state.\n *\n * @example\n * ```ts\n * // lib/commerce-actions.ts\n * import { createCommerceActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const commerceActions = createCommerceActions(getAugurClient(), {\n * defaultContactId: process.env.NEXT_PUBLIC_DEFAULT_CONTACT_ID,\n * defaultCustomerId: process.env.NEXT_PUBLIC_DEFAULT_CUSTOMER_ID,\n * convertUnitOfMeasure: (uom) => uom === \"EA\" ? \"EACH\" : uom,\n * });\n *\n * // In a server action:\n * const cart = await commerceActions.cartHdrLookup({ userId: 123 });\n * const lines = await commerceActions.getCartLines(cart.cartHdrUid);\n * ```\n */\nexport function createCommerceActions(\n api: CommerceApiClient,\n config: CommerceActionsConfig = {},\n): CommerceActions {\n const { defaultContactId, defaultCustomerId, convertUnitOfMeasure } = config;\n\n async function cartHdrLookup(params: {\n userId?: string | number;\n cartToken?: string;\n contactId?: string | number;\n customerId?: string | number;\n }): Promise<TCartLookUp> {\n const lookupParams: Record<string, unknown> = { ...params };\n if (lookupParams.contactId == null && defaultContactId != null) {\n lookupParams.contactId = defaultContactId;\n }\n if (lookupParams.customerId == null && defaultCustomerId != null) {\n lookupParams.customerId = defaultCustomerId;\n }\n const response = await api.commerce.cartHdr.lookup.get(lookupParams);\n return response.data;\n }\n\n async function getCartLines(\n cartHdrUid: number,\n ): Promise<TCartLine[]> {\n const response = await api.commerce.cartLine.get(cartHdrUid);\n return response.data;\n }\n\n async function addToCart(\n cartHdrUid: number,\n items: { itemId: string; quantity: number; unitOfMeasure: string }[],\n ): Promise<unknown> {\n try {\n const mappedItems = items.map((item) => ({\n ...item,\n unitOfMeasure: convertUnitOfMeasure\n ? convertUnitOfMeasure(item.unitOfMeasure)\n : item.unitOfMeasure,\n }));\n const response = await api.commerce.cartLine.add.create(\n cartHdrUid,\n { items: mappedItems },\n );\n return response.data;\n } catch {\n return undefined;\n }\n }\n\n async function updateCartLines(\n cartHdrUid: number,\n lines: { lineNo: number; quantity: number; unitOfMeasure: string }[],\n ): Promise<unknown> {\n try {\n const mappedLines = lines.map((line) => ({\n ...line,\n unitOfMeasure: convertUnitOfMeasure\n ? convertUnitOfMeasure(line.unitOfMeasure)\n : line.unitOfMeasure,\n }));\n const response = await api.commerce.cartLine.update.create(\n cartHdrUid,\n { lines: mappedLines },\n );\n return response.data;\n } catch {\n return undefined;\n }\n }\n\n async function deleteCartItems(cartHdrUid: number): Promise<void> {\n try {\n await api.commerce.cartLine.delete(cartHdrUid);\n } catch {\n // fire and forget — returns void either way\n }\n }\n\n async function getCartAlsoBought(\n cartHdrUid: number,\n ): Promise<unknown[]> {\n const response = await api.commerce.cartHdr.alsoBought.get(cartHdrUid);\n return response.data;\n }\n\n async function checkoutOrder(\n cartHdrUid: number,\n data: Record<string, unknown>,\n ): Promise<unknown> {\n try {\n const response = await api.commerce.checkout.create({\n ...data,\n cartHdrUid,\n });\n return response.data;\n } catch {\n return undefined;\n }\n }\n\n return {\n cartHdrLookup,\n getCartLines,\n addToCart,\n updateCartLines,\n deleteCartItems,\n getCartAlsoBought,\n checkoutOrder,\n };\n}\n","import { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by order actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface OrderApiClient {\n orders: {\n oeHdr: {\n doc: {\n get: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n };\n };\n}\n\nexport interface OrderActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for order doc lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n}\n\nexport interface OrderActions {\n getOrderDoc: (\n orderNo: string,\n zipCode: string,\n ) => Promise<unknown>;\n}\n\n/**\n * Creates server-side order actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/order-actions.ts\n * import { createOrderActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const orderActions = createOrderActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const doc = await orderActions.getOrderDoc(\"12345\", \"90210\");\n * ```\n */\nexport function createOrderActions(\n api: OrderApiClient,\n config: OrderActionsConfig = {},\n): OrderActions {\n const { cachePrefix = \"\", edgeCache = 1, redisTtl = 3600 } = config;\n\n async function getOrderDoc(\n orderNo: string,\n zipCode: string,\n ): Promise<unknown> {\n const params = { orderNo, zipCode, edgeCache };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"orders.oeHdr.doc.get\",\n async () => {\n const response = await api.orders.oeHdr.doc.get(params);\n return response.data;\n },\n params,\n );\n }\n\n return { getOrderDoc };\n}\n","import type { TAttribute, TProductItem } from \"@simpleapps-com/augur-utils\";\nimport { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by search actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface SearchApiClient {\n openSearch: {\n itemSearch: {\n list: (\n params: Record<string, unknown>,\n ) => Promise<{ data: { items: TProductItem[]; totalResults: number } }>;\n attributes: {\n list: (\n params: Record<string, unknown>,\n ) => Promise<{ data: { attributes: TAttribute[] } }>;\n };\n };\n suggestions: {\n suggest: {\n list: (\n params: Record<string, unknown>,\n ) => Promise<{\n data: { data: unknown[]; total: number; totalResults: number };\n }>;\n };\n };\n };\n}\n\nexport interface SearchActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for search lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n /** Default source fields for item search. Default: \"display_desc\". */\n defaultSourceFields?: string;\n}\n\n/** Paginated response for infinite scroll. */\nexport interface SearchPage {\n data: TProductItem[];\n total: number;\n nextCursor?: number;\n}\n\nexport interface SearchActions {\n getSearchAttributes: (q: string) => Promise<TAttribute[]>;\n\n getSearchSuggestions: (\n q: string,\n limit?: number,\n offset?: number,\n ) => Promise<{ data: unknown[]; total: number; totalResults: number }>;\n\n itemSearch: (\n filters: {\n q: string;\n limit: number;\n offset: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n ) => Promise<{ items: TProductItem[]; totalResults: number }>;\n\n itemSearchInfinite: (\n filters: {\n q: string;\n limit: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n pageParam?: number,\n ) => Promise<SearchPage>;\n}\n\n/**\n * Creates server-side search actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/search-actions.ts\n * import { createSearchActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const searchActions = createSearchActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const attrs = await searchActions.getSearchAttributes(\"widget\");\n * const results = await searchActions.itemSearch({ q: \"widget\", limit: 20, offset: 0 });\n * ```\n */\nexport function createSearchActions(\n api: SearchApiClient,\n config: SearchActionsConfig = {},\n): SearchActions {\n const {\n cachePrefix = \"\",\n edgeCache = 1,\n redisTtl = 3600,\n defaultSourceFields = \"display_desc\",\n } = config;\n\n async function getSearchAttributes(q: string): Promise<TAttribute[]> {\n const params = { q, edgeCache };\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.itemSearch.attributes.list\",\n async () => {\n const response =\n await api.openSearch.itemSearch.attributes.list(params);\n return response.data.attributes;\n },\n q,\n );\n }\n\n async function getSearchSuggestions(\n q: string,\n limit?: number,\n offset?: number,\n ): Promise<{ data: unknown[]; total: number; totalResults: number }> {\n const params: Record<string, unknown> = { q, edgeCache };\n if (limit !== undefined) params.size = limit;\n if (offset !== undefined) params.from = offset;\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.suggestions.suggest.list\",\n async () => {\n const response =\n await api.openSearch.suggestions.suggest.list(params);\n return response.data;\n },\n q,\n );\n }\n\n async function itemSearch(\n filters: {\n q: string;\n limit: number;\n offset: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n ): Promise<{ items: TProductItem[]; totalResults: number }> {\n const params: Record<string, unknown> = {\n q: filters.q,\n searchType: \"query\",\n size: filters.limit,\n from: filters.offset,\n sortBy: filters.sortBy,\n classId5List: itemCategoryUid\n ? String(itemCategoryUid)\n : undefined,\n filters: filters.filters?.length\n ? JSON.stringify(filters.filters)\n : undefined,\n sourceFieldsList: defaultSourceFields,\n edgeCache,\n };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.itemSearch.list\",\n async () => {\n const response = await api.openSearch.itemSearch.list(params);\n return response.data;\n },\n filters,\n itemCategoryUid,\n );\n }\n\n async function itemSearchInfinite(\n filters: {\n q: string;\n limit: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n pageParam = 0,\n ): Promise<SearchPage> {\n const params: Record<string, unknown> = {\n q: filters.q,\n searchType: \"query\",\n size: filters.limit,\n from: pageParam,\n sortBy: filters.sortBy,\n classId5List: itemCategoryUid\n ? String(itemCategoryUid)\n : undefined,\n filters: filters.filters?.length\n ? JSON.stringify(filters.filters)\n : undefined,\n sourceFieldsList: defaultSourceFields,\n edgeCache,\n };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.itemSearch.list\",\n async () => {\n const response = await api.openSearch.itemSearch.list(params);\n const { items, totalResults } = response.data;\n const nextOffset = pageParam + filters.limit;\n return {\n data: items,\n total: totalResults,\n nextCursor:\n nextOffset < totalResults ? nextOffset : undefined,\n };\n },\n filters,\n itemCategoryUid,\n pageParam,\n );\n }\n\n return {\n getSearchAttributes,\n getSearchSuggestions,\n itemSearch,\n itemSearchInfinite,\n };\n}\n","import { withServerCache } from \"../cache/with-cache\";\n\nexport interface ShippingAddress {\n address1: string;\n city: string;\n state: string;\n postalCode: string;\n country?: string;\n}\n\n/**\n * The subset of augur-api used by shipping actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface ShippingApiClient {\n ups: {\n ratesShop: {\n get: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n };\n}\n\nexport interface ShippingActionsConfig {\n /** Warehouse/origin address for rate calculations. */\n fromAddress: ShippingAddress;\n /** UPS service codes to filter results. Default: undefined (return all). */\n defaultServiceCodes?: string[];\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for shipping rate lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n}\n\nexport interface ShippingActions {\n getShippingRates: (\n toAddress: ShippingAddress,\n weight: number,\n serviceCodes?: string[],\n ) => Promise<unknown>;\n}\n\n/**\n * Creates server-side shipping actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/shipping-actions.ts\n * import { createShippingActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const shippingActions = createShippingActions(getAugurClient(), {\n * fromAddress: {\n * address1: \"123 Warehouse Ln\",\n * city: \"Chicago\",\n * state: \"IL\",\n * postalCode: \"60601\",\n * },\n * });\n *\n * // In a server component:\n * const rates = await shippingActions.getShippingRates(\n * { address1: \"456 Main St\", city: \"Denver\", state: \"CO\", postalCode: \"80202\" },\n * 5.0,\n * );\n * ```\n */\nexport function createShippingActions(\n api: ShippingApiClient,\n config: ShippingActionsConfig,\n): ShippingActions {\n const {\n fromAddress,\n defaultServiceCodes,\n cachePrefix = \"\",\n edgeCache = 1,\n redisTtl = 3600,\n } = config;\n\n async function getShippingRates(\n toAddress: ShippingAddress,\n weight: number,\n serviceCodes?: string[],\n ): Promise<unknown> {\n const params = {\n fromAddress,\n toAddress: { ...toAddress, country: toAddress.country ?? \"US\" },\n weight,\n serviceCodes: serviceCodes ?? defaultServiceCodes,\n edgeCache,\n };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"ups.ratesShop.get\",\n async () => {\n const response = await api.ups.ratesShop.get(params);\n return response.data;\n },\n params,\n );\n }\n\n return { getShippingRates };\n}\n","import { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by Joomla content actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface JoomlaApiClient {\n joomla: {\n content: {\n doc: {\n get: (\n articleId: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown }>;\n };\n list: (\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n };\n}\n\nexport interface JoomlaActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for Joomla lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n}\n\nexport interface JoomlaActions {\n getJoomlaContent: (articleId: number) => Promise<unknown>;\n getJoomlaContentList: (\n params?: Record<string, unknown>,\n ) => Promise<unknown[]>;\n}\n\n/**\n * Creates server-side Joomla content actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/joomla-actions.ts\n * import { createJoomlaActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const joomlaActions = createJoomlaActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const article = await joomlaActions.getJoomlaContent(42);\n * const articles = await joomlaActions.getJoomlaContentList({ catid: 5 });\n * ```\n */\nexport function createJoomlaActions(\n api: JoomlaApiClient,\n config: JoomlaActionsConfig = {},\n): JoomlaActions {\n const { cachePrefix = \"\", edgeCache = 1, redisTtl = 3600 } = config;\n\n async function getJoomlaContent(\n articleId: number,\n ): Promise<unknown> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"joomla.content.doc.get\",\n async () => {\n const response = await api.joomla.content.doc.get(articleId, {\n edgeCache,\n });\n return response.data;\n },\n articleId,\n );\n }\n\n async function getJoomlaContentList(\n params?: Record<string, unknown>,\n ): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"joomla.content.list\",\n async () => {\n const response = await api.joomla.content.list({\n ...params,\n edgeCache,\n });\n return response.data;\n },\n params,\n );\n }\n\n return { getJoomlaContent, getJoomlaContentList };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/environment.ts","../src/cache/redis-client.ts","../src/sdk-call.ts","../src/cache/with-cache.ts","../src/actions/pricing.ts","../src/actions/items.ts","../src/actions/commerce.ts","../src/actions/orders.ts","../src/actions/search.ts","../src/actions/shipping.ts","../src/actions/joomla.ts"],"sourcesContent":["/**\n * Environment detection that works across server, client, and containers.\n *\n * Priority:\n * 1. DEPLOYMENT_ENV (\"dev\" → staging, \"live\" → production)\n * 2. Server-side NODE_ENV fallback\n * 3. Client-side hostname detection\n */\nfunction getEnvironment(): \"development\" | \"staging\" | \"production\" {\n const deploymentEnv = process.env.DEPLOYMENT_ENV;\n if (deploymentEnv === \"dev\") return \"staging\";\n if (deploymentEnv === \"live\") return \"production\";\n\n if (typeof window === \"undefined\") {\n if (process.env.NODE_ENV === \"development\") return \"development\";\n return \"production\";\n }\n\n const host = window.location.hostname;\n if (host.includes(\"localhost\") || host.includes(\"127.0.0.1\"))\n return \"development\";\n if (host.includes(\"agr-hosting.dev\")) return \"staging\";\n return \"production\";\n}\n\nexport const env = getEnvironment();\nexport const isDev = env === \"development\";\nexport const isStaging = env === \"staging\";\nexport const isProduction = env === \"production\";\n","import type Redis from \"ioredis\";\nimport { isDev, isStaging } from \"../environment\";\n\nconst CIRCUIT_BREAKER_THRESHOLD = 5;\nconst CIRCUIT_BREAKER_RESET_MS = 60_000;\n\ninterface RedisGlobalState {\n client: Redis | null;\n consecutiveFailures: number;\n circuitOpenUntil: number;\n}\n\nconst g = globalThis as unknown as { __redisState?: RedisGlobalState };\nif (!g.__redisState) {\n g.__redisState = {\n client: null,\n consecutiveFailures: 0,\n circuitOpenUntil: 0,\n };\n}\nconst state = g.__redisState;\n\nconst debugEnabled = isDev || isStaging;\n\nfunction log(...args: unknown[]) {\n if (debugEnabled) {\n console.log(\"[Redis]\", ...args);\n }\n}\n\nfunction isCircuitOpen(): boolean {\n if (state.circuitOpenUntil === 0) return false;\n if (Date.now() >= state.circuitOpenUntil) {\n state.circuitOpenUntil = 0;\n state.consecutiveFailures = 0;\n log(\"Circuit breaker reset -- retrying Redis\");\n return false;\n }\n return true;\n}\n\nfunction recordFailure() {\n state.consecutiveFailures++;\n if (state.consecutiveFailures >= CIRCUIT_BREAKER_THRESHOLD) {\n state.circuitOpenUntil = Date.now() + CIRCUIT_BREAKER_RESET_MS;\n log(\n `Circuit breaker OPEN -- skipping Redis for ${CIRCUIT_BREAKER_RESET_MS / 1000}s`,\n );\n }\n}\n\nfunction recordSuccess() {\n state.consecutiveFailures = 0;\n}\n\nfunction getRedisUrl(): string | undefined {\n const containerRedis = process.env.REDIS_SERVERS;\n if (containerRedis) return `redis://${containerRedis}`;\n\n if (isDev) return process.env.REDIS_URL_DEV;\n if (isStaging) return process.env.REDIS_URL_STAGING;\n return process.env.REDIS_URL_PROD;\n}\n\nasync function getClient(): Promise<Redis | null> {\n if (state.client) return state.client;\n\n const url = getRedisUrl();\n if (!url) {\n log(\"No REDIS_URL -- cache disabled\");\n return null;\n }\n\n try {\n // Dynamic import so the built ESM output doesn't use esbuild's __require\n // shim, which breaks in pure ESM environments (Next.js 16 + Turbopack).\n // ioredis is CJS-only; Node wraps its module.exports as { default }.\n const { default: IORedis } = await import(\"ioredis\");\n\n state.client = new IORedis(url, {\n maxRetriesPerRequest: 1,\n connectTimeout: 3000,\n lazyConnect: true,\n enableOfflineQueue: false,\n });\n\n state.client.on(\"error\", (err: Error) => {\n log(\"Connection error:\", err.message);\n recordFailure();\n });\n\n state.client.on(\"connect\", () => log(\"Connected\"));\n\n state.client.connect().catch(() => {\n /* handled by error event */\n });\n\n return state.client;\n } catch {\n log(\"Failed to create client (ioredis not installed?)\");\n return null;\n }\n}\n\nexport async function cacheGet(key: string): Promise<string | null> {\n if (isCircuitOpen()) return null;\n\n const client = await getClient();\n if (!client) return null;\n\n try {\n const value = await client.get(key);\n recordSuccess();\n return value;\n } catch {\n recordFailure();\n return null;\n }\n}\n\nexport async function cacheSet(\n key: string,\n value: string,\n ttlSeconds: number,\n): Promise<void> {\n if (isCircuitOpen()) return;\n\n const client = await getClient();\n if (!client) return;\n\n try {\n await client.setex(key, ttlSeconds, value);\n recordSuccess();\n } catch {\n recordFailure();\n }\n}\n\nexport function getCircuitState(): \"closed\" | \"open\" {\n return isCircuitOpen() ? \"open\" : \"closed\";\n}\n\nexport function isRedisConnected(): boolean {\n return state.client?.status === \"ready\";\n}\n","/**\n * Calls an Augur SDK method, forwarding all arguments with full type safety.\n *\n * With augur-api >= 0.9.6, SDK methods properly declare their `CacheParams`\n * option (including `edgeCache`), so this wrapper preserves both parameter\n * and return-type inference end-to-end.\n *\n * @example\n * ```ts\n * const result = await sdkCall(\n * augurServices.items.invMast.get,\n * invMastUid,\n * { edgeCache: 4 },\n * );\n * ```\n */\nexport async function sdkCall<TArgs extends unknown[], TResult>(\n method: (...args: TArgs) => Promise<TResult>,\n ...args: TArgs\n): Promise<TResult> {\n return method(...args);\n}\n","import { cacheGet, cacheSet } from \"./redis-client\";\n\n/**\n * FNV-1a 32-bit hash. Same implementation as augur-hooks/cache-helper\n * so cache keys are identical across client and server.\n */\nfunction fnv1a(str: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16).padStart(8, \"0\");\n}\n\n/**\n * JSON.stringify with sorted object keys for deterministic cache keys.\n * Same implementation as augur-hooks/stable-stringify.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || value === undefined) return JSON.stringify(value);\n if (typeof value !== \"object\") return JSON.stringify(value);\n if (Array.isArray(value)) {\n return `[${value.map(stableStringify).join(\",\")}]`;\n }\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const entries = keys.map(\n (key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`,\n );\n return `{${entries.join(\",\")}}`;\n}\n\n/**\n * Server-side cache wrapper using augur-server's Redis client.\n *\n * Uses the same cache key format as augur-hooks' `withCache`:\n * `${prefix}sdk:${methodPath}:${fnv1a(stableStringify(keyArgs))}`\n *\n * This means server-side cached data can be read by client-side hooks\n * (and vice versa) when using the same prefix and method path.\n *\n * @param prefix Cache key prefix (e.g. \"ampro:\"). Empty string if none.\n * @param redisTtl Redis TTL in seconds. 0 or undefined = skip caching.\n * @param methodPath Dot-separated SDK method path (e.g. \"pricing.priceEngine.get\").\n * @param fn The async function to cache.\n * @param keyArgs Values to hash for the cache key.\n */\nexport async function withServerCache<T>(\n prefix: string,\n redisTtl: number | undefined,\n methodPath: string,\n fn: () => Promise<T>,\n ...keyArgs: unknown[]\n): Promise<T> {\n if (!redisTtl) return fn();\n\n const key = `${prefix}sdk:${methodPath}:${fnv1a(stableStringify(keyArgs))}`;\n\n try {\n const cached = await cacheGet(key);\n if (cached != null) return JSON.parse(cached) as T;\n } catch {\n /* Redis read error — fall through to SDK call */\n }\n\n const result = await fn();\n\n try {\n cacheSet(key, JSON.stringify(result), redisTtl).catch(() => {});\n /* v8 ignore next 3 -- defensive guard for non-serializable data */\n } catch {\n /* Non-serializable or write error — skip caching */\n }\n\n return result;\n}\n","import type { TPriceData, TTax, TTaxItem } from \"@simpleapps-com/augur-utils\";\nimport { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by pricing actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface PricingApiClient {\n pricing: {\n priceEngine: {\n get: (params: Record<string, unknown>) => Promise<{ data: TPriceData }>;\n };\n taxEngine: {\n create: (params: Record<string, unknown>) => Promise<{ data: TTax }>;\n };\n };\n}\n\nexport interface PricingActionsConfig {\n /** Default customer ID when none is provided by the caller. */\n defaultCustomerId?: string | number;\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 2 (hours). */\n edgeCache?: number;\n /** Redis TTL for price lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n /** Redis TTL for tax lookups in seconds. Default: 1800 (30 min). */\n taxRedisTtl?: number;\n}\n\nexport interface PricingActions {\n getItemPrice: (\n itemId: string,\n customerId?: string | number,\n quantity?: number,\n ) => Promise<TPriceData>;\n\n batchGetItemPrices: (\n itemIds: string[],\n customerId?: string | number,\n quantity?: number,\n ) => Promise<Record<string, TPriceData>>;\n\n getTaxEstimate: (\n customerId: string | number,\n postalCode: string,\n items: TTaxItem[],\n ) => Promise<TTax>;\n}\n\nfunction resolveCustomerId(\n explicit: string | number | undefined,\n fallback: string | number | undefined,\n): number {\n const raw = explicit ?? fallback;\n const num = Number(raw);\n return num > 0 ? num : 0;\n}\n\n/**\n * Creates server-side pricing actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/pricing-actions.ts\n * import { createPricingActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const pricingActions = createPricingActions(getAugurClient(), {\n * defaultCustomerId: process.env.NEXT_PUBLIC_DEFAULT_CUSTOMER_ID,\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const price = await pricingActions.getItemPrice(\"ITEM-1\");\n * const prices = await pricingActions.batchGetItemPrices([\"ITEM-1\", \"ITEM-2\"]);\n * ```\n */\nexport function createPricingActions(\n api: PricingApiClient,\n config: PricingActionsConfig = {},\n): PricingActions {\n const {\n defaultCustomerId,\n cachePrefix = \"\",\n edgeCache = 2,\n redisTtl = 3600,\n taxRedisTtl = 1800,\n } = config;\n\n async function getItemPrice(\n itemId: string,\n customerId?: string | number,\n quantity = 1,\n ): Promise<TPriceData> {\n const custId = resolveCustomerId(customerId, defaultCustomerId);\n const params = { customerId: custId, itemId, quantity, edgeCache };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"pricing.priceEngine.get\",\n async () => {\n const response = await api.pricing.priceEngine.get(params);\n return response.data;\n },\n params,\n );\n }\n\n async function batchGetItemPrices(\n itemIds: string[],\n customerId?: string | number,\n quantity = 1,\n ): Promise<Record<string, TPriceData>> {\n const results = await Promise.all(\n itemIds.map((id) => getItemPrice(id, customerId, quantity)\n .then((data) => [id, data] as const)\n .catch(() => [id, null] as const)),\n );\n\n const out: Record<string, TPriceData> = {};\n for (const [id, data] of results) {\n if (data) out[id] = data;\n }\n return out;\n }\n\n async function getTaxEstimate(\n customerId: string | number,\n postalCode: string,\n items: TTaxItem[],\n ): Promise<TTax> {\n const custId = resolveCustomerId(customerId, defaultCustomerId);\n const params = { customerId: custId, postalCode, items };\n\n return withServerCache(\n cachePrefix,\n taxRedisTtl,\n \"pricing.taxEngine.create\",\n async () => {\n const response = await api.pricing.taxEngine.create(params);\n return response.data;\n },\n params,\n );\n }\n\n return { getItemPrice, batchGetItemPrices, getTaxEstimate };\n}\n","import type {\n TAttribute,\n TCategory,\n TInvMast,\n TInvMastDoc,\n TItemAccessory,\n TStock,\n TStockData,\n} from \"@simpleapps-com/augur-utils\";\nimport { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by item actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface ItemsApiClient {\n items: {\n categories: {\n get: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TCategory }>;\n lookup: {\n get: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n items: {\n list: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n attributes: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: { attributes: TAttribute[] } }>;\n };\n };\n invMast: {\n get: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TInvMast }>;\n doc: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TInvMastDoc }>;\n };\n stock: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TStock }>;\n };\n faq: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n invSub: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n invAccessory: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: TItemAccessory[] }>;\n };\n similar: {\n list: (\n uid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n };\n };\n}\n\nexport interface ItemActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value for most calls. Default: 1 (hour). */\n edgeCache?: number;\n /** CDN edge cache for rarely-changing data like FAQs. Default: 8 (hours). */\n longEdgeCache?: number;\n /** Redis TTL for most calls in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n /** Redis TTL for rarely-changing data in seconds. Default: 28800 (8 hours). */\n longRedisTtl?: number;\n /** Sort category children by sequenceNo. Default: true. */\n sortChildren?: boolean;\n}\n\nexport interface ItemActions {\n // Category operations\n itemCategoryLookup: (path: string) => Promise<unknown>;\n getItemCategory: (\n uid: number,\n options?: Record<string, unknown>,\n ) => Promise<TCategory>;\n getCategoryItems: (\n uid: number,\n filters: Record<string, unknown>,\n ) => Promise<unknown>;\n getItemAttributes: (categoryUid: number) => Promise<TAttribute[]>;\n\n // Inventory operations\n getInvMast: (uid: number) => Promise<TInvMast>;\n getInvMastDoc: (params: {\n invMastUid?: number;\n itemId?: string;\n includePricing?: \"Y\" | \"N\";\n }) => Promise<TInvMastDoc>;\n getStock: (invMastUid: number) => Promise<TStockData[]>;\n getStockCompanySummary: (\n invMastUid: number,\n ) => Promise<Record<string, number>>;\n\n // Item extras\n getItemFaqs: (invMastUid: number) => Promise<unknown[]>;\n getItemSubstitutes: (invMastUid: number) => Promise<unknown[]>;\n getItemAccessories: (invMastUid: number) => Promise<TItemAccessory[]>;\n getSimilarItems: (invMastUid: number) => Promise<unknown[]>;\n\n // Batch operations\n batchGetInvMastDocs: (\n params: { invMastUid?: number; itemId?: string }[],\n ) => Promise<Record<string, TInvMastDoc>>;\n batchGetStockData: (\n invMastUids: number[],\n ) => Promise<Record<number, TStockData[]>>;\n}\n\n/**\n * Creates server-side item actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/item-actions.ts\n * import { createItemActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const itemActions = createItemActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const category = await itemActions.getItemCategory(123);\n * const doc = await itemActions.getInvMastDoc({ itemId: \"ITEM-1\" });\n * ```\n */\nexport function createItemActions(\n api: ItemsApiClient,\n config: ItemActionsConfig = {},\n): ItemActions {\n const {\n cachePrefix = \"\",\n edgeCache = 1,\n longEdgeCache = 8,\n redisTtl = 3600,\n longRedisTtl = 28800,\n sortChildren = true,\n } = config;\n\n function sortCategoryChildren<T extends { sequenceNo: number }>(\n children: T[],\n ): T[] {\n if (!sortChildren) return children;\n return [...children].sort((a, b) => a.sequenceNo - b.sequenceNo);\n }\n\n // ---------------------------------------------------------------------------\n // Category operations\n // ---------------------------------------------------------------------------\n\n async function itemCategoryLookup(path: string): Promise<unknown> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.lookup.get\",\n async () => {\n const response = await api.items.categories.lookup.get({\n path,\n edgeCache,\n });\n return response.data;\n },\n path,\n );\n }\n\n async function getItemCategory(\n uid: number,\n options?: Record<string, unknown>,\n ): Promise<TCategory> {\n const category = await withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.get\",\n async () => {\n const response = await api.items.categories.get(uid, {\n ...options,\n edgeCache,\n });\n return response.data;\n },\n uid,\n options,\n );\n return {\n ...category,\n children: sortCategoryChildren(category.children),\n };\n }\n\n async function getCategoryItems(\n uid: number,\n filters: Record<string, unknown>,\n ): Promise<unknown> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.items.list\",\n async () => {\n const response = await api.items.categories.items.list({\n ...filters,\n itemCategoryUid: uid,\n edgeCache,\n });\n return response.data;\n },\n uid,\n filters,\n );\n }\n\n async function getItemAttributes(\n categoryUid: number,\n ): Promise<TAttribute[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.categories.attributes.list\",\n async () => {\n const response = await api.items.categories.attributes.list(\n categoryUid,\n { edgeCache },\n );\n return response.data.attributes;\n },\n categoryUid,\n );\n }\n\n // ---------------------------------------------------------------------------\n // Inventory operations\n // ---------------------------------------------------------------------------\n\n async function getInvMast(uid: number): Promise<TInvMast> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.get\",\n async () => {\n const response = await api.items.invMast.get(uid, { edgeCache: 4 });\n return response.data;\n },\n uid,\n );\n }\n\n async function getInvMastDoc(params: {\n invMastUid?: number;\n itemId?: string;\n includePricing?: \"Y\" | \"N\";\n }): Promise<TInvMastDoc> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.doc.list\",\n async () => {\n const response = await api.items.invMast.doc.list(\n params.invMastUid ?? 0,\n {\n itemId: params.itemId,\n includePricing: params.includePricing,\n edgeCache: 4,\n },\n );\n return response.data;\n },\n params.invMastUid,\n params.itemId,\n params.includePricing,\n );\n }\n\n async function getStock(invMastUid: number): Promise<TStockData[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.stock.list\",\n async () => {\n const response = await api.items.invMast.stock.list(invMastUid, {\n edgeCache,\n });\n return response.data?.stockData;\n },\n invMastUid,\n );\n }\n\n async function getStockCompanySummary(\n invMastUid: number,\n ): Promise<Record<string, number>> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.stock.list.companySummary\",\n async () => {\n const response = await api.items.invMast.stock.list(invMastUid, {\n edgeCache,\n });\n return response.data?.companySummary;\n },\n invMastUid,\n );\n }\n\n // ---------------------------------------------------------------------------\n // Item extras\n // ---------------------------------------------------------------------------\n\n async function getItemFaqs(invMastUid: number): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n longRedisTtl,\n \"items.invMast.faq.list\",\n async () => {\n const response = await api.items.invMast.faq.list(invMastUid, {\n edgeCache: longEdgeCache,\n });\n return response.data;\n },\n invMastUid,\n );\n }\n\n async function getItemSubstitutes(invMastUid: number): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n longRedisTtl,\n \"items.invMast.invSub.list\",\n async () => {\n const response = await api.items.invMast.invSub.list(invMastUid, {\n edgeCache: longEdgeCache,\n });\n return response.data;\n },\n invMastUid,\n );\n }\n\n async function getItemAccessories(\n invMastUid: number,\n ): Promise<TItemAccessory[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"items.invMast.invAccessory.list\",\n async () => {\n const response = await api.items.invMast.invAccessory.list(\n invMastUid,\n { edgeCache },\n );\n return response.data;\n },\n invMastUid,\n );\n }\n\n async function getSimilarItems(invMastUid: number): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n longRedisTtl,\n \"items.invMast.similar.list\",\n async () => {\n const response = await api.items.invMast.similar.list(invMastUid, {\n edgeCache: longEdgeCache,\n });\n return response.data;\n },\n invMastUid,\n );\n }\n\n // ---------------------------------------------------------------------------\n // Batch operations\n // ---------------------------------------------------------------------------\n\n async function batchGetInvMastDocs(\n params: { invMastUid?: number; itemId?: string }[],\n ): Promise<Record<string, TInvMastDoc>> {\n const results = await Promise.all(\n params.map((p) =>\n getInvMastDoc(p)\n .then((data) => [p.itemId ?? String(p.invMastUid), data] as const)\n .catch(() => [p.itemId ?? String(p.invMastUid), undefined] as const),\n ),\n );\n\n const out: Record<string, TInvMastDoc> = {};\n for (const [key, data] of results) {\n if (data) out[key] = data;\n }\n return out;\n }\n\n async function batchGetStockData(\n invMastUids: number[],\n ): Promise<Record<number, TStockData[]>> {\n const results = await Promise.all(\n invMastUids.map((uid) =>\n getStock(uid)\n .then((data) => [uid, data] as const)\n .catch(() => [uid, undefined] as const),\n ),\n );\n\n const out: Record<number, TStockData[]> = {};\n for (const [uid, data] of results) {\n if (data) out[uid] = data;\n }\n return out;\n }\n\n return {\n itemCategoryLookup,\n getItemCategory,\n getCategoryItems,\n getItemAttributes,\n getInvMast,\n getInvMastDoc,\n getStock,\n getStockCompanySummary,\n getItemFaqs,\n getItemSubstitutes,\n getItemAccessories,\n getSimilarItems,\n batchGetInvMastDocs,\n batchGetStockData,\n };\n}\n","import type { TCartLine, TCartLookUp } from \"@simpleapps-com/augur-utils\";\n\n/**\n * The subset of augur-api used by commerce actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface CommerceApiClient {\n commerce: {\n cartHdr: {\n lookup: {\n get: (\n params: Record<string, unknown>,\n ) => Promise<{ data: TCartLookUp }>;\n };\n alsoBought: {\n get: (\n cartHdrUid: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n };\n cartLine: {\n get: (cartHdrUid: number) => Promise<{ data: TCartLine[] }>;\n add: {\n create: (\n cartHdrUid: number,\n params: Record<string, unknown>,\n ) => Promise<{ data: unknown }>;\n };\n update: {\n create: (\n cartHdrUid: number,\n params: Record<string, unknown>,\n ) => Promise<{ data: unknown }>;\n };\n delete: (cartHdrUid: number) => Promise<{ data: unknown }>;\n };\n checkout: {\n create: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n };\n}\n\nexport interface CommerceActionsConfig {\n defaultContactId?: string | number;\n defaultCustomerId?: string | number;\n /** Optional UOM conversion function. E.g. (uom) => uom === \"EA\" ? \"EACH\" : uom */\n convertUnitOfMeasure?: (uom: string) => string;\n}\n\nexport interface CommerceActions {\n cartHdrLookup: (params: {\n userId?: string | number;\n cartToken?: string;\n contactId?: string | number;\n customerId?: string | number;\n }) => Promise<TCartLookUp>;\n\n getCartLines: (cartHdrUid: number) => Promise<TCartLine[]>;\n\n addToCart: (\n cartHdrUid: number,\n items: {\n itemId: string;\n quantity: number;\n unitOfMeasure: string;\n }[],\n ) => Promise<unknown>;\n\n updateCartLines: (\n cartHdrUid: number,\n lines: {\n lineNo: number;\n quantity: number;\n unitOfMeasure: string;\n }[],\n ) => Promise<unknown>;\n\n deleteCartItems: (cartHdrUid: number) => Promise<void>;\n\n getCartAlsoBought: (cartHdrUid: number) => Promise<unknown[]>;\n\n checkoutOrder: (\n cartHdrUid: number,\n data: Record<string, unknown>,\n ) => Promise<unknown>;\n}\n\n/**\n * Creates server-side commerce actions for cart operations.\n *\n * Unlike pricing actions, commerce actions do NOT use caching because\n * cart operations are real-time and must always reflect current state.\n *\n * @example\n * ```ts\n * // lib/commerce-actions.ts\n * import { createCommerceActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const commerceActions = createCommerceActions(getAugurClient(), {\n * defaultContactId: process.env.NEXT_PUBLIC_DEFAULT_CONTACT_ID,\n * defaultCustomerId: process.env.NEXT_PUBLIC_DEFAULT_CUSTOMER_ID,\n * convertUnitOfMeasure: (uom) => uom === \"EA\" ? \"EACH\" : uom,\n * });\n *\n * // In a server action:\n * const cart = await commerceActions.cartHdrLookup({ userId: 123 });\n * const lines = await commerceActions.getCartLines(cart.cartHdrUid);\n * ```\n */\nexport function createCommerceActions(\n api: CommerceApiClient,\n config: CommerceActionsConfig = {},\n): CommerceActions {\n const { defaultContactId, defaultCustomerId, convertUnitOfMeasure } = config;\n\n async function cartHdrLookup(params: {\n userId?: string | number;\n cartToken?: string;\n contactId?: string | number;\n customerId?: string | number;\n }): Promise<TCartLookUp> {\n const lookupParams: Record<string, unknown> = { ...params };\n if (lookupParams.contactId == null && defaultContactId != null) {\n lookupParams.contactId = defaultContactId;\n }\n if (lookupParams.customerId == null && defaultCustomerId != null) {\n lookupParams.customerId = defaultCustomerId;\n }\n const response = await api.commerce.cartHdr.lookup.get(lookupParams);\n return response.data;\n }\n\n async function getCartLines(\n cartHdrUid: number,\n ): Promise<TCartLine[]> {\n const response = await api.commerce.cartLine.get(cartHdrUid);\n return response.data;\n }\n\n async function addToCart(\n cartHdrUid: number,\n items: { itemId: string; quantity: number; unitOfMeasure: string }[],\n ): Promise<unknown> {\n try {\n const mappedItems = items.map((item) => ({\n ...item,\n unitOfMeasure: convertUnitOfMeasure\n ? convertUnitOfMeasure(item.unitOfMeasure)\n : item.unitOfMeasure,\n }));\n const response = await api.commerce.cartLine.add.create(\n cartHdrUid,\n { items: mappedItems },\n );\n return response.data;\n } catch {\n return undefined;\n }\n }\n\n async function updateCartLines(\n cartHdrUid: number,\n lines: { lineNo: number; quantity: number; unitOfMeasure: string }[],\n ): Promise<unknown> {\n try {\n const mappedLines = lines.map((line) => ({\n ...line,\n unitOfMeasure: convertUnitOfMeasure\n ? convertUnitOfMeasure(line.unitOfMeasure)\n : line.unitOfMeasure,\n }));\n const response = await api.commerce.cartLine.update.create(\n cartHdrUid,\n { lines: mappedLines },\n );\n return response.data;\n } catch {\n return undefined;\n }\n }\n\n async function deleteCartItems(cartHdrUid: number): Promise<void> {\n try {\n await api.commerce.cartLine.delete(cartHdrUid);\n } catch {\n // fire and forget — returns void either way\n }\n }\n\n async function getCartAlsoBought(\n cartHdrUid: number,\n ): Promise<unknown[]> {\n const response = await api.commerce.cartHdr.alsoBought.get(cartHdrUid);\n return response.data;\n }\n\n async function checkoutOrder(\n cartHdrUid: number,\n data: Record<string, unknown>,\n ): Promise<unknown> {\n try {\n const response = await api.commerce.checkout.create({\n ...data,\n cartHdrUid,\n });\n return response.data;\n } catch {\n return undefined;\n }\n }\n\n return {\n cartHdrLookup,\n getCartLines,\n addToCart,\n updateCartLines,\n deleteCartItems,\n getCartAlsoBought,\n checkoutOrder,\n };\n}\n","import { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by order actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface OrderApiClient {\n orders: {\n oeHdr: {\n doc: {\n get: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n };\n };\n}\n\nexport interface OrderActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for order doc lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n}\n\nexport interface OrderActions {\n getOrderDoc: (\n orderNo: string,\n zipCode: string,\n ) => Promise<unknown>;\n}\n\n/**\n * Creates server-side order actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/order-actions.ts\n * import { createOrderActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const orderActions = createOrderActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const doc = await orderActions.getOrderDoc(\"12345\", \"90210\");\n * ```\n */\nexport function createOrderActions(\n api: OrderApiClient,\n config: OrderActionsConfig = {},\n): OrderActions {\n const { cachePrefix = \"\", edgeCache = 1, redisTtl = 3600 } = config;\n\n async function getOrderDoc(\n orderNo: string,\n zipCode: string,\n ): Promise<unknown> {\n const params = { orderNo, zipCode, edgeCache };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"orders.oeHdr.doc.get\",\n async () => {\n const response = await api.orders.oeHdr.doc.get(params);\n return response.data;\n },\n params,\n );\n }\n\n return { getOrderDoc };\n}\n","import type { TAttribute, TProductItem } from \"@simpleapps-com/augur-utils\";\nimport { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by search actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface SearchApiClient {\n openSearch: {\n itemSearch: {\n list: (\n params: Record<string, unknown>,\n ) => Promise<{ data: { items: TProductItem[]; totalResults: number } }>;\n attributes: {\n list: (\n params: Record<string, unknown>,\n ) => Promise<{ data: { attributes: TAttribute[] } }>;\n };\n };\n suggestions: {\n suggest: {\n list: (\n params: Record<string, unknown>,\n ) => Promise<{\n data: { data: unknown[]; total: number; totalResults: number };\n }>;\n };\n };\n };\n}\n\nexport interface SearchActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for search lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n /** Default source fields for item search. Default: \"display_desc\". */\n defaultSourceFields?: string;\n}\n\n/** Paginated response for infinite scroll. */\nexport interface SearchPage {\n data: TProductItem[];\n total: number;\n nextCursor?: number;\n}\n\nexport interface SearchActions {\n getSearchAttributes: (q: string) => Promise<TAttribute[]>;\n\n getSearchSuggestions: (\n q: string,\n limit?: number,\n offset?: number,\n ) => Promise<{ data: unknown[]; total: number; totalResults: number }>;\n\n itemSearch: (\n filters: {\n q: string;\n limit: number;\n offset: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n ) => Promise<{ items: TProductItem[]; totalResults: number }>;\n\n itemSearchInfinite: (\n filters: {\n q: string;\n limit: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n pageParam?: number,\n ) => Promise<SearchPage>;\n}\n\n/**\n * Creates server-side search actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/search-actions.ts\n * import { createSearchActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const searchActions = createSearchActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const attrs = await searchActions.getSearchAttributes(\"widget\");\n * const results = await searchActions.itemSearch({ q: \"widget\", limit: 20, offset: 0 });\n * ```\n */\nexport function createSearchActions(\n api: SearchApiClient,\n config: SearchActionsConfig = {},\n): SearchActions {\n const {\n cachePrefix = \"\",\n edgeCache = 1,\n redisTtl = 3600,\n defaultSourceFields = \"display_desc\",\n } = config;\n\n async function getSearchAttributes(q: string): Promise<TAttribute[]> {\n const params = { q, edgeCache };\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.itemSearch.attributes.list\",\n async () => {\n const response =\n await api.openSearch.itemSearch.attributes.list(params);\n return response.data.attributes;\n },\n q,\n );\n }\n\n async function getSearchSuggestions(\n q: string,\n limit?: number,\n offset?: number,\n ): Promise<{ data: unknown[]; total: number; totalResults: number }> {\n const params: Record<string, unknown> = { q, edgeCache };\n if (limit !== undefined) params.size = limit;\n if (offset !== undefined) params.from = offset;\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.suggestions.suggest.list\",\n async () => {\n const response =\n await api.openSearch.suggestions.suggest.list(params);\n return response.data;\n },\n q,\n );\n }\n\n async function itemSearch(\n filters: {\n q: string;\n limit: number;\n offset: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n ): Promise<{ items: TProductItem[]; totalResults: number }> {\n const params: Record<string, unknown> = {\n q: filters.q,\n searchType: \"query\",\n size: filters.limit,\n from: filters.offset,\n sortBy: filters.sortBy,\n classId5List: itemCategoryUid\n ? String(itemCategoryUid)\n : undefined,\n filters: filters.filters?.length\n ? JSON.stringify(filters.filters)\n : undefined,\n sourceFieldsList: defaultSourceFields,\n edgeCache,\n };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.itemSearch.list\",\n async () => {\n const response = await api.openSearch.itemSearch.list(params);\n return response.data;\n },\n filters,\n itemCategoryUid,\n );\n }\n\n async function itemSearchInfinite(\n filters: {\n q: string;\n limit: number;\n sortBy?: string;\n filters?: [string, string][];\n },\n itemCategoryUid?: number | string,\n pageParam = 0,\n ): Promise<SearchPage> {\n const params: Record<string, unknown> = {\n q: filters.q,\n searchType: \"query\",\n size: filters.limit,\n from: pageParam,\n sortBy: filters.sortBy,\n classId5List: itemCategoryUid\n ? String(itemCategoryUid)\n : undefined,\n filters: filters.filters?.length\n ? JSON.stringify(filters.filters)\n : undefined,\n sourceFieldsList: defaultSourceFields,\n edgeCache,\n };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"openSearch.itemSearch.list\",\n async () => {\n const response = await api.openSearch.itemSearch.list(params);\n const { items, totalResults } = response.data;\n const nextOffset = pageParam + filters.limit;\n return {\n data: items,\n total: totalResults,\n nextCursor:\n nextOffset < totalResults ? nextOffset : undefined,\n };\n },\n filters,\n itemCategoryUid,\n pageParam,\n );\n }\n\n return {\n getSearchAttributes,\n getSearchSuggestions,\n itemSearch,\n itemSearchInfinite,\n };\n}\n","import { withServerCache } from \"../cache/with-cache\";\n\nexport interface ShippingAddress {\n address1: string;\n city: string;\n state: string;\n postalCode: string;\n country?: string;\n}\n\n/**\n * The subset of augur-api used by shipping actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface ShippingApiClient {\n ups: {\n ratesShop: {\n get: (params: Record<string, unknown>) => Promise<{ data: unknown }>;\n };\n };\n}\n\nexport interface ShippingActionsConfig {\n /** Warehouse/origin address for rate calculations. */\n fromAddress: ShippingAddress;\n /** UPS service codes to filter results. Default: undefined (return all). */\n defaultServiceCodes?: string[];\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for shipping rate lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n}\n\nexport interface ShippingActions {\n getShippingRates: (\n toAddress: ShippingAddress,\n weight: number,\n serviceCodes?: string[],\n ) => Promise<unknown>;\n}\n\n/**\n * Creates server-side shipping actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/shipping-actions.ts\n * import { createShippingActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const shippingActions = createShippingActions(getAugurClient(), {\n * fromAddress: {\n * address1: \"123 Warehouse Ln\",\n * city: \"Chicago\",\n * state: \"IL\",\n * postalCode: \"60601\",\n * },\n * });\n *\n * // In a server component:\n * const rates = await shippingActions.getShippingRates(\n * { address1: \"456 Main St\", city: \"Denver\", state: \"CO\", postalCode: \"80202\" },\n * 5.0,\n * );\n * ```\n */\nexport function createShippingActions(\n api: ShippingApiClient,\n config: ShippingActionsConfig,\n): ShippingActions {\n const {\n fromAddress,\n defaultServiceCodes,\n cachePrefix = \"\",\n edgeCache = 1,\n redisTtl = 3600,\n } = config;\n\n async function getShippingRates(\n toAddress: ShippingAddress,\n weight: number,\n serviceCodes?: string[],\n ): Promise<unknown> {\n const params = {\n fromAddress,\n toAddress: { ...toAddress, country: toAddress.country ?? \"US\" },\n weight,\n serviceCodes: serviceCodes ?? defaultServiceCodes,\n edgeCache,\n };\n\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"ups.ratesShop.get\",\n async () => {\n const response = await api.ups.ratesShop.get(params);\n return response.data;\n },\n params,\n );\n }\n\n return { getShippingRates };\n}\n","import { withServerCache } from \"../cache/with-cache\";\n\n/**\n * The subset of augur-api used by Joomla content actions.\n * Avoids importing the full SDK type so augur-server stays lightweight.\n */\nexport interface JoomlaApiClient {\n joomla: {\n content: {\n doc: {\n get: (\n articleId: number,\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown }>;\n };\n list: (\n params?: Record<string, unknown>,\n ) => Promise<{ data: unknown[] }>;\n };\n };\n}\n\nexport interface JoomlaActionsConfig {\n /** Cache key prefix (e.g. \"ampro:\"). Default: \"\". */\n cachePrefix?: string;\n /** CDN edge cache value passed to SDK. Default: 1 (hour). */\n edgeCache?: number;\n /** Redis TTL for Joomla lookups in seconds. Default: 3600 (1 hour). */\n redisTtl?: number;\n}\n\nexport interface JoomlaActions {\n getJoomlaContent: (articleId: number) => Promise<unknown>;\n getJoomlaContentList: (\n params?: Record<string, unknown>,\n ) => Promise<unknown[]>;\n}\n\n/**\n * Creates server-side Joomla content actions with Redis caching and edge cache support.\n *\n * Uses `withServerCache` which produces cache keys compatible with augur-hooks'\n * `withCache`, so server-prefetched data is shared with client-side hooks.\n *\n * @example\n * ```ts\n * // lib/joomla-actions.ts\n * import { createJoomlaActions } from \"@simpleapps-com/augur-server\";\n * import { getAugurClient } from \"./augur-client\";\n *\n * export const joomlaActions = createJoomlaActions(getAugurClient(), {\n * cachePrefix: \"ampro:\",\n * });\n *\n * // In a server component:\n * const article = await joomlaActions.getJoomlaContent(42);\n * const articles = await joomlaActions.getJoomlaContentList({ catid: 5 });\n * ```\n */\nexport function createJoomlaActions(\n api: JoomlaApiClient,\n config: JoomlaActionsConfig = {},\n): JoomlaActions {\n const { cachePrefix = \"\", edgeCache = 1, redisTtl = 3600 } = config;\n\n async function getJoomlaContent(\n articleId: number,\n ): Promise<unknown> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"joomla.content.doc.get\",\n async () => {\n const response = await api.joomla.content.doc.get(articleId, {\n edgeCache,\n });\n return response.data;\n },\n articleId,\n );\n }\n\n async function getJoomlaContentList(\n params?: Record<string, unknown>,\n ): Promise<unknown[]> {\n return withServerCache(\n cachePrefix,\n redisTtl,\n \"joomla.content.list\",\n async () => {\n const response = await api.joomla.content.list({\n ...params,\n edgeCache,\n });\n return response.data;\n },\n params,\n );\n }\n\n return { getJoomlaContent, getJoomlaContentList };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simpleapps-com/augur-server",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Server-side utilities for Augur ecommerce sites (Redis caching, SDK helpers, auth)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -37,7 +37,7 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "valibot": "^1.0.0",
40
- "@simpleapps-com/augur-utils": "0.2.5"
40
+ "@simpleapps-com/augur-utils": "0.2.6"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@simpleapps-com/augur-api": "^0.9.6",
@@ -46,7 +46,7 @@
46
46
  "next": ">=16.0.0",
47
47
  "next-auth": "5.0.0-beta.30",
48
48
  "react": "^19.0.0",
49
- "@simpleapps-com/augur-hooks": "0.2.5"
49
+ "@simpleapps-com/augur-hooks": "0.2.6"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "ioredis": {
@@ -69,7 +69,7 @@
69
69
  "tsup": "^8.5.0",
70
70
  "vitest": "^3.2.0",
71
71
  "@augur-packages/tsconfig": "0.0.0",
72
- "@simpleapps-com/augur-hooks": "0.2.5"
72
+ "@simpleapps-com/augur-hooks": "0.2.6"
73
73
  },
74
74
  "scripts": {
75
75
  "build": "tsup",