Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 1x 1x 1x 4x 4x | import * as v from 'valibot';
import type {
EpagesProductPage,
EpagesSearchResponse,
EpagesVariationsResponse,
} from '@/types/labchem';
const epagesSearchResponseSchema = v.object({
products: v.array(
v.looseObject({
productId: v.string(),
name: v.string(),
links: v.array(v.looseObject({ rel: v.string(), href: v.string() })),
}),
),
totalNumberOfProducts: v.number(),
});
const epagesVariationsResponseSchema = v.object({
results: v.number(),
items: v.array(
v.looseObject({
link: v.looseObject({ rel: v.string(), href: v.string() }),
}),
),
});
const epagesProductPageSchema = v.looseObject({
productId: v.string(),
forSale: v.boolean(),
});
/**
* Type guard for the ePages catalog search response
* (`POST /api/v2/search`). Verifies the `products` array (each with an id, name,
* and links) and the `totalNumberOfProducts` count used to drive pagination.
*
* @category Typeguards
* @param response - The value to validate
* @returns Type predicate indicating whether `response` is an EpagesSearchResponse
* @example
* ```typescript
* const json = await httpPostJson({ path: "/api/v2/search", body: { query: "" } });
* if (isEpagesSearchResponse(json)) {
* console.log(`${json.totalNumberOfProducts} products in catalog`);
* }
* ```
* @source
*/
export function isEpagesSearchResponse(response: unknown): response is EpagesSearchResponse {
return v.safeParse(epagesSearchResponseSchema, response).success;
}
/**
* Type guard for a master product's variations list
* (`GET …/products/{masterId}/variations`). Verifies the `items` array, each
* entry carrying a `link` to its variation product page.
*
* @category Typeguards
* @param response - The value to validate
* @returns Type predicate indicating whether `response` is an EpagesVariationsResponse
* @example
* ```typescript
* const json = await httpGetJson({ path: `/rs/shops/${shopId}/products/${id}/variations` });
* if (isEpagesVariationsResponse(json)) {
* const purchasable = json.items.filter((i) => i.additionalAttributes?.purchasable !== false);
* }
* ```
* @source
*/
export function isEpagesVariationsResponse(
response: unknown,
): response is EpagesVariationsResponse {
return v.safeParse(epagesVariationsResponseSchema, response).success;
}
/**
* Type guard for a per-variation (or master) product page (`GET …/products/{id}`).
* Verifies the fields the enrichment step reads first — `productId` and the
* `forSale` stock flag.
*
* @category Typeguards
* @param response - The value to validate
* @returns Type predicate indicating whether `response` is an EpagesProductPage
* @example
* ```typescript
* const json = await httpGetJson({ path: variation.link.href });
* if (isEpagesProductPage(json) && json.forSale) {
* console.log(json.priceInfo?.price?.amount);
* }
* ```
* @source
*/
export function isEpagesProductPage(response: unknown): response is EpagesProductPage {
return v.safeParse(epagesProductPageSchema, response).success;
}
|