@shopify/remix-oxygen 2.0.10 → 2.0.12

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.
@@ -8,8 +8,8 @@ var serverRuntime = require('@remix-run/server-runtime');
8
8
  var encoder = new TextEncoder();
9
9
  var sign = async (value, secret) => {
10
10
  const key = await createKey(secret, ["sign"]);
11
- const data = encoder.encode(value);
12
- const signature = await crypto.subtle.sign("HMAC", key, data);
11
+ const data2 = encoder.encode(value);
12
+ const signature = await crypto.subtle.sign("HMAC", key, data2);
13
13
  const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(
14
14
  /=+$/,
15
15
  ""
@@ -21,9 +21,9 @@ var unsign = async (signed, secret) => {
21
21
  const value = signed.slice(0, index);
22
22
  const hash = signed.slice(index + 1);
23
23
  const key = await createKey(secret, ["verify"]);
24
- const data = encoder.encode(value);
24
+ const data2 = encoder.encode(value);
25
25
  const signature = byteStringToUint8Array(atob(hash));
26
- const valid = await crypto.subtle.verify("HMAC", key, signature, data);
26
+ const valid = await crypto.subtle.verify("HMAC", key, signature, data2);
27
27
  return valid ? value : false;
28
28
  };
29
29
  async function createKey(secret, usages) {
@@ -154,6 +154,10 @@ Object.defineProperty(exports, "createSession", {
154
154
  enumerable: true,
155
155
  get: function () { return serverRuntime.createSession; }
156
156
  });
157
+ Object.defineProperty(exports, "data", {
158
+ enumerable: true,
159
+ get: function () { return serverRuntime.data; }
160
+ });
157
161
  Object.defineProperty(exports, "defer", {
158
162
  enumerable: true,
159
163
  get: function () { return serverRuntime.defer; }
@@ -184,5 +188,5 @@ exports.createMemorySessionStorage = createMemorySessionStorage;
184
188
  exports.createRequestHandler = createRequestHandler;
185
189
  exports.createSessionStorage = createSessionStorage;
186
190
  exports.getStorefrontHeaders = getStorefrontHeaders;
187
- //# sourceMappingURL=out.js.map
191
+ //# sourceMappingURL=index.cjs.map
188
192
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/implementations.ts","../../src/crypto.ts","../../src/server.ts","../../src/event-logger.ts","../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n","type H2OEvent = Parameters<NonNullable<typeof __H2O_LOG_EVENT>>[0];\n\nlet hasWarned = false;\n\n/**\n * @deprecated Only used with the classic Remix compiler\n */\nexport function createEventLogger(appLoadContext: Record<string, unknown>) {\n const context = (appLoadContext || {}) as {\n env?: Record<string, any>;\n waitUntil?: (promise: Promise<any>) => void;\n };\n\n const eventLoggerService = context?.env?.H2O_LOG_EVENT as\n | undefined\n | {fetch: (req: Request) => Promise<Response>};\n\n if (typeof eventLoggerService?.fetch !== 'function') return;\n\n return ({\n url,\n endTime = Date.now(),\n waitUntil = context?.waitUntil,\n ...rest\n }: H2OEvent) => {\n const promise = Promise.resolve().then(() =>\n eventLoggerService\n .fetch(\n new Request(url, {\n method: 'POST',\n body: JSON.stringify({\n endTime,\n ...rest,\n }),\n }),\n )\n .catch((error: Error) => {\n if (!hasWarned) {\n // This might repeat a lot of times due to\n // the same issue, so we only warn once.\n console.debug('Failed to log H2O event\\n', error.stack);\n hasWarned = true;\n }\n }),\n );\n\n promise && waitUntil?.(promise);\n };\n}\n","export {\n createCookie,\n createCookieSessionStorage,\n createMemorySessionStorage,\n createSessionStorage,\n} from './implementations';\n\nexport {createRequestHandler, getStorefrontHeaders} from './server';\n\nexport {\n createSession,\n defer,\n isCookie,\n isSession,\n json,\n MaxPartSizeExceededError,\n redirect,\n redirectDocument,\n} from '@remix-run/server-runtime';\n\nexport type {\n ActionFunction,\n ActionFunctionArgs,\n AppLoadContext,\n Cookie,\n CookieOptions,\n CookieParseOptions,\n CookieSerializeOptions,\n CookieSignatureOptions,\n DataFunctionArgs,\n EntryContext,\n ErrorResponse,\n HandleDataRequestFunction,\n HandleDocumentRequestFunction,\n HeadersArgs,\n HeadersFunction,\n HtmlLinkDescriptor,\n JsonFunction,\n LinkDescriptor,\n LinksFunction,\n LoaderFunction,\n LoaderFunctionArgs,\n MemoryUploadHandlerFilterArgs,\n MemoryUploadHandlerOptions,\n HandleErrorFunction,\n PageLinkDescriptor,\n RequestHandler,\n SerializeFrom,\n ServerBuild,\n ServerEntryModule,\n ServerRuntimeMetaArgs as MetaArgs,\n ServerRuntimeMetaDescriptor as MetaDescriptor,\n ServerRuntimeMetaFunction as MetaFunction,\n Session,\n SessionData,\n SessionIdStorageStrategy,\n SessionStorage,\n SignFunction,\n TypedDeferredData,\n TypedResponse,\n UnsignFunction,\n UploadHandler,\n UploadHandlerPart,\n} from '@remix-run/server-runtime';\n"]}
1
+ {"version":3,"sources":["../../src/crypto.ts","../../src/implementations.ts","../../src/event-logger.ts","../../src/server.ts"],"names":["data","createCookieFactory","createCookieSessionStorageFactory","createSessionStorageFactory","createMemorySessionStorageFactory","createRemixRequestHandler"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","type H2OEvent = Parameters<NonNullable<typeof __H2O_LOG_EVENT>>[0];\n\nlet hasWarned = false;\n\n/**\n * @deprecated Only used with the classic Remix compiler\n */\nexport function createEventLogger(appLoadContext: Record<string, unknown>) {\n const context = (appLoadContext || {}) as {\n env?: Record<string, any>;\n waitUntil?: (promise: Promise<any>) => void;\n };\n\n const eventLoggerService = context?.env?.H2O_LOG_EVENT as\n | undefined\n | {fetch: (req: Request) => Promise<Response>};\n\n if (typeof eventLoggerService?.fetch !== 'function') return;\n\n return ({\n url,\n endTime = Date.now(),\n waitUntil = context?.waitUntil,\n ...rest\n }: H2OEvent) => {\n const promise = Promise.resolve().then(() =>\n eventLoggerService\n .fetch(\n new Request(url, {\n method: 'POST',\n body: JSON.stringify({\n endTime,\n ...rest,\n }),\n }),\n )\n .catch((error: Error) => {\n if (!hasWarned) {\n // This might repeat a lot of times due to\n // the same issue, so we only warn once.\n console.debug('Failed to log H2O event\\n', error.stack);\n hasWarned = true;\n }\n }),\n );\n\n promise && waitUntil?.(promise);\n };\n}\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { createCookieFactory, createCookieSessionStorageFactory, createSessionStorageFactory, createMemorySessionStorageFactory, createRequestHandler as createRequestHandler$1 } from '@remix-run/server-runtime';
2
- export { MaxPartSizeExceededError, createSession, defer, isCookie, isSession, json, redirect, redirectDocument } from '@remix-run/server-runtime';
2
+ export { MaxPartSizeExceededError, createSession, data, defer, isCookie, isSession, json, redirect, redirectDocument } from '@remix-run/server-runtime';
3
3
 
4
4
  // src/implementations.ts
5
5
 
@@ -7,8 +7,8 @@ export { MaxPartSizeExceededError, createSession, defer, isCookie, isSession, js
7
7
  var encoder = new TextEncoder();
8
8
  var sign = async (value, secret) => {
9
9
  const key = await createKey(secret, ["sign"]);
10
- const data = encoder.encode(value);
11
- const signature = await crypto.subtle.sign("HMAC", key, data);
10
+ const data2 = encoder.encode(value);
11
+ const signature = await crypto.subtle.sign("HMAC", key, data2);
12
12
  const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(
13
13
  /=+$/,
14
14
  ""
@@ -20,9 +20,9 @@ var unsign = async (signed, secret) => {
20
20
  const value = signed.slice(0, index);
21
21
  const hash = signed.slice(index + 1);
22
22
  const key = await createKey(secret, ["verify"]);
23
- const data = encoder.encode(value);
23
+ const data2 = encoder.encode(value);
24
24
  const signature = byteStringToUint8Array(atob(hash));
25
- const valid = await crypto.subtle.verify("HMAC", key, signature, data);
25
+ const valid = await crypto.subtle.verify("HMAC", key, signature, data2);
26
26
  return valid ? value : false;
27
27
  };
28
28
  async function createKey(secret, usages) {
@@ -146,5 +146,5 @@ function getStorefrontHeaders(request) {
146
146
  }
147
147
 
148
148
  export { createCookie, createCookieSessionStorage, createMemorySessionStorage, createRequestHandler, createSessionStorage, getStorefrontHeaders };
149
- //# sourceMappingURL=out.js.map
149
+ //# sourceMappingURL=index.js.map
150
150
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/implementations.ts","../../src/crypto.ts","../../src/server.ts","../../src/event-logger.ts","../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n","type H2OEvent = Parameters<NonNullable<typeof __H2O_LOG_EVENT>>[0];\n\nlet hasWarned = false;\n\n/**\n * @deprecated Only used with the classic Remix compiler\n */\nexport function createEventLogger(appLoadContext: Record<string, unknown>) {\n const context = (appLoadContext || {}) as {\n env?: Record<string, any>;\n waitUntil?: (promise: Promise<any>) => void;\n };\n\n const eventLoggerService = context?.env?.H2O_LOG_EVENT as\n | undefined\n | {fetch: (req: Request) => Promise<Response>};\n\n if (typeof eventLoggerService?.fetch !== 'function') return;\n\n return ({\n url,\n endTime = Date.now(),\n waitUntil = context?.waitUntil,\n ...rest\n }: H2OEvent) => {\n const promise = Promise.resolve().then(() =>\n eventLoggerService\n .fetch(\n new Request(url, {\n method: 'POST',\n body: JSON.stringify({\n endTime,\n ...rest,\n }),\n }),\n )\n .catch((error: Error) => {\n if (!hasWarned) {\n // This might repeat a lot of times due to\n // the same issue, so we only warn once.\n console.debug('Failed to log H2O event\\n', error.stack);\n hasWarned = true;\n }\n }),\n );\n\n promise && waitUntil?.(promise);\n };\n}\n","export {\n createCookie,\n createCookieSessionStorage,\n createMemorySessionStorage,\n createSessionStorage,\n} from './implementations';\n\nexport {createRequestHandler, getStorefrontHeaders} from './server';\n\nexport {\n createSession,\n defer,\n isCookie,\n isSession,\n json,\n MaxPartSizeExceededError,\n redirect,\n redirectDocument,\n} from '@remix-run/server-runtime';\n\nexport type {\n ActionFunction,\n ActionFunctionArgs,\n AppLoadContext,\n Cookie,\n CookieOptions,\n CookieParseOptions,\n CookieSerializeOptions,\n CookieSignatureOptions,\n DataFunctionArgs,\n EntryContext,\n ErrorResponse,\n HandleDataRequestFunction,\n HandleDocumentRequestFunction,\n HeadersArgs,\n HeadersFunction,\n HtmlLinkDescriptor,\n JsonFunction,\n LinkDescriptor,\n LinksFunction,\n LoaderFunction,\n LoaderFunctionArgs,\n MemoryUploadHandlerFilterArgs,\n MemoryUploadHandlerOptions,\n HandleErrorFunction,\n PageLinkDescriptor,\n RequestHandler,\n SerializeFrom,\n ServerBuild,\n ServerEntryModule,\n ServerRuntimeMetaArgs as MetaArgs,\n ServerRuntimeMetaDescriptor as MetaDescriptor,\n ServerRuntimeMetaFunction as MetaFunction,\n Session,\n SessionData,\n SessionIdStorageStrategy,\n SessionStorage,\n SignFunction,\n TypedDeferredData,\n TypedResponse,\n UnsignFunction,\n UploadHandler,\n UploadHandlerPart,\n} from '@remix-run/server-runtime';\n"]}
1
+ {"version":3,"sources":["../../src/crypto.ts","../../src/implementations.ts","../../src/event-logger.ts","../../src/server.ts"],"names":["data","createRemixRequestHandler"],"mappings":"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","file":"index.js","sourcesContent":["import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","type H2OEvent = Parameters<NonNullable<typeof __H2O_LOG_EVENT>>[0];\n\nlet hasWarned = false;\n\n/**\n * @deprecated Only used with the classic Remix compiler\n */\nexport function createEventLogger(appLoadContext: Record<string, unknown>) {\n const context = (appLoadContext || {}) as {\n env?: Record<string, any>;\n waitUntil?: (promise: Promise<any>) => void;\n };\n\n const eventLoggerService = context?.env?.H2O_LOG_EVENT as\n | undefined\n | {fetch: (req: Request) => Promise<Response>};\n\n if (typeof eventLoggerService?.fetch !== 'function') return;\n\n return ({\n url,\n endTime = Date.now(),\n waitUntil = context?.waitUntil,\n ...rest\n }: H2OEvent) => {\n const promise = Promise.resolve().then(() =>\n eventLoggerService\n .fetch(\n new Request(url, {\n method: 'POST',\n body: JSON.stringify({\n endTime,\n ...rest,\n }),\n }),\n )\n .catch((error: Error) => {\n if (!hasWarned) {\n // This might repeat a lot of times due to\n // the same issue, so we only warn once.\n console.debug('Failed to log H2O event\\n', error.stack);\n hasWarned = true;\n }\n }),\n );\n\n promise && waitUntil?.(promise);\n };\n}\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n"]}
@@ -1,46 +1,3 @@
1
- 'use strict';
2
-
3
- var serverRuntime = require('@remix-run/server-runtime');
4
-
5
- var c=new TextEncoder,l=async(e,t)=>{let r=await y(t,["sign"]),n=c.encode(e),s=await crypto.subtle.sign("HMAC",r,n),o=btoa(String.fromCharCode(...new Uint8Array(s))).replace(/=+$/,"");return e+"."+o},g=async(e,t)=>{let r=e.lastIndexOf("."),n=e.slice(0,r),s=e.slice(r+1),o=await y(t,["verify"]),a=c.encode(n),i=m(atob(s));return await crypto.subtle.verify("HMAC",o,i,a)?n:!1};async function y(e,t){return await crypto.subtle.importKey("raw",c.encode(e),{name:"HMAC",hash:"SHA-256"},!1,t)}function m(e){let t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}var u=serverRuntime.createCookieFactory({sign:l,unsign:g}),C=serverRuntime.createCookieSessionStorageFactory(u),S=serverRuntime.createSessionStorageFactory(u),k=serverRuntime.createMemorySessionStorageFactory(S);var A=Error.prototype.toString;Error.prototype.toString=function(){return this.stack||A.call(this)};function E({build:e,mode:t,poweredByHeader:r=!0,getLoadContext:n}){let s=serverRuntime.createRequestHandler(e,t);return async o=>{let a=o.method;if((a==="GET"||a==="HEAD")&&o.body)return new Response(`${a} requests cannot have a body`,{status:400});let i=new URL(o.url);if(i.pathname.includes("//"))return new Response(null,{status:301,headers:{location:i.pathname.replace(/\/+/g,"/")}});let p=n?await n(o):void 0,d=await s(o,p);return r&&d.headers.append("powered-by","Shopify, Hydrogen"),d}}function v(e){let t=e.headers;return {requestGroupId:t.get("request-id"),buyerIp:t.get("oxygen-buyer-ip"),cookie:t.get("cookie"),purpose:t.get("purpose")}}
6
-
7
- Object.defineProperty(exports, "MaxPartSizeExceededError", {
8
- enumerable: true,
9
- get: function () { return serverRuntime.MaxPartSizeExceededError; }
10
- });
11
- Object.defineProperty(exports, "createSession", {
12
- enumerable: true,
13
- get: function () { return serverRuntime.createSession; }
14
- });
15
- Object.defineProperty(exports, "defer", {
16
- enumerable: true,
17
- get: function () { return serverRuntime.defer; }
18
- });
19
- Object.defineProperty(exports, "isCookie", {
20
- enumerable: true,
21
- get: function () { return serverRuntime.isCookie; }
22
- });
23
- Object.defineProperty(exports, "isSession", {
24
- enumerable: true,
25
- get: function () { return serverRuntime.isSession; }
26
- });
27
- Object.defineProperty(exports, "json", {
28
- enumerable: true,
29
- get: function () { return serverRuntime.json; }
30
- });
31
- Object.defineProperty(exports, "redirect", {
32
- enumerable: true,
33
- get: function () { return serverRuntime.redirect; }
34
- });
35
- Object.defineProperty(exports, "redirectDocument", {
36
- enumerable: true,
37
- get: function () { return serverRuntime.redirectDocument; }
38
- });
39
- exports.createCookie = u;
40
- exports.createCookieSessionStorage = C;
41
- exports.createMemorySessionStorage = k;
42
- exports.createRequestHandler = E;
43
- exports.createSessionStorage = S;
44
- exports.getStorefrontHeaders = v;
45
- //# sourceMappingURL=out.js.map
1
+ 'use strict';var serverRuntime=require('@remix-run/server-runtime');var c=new TextEncoder,l=async(e,t)=>{let r=await y(t,["sign"]),n=c.encode(e),s=await crypto.subtle.sign("HMAC",r,n),o=btoa(String.fromCharCode(...new Uint8Array(s))).replace(/=+$/,"");return e+"."+o},g=async(e,t)=>{let r=e.lastIndexOf("."),n=e.slice(0,r),s=e.slice(r+1),o=await y(t,["verify"]),a=c.encode(n),i=m(atob(s));return await crypto.subtle.verify("HMAC",o,i,a)?n:false};async function y(e,t){return await crypto.subtle.importKey("raw",c.encode(e),{name:"HMAC",hash:"SHA-256"},false,t)}function m(e){let t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}var u=serverRuntime.createCookieFactory({sign:l,unsign:g}),C=serverRuntime.createCookieSessionStorageFactory(u),S=serverRuntime.createSessionStorageFactory(u),k=serverRuntime.createMemorySessionStorageFactory(S);var A=Error.prototype.toString;Error.prototype.toString=function(){return this.stack||A.call(this)};function E({build:e,mode:t,poweredByHeader:r=true,getLoadContext:n}){let s=serverRuntime.createRequestHandler(e,t);return async o=>{let a=o.method;if((a==="GET"||a==="HEAD")&&o.body)return new Response(`${a} requests cannot have a body`,{status:400});let i=new URL(o.url);if(i.pathname.includes("//"))return new Response(null,{status:301,headers:{location:i.pathname.replace(/\/+/g,"/")}});let p=n?await n(o):void 0,d=await s(o,p);return r&&d.headers.append("powered-by","Shopify, Hydrogen"),d}}function v(e){let t=e.headers;return {requestGroupId:t.get("request-id"),buyerIp:t.get("oxygen-buyer-ip"),cookie:t.get("cookie"),purpose:t.get("purpose")}}
2
+ Object.defineProperty(exports,"MaxPartSizeExceededError",{enumerable:true,get:function(){return serverRuntime.MaxPartSizeExceededError}});Object.defineProperty(exports,"createSession",{enumerable:true,get:function(){return serverRuntime.createSession}});Object.defineProperty(exports,"data",{enumerable:true,get:function(){return serverRuntime.data}});Object.defineProperty(exports,"defer",{enumerable:true,get:function(){return serverRuntime.defer}});Object.defineProperty(exports,"isCookie",{enumerable:true,get:function(){return serverRuntime.isCookie}});Object.defineProperty(exports,"isSession",{enumerable:true,get:function(){return serverRuntime.isSession}});Object.defineProperty(exports,"json",{enumerable:true,get:function(){return serverRuntime.json}});Object.defineProperty(exports,"redirect",{enumerable:true,get:function(){return serverRuntime.redirect}});Object.defineProperty(exports,"redirectDocument",{enumerable:true,get:function(){return serverRuntime.redirectDocument}});exports.createCookie=u;exports.createCookieSessionStorage=C;exports.createMemorySessionStorage=k;exports.createRequestHandler=E;exports.createSessionStorage=S;exports.getStorefrontHeaders=v;//# sourceMappingURL=index.cjs.map
46
3
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/implementations.ts","../../src/crypto.ts","../../src/server.ts","../../src/index.ts"],"names":["createCookieFactory","createCookieSessionStorageFactory","createMemorySessionStorageFactory","createSessionStorageFactory","encoder","sign","value","secret","key","createKey","data","signature","hash","unsign","signed","index","byteStringToUint8Array","usages","byteString","array","i","createCookie","createCookieSessionStorage","createSessionStorage","createMemorySessionStorage","createRemixRequestHandler","originalErrorToString","createRequestHandler","build","mode","poweredByHeader","getLoadContext","handleRequest","request","method","url","context","startTime","response","getStorefrontHeaders","headers","createSession","defer","isCookie","isSession","json","MaxPartSizeExceededError","redirect","redirectDocument"],"mappings":"AAAA,OACE,uBAAAA,EACA,qCAAAC,EACA,qCAAAC,EACA,+BAAAC,MACK,4BCHP,IAAMC,EAAU,IAAI,YAEPC,EAAqB,MAAOC,EAAOC,IAAW,CACzD,IAAMC,EAAM,MAAMC,EAAUF,EAAQ,CAAC,MAAM,CAAC,EACtCG,EAAON,EAAQ,OAAOE,CAAK,EAC3BK,EAAY,MAAM,OAAO,OAAO,KAAK,OAAQH,EAAKE,CAAI,EACtDE,EAAO,KAAK,OAAO,aAAa,GAAG,IAAI,WAAWD,CAAS,CAAC,CAAC,EAAE,QACnE,MACA,EACF,EAEA,OAAOL,EAAQ,IAAMM,CACvB,EAEaC,EAAyB,MAAOC,EAAQP,IAAW,CAC9D,IAAMQ,EAAQD,EAAO,YAAY,GAAG,EAC9BR,EAAQQ,EAAO,MAAM,EAAGC,CAAK,EAC7BH,EAAOE,EAAO,MAAMC,EAAQ,CAAC,EAE7BP,EAAM,MAAMC,EAAUF,EAAQ,CAAC,QAAQ,CAAC,EACxCG,EAAON,EAAQ,OAAOE,CAAK,EAC3BK,EAAYK,EAAuB,KAAKJ,CAAI,CAAC,EAGnD,OAFc,MAAM,OAAO,OAAO,OAAO,OAAQJ,EAAKG,EAAWD,CAAI,EAEtDJ,EAAQ,EACzB,EAEA,eAAeG,EACbF,EACAU,EACoB,CASpB,OARY,MAAM,OAAO,OAAO,UAC9B,MACAb,EAAQ,OAAOG,CAAM,EACrB,CAAC,KAAM,OAAQ,KAAM,SAAS,EAC9B,GACAU,CACF,CAGF,CAEA,SAASD,EAAuBE,EAAgC,CAC9D,IAAMC,EAAQ,IAAI,WAAWD,EAAW,MAAM,EAE9C,QAASE,EAAI,EAAGA,EAAIF,EAAW,OAAQE,IACrCD,EAAMC,CAAC,EAAIF,EAAW,WAAWE,CAAC,EAGpC,OAAOD,CACT,CD3CO,IAAME,EAAerB,EAAoB,CAAC,KAAAK,EAAM,OAAAQ,CAAM,CAAC,EACjDS,EACXrB,EAAkCoB,CAAY,EACnCE,EAAuBpB,EAA4BkB,CAAY,EAC/DG,EACXtB,EAAkCqB,CAAoB,EEbxD,OACE,wBAAwBE,MAGnB,4BAGP,IAAMC,EAAwB,MAAM,UAAU,SAC9C,MAAM,UAAU,SAAW,UAAY,CACrC,OAAO,KAAK,OAASA,EAAsB,KAAK,IAAI,CACtD,EAEO,SAASC,EAAwC,CACtD,MAAAC,EACA,KAAAC,EACA,gBAAAC,EAAkB,GAClB,eAAAC,CACF,EAKG,CACD,IAAMC,EAAgBP,EAA0BG,EAAOC,CAAI,EAE3D,MAAO,OAAOI,GAAqB,CACjC,IAAMC,EAASD,EAAQ,OAEvB,IAAKC,IAAW,OAASA,IAAW,SAAWD,EAAQ,KACrD,OAAO,IAAI,SAAS,GAAGC,CAAM,+BAAgC,CAC3D,OAAQ,GACV,CAAC,EAGH,IAAMC,EAAM,IAAI,IAAIF,EAAQ,GAAG,EAE/B,GAAIE,EAAI,SAAS,SAAS,IAAI,EAC5B,OAAO,IAAI,SAAS,KAAM,CACxB,OAAQ,IACR,QAAS,CACP,SAAUA,EAAI,SAAS,QAAQ,OAAQ,GAAG,CAC5C,CACF,CAAC,EAGH,IAAMC,EAAUL,EACV,MAAMA,EAAeE,CAAO,EAC9B,OASEI,EAAY,KAAK,IAAI,EAErBC,EAAW,MAAMN,EAAcC,EAASG,CAAO,EAErD,OAAIN,GACFQ,EAAS,QAAQ,OAAO,aAAc,mBAAmB,EAkBpDA,CACT,CACF,CASO,SAASC,EAAqBN,EAAqC,CACxE,IAAMO,EAAUP,EAAQ,QACxB,MAAO,CACL,eAAgBO,EAAQ,IAAI,YAAY,EACxC,QAASA,EAAQ,IAAI,iBAAiB,EACtC,OAAQA,EAAQ,IAAI,QAAQ,EAC5B,QAASA,EAAQ,IAAI,SAAS,CAChC,CACF,CC1FA,OACE,iBAAAC,EACA,SAAAC,EACA,YAAAC,EACA,aAAAC,EACA,QAAAC,EACA,4BAAAC,EACA,YAAAC,EACA,oBAAAC,MACK","sourcesContent":["import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n","export {\n createCookie,\n createCookieSessionStorage,\n createMemorySessionStorage,\n createSessionStorage,\n} from './implementations';\n\nexport {createRequestHandler, getStorefrontHeaders} from './server';\n\nexport {\n createSession,\n defer,\n isCookie,\n isSession,\n json,\n MaxPartSizeExceededError,\n redirect,\n redirectDocument,\n} from '@remix-run/server-runtime';\n\nexport type {\n ActionFunction,\n ActionFunctionArgs,\n AppLoadContext,\n Cookie,\n CookieOptions,\n CookieParseOptions,\n CookieSerializeOptions,\n CookieSignatureOptions,\n DataFunctionArgs,\n EntryContext,\n ErrorResponse,\n HandleDataRequestFunction,\n HandleDocumentRequestFunction,\n HeadersArgs,\n HeadersFunction,\n HtmlLinkDescriptor,\n JsonFunction,\n LinkDescriptor,\n LinksFunction,\n LoaderFunction,\n LoaderFunctionArgs,\n MemoryUploadHandlerFilterArgs,\n MemoryUploadHandlerOptions,\n HandleErrorFunction,\n PageLinkDescriptor,\n RequestHandler,\n SerializeFrom,\n ServerBuild,\n ServerEntryModule,\n ServerRuntimeMetaArgs as MetaArgs,\n ServerRuntimeMetaDescriptor as MetaDescriptor,\n ServerRuntimeMetaFunction as MetaFunction,\n Session,\n SessionData,\n SessionIdStorageStrategy,\n SessionStorage,\n SignFunction,\n TypedDeferredData,\n TypedResponse,\n UnsignFunction,\n UploadHandler,\n UploadHandlerPart,\n} from '@remix-run/server-runtime';\n"]}
1
+ {"version":3,"sources":["../../src/crypto.ts","../../src/implementations.ts","../../src/server.ts"],"names":["encoder","sign","value","secret","key","createKey","data","signature","hash","unsign","signed","index","byteStringToUint8Array","usages","byteString","array","i","createCookie","createCookieFactory","createCookieSessionStorage","createCookieSessionStorageFactory","createSessionStorage","createSessionStorageFactory","createMemorySessionStorage","createMemorySessionStorageFactory","originalErrorToString","createRequestHandler","build","mode","poweredByHeader","getLoadContext","handleRequest","createRemixRequestHandler","request","method","url","context","response","getStorefrontHeaders","headers"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import * as _remix_run_server_runtime from '@remix-run/server-runtime';
2
2
  import { ServerBuild } from '@remix-run/server-runtime';
3
- export { ActionFunction, ActionFunctionArgs, AppLoadContext, Cookie, CookieOptions, CookieParseOptions, CookieSerializeOptions, CookieSignatureOptions, DataFunctionArgs, EntryContext, ErrorResponse, HandleDataRequestFunction, HandleDocumentRequestFunction, HandleErrorFunction, HeadersArgs, HeadersFunction, HtmlLinkDescriptor, JsonFunction, LinkDescriptor, LinksFunction, LoaderFunction, LoaderFunctionArgs, MaxPartSizeExceededError, MemoryUploadHandlerFilterArgs, MemoryUploadHandlerOptions, ServerRuntimeMetaArgs as MetaArgs, ServerRuntimeMetaDescriptor as MetaDescriptor, ServerRuntimeMetaFunction as MetaFunction, PageLinkDescriptor, RequestHandler, SerializeFrom, ServerBuild, ServerEntryModule, Session, SessionData, SessionIdStorageStrategy, SessionStorage, SignFunction, TypedDeferredData, TypedResponse, UnsignFunction, UploadHandler, UploadHandlerPart, createSession, defer, isCookie, isSession, json, redirect, redirectDocument } from '@remix-run/server-runtime';
3
+ export { ActionFunction, ActionFunctionArgs, AppLoadContext, Cookie, CookieOptions, CookieParseOptions, CookieSerializeOptions, CookieSignatureOptions, DataFunctionArgs, EntryContext, ErrorResponse, HandleDataRequestFunction, HandleDocumentRequestFunction, HandleErrorFunction, HeadersArgs, HeadersFunction, HtmlLinkDescriptor, JsonFunction, LinkDescriptor, LinksFunction, LoaderFunction, LoaderFunctionArgs, MaxPartSizeExceededError, MemoryUploadHandlerFilterArgs, MemoryUploadHandlerOptions, ServerRuntimeMetaArgs as MetaArgs, ServerRuntimeMetaDescriptor as MetaDescriptor, ServerRuntimeMetaFunction as MetaFunction, PageLinkDescriptor, RequestHandler, SerializeFrom, ServerBuild, ServerEntryModule, Session, SessionData, SessionIdStorageStrategy, SessionStorage, SignFunction, TypedDeferredData, TypedResponse, UnsignFunction, UploadHandler, UploadHandlerPart, createSession, data, defer, isCookie, isSession, json, redirect, redirectDocument } from '@remix-run/server-runtime';
4
4
 
5
5
  declare const createCookie: _remix_run_server_runtime.CreateCookieFunction;
6
6
  declare const createCookieSessionStorage: _remix_run_server_runtime.CreateCookieSessionStorageFunction;
@@ -1,6 +1,6 @@
1
1
  import * as _remix_run_server_runtime from '@remix-run/server-runtime';
2
2
  import { ServerBuild } from '@remix-run/server-runtime';
3
- export { ActionFunction, ActionFunctionArgs, AppLoadContext, Cookie, CookieOptions, CookieParseOptions, CookieSerializeOptions, CookieSignatureOptions, DataFunctionArgs, EntryContext, ErrorResponse, HandleDataRequestFunction, HandleDocumentRequestFunction, HandleErrorFunction, HeadersArgs, HeadersFunction, HtmlLinkDescriptor, JsonFunction, LinkDescriptor, LinksFunction, LoaderFunction, LoaderFunctionArgs, MaxPartSizeExceededError, MemoryUploadHandlerFilterArgs, MemoryUploadHandlerOptions, ServerRuntimeMetaArgs as MetaArgs, ServerRuntimeMetaDescriptor as MetaDescriptor, ServerRuntimeMetaFunction as MetaFunction, PageLinkDescriptor, RequestHandler, SerializeFrom, ServerBuild, ServerEntryModule, Session, SessionData, SessionIdStorageStrategy, SessionStorage, SignFunction, TypedDeferredData, TypedResponse, UnsignFunction, UploadHandler, UploadHandlerPart, createSession, defer, isCookie, isSession, json, redirect, redirectDocument } from '@remix-run/server-runtime';
3
+ export { ActionFunction, ActionFunctionArgs, AppLoadContext, Cookie, CookieOptions, CookieParseOptions, CookieSerializeOptions, CookieSignatureOptions, DataFunctionArgs, EntryContext, ErrorResponse, HandleDataRequestFunction, HandleDocumentRequestFunction, HandleErrorFunction, HeadersArgs, HeadersFunction, HtmlLinkDescriptor, JsonFunction, LinkDescriptor, LinksFunction, LoaderFunction, LoaderFunctionArgs, MaxPartSizeExceededError, MemoryUploadHandlerFilterArgs, MemoryUploadHandlerOptions, ServerRuntimeMetaArgs as MetaArgs, ServerRuntimeMetaDescriptor as MetaDescriptor, ServerRuntimeMetaFunction as MetaFunction, PageLinkDescriptor, RequestHandler, SerializeFrom, ServerBuild, ServerEntryModule, Session, SessionData, SessionIdStorageStrategy, SessionStorage, SignFunction, TypedDeferredData, TypedResponse, UnsignFunction, UploadHandler, UploadHandlerPart, createSession, data, defer, isCookie, isSession, json, redirect, redirectDocument } from '@remix-run/server-runtime';
4
4
 
5
5
  declare const createCookie: _remix_run_server_runtime.CreateCookieFunction;
6
6
  declare const createCookieSessionStorage: _remix_run_server_runtime.CreateCookieSessionStorageFunction;
@@ -1,8 +1,3 @@
1
- import { createCookieFactory, createCookieSessionStorageFactory, createSessionStorageFactory, createMemorySessionStorageFactory, createRequestHandler } from '@remix-run/server-runtime';
2
- export { MaxPartSizeExceededError, createSession, defer, isCookie, isSession, json, redirect, redirectDocument } from '@remix-run/server-runtime';
3
-
4
- var c=new TextEncoder,l=async(e,t)=>{let r=await y(t,["sign"]),n=c.encode(e),s=await crypto.subtle.sign("HMAC",r,n),o=btoa(String.fromCharCode(...new Uint8Array(s))).replace(/=+$/,"");return e+"."+o},g=async(e,t)=>{let r=e.lastIndexOf("."),n=e.slice(0,r),s=e.slice(r+1),o=await y(t,["verify"]),a=c.encode(n),i=m(atob(s));return await crypto.subtle.verify("HMAC",o,i,a)?n:!1};async function y(e,t){return await crypto.subtle.importKey("raw",c.encode(e),{name:"HMAC",hash:"SHA-256"},!1,t)}function m(e){let t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}var u=createCookieFactory({sign:l,unsign:g}),C=createCookieSessionStorageFactory(u),S=createSessionStorageFactory(u),k=createMemorySessionStorageFactory(S);var A=Error.prototype.toString;Error.prototype.toString=function(){return this.stack||A.call(this)};function E({build:e,mode:t,poweredByHeader:r=!0,getLoadContext:n}){let s=createRequestHandler(e,t);return async o=>{let a=o.method;if((a==="GET"||a==="HEAD")&&o.body)return new Response(`${a} requests cannot have a body`,{status:400});let i=new URL(o.url);if(i.pathname.includes("//"))return new Response(null,{status:301,headers:{location:i.pathname.replace(/\/+/g,"/")}});let p=n?await n(o):void 0,d=await s(o,p);return r&&d.headers.append("powered-by","Shopify, Hydrogen"),d}}function v(e){let t=e.headers;return {requestGroupId:t.get("request-id"),buyerIp:t.get("oxygen-buyer-ip"),cookie:t.get("cookie"),purpose:t.get("purpose")}}
5
-
6
- export { u as createCookie, C as createCookieSessionStorage, k as createMemorySessionStorage, E as createRequestHandler, S as createSessionStorage, v as getStorefrontHeaders };
7
- //# sourceMappingURL=out.js.map
1
+ import {createCookieFactory,createCookieSessionStorageFactory,createSessionStorageFactory,createMemorySessionStorageFactory,createRequestHandler}from'@remix-run/server-runtime';export{MaxPartSizeExceededError,createSession,data,defer,isCookie,isSession,json,redirect,redirectDocument}from'@remix-run/server-runtime';var c=new TextEncoder,l=async(e,t)=>{let r=await y(t,["sign"]),n=c.encode(e),s=await crypto.subtle.sign("HMAC",r,n),o=btoa(String.fromCharCode(...new Uint8Array(s))).replace(/=+$/,"");return e+"."+o},g=async(e,t)=>{let r=e.lastIndexOf("."),n=e.slice(0,r),s=e.slice(r+1),o=await y(t,["verify"]),a=c.encode(n),i=m(atob(s));return await crypto.subtle.verify("HMAC",o,i,a)?n:false};async function y(e,t){return await crypto.subtle.importKey("raw",c.encode(e),{name:"HMAC",hash:"SHA-256"},false,t)}function m(e){let t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}var u=createCookieFactory({sign:l,unsign:g}),C=createCookieSessionStorageFactory(u),S=createSessionStorageFactory(u),k=createMemorySessionStorageFactory(S);var A=Error.prototype.toString;Error.prototype.toString=function(){return this.stack||A.call(this)};function E({build:e,mode:t,poweredByHeader:r=true,getLoadContext:n}){let s=createRequestHandler(e,t);return async o=>{let a=o.method;if((a==="GET"||a==="HEAD")&&o.body)return new Response(`${a} requests cannot have a body`,{status:400});let i=new URL(o.url);if(i.pathname.includes("//"))return new Response(null,{status:301,headers:{location:i.pathname.replace(/\/+/g,"/")}});let p=n?await n(o):void 0,d=await s(o,p);return r&&d.headers.append("powered-by","Shopify, Hydrogen"),d}}function v(e){let t=e.headers;return {requestGroupId:t.get("request-id"),buyerIp:t.get("oxygen-buyer-ip"),cookie:t.get("cookie"),purpose:t.get("purpose")}}
2
+ export{u as createCookie,C as createCookieSessionStorage,k as createMemorySessionStorage,E as createRequestHandler,S as createSessionStorage,v as getStorefrontHeaders};//# sourceMappingURL=index.js.map
8
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/implementations.ts","../../src/crypto.ts","../../src/server.ts","../../src/index.ts"],"names":["createCookieFactory","createCookieSessionStorageFactory","createMemorySessionStorageFactory","createSessionStorageFactory","encoder","sign","value","secret","key","createKey","data","signature","hash","unsign","signed","index","byteStringToUint8Array","usages","byteString","array","i","createCookie","createCookieSessionStorage","createSessionStorage","createMemorySessionStorage","createRemixRequestHandler","originalErrorToString","createRequestHandler","build","mode","poweredByHeader","getLoadContext","handleRequest","request","method","url","context","startTime","response","getStorefrontHeaders","headers","createSession","defer","isCookie","isSession","json","MaxPartSizeExceededError","redirect","redirectDocument"],"mappings":"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","sourcesContent":["import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n","export {\n createCookie,\n createCookieSessionStorage,\n createMemorySessionStorage,\n createSessionStorage,\n} from './implementations';\n\nexport {createRequestHandler, getStorefrontHeaders} from './server';\n\nexport {\n createSession,\n defer,\n isCookie,\n isSession,\n json,\n MaxPartSizeExceededError,\n redirect,\n redirectDocument,\n} from '@remix-run/server-runtime';\n\nexport type {\n ActionFunction,\n ActionFunctionArgs,\n AppLoadContext,\n Cookie,\n CookieOptions,\n CookieParseOptions,\n CookieSerializeOptions,\n CookieSignatureOptions,\n DataFunctionArgs,\n EntryContext,\n ErrorResponse,\n HandleDataRequestFunction,\n HandleDocumentRequestFunction,\n HeadersArgs,\n HeadersFunction,\n HtmlLinkDescriptor,\n JsonFunction,\n LinkDescriptor,\n LinksFunction,\n LoaderFunction,\n LoaderFunctionArgs,\n MemoryUploadHandlerFilterArgs,\n MemoryUploadHandlerOptions,\n HandleErrorFunction,\n PageLinkDescriptor,\n RequestHandler,\n SerializeFrom,\n ServerBuild,\n ServerEntryModule,\n ServerRuntimeMetaArgs as MetaArgs,\n ServerRuntimeMetaDescriptor as MetaDescriptor,\n ServerRuntimeMetaFunction as MetaFunction,\n Session,\n SessionData,\n SessionIdStorageStrategy,\n SessionStorage,\n SignFunction,\n TypedDeferredData,\n TypedResponse,\n UnsignFunction,\n UploadHandler,\n UploadHandlerPart,\n} from '@remix-run/server-runtime';\n"]}
1
+ {"version":3,"sources":["../../src/crypto.ts","../../src/implementations.ts","../../src/server.ts"],"names":["encoder","sign","value","secret","key","createKey","data","signature","hash","unsign","signed","index","byteStringToUint8Array","usages","byteString","array","i","createCookie","createCookieFactory","createCookieSessionStorage","createCookieSessionStorageFactory","createSessionStorage","createSessionStorageFactory","createMemorySessionStorage","createMemorySessionStorageFactory","originalErrorToString","createRequestHandler","build","mode","poweredByHeader","getLoadContext","handleRequest","createRemixRequestHandler","request","method","url","context","response","getStorefrontHeaders","headers"],"mappings":"4TAEA,IAAMA,CAAU,CAAA,IAAI,YAEPC,CAAqB,CAAA,MAAOC,EAAOC,CAAW,GAAA,CACzD,IAAMC,CAAM,CAAA,MAAMC,CAAUF,CAAAA,CAAAA,CAAQ,CAAC,MAAM,CAAC,EACtCG,CAAON,CAAAA,CAAAA,CAAQ,OAAOE,CAAK,CAAA,CAC3BK,EAAY,MAAM,MAAA,CAAO,OAAO,IAAK,CAAA,MAAA,CAAQH,EAAKE,CAAI,CAAA,CACtDE,EAAO,IAAK,CAAA,MAAA,CAAO,YAAa,CAAA,GAAG,IAAI,UAAWD,CAAAA,CAAS,CAAC,CAAC,CAAA,CAAE,QACnE,KACA,CAAA,EACF,EAEA,OAAOL,CAAAA,CAAQ,IAAMM,CACvB,CAAA,CAEaC,EAAyB,MAAOC,CAAAA,CAAQP,IAAW,CAC9D,IAAMQ,EAAQD,CAAO,CAAA,WAAA,CAAY,GAAG,CAC9BR,CAAAA,CAAAA,CAAQQ,EAAO,KAAM,CAAA,CAAA,CAAGC,CAAK,CAC7BH,CAAAA,CAAAA,CAAOE,EAAO,KAAMC,CAAAA,CAAAA,CAAQ,CAAC,CAE7BP,CAAAA,CAAAA,CAAM,MAAMC,CAAUF,CAAAA,CAAAA,CAAQ,CAAC,QAAQ,CAAC,CACxCG,CAAAA,CAAAA,CAAON,EAAQ,MAAOE,CAAAA,CAAK,EAC3BK,CAAYK,CAAAA,CAAAA,CAAuB,KAAKJ,CAAI,CAAC,EAGnD,OAFc,MAAM,OAAO,MAAO,CAAA,MAAA,CAAO,OAAQJ,CAAKG,CAAAA,CAAAA,CAAWD,CAAI,CAEtDJ,CAAAA,CAAAA,CAAQ,KACzB,CAEA,CAAA,eAAeG,EACbF,CACAU,CAAAA,CAAAA,CACoB,CASpB,OARY,MAAM,OAAO,MAAO,CAAA,SAAA,CAC9B,MACAb,CAAQ,CAAA,MAAA,CAAOG,CAAM,CACrB,CAAA,CAAC,KAAM,MAAQ,CAAA,IAAA,CAAM,SAAS,CAC9B,CAAA,KAAA,CACAU,CACF,CAGF,CAEA,SAASD,CAAAA,CAAuBE,EAAgC,CAC9D,IAAMC,EAAQ,IAAI,UAAA,CAAWD,EAAW,MAAM,CAAA,CAE9C,QAASE,CAAI,CAAA,CAAA,CAAGA,EAAIF,CAAW,CAAA,MAAA,CAAQE,IACrCD,CAAMC,CAAAA,CAAC,EAAIF,CAAW,CAAA,UAAA,CAAWE,CAAC,CAGpC,CAAA,OAAOD,CACT,CC3CO,IAAME,EAAeC,mBAAoB,CAAA,CAAC,KAAAjB,CAAM,CAAA,MAAA,CAAAQ,CAAM,CAAC,CAAA,CACjDU,EACXC,iCAAkCH,CAAAA,CAAY,EACnCI,CAAuBC,CAAAA,2BAAAA,CAA4BL,CAAY,CAAA,CAC/DM,EACXC,iCAAkCH,CAAAA,CAAoB,ECNxD,IAAMI,EAAwB,KAAM,CAAA,SAAA,CAAU,SAC9C,KAAM,CAAA,SAAA,CAAU,SAAW,UAAY,CACrC,OAAO,IAAK,CAAA,KAAA,EAASA,CAAsB,CAAA,IAAA,CAAK,IAAI,CACtD,CAAA,CAEO,SAASC,CAAwC,CAAA,CACtD,MAAAC,CACA,CAAA,IAAA,CAAAC,EACA,eAAAC,CAAAA,CAAAA,CAAkB,KAClB,cAAAC,CAAAA,CACF,EAKG,CACD,IAAMC,EAAgBC,oBAA0BL,CAAAA,CAAAA,CAAOC,CAAI,CAAA,CAE3D,OAAcK,MAAAA,CAAAA,EAAqB,CACjC,IAAMC,CAAAA,CAASD,EAAQ,MAEvB,CAAA,GAAA,CAAKC,IAAW,KAASA,EAAAA,CAAAA,GAAW,SAAWD,CAAQ,CAAA,IAAA,CACrD,OAAO,IAAI,QAAA,CAAS,GAAGC,CAAM,CAAA,4BAAA,CAAA,CAAgC,CAC3D,MAAQ,CAAA,GACV,CAAC,CAGH,CAAA,IAAMC,EAAM,IAAI,GAAA,CAAIF,EAAQ,GAAG,CAAA,CAE/B,GAAIE,CAAI,CAAA,QAAA,CAAS,SAAS,IAAI,CAAA,CAC5B,OAAO,IAAI,QAAA,CAAS,KAAM,CACxB,MAAA,CAAQ,GACR,CAAA,OAAA,CAAS,CACP,QAAUA,CAAAA,CAAAA,CAAI,SAAS,OAAQ,CAAA,MAAA,CAAQ,GAAG,CAC5C,CACF,CAAC,CAGH,CAAA,IAAMC,EAAUN,CACV,CAAA,MAAMA,EAAeG,CAAO,CAAA,CAC9B,OAWEI,CAAAA,CAAW,MAAMN,CAAcE,CAAAA,CAAAA,CAASG,CAAO,EAErD,OAAIP,GACFQ,CAAS,CAAA,OAAA,CAAQ,OAAO,YAAc,CAAA,mBAAmB,EAkBpDA,CACT,CACF,CASO,SAASC,CAAAA,CAAqBL,EAAqC,CACxE,IAAMM,CAAUN,CAAAA,CAAAA,CAAQ,QACxB,OAAO,CACL,eAAgBM,CAAQ,CAAA,GAAA,CAAI,YAAY,CACxC,CAAA,OAAA,CAASA,EAAQ,GAAI,CAAA,iBAAiB,EACtC,MAAQA,CAAAA,CAAAA,CAAQ,IAAI,QAAQ,CAAA,CAC5B,QAASA,CAAQ,CAAA,GAAA,CAAI,SAAS,CAChC,CACF","file":"index.js","sourcesContent":["import type {SignFunction, UnsignFunction} from '@remix-run/server-runtime';\n\nconst encoder = new TextEncoder();\n\nexport const sign: SignFunction = async (value, secret) => {\n const key = await createKey(secret, ['sign']);\n const data = encoder.encode(value);\n const signature = await crypto.subtle.sign('HMAC', key, data);\n const hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace(\n /=+$/,\n '',\n );\n\n return value + '.' + hash;\n};\n\nexport const unsign: UnsignFunction = async (signed, secret) => {\n const index = signed.lastIndexOf('.');\n const value = signed.slice(0, index);\n const hash = signed.slice(index + 1);\n\n const key = await createKey(secret, ['verify']);\n const data = encoder.encode(value);\n const signature = byteStringToUint8Array(atob(hash));\n const valid = await crypto.subtle.verify('HMAC', key, signature, data);\n\n return valid ? value : false;\n};\n\nasync function createKey(\n secret: string,\n usages: CryptoKey['usages'],\n): Promise<CryptoKey> {\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n {name: 'HMAC', hash: 'SHA-256'},\n false,\n usages,\n );\n\n return key;\n}\n\nfunction byteStringToUint8Array(byteString: string): Uint8Array {\n const array = new Uint8Array(byteString.length);\n\n for (let i = 0; i < byteString.length; i++) {\n array[i] = byteString.charCodeAt(i);\n }\n\n return array;\n}\n","import {\n createCookieFactory,\n createCookieSessionStorageFactory,\n createMemorySessionStorageFactory,\n createSessionStorageFactory,\n} from '@remix-run/server-runtime';\n\nimport {sign, unsign} from './crypto';\n\nexport const createCookie = createCookieFactory({sign, unsign});\nexport const createCookieSessionStorage =\n createCookieSessionStorageFactory(createCookie);\nexport const createSessionStorage = createSessionStorageFactory(createCookie);\nexport const createMemorySessionStorage =\n createMemorySessionStorageFactory(createSessionStorage);\n","/// <reference types=\"@shopify/hydrogen\" />\nimport {\n createRequestHandler as createRemixRequestHandler,\n type AppLoadContext,\n type ServerBuild,\n} from '@remix-run/server-runtime';\nimport {createEventLogger} from './event-logger';\n\nconst originalErrorToString = Error.prototype.toString;\nError.prototype.toString = function () {\n return this.stack || originalErrorToString.call(this);\n};\n\nexport function createRequestHandler<Context = unknown>({\n build,\n mode,\n poweredByHeader = true,\n getLoadContext,\n}: {\n build: ServerBuild;\n mode?: string;\n poweredByHeader?: boolean;\n getLoadContext?: (request: Request) => Promise<Context> | Context;\n}) {\n const handleRequest = createRemixRequestHandler(build, mode);\n\n return async (request: Request) => {\n const method = request.method;\n\n if ((method === 'GET' || method === 'HEAD') && request.body) {\n return new Response(`${method} requests cannot have a body`, {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n\n if (url.pathname.includes('//')) {\n return new Response(null, {\n status: 301,\n headers: {\n location: url.pathname.replace(/\\/+/g, '/'),\n },\n });\n }\n\n const context = getLoadContext\n ? ((await getLoadContext(request)) as AppLoadContext)\n : undefined;\n\n if (process.env.NODE_ENV === 'development' && context) {\n // Store logger in globalThis so it can be accessed from the worker.\n // The global property must be different from the binding name,\n // otherwise Miniflare throws an error when accessing it.\n globalThis.__H2O_LOG_EVENT ??= createEventLogger(context);\n }\n\n const startTime = Date.now();\n\n const response = await handleRequest(request, context);\n\n if (poweredByHeader) {\n response.headers.append('powered-by', 'Shopify, Hydrogen');\n }\n\n if (process.env.NODE_ENV === 'development') {\n globalThis.__H2O_LOG_EVENT?.({\n eventType: 'request',\n url: request.url,\n requestId: request.headers.get('request-id'),\n purpose: request.headers.get('purpose'),\n startTime,\n responseInit: {\n status: response.status,\n statusText: response.statusText,\n headers: Array.from(response.headers.entries()),\n } satisfies ResponseInit,\n });\n }\n\n return response;\n };\n}\n\ntype StorefrontHeaders = {\n requestGroupId: string | null;\n buyerIp: string | null;\n cookie: string | null;\n purpose: string | null;\n};\n\nexport function getStorefrontHeaders(request: Request): StorefrontHeaders {\n const headers = request.headers;\n return {\n requestGroupId: headers.get('request-id'),\n buyerIp: headers.get('oxygen-buyer-ip'),\n cookie: headers.get('cookie'),\n purpose: headers.get('purpose'),\n };\n}\n"]}
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "@shopify:registry": "https://registry.npmjs.org"
6
6
  },
7
7
  "type": "module",
8
- "version": "2.0.10",
8
+ "version": "2.0.12",
9
9
  "license": "MIT",
10
10
  "main": "dist/index.cjs",
11
11
  "module": "dist/production/index.js",
@@ -45,11 +45,11 @@
45
45
  "dist"
46
46
  ],
47
47
  "devDependencies": {
48
- "@remix-run/server-runtime": "^2.15.2",
49
- "@shopify/oxygen-workers-types": "^4.1.2"
48
+ "@remix-run/server-runtime": "^2.16.1",
49
+ "@shopify/oxygen-workers-types": "^4.1.6"
50
50
  },
51
51
  "peerDependencies": {
52
- "@remix-run/server-runtime": "^2.1.0",
52
+ "@remix-run/server-runtime": "^2.16.1",
53
53
  "@shopify/oxygen-workers-types": "^3.17.3 || ^4.1.2"
54
54
  }
55
55
  }