@reactionary/lipscore 0.9.22 → 0.9.23

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.
@@ -18,7 +18,10 @@ import {
18
18
  error,
19
19
  success
20
20
  } from "@reactionary/core";
21
- import { LipscoreProductsResponseSchema } from "../schema/lipscore.schema.js";
21
+ import {
22
+ LipscoreProductsListSchema,
23
+ LipscoreReviewsResponseSchema
24
+ } from "../schema/lipscore.schema.js";
22
25
  class LipscoreProductReviewsCapability extends ProductReviewsCapability {
23
26
  constructor(cache, context, config, client, factory) {
24
27
  super(cache, context);
@@ -27,27 +30,42 @@ class LipscoreProductReviewsCapability extends ProductReviewsCapability {
27
30
  this.factory = factory;
28
31
  }
29
32
  async getRatingSummary(query) {
30
- const response = await this.client.callGet(
31
- this.getReviewsUrl(),
32
- this.getRatingSummaryParams(query.product.key),
33
- LipscoreProductsResponseSchema
33
+ const product = await this.getProduct(query.product.key);
34
+ return success(
35
+ this.factory.parseRatingSummary(this.context, {
36
+ productKey: query.product.key,
37
+ votes: product?.votes ?? null,
38
+ rating: product?.rating ?? null
39
+ })
34
40
  );
35
- return success(this.factory.parseRatingSummary(this.context, response));
36
41
  }
37
42
  async findReviews(query) {
38
43
  const pageSize = query.paginationOptions?.pageSize ?? 10;
39
44
  const pageNumber = query.paginationOptions?.pageNumber ?? 1;
40
- const response = await this.client.callGet(
41
- this.getReviewsUrl(),
42
- this.getReviewsParams(query.product.key),
43
- LipscoreProductsResponseSchema
45
+ const product = await this.getProduct(query.product.key);
46
+ if (product === null) {
47
+ return success(
48
+ this.factory.parseReviewPaginatedResult(this.context, {
49
+ reviews: [],
50
+ productKey: query.product.key,
51
+ pageSize,
52
+ pageNumber,
53
+ totalReviewCount: 0
54
+ })
55
+ );
56
+ }
57
+ const reviews = await this.client.callGet(
58
+ this.getReviewsUrl(product.id),
59
+ this.getReviewsParams(pageSize, pageNumber),
60
+ LipscoreReviewsResponseSchema
44
61
  );
45
62
  return success(
46
63
  this.factory.parseReviewPaginatedResult(this.context, {
47
- response,
64
+ reviews,
48
65
  productKey: query.product.key,
49
66
  pageSize,
50
- pageNumber
67
+ pageNumber,
68
+ totalReviewCount: product.review_count ?? void 0
51
69
  })
52
70
  );
53
71
  }
@@ -60,17 +78,32 @@ class LipscoreProductReviewsCapability extends ProductReviewsCapability {
60
78
  // ---------------------------------------------------------------------------
61
79
  // Extension points — override in subclasses to customise API calls
62
80
  // ---------------------------------------------------------------------------
63
- getReviewsUrl() {
81
+ async getProduct(productKey) {
82
+ const params = this.getProductsParams(productKey);
83
+ const products = await this.client.callGet(
84
+ this.getProductsUrl(),
85
+ params,
86
+ LipscoreProductsListSchema
87
+ );
88
+ return products[0] ?? null;
89
+ }
90
+ getProductsUrl() {
64
91
  return `${this.client.baseUrl}/products`;
65
92
  }
66
- getReviewsParams(productId) {
93
+ getReviewsUrl(lipscoreProductId) {
94
+ return `${this.client.baseUrl}/products/${lipscoreProductId}/reviews`;
95
+ }
96
+ getProductsParams(productKey) {
67
97
  const params = new URLSearchParams();
68
- params.set("internal_id[]", productId);
69
- params.set("fields", "reviews");
98
+ params.set("internal_id", productKey);
99
+ params.set("fields", "rating,review_count");
70
100
  return params;
71
101
  }
72
- getRatingSummaryParams(productId) {
73
- return this.getReviewsParams(productId);
102
+ getReviewsParams(pageSize, pageNumber) {
103
+ const params = new URLSearchParams();
104
+ params.set("page", String(pageNumber));
105
+ params.set("per_page", String(pageSize));
106
+ return params;
74
107
  }
75
108
  }
76
109
  __decorateClass([
@@ -5,63 +5,37 @@ class LipscoreProductReviewsFactory {
5
5
  this.reviewPaginatedSchema = reviewPaginatedSchema;
6
6
  }
7
7
  parseRatingSummary(_context, data) {
8
- const product = data[0];
9
- const reviews = product?.reviews ?? [];
10
- if (reviews.length === 0) {
11
- return this.ratingSummarySchema.parse({
12
- identifier: { product: { key: String(product?.internal_id ?? "") } },
13
- averageRating: 0,
14
- totalRatings: void 0,
15
- ratingDistribution: void 0
16
- });
17
- }
18
- const total = reviews.length;
19
- const sum = reviews.reduce((acc, r) => acc + r.rating, 0);
20
- const averageRating = Math.round(sum / total * 100) / 100;
21
- const distribution = {
22
- "1": 0,
23
- "2": 0,
24
- "3": 0,
25
- "4": 0,
26
- "5": 0
27
- };
28
- for (const review of reviews) {
29
- const key = String(Math.min(5, Math.max(1, Math.round(review.rating))));
30
- distribution[key] = (distribution[key] ?? 0) + 1;
31
- }
8
+ const votes = data.votes ?? 0;
9
+ const averageRating = votes > 0 && data.rating ? Math.round(parseFloat(data.rating) * 100) / 100 : 0;
32
10
  return this.ratingSummarySchema.parse({
33
- identifier: { product: { key: String(product?.internal_id ?? "") } },
11
+ identifier: { product: { key: data.productKey } },
34
12
  averageRating,
35
- totalRatings: total,
36
- ratingDistribution: distribution
13
+ totalRatings: votes > 0 ? votes : void 0,
14
+ ratingDistribution: void 0
37
15
  });
38
16
  }
39
17
  parseReview(_context, data) {
40
18
  return this.reviewSchema.parse({
41
19
  identifier: { key: String(data.id) },
42
- product: { key: String(data.id) },
43
- authorName: data.displayed_name ?? data.user?.name ?? "Anonymous",
20
+ product: { key: data.product?.internal_id ?? String(data.id) },
21
+ authorName: data.displayed_name ?? data.user?.short_name ?? data.user?.name ?? "Anonymous",
44
22
  authorId: data.user?.id != null ? String(data.user.id) : void 0,
45
23
  rating: data.rating,
46
24
  title: "",
47
25
  content: data.text ?? data.translated_text ?? "",
48
- reply: typeof data.review_reply === "string" ? data.review_reply : void 0,
49
- repliedAt: void 0,
26
+ reply: data.review_reply != null ? data.review_reply.text ?? void 0 : void 0,
27
+ repliedAt: data.review_reply != null ? data.review_reply.created_at ?? void 0 : void 0,
50
28
  createdAt: data.created_at,
51
29
  updatedAt: void 0,
52
- verified: data.testimonial ?? false
30
+ verified: false
53
31
  });
54
32
  }
55
33
  parseReviewPaginatedResult(context, data) {
56
- const product = data.response[0];
57
- const allReviews = product?.reviews ?? [];
58
- const totalCount = allReviews.length;
59
34
  const pageSize = data.pageSize > 0 ? data.pageSize : 10;
60
35
  const pageNumber = data.pageNumber > 0 ? data.pageNumber : 1;
36
+ const totalCount = data.totalReviewCount !== void 0 ? data.totalReviewCount : data.reviews.length < pageSize ? (pageNumber - 1) * pageSize + data.reviews.length : pageNumber * pageSize + 1;
61
37
  const totalPages = pageSize > 0 ? Math.ceil(totalCount / pageSize) : 1;
62
- const offset = (pageNumber - 1) * pageSize;
63
- const pageReviews = allReviews.slice(offset, offset + pageSize);
64
- const items = pageReviews.map((r) => {
38
+ const items = data.reviews.map((r) => {
65
39
  const parsed = this.parseReview(context, r);
66
40
  return { ...parsed, product: { key: data.productKey } };
67
41
  });
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@reactionary/lipscore",
3
- "version": "0.9.22",
3
+ "version": "0.9.23",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./src/index.d.ts",
7
7
  "dependencies": {
8
- "@reactionary/core": "0.9.22",
8
+ "@reactionary/core": "0.9.23",
9
9
  "zod": "4.1.9"
10
10
  },
11
11
  "devDependencies": {
@@ -1,8 +1,8 @@
1
1
  import * as z from "zod";
2
2
  const LipscoreConfigurationSchema = z.looseObject({
3
3
  apiKey: z.string().meta({ description: "Lipscore public API key." }),
4
- apiSecret: z.string().optional().meta({
5
- description: "Lipscore server-side API secret. When set it is sent as the X-Authorization header."
4
+ apiSecret: z.string().meta({
5
+ description: "Lipscore server-side API secret. Sent as the X-Authorization header on all v2 API requests."
6
6
  }),
7
7
  apiUrl: z.string().default("https://api.lipscore.com").meta({ description: "Base Lipscore API URL." })
8
8
  });
@@ -1,37 +1,77 @@
1
1
  import * as z from "zod";
2
- const LipscoreReviewUserSchema = z.looseObject({
2
+ const LipscoreUserSchema = z.looseObject({
3
3
  id: z.number().optional(),
4
4
  name: z.string().optional(),
5
5
  short_name: z.string().optional(),
6
6
  email: z.string().optional()
7
7
  });
8
+ const LipscoreProductEmbedSchema = z.looseObject({
9
+ name: z.string().nullable().optional(),
10
+ gtin: z.string().nullable().optional(),
11
+ sku: z.string().nullable().optional(),
12
+ variant_id: z.string().nullable().optional(),
13
+ mpn: z.string().nullable().optional(),
14
+ internal_id: z.string().nullable().optional()
15
+ });
16
+ const LipscoreRatingSchema = z.looseObject({
17
+ id: z.number(),
18
+ created_at: z.string(),
19
+ updated_at: z.string().optional(),
20
+ status: z.string().nullable().optional(),
21
+ lang: z.string().optional(),
22
+ origin: z.string().optional(),
23
+ rating: z.number(),
24
+ user: LipscoreUserSchema.optional(),
25
+ product: LipscoreProductEmbedSchema.optional(),
26
+ internal_order_id: z.string().nullable().optional(),
27
+ internal_customer_id: z.string().nullable().optional()
28
+ });
29
+ const LipscoreRatingsResponseSchema = z.array(LipscoreRatingSchema);
8
30
  const LipscoreReviewImageSchema = z.looseObject({
31
+ id: z.number().optional(),
9
32
  thumb_url: z.string().optional(),
10
33
  image_url: z.string().optional()
11
34
  });
35
+ const LipscoreReviewReplySchema = z.looseObject({
36
+ text: z.string().optional(),
37
+ created_at: z.string().optional(),
38
+ translated_text: z.string().nullable().optional(),
39
+ member_site: z.string().optional(),
40
+ lang: z.string().optional()
41
+ });
12
42
  const LipscoreReviewSchema = z.looseObject({
13
43
  id: z.number(),
14
- text: z.string().optional(),
15
- translated_text: z.string().optional(),
44
+ text: z.string().nullable().optional(),
45
+ translated_text: z.string().nullable().optional(),
16
46
  created_at: z.string(),
17
47
  votes_up: z.number().optional(),
18
48
  votes_down: z.number().optional(),
19
- purchase_date: z.string().optional(),
49
+ purchase_date: z.string().nullable().optional(),
20
50
  rating: z.number(),
21
- user: LipscoreReviewUserSchema.optional(),
51
+ user: LipscoreUserSchema.optional(),
22
52
  images: z.array(LipscoreReviewImageSchema).optional(),
23
- review_reply: z.unknown().optional(),
24
- displayed_name: z.string().optional(),
53
+ review_reply: z.union([LipscoreReviewReplySchema, z.null()]).optional(),
25
54
  testimonial: z.boolean().optional(),
55
+ displayed_name: z.string().nullable().optional(),
56
+ imported_at: z.string().optional(),
57
+ product: LipscoreProductEmbedSchema.optional(),
26
58
  attributes: z.array(z.unknown()).optional()
27
59
  });
28
- const LipscoreProductSchema = z.looseObject({
29
- internal_id: z.union([z.string(), z.number()]).optional(),
60
+ const LipscoreReviewsResponseSchema = z.array(LipscoreReviewSchema);
61
+ const LipscoreProductListItemSchema = z.looseObject({
62
+ id: z.number(),
63
+ internal_id: z.string().optional(),
64
+ votes: z.number().nullable().optional(),
65
+ rating: z.string().nullable().optional(),
66
+ review_count: z.number().nullable().optional(),
30
67
  reviews: z.array(LipscoreReviewSchema).default([])
31
68
  });
32
- const LipscoreProductsResponseSchema = z.array(LipscoreProductSchema);
69
+ const LipscoreProductsListSchema = z.array(LipscoreProductListItemSchema);
33
70
  export {
34
- LipscoreProductSchema,
35
- LipscoreProductsResponseSchema,
36
- LipscoreReviewSchema
71
+ LipscoreProductListItemSchema,
72
+ LipscoreProductsListSchema,
73
+ LipscoreRatingSchema,
74
+ LipscoreRatingsResponseSchema,
75
+ LipscoreReviewSchema,
76
+ LipscoreReviewsResponseSchema
37
77
  };
@@ -1,4 +1,5 @@
1
1
  import { ProductReviewsCapability, type Cache, type ProductReviewMutationSubmit, type ProductReviewsFactory, type ProductReviewsFactoryRatingOutput, type ProductReviewsFactoryReviewOutput, type ProductReviewsFactoryReviewPaginatedOutput, type ProductReviewsFactoryWithOutput, type ProductReviewsGetRatingSummaryQuery, type ProductReviewsListQuery, type RequestContext, type Result } from '@reactionary/core';
2
+ import type { LipscoreProductListItem } from '../schema/lipscore.schema.js';
2
3
  import type { LipscoreConfiguration } from '../schema/configuration.schema.js';
3
4
  import type { LipscoreClient } from '../core/client.js';
4
5
  import type { LipscoreProductReviewsFactory } from '../factories/product-reviews/product-reviews.factory.js';
@@ -10,7 +11,9 @@ export declare class LipscoreProductReviewsCapability<TFactory extends ProductRe
10
11
  getRatingSummary(query: ProductReviewsGetRatingSummaryQuery): Promise<Result<ProductReviewsFactoryRatingOutput<TFactory>>>;
11
12
  findReviews(query: ProductReviewsListQuery): Promise<Result<ProductReviewsFactoryReviewPaginatedOutput<TFactory>>>;
12
13
  submitReview(mutation: ProductReviewMutationSubmit): Promise<Result<ProductReviewsFactoryReviewOutput<TFactory>>>;
13
- protected getReviewsUrl(): string;
14
- protected getReviewsParams(productId: string): URLSearchParams;
15
- protected getRatingSummaryParams(productId: string): URLSearchParams;
14
+ protected getProduct(productKey: string): Promise<LipscoreProductListItem | null>;
15
+ protected getProductsUrl(): string;
16
+ protected getReviewsUrl(lipscoreProductId: number): string;
17
+ protected getProductsParams(productKey: string): URLSearchParams;
18
+ protected getReviewsParams(pageSize: number, pageNumber: number): URLSearchParams;
16
19
  }
@@ -1,18 +1,24 @@
1
1
  import type * as z from 'zod';
2
2
  import type { AnyProductRatingSummarySchema, AnyProductReviewPaginatedSchema, AnyProductReviewSchema, ProductReviewsFactory, RequestContext, ProductRatingSummarySchema, ProductReviewSchema, ProductReviewPaginatedResultSchema } from '@reactionary/core';
3
- import type { LipscoreReview, LipscoreProductsResponse } from '../../schema/lipscore.schema.js';
3
+ import type { LipscoreReview } from '../../schema/lipscore.schema.js';
4
+ export interface LipscoreRatingSummaryData {
5
+ productKey: string;
6
+ votes: number | null;
7
+ rating: string | null;
8
+ }
4
9
  export interface LipscoreReviewsPage {
5
- response: LipscoreProductsResponse;
10
+ reviews: LipscoreReview[];
6
11
  productKey: string;
7
12
  pageSize: number;
8
13
  pageNumber: number;
14
+ totalReviewCount?: number;
9
15
  }
10
16
  export declare class LipscoreProductReviewsFactory<TRatingSummarySchema extends AnyProductRatingSummarySchema = typeof ProductRatingSummarySchema, TReviewSchema extends AnyProductReviewSchema = typeof ProductReviewSchema, TReviewPaginatedSchema extends AnyProductReviewPaginatedSchema = typeof ProductReviewPaginatedResultSchema> implements ProductReviewsFactory<TRatingSummarySchema, TReviewSchema, TReviewPaginatedSchema> {
11
17
  readonly ratingSummarySchema: TRatingSummarySchema;
12
18
  readonly reviewSchema: TReviewSchema;
13
19
  readonly reviewPaginatedSchema: TReviewPaginatedSchema;
14
20
  constructor(ratingSummarySchema: TRatingSummarySchema, reviewSchema: TReviewSchema, reviewPaginatedSchema: TReviewPaginatedSchema);
15
- parseRatingSummary(_context: RequestContext, data: LipscoreProductsResponse): z.output<TRatingSummarySchema>;
21
+ parseRatingSummary(_context: RequestContext, data: LipscoreRatingSummaryData): z.output<TRatingSummarySchema>;
16
22
  parseReview(_context: RequestContext, data: LipscoreReview): z.output<TReviewSchema>;
17
23
  parseReviewPaginatedResult(context: RequestContext, data: LipscoreReviewsPage): z.output<TReviewPaginatedSchema>;
18
24
  }
@@ -1,7 +1,7 @@
1
1
  import * as z from 'zod';
2
2
  export declare const LipscoreConfigurationSchema: z.ZodObject<{
3
3
  apiKey: z.ZodString;
4
- apiSecret: z.ZodOptional<z.ZodString>;
4
+ apiSecret: z.ZodString;
5
5
  apiUrl: z.ZodDefault<z.ZodString>;
6
6
  }, z.core.$loose>;
7
7
  export type LipscoreConfiguration = z.infer<typeof LipscoreConfigurationSchema>;
@@ -1,12 +1,64 @@
1
1
  import * as z from 'zod';
2
+ export declare const LipscoreRatingSchema: z.ZodObject<{
3
+ id: z.ZodNumber;
4
+ created_at: z.ZodString;
5
+ updated_at: z.ZodOptional<z.ZodString>;
6
+ status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
7
+ lang: z.ZodOptional<z.ZodString>;
8
+ origin: z.ZodOptional<z.ZodString>;
9
+ rating: z.ZodNumber;
10
+ user: z.ZodOptional<z.ZodObject<{
11
+ id: z.ZodOptional<z.ZodNumber>;
12
+ name: z.ZodOptional<z.ZodString>;
13
+ short_name: z.ZodOptional<z.ZodString>;
14
+ email: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$loose>>;
16
+ product: z.ZodOptional<z.ZodObject<{
17
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
18
+ gtin: z.ZodOptional<z.ZodNullable<z.ZodString>>;
19
+ sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
20
+ variant_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
21
+ mpn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
22
+ internal_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
23
+ }, z.core.$loose>>;
24
+ internal_order_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
25
+ internal_customer_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
26
+ }, z.core.$loose>;
27
+ export type LipscoreRating = z.infer<typeof LipscoreRatingSchema>;
28
+ export declare const LipscoreRatingsResponseSchema: z.ZodArray<z.ZodObject<{
29
+ id: z.ZodNumber;
30
+ created_at: z.ZodString;
31
+ updated_at: z.ZodOptional<z.ZodString>;
32
+ status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
33
+ lang: z.ZodOptional<z.ZodString>;
34
+ origin: z.ZodOptional<z.ZodString>;
35
+ rating: z.ZodNumber;
36
+ user: z.ZodOptional<z.ZodObject<{
37
+ id: z.ZodOptional<z.ZodNumber>;
38
+ name: z.ZodOptional<z.ZodString>;
39
+ short_name: z.ZodOptional<z.ZodString>;
40
+ email: z.ZodOptional<z.ZodString>;
41
+ }, z.core.$loose>>;
42
+ product: z.ZodOptional<z.ZodObject<{
43
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
44
+ gtin: z.ZodOptional<z.ZodNullable<z.ZodString>>;
45
+ sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
46
+ variant_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
47
+ mpn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
48
+ internal_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
49
+ }, z.core.$loose>>;
50
+ internal_order_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
+ internal_customer_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
52
+ }, z.core.$loose>>;
53
+ export type LipscoreRatingsResponse = z.infer<typeof LipscoreRatingsResponseSchema>;
2
54
  export declare const LipscoreReviewSchema: z.ZodObject<{
3
55
  id: z.ZodNumber;
4
- text: z.ZodOptional<z.ZodString>;
5
- translated_text: z.ZodOptional<z.ZodString>;
56
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
57
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
6
58
  created_at: z.ZodString;
7
59
  votes_up: z.ZodOptional<z.ZodNumber>;
8
60
  votes_down: z.ZodOptional<z.ZodNumber>;
9
- purchase_date: z.ZodOptional<z.ZodString>;
61
+ purchase_date: z.ZodOptional<z.ZodNullable<z.ZodString>>;
10
62
  rating: z.ZodNumber;
11
63
  user: z.ZodOptional<z.ZodObject<{
12
64
  id: z.ZodOptional<z.ZodNumber>;
@@ -15,25 +67,86 @@ export declare const LipscoreReviewSchema: z.ZodObject<{
15
67
  email: z.ZodOptional<z.ZodString>;
16
68
  }, z.core.$loose>>;
17
69
  images: z.ZodOptional<z.ZodArray<z.ZodObject<{
70
+ id: z.ZodOptional<z.ZodNumber>;
18
71
  thumb_url: z.ZodOptional<z.ZodString>;
19
72
  image_url: z.ZodOptional<z.ZodString>;
20
73
  }, z.core.$loose>>>;
21
- review_reply: z.ZodOptional<z.ZodUnknown>;
22
- displayed_name: z.ZodOptional<z.ZodString>;
74
+ review_reply: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
75
+ text: z.ZodOptional<z.ZodString>;
76
+ created_at: z.ZodOptional<z.ZodString>;
77
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
78
+ member_site: z.ZodOptional<z.ZodString>;
79
+ lang: z.ZodOptional<z.ZodString>;
80
+ }, z.core.$loose>, z.ZodNull]>>;
23
81
  testimonial: z.ZodOptional<z.ZodBoolean>;
82
+ displayed_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
83
+ imported_at: z.ZodOptional<z.ZodString>;
84
+ product: z.ZodOptional<z.ZodObject<{
85
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
86
+ gtin: z.ZodOptional<z.ZodNullable<z.ZodString>>;
87
+ sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
88
+ variant_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
89
+ mpn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
90
+ internal_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
91
+ }, z.core.$loose>>;
24
92
  attributes: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
25
93
  }, z.core.$loose>;
26
94
  export type LipscoreReview = z.infer<typeof LipscoreReviewSchema>;
27
- export declare const LipscoreProductSchema: z.ZodObject<{
28
- internal_id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
95
+ export declare const LipscoreReviewsResponseSchema: z.ZodArray<z.ZodObject<{
96
+ id: z.ZodNumber;
97
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
98
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
99
+ created_at: z.ZodString;
100
+ votes_up: z.ZodOptional<z.ZodNumber>;
101
+ votes_down: z.ZodOptional<z.ZodNumber>;
102
+ purchase_date: z.ZodOptional<z.ZodNullable<z.ZodString>>;
103
+ rating: z.ZodNumber;
104
+ user: z.ZodOptional<z.ZodObject<{
105
+ id: z.ZodOptional<z.ZodNumber>;
106
+ name: z.ZodOptional<z.ZodString>;
107
+ short_name: z.ZodOptional<z.ZodString>;
108
+ email: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$loose>>;
110
+ images: z.ZodOptional<z.ZodArray<z.ZodObject<{
111
+ id: z.ZodOptional<z.ZodNumber>;
112
+ thumb_url: z.ZodOptional<z.ZodString>;
113
+ image_url: z.ZodOptional<z.ZodString>;
114
+ }, z.core.$loose>>>;
115
+ review_reply: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
116
+ text: z.ZodOptional<z.ZodString>;
117
+ created_at: z.ZodOptional<z.ZodString>;
118
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
119
+ member_site: z.ZodOptional<z.ZodString>;
120
+ lang: z.ZodOptional<z.ZodString>;
121
+ }, z.core.$loose>, z.ZodNull]>>;
122
+ testimonial: z.ZodOptional<z.ZodBoolean>;
123
+ displayed_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
124
+ imported_at: z.ZodOptional<z.ZodString>;
125
+ product: z.ZodOptional<z.ZodObject<{
126
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
127
+ gtin: z.ZodOptional<z.ZodNullable<z.ZodString>>;
128
+ sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
129
+ variant_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
130
+ mpn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
131
+ internal_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
132
+ }, z.core.$loose>>;
133
+ attributes: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
134
+ }, z.core.$loose>>;
135
+ export type LipscoreReviewsResponse = z.infer<typeof LipscoreReviewsResponseSchema>;
136
+ export declare const LipscoreProductListItemSchema: z.ZodObject<{
137
+ id: z.ZodNumber;
138
+ internal_id: z.ZodOptional<z.ZodString>;
139
+ votes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
140
+ rating: z.ZodOptional<z.ZodNullable<z.ZodString>>;
141
+ review_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
29
142
  reviews: z.ZodDefault<z.ZodArray<z.ZodObject<{
30
143
  id: z.ZodNumber;
31
- text: z.ZodOptional<z.ZodString>;
32
- translated_text: z.ZodOptional<z.ZodString>;
144
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
145
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
33
146
  created_at: z.ZodString;
34
147
  votes_up: z.ZodOptional<z.ZodNumber>;
35
148
  votes_down: z.ZodOptional<z.ZodNumber>;
36
- purchase_date: z.ZodOptional<z.ZodString>;
149
+ purchase_date: z.ZodOptional<z.ZodNullable<z.ZodString>>;
37
150
  rating: z.ZodNumber;
38
151
  user: z.ZodOptional<z.ZodObject<{
39
152
  id: z.ZodOptional<z.ZodNumber>;
@@ -42,26 +155,45 @@ export declare const LipscoreProductSchema: z.ZodObject<{
42
155
  email: z.ZodOptional<z.ZodString>;
43
156
  }, z.core.$loose>>;
44
157
  images: z.ZodOptional<z.ZodArray<z.ZodObject<{
158
+ id: z.ZodOptional<z.ZodNumber>;
45
159
  thumb_url: z.ZodOptional<z.ZodString>;
46
160
  image_url: z.ZodOptional<z.ZodString>;
47
161
  }, z.core.$loose>>>;
48
- review_reply: z.ZodOptional<z.ZodUnknown>;
49
- displayed_name: z.ZodOptional<z.ZodString>;
162
+ review_reply: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
163
+ text: z.ZodOptional<z.ZodString>;
164
+ created_at: z.ZodOptional<z.ZodString>;
165
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
166
+ member_site: z.ZodOptional<z.ZodString>;
167
+ lang: z.ZodOptional<z.ZodString>;
168
+ }, z.core.$loose>, z.ZodNull]>>;
50
169
  testimonial: z.ZodOptional<z.ZodBoolean>;
170
+ displayed_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
171
+ imported_at: z.ZodOptional<z.ZodString>;
172
+ product: z.ZodOptional<z.ZodObject<{
173
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
174
+ gtin: z.ZodOptional<z.ZodNullable<z.ZodString>>;
175
+ sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
176
+ variant_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
177
+ mpn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
178
+ internal_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
179
+ }, z.core.$loose>>;
51
180
  attributes: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
52
181
  }, z.core.$loose>>>;
53
182
  }, z.core.$loose>;
54
- export type LipscoreProduct = z.infer<typeof LipscoreProductSchema>;
55
- export declare const LipscoreProductsResponseSchema: z.ZodArray<z.ZodObject<{
56
- internal_id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
183
+ export declare const LipscoreProductsListSchema: z.ZodArray<z.ZodObject<{
184
+ id: z.ZodNumber;
185
+ internal_id: z.ZodOptional<z.ZodString>;
186
+ votes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
187
+ rating: z.ZodOptional<z.ZodNullable<z.ZodString>>;
188
+ review_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
57
189
  reviews: z.ZodDefault<z.ZodArray<z.ZodObject<{
58
190
  id: z.ZodNumber;
59
- text: z.ZodOptional<z.ZodString>;
60
- translated_text: z.ZodOptional<z.ZodString>;
191
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
192
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
61
193
  created_at: z.ZodString;
62
194
  votes_up: z.ZodOptional<z.ZodNumber>;
63
195
  votes_down: z.ZodOptional<z.ZodNumber>;
64
- purchase_date: z.ZodOptional<z.ZodString>;
196
+ purchase_date: z.ZodOptional<z.ZodNullable<z.ZodString>>;
65
197
  rating: z.ZodNumber;
66
198
  user: z.ZodOptional<z.ZodObject<{
67
199
  id: z.ZodOptional<z.ZodNumber>;
@@ -70,13 +202,29 @@ export declare const LipscoreProductsResponseSchema: z.ZodArray<z.ZodObject<{
70
202
  email: z.ZodOptional<z.ZodString>;
71
203
  }, z.core.$loose>>;
72
204
  images: z.ZodOptional<z.ZodArray<z.ZodObject<{
205
+ id: z.ZodOptional<z.ZodNumber>;
73
206
  thumb_url: z.ZodOptional<z.ZodString>;
74
207
  image_url: z.ZodOptional<z.ZodString>;
75
208
  }, z.core.$loose>>>;
76
- review_reply: z.ZodOptional<z.ZodUnknown>;
77
- displayed_name: z.ZodOptional<z.ZodString>;
209
+ review_reply: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
210
+ text: z.ZodOptional<z.ZodString>;
211
+ created_at: z.ZodOptional<z.ZodString>;
212
+ translated_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
213
+ member_site: z.ZodOptional<z.ZodString>;
214
+ lang: z.ZodOptional<z.ZodString>;
215
+ }, z.core.$loose>, z.ZodNull]>>;
78
216
  testimonial: z.ZodOptional<z.ZodBoolean>;
217
+ displayed_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
218
+ imported_at: z.ZodOptional<z.ZodString>;
219
+ product: z.ZodOptional<z.ZodObject<{
220
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
221
+ gtin: z.ZodOptional<z.ZodNullable<z.ZodString>>;
222
+ sku: z.ZodOptional<z.ZodNullable<z.ZodString>>;
223
+ variant_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
224
+ mpn: z.ZodOptional<z.ZodNullable<z.ZodString>>;
225
+ internal_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
226
+ }, z.core.$loose>>;
79
227
  attributes: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
80
228
  }, z.core.$loose>>>;
81
229
  }, z.core.$loose>>;
82
- export type LipscoreProductsResponse = z.infer<typeof LipscoreProductsResponseSchema>;
230
+ export type LipscoreProductListItem = z.infer<typeof LipscoreProductListItemSchema>;