All files / src/utils/typeGuards mysimplestore.ts

100% Statements 29/29
100% Branches 2/2
100% Functions 2/2
100% Lines 29/29

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 681x   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  
import * as v from 'valibot';
 
/**
 * Minimal shape every MySimpleStore search-list product must satisfy for the
 * supplier to consume it. Only the fields read while building a product are
 * required; the response carries many more, all optional from our perspective.
 * `image_list` is validated only as an array — its per-item shape is read
 * tolerantly at the point of use — and stays optional since a product may
 * legitimately carry no images.
 */
const mySimpleStoreListProductSchema = v.object({
  id: v.string(),
  slug: v.string(),
  name: v.string(),
  relative_url: v.string(),
  image_list: v.optional(v.array(v.unknown())),
});
 
const mySimpleStoreSearchResponseSchema = v.object({
  products: v.array(mySimpleStoreListProductSchema),
});
 
/**
 * Type guard validating that a value matches the MySimpleStore search/list
 * response envelope: an object with a `products` array whose items each carry
 * the minimal id/slug/name/relative_url fields the supplier reads.
 * @category Typeguards
 * @param response - The value to validate (typically a parsed JSON response)
 * @returns Type predicate indicating whether `response` is a valid search response
 * @example
 * ```typescript
 * const data = await this.httpGetJson({ host: this.apiHost, path: "/api/v2/products" });
 * if (isValidSearchResponse(data)) {
 *   for (const product of data.products) console.log(product.name);
 * }
 * ```
 * @source
 */
export function isValidSearchResponse(response: unknown): response is MySimpleStoreSearchResponse {
  return v.safeParse(mySimpleStoreSearchResponseSchema, response).success;
}
 
const mySimpleStoreProductDetailSchema = v.object({
  id: v.string(),
  slug: v.string(),
  name: v.string(),
  variants: v.optional(v.array(v.unknown())),
});
 
/**
 * Type guard validating that a value matches the MySimpleStore product-detail
 * response: an object with id/slug/name and an optional `variants` array. The
 * per-variant shape is guarded at the point of use so a stray entry can't
 * reject the whole response.
 * @category Typeguards
 * @param product - The value to validate (typically a parsed JSON response)
 * @returns Type predicate indicating whether `product` is a valid product detail
 * @example
 * ```typescript
 * const data = await this.httpGetJson({ host: this.apiHost, path: "/api/v2/products/geraniol-60" });
 * if (isProductDetail(data)) console.log(data.variants?.length);
 * ```
 * @source
 */
export function isProductDetail(product: unknown): product is MySimpleStoreProductDetail {
  return v.safeParse(mySimpleStoreProductDetailSchema, product).success;
}