@shopify/hydrogen 0.8.1 → 0.8.2

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.
Files changed (36) hide show
  1. package/dist/esnext/components/ShopPayButton/ShopPayButton.client.js +1 -1
  2. package/dist/esnext/entry-server.js +9 -5
  3. package/dist/esnext/foundation/RenderCacheProvider/hook.js +1 -1
  4. package/dist/esnext/foundation/RenderCacheProvider/types.d.ts +9 -2
  5. package/dist/esnext/foundation/Router/DefaultRoutes.d.ts +1 -1
  6. package/dist/esnext/foundation/useQuery/hooks.js +1 -1
  7. package/dist/esnext/handle-event.js +0 -6
  8. package/dist/esnext/hooks/useShopQuery/hooks.js +20 -2
  9. package/dist/esnext/index.d.ts +2 -1
  10. package/dist/esnext/index.js +2 -1
  11. package/dist/esnext/types.d.ts +0 -4
  12. package/dist/esnext/utilities/fetch.js +3 -6
  13. package/dist/esnext/utilities/index.d.ts +0 -1
  14. package/dist/esnext/utilities/index.js +0 -1
  15. package/dist/esnext/utilities/log/log.d.ts +1 -4
  16. package/dist/esnext/utilities/log/log.js +20 -21
  17. package/dist/esnext/version.d.ts +1 -1
  18. package/dist/esnext/version.js +1 -1
  19. package/dist/node/handle-event.js +0 -6
  20. package/dist/node/types.d.ts +0 -4
  21. package/dist/node/utilities/fetch.js +3 -6
  22. package/dist/node/utilities/index.d.ts +0 -1
  23. package/dist/node/utilities/index.js +1 -7
  24. package/dist/node/version.d.ts +1 -1
  25. package/dist/node/version.js +1 -1
  26. package/dist/worker/handle-event.js +0 -6
  27. package/dist/worker/types.d.ts +0 -4
  28. package/package.json +2 -2
  29. package/dist/node/utilities/log/index.d.ts +0 -1
  30. package/dist/node/utilities/log/index.js +0 -9
  31. package/dist/node/utilities/log/log.d.ts +0 -20
  32. package/dist/node/utilities/log/log.js +0 -78
  33. package/dist/worker/utilities/log/index.d.ts +0 -1
  34. package/dist/worker/utilities/log/index.js +0 -1
  35. package/dist/worker/utilities/log/log.d.ts +0 -20
  36. package/dist/worker/utilities/log/log.js +0 -71
