@okendo/shopify-hydrogen 1.2.1 → 1.2.3

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.
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { FC } from 'react';
2
2
  import type { OkendoClientStarRatingProps } from '../models/starRating';
3
- export declare const OkendoClientStarRating: React.FunctionComponent<OkendoClientStarRatingProps>;
3
+ export declare const OkendoClientStarRating: FC<OkendoClientStarRatingProps>;
4
4
  export default OkendoClientStarRating;
@@ -2,15 +2,15 @@ import React from 'react';
2
2
  import { OkendoWidgetClient } from './OkendoWidget.client';
3
3
  import { getOkendoProductId } from '../shared/productUtils';
4
4
  import { widgetConfigurationError, widgetMetafieldError } from '../shared/errorUtils';
5
- export const OkendoClientStarRating = (props) => {
6
- const { productId, okendoStarRatingSnippet } = props;
5
+ import { logger } from '../shared/logger';
6
+ export const OkendoClientStarRating = ({ productId, okendoStarRatingSnippet }) => {
7
7
  const okendoProductId = getOkendoProductId(productId);
8
8
  if (!okendoProductId) {
9
- console.error(widgetConfigurationError('OkendoClientStarRating', 'productId was not provided'));
9
+ logger.error(widgetConfigurationError('OkendoClientStarRating', 'productId was not provided'));
10
10
  return null;
11
11
  }
12
12
  if (!okendoStarRatingSnippet?.value) {
13
- console.warn(widgetMetafieldError('OkendoStarRating', 'StarRatingSnippet'));
13
+ logger.warn(widgetMetafieldError('OkendoStarRating', 'StarRatingSnippet'));
14
14
  }
15
15
  const dataAttributes = {
16
16
  'data-oke-star-rating': '',
@@ -1,7 +1,7 @@
1
- import React from 'react';
1
+ import { FC } from 'react';
2
2
  import type { ReviewsWidgetPlus } from '@okendo/reviews-widget-plus/dist-utils/ReviewsWidgetPlus';
3
3
  import type { SKO } from '../shared/sharedTypes';
4
- export declare const OkendoWidgetClient: React.FunctionComponent<OkendoWidgetClientProps>;
4
+ export declare const OkendoWidgetClient: FC<OkendoWidgetClientProps>;
5
5
  export interface OkendoWidgetClientProps {
6
6
  dataAttributes: SKO;
7
7
  metafieldContent?: string;
@@ -1,22 +1,23 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
- export const OkendoWidgetClient = (props) => {
3
- const { dataAttributes, metafieldContent = '' } = props;
2
+ export const OkendoWidgetClient = ({ dataAttributes, metafieldContent = '' }) => {
4
3
  const widgetContainer = useRef(null);
5
- const initializeReviewsWidget = () => {
4
+ const initializeWidget = () => {
6
5
  if (widgetContainer.current) {
7
- window.okeWidgetApi.initWidget(widgetContainer.current);
6
+ // `forceReinitialisation` must be true because we can expect `data-oke-rendered`
7
+ // to be present on already-initialised widget snippets.
8
+ window.okeWidgetApi.initWidget(widgetContainer.current, true);
8
9
  }
9
10
  };
10
11
  useEffect(() => {
11
12
  if (window.okeWidgetApi && widgetContainer.current) {
12
- initializeReviewsWidget();
13
+ initializeWidget();
13
14
  }
14
15
  else {
15
- document.addEventListener('oke-script-loaded', initializeReviewsWidget);
16
+ document.addEventListener('oke-script-loaded', initializeWidget);
16
17
  }
17
18
  return () => {
18
- document.removeEventListener('oke-script-loaded', initializeReviewsWidget);
19
+ document.removeEventListener('oke-script-loaded', initializeWidget);
19
20
  };
20
- }, []);
21
+ }, [dataAttributes]);
21
22
  return (React.createElement("div", { ref: widgetContainer, ...dataAttributes, dangerouslySetInnerHTML: { __html: metafieldContent } }));
22
23
  };
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
- export declare const OkendoProvider: React.FunctionComponent<OkendoProviderProps>;
1
+ import React, { FC } from 'react';
2
+ export declare const OkendoProvider: FC<OkendoProviderProps>;
3
3
  interface OkendoProviderProps {
4
4
  apiDomain?: string;
5
5
  cdnDomain?: string;
@@ -2,17 +2,18 @@ import React from 'react';
2
2
  import { fetchSync, useShopQuery, gql, CacheShort } from '@shopify/hydrogen';
3
3
  import { Head } from '@shopify/hydrogen';
4
4
  import { okendoError } from '../shared/errorUtils';
5
- import { setInOkendoRequestContext } from '../shared/server/requestUtils';
5
+ import { useOkendoRequestContext } from '../shared/server/requestUtils';
6
+ import { logger } from '../shared/logger';
6
7
  const kDefaultOkendoApiDomain = 'api.okendo.io/v1';
7
8
  const kDefaultOkendoCdnDomain = 'cdn-static.okendo.io';
8
- export const OkendoProvider = (props) => {
9
- const { apiDomain, cdnDomain, children, productUrlFormatOverride, subscriberId } = props;
9
+ export const OkendoProvider = ({ apiDomain, cdnDomain, children, productUrlFormatOverride, subscriberId }) => {
10
+ const okendoRequestContext = useOkendoRequestContext();
10
11
  // Download subscriber widget plus settings.
11
12
  const url = `https://${apiDomain ?? kDefaultOkendoApiDomain}/stores/${subscriberId}/widget_plus_settings`;
12
13
  const settingsResponse = fetchSync(url, { preload: true });
13
14
  if (!settingsResponse.ok) {
14
- console.error(okendoError('Failed to retrieve subscriber settings. Please check your environment variables.'));
15
- setInOkendoRequestContext('setupFailed', true);
15
+ logger.error(okendoError('Failed to retrieve subscriber settings. Please check your environment variables.'));
16
+ okendoRequestContext.setupFailed = true;
16
17
  return null;
17
18
  }
18
19
  const { cssVariables, customCss, reviewsHeaderConfig, starSymbols } = settingsResponse.json();
@@ -24,11 +25,14 @@ export const OkendoProvider = (props) => {
24
25
  preload: true
25
26
  });
26
27
  if (!initScriptResponse.ok) {
27
- console.error(okendoError('Failed to retrieve widget initialization script.'));
28
- setInOkendoRequestContext('setupFailed', true);
28
+ logger.error(okendoError('Failed to retrieve widget initialization script.'));
29
+ okendoRequestContext.setupFailed = true;
29
30
  return null;
30
31
  }
31
32
  const initScriptContents = initScriptResponse.text();
33
+ return React.createElement(OkendoProviderContent, { productUrlFormatOverride: productUrlFormatOverride, subscriberId: subscriberId, reviewsHeaderConfig: reviewsHeaderConfig, starSymbols: starSymbols, cssVariablesNormalized: cssVariablesNormalized, customCssNormalized: customCssNormalized, initScriptContents: initScriptContents }, children);
34
+ };
35
+ const OkendoProviderContent = ({ children, productUrlFormatOverride, subscriberId, reviewsHeaderConfig, starSymbols, cssVariablesNormalized, customCssNormalized, initScriptContents, }) => {
32
36
  // Set up product URL formatter.
33
37
  const productUrlFormatter = typeof productUrlFormatOverride === 'function'
34
38
  ? productUrlFormatOverride
@@ -36,22 +40,22 @@ export const OkendoProvider = (props) => {
36
40
  ? `/products/${product.productHandle}/${product.variantId ? '?variantId=' + product.variantId : ''}`
37
41
  : undefined;
38
42
  // Get pre-rendered style settings.
39
- const query = gql `
40
- query metafields {
41
- shop {
42
- widgetPreRenderStyleTags: metafield(namespace: "okendo", key: "WidgetPreRenderStyleTags") {
43
- value
44
- }
45
- }
46
- }
47
- `;
43
+ const query = gql `
44
+ query metafields {
45
+ shop {
46
+ widgetPreRenderStyleTags: metafield(namespace: "okendo", key: "WidgetPreRenderStyleTags") {
47
+ value
48
+ }
49
+ }
50
+ }
51
+ `;
48
52
  const { data: { shop: { widgetPreRenderStyleTags } } } = useShopQuery({
49
- query: query,
53
+ query,
50
54
  preload: true
51
55
  });
52
56
  const preRenderStyleTags = widgetPreRenderStyleTags?.value ?? '';
53
57
  if (!preRenderStyleTags) {
54
- console.warn(okendoError('Failed to retrieve pre-rendered widget style settings.'));
58
+ logger.warn(okendoError('Failed to retrieve pre-rendered widget style settings.'));
55
59
  }
56
60
  return (React.createElement(React.Fragment, null,
57
61
  React.createElement(Head, null,
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
- export declare const OkendoReviewsWidget: React.FunctionComponent<OkendoReviewsWidgetProps>;
1
+ import { FC } from 'react';
2
+ export declare const OkendoReviewsWidget: FC<OkendoReviewsWidgetProps>;
3
3
  interface OkendoReviewsWidgetProps {
4
4
  productId?: string;
5
5
  }
@@ -4,43 +4,46 @@ import { OkendoWidgetClient } from '../client-components/OkendoWidget.client';
4
4
  import { widgetMetafieldError } from '../shared/errorUtils';
5
5
  import { getOkendoProductId } from '../shared/productUtils';
6
6
  import { useOkendoRequestContext } from '../shared/server/requestUtils';
7
+ import { logger } from '../shared/logger';
7
8
  export const OkendoReviewsWidget = (props) => {
8
9
  const { setupFailed } = useOkendoRequestContext();
9
10
  if (setupFailed) {
10
11
  return null;
11
12
  }
12
- const { productId } = props;
13
+ return React.createElement(OkendoReviewsWidgetContent, { ...props });
14
+ };
15
+ const OkendoReviewsWidgetContent = ({ productId }) => {
13
16
  const productQuery = productId
14
- ? `
15
- product(id: $productId) {
16
- reviewsWidgetSnippet: metafield(namespace: "okendo", key: "ReviewsWidgetSnippet") {
17
- value
18
- }
19
- }
17
+ ? `
18
+ product(id: $productId) {
19
+ reviewsWidgetSnippet: metafield(namespace: "okendo", key: "ReviewsWidgetSnippet") {
20
+ value
21
+ }
22
+ }
20
23
  `
21
24
  : '';
22
- const query = gql `
23
- query metafields${productId ? '($productId: ID!)' : ''} {
24
- ${productQuery}
25
- shop {
26
- widgetPreRenderBodyStyleTags: metafield(namespace: "okendo", key: "WidgetPreRenderBodyStyleTags") {
27
- value
28
- }
29
- }
30
- }
25
+ const query = gql `
26
+ query metafields${productId ? '($productId: ID!)' : ''} {
27
+ ${productQuery}
28
+ shop {
29
+ widgetPreRenderBodyStyleTags: metafield(namespace: "okendo", key: "WidgetPreRenderBodyStyleTags") {
30
+ value
31
+ }
32
+ }
33
+ }
31
34
  `;
32
35
  const { data: { product, shop } } = useShopQuery({
33
- query: query,
36
+ query,
34
37
  preload: true,
35
38
  variables: {
36
39
  productId
37
40
  }
38
41
  });
39
42
  if (productId && !product?.reviewsWidgetSnippet?.value) {
40
- console.warn(widgetMetafieldError('OkendoReviewsWidget', 'ReviewsWidgetSnippet'));
43
+ logger.warn(widgetMetafieldError('OkendoReviewsWidget', 'ReviewsWidgetSnippet'));
41
44
  }
42
45
  if (!shop?.widgetPreRenderBodyStyleTags?.value) {
43
- console.warn(widgetMetafieldError('OkendoReviewsWidget', 'WidgetPreRenderBodyStyleTags'));
46
+ logger.warn(widgetMetafieldError('OkendoReviewsWidget', 'WidgetPreRenderBodyStyleTags'));
44
47
  }
45
48
  const dataAttributes = {
46
49
  'data-oke-widget': ''
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { FC } from 'react';
2
2
  import type { OkendoStarRatingProps } from '../models/starRating';
3
- export declare const OkendoStarRating: React.FunctionComponent<OkendoStarRatingProps>;
3
+ export declare const OkendoStarRating: FC<OkendoStarRatingProps>;
4
4
  export default OkendoStarRating;
@@ -4,35 +4,38 @@ import { OkendoWidgetClient } from '../client-components/OkendoWidget.client';
4
4
  import { widgetConfigurationError, widgetMetafieldError } from '../shared/errorUtils';
5
5
  import { getOkendoProductId } from '../shared/productUtils';
6
6
  import { useOkendoRequestContext } from '../shared/server/requestUtils';
7
+ import { logger } from '../shared/logger';
7
8
  export const OkendoStarRating = (props) => {
8
9
  const { setupFailed } = useOkendoRequestContext();
9
10
  if (setupFailed) {
10
11
  return null;
11
12
  }
12
- const { productId } = props;
13
- const okendoProductId = getOkendoProductId(productId);
13
+ const okendoProductId = getOkendoProductId(props.productId);
14
14
  if (!okendoProductId) {
15
- console.error(widgetConfigurationError('OkendoStarRating', 'productId was not provided'));
15
+ logger.error(widgetConfigurationError('OkendoStarRating', 'productId was not provided'));
16
16
  return null;
17
17
  }
18
- const query = gql `
19
- query metafields($productId: ID!) {
20
- product(id: $productId) {
21
- starRatingSnippet: metafield(namespace: "okendo", key: "StarRatingSnippet") {
22
- value
23
- }
24
- }
25
- }
18
+ return React.createElement(OkendoStarRatingContent, { ...props, okendoProductId: okendoProductId });
19
+ };
20
+ const OkendoStarRatingContent = ({ productId, okendoProductId }) => {
21
+ const query = gql `
22
+ query metafields($productId: ID!) {
23
+ product(id: $productId) {
24
+ starRatingSnippet: metafield(namespace: "okendo", key: "StarRatingSnippet") {
25
+ value
26
+ }
27
+ }
28
+ }
26
29
  `;
27
30
  const { data: { product: { starRatingSnippet } } } = useShopQuery({
28
- query: query,
31
+ query,
29
32
  preload: true,
30
33
  variables: {
31
34
  productId
32
35
  }
33
36
  });
34
37
  if (!starRatingSnippet?.value) {
35
- console.warn(widgetMetafieldError('OkendoStarRating', 'StarRatingSnippet'));
38
+ logger.warn(widgetMetafieldError('OkendoStarRating', 'StarRatingSnippet'));
36
39
  }
37
40
  const dataAttributes = {
38
41
  'data-oke-star-rating': '',
@@ -1,11 +1,11 @@
1
1
  import { gql } from '@shopify/hydrogen';
2
- export const OKENDO_PRODUCT_STAR_RATING_FRAGMENT = gql `
3
- fragment OkendoStarRatingSnippet on Product {
4
- okendoStarRatingSnippet: metafield(
5
- namespace: "okendo"
6
- key: "StarRatingSnippet"
7
- ) {
8
- value
9
- }
10
- }
2
+ export const OKENDO_PRODUCT_STAR_RATING_FRAGMENT = gql `
3
+ fragment OkendoStarRatingSnippet on Product {
4
+ okendoStarRatingSnippet: metafield(
5
+ namespace: "okendo"
6
+ key: "StarRatingSnippet"
7
+ ) {
8
+ value
9
+ }
10
+ }
11
11
  `;
@@ -0,0 +1,14 @@
1
+ export declare const logger: {
2
+ log: {
3
+ (...data: any[]): void;
4
+ (message?: any, ...optionalParams: any[]): void;
5
+ };
6
+ warn: {
7
+ (...data: any[]): void;
8
+ (message?: any, ...optionalParams: any[]): void;
9
+ };
10
+ error: {
11
+ (...data: any[]): void;
12
+ (message?: any, ...optionalParams: any[]): void;
13
+ };
14
+ };
@@ -0,0 +1,7 @@
1
+ const isProduction = process.env.NODE_ENV === 'production';
2
+ const noop = () => undefined;
3
+ export const logger = {
4
+ log: isProduction ? noop : console.info,
5
+ warn: isProduction ? noop : console.warn,
6
+ error: console.error
7
+ };
@@ -1,11 +1,7 @@
1
- import type { SKO } from '../sharedTypes';
2
- export declare function setInOkendoRequestContext(key: keyof OkendoRequestContextKeys, value: RequestContextSafeType | RequestContextSafeType[]): void;
3
1
  export declare function useOkendoRequestContext(): OkendoRequestContext;
4
- interface OkendoRequestContextKeys {
2
+ declare type RequestContextSafeType = string | number | boolean;
3
+ declare type RequestContext = Record<string, RequestContextSafeType>;
4
+ export interface OkendoRequestContext extends RequestContext {
5
5
  setupFailed: boolean;
6
6
  }
7
- export interface OkendoRequestContext extends OkendoRequestContextKeysWithSKO {
8
- }
9
- declare type OkendoRequestContextKeysWithSKO = OkendoRequestContextKeys & SKO;
10
- declare type RequestContextSafeType = string | number | boolean;
11
7
  export {};
@@ -1,8 +1,4 @@
1
1
  import { useRequestContext } from '@shopify/hydrogen';
2
- export function setInOkendoRequestContext(key, value) {
3
- const okendoRequestContext = useOkendoRequestContext();
4
- okendoRequestContext[key] = value;
5
- }
6
2
  export function useOkendoRequestContext() {
7
3
  return useRequestContext('okendo');
8
4
  }
package/package.json CHANGED
@@ -1,58 +1,65 @@
1
- {
2
- "name": "@okendo/shopify-hydrogen",
3
- "version": "1.2.1",
4
- "description": "A component library containing Okendo Reviews React components.",
5
- "main": "dist/esnext/index.js",
6
- "engines": {
7
- "node": ">=14"
8
- },
9
- "exports": {
10
- ".": "./dist/esnext/index.js",
11
- "./plugin": {
12
- "import": "./dist/esnext/framework/plugins/plugin.js",
13
- "require": "./dist/node/framework/plugins/plugin.js"
14
- },
15
- "./client": {
16
- "import": {
17
- "types": "./dist/esnext/client.d.ts",
18
- "default": "./dist/esnext/client.js"
19
- },
20
- "node": {
21
- "types": "./dist/esnext/client.d.ts",
22
- "default": "./dist/esnext/client.js"
23
- }
24
- },
25
- "./plugin.cjs": "./plugin.cjs",
26
- "./package.json": "./package.json",
27
- "./*": "./dist/esnext/*.js"
28
- },
29
- "types": "dist/esnext/index.d.ts",
30
- "files": [
31
- "dist",
32
- "plugin.cjs"
33
- ],
34
- "scripts": {
35
- "build": "rimraf dist/ && npm run build:esm && npm run build:plugin:cjs",
36
- "build:plugin:cjs": "tsc --p tsconfig.plugin.cjs.json",
37
- "build:esm": "tsc --p tsconfig.esm.json",
38
- "prepublishOnly": "npm run build"
39
- },
40
- "author": "Okendo",
41
- "license": "SEE LICENSE IN LICENSE.txt",
42
- "devDependencies": {
43
- "@okendo/reviews-widget-plus": "^0.49.0",
44
- "@okendo/tsconfig": "0.0.2",
45
- "@shopify/hydrogen": "^1.2.0",
46
- "@types/node": "^17.0.35",
47
- "@types/react": "^18.0.14",
48
- "@types/react-dom": "^18.0.5",
49
- "dotenv": "^16.0.1",
50
- "ncp": "^2.0.0",
51
- "rimraf": "^3.0.2",
52
- "typescript": "^4.7.4",
53
- "vite": "^2.9.0"
54
- },
55
- "peerDependencies": {
56
- "@shopify/hydrogen": "1.2.x"
57
- }
58
- }
1
+ {
2
+ "name": "@okendo/shopify-hydrogen",
3
+ "version": "1.2.3",
4
+ "description": "A component library containing Okendo Reviews React components.",
5
+ "main": "dist/esnext/index.js",
6
+ "engines": {
7
+ "node": ">=14"
8
+ },
9
+ "exports": {
10
+ ".": "./dist/esnext/index.js",
11
+ "./plugin": {
12
+ "import": "./dist/esnext/framework/plugins/plugin.js",
13
+ "require": "./dist/node/framework/plugins/plugin.js"
14
+ },
15
+ "./client": {
16
+ "import": {
17
+ "types": "./dist/esnext/client.d.ts",
18
+ "default": "./dist/esnext/client.js"
19
+ },
20
+ "node": {
21
+ "types": "./dist/esnext/client.d.ts",
22
+ "default": "./dist/esnext/client.js"
23
+ }
24
+ },
25
+ "./plugin.cjs": "./plugin.cjs",
26
+ "./package.json": "./package.json",
27
+ "./*": "./dist/esnext/*.js"
28
+ },
29
+ "types": "dist/esnext/index.d.ts",
30
+ "files": [
31
+ "dist",
32
+ "plugin.cjs"
33
+ ],
34
+ "scripts": {
35
+ "build": "rimraf dist/ && npm run build:esm && npm run build:plugin:cjs",
36
+ "build:plugin:cjs": "tsc --p tsconfig.plugin.cjs.json",
37
+ "build:esm": "tsc --p tsconfig.esm.json",
38
+ "prepublishOnly": "npm run build",
39
+ "eslint": "eslint 'src/**/*.{ts,tsx}'",
40
+ "eslint-fix": "npm run eslint -- --fix"
41
+ },
42
+ "author": "Okendo",
43
+ "license": "SEE LICENSE IN LICENSE.txt",
44
+ "devDependencies": {
45
+ "@okendo/reviews-widget-plus": "^0.53.1",
46
+ "@okendo/tsconfig": "0.0.2",
47
+ "@shopify/hydrogen": "^1.2.0",
48
+ "@types/node": "^17.0.35",
49
+ "@types/react": "^18.0.14",
50
+ "@types/react-dom": "^18.0.5",
51
+ "@typescript-eslint/eslint-plugin": "^5.38.1",
52
+ "@typescript-eslint/parser": "^5.38.1",
53
+ "dotenv": "^16.0.1",
54
+ "eslint": "^8.24.0",
55
+ "eslint-plugin-react": "^7.31.8",
56
+ "eslint-plugin-react-hooks": "^4.6.0",
57
+ "ncp": "^2.0.0",
58
+ "rimraf": "^3.0.2",
59
+ "typescript": "^4.7.4",
60
+ "vite": "^2.9.0"
61
+ },
62
+ "peerDependencies": {
63
+ "@shopify/hydrogen": "1.2.x"
64
+ }
65
+ }
package/plugin.cjs CHANGED
@@ -1 +1 @@
1
- module.exports = require('./dist/node/framework/plugin');
1
+ module.exports = require('./dist/node/framework/plugin');