@cloudcart/nitro 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,6 @@
1
1
  // src/csp/policy.ts
2
- import { randomBytes } from "crypto";
3
2
  function createContentSecurityPolicy(options) {
4
- const nonce = options?.nonce ?? randomBytes(16).toString("base64");
3
+ const nonce = options?.nonce ?? generateNonce();
5
4
  const custom = options?.directives ?? {};
6
5
  const directives = {
7
6
  defaultSrc: custom.defaultSrc ?? ["'self'"],
@@ -25,6 +24,15 @@ function createContentSecurityPolicy(options) {
25
24
  }).join("; ");
26
25
  return { nonce, header };
27
26
  }
27
+ function generateNonce() {
28
+ const array = new Uint8Array(16);
29
+ if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.getRandomValues) {
30
+ globalThis.crypto.getRandomValues(array);
31
+ } else {
32
+ for (let i = 0; i < 16; i++) array[i] = Math.floor(Math.random() * 256);
33
+ }
34
+ return btoa(String.fromCharCode(...array));
35
+ }
28
36
 
29
37
  // src/csp/nonce.tsx
30
38
  import { createContext, useContext } from "react";
@@ -42,4 +50,4 @@ export {
42
50
  NonceProvider,
43
51
  useNonce
44
52
  };
45
- //# sourceMappingURL=chunk-RTJ73SCX.js.map
53
+ //# sourceMappingURL=chunk-SKIHOP57.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/csp/policy.ts","../src/csp/nonce.tsx"],"sourcesContent":["export interface CspDirectives {\n defaultSrc?: string[];\n scriptSrc?: string[];\n styleSrc?: string[];\n imgSrc?: string[];\n connectSrc?: string[];\n fontSrc?: string[];\n objectSrc?: string[];\n mediaSrc?: string[];\n frameSrc?: string[];\n childSrc?: string[];\n workerSrc?: string[];\n frameAncestors?: string[];\n formAction?: string[];\n baseUri?: string[];\n}\n\n/**\n * Creates a Content Security Policy with a unique nonce per request.\n * Mirrors Hydrogen's createContentSecurityPolicy.\n */\nexport function createContentSecurityPolicy(options?: {\n nonce?: string;\n directives?: CspDirectives;\n}) {\n const nonce = options?.nonce ?? generateNonce();\n const custom = options?.directives ?? {};\n\n const directives: Record<string, string[]> = {\n defaultSrc: custom.defaultSrc ?? [\"'self'\"],\n scriptSrc: custom.scriptSrc ?? [\"'self'\", `'nonce-${nonce}'`],\n styleSrc: custom.styleSrc ?? [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: custom.imgSrc ?? [\"'self'\", 'data:', 'https:'],\n connectSrc: custom.connectSrc ?? [\"'self'\", 'https:'],\n fontSrc: custom.fontSrc ?? [\"'self'\"],\n objectSrc: custom.objectSrc ?? [\"'none'\"],\n mediaSrc: custom.mediaSrc ?? [\"'self'\"],\n frameSrc: custom.frameSrc ?? [\"'none'\"],\n baseUri: custom.baseUri ?? [\"'self'\"],\n };\n\n // Ensure nonce is in scriptSrc\n const nonceStr = `'nonce-${nonce}'`;\n if (!directives.scriptSrc.includes(nonceStr)) {\n directives.scriptSrc.push(nonceStr);\n }\n\n const header = Object.entries(directives)\n .map(([key, values]) => {\n const directive = key.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase());\n return `${directive} ${values.join(' ')}`;\n })\n .join('; ');\n\n return {nonce, header};\n}\n\nfunction generateNonce(): string {\n const array = new Uint8Array(16);\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues) {\n globalThis.crypto.getRandomValues(array);\n } else {\n for (let i = 0; i < 16; i++) array[i] = Math.floor(Math.random() * 256);\n }\n return btoa(String.fromCharCode(...array));\n}\n","import {createContext, useContext, type ReactNode} from 'react';\n\nconst NonceContext = createContext<string>('');\n\nexport function NonceProvider({value, children}: {value: string; children: ReactNode}) {\n return <NonceContext.Provider value={value}>{children}</NonceContext.Provider>;\n}\n\nexport function useNonce(): string {\n return useContext(NonceContext);\n}\n"],"mappings":";AAqBO,SAAS,4BAA4B,SAGzC;AACD,QAAM,QAAQ,SAAS,SAAS,cAAc;AAC9C,QAAM,SAAS,SAAS,cAAc,CAAC;AAEvC,QAAM,aAAuC;AAAA,IAC3C,YAAY,OAAO,cAAc,CAAC,QAAQ;AAAA,IAC1C,WAAW,OAAO,aAAa,CAAC,UAAU,UAAU,KAAK,GAAG;AAAA,IAC5D,UAAU,OAAO,YAAY,CAAC,UAAU,iBAAiB;AAAA,IACzD,QAAQ,OAAO,UAAU,CAAC,UAAU,SAAS,QAAQ;AAAA,IACrD,YAAY,OAAO,cAAc,CAAC,UAAU,QAAQ;AAAA,IACpD,SAAS,OAAO,WAAW,CAAC,QAAQ;AAAA,IACpC,WAAW,OAAO,aAAa,CAAC,QAAQ;AAAA,IACxC,UAAU,OAAO,YAAY,CAAC,QAAQ;AAAA,IACtC,UAAU,OAAO,YAAY,CAAC,QAAQ;AAAA,IACtC,SAAS,OAAO,WAAW,CAAC,QAAQ;AAAA,EACtC;AAGA,QAAM,WAAW,UAAU,KAAK;AAChC,MAAI,CAAC,WAAW,UAAU,SAAS,QAAQ,GAAG;AAC5C,eAAW,UAAU,KAAK,QAAQ;AAAA,EACpC;AAEA,QAAM,SAAS,OAAO,QAAQ,UAAU,EACrC,IAAI,CAAC,CAAC,KAAK,MAAM,MAAM;AACtB,UAAM,YAAY,IAAI,QAAQ,UAAU,CAAC,MAAM,MAAM,EAAE,YAAY,CAAC;AACpE,WAAO,GAAG,SAAS,IAAI,OAAO,KAAK,GAAG,CAAC;AAAA,EACzC,CAAC,EACA,KAAK,IAAI;AAEZ,SAAO,EAAC,OAAO,OAAM;AACvB;AAEA,SAAS,gBAAwB;AAC/B,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,MAAI,OAAO,WAAW,WAAW,eAAe,WAAW,OAAO,iBAAiB;AACjF,eAAW,OAAO,gBAAgB,KAAK;AAAA,EACzC,OAAO;AACL,aAAS,IAAI,GAAG,IAAI,IAAI,IAAK,OAAM,CAAC,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG;AAAA,EACxE;AACA,SAAO,KAAK,OAAO,aAAa,GAAG,KAAK,CAAC;AAC3C;;;ACjEA,SAAQ,eAAe,kBAAiC;AAK/C;AAHT,IAAM,eAAe,cAAsB,EAAE;AAEtC,SAAS,cAAc,EAAC,OAAO,SAAQ,GAAyC;AACrF,SAAO,oBAAC,aAAa,UAAb,EAAsB,OAAe,UAAS;AACxD;AAEO,SAAS,WAAmB;AACjC,SAAO,WAAW,YAAY;AAChC;","names":[]}
package/dist/csp/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  NonceProvider,
3
3
  createContentSecurityPolicy,
