@okendo/shopify-hydrogen 0.0.2 → 0.0.5

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/README.md CHANGED
@@ -7,7 +7,412 @@ Currently we support server side components for 2 widgets:
7
7
  1. Reviews List
8
8
  2. Star Ratings
9
9
 
10
- ## Overview
10
+ <br/>
11
+
12
+ # Table of contents
13
+
14
+ 1. [What is Okendo Shopify Hydrogen](#introduction)
15
+ 2. [Guided Installation](#installation)
16
+ 1. [Configure Hydrogen App](#configurehydrogenapp)
17
+ 2. [Expose Shopify Metafields](#exposemetafields)
18
+ 3. [How to Use Okendo Hydrogen Components In Your Hydrogen Apps](#okendohydrogencomponentsusage)
19
+ 4. [Component Props](#componentprops)
20
+ 5. [NPM Component Terminology/Defintions](#npmdefinitions)
21
+ 6. [View Our Okendo Sample Hydrogen App](#learnmore)
22
+
23
+ <br/><br/>
24
+
25
+ # What is Okendo Shopify Hydrogen?<a name="introduction"></a>
26
+
27
+ Okendo Shopify Hydrogen is a React component library to be used in Shopify Hydrogen apps. This utilises [Shopify’s Hydrogen framework](https://shopify.dev/custom-storefronts/hydrogen/framework) which is used to create custom storefronts using both server-side rendered and client-side rendered React components.
28
+
29
+ The purpose of this library is for a Hydrogen-based React Shopify storefront to import this library so that the Okendo Reviews List and Okendo Star Ratings components can be rendered within their React application, providing [Okendo’s reviews display functionality](https://www.okendo.io/blog/widget-plus/).
30
+
31
+ <br/>
32
+
33
+ # Guided Installation <a name="installation"></a>
34
+
35
+ The purpose of this documentation is to guide you on the following:
36
+
37
+ - How to configure your Shopify store ready for Okendo Shopify Hydrogen.
38
+ - How to install and configure Okendo Shopify Hydrogen components in your Shopify Hydrogen app.
39
+
40
+ <br/>
41
+
42
+ ## Requirements
43
+
44
+ - You have an existing Shopify store.
45
+ - You have an existing Hydrogen app. ([Learn how to create a Hydrogen app](https://shopify.dev/custom-storefronts/hydrogen/getting-started/create))
46
+ - You have a current Okendo Reviews subscription and have the **Okendo: Product Reviews & UCG** app installed and configured.
47
+ - You have an existing Shopify custom app with Storefront access token. ([Learn how to configure Shopify Storefront](https://www.notion.so/Configure-Shopify-Storefront-9e78e31bb4d94546aa1d037367c6a0b8))
48
+
49
+ <br/>
50
+
51
+ <a name="configurehydrogenapp"></a>
52
+
53
+ ## 1. Configure Hydrogen app config
54
+
55
+ 1. Open **hydrogen.config.js** in your project.
56
+ 2. Make the following changes and save the file:
57
+ - Update `storeDomain` to specify your store's domain name.
58
+ - Update `storefrontToken` to specify your Storefront API access token.
59
+
60
+ <br/>
61
+
62
+ <a name="exposemetafields"></a>
63
+
64
+ ## 2. Expose Shopify Metafields
65
+
66
+ Okendo Reviews utilise Product and Shop specific [metafields](https://shopify.dev/api/examples/metafields) in order to function and provide a seamless user experience. You will need to expose these metafields so that they can be retrieved by your Hydrogen app.
67
+
68
+ At this point in time, unfortunately Shopify does not have a way of exposing Shop Metafields through their admin UI.
69
+
70
+ The preferred method to expose Metafields is to [contact Okendo Support](mailto:support@okendo.io).
71
+
72
+ <br/>
73
+
74
+ ### For Technical/Advanced Users
75
+
76
+ <details>
77
+ <summary>Learn How to Expose Metafields Via The Storefront API</summary>
78
+
79
+ # Exposing Metafields via GraphQL
80
+
81
+ ## Using Curl
82
+
83
+ You can also expose the required Okendo Shopify Metafields by using GraphQL with curl.
84
+
85
+ 1. Open a new terminal or PowerShell window.
86
+ 2. Run the following command to expose the `WidgetPreRenderStyleTag` Shop Metafield.
87
+
88
+ ```bash
89
+ curl -X POST \
90
+ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
91
+ -H 'Content-Type: application/graphql' \
92
+ -H 'X-Shopify-Access-Token: {access_token}' \
93
+ -d '
94
+ mutation {
95
+ metafieldStorefrontVisibilityCreate(
96
+ input: {
97
+ namespace: "okendo"
98
+ key: "WidgetPreRenderStyleTags"
99
+ ownerType: SHOP
100
+ }
101
+ ) {
102
+ metafieldStorefrontVisibility {
103
+ id
104
+ }
105
+ userErrors {
106
+ field
107
+ message
108
+ }
109
+ }
110
+ }
111
+ '
112
+ ```
113
+
114
+ 3. Run the following command to expose the `WidgetPreRenderBodyStyleTags` Shop Metafield.
115
+
116
+ ```bash
117
+ curl -X POST \
118
+ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
119
+ -H 'Content-Type: application/graphql' \
120
+ -H 'X-Shopify-Access-Token: {access_token}' \
121
+ -d '
122
+ mutation {
123
+ metafieldStorefrontVisibilityCreate(
124
+ input: {
125
+ namespace: "okendo"
126
+ key: "WidgetPreRenderBodyStyleTags"
127
+ ownerType: SHOP
128
+ }
129
+ ) {
130
+ metafieldStorefrontVisibility {
131
+ id
132
+ }
133
+ userErrors {
134
+ field
135
+ message
136
+ }
137
+ }
138
+ }
139
+ '
140
+ ```
141
+
142
+ 4. Run the following command to expose the `ReviewsWidgetSnippet` Product Metafield.
143
+
144
+ ```bash
145
+ curl -X POST \
146
+ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
147
+ -H 'Content-Type: application/graphql' \
148
+ -H 'X-Shopify-Access-Token: {access_token}' \
149
+ -d '
150
+ mutation {
151
+ metafieldStorefrontVisibilityCreate(
152
+ input: {
153
+ namespace: "okendo"
154
+ key: "ReviewsWidgetSnippet"
155
+ ownerType: PRODUCT
156
+ }
157
+ ) {
158
+ metafieldStorefrontVisibility {
159
+ id
160
+ }
161
+ userErrors {
162
+ field
163
+ message
164
+ }
165
+ }
166
+ }
167
+ '
168
+ ```
169
+
170
+ 5. Run the following command to expose the `StarRatingSnippet` the Product Metafield.
171
+
172
+ ```bash
173
+ curl -X POST \
174
+ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
175
+ -H 'Content-Type: application/graphql' \
176
+ -H 'X-Shopify-Access-Token: {access_token}' \
177
+ -d '
178
+ mutation {
179
+ metafieldStorefrontVisibilityCreate(
180
+ input: {
181
+ namespace: "okendo"
182
+ key: "StarRatingSnippet"
183
+ ownerType: PRODUCT
184
+ }
185
+ ) {
186
+ metafieldStorefrontVisibility {
187
+ id
188
+ }
189
+ userErrors {
190
+ field
191
+ message
192
+ }
193
+ }
194
+ }
195
+ '
196
+ ```
197
+
198
+ ## Using GraphQL IDE
199
+
200
+ 1. Open your GraphQL IDE (such as Postman) and make a `POST` request with the following details:
201
+
202
+ - **URL:** https://{shop}.myshopify.com/admin/api/2022-04/graphql.json
203
+ - **Headers:** - X-Shopify-Access-Token: {access_token} - Content-Type: application/json 2. Execute the following request to expose the `WidgetPreRenderStyleTag` Shop Metafield.
204
+
205
+ ```graphql
206
+ mutation {
207
+ metafieldStorefrontVisibilityCreate(
208
+ input: {
209
+ namespace: "okendo"
210
+ key: "WidgetPreRenderStyleTags"
211
+ ownerType: SHOP
212
+ }
213
+ ) {
214
+ metafieldStorefrontVisibility {
215
+ id
216
+ }
217
+ userErrors {
218
+ field
219
+ message
220
+ }
221
+ }
222
+ }
223
+ ```
224
+
225
+ 3. Execute the following request to expose the `WidgetPreRenderBodyStyleTags` Shop Metafield.
226
+
227
+ ```graphql
228
+ mutation {
229
+ metafieldStorefrontVisibilityCreate(
230
+ input: {
231
+ namespace: "okendo"
232
+ key: "WidgetPreRenderBodyStyleTags"
233
+ ownerType: SHOP
234
+ }
235
+ ) {
236
+ metafieldStorefrontVisibility {
237
+ id
238
+ }
239
+ userErrors {
240
+ field
241
+ message
242
+ }
243
+ }
244
+ }
245
+ ```
246
+
247
+ 4. Execute the following request to expose the `ReviewsWidgetSnippet` Product Metafield.
248
+
249
+ ```graphql
250
+ mutation {
251
+ metafieldStorefrontVisibilityCreate(
252
+ input: {
253
+ namespace: "okendo"
254
+ key: "ReviewsWidgetSnippet"
255
+ ownerType: PRODUCT
256
+ }
257
+ ) {
258
+ metafieldStorefrontVisibility {
259
+ id
260
+ }
261
+ userErrors {
262
+ field
263
+ message
264
+ }
265
+ }
266
+ }
267
+ ```
268
+
269
+ 5. Execute the following request to expose the `StarRatingSnippet` the Product Metafield.
270
+
271
+ ```graphql
272
+ mutation {
273
+ metafieldStorefrontVisibilityCreate(
274
+ input: {
275
+ namespace: "okendo"
276
+ key: "StarRatingSnippet"
277
+ ownerType: PRODUCT
278
+ }
279
+ ) {
280
+ metafieldStorefrontVisibility {
281
+ id
282
+ }
283
+ userErrors {
284
+ field
285
+ message
286
+ }
287
+ }
288
+ }
289
+ ```
290
+
291
+ **References**
292
+
293
+ [https://shopify.dev/api/examples/metafields#step-1-expose-metafields](https://shopify.dev/api/examples/metafields#step-1-expose-metafields)
294
+ [https://shopify.dev/api/admin-graphql/2022-04/mutations/metafieldstorefrontvisibilitycreate](https://shopify.dev/api/admin-graphql/2022-04/mutations/metafieldstorefrontvisibilitycreate)
295
+ </details>
296
+
297
+ <br/><br/>
298
+
299
+ <a name="okendohydrogencomponentsusage"></a>
300
+
301
+ ## 3. How to Use Okendo Hydrogen Components In Your Hydrogen App
302
+
303
+ ### Installation
304
+
305
+ 1. In your Hydrogen app directory, run `npm install @okendo/shopify-hydrogen` inside a terminal or PowerShell window.
306
+ 2. Open **vite.config.js** and add `import okendo from '@okendo/shopify-hydrogen/plugin` to the list of imports.
307
+ 3. Add `okendo()` to the list of `plugins`.
308
+
309
+ ```tsx
310
+ /* **vite.config.js */**
311
+ import {defineConfig} from 'vite';
312
+ import hydrogen from '@shopify/hydrogen/plugin';
313
+ import okendo from '@okendo/shopify-hydrogen/plugin';
314
+
315
+ // https://vitejs.dev/config/
316
+ export default defineConfig({
317
+ plugins: [hydrogen(), okendo()],
318
+ optimizeDeps: {include: ['@headlessui/react']},
319
+ test: {
320
+ globals: true,
321
+ testTimeout: 10000,
322
+ hookTimeout: 10000,
323
+ },
324
+ });
325
+ ```
326
+
327
+ 4. Open **App.server.jsx** and import `OkendoProvider`.
328
+ 5. Include the `OkendoProvider` as shown below.
329
+
330
+ ```tsx
331
+ /* **App.server.jsx */**
332
+ import { OkendoProvider } from '@okendo/shopify-hydrogen';
333
+
334
+ function App() {
335
+ return (
336
+ <Suspense fallback={<LoadingFallback />}>
337
+ <ShopifyProvider>
338
+ <!-- *** Include OkendoProvider HERE *** -->
339
+ <OkendoProvider subscriberId={okendo_subscriber_id} />
340
+ <ServerCartProvider>
341
+ <DefaultSeo />
342
+ <Router>
343
+ <FileRoutes />
344
+ <Route path="*" page={<NotFound />} />
345
+ </Router>
346
+ </ServerCartProvider>
347
+ <PerformanceMetrics />
348
+ {import.meta.env.DEV && <PerformanceMetricsDebug />}
349
+ </ShopifyProvider>
350
+ </Suspense>
351
+ );
352
+
353
+ ```
354
+
355
+ ### **Widget Usage**
356
+
357
+ - Import `OkendoReviewsWidget` and `OkendoStarRating` and use as JSX components. Pass in the Shopify product ID as a prop.
358
+ - The `productId` prop is optional for the `OkendoReviewsWidget`. Not providing will mean that the widget will display reviews for all products, which is ideal for homepages or collection pages.
359
+
360
+ ```tsx
361
+ import {
362
+ OkendoReviewsWidget,
363
+ OkendoStarRating,
364
+ } from "@okendo/shopify-hydrogen";
365
+
366
+ const okendoReviewsWidget = <OkendoReviewsWidget productId={product.id} />;
367
+ const okendoStarRating = <OkendoStarRating productId={product.id} />;
368
+ ```
369
+
370
+ > ℹ️ If you are wanting to use Okendo server components within React client components, you must pass the component in as a prop to the client component passed down from another server component. Otherwise, you can use the component directly in a server component. [Learn more here](https://shopify.dev/api/hydrogen/components#customizing-hydrogen-components).
371
+
372
+ <br/>
373
+
374
+ ---
375
+
376
+ <a name="componentprops"></a>
377
+
378
+ ## Component Props
379
+
380
+ <br/>
381
+
382
+ ### OkendoProviderProps
383
+
384
+ | Name | Type | Description | Optional |
385
+ | ------------------------ | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
386
+ | subscriberId | string | The Okendo subscriber ID. | no |
387
+ | apiDomain | string | To override the default Okendo API Domain. (Default: api.okendo.io/v1) | yes |
388
+ | cdnDomain | string | To override the default Okendo CDN domain. (Default: d3hw6dc1ow8pp2.cloudfront.net) | yes |
389
+ | productUrlFormatOverride | (product: Pick<ReviewWithProductPublic, 'productHandle' \| 'productId' \| 'variantId'>) => string; | By default, we use Hydrogen’s default product routing. **Advanced Usage Only:** Function hook which allows the custom configuration of the Shopify product URLs from the Okendo Reviews Widget. | yes |
390
+
391
+ <br/><br/>
392
+
393
+ ### OkendoReviewsWidgetProps
394
+
395
+ | Name | Type | Description | Optional |
396
+ | --------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
397
+ | productId | string | The Shopify Product ID. If provided, the Reviews Widget will be configured to display reviews specific to that product. Otherwise, the Reviews Widget will display reviews for all products. | yes |
398
+
399
+ <br/>
400
+
401
+ ### OkendoStarRatingProps
402
+
403
+ | Name | Type | Description | Optional |
404
+ | --------- | ------ | ----------------------- | -------- |
405
+ | productId | string | The Shopify Product ID. | no |
406
+
407
+ <br/>
408
+
409
+ ---
410
+
411
+ <br/>
412
+
413
+ <a name="npmdefinitions"></a>
414
+
415
+ ## NPM Component Definitions
11
416
 
12
417
  ### OkendoProvider.server
13
418
 
@@ -25,21 +430,26 @@ The final server side render/output includes:
25
430
  - Okendo Initialisation Script: This is used to render the widgets on the page.
26
431
  - Any custom CSS specified in the Okendo Admin.
27
432
 
433
+ <br/>
434
+
28
435
  ### OkendoStarRating.server
29
436
 
30
- This is the server-side rendered Star Rating widget. It then invokes the client side `OkendoWidget.client.tsx` component to perform client side hydration.
437
+ This is the server-side rendered Star Rating widget - It then invokes the client side `OkendoWidget.client.tsx` component to perform client side hydration.
438
+
439
+ <br/>
31
440
 
32
441
  ### OkendoReviewsWidget.server
33
442
 
34
- This is the server-side rendered Reviews List widget. It then invokes the client side `OkendoWidget.client.tsx` component to perform client side hydration.
443
+ This is the server-side rendered Reviews List widget - It then invokes the client side `OkendoWidget.client.tsx` component to perform client side hydration.
444
+
445
+ ---
446
+
447
+ <br/>
35
448
 
36
- ## How do I use this in my Shopify Hydrogen project?
449
+ <a name="learnmore"></a>
37
450
 
38
- - [Okendo Shopify Hydrogen Guide](https://www.notion.so/okendo/Okendo-Shopify-Hydrogen-Guide-0054b79113c34a1fb3f9a8b661ddaac9)
39
- - [Okendo Shopify Hydrogen Demo Project](https://bitbucket.org/okendo/okendo-shopify-hydrogen-demo/)
451
+ ## View Our Okendo Sample Hydrogen App
40
452
 
41
- ## Who do I talk to?
453
+ We have created a Shopify Hydrogen sample application with our widgets pre-installed.
42
454
 
43
- - Tom Fulcher - tom.fulcher@okendo.io
44
- - Susanne Peng - susanne.peng@okendo.io
45
- - Rowan Puckeridge - rowan.puckeridge@okendo.io
455
+ - [View our Sample Okendo Shopify Hydrogen Demo Repository](https://github.com/okendo/okendo-shopify-hydrogen-demo)
@@ -1,12 +1,12 @@
1
- import React from "react";
1
+ import React from 'react';
2
+ import { ServerComponentRequest } from '@shopify/hydrogen/dist/esnext/framework/Hydration/ServerComponentRequest.server';
2
3
  import type { ReviewWithProductPublic } from '@okendo/reviews-common';
3
- export declare const OkendoContext: React.Context<{}>;
4
4
  export declare const OkendoProvider: React.FunctionComponent<OkendoProviderProps>;
5
5
  interface OkendoProviderProps {
6
- children: React.ReactNode;
7
- subscriberId: string;
8
6
  apiDomain?: string;
9
7
  cdnDomain?: string;
10
8
  productUrlFormatOverride?: (product: Pick<ReviewWithProductPublic, 'productHandle' | 'productId' | 'variantId'>) => string;
9
+ request: ServerComponentRequest;
10
+ subscriberId: string;
11
11
  }
12
12
  export {};
@@ -1,23 +1,41 @@
1
- import React from "react";
2
- import parse from "html-react-parser";
3
- import { Head } from "@shopify/hydrogen/client";
4
- import { fetchSync, useShopQuery, gql } from "@shopify/hydrogen";
5
- const kDefaultContext = {};
1
+ import React from 'react';
2
+ import parse from 'html-react-parser';
3
+ import { fetchSync, useShopQuery, gql, CacheMinutes } from '@shopify/hydrogen';
4
+ import { Head } from '@shopify/hydrogen/client';
5
+ import { okendoError, setInOkendoRequestContext } from '../shared';
6
6
  const kDefaultOkendoApiDomain = 'api.okendo.io/v1';
7
7
  const kDefaultOkendoCdnDomain = 'd3hw6dc1ow8pp2.cloudfront.net';
8
- export const OkendoContext = React.createContext(kDefaultContext);
9
8
  export const OkendoProvider = (props) => {
10
- var _a;
11
- const { children, subscriberId, apiDomain, cdnDomain, productUrlFormatOverride } = props;
9
+ const { apiDomain, cdnDomain, productUrlFormatOverride, request, subscriberId } = props;
10
+ // Download subscriber widget plus settings.
12
11
  const url = `https://${apiDomain !== null && apiDomain !== void 0 ? apiDomain : kDefaultOkendoApiDomain}/stores/${subscriberId}/widget_plus_settings`;
13
- const { reviewsHeaderConfig, cssVariables, customCss, starSymbols } = fetchSync(url, { preload: true }).json();
12
+ const settingsResponse = fetchSync(url, { preload: true });
13
+ if (!settingsResponse.response.ok) {
14
+ console.error(okendoError('Failed to retrieve subscriber settings. Please check your environment variables.'));
15
+ setInOkendoRequestContext(request, 'setupFailed', true);
16
+ return null;
17
+ }
18
+ const { cssVariables, customCss, reviewsHeaderConfig, starSymbols } = settingsResponse.json();
14
19
  const cssVariablesNormalized = cssVariables.replace('<style id="oke-css-vars">', '').replace('</style>', '');
15
- const customCssNormalized = customCss && customCss.replace('<style id="oke-reviews-custom-css">', '').replace('</style>', '');
20
+ const customCssNormalized = customCss ? customCss.replace('<style id="oke-reviews-custom-css">', '').replace('</style>', '') : '';
21
+ // Download contents of widget initialisation script.
22
+ const initScriptResponse = fetchSync(`https://${cdnDomain !== null && cdnDomain !== void 0 ? cdnDomain : kDefaultOkendoCdnDomain}/reviews-widget-plus/js/okendo-reviews.js`, {
23
+ cache: CacheMinutes(),
24
+ preload: true
25
+ });
26
+ if (!initScriptResponse.response.ok) {
27
+ console.error(okendoError('Failed to retrieve widget initialization script.'));
28
+ setInOkendoRequestContext(request, 'setupFailed', true);
29
+ return null;
30
+ }
31
+ const initScriptContents = initScriptResponse.text();
32
+ // Set up product URL formatter.
16
33
  const productUrlFormatter = typeof productUrlFormatOverride === 'function'
17
34
  ? productUrlFormatOverride
18
35
  : (product) => (product === null || product === void 0 ? void 0 : product.productHandle)
19
36
  ? `/products/${product.productHandle}/${product.variantId ? '?variantId=' + product.variantId : ''}`
20
37
  : undefined;
38
+ // Get pre-rendered style settings.
21
39
  const query = gql `
22
40
  query metafields {
23
41
  shop {
@@ -31,9 +49,10 @@ export const OkendoProvider = (props) => {
31
49
  query: query,
32
50
  preload: true
33
51
  });
34
- const styles = parse((_a = widgetPreRenderStyleTags === null || widgetPreRenderStyleTags === void 0 ? void 0 : widgetPreRenderStyleTags.value) !== null && _a !== void 0 ? _a : '');
35
- // Download contents of widget initialisation script.
36
- const initScriptContents = fetchSync(`https://${cdnDomain !== null && cdnDomain !== void 0 ? cdnDomain : kDefaultOkendoCdnDomain}/reviews-widget-plus/js/okendo-reviews.js`).text();
52
+ const preRenderStyleTags = (widgetPreRenderStyleTags === null || widgetPreRenderStyleTags === void 0 ? void 0 : widgetPreRenderStyleTags.value) ? parse(widgetPreRenderStyleTags.value) : '';
53
+ if (!preRenderStyleTags) {
54
+ console.warn(okendoError('Failed to retrieve pre-rendered widget style settings.'));
55
+ }
37
56
  return (React.createElement(React.Fragment, null,
38
57
  React.createElement(Head, null,
39
58
  React.createElement("script", { id: "oke-reviews-settings", type: "application/json" }, JSON.stringify(reviewsHeaderConfig)),
@@ -42,8 +61,7 @@ export const OkendoProvider = (props) => {
42
61
  React.createElement("meta", { name: "oke:subscriber_id", content: subscriberId }),
43
62
  React.createElement("script", null, initScriptContents),
44
63
  productUrlFormatter && React.createElement("script", { type: "text/javascript" }, `window.okeProductUrlFormatter = ${productUrlFormatter}`)),
45
- styles,
46
- parse(starSymbols),
47
- children));
64
+ preRenderStyleTags,
65
+ parse(starSymbols)));
48
66
  };
49
67
  //# sourceMappingURL=OkendoProvider.server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OkendoProvider.server.js","sourceRoot":"","sources":["../../../src/components/OkendoProvider.server.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\nimport parse from \"html-react-parser\";\nimport { Head } from \"@shopify/hydrogen/client\";\nimport { fetchSync, useShopQuery, gql } from \"@shopify/hydrogen\";\nimport type { ReviewsAPIPublic, ReviewWithProductPublic } from '@okendo/reviews-common';\nimport type { Metafield } from \"@shopify/hydrogen/dist/esnext/storefront-api-types\";\n\nconst kDefaultContext = {};\nconst kDefaultOkendoApiDomain = 'api.okendo.io/v1';\nconst kDefaultOkendoCdnDomain = 'd3hw6dc1ow8pp2.cloudfront.net';\n\nexport const OkendoContext = React.createContext(kDefaultContext);\n\nexport const OkendoProvider: React.FunctionComponent<OkendoProviderProps> = (props): JSX.Element => {\n const { children, subscriberId, apiDomain, cdnDomain, productUrlFormatOverride } = props;\n const url = `https://${apiDomain ?? kDefaultOkendoApiDomain}/stores/${subscriberId}/widget_plus_settings`;\n const { reviewsHeaderConfig, cssVariables, customCss, starSymbols } = fetchSync(url, { preload: true }).json() as ReviewsAPIPublic.Reviews.WidgetPlusSettings.Get.Response;\n\n const cssVariablesNormalized = cssVariables.replace('<style id=\"oke-css-vars\">', '').replace('</style>', '');\n const customCssNormalized = customCss && customCss.replace('<style id=\"oke-reviews-custom-css\">', '').replace('</style>', '');\n\n const productUrlFormatter = typeof productUrlFormatOverride === 'function' \n ? productUrlFormatOverride \n : (product: Pick<ReviewWithProductPublic, 'productHandle' | 'productId' | 'variantId'>) =>\n product?.productHandle\n ? `/products/${product.productHandle}/${\n product.variantId ? '?variantId=' + product.variantId : ''\n }`\n : undefined;\n\n const query = gql`\n query metafields {\n shop {\n widgetPreRenderStyleTags: metafield(namespace: \"okendo\", key: \"WidgetPreRenderStyleTags\") {\n value\n }\n }\n }\n `;\n\n const {\n data: { shop: { widgetPreRenderStyleTags } }\n } = useShopQuery<OkendoProviderMetafields>({\n query: query,\n preload: true\n });\n\n const styles = parse(widgetPreRenderStyleTags?.value ?? '');\n\n // Download contents of widget initialisation script.\n const initScriptContents: string = fetchSync(`https://${cdnDomain ?? kDefaultOkendoCdnDomain}/reviews-widget-plus/js/okendo-reviews.js`).text();\n return (\n <>\n <Head>\n <script id=\"oke-reviews-settings\" type=\"application/json\">\n {JSON.stringify(reviewsHeaderConfig)}\n </script>\n <style id=\"oke-css-vars\">\n {cssVariablesNormalized}\n </style>\n {customCssNormalized && <style id=\"oke-reviews-custom-css\">{customCssNormalized}</style>}\n <meta name=\"oke:subscriber_id\" content={subscriberId} />\n <script>{initScriptContents}</script>\n {productUrlFormatter && <script type=\"text/javascript\">{`window.okeProductUrlFormatter = ${productUrlFormatter}`}</script>}\n </Head>\n {styles}\n {parse(starSymbols)}\n {children}\n </>\n );\n}\n\ninterface OkendoProviderProps {\n children: React.ReactNode;\n subscriberId: string;\n apiDomain?: string;\n cdnDomain?: string;\n productUrlFormatOverride?: (product: Pick<ReviewWithProductPublic, 'productHandle' | 'productId' | 'variantId'>) => string;\n}\n\ninterface OkendoProviderMetafields {\n shop: {\n widgetPreRenderStyleTags?: Pick<Metafield, 'value'>\n };\n}\n"]}
1
+ {"version":3,"file":"OkendoProvider.server.js","sourceRoot":"","sources":["../../../src/components/OkendoProvider.server.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport parse from 'html-react-parser';\nimport { fetchSync, useShopQuery, gql, CacheMinutes } from '@shopify/hydrogen';\nimport { Head } from '@shopify/hydrogen/client';\nimport { ServerComponentRequest } from '@shopify/hydrogen/dist/esnext/framework/Hydration/ServerComponentRequest.server';\nimport type { Metafield } from '@shopify/hydrogen/dist/esnext/storefront-api-types';\nimport type { ReviewsAPIPublic, ReviewWithProductPublic } from '@okendo/reviews-common';\n\nimport { okendoError, setInOkendoRequestContext } from '../shared';\n\nconst kDefaultOkendoApiDomain = 'api.okendo.io/v1';\nconst kDefaultOkendoCdnDomain = 'd3hw6dc1ow8pp2.cloudfront.net';\n\nexport const OkendoProvider: React.FunctionComponent<OkendoProviderProps> = (props): JSX.Element | null => {\n const { apiDomain, cdnDomain, productUrlFormatOverride, request, subscriberId } = props;\n\n // Download subscriber widget plus settings.\n const url = `https://${apiDomain ?? kDefaultOkendoApiDomain}/stores/${subscriberId}/widget_plus_settings`;\n const settingsResponse = fetchSync(url, { preload: true });\n\n if (!settingsResponse.response.ok) {\n console.error(okendoError('Failed to retrieve subscriber settings. Please check your environment variables.'));\n setInOkendoRequestContext(request, 'setupFailed', true);\n return null;\n }\n\n const { cssVariables, customCss, reviewsHeaderConfig, starSymbols } = settingsResponse.json() as ReviewsAPIPublic.Reviews.WidgetPlusSettings.Get.Response;\n const cssVariablesNormalized = cssVariables.replace('<style id=\"oke-css-vars\">', '').replace('</style>', '');\n const customCssNormalized = customCss ? customCss.replace('<style id=\"oke-reviews-custom-css\">', '').replace('</style>', '') : '';\n\n // Download contents of widget initialisation script.\n const initScriptResponse = fetchSync(`https://${cdnDomain ?? kDefaultOkendoCdnDomain}/reviews-widget-plus/js/okendo-reviews.js`, {\n cache: CacheMinutes(),\n preload: true\n });\n\n if (!initScriptResponse.response.ok) {\n console.error(okendoError('Failed to retrieve widget initialization script.'));\n setInOkendoRequestContext(request, 'setupFailed', true);\n return null;\n }\n\n const initScriptContents = initScriptResponse.text();\n\n // Set up product URL formatter.\n const productUrlFormatter = typeof productUrlFormatOverride === 'function'\n ? productUrlFormatOverride\n : (product: Pick<ReviewWithProductPublic, 'productHandle' | 'productId' | 'variantId'>) =>\n product?.productHandle\n ? `/products/${product.productHandle}/${product.variantId ? '?variantId=' + product.variantId : ''}`\n : undefined;\n\n // Get pre-rendered style settings.\n const query = gql`\n query metafields {\n shop {\n widgetPreRenderStyleTags: metafield(namespace: \"okendo\", key: \"WidgetPreRenderStyleTags\") {\n value\n }\n }\n }\n `;\n\n const {\n data: { shop: { widgetPreRenderStyleTags } }\n } = useShopQuery<OkendoProviderMetafields>({\n query: query,\n preload: true\n });\n\n const preRenderStyleTags = widgetPreRenderStyleTags?.value ? parse(widgetPreRenderStyleTags.value) : '';\n\n if (!preRenderStyleTags) {\n console.warn(okendoError('Failed to retrieve pre-rendered widget style settings.'));\n }\n\n return (\n <>\n <Head>\n <script id=\"oke-reviews-settings\" type=\"application/json\">{JSON.stringify(reviewsHeaderConfig)}</script>\n <style id=\"oke-css-vars\">{cssVariablesNormalized}</style>\n {customCssNormalized && <style id=\"oke-reviews-custom-css\">{customCssNormalized}</style>}\n <meta name=\"oke:subscriber_id\" content={subscriberId} />\n <script>{initScriptContents}</script>\n {productUrlFormatter && <script type=\"text/javascript\">{`window.okeProductUrlFormatter = ${productUrlFormatter}`}</script>}\n </Head>\n {preRenderStyleTags}\n {parse(starSymbols)}\n </>\n );\n}\n\ninterface OkendoProviderProps {\n apiDomain?: string;\n cdnDomain?: string;\n productUrlFormatOverride?: (product: Pick<ReviewWithProductPublic, 'productHandle' | 'productId' | 'variantId'>) => string;\n request: ServerComponentRequest;\n subscriberId: string;\n}\n\ninterface OkendoProviderMetafields {\n shop: {\n widgetPreRenderStyleTags?: Pick<Metafield, 'value'>\n };\n}\n"]}
@@ -1,10 +1,14 @@
1
- import { useShopQuery, gql } from '@shopify/hydrogen';
1
+ import React from 'react';
2
2
  import parse from 'html-react-parser';
3
+ import { useShopQuery, gql } from '@shopify/hydrogen';
3
4
  import { OkendoWidgetClient } from './OkendoWidget.client';
4
- import { getOkendoProductId } from '../shared/productUtils';
5
- import React from 'react';
5
+ import { getOkendoProductId, useOkendoRequestContext, widgetMetafieldError } from '../shared';
6
6
  export const OkendoReviewsWidget = (props) => {
7
- var _a, _b, _c, _d;
7
+ var _a, _b, _c, _d, _e, _f;
8
+ const { setupFailed } = useOkendoRequestContext();
9
+ if (setupFailed) {
10
+ return null;
11
+ }
8
12
  const { productId } = props;
9
13
  const productQuery = productId
10
14
  ? `
@@ -29,16 +33,14 @@ export const OkendoReviewsWidget = (props) => {
29
33
  query: query,
30
34
  preload: true,
31
35
  variables: {
32
- productId: productId
36
+ productId
33
37
  }
34
38
  });
35
39
  if (productId && !((_a = product === null || product === void 0 ? void 0 : product.reviewsWidgetSnippet) === null || _a === void 0 ? void 0 : _a.value)) {
36
- console.error(`--OKE-- Could not retrieve product 'reviewsWidgetSnippet' metafield.`);
37
- return null;
40
+ console.warn(widgetMetafieldError('OkendoReviewsWidget', 'ReviewsWidgetSnippet'));
38
41
  }
39
42
  if (!((_b = shop === null || shop === void 0 ? void 0 : shop.widgetPreRenderBodyStyleTags) === null || _b === void 0 ? void 0 : _b.value)) {
40
- console.error(`--OKE-- Could not retrieve shop 'widgetPreRenderBodyStyleTags' metafield.`);
41
- return null;
43
+ console.warn(widgetMetafieldError('OkendoReviewsWidget', 'WidgetPreRenderBodyStyleTags'));
42
44
  }
43
45
  const dataAttributes = {
44
46
  'data-oke-widget': ''
@@ -50,8 +52,8 @@ export const OkendoReviewsWidget = (props) => {
50
52
  }
51
53
  }
52
54
  return (React.createElement(React.Fragment, null,
53
- parse(shop.widgetPreRenderBodyStyleTags.value),
54
- React.createElement(OkendoWidgetClient, { dataAttributes: dataAttributes, metafieldContent: (_d = (_c = product === null || product === void 0 ? void 0 : product.reviewsWidgetSnippet) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : '' })));
55
+ parse((_d = (_c = shop === null || shop === void 0 ? void 0 : shop.widgetPreRenderBodyStyleTags) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : ''),
56
+ React.createElement(OkendoWidgetClient, { dataAttributes: dataAttributes, metafieldContent: (_f = (_e = product === null || product === void 0 ? void 0 : product.reviewsWidgetSnippet) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : '' })));
55
57
  };
56
58
  export default OkendoReviewsWidget;
57
59
  //# sourceMappingURL=OkendoReviewsWidget.server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OkendoReviewsWidget.server.js","sourceRoot":"","sources":["../../../src/components/OkendoReviewsWidget.server.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,mBAAmB,GAAsD,CAAC,KAAK,EAAE,EAAE;;IAC5F,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE5B,MAAM,YAAY,GAAG,SAAS;QAC1B,CAAC,CAAC;;;;;;SAMD;QACD,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,KAAK,GAAG,GAAG,CAAA;0BACK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE;cAChD,YAAY;;;;;;;KAOrB,CAAC;IAEF,MAAM,EACF,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAC1B,GAAG,YAAY,CAAgC;QAC5C,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,IAAI;QACb,SAAS,EAAE;YACP,SAAS,EAAE,SAAS;SACvB;KACJ,CAAC,CAAC;IAEH,IAAI,SAAS,IAAI,CAAC,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,0CAAE,KAAK,CAAA,EAAE;QACpD,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;KACf;IAED,IAAI,CAAC,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,4BAA4B,0CAAE,KAAK,CAAA,EAAE;QAC5C,OAAO,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC3F,OAAO,IAAI,CAAC;KACf;IAED,MAAM,cAAc,GAAQ;QACxB,iBAAiB,EAAE,EAAE;KACxB,CAAC;IAEF,IAAI,SAAS,EAAE;QACX,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,eAAe,EAAE;YACjB,cAAc,CAAC,6BAA6B,CAAC,GAAG,eAAe,CAAC;SACnE;KACJ;IAED,OAAO,CACH;QACK,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,KAAK,CAAC;QAC/C,oBAAC,kBAAkB,IAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,0CAAE,KAAK,mCAAI,EAAE,GAAI,CACrH,CACN,CAAC;AACN,CAAC,CAAC;AAeF,eAAe,mBAAmB,CAAC","sourcesContent":["import { useShopQuery, gql } from '@shopify/hydrogen';\nimport parse from 'html-react-parser';\nimport { OkendoWidgetClient } from './OkendoWidget.client';\nimport { Metafield } from '@shopify/hydrogen/dist/esnext/storefront-api-types';\nimport { getOkendoProductId } from '../shared/productUtils';\nimport type { SKO } from '@okendo/reviews-common';\nimport React from 'react';\n\nexport const OkendoReviewsWidget: React.FunctionComponent<OkendoReviewsWidgetProps> = (props) => {\n const { productId } = props;\n\n const productQuery = productId\n ? `\n product(id: $productId) {\n reviewsWidgetSnippet: metafield(namespace: \"okendo\", key: \"ReviewsWidgetSnippet\") {\n value\n }\n }\n `\n : '';\n\n const query = gql`\n query metafields${productId ? '($productId: ID!)' : ''} {\n ${productQuery}\n shop {\n widgetPreRenderBodyStyleTags: metafield(namespace: \"okendo\", key: \"WidgetPreRenderBodyStyleTags\") {\n value\n }\n }\n }\n `;\n\n const {\n data: { product, shop }\n } = useShopQuery<OkendoReviewsWidgetMetafields>({\n query: query,\n preload: true,\n variables: {\n productId: productId\n }\n });\n\n if (productId && !product?.reviewsWidgetSnippet?.value) {\n console.error(`--OKE-- Could not retrieve product 'reviewsWidgetSnippet' metafield.`);\n return null;\n }\n\n if (!shop?.widgetPreRenderBodyStyleTags?.value) {\n console.error(`--OKE-- Could not retrieve shop 'widgetPreRenderBodyStyleTags' metafield.`);\n return null;\n }\n\n const dataAttributes: SKO = {\n 'data-oke-widget': ''\n };\n\n if (productId) {\n const okendoProductId = getOkendoProductId(productId);\n if (okendoProductId) {\n dataAttributes['data-oke-reviews-product-id'] = okendoProductId;\n }\n }\n\n return (\n <>\n {parse(shop.widgetPreRenderBodyStyleTags.value)}\n <OkendoWidgetClient dataAttributes={dataAttributes} metafieldContent={product?.reviewsWidgetSnippet?.value ?? ''} />\n </>\n );\n};\n\ninterface OkendoReviewsWidgetProps {\n productId?: string;\n}\n\ninterface OkendoReviewsWidgetMetafields {\n product: {\n reviewsWidgetSnippet?: Pick<Metafield, 'value'>;\n };\n shop: {\n widgetPreRenderBodyStyleTags?: Pick<Metafield, 'value'>;\n };\n}\n\nexport default OkendoReviewsWidget;\n"]}
1
+ {"version":3,"file":"OkendoReviewsWidget.server.js","sourceRoot":"","sources":["../../../src/components/OkendoReviewsWidget.server.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAItD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAE9F,MAAM,CAAC,MAAM,mBAAmB,GAAsD,CAAC,KAAK,EAA6B,EAAE;;IACvH,MAAM,EAAE,WAAW,EAAE,GAAG,uBAAuB,EAAE,CAAC;IAClD,IAAI,WAAW,EAAE;QACb,OAAO,IAAI,CAAC;KACf;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE5B,MAAM,YAAY,GAAG,SAAS;QAC1B,CAAC,CAAC;;;;;;SAMD;QACD,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,KAAK,GAAG,GAAG,CAAA;0BACK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE;cAChD,YAAY;;;;;;;KAOrB,CAAC;IAEF,MAAM,EACF,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAC1B,GAAG,YAAY,CAAgC;QAC5C,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,IAAI;QACb,SAAS,EAAE;YACP,SAAS;SACZ;KACJ,CAAC,CAAC;IAEH,IAAI,SAAS,IAAI,CAAC,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,0CAAE,KAAK,CAAA,EAAE;QACpD,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,EAAE,sBAAsB,CAAC,CAAC,CAAC;KACrF;IAED,IAAI,CAAC,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,4BAA4B,0CAAE,KAAK,CAAA,EAAE;QAC5C,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,EAAE,8BAA8B,CAAC,CAAC,CAAC;KAC7F;IAED,MAAM,cAAc,GAAQ;QACxB,iBAAiB,EAAE,EAAE;KACxB,CAAC;IAEF,IAAI,SAAS,EAAE;QACX,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,eAAe,EAAE;YACjB,cAAc,CAAC,6BAA6B,CAAC,GAAG,eAAe,CAAC;SACnE;KACJ;IAED,OAAO,CACH;QACK,KAAK,CAAC,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,4BAA4B,0CAAE,KAAK,mCAAI,EAAE,CAAC;QACvD,oBAAC,kBAAkB,IAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,0CAAE,KAAK,mCAAI,EAAE,GAAI,CACrH,CACN,CAAC;AACN,CAAC,CAAC;AAeF,eAAe,mBAAmB,CAAC","sourcesContent":["import React from 'react';\nimport parse from 'html-react-parser';\nimport { useShopQuery, gql } from '@shopify/hydrogen';\nimport type { Metafield } from '@shopify/hydrogen/dist/esnext/storefront-api-types';\nimport type { SKO } from '@okendo/reviews-common';\n\nimport { OkendoWidgetClient } from './OkendoWidget.client';\nimport { getOkendoProductId, useOkendoRequestContext, widgetMetafieldError } from '../shared';\n\nexport const OkendoReviewsWidget: React.FunctionComponent<OkendoReviewsWidgetProps> = (props): React.ReactElement | null => {\n const { setupFailed } = useOkendoRequestContext();\n if (setupFailed) {\n return null;\n }\n\n const { productId } = props;\n\n const productQuery = productId\n ? `\n product(id: $productId) {\n reviewsWidgetSnippet: metafield(namespace: \"okendo\", key: \"ReviewsWidgetSnippet\") {\n value\n }\n }\n `\n : '';\n\n const query = gql`\n query metafields${productId ? '($productId: ID!)' : ''} {\n ${productQuery}\n shop {\n widgetPreRenderBodyStyleTags: metafield(namespace: \"okendo\", key: \"WidgetPreRenderBodyStyleTags\") {\n value\n }\n }\n }\n `;\n\n const {\n data: { product, shop }\n } = useShopQuery<OkendoReviewsWidgetMetafields>({\n query: query,\n preload: true,\n variables: {\n productId\n }\n });\n\n if (productId && !product?.reviewsWidgetSnippet?.value) {\n console.warn(widgetMetafieldError('OkendoReviewsWidget', 'ReviewsWidgetSnippet'));\n }\n\n if (!shop?.widgetPreRenderBodyStyleTags?.value) {\n console.warn(widgetMetafieldError('OkendoReviewsWidget', 'WidgetPreRenderBodyStyleTags'));\n }\n\n const dataAttributes: SKO = {\n 'data-oke-widget': ''\n };\n\n if (productId) {\n const okendoProductId = getOkendoProductId(productId);\n if (okendoProductId) {\n dataAttributes['data-oke-reviews-product-id'] = okendoProductId;\n }\n }\n\n return (\n <>\n {parse(shop?.widgetPreRenderBodyStyleTags?.value ?? '')}\n <OkendoWidgetClient dataAttributes={dataAttributes} metafieldContent={product?.reviewsWidgetSnippet?.value ?? ''} />\n </>\n );\n};\n\ninterface OkendoReviewsWidgetProps {\n productId?: string;\n}\n\ninterface OkendoReviewsWidgetMetafields {\n product: {\n reviewsWidgetSnippet?: Pick<Metafield, 'value'>;\n };\n shop: {\n widgetPreRenderBodyStyleTags?: Pick<Metafield, 'value'>;\n };\n}\n\nexport default OkendoReviewsWidget;\n"]}
@@ -1,12 +1,16 @@
1
+ import React from 'react';
1
2
  import { useShopQuery, gql } from '@shopify/hydrogen';
2
3
  import { OkendoWidgetClient } from './OkendoWidget.client';
3
- import { getOkendoProductId } from '../shared/productUtils';
4
- import React from 'react';
4
+ import { getOkendoProductId, useOkendoRequestContext, widgetConfigurationError, widgetMetafieldError } from '../shared';
5
5
  export const OkendoStarRating = (props) => {
6
+ const { setupFailed } = useOkendoRequestContext();
7
+ if (setupFailed) {
8
+ return null;
9
+ }
6
10
  const { productId } = props;
7
11
  const okendoProductId = getOkendoProductId(productId);
8
12
  if (!okendoProductId) {
9
- console.warn(`--OKE-- Product does not contain id.`);
13
+ console.error(widgetConfigurationError('OkendoStarRating', 'productId was not provided'));
10
14
  return null;
11
15
  }
12
16
  const query = gql `
@@ -22,19 +26,18 @@ export const OkendoStarRating = (props) => {
22
26
  query: query,
23
27
  preload: true,
24
28
  variables: {
25
- productId: productId
29
+ productId
26
30
  }
27
31
  });
28
32
  if (!(starRatingSnippet === null || starRatingSnippet === void 0 ? void 0 : starRatingSnippet.value)) {
29
- console.error(`--OKE-- Could not retrieve product 'starRatingSnippet' metafield.`);
30
- return null;
33
+ console.warn(widgetMetafieldError('OkendoStarRating', 'StarRatingSnippet'));
31
34
  }
32
35
  const dataAttributes = {
33
36
  'data-oke-star-rating': '',
34
37
  'data-oke-reviews-product-id': okendoProductId,
35
38
  'data-oke-scroll-disabled': 'true'
36
39
  };
37
- return (React.createElement(OkendoWidgetClient, { dataAttributes: dataAttributes, metafieldContent: starRatingSnippet.value }));
40
+ return (React.createElement(OkendoWidgetClient, { dataAttributes: dataAttributes, metafieldContent: starRatingSnippet === null || starRatingSnippet === void 0 ? void 0 : starRatingSnippet.value }));
38
41
  };
39
42
  export default OkendoStarRating;
40
43
  //# sourceMappingURL=OkendoStarRating.server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OkendoStarRating.server.js","sourceRoot":"","sources":["../../../src/components/OkendoStarRating.server.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,gBAAgB,GAAmD,CAAC,KAAK,EAAuB,EAAE;IAC3G,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE5B,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,eAAe,EAAE;QAClB,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;KACf;IAED,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;;;;KAQhB,CAAC;IAEF,MAAM,EACF,IAAI,EAAE,EACF,OAAO,EAAE,EAAE,iBAAiB,EAAE,EACjC,EACJ,GAAG,YAAY,CAA6B;QACzC,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,IAAI;QACb,SAAS,EAAE;YACP,SAAS,EAAE,SAAS;SACvB;KACJ,CAAC,CAAC;IAEH,IAAI,CAAC,CAAA,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,KAAK,CAAA,EAAE;QAC3B,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC;KACf;IAED,MAAM,cAAc,GAAG;QACnB,sBAAsB,EAAE,EAAE;QAC1B,6BAA6B,EAAE,eAAe;QAC9C,0BAA0B,EAAE,MAAM;KACrC,CAAC;IAEF,OAAO,CACH,oBAAC,kBAAkB,IAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,KAAK,GAAI,CACpG,CAAC;AACN,CAAC,CAAC;AAYF,eAAe,gBAAgB,CAAC","sourcesContent":["import { useShopQuery, gql } from '@shopify/hydrogen';\nimport { Metafield } from '@shopify/hydrogen/dist/esnext/storefront-api-types';\nimport { ReactElement } from 'react';\nimport { OkendoWidgetClient } from './OkendoWidget.client';\nimport { getOkendoProductId } from '../shared/productUtils';\nimport React from 'react';\n\nexport const OkendoStarRating: React.FunctionComponent<OkendoStarRatingProps> = (props): ReactElement | null => {\n const { productId } = props;\n\n const okendoProductId = getOkendoProductId(productId);\n if (!okendoProductId) {\n console.warn(`--OKE-- Product does not contain id.`);\n return null;\n }\n\n const query = gql`\n query metafields($productId: ID!) {\n product(id: $productId) {\n starRatingSnippet: metafield(namespace: \"okendo\", key: \"StarRatingSnippet\") {\n value\n }\n }\n }\n `;\n\n const {\n data: {\n product: { starRatingSnippet }\n }\n } = useShopQuery<OkendoStarRatingMetafields>({\n query: query,\n preload: true,\n variables: {\n productId: productId\n }\n });\n\n if (!starRatingSnippet?.value) {\n console.error(`--OKE-- Could not retrieve product 'starRatingSnippet' metafield.`);\n return null;\n }\n\n const dataAttributes = {\n 'data-oke-star-rating': '',\n 'data-oke-reviews-product-id': okendoProductId,\n 'data-oke-scroll-disabled': 'true'\n };\n\n return (\n <OkendoWidgetClient dataAttributes={dataAttributes} metafieldContent={starRatingSnippet.value} />\n );\n};\n\ninterface OkendoStarRatingProps {\n productId: string;\n}\n\ninterface OkendoStarRatingMetafields {\n product: {\n starRatingSnippet?: Pick<Metafield, 'value'>;\n };\n}\n\nexport default OkendoStarRating;\n"]}
1
+ {"version":3,"file":"OkendoStarRating.server.js","sourceRoot":"","sources":["../../../src/components/OkendoStarRating.server.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAExH,MAAM,CAAC,MAAM,gBAAgB,GAAmD,CAAC,KAAK,EAA6B,EAAE;IACjH,MAAM,EAAE,WAAW,EAAE,GAAG,uBAAuB,EAAE,CAAC;IAClD,IAAI,WAAW,EAAE;QACb,OAAO,IAAI,CAAC;KACf;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE5B,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,eAAe,EAAE;QAClB,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC,CAAC;QAC1F,OAAO,IAAI,CAAC;KACf;IAED,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;;;;KAQhB,CAAC;IAEF,MAAM,EACF,IAAI,EAAE,EACF,OAAO,EAAE,EAAE,iBAAiB,EAAE,EACjC,EACJ,GAAG,YAAY,CAA6B;QACzC,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,IAAI;QACb,SAAS,EAAE;YACP,SAAS;SACZ;KACJ,CAAC,CAAC;IAEH,IAAI,CAAC,CAAA,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,KAAK,CAAA,EAAE;QAC3B,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CAAC,CAAC;KAC/E;IAED,MAAM,cAAc,GAAG;QACnB,sBAAsB,EAAE,EAAE;QAC1B,6BAA6B,EAAE,eAAe;QAC9C,0BAA0B,EAAE,MAAM;KACrC,CAAC;IAEF,OAAO,CACH,oBAAC,kBAAkB,IAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,KAAK,GAAI,CACrG,CAAC;AACN,CAAC,CAAC;AAYF,eAAe,gBAAgB,CAAC","sourcesContent":["import React from 'react';\nimport { useShopQuery, gql } from '@shopify/hydrogen';\nimport type { Metafield } from '@shopify/hydrogen/dist/esnext/storefront-api-types';\n\nimport { OkendoWidgetClient } from './OkendoWidget.client';\nimport { getOkendoProductId, useOkendoRequestContext, widgetConfigurationError, widgetMetafieldError } from '../shared';\n\nexport const OkendoStarRating: React.FunctionComponent<OkendoStarRatingProps> = (props): React.ReactElement | null => {\n const { setupFailed } = useOkendoRequestContext();\n if (setupFailed) {\n return null;\n }\n\n const { productId } = props;\n\n const okendoProductId = getOkendoProductId(productId);\n if (!okendoProductId) {\n console.error(widgetConfigurationError('OkendoStarRating', 'productId was not provided'));\n return null;\n }\n\n const query = gql`\n query metafields($productId: ID!) {\n product(id: $productId) {\n starRatingSnippet: metafield(namespace: \"okendo\", key: \"StarRatingSnippet\") {\n value\n }\n }\n }\n `;\n\n const {\n data: {\n product: { starRatingSnippet }\n }\n } = useShopQuery<OkendoStarRatingMetafields>({\n query: query,\n preload: true,\n variables: {\n productId\n }\n });\n\n if (!starRatingSnippet?.value) {\n console.warn(widgetMetafieldError('OkendoStarRating', 'StarRatingSnippet'));\n }\n\n const dataAttributes = {\n 'data-oke-star-rating': '',\n 'data-oke-reviews-product-id': okendoProductId,\n 'data-oke-scroll-disabled': 'true'\n };\n\n return (\n <OkendoWidgetClient dataAttributes={dataAttributes} metafieldContent={starRatingSnippet?.value} />\n );\n};\n\ninterface OkendoStarRatingProps {\n productId: string;\n}\n\ninterface OkendoStarRatingMetafields {\n product: {\n starRatingSnippet?: Pick<Metafield, 'value'>;\n };\n}\n\nexport default OkendoStarRating;\n"]}
@@ -1,10 +1,10 @@
1
- import type { SKO } from "@okendo/reviews-common";
1
+ import React from 'react';
2
+ import type { SKO } from '@okendo/reviews-common';
2
3
  import type { ReviewsWidgetPlus } from '@okendo/reviews-widget-plus/dist-utils/ReviewsWidgetPlus';
3
- import React from "react";
4
4
  export declare const OkendoWidgetClient: React.FunctionComponent<OkendoWidgetClientProps>;
5
5
  export interface OkendoWidgetClientProps {
6
6
  dataAttributes: SKO;
7
- metafieldContent: string;
7
+ metafieldContent?: string;
8
8
  }
9
9
  declare global {
10
10
  interface Window {
@@ -1,7 +1,6 @@
1
- import React from "react";
2
- import { useEffect, useRef } from "react";
1
+ import React, { useEffect, useRef } from 'react';
3
2
  export const OkendoWidgetClient = (props) => {
4
- const { dataAttributes, metafieldContent } = props;
3
+ const { dataAttributes, metafieldContent = '' } = props;
5
4
  const widgetContainer = useRef(null);
6
5
  const initialiseReviewsWidget = () => {
7
6
  if (widgetContainer.current) {
@@ -1 +1 @@
1
- {"version":3,"file":"OkendoWidget.client.js","sourceRoot":"","sources":["../../../src/components/OkendoWidget.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,CAAC,MAAM,kBAAkB,GAAqD,CAAC,KAAK,EAAE,EAAE;IAC1F,MAAM,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;IACnD,MAAM,eAAe,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAErD,MAAM,uBAAuB,GAAG,GAAG,EAAE;QACjC,IAAI,eAAe,CAAC,OAAO,EAAE;YACzB,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;SAC3D;IACL,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,MAAM,CAAC,YAAY,EAAE;YACrB,uBAAuB,EAAE,CAAC;SAC7B;aACI;YACD,MAAM,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;SACzE;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACH,6BAAK,GAAG,EAAE,eAAe,KAAM,cAAc,EAAE,uBAAuB,EAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAS,CACjH,CAAC;AACN,CAAC,CAAA","sourcesContent":["import type { SKO } from \"@okendo/reviews-common\";\nimport type { ReviewsWidgetPlus } from '@okendo/reviews-widget-plus/dist-utils/ReviewsWidgetPlus';\nimport React from \"react\";\nimport { useEffect, useRef } from \"react\";\n\nexport const OkendoWidgetClient: React.FunctionComponent<OkendoWidgetClientProps> = (props) => {\n const { dataAttributes, metafieldContent } = props;\n const widgetContainer = useRef<HTMLDivElement>(null);\n\n const initialiseReviewsWidget = () => {\n if (widgetContainer.current) {\n window.okeWidgetApi.initWidget(widgetContainer.current);\n }\n };\n\n useEffect(() => {\n if (window.okeWidgetApi) {\n initialiseReviewsWidget();\n }\n else {\n window.addEventListener('oke-script-loaded', initialiseReviewsWidget);\n }\n }, []);\n\n return (\n <div ref={widgetContainer} {...dataAttributes} dangerouslySetInnerHTML={ { __html: metafieldContent } }></div>\n );\n}\n\nexport interface OkendoWidgetClientProps {\n dataAttributes: SKO;\n metafieldContent: string;\n}\n\ndeclare global {\n interface Window {\n okeWidgetApi: ReviewsWidgetPlus.WidgetWindowApi;\n }\n}\n"]}
1
+ {"version":3,"file":"OkendoWidget.client.js","sourceRoot":"","sources":["../../../src/components/OkendoWidget.client.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAIjD,MAAM,CAAC,MAAM,kBAAkB,GAAqD,CAAC,KAAK,EAAE,EAAE;IAC1F,MAAM,EAAE,cAAc,EAAE,gBAAgB,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC;IACxD,MAAM,eAAe,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAErD,MAAM,uBAAuB,GAAG,GAAG,EAAE;QACjC,IAAI,eAAe,CAAC,OAAO,EAAE;YACzB,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;SAC3D;IACL,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,MAAM,CAAC,YAAY,EAAE;YACrB,uBAAuB,EAAE,CAAC;SAC7B;aACI;YACD,MAAM,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;SACzE;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACH,6BAAK,GAAG,EAAE,eAAe,KAAM,cAAc,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAQ,CAC/G,CAAC;AACN,CAAC,CAAA","sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport type { SKO } from '@okendo/reviews-common';\nimport type { ReviewsWidgetPlus } from '@okendo/reviews-widget-plus/dist-utils/ReviewsWidgetPlus';\n\nexport const OkendoWidgetClient: React.FunctionComponent<OkendoWidgetClientProps> = (props) => {\n const { dataAttributes, metafieldContent = '' } = props;\n const widgetContainer = useRef<HTMLDivElement>(null);\n\n const initialiseReviewsWidget = () => {\n if (widgetContainer.current) {\n window.okeWidgetApi.initWidget(widgetContainer.current);\n }\n };\n\n useEffect(() => {\n if (window.okeWidgetApi) {\n initialiseReviewsWidget();\n }\n else {\n window.addEventListener('oke-script-loaded', initialiseReviewsWidget);\n }\n }, []);\n\n return (\n <div ref={widgetContainer} {...dataAttributes} dangerouslySetInnerHTML={{ __html: metafieldContent }}></div>\n );\n}\n\nexport interface OkendoWidgetClientProps {\n dataAttributes: SKO;\n metafieldContent?: string;\n}\n\ndeclare global {\n interface Window {\n okeWidgetApi: ReviewsWidgetPlus.WidgetWindowApi;\n }\n}\n"]}
@@ -1 +1,2 @@
1
1
  export * from './components';
2
+ export * from './shared';
@@ -1,2 +1,3 @@
1
1
  export * from './components';
2
+ export * from './shared';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC","sourcesContent":["export * from './components';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC","sourcesContent":["export * from './components';\nexport * from './shared';\n"]}
@@ -0,0 +1,3 @@
1
+ export declare function okendoError(message: string): string;
2
+ export declare function widgetConfigurationError(widgetName: string, message: string): string;
3
+ export declare function widgetMetafieldError(widgetName: string, metafieldName: string): string;
@@ -0,0 +1,10 @@
1
+ export function okendoError(message) {
2
+ return `Okendo: ${message}`;
3
+ }
4
+ export function widgetConfigurationError(widgetName, message) {
5
+ return okendoError(`${widgetName} error: ${message}`);
6
+ }
7
+ export function widgetMetafieldError(widgetName, metafieldName) {
8
+ return okendoError(`${widgetName} error: Failed to retrieve metafield '${metafieldName}'.`);
9
+ }
10
+ //# sourceMappingURL=errorUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorUtils.js","sourceRoot":"","sources":["../../../src/shared/errorUtils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,OAAe;IACvC,OAAO,WAAW,OAAO,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,UAAkB,EAAE,OAAe;IACxE,OAAO,WAAW,CAAC,GAAG,UAAU,WAAW,OAAO,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,aAAqB;IAC1E,OAAO,WAAW,CAAC,GAAG,UAAU,yCAAyC,aAAa,IAAI,CAAC,CAAC;AAChG,CAAC","sourcesContent":["export function okendoError(message: string): string {\n return `Okendo: ${message}`;\n}\n\nexport function widgetConfigurationError(widgetName: string, message: string): string {\n return okendoError(`${widgetName} error: ${message}`);\n}\n\nexport function widgetMetafieldError(widgetName: string, metafieldName: string): string {\n return okendoError(`${widgetName} error: Failed to retrieve metafield '${metafieldName}'.`);\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export * from './errorUtils';
2
+ export * from './productUtils';
3
+ export * from './requestUtils';
@@ -0,0 +1,4 @@
1
+ export * from './errorUtils';
2
+ export * from './productUtils';
3
+ export * from './requestUtils';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC","sourcesContent":["export * from './errorUtils';\nexport * from './productUtils';\nexport * from './requestUtils';\n"]}
@@ -0,0 +1,12 @@
1
+ import { SKO } from '@okendo/reviews-common';
2
+ import { ServerComponentRequest } from '@shopify/hydrogen/dist/esnext/framework/Hydration/ServerComponentRequest.server';
3
+ export declare function setInOkendoRequestContext(request: ServerComponentRequest, key: keyof OkendoRequestContextKeys, value: RequestContextSafeType | RequestContextSafeType[]): void;
4
+ export declare function useOkendoRequestContext(): OkendoRequestContext;
5
+ interface OkendoRequestContextKeys {
6
+ setupFailed: boolean;
7
+ }
8
+ export interface OkendoRequestContext extends OkendoRequestContextKeysWithSKO {
9
+ }
10
+ declare type OkendoRequestContextKeysWithSKO = OkendoRequestContextKeys & SKO;
11
+ declare type RequestContextSafeType = string | number | boolean;
12
+ export {};
@@ -0,0 +1,11 @@
1
+ import { useServerRequest } from '@shopify/hydrogen/dist/esnext/foundation/ServerRequestProvider';
2
+ export function setInOkendoRequestContext(request, key, value) {
3
+ const okendoRequestContext = request.ctx.okendoRequestContext || {};
4
+ okendoRequestContext[key] = value;
5
+ request.ctx.okendoRequestContext = okendoRequestContext;
6
+ }
7
+ export function useOkendoRequestContext() {
8
+ const { ctx: { okendoRequestContext } } = useServerRequest();
9
+ return okendoRequestContext || {};
10
+ }
11
+ //# sourceMappingURL=requestUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestUtils.js","sourceRoot":"","sources":["../../../src/shared/requestUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gEAAgE,CAAC;AAGlG,MAAM,UAAU,yBAAyB,CAAC,OAA+B,EAAE,GAAmC,EAAE,KAAwD;IACpK,MAAM,oBAAoB,GAAyB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC;IAC1F,oBAAoB,CAAC,GAAG,CAAC,GAAG,KAAY,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,uBAAuB;IACnC,MAAM,EAAE,GAAG,EAAE,EAAE,oBAAoB,EAAE,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAC7D,OAAO,oBAAoB,IAAI,EAAE,CAAC;AACtC,CAAC","sourcesContent":["import { SKO } from '@okendo/reviews-common';\nimport { useServerRequest } from '@shopify/hydrogen/dist/esnext/foundation/ServerRequestProvider';\nimport { ServerComponentRequest } from '@shopify/hydrogen/dist/esnext/framework/Hydration/ServerComponentRequest.server';\n\nexport function setInOkendoRequestContext(request: ServerComponentRequest, key: keyof OkendoRequestContextKeys, value: RequestContextSafeType | RequestContextSafeType[]): void {\n const okendoRequestContext: OkendoRequestContext = request.ctx.okendoRequestContext || {};\n okendoRequestContext[key] = value as any;\n request.ctx.okendoRequestContext = okendoRequestContext;\n}\n\nexport function useOkendoRequestContext(): OkendoRequestContext {\n const { ctx: { okendoRequestContext } } = useServerRequest();\n return okendoRequestContext || {};\n}\n\ninterface OkendoRequestContextKeys {\n setupFailed: boolean;\n}\n\nexport interface OkendoRequestContext extends OkendoRequestContextKeysWithSKO { }\n\ntype OkendoRequestContextKeysWithSKO = OkendoRequestContextKeys & SKO;\n\ntype RequestContextSafeType = string | number | boolean;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":";;AACA,qEAAkE;AAElE,kBAAe,GAAG,EAAE;IAChB,OAAO;QACH,IAAA,+CAAsB,GAAE;KACf,CAAC;AAClB,CAAC,CAAC","sourcesContent":["import type { Plugin } from 'vite';\nimport { extendViteOptimizeDeps } from './extendViteOptimizeDeps';\n\nexport default () => {\n return [\n extendViteOptimizeDeps()\n ] as Plugin[];\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":";;AAEA,qEAAkE;AAElE,kBAAe,GAAG,EAAE;IAChB,OAAO;QACH,IAAA,+CAAsB,GAAE;KACf,CAAC;AAClB,CAAC,CAAC","sourcesContent":["import type { Plugin } from 'vite';\n\nimport { extendViteOptimizeDeps } from './extendViteOptimizeDeps';\n\nexport default () => {\n return [\n extendViteOptimizeDeps()\n ] as Plugin[];\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okendo/shopify-hydrogen",
3
- "version": "0.0.2",
3
+ "version": "0.0.5",
4
4
  "description": "A component library containing Okendo Reviews React components.",
5
5
  "main": "dist/esnext/index.js",
6
6
  "files": [