@@ -11,7 +11,7 @@ export function ShopPayButton({ variantIds, className }) {
11
11
  const { storeDomain } = useShop();
12
12
  useEffect(() => {
13
13
  const ids = variantIds.reduce((accumulator, gid) => {
14
- const id = atob(gid).split('/').pop();
14
+ const id = gid.split('/').pop();
15
15
  if (id) {
16
16
  accumulator.push(id);
17
17
  }
@@ -5,7 +5,7 @@ renderToPipeableStream, // Only available in Node context
5
5
  // @ts-ignore
6
6
  renderToReadableStream, // Only available in Browser/Worker context
7
7
  } from 'react-dom/server';
8
- import { logServerResponse } from './utilities/log/log';
8
+ import { logServerResponse, getLoggerFromContext, } from './utilities/log/log';
9
9
  import { renderToString } from 'react-dom/server';
10
10
  import { getErrorMarkup } from './utilities/error';
11
11
  import ssrPrepass from 'react-ssr-prepass';
@@ -36,8 +36,9 @@ const renderHydrogen = (App, hook) => {
36
36
  * and returning any initial state that needs to be hydrated into the client version of the app.
37
37
  * NOTE: This is currently only used for SEO bots or Worker runtime (where Stream is not yet supported).
38
38
  */
39
- const render = async function (url, { context, request, isReactHydrationRequest, dev, log }) {
40
- var _a, _b;
39
+ const render = async function (url, { context, request, isReactHydrationRequest, dev }) {
40
+ var _a, _b, _c, _d, _f;
41
+ const log = getLoggerFromContext(request);
41
42
  const state = isReactHydrationRequest
42
43
  ? JSON.parse((_b = (_a = url.searchParams) === null || _a === void 0 ? void 0 : _a.get('state')) !== null && _b !== void 0 ? _b : '{}')
43
44
  : { pathname: url.pathname, search: url.search };
@@ -50,6 +51,7 @@ const renderHydrogen = (App, hook) => {
50
51
  log,
51
52
  });
52
53
  const body = await renderApp(ReactApp, state, log, isReactHydrationRequest);
54
+ logServerResponse('ssr', log, request, (_f = (_d = (_c = componentResponse.customStatus) === null || _c === void 0 ? void 0 : _c.code) !== null && _d !== void 0 ? _d : componentResponse.status) !== null && _f !== void 0 ? _f : 200);
53
55
  if (componentResponse.customBody) {
54
56
  return { body: await componentResponse.customBody, url, componentResponse };
55
57
  }
@@ -66,7 +68,8 @@ const renderHydrogen = (App, hook) => {
66
68
  * Stream a response to the client. NOTE: This omits custom `<head>`
67
69
  * information, so this method should not be used by crawlers.
68
70
  */
69
- const stream = function (url, { context, request, response, template, dev, log }) {
71
+ const stream = function (url, { context, request, response, template, dev }) {
72
+ const log = getLoggerFromContext(request);
70
73
  const state = { pathname: url.pathname, search: url.search };
71
74
  const { ReactApp, componentResponse } = buildReactApp({
72
75
  App,
@@ -142,7 +145,8 @@ const renderHydrogen = (App, hook) => {
142
145
  /**
143
146
  * Stream a hydration response to the client.
144
147
  */
145
- const hydrate = function (url, { context, request, response, dev, log }) {
148
+ const hydrate = function (url, { context, request, response, dev }) {
149
+ const log = getLoggerFromContext(request);
146
150
  const state = JSON.parse(url.searchParams.get('state') || '{}');
147
151
  const { ReactApp, componentResponse } = buildReactApp({
148
152
  App,
@@ -25,7 +25,7 @@ export function useRenderCacheData(key, fetcher) {
25
25
  if (data !== undefined)
26
26
  return data;
27
27
  if (!promise) {
28
- promise = fetcher().then((r) => (data = { data: r }), (e) => (data = { data: e }));
28
+ promise = fetcher().then((r) => (data = { data: r }), (e) => (data = { error: e }));
29
29
  }
30
30
  throw promise;
31
31
  };
@@ -6,6 +6,13 @@ export declare type RenderCacheProviderProps = {
6
6
  cache: RenderCache;
7
7
  children?: React.ReactNode;
8
8
  };
9
- export interface RenderCacheResult<T> {
9
+ export declare type RenderCacheResult<T> = RenderCacheResultSuccess<T> | RenderCacheResultError;
10
+ declare type RenderCacheResultSuccess<T> = {
10
11
  data: T;
11
- }
12
+ error?: never;
13
+ };
14
+ declare type RenderCacheResultError = {
15
+ data?: never;
16
+ error: Response;
17
+ };
18
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
- import { Logger } from '../../utilities/log/log';
2
+ import type { Logger } from '../../utilities/log/log';
3
3
  export declare type ImportGlobEagerOutput = Record<string, Record<'default', any>>;
4
4
  /**
5
5
  * Build a set of default Hydrogen routes based on the output provided by Vite's
@@ -1,4 +1,4 @@
1
- import { log } from '../../utilities';
1
+ import { log } from '../../utilities/log';
2
2
  import { deleteItemFromCache, getItemFromCache, isStale, setItemInCache, } from '../../framework/cache';
3
3
  import { runDelayedFunction } from '../../framework/runtime';
4
4
  import { useRenderCacheData } from '../RenderCacheProvider/hook';
@@ -1,7 +1,6 @@
1
1
  import { getCacheControlHeader } from './framework/cache';
2
2
  import { setContext, setCache } from './framework/runtime';
3
3
  import { setConfig } from './framework/config';
4
- import { getLoggerFromContext, logServerResponse } from './utilities/log';
5
4
  export default async function handleEvent(event, { request, entrypoint, indexTemplate, assetHandler, streamableResponse, dev, cache, context, }) {
6
5
  var _a, _b, _c, _d, _e;
7
6
  const url = new URL(request.url);
@@ -30,7 +29,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
30
29
  }
31
30
  const userAgent = request.headers.get('user-agent');
32
31
  const isStreamable = streamableResponse && !isBotUA(url, userAgent);
33
- const logger = getLoggerFromContext(request);
34
32
  /**
35
33
  * Stream back real-user responses, but for bots/etc,
36
34
  * use `render` instead. This is because we need to inject <head>
@@ -43,7 +41,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
43
41
  request,
44
42
  response: streamableResponse,
45
43
  dev,
46
- log: logger,
47
44
  });
48
45
  }
49
46
  else {
@@ -53,7 +50,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
53
50
  response: streamableResponse,
54
51
  template,
55
52
  dev,
56
- log: logger,
57
53
  });
58
54
  }
59
55
  return;
@@ -63,7 +59,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
63
59
  context: {},
64
60
  isReactHydrationRequest,
65
61
  dev,
66
- log: logger,
67
62
  });
68
63
  const headers = componentResponse.headers;
69
64
  /**
@@ -100,7 +95,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
100
95
  headers,
101
96
  });
102
97
  }
103
- logServerResponse('ssr', logger, request, response.status);
104
98
  return response;
105
99
  }
106
100
  /**
@@ -1,5 +1,5 @@
1
1
  import { useShop } from '../../foundation/useShop';
2
- import { log } from '../../utilities';
2
+ import { log } from '../../utilities/log';
3
3
  import { useQuery } from '../../foundation/useQuery';
4
4
  import { isClient, fetchBuilder, graphqlRequestBody } from '../../utilities';
5
5
  import { getConfig } from '../../framework/config';
@@ -12,10 +12,28 @@ export function useShopQuery({ query, variables = {}, cache = {}, }) {
12
12
  }
13
13
  const body = query ? graphqlRequestBody(query, variables) : '';
14
14
  const { request, key } = createShopRequest(body);
15
- const { data } = useQuery(key, query
15
+ const { data, error: fetchError } = useQuery(key, query
16
16
  ? fetchBuilder(request)
17
17
  : // If no query, avoid calling SFAPI & return nothing
18
18
  async () => ({ data: undefined, errors: undefined }), { cache });
19
+ /**
20
+ * The fetch request itself failed, so we handle that differently than a GraphQL error
21
+ */
22
+ if (fetchError) {
23
+ const errorMessage = `Failed to fetch the Storefront API. ${
24
+ // 403s to the SF API (almost?) always mean that your Shopify credentials are bad/wrong
25
+ fetchError.status === 403
26
+ ? `You may have a bad value in 'shopify.config.js'`
27
+ : `${fetchError.statusText}`}`;
28
+ log.error(errorMessage);
29
+ if (getConfig().dev) {
30
+ throw new Error(errorMessage);
31
+ }
32
+ else {
33
+ // in non-dev environments, we probably don't want super-detailed error messages for the user
34
+ throw new Error(`The fetch attempt failed; there was an issue connecting to the data source.`);
35
+ }
36
+ }
19
37
  /**
20
38
  * GraphQL errors get printed to the console but ultimately
21
39
  * get returned to the consumer.
@@ -1,7 +1,8 @@
1
1
  export * from './foundation/';
2
2
  export * from './components/';
3
3
  export * from './hooks/';
4
- export { flattenConnection, fetchBuilder, graphqlRequestBody, decodeShopifyId, isClient, log, setLogger, getTime, Logger, } from './utilities';
4
+ export { flattenConnection, fetchBuilder, graphqlRequestBody, decodeShopifyId, isClient, getTime, } from './utilities';
5
+ export { log, setLogger, Logger } from './utilities/log';
5
6
  export { Helmet } from 'react-helmet-async';
6
7
  export { LocalizationProvider } from './components/LocalizationProvider/LocalizationProvider.server';
7
8
  export * from './hooks/useShopQuery';
@@ -1,7 +1,8 @@
1
1
  export * from './foundation/';
2
2
  export * from './components/';
3
3
  export * from './hooks/';
4
- export { flattenConnection, fetchBuilder, graphqlRequestBody, decodeShopifyId, isClient, log, setLogger, getTime, } from './utilities';
4
+ export { flattenConnection, fetchBuilder, graphqlRequestBody, decodeShopifyId, isClient, getTime, } from './utilities';
5
+ export { log, setLogger } from './utilities/log';
5
6
  export { Helmet } from 'react-helmet-async';
6
7
  // This is exported here because it contains a Server Component
7
8
  export { LocalizationProvider } from './components/LocalizationProvider/LocalizationProvider.server';
@@ -1,6 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  import { ServerResponse } from 'http';
3
- import type { Logger } from './utilities/log/log';
4
3
  import type { ServerComponentResponse } from './framework/Hydration/ServerComponentResponse.server';
5
4
  import type { ServerComponentRequest } from './framework/Hydration/ServerComponentRequest.server';
6
5
  import type { Metafield, Image, MediaContentType } from './graphql/types/types';
@@ -9,7 +8,6 @@ export declare type Renderer = (url: URL, options: {
9
8
  context?: Record<string, any>;
10
9
  isReactHydrationRequest?: boolean;
11
10
  dev?: boolean;
12
- log: Logger;
13
11
  }) => Promise<{
14
12
  body: string;
15
13
  componentResponse: ServerComponentResponse;
@@ -19,14 +17,12 @@ export declare type Streamer = (url: URL, options: {
19
17
  request: ServerComponentRequest;
20
18
  response: ServerResponse;
21
19
  template: string;
22
- log: Logger;
23
20
  dev?: boolean;
24
21
  }) => void;
25
22
  export declare type Hydrator = (url: URL, options: {
26
23
  context: any;
27
24
  request: ServerComponentRequest;
28
25
  response: ServerResponse;
29
- log: Logger;
30
26
  dev?: boolean;
31
27
  }) => void;
32
28
  export declare type EntryServerHandler = {
@@ -38,6 +38,9 @@ export function fetchBuilder(request) {
38
38
  headers,
39
39
  method: clonedRequest.method,
40
40
  });
41
+ if (!response.ok) {
42
+ throw response;
43
+ }
41
44
  const data = await response.json();
42
45
  return data;
43
46
  };
@@ -50,12 +53,6 @@ export function graphqlRequestBody(query, variables) {
50
53
  });
51
54
  }
52
55
  export function decodeShopifyId(id) {
53
- if (!id.startsWith('gid://')) {
54
- id =
55
- typeof btoa !== 'undefined'
56
- ? btoa(id)
57
- : Buffer.from(id, 'base64').toString('ascii');
58
- }
59
56
  if (!id.startsWith('gid://')) {
60
57
  throw new Error('invalid Shopify ID');
61
58
  }
@@ -5,7 +5,6 @@ export { wrapPromise } from './suspense';
5
5
  export { flattenConnection } from './flattenConnection';
6
6
  export { isClient } from './isClient';
7
7
  export { isServer } from './isServer';
8
- export { log, setLogger, Logger, logServerResponse, getLoggerFromContext, resetLogger, } from './log';
9
8
  export { getMeasurementAsParts, getMeasurementAsString } from './measurement';
10
9
  export { parseMetafieldValue } from './parseMetafieldValue';
11
10
  export { fetchBuilder, graphqlRequestBody, decodeShopifyId } from './fetch';
@@ -5,7 +5,6 @@ export { wrapPromise } from './suspense';
5
5
  export { flattenConnection } from './flattenConnection';
6
6
  export { isClient } from './isClient';
7
7
  export { isServer } from './isServer';
8
- export { log, setLogger, logServerResponse, getLoggerFromContext, resetLogger, } from './log';
9
8
  export { getMeasurementAsParts, getMeasurementAsString } from './measurement';
10
9
  export { parseMetafieldValue } from './parseMetafieldValue';
11
10
  export { fetchBuilder, graphqlRequestBody, decodeShopifyId } from './fetch';
@@ -3,9 +3,6 @@ import { ServerComponentRequest } from '../../framework/Hydration/ServerComponen
3
3
  * Use by importing `log` `@shopify/hydrogen` or by using a `log` prop passed to each page
4
4
  * component. Using the latter is ideal, because it will ty your log to the current request in progress.
5
5
  */
6
- declare global {
7
- var __hlogger: Logger;
8
- }
9
6
  export interface Logger {
10
7
  trace: (...args: Array<any>) => void;
11
8
  debug: (...args: Array<any>) => void;
@@ -14,7 +11,7 @@ export interface Logger {
14
11
  fatal: (...args: Array<any>) => void;
15
12
  }
16
13
  export declare function getLoggerFromContext(context: any): Logger;
17
- export declare function setLogger(_logger: Logger): void;
14
+ export declare function setLogger(newLogger: Logger): void;
18
15
  export declare function resetLogger(): void;
19
16
  export declare const log: Logger;
20
17
  export declare function logServerResponse(type: 'str' | 'rsc' | 'ssr', log: Logger, request: ServerComponentRequest, responseStatus: number): void;
@@ -1,17 +1,6 @@
1
1
  import { yellow, red, green, italic, lightBlue } from 'kolorist';
2
2
  import { getTime } from '../timing';
3
- export function getLoggerFromContext(context) {
4
- return {
5
- trace: (...args) => globalThis.__hlogger.trace(context, ...args),
6
- debug: (...args) => globalThis.__hlogger.debug(context, ...args),
7
- warn: (...args) => globalThis.__hlogger.warn(context, ...args),
8
- error: (...args) => globalThis.__hlogger.error(context, ...args),
9
- fatal: (...args) => globalThis.__hlogger.fatal(context, ...args),
10
- };
11
- }
12
- // @todo - multiple instances of log.ts are loaded, we utilitze the
13
- // global in order to make sure that the logger is a singleton
14
- const defaultLogger = (globalThis.__hlogger = {
3
+ const defaultLogger = {
15
4
  trace(context, ...args) {
16
5
  console.log(...args);
17
6
  },
@@ -27,28 +16,38 @@ const defaultLogger = (globalThis.__hlogger = {
27
16
  fatal(context, ...args) {
28
17
  console.error(red('FATAL: '), ...args);
29
18
  },
30
- });
31
- export function setLogger(_logger) {
32
- globalThis.__hlogger = _logger;
19
+ };
20
+ let logger = defaultLogger;
21
+ export function getLoggerFromContext(context) {
22
+ return {
23
+ trace: (...args) => logger.trace(context, ...args),
24
+ debug: (...args) => logger.debug(context, ...args),
25
+ warn: (...args) => logger.warn(context, ...args),
26
+ error: (...args) => logger.error(context, ...args),
27
+ fatal: (...args) => logger.fatal(context, ...args),
28
+ };
29
+ }
30
+ export function setLogger(newLogger) {
31
+ logger = newLogger;
33
32
  }
34
33
  export function resetLogger() {
35
- globalThis.__hlogger = defaultLogger;
34
+ logger = defaultLogger;
36
35
  }
37
36
  export const log = {
38
37
  trace(...args) {
39
- return globalThis.__hlogger.trace({}, ...args);
38
+ return logger.trace({}, ...args);
40
39
  },
41
40
  debug(...args) {
42
- return globalThis.__hlogger.debug({}, ...args);
41
+ return logger.debug({}, ...args);
43
42
  },
44
43
  warn(...args) {
45
- return globalThis.__hlogger.warn({}, ...args);
44
+ return logger.warn({}, ...args);
46
45
  },
47
46
  error(...args) {
48
- return globalThis.__hlogger.error({}, ...args);
47
+ return logger.error({}, ...args);
49
48
  },
50
49
  fatal(...args) {
51
- return globalThis.__hlogger.fatal({}, ...args);
50
+ return logger.fatal({}, ...args);
52
51
  },
53
52
  };
54
53
  export function logServerResponse(type, log, request, responseStatus) {
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "0.8.1";
1
+ export declare const LIB_VERSION = "0.8.2";
@@ -1 +1 @@
1
- export const LIB_VERSION = '0.8.1';
1
+ export const LIB_VERSION = '0.8.2';
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const cache_1 = require("./framework/cache");
4
4
  const runtime_1 = require("./framework/runtime");
5
5
  const config_1 = require("./framework/config");
6
- const log_1 = require("./utilities/log");
7
6
  async function handleEvent(event, { request, entrypoint, indexTemplate, assetHandler, streamableResponse, dev, cache, context, }) {
8
7
  var _a, _b, _c, _d, _e;
9
8
  const url = new URL(request.url);
@@ -32,7 +31,6 @@ async function handleEvent(event, { request, entrypoint, indexTemplate, assetHan
32
31
  }
33
32
  const userAgent = request.headers.get('user-agent');
34
33
  const isStreamable = streamableResponse && !isBotUA(url, userAgent);
35
- const logger = (0, log_1.getLoggerFromContext)(request);
36
34
  /**
37
35
  * Stream back real-user responses, but for bots/etc,
38
36
  * use `render` instead. This is because we need to inject <head>
@@ -45,7 +43,6 @@ async function handleEvent(event, { request, entrypoint, indexTemplate, assetHan
45
43
  request,
46
44
  response: streamableResponse,
47
45
  dev,
48
- log: logger,
49
46
  });
50
47
  }
51
48
  else {
@@ -55,7 +52,6 @@ async function handleEvent(event, { request, entrypoint, indexTemplate, assetHan
55
52
  response: streamableResponse,
56
53
  template,
57
54
  dev,
58
- log: logger,
59
55
  });
60
56
  }
61
57
  return;
@@ -65,7 +61,6 @@ async function handleEvent(event, { request, entrypoint, indexTemplate, assetHan
65
61
  context: {},
66
62
  isReactHydrationRequest,
67
63
  dev,
68
- log: logger,
69
64
  });
70
65
  const headers = componentResponse.headers;
71
66
  /**
@@ -102,7 +97,6 @@ async function handleEvent(event, { request, entrypoint, indexTemplate, assetHan
102
97
  headers,
103
98
  });
104
99
  }
105
- (0, log_1.logServerResponse)('ssr', logger, request, response.status);
106
100
  return response;
107
101
  }
108
102
  exports.default = handleEvent;
@@ -1,6 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  import { ServerResponse } from 'http';
3
- import type { Logger } from './utilities/log/log';
4
3
  import type { ServerComponentResponse } from './framework/Hydration/ServerComponentResponse.server';
5
4
  import type { ServerComponentRequest } from './framework/Hydration/ServerComponentRequest.server';
6
5
  import type { Metafield, Image, MediaContentType } from './graphql/types/types';
@@ -9,7 +8,6 @@ export declare type Renderer = (url: URL, options: {
9
8
  context?: Record<string, any>;
10
9
  isReactHydrationRequest?: boolean;
11
10
  dev?: boolean;
12
- log: Logger;
13
11
  }) => Promise<{
14
12
  body: string;
15
13
  componentResponse: ServerComponentResponse;
@@ -19,14 +17,12 @@ export declare type Streamer = (url: URL, options: {
19
17
  request: ServerComponentRequest;
20
18
  response: ServerResponse;
21
19
  template: string;
22
- log: Logger;
23
20
  dev?: boolean;
24
21
  }) => void;
25
22
  export declare type Hydrator = (url: URL, options: {
26
23
  context: any;
27
24
  request: ServerComponentRequest;
28
25
  response: ServerResponse;
29
- log: Logger;
30
26
  dev?: boolean;
31
27
  }) => void;
32
28
  export declare type EntryServerHandler = {
@@ -41,6 +41,9 @@ function fetchBuilder(request) {
41
41
  headers,
42
42
  method: clonedRequest.method,
43
43
  });
44
+ if (!response.ok) {
45
+ throw response;
46
+ }
44
47
  const data = await response.json();
45
48
  return data;
46
49
  };
@@ -55,12 +58,6 @@ function graphqlRequestBody(query, variables) {
55
58
  }
56
59
  exports.graphqlRequestBody = graphqlRequestBody;
57
60
  function decodeShopifyId(id) {
58
- if (!id.startsWith('gid://')) {
59
- id =
60
- typeof btoa !== 'undefined'
61
- ? btoa(id)
62
- : Buffer.from(id, 'base64').toString('ascii');
63
- }
64
61
  if (!id.startsWith('gid://')) {
65
62
  throw new Error('invalid Shopify ID');
66
63
  }
@@ -5,7 +5,6 @@ export { wrapPromise } from './suspense';
5
5
  export { flattenConnection } from './flattenConnection';
6
6
  export { isClient } from './isClient';
7
7
  export { isServer } from './isServer';
8
- export { log, setLogger, Logger, logServerResponse, getLoggerFromContext, resetLogger, } from './log';
9
8
  export { getMeasurementAsParts, getMeasurementAsString } from './measurement';
10
9
  export { parseMetafieldValue } from './parseMetafieldValue';
11
10
  export { fetchBuilder, graphqlRequestBody, decodeShopifyId } from './fetch';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTime = exports.decodeShopifyId = exports.graphqlRequestBody = exports.fetchBuilder = exports.parseMetafieldValue = exports.getMeasurementAsString = exports.getMeasurementAsParts = exports.resetLogger = exports.getLoggerFromContext = exports.logServerResponse = exports.setLogger = exports.log = exports.isServer = exports.isClient = exports.flattenConnection = exports.wrapPromise = exports.loadScript = exports.useEmbeddedVideoUrl = exports.addParametersToEmbeddedVideoUrl = exports.shopifyImageLoader = exports.getShopifyImageDimensions = exports.useImageUrl = exports.addImageSizeParametersToUrl = void 0;
3
+ exports.getTime = exports.decodeShopifyId = exports.graphqlRequestBody = exports.fetchBuilder = exports.parseMetafieldValue = exports.getMeasurementAsString = exports.getMeasurementAsParts = exports.isServer = exports.isClient = exports.flattenConnection = exports.wrapPromise = exports.loadScript = exports.useEmbeddedVideoUrl = exports.addParametersToEmbeddedVideoUrl = exports.shopifyImageLoader = exports.getShopifyImageDimensions = exports.useImageUrl = exports.addImageSizeParametersToUrl = void 0;
4
4
  var image_size_1 = require("./image_size");
5
5
  Object.defineProperty(exports, "addImageSizeParametersToUrl", { enumerable: true, get: function () { return image_size_1.addImageSizeParametersToUrl; } });
6
6
  Object.defineProperty(exports, "useImageUrl", { enumerable: true, get: function () { return image_size_1.useImageUrl; } });
@@ -19,12 +19,6 @@ var isClient_1 = require("./isClient");
19
19
  Object.defineProperty(exports, "isClient", { enumerable: true, get: function () { return isClient_1.isClient; } });
20
20
  var isServer_1 = require("./isServer");
21
21
  Object.defineProperty(exports, "isServer", { enumerable: true, get: function () { return isServer_1.isServer; } });
22
- var log_1 = require("./log");
23
- Object.defineProperty(exports, "log", { enumerable: true, get: function () { return log_1.log; } });
24
- Object.defineProperty(exports, "setLogger", { enumerable: true, get: function () { return log_1.setLogger; } });
25
- Object.defineProperty(exports, "logServerResponse", { enumerable: true, get: function () { return log_1.logServerResponse; } });
26
- Object.defineProperty(exports, "getLoggerFromContext", { enumerable: true, get: function () { return log_1.getLoggerFromContext; } });
27
- Object.defineProperty(exports, "resetLogger", { enumerable: true, get: function () { return log_1.resetLogger; } });
28
22
  var measurement_1 = require("./measurement");
29
23
  Object.defineProperty(exports, "getMeasurementAsParts", { enumerable: true, get: function () { return measurement_1.getMeasurementAsParts; } });
30
24
  Object.defineProperty(exports, "getMeasurementAsString", { enumerable: true, get: function () { return measurement_1.getMeasurementAsString; } });
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "0.8.1";
1
+ export declare const LIB_VERSION = "0.8.2";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LIB_VERSION = void 0;
4
- exports.LIB_VERSION = '0.8.1';
4
+ exports.LIB_VERSION = '0.8.2';
@@ -1,7 +1,6 @@
1
1
  import { getCacheControlHeader } from './framework/cache';
2
2
  import { setContext, setCache } from './framework/runtime';
3
3
  import { setConfig } from './framework/config';
4
- import { getLoggerFromContext, logServerResponse } from './utilities/log';
5
4
  export default async function handleEvent(event, { request, entrypoint, indexTemplate, assetHandler, streamableResponse, dev, cache, context, }) {
6
5
  var _a, _b, _c, _d, _e;
7
6
  const url = new URL(request.url);
@@ -30,7 +29,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
30
29
  }
31
30
  const userAgent = request.headers.get('user-agent');
32
31
  const isStreamable = streamableResponse && !isBotUA(url, userAgent);
33
- const logger = getLoggerFromContext(request);
34
32
  /**
35
33
  * Stream back real-user responses, but for bots/etc,
36
34
  * use `render` instead. This is because we need to inject <head>
@@ -43,7 +41,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
43
41
  request,
44
42
  response: streamableResponse,
45
43
  dev,
46
- log: logger,
47
44
  });
48
45
  }
49
46
  else {
@@ -53,7 +50,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
53
50
  response: streamableResponse,
54
51
  template,
55
52
  dev,
56
- log: logger,
57
53
  });
58
54
  }
59
55
  return;
@@ -63,7 +59,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
63
59
  context: {},
64
60
  isReactHydrationRequest,
65
61
  dev,
66
- log: logger,
67
62
  });
68
63
  const headers = componentResponse.headers;
69
64
  /**
@@ -100,7 +95,6 @@ export default async function handleEvent(event, { request, entrypoint, indexTem
100
95
  headers,
101
96
  });
102
97
  }
103
- logServerResponse('ssr', logger, request, response.status);
104
98
  return response;
105
99
  }
106
100
  /**
@@ -1,6 +1,5 @@
1
1
  /// <reference types="@types/node" />
2
2
  import { ServerResponse } from 'http';
3
- import type { Logger } from './utilities/log/log';
4
3
  import type { ServerComponentResponse } from './framework/Hydration/ServerComponentResponse.server';
5
4
  import type { ServerComponentRequest } from './framework/Hydration/ServerComponentRequest.server';
6
5
  import type { Metafield, Image, MediaContentType } from './graphql/types/types';
@@ -9,7 +8,6 @@ export declare type Renderer = (url: URL, options: {
9
8
  context?: Record<string, any>;
10
9
  isReactHydrationRequest?: boolean;
11
10
  dev?: boolean;
12
- log: Logger;
13
11
  }) => Promise<{
14
12
  body: string;
15
13
  componentResponse: ServerComponentResponse;
@@ -19,14 +17,12 @@ export declare type Streamer = (url: URL, options: {
19
17
  request: ServerComponentRequest;
20
18
  response: ServerResponse;
21
19
  template: string;
22
- log: Logger;
23
20
  dev?: boolean;
24
21
  }) => void;
25
22
  export declare type Hydrator = (url: URL, options: {
26
23
  context: any;
27
24
  request: ServerComponentRequest;
28
25
  response: ServerResponse;
29
- log: Logger;
30
26
  dev?: boolean;
31
27
  }) => void;
32
28
  export declare type EntryServerHandler = {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public",
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
- "version": "0.8.1",
7
+ "version": "0.8.2",
8
8
  "description": "Modern custom Shopify storefronts",
9
9
  "license": "MIT",
10
10
  "main": "dist/esnext/index.js",
@@ -99,5 +99,5 @@
99
99
  "react-ssr-prepass": "^1.4.0",
100
100
  "vite-plugin-inspect": "^0.3.6"
101
101
  },
102
- "gitHead": "e16175bc14ef3e449baeba1c7bc31eae9c6bbe0f"
102
+ "gitHead": "587f117221ab94a06165e69602658c4e561f5723"
103
103
  }
@@ -1 +0,0 @@
1
- export { log, setLogger, Logger, logServerResponse, getLoggerFromContext, resetLogger, } from './log';
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resetLogger = exports.getLoggerFromContext = exports.logServerResponse = exports.setLogger = exports.log = void 0;
4
- var log_1 = require("./log");
5
- Object.defineProperty(exports, "log", { enumerable: true, get: function () { return log_1.log; } });
6
- Object.defineProperty(exports, "setLogger", { enumerable: true, get: function () { return log_1.setLogger; } });
7
- Object.defineProperty(exports, "logServerResponse", { enumerable: true, get: function () { return log_1.logServerResponse; } });
8
- Object.defineProperty(exports, "getLoggerFromContext", { enumerable: true, get: function () { return log_1.getLoggerFromContext; } });
9
- Object.defineProperty(exports, "resetLogger", { enumerable: true, get: function () { return log_1.resetLogger; } });
@@ -1,20 +0,0 @@
1
- import { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
2
- /** A utility for logging debugging, warning, and error information about the application.
3
- * Use by importing `log` `@shopify/hydrogen` or by using a `log` prop passed to each page
4
- * component. Using the latter is ideal, because it will ty your log to the current request in progress.
5
- */
6
- declare global {
7
- var __hlogger: Logger;
8
- }
9
- export interface Logger {
10
- trace: (...args: Array<any>) => void;
11
- debug: (...args: Array<any>) => void;
12
- warn: (...args: Array<any>) => void;
13
- error: (...args: Array<any>) => void;
14
- fatal: (...args: Array<any>) => void;
15
- }
16
- export declare function getLoggerFromContext(context: any): Logger;
17
- export declare function setLogger(_logger: Logger): void;
18
- export declare function resetLogger(): void;
19
- export declare const log: Logger;
20
- export declare function logServerResponse(type: 'str' | 'rsc' | 'ssr', log: Logger, request: ServerComponentRequest, responseStatus: number): void;
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logServerResponse = exports.log = exports.resetLogger = exports.setLogger = exports.getLoggerFromContext = void 0;
4
- const kolorist_1 = require("kolorist");
5
- const timing_1 = require("../timing");
6
- function getLoggerFromContext(context) {
7
- return {
8
- trace: (...args) => globalThis.__hlogger.trace(context, ...args),
9
- debug: (...args) => globalThis.__hlogger.debug(context, ...args),
10
- warn: (...args) => globalThis.__hlogger.warn(context, ...args),
11
- error: (...args) => globalThis.__hlogger.error(context, ...args),
12
- fatal: (...args) => globalThis.__hlogger.fatal(context, ...args),
13
- };
14
- }
15
- exports.getLoggerFromContext = getLoggerFromContext;
16
- // @todo - multiple instances of log.ts are loaded, we utilitze the
17
- // global in order to make sure that the logger is a singleton
18
- const defaultLogger = (globalThis.__hlogger = {
19
- trace(context, ...args) {
20
- console.log(...args);
21
- },
22
- debug(context, ...args) {
23
- console.log(...args);
24
- },
25
- warn(context, ...args) {
26
- console.warn((0, kolorist_1.yellow)('WARN: '), ...args);
27
- },
28
- error(context, ...args) {
29
- console.error((0, kolorist_1.red)('ERROR: '), ...args);
30
- },
31
- fatal(context, ...args) {
32
- console.error((0, kolorist_1.red)('FATAL: '), ...args);
33
- },
34
- });
35
- function setLogger(_logger) {
36
- globalThis.__hlogger = _logger;
37
- }
38
- exports.setLogger = setLogger;
39
- function resetLogger() {
40
- globalThis.__hlogger = defaultLogger;
41
- }
42
- exports.resetLogger = resetLogger;
43
- exports.log = {
44
- trace(...args) {
45
- return globalThis.__hlogger.trace({}, ...args);
46
- },
47
- debug(...args) {
48
- return globalThis.__hlogger.debug({}, ...args);
49
- },
50
- warn(...args) {
51
- return globalThis.__hlogger.warn({}, ...args);
52
- },
53
- error(...args) {
54
- return globalThis.__hlogger.error({}, ...args);
55
- },
56
- fatal(...args) {
57
- return globalThis.__hlogger.fatal({}, ...args);
58
- },
59
- };
60
- function logServerResponse(type, log, request, responseStatus) {
61
- const coloredResponseStatus = responseStatus >= 500
62
- ? (0, kolorist_1.red)(responseStatus)
63
- : responseStatus >= 400
64
- ? (0, kolorist_1.yellow)(responseStatus)
65
- : responseStatus >= 300
66
- ? (0, kolorist_1.lightBlue)(responseStatus)
67
- : (0, kolorist_1.green)(responseStatus);
68
- const styledType = (0, kolorist_1.italic)(type);
69
- const paddedTiming = pad(((0, timing_1.getTime)() - request.time).toFixed(2) + ' ms', ' ');
70
- const url = type === 'rsc'
71
- ? decodeURIComponent(request.url.substring(request.url.indexOf('=') + 1))
72
- : request.url;
73
- log.debug(`${request.method} ${styledType} ${coloredResponseStatus} ${paddedTiming} ${url}`);
74
- }
75
- exports.logServerResponse = logServerResponse;
76
- function pad(str, _pad) {
77
- return (str + _pad).substring(0, _pad.length);
78
- }
@@ -1 +0,0 @@
1
- export { log, setLogger, Logger, logServerResponse, getLoggerFromContext, resetLogger, } from './log';
@@ -1 +0,0 @@
1
- export { log, setLogger, logServerResponse, getLoggerFromContext, resetLogger, } from './log';
@@ -1,20 +0,0 @@
1
- import { ServerComponentRequest } from '../../framework/Hydration/ServerComponentRequest.server';
2
- /** A utility for logging debugging, warning, and error information about the application.
3
- * Use by importing `log` `@shopify/hydrogen` or by using a `log` prop passed to each page
4
- * component. Using the latter is ideal, because it will ty your log to the current request in progress.
5
- */
6
- declare global {
7
- var __hlogger: Logger;
8
- }
9
- export interface Logger {
10
- trace: (...args: Array<any>) => void;
11
- debug: (...args: Array<any>) => void;
12
- warn: (...args: Array<any>) => void;
13
- error: (...args: Array<any>) => void;
14
- fatal: (...args: Array<any>) => void;
15
- }
16
- export declare function getLoggerFromContext(context: any): Logger;
17
- export declare function setLogger(_logger: Logger): void;
18
- export declare function resetLogger(): void;
19
- export declare const log: Logger;
20
- export declare function logServerResponse(type: 'str' | 'rsc' | 'ssr', log: Logger, request: ServerComponentRequest, responseStatus: number): void;
@@ -1,71 +0,0 @@
1
- import { yellow, red, green, italic, lightBlue } from 'kolorist';
2
- import { getTime } from '../timing';
3
- export function getLoggerFromContext(context) {
4
- return {
5
- trace: (...args) => globalThis.__hlogger.trace(context, ...args),
6
- debug: (...args) => globalThis.__hlogger.debug(context, ...args),
7
- warn: (...args) => globalThis.__hlogger.warn(context, ...args),
8
- error: (...args) => globalThis.__hlogger.error(context, ...args),
9
- fatal: (...args) => globalThis.__hlogger.fatal(context, ...args),
10
- };
11
- }
12
- // @todo - multiple instances of log.ts are loaded, we utilitze the
13
- // global in order to make sure that the logger is a singleton
14
- const defaultLogger = (globalThis.__hlogger = {
15
- trace(context, ...args) {
16
- console.log(...args);
17
- },
18
- debug(context, ...args) {
19
- console.log(...args);
20
- },
21
- warn(context, ...args) {
22
- console.warn(yellow('WARN: '), ...args);
23
- },
24
- error(context, ...args) {
25
- console.error(red('ERROR: '), ...args);
26
- },
27
- fatal(context, ...args) {
28
- console.error(red('FATAL: '), ...args);
29
- },
30
- });
31
- export function setLogger(_logger) {
32
- globalThis.__hlogger = _logger;
33
- }
34
- export function resetLogger() {
35
- globalThis.__hlogger = defaultLogger;
36
- }
37
- export const log = {
38
- trace(...args) {
39
- return globalThis.__hlogger.trace({}, ...args);
40
- },
41
- debug(...args) {
42
- return globalThis.__hlogger.debug({}, ...args);
43
- },
44
- warn(...args) {
45
- return globalThis.__hlogger.warn({}, ...args);
46
- },
47
- error(...args) {
48
- return globalThis.__hlogger.error({}, ...args);
49
- },
50
- fatal(...args) {
51
- return globalThis.__hlogger.fatal({}, ...args);
52
- },
53
- };
54
- export function logServerResponse(type, log, request, responseStatus) {
55
- const coloredResponseStatus = responseStatus >= 500
56
- ? red(responseStatus)
57
- : responseStatus >= 400
58
- ? yellow(responseStatus)
59
- : responseStatus >= 300
60
- ? lightBlue(responseStatus)
61
- : green(responseStatus);
62
- const styledType = italic(type);
63
- const paddedTiming = pad((getTime() - request.time).toFixed(2) + ' ms', ' ');
64
- const url = type === 'rsc'
65
- ? decodeURIComponent(request.url.substring(request.url.indexOf('=') + 1))
66
- : request.url;
67
- log.debug(`${request.method} ${styledType} ${coloredResponseStatus} ${paddedTiming} ${url}`);
68
- }
69
- function pad(str, _pad) {
70
- return (str + _pad).substring(0, _pad.length);
71
- }