4
4
  useNonce
5
- } from "../chunk-RTJ73SCX.js";
5
+ } from "../chunk-SKIHOP57.js";
6
6
  export {
7
7
  NonceProvider,
8
8
  createContentSecurityPolicy,
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  NonceProvider,
28
28
  createContentSecurityPolicy,
29
29
  useNonce
30
- } from "./chunk-RTJ73SCX.js";
30
+ } from "./chunk-SKIHOP57.js";
31
31
  import {
32
32
  getLocaleFromRequest,
33
33
  injectI18nVariables
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcart/nitro",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CloudCart Nitro — headless commerce framework for React Router",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/csp/policy.ts","../src/csp/nonce.tsx"],"sourcesContent":["import {randomBytes} from 'node:crypto';\n\nexport interface CspDirectives {\n defaultSrc?: string[];\n scriptSrc?: string[];\n styleSrc?: string[];\n imgSrc?: string[];\n connectSrc?: string[];\n fontSrc?: string[];\n objectSrc?: string[];\n mediaSrc?: string[];\n frameSrc?: string[];\n childSrc?: string[];\n workerSrc?: string[];\n frameAncestors?: string[];\n formAction?: string[];\n baseUri?: string[];\n}\n\n/**\n * Creates a Content Security Policy with a unique nonce per request.\n * Mirrors Hydrogen's createContentSecurityPolicy.\n */\nexport function createContentSecurityPolicy(options?: {\n nonce?: string;\n directives?: CspDirectives;\n}) {\n const nonce = options?.nonce ?? randomBytes(16).toString('base64');\n const custom = options?.directives ?? {};\n\n const directives: Record<string, string[]> = {\n defaultSrc: custom.defaultSrc ?? [\"'self'\"],\n scriptSrc: custom.scriptSrc ?? [\"'self'\", `'nonce-${nonce}'`],\n styleSrc: custom.styleSrc ?? [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: custom.imgSrc ?? [\"'self'\", 'data:', 'https:'],\n connectSrc: custom.connectSrc ?? [\"'self'\", 'https:'],\n fontSrc: custom.fontSrc ?? [\"'self'\"],\n objectSrc: custom.objectSrc ?? [\"'none'\"],\n mediaSrc: custom.mediaSrc ?? [\"'self'\"],\n frameSrc: custom.frameSrc ?? [\"'none'\"],\n baseUri: custom.baseUri ?? [\"'self'\"],\n };\n\n // Ensure nonce is in scriptSrc\n const nonceStr = `'nonce-${nonce}'`;\n if (!directives.scriptSrc.includes(nonceStr)) {\n directives.scriptSrc.push(nonceStr);\n }\n\n const header = Object.entries(directives)\n .map(([key, values]) => {\n const directive = key.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase());\n return `${directive} ${values.join(' ')}`;\n })\n .join('; ');\n\n return {nonce, header};\n}\n","import {createContext, useContext, type ReactNode} from 'react';\n\nconst NonceContext = createContext<string>('');\n\nexport function NonceProvider({value, children}: {value: string; children: ReactNode}) {\n return <NonceContext.Provider value={value}>{children}</NonceContext.Provider>;\n}\n\nexport function useNonce(): string {\n return useContext(NonceContext);\n}\n"],"mappings":";AAAA,SAAQ,mBAAkB;AAuBnB,SAAS,4BAA4B,SAGzC;AACD,QAAM,QAAQ,SAAS,SAAS,YAAY,EAAE,EAAE,SAAS,QAAQ;AACjE,QAAM,SAAS,SAAS,cAAc,CAAC;AAEvC,QAAM,aAAuC;AAAA,IAC3C,YAAY,OAAO,cAAc,CAAC,QAAQ;AAAA,IAC1C,WAAW,OAAO,aAAa,CAAC,UAAU,UAAU,KAAK,GAAG;AAAA,IAC5D,UAAU,OAAO,YAAY,CAAC,UAAU,iBAAiB;AAAA,IACzD,QAAQ,OAAO,UAAU,CAAC,UAAU,SAAS,QAAQ;AAAA,IACrD,YAAY,OAAO,cAAc,CAAC,UAAU,QAAQ;AAAA,IACpD,SAAS,OAAO,WAAW,CAAC,QAAQ;AAAA,IACpC,WAAW,OAAO,aAAa,CAAC,QAAQ;AAAA,IACxC,UAAU,OAAO,YAAY,CAAC,QAAQ;AAAA,IACtC,UAAU,OAAO,YAAY,CAAC,QAAQ;AAAA,IACtC,SAAS,OAAO,WAAW,CAAC,QAAQ;AAAA,EACtC;AAGA,QAAM,WAAW,UAAU,KAAK;AAChC,MAAI,CAAC,WAAW,UAAU,SAAS,QAAQ,GAAG;AAC5C,eAAW,UAAU,KAAK,QAAQ;AAAA,EACpC;AAEA,QAAM,SAAS,OAAO,QAAQ,UAAU,EACrC,IAAI,CAAC,CAAC,KAAK,MAAM,MAAM;AACtB,UAAM,YAAY,IAAI,QAAQ,UAAU,CAAC,MAAM,MAAM,EAAE,YAAY,CAAC;AACpE,WAAO,GAAG,SAAS,IAAI,OAAO,KAAK,GAAG,CAAC;AAAA,EACzC,CAAC,EACA,KAAK,IAAI;AAEZ,SAAO,EAAC,OAAO,OAAM;AACvB;;;ACzDA,SAAQ,eAAe,kBAAiC;AAK/C;AAHT,IAAM,eAAe,cAAsB,EAAE;AAEtC,SAAS,cAAc,EAAC,OAAO,SAAQ,GAAyC;AACrF,SAAO,oBAAC,aAAa,UAAb,EAAsB,OAAe,UAAS;AACxD;AAEO,SAAS,WAAmB;AACjC,SAAO,WAAW,YAAY;AAChC;","names":[]}