@simpleapps-com/augur-server 0.2.2 → 0.2.4

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
@@ -1,5 +1,6 @@
1
1
  import { QueryClient } from '@tanstack/react-query';
2
2
  export { QueryOptionsConfig, createQueryOptions, createSuspenseQueryOptions } from './query.js';
3
+ import { TPriceData, TTaxItem, TTax, TCategory, TAttribute, TInvMast, TInvMastDoc, TStockData, TItemAccessory, TStock, TCartLookUp, TCartLine, TProductItem } from '@simpleapps-com/augur-utils';
3
4
 
4
5
  declare const env: "development" | "staging" | "production";
5
6
  declare const isDev: boolean;
@@ -47,4 +48,561 @@ declare function createServerQueryClient(): QueryClient;
47
48
  */
48
49
  declare const getServerQueryClient: () => QueryClient;
49
50
 
50
- export { cacheGet, cacheSet, createServerQueryClient, env, getCircuitState, getServerQueryClient, isDev, isProduction, isRedisConnected, isStaging, sdkCall };
51
+ /**
52
+ * Server-side cache wrapper using augur-server's Redis client.
53
+ *
54
+ * Uses the same cache key format as augur-hooks' `withCache`:
55
+ * `${prefix}sdk:${methodPath}:${fnv1a(stableStringify(keyArgs))}`
56
+ *
57
+ * This means server-side cached data can be read by client-side hooks
58
+ * (and vice versa) when using the same prefix and method path.
59
+ *
60
+ * @param prefix Cache key prefix (e.g. "ampro:"). Empty string if none.
61
+ * @param redisTtl Redis TTL in seconds. 0 or undefined = skip caching.
62
+ * @param methodPath Dot-separated SDK method path (e.g. "pricing.priceEngine.get").
63
+ * @param fn The async function to cache.
64
+ * @param keyArgs Values to hash for the cache key.
65
+ */
66
+ declare function withServerCache<T>(prefix: string, redisTtl: number | undefined, methodPath: string, fn: () => Promise<T>, ...keyArgs: unknown[]): Promise<T>;
67
+
68
+ /**
69
+ * The subset of augur-api used by pricing actions.
70
+ * Avoids importing the full SDK type so augur-server stays lightweight.
71
+ */
72
+ interface PricingApiClient {
73
+ pricing: {
74
+ priceEngine: {
75
+ get: (params: Record<string, unknown>) => Promise<{
76
+ data: TPriceData;
77
+ }>;
78
+ };
79
+ taxEngine: {
80
+ create: (params: Record<string, unknown>) => Promise<{
81
+ data: TTax;
82
+ }>;
83
+ };
84
+ };
85
+ }
86
+ interface PricingActionsConfig {
87
+ /** Default customer ID when none is provided by the caller. */
88
+ defaultCustomerId?: string | number;
89
+ /** Cache key prefix (e.g. "ampro:"). Default: "". */
90
+ cachePrefix?: string;
91
+ /** CDN edge cache value passed to SDK. Default: 2 (hours). */
92
+ edgeCache?: number;
93
+ /** Redis TTL for price lookups in seconds. Default: 3600 (1 hour). */
94
+ redisTtl?: number;
95
+ /** Redis TTL for tax lookups in seconds. Default: 1800 (30 min). */
96
+ taxRedisTtl?: number;
97
+ }
98
+ interface PricingActions {
99
+ getItemPrice: (itemId: string, customerId?: string | number, quantity?: number) => Promise<TPriceData>;
100
+ batchGetItemPrices: (itemIds: string[], customerId?: string | number, quantity?: number) => Promise<Record<string, TPriceData>>;
101
+ getTaxEstimate: (customerId: string | number, postalCode: string, items: TTaxItem[]) => Promise<TTax>;
102
+ }
103
+ /**
104
+ * Creates server-side pricing actions with Redis caching and edge cache support.
105
+ *
106
+ * Uses `withServerCache` which produces cache keys compatible with augur-hooks'
107
+ * `withCache`, so server-prefetched data is shared with client-side hooks.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * // lib/pricing-actions.ts
112
+ * import { createPricingActions } from "@simpleapps-com/augur-server";
113
+ * import { getAugurClient } from "./augur-client";
114
+ *
115
+ * export const pricingActions = createPricingActions(getAugurClient(), {
116
+ * defaultCustomerId: process.env.NEXT_PUBLIC_DEFAULT_CUSTOMER_ID,
117
+ * cachePrefix: "ampro:",
118
+ * });
119
+ *
120
+ * // In a server component:
121
+ * const price = await pricingActions.getItemPrice("ITEM-1");
122
+ * const prices = await pricingActions.batchGetItemPrices(["ITEM-1", "ITEM-2"]);
123
+ * ```
124
+ */
125
+ declare function createPricingActions(api: PricingApiClient, config?: PricingActionsConfig): PricingActions;
126
+
127
+ /**
128
+ * The subset of augur-api used by item actions.
129
+ * Avoids importing the full SDK type so augur-server stays lightweight.
130
+ */
131
+ interface ItemsApiClient {
132
+ items: {
133
+ categories: {
134
+ get: (uid: number, params?: Record<string, unknown>) => Promise<{
135
+ data: TCategory;
136
+ }>;
137
+ lookup: {
138
+ get: (params: Record<string, unknown>) => Promise<{
139
+ data: unknown;
140
+ }>;
141
+ };
142
+ items: {
143
+ list: (params: Record<string, unknown>) => Promise<{
144
+ data: unknown;
145
+ }>;
146
+ };
147
+ attributes: {
148
+ list: (uid: number, params?: Record<string, unknown>) => Promise<{
149
+ data: {
150
+ attributes: TAttribute[];
151
+ };
152
+ }>;
153
+ };
154
+ };
155
+ invMast: {
156
+ get: (uid: number, params?: Record<string, unknown>) => Promise<{
157
+ data: TInvMast;
158
+ }>;
159
+ doc: {
160
+ list: (uid: number, params?: Record<string, unknown>) => Promise<{
161
+ data: TInvMastDoc;
162
+ }>;
163
+ };
164
+ stock: {
165
+ list: (uid: number, params?: Record<string, unknown>) => Promise<{
166
+ data: TStock;
167
+ }>;
168
+ };
169
+ faq: {
170
+ list: (uid: number, params?: Record<string, unknown>) => Promise<{
171
+ data: unknown[];
172
+ }>;
173
+ };
174
+ invSub: {
175
+ list: (uid: number, params?: Record<string, unknown>) => Promise<{
176
+ data: unknown[];
177
+ }>;
178
+ };
179
+ invAccessory: {
180
+ list: (uid: number, params?: Record<string, unknown>) => Promise<{
181
+ data: TItemAccessory[];
182
+ }>;
183
+ };
184
+ similar: {
185
+ list: (uid: number, params?: Record<string, unknown>) => Promise<{
186
+ data: unknown[];
187
+ }>;
188
+ };
189
+ };
190
+ };
191
+ }
192
+ interface ItemActionsConfig {
193
+ /** Cache key prefix (e.g. "ampro:"). Default: "". */
194
+ cachePrefix?: string;
195
+ /** CDN edge cache value for most calls. Default: 1 (hour). */
196
+ edgeCache?: number;
197
+ /** CDN edge cache for rarely-changing data like FAQs. Default: 8 (hours). */
198
+ longEdgeCache?: number;
199
+ /** Redis TTL for most calls in seconds. Default: 3600 (1 hour). */
200
+ redisTtl?: number;
201
+ /** Redis TTL for rarely-changing data in seconds. Default: 28800 (8 hours). */
202
+ longRedisTtl?: number;
203
+ }
204
+ interface ItemActions {
205
+ itemCategoryLookup: (path: string) => Promise<unknown>;
206
+ getItemCategory: (uid: number, options?: Record<string, unknown>) => Promise<TCategory>;
207
+ getCategoryItems: (uid: number, filters: Record<string, unknown>) => Promise<unknown>;
208
+ getItemAttributes: (categoryUid: number) => Promise<TAttribute[]>;
209
+ getInvMast: (uid: number) => Promise<TInvMast>;
210
+ getInvMastDoc: (params: {
211
+ invMastUid?: number;
212
+ itemId?: string;
213
+ }) => Promise<TInvMastDoc>;
214
+ getStock: (invMastUid: number) => Promise<TStockData[]>;
215
+ getStockCompanySummary: (invMastUid: number) => Promise<Record<string, number>>;
216
+ getItemFaqs: (invMastUid: number) => Promise<unknown[]>;
217
+ getItemSubstitutes: (invMastUid: number) => Promise<unknown[]>;
218
+ getItemAccessories: (invMastUid: number) => Promise<TItemAccessory[]>;
219
+ getSimilarItems: (invMastUid: number) => Promise<unknown[]>;
220
+ batchGetInvMastDocs: (params: {
221
+ invMastUid?: number;
222
+ itemId?: string;
223
+ }[]) => Promise<Record<string, TInvMastDoc>>;
224
+ batchGetStockData: (invMastUids: number[]) => Promise<Record<number, TStockData[]>>;
225
+ }
226
+ /**
227
+ * Creates server-side item actions with Redis caching and edge cache support.
228
+ *
229
+ * Uses `withServerCache` which produces cache keys compatible with augur-hooks'
230
+ * `withCache`, so server-prefetched data is shared with client-side hooks.
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * // lib/item-actions.ts
235
+ * import { createItemActions } from "@simpleapps-com/augur-server";
236
+ * import { getAugurClient } from "./augur-client";
237
+ *
238
+ * export const itemActions = createItemActions(getAugurClient(), {
239
+ * cachePrefix: "ampro:",
240
+ * });
241
+ *
242
+ * // In a server component:
243
+ * const category = await itemActions.getItemCategory(123);
244
+ * const doc = await itemActions.getInvMastDoc({ itemId: "ITEM-1" });
245
+ * ```
246
+ */
247
+ declare function createItemActions(api: ItemsApiClient, config?: ItemActionsConfig): ItemActions;
248
+
249
+ /**
250
+ * The subset of augur-api used by commerce actions.
251
+ * Avoids importing the full SDK type so augur-server stays lightweight.
252
+ */
253
+ interface CommerceApiClient {
254
+ commerce: {
255
+ cartHdr: {
256
+ lookup: {
257
+ get: (params: Record<string, unknown>) => Promise<{
258
+ data: TCartLookUp;
259
+ }>;
260
+ };
261
+ alsoBought: {
262
+ get: (cartHdrUid: number, params?: Record<string, unknown>) => Promise<{
263
+ data: unknown[];
264
+ }>;
265
+ };
266
+ };
267
+ cartLine: {
268
+ get: (cartHdrUid: number) => Promise<{
269
+ data: TCartLine[];
270
+ }>;
271
+ add: {
272
+ create: (cartHdrUid: number, params: Record<string, unknown>) => Promise<{
273
+ data: unknown;
274
+ }>;
275
+ };
276
+ update: {
277
+ create: (cartHdrUid: number, params: Record<string, unknown>) => Promise<{
278
+ data: unknown;
279
+ }>;
280
+ };
281
+ delete: (cartHdrUid: number) => Promise<{
282
+ data: unknown;
283
+ }>;
284
+ };
285
+ checkout: {
286
+ create: (params: Record<string, unknown>) => Promise<{
287
+ data: unknown;
288
+ }>;
289
+ };
290
+ };
291
+ }
292
+ interface CommerceActionsConfig {
293
+ defaultContactId?: string | number;
294
+ defaultCustomerId?: string | number;
295
+ /** Optional UOM conversion function. E.g. (uom) => uom === "EA" ? "EACH" : uom */
296
+ convertUnitOfMeasure?: (uom: string) => string;
297
+ }
298
+ interface CommerceActions {
299
+ cartHdrLookup: (params: {
300
+ userId?: string | number;
301
+ cartToken?: string;
302
+ contactId?: string | number;
303
+ customerId?: string | number;
304
+ }) => Promise<TCartLookUp>;
305
+ getCartLines: (cartHdrUid: number) => Promise<TCartLine[]>;
306
+ addToCart: (cartHdrUid: number, items: {
307
+ itemId: string;
308
+ quantity: number;
309
+ unitOfMeasure: string;
310
+ }[]) => Promise<unknown>;
311
+ updateCartLines: (cartHdrUid: number, lines: {
312
+ lineNo: number;
313
+ quantity: number;
314
+ unitOfMeasure: string;
315
+ }[]) => Promise<unknown>;
316
+ deleteCartItems: (cartHdrUid: number) => Promise<void>;
317
+ getCartAlsoBought: (cartHdrUid: number) => Promise<unknown[]>;
318
+ checkoutOrder: (cartHdrUid: number, data: Record<string, unknown>) => Promise<unknown>;
319
+ }
320
+ /**
321
+ * Creates server-side commerce actions for cart operations.
322
+ *
323
+ * Unlike pricing actions, commerce actions do NOT use caching because
324
+ * cart operations are real-time and must always reflect current state.
325
+ *
326
+ * @example
327
+ * ```ts
328
+ * // lib/commerce-actions.ts
329
+ * import { createCommerceActions } from "@simpleapps-com/augur-server";
330
+ * import { getAugurClient } from "./augur-client";
331
+ *
332
+ * export const commerceActions = createCommerceActions(getAugurClient(), {
333
+ * defaultContactId: process.env.NEXT_PUBLIC_DEFAULT_CONTACT_ID,
334
+ * defaultCustomerId: process.env.NEXT_PUBLIC_DEFAULT_CUSTOMER_ID,
335
+ * convertUnitOfMeasure: (uom) => uom === "EA" ? "EACH" : uom,
336
+ * });
337
+ *
338
+ * // In a server action:
339
+ * const cart = await commerceActions.cartHdrLookup({ userId: 123 });
340
+ * const lines = await commerceActions.getCartLines(cart.cartHdrUid);
341
+ * ```
342
+ */
343
+ declare function createCommerceActions(api: CommerceApiClient, config?: CommerceActionsConfig): CommerceActions;
344
+
345
+ /**
346
+ * The subset of augur-api used by order actions.
347
+ * Avoids importing the full SDK type so augur-server stays lightweight.
348
+ */
349
+ interface OrderApiClient {
350
+ orders: {
351
+ oeHdr: {
352
+ doc: {
353
+ get: (params: Record<string, unknown>) => Promise<{
354
+ data: unknown;
355
+ }>;
356
+ };
357
+ };
358
+ };
359
+ }
360
+ interface OrderActionsConfig {
361
+ /** Cache key prefix (e.g. "ampro:"). Default: "". */
362
+ cachePrefix?: string;
363
+ /** CDN edge cache value passed to SDK. Default: 1 (hour). */
364
+ edgeCache?: number;
365
+ /** Redis TTL for order doc lookups in seconds. Default: 3600 (1 hour). */
366
+ redisTtl?: number;
367
+ }
368
+ interface OrderActions {
369
+ getOrderDoc: (orderNo: string, zipCode: string) => Promise<unknown>;
370
+ }
371
+ /**
372
+ * Creates server-side order actions with Redis caching and edge cache support.
373
+ *
374
+ * Uses `withServerCache` which produces cache keys compatible with augur-hooks'
375
+ * `withCache`, so server-prefetched data is shared with client-side hooks.
376
+ *
377
+ * @example
378
+ * ```ts
379
+ * // lib/order-actions.ts
380
+ * import { createOrderActions } from "@simpleapps-com/augur-server";
381
+ * import { getAugurClient } from "./augur-client";
382
+ *
383
+ * export const orderActions = createOrderActions(getAugurClient(), {
384
+ * cachePrefix: "ampro:",
385
+ * });
386
+ *
387
+ * // In a server component:
388
+ * const doc = await orderActions.getOrderDoc("12345", "90210");
389
+ * ```
390
+ */
391
+ declare function createOrderActions(api: OrderApiClient, config?: OrderActionsConfig): OrderActions;
392
+
393
+ /**
394
+ * The subset of augur-api used by search actions.
395
+ * Avoids importing the full SDK type so augur-server stays lightweight.
396
+ */
397
+ interface SearchApiClient {
398
+ openSearch: {
399
+ itemSearch: {
400
+ list: (params: Record<string, unknown>) => Promise<{
401
+ data: {
402
+ items: TProductItem[];
403
+ totalResults: number;
404
+ };
405
+ }>;
406
+ attributes: {
407
+ list: (params: Record<string, unknown>) => Promise<{
408
+ data: {
409
+ attributes: TAttribute[];
410
+ };
411
+ }>;
412
+ };
413
+ };
414
+ suggestions: {
415
+ suggest: {
416
+ list: (params: Record<string, unknown>) => Promise<{
417
+ data: {
418
+ data: unknown[];
419
+ total: number;
420
+ totalResults: number;
421
+ };
422
+ }>;
423
+ };
424
+ };
425
+ };
426
+ }
427
+ interface SearchActionsConfig {
428
+ /** Cache key prefix (e.g. "ampro:"). Default: "". */
429
+ cachePrefix?: string;
430
+ /** CDN edge cache value passed to SDK. Default: 1 (hour). */
431
+ edgeCache?: number;
432
+ /** Redis TTL for search lookups in seconds. Default: 3600 (1 hour). */
433
+ redisTtl?: number;
434
+ /** Default source fields for item search. Default: "display_desc". */
435
+ defaultSourceFields?: string;
436
+ }
437
+ /** Paginated response for infinite scroll. */
438
+ interface SearchPage {
439
+ data: TProductItem[];
440
+ total: number;
441
+ nextCursor?: number;
442
+ }
443
+ interface SearchActions {
444
+ getSearchAttributes: (q: string) => Promise<TAttribute[]>;
445
+ getSearchSuggestions: (q: string, limit?: number, offset?: number) => Promise<{
446
+ data: unknown[];
447
+ total: number;
448
+ totalResults: number;
449
+ }>;
450
+ itemSearch: (filters: {
451
+ q: string;
452
+ limit: number;
453
+ offset: number;
454
+ sortBy?: string;
455
+ filters?: [string, string][];
456
+ }, itemCategoryUid?: number | string) => Promise<{
457
+ items: TProductItem[];
458
+ totalResults: number;
459
+ }>;
460
+ itemSearchInfinite: (filters: {
461
+ q: string;
462
+ limit: number;
463
+ sortBy?: string;
464
+ filters?: [string, string][];
465
+ }, itemCategoryUid?: number | string, pageParam?: number) => Promise<SearchPage>;
466
+ }
467
+ /**
468
+ * Creates server-side search actions with Redis caching and edge cache support.
469
+ *
470
+ * Uses `withServerCache` which produces cache keys compatible with augur-hooks'
471
+ * `withCache`, so server-prefetched data is shared with client-side hooks.
472
+ *
473
+ * @example
474
+ * ```ts
475
+ * // lib/search-actions.ts
476
+ * import { createSearchActions } from "@simpleapps-com/augur-server";
477
+ * import { getAugurClient } from "./augur-client";
478
+ *
479
+ * export const searchActions = createSearchActions(getAugurClient(), {
480
+ * cachePrefix: "ampro:",
481
+ * });
482
+ *
483
+ * // In a server component:
484
+ * const attrs = await searchActions.getSearchAttributes("widget");
485
+ * const results = await searchActions.itemSearch({ q: "widget", limit: 20, offset: 0 });
486
+ * ```
487
+ */
488
+ declare function createSearchActions(api: SearchApiClient, config?: SearchActionsConfig): SearchActions;
489
+
490
+ interface ShippingAddress {
491
+ address1: string;
492
+ city: string;
493
+ state: string;
494
+ postalCode: string;
495
+ country?: string;
496
+ }
497
+ /**
498
+ * The subset of augur-api used by shipping actions.
499
+ * Avoids importing the full SDK type so augur-server stays lightweight.
500
+ */
501
+ interface ShippingApiClient {
502
+ ups: {
503
+ ratesShop: {
504
+ get: (params: Record<string, unknown>) => Promise<{
505
+ data: unknown;
506
+ }>;
507
+ };
508
+ };
509
+ }
510
+ interface ShippingActionsConfig {
511
+ /** Warehouse/origin address for rate calculations. */
512
+ fromAddress: ShippingAddress;
513
+ /** UPS service codes to filter results. Default: undefined (return all). */
514
+ defaultServiceCodes?: string[];
515
+ /** Cache key prefix (e.g. "ampro:"). Default: "". */
516
+ cachePrefix?: string;
517
+ /** CDN edge cache value passed to SDK. Default: 1 (hour). */
518
+ edgeCache?: number;
519
+ /** Redis TTL for shipping rate lookups in seconds. Default: 3600 (1 hour). */
520
+ redisTtl?: number;
521
+ }
522
+ interface ShippingActions {
523
+ getShippingRates: (toAddress: ShippingAddress, weight: number, serviceCodes?: string[]) => Promise<unknown>;
524
+ }
525
+ /**
526
+ * Creates server-side shipping actions with Redis caching and edge cache support.
527
+ *
528
+ * Uses `withServerCache` which produces cache keys compatible with augur-hooks'
529
+ * `withCache`, so server-prefetched data is shared with client-side hooks.
530
+ *
531
+ * @example
532
+ * ```ts
533
+ * // lib/shipping-actions.ts
534
+ * import { createShippingActions } from "@simpleapps-com/augur-server";
535
+ * import { getAugurClient } from "./augur-client";
536
+ *
537
+ * export const shippingActions = createShippingActions(getAugurClient(), {
538
+ * fromAddress: {
539
+ * address1: "123 Warehouse Ln",
540
+ * city: "Chicago",
541
+ * state: "IL",
542
+ * postalCode: "60601",
543
+ * },
544
+ * });
545
+ *
546
+ * // In a server component:
547
+ * const rates = await shippingActions.getShippingRates(
548
+ * { address1: "456 Main St", city: "Denver", state: "CO", postalCode: "80202" },
549
+ * 5.0,
550
+ * );
551
+ * ```
552
+ */
553
+ declare function createShippingActions(api: ShippingApiClient, config: ShippingActionsConfig): ShippingActions;
554
+
555
+ /**
556
+ * The subset of augur-api used by Joomla content actions.
557
+ * Avoids importing the full SDK type so augur-server stays lightweight.
558
+ */
559
+ interface JoomlaApiClient {
560
+ joomla: {
561
+ content: {
562
+ doc: {
563
+ get: (articleId: number, params?: Record<string, unknown>) => Promise<{
564
+ data: unknown;
565
+ }>;
566
+ };
567
+ list: (params?: Record<string, unknown>) => Promise<{
568
+ data: unknown[];
569
+ }>;
570
+ };
571
+ };
572
+ }
573
+ interface JoomlaActionsConfig {
574
+ /** Cache key prefix (e.g. "ampro:"). Default: "". */
575
+ cachePrefix?: string;
576
+ /** CDN edge cache value passed to SDK. Default: 1 (hour). */
577
+ edgeCache?: number;
578
+ /** Redis TTL for Joomla lookups in seconds. Default: 3600 (1 hour). */
579
+ redisTtl?: number;
580
+ }
581
+ interface JoomlaActions {
582
+ getJoomlaContent: (articleId: number) => Promise<unknown>;
583
+ getJoomlaContentList: (params?: Record<string, unknown>) => Promise<unknown[]>;
584
+ }
585
+ /**
586
+ * Creates server-side Joomla content actions with Redis caching and edge cache support.
587
+ *
588
+ * Uses `withServerCache` which produces cache keys compatible with augur-hooks'
589
+ * `withCache`, so server-prefetched data is shared with client-side hooks.
590
+ *
591
+ * @example
592
+ * ```ts
593
+ * // lib/joomla-actions.ts
594
+ * import { createJoomlaActions } from "@simpleapps-com/augur-server";
595
+ * import { getAugurClient } from "./augur-client";
596
+ *
597
+ * export const joomlaActions = createJoomlaActions(getAugurClient(), {
598
+ * cachePrefix: "ampro:",
599
+ * });
600
+ *
601
+ * // In a server component:
602
+ * const article = await joomlaActions.getJoomlaContent(42);
603
+ * const articles = await joomlaActions.getJoomlaContentList({ catid: 5 });
604
+ * ```
605
+ */
606
+ declare function createJoomlaActions(api: JoomlaApiClient, config?: JoomlaActionsConfig): JoomlaActions;
607
+
608
+ export { type CommerceActions, type CommerceActionsConfig, type CommerceApiClient, type ItemActions, type ItemActionsConfig, type ItemsApiClient, type JoomlaActions, type JoomlaActionsConfig, type JoomlaApiClient, type OrderActions, type OrderActionsConfig, type OrderApiClient, type PricingActions, type PricingActionsConfig, type PricingApiClient, type SearchActions, type SearchActionsConfig, type SearchApiClient, type SearchPage, type ShippingActions, type ShippingActionsConfig, type ShippingAddress, type ShippingApiClient, cacheGet, cacheSet, createCommerceActions, createItemActions, createJoomlaActions, createOrderActions, createPricingActions, createSearchActions, createServerQueryClient, createShippingActions, env, getCircuitState, getServerQueryClient, isDev, isProduction, isRedisConnected, isStaging, sdkCall, withServerCache };
package/dist/index.js CHANGED
@@ -155,11 +155,603 @@ function createServerQueryClient() {
155
155
  var getServerQueryClient = cache(
156
156
  () => createServerQueryClient()
157
157
  );
158
+
159
+ // src/cache/with-cache.ts
160
+ function fnv1a(str) {
161
+ let h = 2166136261;
162
+ for (let i = 0; i < str.length; i++) {
163
+ h ^= str.charCodeAt(i);
164
+ h = Math.imul(h, 16777619);
165
+ }
166
+ return (h >>> 0).toString(16).padStart(8, "0");
167
+ }
168
+ function stableStringify(value) {
169
+ if (value === null || value === void 0) return JSON.stringify(value);
170
+ if (typeof value !== "object") return JSON.stringify(value);
171
+ if (Array.isArray(value)) {
172
+ return `[${value.map(stableStringify).join(",")}]`;
173
+ }
174
+ const obj = value;
175
+ const keys = Object.keys(obj).sort();
176
+ const entries = keys.map(
177
+ (key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`
178
+ );
179
+ return `{${entries.join(",")}}`;
180
+ }
181
+ async function withServerCache(prefix, redisTtl, methodPath, fn, ...keyArgs) {
182
+ if (!redisTtl) return fn();
183
+ const key = `${prefix}sdk:${methodPath}:${fnv1a(stableStringify(keyArgs))}`;
184
+ try {
185
+ const cached = await cacheGet(key);
186
+ if (cached != null) return JSON.parse(cached);
187
+ } catch {
188
+ }
189
+ const result = await fn();
190
+ try {
191
+ cacheSet(key, JSON.stringify(result), redisTtl).catch(() => {
192
+ });
193
+ } catch {
194
+ }
195
+ return result;
196
+ }
197
+
198
+ // src/actions/pricing.ts
199
+ function resolveCustomerId(explicit, fallback) {
200
+ const raw = explicit ?? fallback;
201
+ const num = Number(raw);
202
+ return num > 0 ? num : 0;
203
+ }
204
+ function createPricingActions(api, config = {}) {
205
+ const {
206
+ defaultCustomerId,
207
+ cachePrefix = "",
208
+ edgeCache = 2,
209
+ redisTtl = 3600,
210
+ taxRedisTtl = 1800
211
+ } = config;
212
+ async function getItemPrice(itemId, customerId, quantity = 1) {
213
+ const custId = resolveCustomerId(customerId, defaultCustomerId);
214
+ const params = { customerId: custId, itemId, quantity, edgeCache };
215
+ return withServerCache(
216
+ cachePrefix,
217
+ redisTtl,
218
+ "pricing.priceEngine.get",
219
+ async () => {
220
+ const response = await api.pricing.priceEngine.get(params);
221
+ return response.data;
222
+ },
223
+ params
224
+ );
225
+ }
226
+ async function batchGetItemPrices(itemIds, customerId, quantity = 1) {
227
+ const results = await Promise.all(
228
+ itemIds.map((id) => getItemPrice(id, customerId, quantity).then((data) => [id, data]).catch(() => [id, null]))
229
+ );
230
+ const out = {};
231
+ for (const [id, data] of results) {
232
+ if (data) out[id] = data;
233
+ }
234
+ return out;
235
+ }
236
+ async function getTaxEstimate(customerId, postalCode, items) {
237
+ const custId = resolveCustomerId(customerId, defaultCustomerId);
238
+ const params = { customerId: custId, postalCode, items };
239
+ return withServerCache(
240
+ cachePrefix,
241
+ taxRedisTtl,
242
+ "pricing.taxEngine.create",
243
+ async () => {
244
+ const response = await api.pricing.taxEngine.create(params);
245
+ return response.data;
246
+ },
247
+ params
248
+ );
249
+ }
250
+ return { getItemPrice, batchGetItemPrices, getTaxEstimate };
251
+ }
252
+
253
+ // src/actions/items.ts
254
+ function createItemActions(api, config = {}) {
255
+ const {
256
+ cachePrefix = "",
257
+ edgeCache = 1,
258
+ longEdgeCache = 8,
259
+ redisTtl = 3600,
260
+ longRedisTtl = 28800
261
+ } = config;
262
+ async function itemCategoryLookup(path) {
263
+ return withServerCache(
264
+ cachePrefix,
265
+ redisTtl,
266
+ "items.categories.lookup.get",
267
+ async () => {
268
+ const response = await api.items.categories.lookup.get({
269
+ path,
270
+ edgeCache
271
+ });
272
+ return response.data;
273
+ },
274
+ path
275
+ );
276
+ }
277
+ async function getItemCategory(uid, options) {
278
+ return withServerCache(
279
+ cachePrefix,
280
+ redisTtl,
281
+ "items.categories.get",
282
+ async () => {
283
+ const response = await api.items.categories.get(uid, {
284
+ ...options,
285
+ edgeCache
286
+ });
287
+ return response.data;
288
+ },
289
+ uid,
290
+ options
291
+ );
292
+ }
293
+ async function getCategoryItems(uid, filters) {
294
+ return withServerCache(
295
+ cachePrefix,
296
+ redisTtl,
297
+ "items.categories.items.list",
298
+ async () => {
299
+ const response = await api.items.categories.items.list({
300
+ ...filters,
301
+ itemCategoryUid: uid,
302
+ edgeCache
303
+ });
304
+ return response.data;
305
+ },
306
+ uid,
307
+ filters
308
+ );
309
+ }
310
+ async function getItemAttributes(categoryUid) {
311
+ return withServerCache(
312
+ cachePrefix,
313
+ redisTtl,
314
+ "items.categories.attributes.list",
315
+ async () => {
316
+ const response = await api.items.categories.attributes.list(
317
+ categoryUid,
318
+ { edgeCache }
319
+ );
320
+ return response.data.attributes;
321
+ },
322
+ categoryUid
323
+ );
324
+ }
325
+ async function getInvMast(uid) {
326
+ return withServerCache(
327
+ cachePrefix,
328
+ redisTtl,
329
+ "items.invMast.get",
330
+ async () => {
331
+ const response = await api.items.invMast.get(uid, { edgeCache: 4 });
332
+ return response.data;
333
+ },
334
+ uid
335
+ );
336
+ }
337
+ async function getInvMastDoc(params) {
338
+ return withServerCache(
339
+ cachePrefix,
340
+ redisTtl,
341
+ "items.invMast.doc.list",
342
+ async () => {
343
+ const response = await api.items.invMast.doc.list(
344
+ params.invMastUid ?? 0,
345
+ { itemId: params.itemId, edgeCache: 4 }
346
+ );
347
+ return response.data;
348
+ },
349
+ params.invMastUid,
350
+ params.itemId
351
+ );
352
+ }
353
+ async function getStock(invMastUid) {
354
+ return withServerCache(
355
+ cachePrefix,
356
+ redisTtl,
357
+ "items.invMast.stock.list",
358
+ async () => {
359
+ const response = await api.items.invMast.stock.list(invMastUid, {
360
+ edgeCache
361
+ });
362
+ return response.data?.stockData;
363
+ },
364
+ invMastUid
365
+ );
366
+ }
367
+ async function getStockCompanySummary(invMastUid) {
368
+ return withServerCache(
369
+ cachePrefix,
370
+ redisTtl,
371
+ "items.invMast.stock.list.companySummary",
372
+ async () => {
373
+ const response = await api.items.invMast.stock.list(invMastUid, {
374
+ edgeCache
375
+ });
376
+ return response.data?.companySummary;
377
+ },
378
+ invMastUid
379
+ );
380
+ }
381
+ async function getItemFaqs(invMastUid) {
382
+ return withServerCache(
383
+ cachePrefix,
384
+ longRedisTtl,
385
+ "items.invMast.faq.list",
386
+ async () => {
387
+ const response = await api.items.invMast.faq.list(invMastUid, {
388
+ edgeCache: longEdgeCache
389
+ });
390
+ return response.data;
391
+ },
392
+ invMastUid
393
+ );
394
+ }
395
+ async function getItemSubstitutes(invMastUid) {
396
+ return withServerCache(
397
+ cachePrefix,
398
+ longRedisTtl,
399
+ "items.invMast.invSub.list",
400
+ async () => {
401
+ const response = await api.items.invMast.invSub.list(invMastUid, {
402
+ edgeCache: longEdgeCache
403
+ });
404
+ return response.data;
405
+ },
406
+ invMastUid
407
+ );
408
+ }
409
+ async function getItemAccessories(invMastUid) {
410
+ return withServerCache(
411
+ cachePrefix,
412
+ redisTtl,
413
+ "items.invMast.invAccessory.list",
414
+ async () => {
415
+ const response = await api.items.invMast.invAccessory.list(
416
+ invMastUid,
417
+ { edgeCache }
418
+ );
419
+ return response.data;
420
+ },
421
+ invMastUid
422
+ );
423
+ }
424
+ async function getSimilarItems(invMastUid) {
425
+ return withServerCache(
426
+ cachePrefix,
427
+ longRedisTtl,
428
+ "items.invMast.similar.list",
429
+ async () => {
430
+ const response = await api.items.invMast.similar.list(invMastUid, {
431
+ edgeCache: longEdgeCache
432
+ });
433
+ return response.data;
434
+ },
435
+ invMastUid
436
+ );
437
+ }
438
+ async function batchGetInvMastDocs(params) {
439
+ const results = await Promise.all(
440
+ params.map(
441
+ (p) => getInvMastDoc(p).then((data) => [p.itemId ?? String(p.invMastUid), data]).catch(() => [p.itemId ?? String(p.invMastUid), void 0])
442
+ )
443
+ );
444
+ const out = {};
445
+ for (const [key, data] of results) {
446
+ if (data) out[key] = data;
447
+ }
448
+ return out;
449
+ }
450
+ async function batchGetStockData(invMastUids) {
451
+ const results = await Promise.all(
452
+ invMastUids.map(
453
+ (uid) => getStock(uid).then((data) => [uid, data]).catch(() => [uid, void 0])
454
+ )
455
+ );
456
+ const out = {};
457
+ for (const [uid, data] of results) {
458
+ if (data) out[uid] = data;
459
+ }
460
+ return out;
461
+ }
462
+ return {
463
+ itemCategoryLookup,
464
+ getItemCategory,
465
+ getCategoryItems,
466
+ getItemAttributes,
467
+ getInvMast,
468
+ getInvMastDoc,
469
+ getStock,
470
+ getStockCompanySummary,
471
+ getItemFaqs,
472
+ getItemSubstitutes,
473
+ getItemAccessories,
474
+ getSimilarItems,
475
+ batchGetInvMastDocs,
476
+ batchGetStockData
477
+ };
478
+ }
479
+
480
+ // src/actions/commerce.ts
481
+ function createCommerceActions(api, config = {}) {
482
+ const { defaultContactId, defaultCustomerId, convertUnitOfMeasure } = config;
483
+ async function cartHdrLookup(params) {
484
+ const lookupParams = { ...params };
485
+ if (lookupParams.contactId == null && defaultContactId != null) {
486
+ lookupParams.contactId = defaultContactId;
487
+ }
488
+ if (lookupParams.customerId == null && defaultCustomerId != null) {
489
+ lookupParams.customerId = defaultCustomerId;
490
+ }
491
+ const response = await api.commerce.cartHdr.lookup.get(lookupParams);
492
+ return response.data;
493
+ }
494
+ async function getCartLines(cartHdrUid) {
495
+ const response = await api.commerce.cartLine.get(cartHdrUid);
496
+ return response.data;
497
+ }
498
+ async function addToCart(cartHdrUid, items) {
499
+ try {
500
+ const mappedItems = items.map((item) => ({
501
+ ...item,
502
+ unitOfMeasure: convertUnitOfMeasure ? convertUnitOfMeasure(item.unitOfMeasure) : item.unitOfMeasure
503
+ }));
504
+ const response = await api.commerce.cartLine.add.create(
505
+ cartHdrUid,
506
+ { items: mappedItems }
507
+ );
508
+ return response.data;
509
+ } catch {
510
+ return void 0;
511
+ }
512
+ }
513
+ async function updateCartLines(cartHdrUid, lines) {
514
+ try {
515
+ const mappedLines = lines.map((line) => ({
516
+ ...line,
517
+ unitOfMeasure: convertUnitOfMeasure ? convertUnitOfMeasure(line.unitOfMeasure) : line.unitOfMeasure
518
+ }));
519
+ const response = await api.commerce.cartLine.update.create(
520
+ cartHdrUid,
521
+ { lines: mappedLines }
522
+ );
523
+ return response.data;
524
+ } catch {
525
+ return void 0;
526
+ }
527
+ }
528
+ async function deleteCartItems(cartHdrUid) {
529
+ try {
530
+ await api.commerce.cartLine.delete(cartHdrUid);
531
+ } catch {
532
+ }
533
+ }
534
+ async function getCartAlsoBought(cartHdrUid) {
535
+ const response = await api.commerce.cartHdr.alsoBought.get(cartHdrUid);
536
+ return response.data;
537
+ }
538
+ async function checkoutOrder(cartHdrUid, data) {
539
+ try {
540
+ const response = await api.commerce.checkout.create({
541
+ ...data,
542
+ cartHdrUid
543
+ });
544
+ return response.data;
545
+ } catch {
546
+ return void 0;
547
+ }
548
+ }
549
+ return {
550
+ cartHdrLookup,
551
+ getCartLines,
552
+ addToCart,
553
+ updateCartLines,
554
+ deleteCartItems,
555
+ getCartAlsoBought,
556
+ checkoutOrder
557
+ };
558
+ }
559
+
560
+ // src/actions/orders.ts
561
+ function createOrderActions(api, config = {}) {
562
+ const { cachePrefix = "", edgeCache = 1, redisTtl = 3600 } = config;
563
+ async function getOrderDoc(orderNo, zipCode) {
564
+ const params = { orderNo, zipCode, edgeCache };
565
+ return withServerCache(
566
+ cachePrefix,
567
+ redisTtl,
568
+ "orders.oeHdr.doc.get",
569
+ async () => {
570
+ const response = await api.orders.oeHdr.doc.get(params);
571
+ return response.data;
572
+ },
573
+ params
574
+ );
575
+ }
576
+ return { getOrderDoc };
577
+ }
578
+
579
+ // src/actions/search.ts
580
+ function createSearchActions(api, config = {}) {
581
+ const {
582
+ cachePrefix = "",
583
+ edgeCache = 1,
584
+ redisTtl = 3600,
585
+ defaultSourceFields = "display_desc"
586
+ } = config;
587
+ async function getSearchAttributes(q) {
588
+ const params = { q, edgeCache };
589
+ return withServerCache(
590
+ cachePrefix,
591
+ redisTtl,
592
+ "openSearch.itemSearch.attributes.list",
593
+ async () => {
594
+ const response = await api.openSearch.itemSearch.attributes.list(params);
595
+ return response.data.attributes;
596
+ },
597
+ q
598
+ );
599
+ }
600
+ async function getSearchSuggestions(q, limit, offset) {
601
+ const params = { q, edgeCache };
602
+ if (limit !== void 0) params.size = limit;
603
+ if (offset !== void 0) params.from = offset;
604
+ return withServerCache(
605
+ cachePrefix,
606
+ redisTtl,
607
+ "openSearch.suggestions.suggest.list",
608
+ async () => {
609
+ const response = await api.openSearch.suggestions.suggest.list(params);
610
+ return response.data;
611
+ },
612
+ q
613
+ );
614
+ }
615
+ async function itemSearch(filters, itemCategoryUid) {
616
+ const params = {
617
+ q: filters.q,
618
+ searchType: "query",
619
+ size: filters.limit,
620
+ from: filters.offset,
621
+ sortBy: filters.sortBy,
622
+ classId5List: itemCategoryUid ? String(itemCategoryUid) : void 0,
623
+ filters: filters.filters?.length ? JSON.stringify(filters.filters) : void 0,
624
+ sourceFieldsList: defaultSourceFields,
625
+ edgeCache
626
+ };
627
+ return withServerCache(
628
+ cachePrefix,
629
+ redisTtl,
630
+ "openSearch.itemSearch.list",
631
+ async () => {
632
+ const response = await api.openSearch.itemSearch.list(params);
633
+ return response.data;
634
+ },
635
+ filters,
636
+ itemCategoryUid
637
+ );
638
+ }
639
+ async function itemSearchInfinite(filters, itemCategoryUid, pageParam = 0) {
640
+ const params = {
641
+ q: filters.q,
642
+ searchType: "query",
643
+ size: filters.limit,
644
+ from: pageParam,
645
+ sortBy: filters.sortBy,
646
+ classId5List: itemCategoryUid ? String(itemCategoryUid) : void 0,
647
+ filters: filters.filters?.length ? JSON.stringify(filters.filters) : void 0,
648
+ sourceFieldsList: defaultSourceFields,
649
+ edgeCache
650
+ };
651
+ return withServerCache(
652
+ cachePrefix,
653
+ redisTtl,
654
+ "openSearch.itemSearch.list",
655
+ async () => {
656
+ const response = await api.openSearch.itemSearch.list(params);
657
+ const { items, totalResults } = response.data;
658
+ const nextOffset = pageParam + filters.limit;
659
+ return {
660
+ data: items,
661
+ total: totalResults,
662
+ nextCursor: nextOffset < totalResults ? nextOffset : void 0
663
+ };
664
+ },
665
+ filters,
666
+ itemCategoryUid,
667
+ pageParam
668
+ );
669
+ }
670
+ return {
671
+ getSearchAttributes,
672
+ getSearchSuggestions,
673
+ itemSearch,
674
+ itemSearchInfinite
675
+ };
676
+ }
677
+
678
+ // src/actions/shipping.ts
679
+ function createShippingActions(api, config) {
680
+ const {
681
+ fromAddress,
682
+ defaultServiceCodes,
683
+ cachePrefix = "",
684
+ edgeCache = 1,
685
+ redisTtl = 3600
686
+ } = config;
687
+ async function getShippingRates(toAddress, weight, serviceCodes) {
688
+ const params = {
689
+ fromAddress,
690
+ toAddress: { ...toAddress, country: toAddress.country ?? "US" },
691
+ weight,
692
+ serviceCodes: serviceCodes ?? defaultServiceCodes,
693
+ edgeCache
694
+ };
695
+ return withServerCache(
696
+ cachePrefix,
697
+ redisTtl,
698
+ "ups.ratesShop.get",
699
+ async () => {
700
+ const response = await api.ups.ratesShop.get(params);
701
+ return response.data;
702
+ },
703
+ params
704
+ );
705
+ }
706
+ return { getShippingRates };
707
+ }
708
+
709
+ // src/actions/joomla.ts
710
+ function createJoomlaActions(api, config = {}) {
711
+ const { cachePrefix = "", edgeCache = 1, redisTtl = 3600 } = config;
712
+ async function getJoomlaContent(articleId) {
713
+ return withServerCache(
714
+ cachePrefix,
715
+ redisTtl,
716
+ "joomla.content.doc.get",
717
+ async () => {
718
+ const response = await api.joomla.content.doc.get(articleId, {
719
+ edgeCache
720
+ });
721
+ return response.data;
722
+ },
723
+ articleId
724
+ );
725
+ }
726
+ async function getJoomlaContentList(params) {
727
+ return withServerCache(
728
+ cachePrefix,
729
+ redisTtl,
730
+ "joomla.content.list",
731
+ async () => {
732
+ const response = await api.joomla.content.list({
733
+ ...params,
734
+ edgeCache
735
+ });
736
+ return response.data;
737
+ },
738
+ params
739
+ );
740
+ }
741
+ return { getJoomlaContent, getJoomlaContentList };
742
+ }
158
743
  export {
159
744
  cacheGet,
160
745
  cacheSet,
746
+ createCommerceActions,
747
+ createItemActions,
748
+ createJoomlaActions,
749
+ createOrderActions,
750
+ createPricingActions,
161
751
  createQueryOptions,
752
+ createSearchActions,
162
753
  createServerQueryClient,
754
+ createShippingActions,
163
755
  createSuspenseQueryOptions,
164
756
  env,
165
757
  getCircuitState,
@@ -168,6 +760,7 @@ export {
168
760
  isProduction,
169
761
  isRedisConnected,
170
762
  isStaging,
171
- sdkCall
763
+ sdkCall,
764
+ withServerCache
172
765
  };
173
766
  //# sourceMappingURL=index.js.map
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/server-query-client.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 { cache } from \"react\";\nimport { QueryClient } from \"@tanstack/react-query\";\nimport { CACHE_CONFIG } from \"@simpleapps-com/augur-utils\";\n\n/**\n * Creates a server-side query client optimised for prefetching.\n *\n * - No persistence (server-only)\n * - Longer cache times for prefetched data\n * - No retries (fail fast on server)\n * - No refetching (server renders are one-shot)\n */\nexport function createServerQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: CACHE_CONFIG.STATIC.staleTime,\n gcTime: CACHE_CONFIG.STATIC.staleTime,\n retry: 0,\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n },\n });\n}\n\n/**\n * Returns a per-request singleton QueryClient for React Server Components.\n *\n * React's `cache()` deduplicates calls within a single server request,\n * so each request gets its own QueryClient while avoiding the cross-request\n * state leakage that a module-level singleton would cause.\n */\nexport const getServerQueryClient = cache(\n (): QueryClient => createServerQueryClient(),\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/server-query-client.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 { cache } from \"react\";\nimport { QueryClient } from \"@tanstack/react-query\";\nimport { CACHE_CONFIG } from \"@simpleapps-com/augur-utils\";\n\n/**\n * Creates a server-side query client optimised for prefetching.\n *\n * - No persistence (server-only)\n * - Longer cache times for prefetched data\n * - No retries (fail fast on server)\n * - No refetching (server renders are one-shot)\n */\nexport function createServerQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: CACHE_CONFIG.STATIC.staleTime,\n gcTime: CACHE_CONFIG.STATIC.staleTime,\n retry: 0,\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n },\n },\n });\n}\n\n/**\n * Returns a per-request singleton QueryClient for React Server Components.\n *\n * React's `cache()` deduplicates calls within a single server request,\n * so each request gets its own QueryClient while avoiding the cross-request\n * state leakage that a module-level singleton would cause.\n */\nexport const getServerQueryClient = cache(\n (): QueryClient => createServerQueryClient(),\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":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simpleapps-com/augur-server",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Server-side utilities for Augur ecommerce sites (Redis caching, SDK helpers, auth)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,7 +33,7 @@
33
33
  ],
34
34
  "dependencies": {
35
35
  "valibot": "^1.0.0",
36
- "@simpleapps-com/augur-utils": "0.2.2"
36
+ "@simpleapps-com/augur-utils": "0.2.4"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@simpleapps-com/augur-api": "^0.9.6",