@contentful/optimization-node 0.1.0-alpha14 → 0.1.0-alpha15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/260.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha14";
1
+ const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha15";
2
2
  const OPTIMIZATION_NODE_SDK_NAME = "@contentful/optimization-node";
3
3
  export { ANONYMOUS_ID_COOKIE, ANONYMOUS_ID_KEY } from "@contentful/optimization-core/constants";
4
4
  export { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION };
@@ -30,7 +30,7 @@ __webpack_require__.d(__webpack_exports__, {
30
30
  OPTIMIZATION_NODE_SDK_VERSION: ()=>OPTIMIZATION_NODE_SDK_VERSION
31
31
  });
32
32
  const constants_namespaceObject = require("@contentful/optimization-core/constants");
33
- const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha14";
33
+ const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha15";
34
34
  const OPTIMIZATION_NODE_SDK_NAME = "@contentful/optimization-node";
35
35
  exports.ANONYMOUS_ID_COOKIE = __webpack_exports__.ANONYMOUS_ID_COOKIE;
36
36
  exports.ANONYMOUS_ID_KEY = __webpack_exports__.ANONYMOUS_ID_KEY;
package/dist/index.cjs CHANGED
@@ -6,7 +6,7 @@ var __webpack_modules__ = {
6
6
  OPTIMIZATION_NODE_SDK_VERSION: ()=>OPTIMIZATION_NODE_SDK_VERSION
7
7
  });
8
8
  require("@contentful/optimization-core/constants");
9
- const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha14";
9
+ const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha15";
10
10
  const OPTIMIZATION_NODE_SDK_NAME = "@contentful/optimization-node";
11
11
  }
12
12
  };
@@ -51,52 +51,10 @@ var __webpack_exports__ = {};
51
51
  });
52
52
  const optimization_core_namespaceObject = require("@contentful/optimization-core");
53
53
  var constants = __webpack_require__("./src/constants.ts");
54
- const DEFAULT_RUNTIME_LOCALE = 'en-US';
55
- const DEFAULT_ACCEPT_LANGUAGE_QUALITY = 1;
56
- const QUALITY_PARAM_PATTERN = /;\s*q=/;
57
54
  const DEFAULT_NODE_ALLOWED_EVENT_TYPES = [
58
55
  'identify',
59
56
  'page'
60
57
  ];
61
- function normalizeHeaderValue(header) {
62
- if ('string' == typeof header) return header;
63
- return Array.isArray(header) ? header.filter((item)=>'string' == typeof item).join(',') : void 0;
64
- }
65
- function getAcceptLanguageHeader(input) {
66
- if ('string' == typeof input) return input;
67
- if ('object' != typeof input || null === input) return;
68
- const headerFromGetter = input.get?.('accept-language');
69
- if ('string' == typeof headerFromGetter) return headerFromGetter;
70
- const { headers } = input;
71
- if ('object' != typeof headers || null === headers) return;
72
- const get = Reflect.get(headers, 'get');
73
- const header = 'function' == typeof get ? Reflect.apply(get, headers, [
74
- 'accept-language'
75
- ]) : Reflect.get(headers, 'accept-language') ?? Reflect.get(headers, 'Accept-Language');
76
- return normalizeHeaderValue(header);
77
- }
78
- function parseAcceptLanguage(acceptLanguage) {
79
- const candidates = [];
80
- for (const [index, value] of (acceptLanguage ?? '').split(',').entries()){
81
- const [rawLocale, rawQuality] = value.split(QUALITY_PARAM_PATTERN);
82
- const locale = (0, optimization_core_namespaceObject.normalizeLocale)(rawLocale);
83
- if (void 0 === locale) continue;
84
- const parsedQuality = void 0 === rawQuality ? DEFAULT_ACCEPT_LANGUAGE_QUALITY : Number(rawQuality);
85
- const quality = Number.isFinite(parsedQuality) ? parsedQuality : DEFAULT_ACCEPT_LANGUAGE_QUALITY;
86
- if (quality > 0) candidates.push({
87
- index,
88
- locale,
89
- quality
90
- });
91
- }
92
- return candidates.sort((left, right)=>right.quality - left.quality || left.index - right.index).map((candidate)=>candidate.locale);
93
- }
94
- function getRequestLocaleCandidates(input) {
95
- const parsedHeaderLocales = parseAcceptLanguage(getAcceptLanguageHeader(input));
96
- if (parsedHeaderLocales.length > 0) return parsedHeaderLocales;
97
- if ('object' != typeof input || null === input) return [];
98
- return input.acceptsLanguages?.().map(optimization_core_namespaceObject.normalizeLocale).filter((locale)=>void 0 !== locale) ?? [];
99
- }
100
58
  class ContentfulOptimization extends optimization_core_namespaceObject.CoreStateless {
101
59
  constructor({ app, allowedEventTypes, eventBuilder, ...config }){
102
60
  const { library, getConsent: _getConsent, ...eventBuilderConfig } = eventBuilder ?? {};
@@ -116,20 +74,6 @@ var __webpack_exports__ = {};
116
74
  }
117
75
  });
118
76
  }
119
- resolveRequestLocale(input) {
120
- const candidates = getRequestLocaleCandidates(input);
121
- const eventLocale = candidates[0] ?? DEFAULT_RUNTIME_LOCALE;
122
- const contentfulLocale = (0, optimization_core_namespaceObject.resolveContentfulLocale)({
123
- candidates,
124
- contentfulLocales: this.config.contentfulLocales
125
- }) ?? this.locale;
126
- return void 0 === contentfulLocale ? {
127
- eventLocale
128
- } : {
129
- eventLocale,
130
- contentfulLocale
131
- };
132
- }
133
77
  }
134
78
  const src_ContentfulOptimization = ContentfulOptimization;
135
79
  const src = src_ContentfulOptimization;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/constants.ts","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../src/ContentfulOptimization.ts","../src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/naming-convention -- Replaced at build-time\ndeclare const __OPTIMIZATION_VERSION__: string | undefined\n// eslint-disable-next-line @typescript-eslint/naming-convention -- Replaced at build-time\ndeclare const __OPTIMIZATION_PACKAGE_NAME__: string | undefined\n\n/**\n * The current version of the Optimization Node SDK, injected at build-time.\n *\n * @defaultValue `'0.0.0'` when the build-time replacement is unavailable.\n *\n * @public\n */\nexport const OPTIMIZATION_NODE_SDK_VERSION =\n typeof __OPTIMIZATION_VERSION__ === 'string' ? __OPTIMIZATION_VERSION__ : '0.0.0'\n\n/**\n * The package name of the Optimization Node SDK, injected at build-time.\n *\n * @defaultValue `'@contentful/optimization-node'` when the build-time replacement is unavailable.\n *\n * @public\n */\nexport const OPTIMIZATION_NODE_SDK_NAME =\n typeof __OPTIMIZATION_PACKAGE_NAME__ === 'string'\n ? __OPTIMIZATION_PACKAGE_NAME__\n : '@contentful/optimization-node'\n\n/**\n * Re-exports of anonymous identifier constants used by the Optimization Core.\n *\n * @remarks\n * This constant is surfaced here to provide a stable import path for Node SDK\n * consumers. It represents the cookie key used by the Optimization Framework\n * to persist an anonymous identifier for tracking optimization and insights\n * events when no explicit profile is known.\n *\n * @example\n * ```ts\n * import { ANONYMOUS_ID_COOKIE, ANONYMOUS_ID_KEY } from '@contentful/optimization-node/constants'\n * const cookieId = request.cookies[ANONYMOUS_ID_COOKIE]\n * const storageId = localStorage.getItem(ANONYMOUS_ID_KEY)\n * ```\n *\n * @see {@link ANONYMOUS_ID_COOKIE} and {@link ANONYMOUS_ID_KEY} in\n * `@contentful/optimization-core` for the\n * authoritative definition and documentation.\n *\n * @public\n */\nexport { ANONYMOUS_ID_COOKIE, ANONYMOUS_ID_KEY } from '@contentful/optimization-core/constants'\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import {\n CoreStateless,\n normalizeLocale,\n resolveContentfulLocale,\n type CoreStatelessConfig,\n type EventType,\n} from '@contentful/optimization-core'\nimport type { App } from '@contentful/optimization-core/api-schemas'\nimport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\n\nconst DEFAULT_RUNTIME_LOCALE = 'en-US'\nconst DEFAULT_ACCEPT_LANGUAGE_QUALITY = 1\nconst QUALITY_PARAM_PATTERN = /;\\s*q=/\nconst DEFAULT_NODE_ALLOWED_EVENT_TYPES: EventType[] = ['identify', 'page']\n\ntype NodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app'>>\ntype PublicNodeEventBuilderConfig = Omit<NodeEventBuilderConfig, 'getConsent'>\n\ninterface HeaderRequestLike {\n acceptsLanguages?: () => string[]\n get?: (name: string) => string | null | undefined\n headers?: unknown\n}\n\n/**\n * Locale pair resolved from an incoming server request.\n *\n * @public\n */\nexport interface ResolvedRequestLocale {\n /** Locale to place on SDK event context. */\n readonly eventLocale: string\n /** Contentful locale to use for CDA fetches and Experience API request options, when configured. */\n readonly contentfulLocale?: string\n}\n\n/**\n * Accepted inputs for {@link ContentfulOptimization.resolveRequestLocale}.\n *\n * @public\n */\nexport type RequestLocaleInput = string | null | undefined | HeaderRequestLike\n\n/**\n * Configuration for the Node-specific ContentfulOptimization SDK.\n *\n * @remarks\n * This configuration extends {@link CoreStatelessConfig} but allows partial\n * overrides of the event-builder configuration. SDKs commonly inject their own\n * library metadata or channel definitions.\n *\n * @see {@link CoreStatelessConfig}\n *\n * @public\n */\nexport interface OptimizationNodeConfig extends Omit<CoreStatelessConfig, 'eventBuilder'> {\n /**\n * The application definition used to attribute events to a specific consumer app.\n *\n * @remarks\n * When not provided, events will not contain app metadata in their context.\n */\n app?: App\n\n /**\n * Partial overrides for the event builder configuration.\n *\n * @remarks\n * Any provided fields are merged with the default Node SDK metadata.\n * Request-scoped consent should be bound with `forRequest()`, not configured\n * on the SDK singleton.\n *\n * This differs from {@link CoreStatelessConfig} eventBuilder, which expects\n * a full configuration object.\n */\n eventBuilder?: PublicNodeEventBuilderConfig\n}\n\nfunction normalizeHeaderValue(header: unknown): string | undefined {\n if (typeof header === 'string') {\n return header\n }\n\n return Array.isArray(header)\n ? header.filter((item): item is string => typeof item === 'string').join(',')\n : undefined\n}\n\nfunction getAcceptLanguageHeader(input: RequestLocaleInput): string | undefined {\n if (typeof input === 'string') {\n return input\n }\n\n if (typeof input !== 'object' || input === null) {\n return undefined\n }\n\n const headerFromGetter = input.get?.('accept-language')\n\n if (typeof headerFromGetter === 'string') {\n return headerFromGetter\n }\n\n const { headers } = input\n\n if (typeof headers !== 'object' || headers === null) {\n return undefined\n }\n\n const get: unknown = Reflect.get(headers, 'get')\n const header: unknown =\n typeof get === 'function'\n ? Reflect.apply(get, headers, ['accept-language'])\n : (Reflect.get(headers, 'accept-language') ?? Reflect.get(headers, 'Accept-Language'))\n\n return normalizeHeaderValue(header)\n}\n\nfunction parseAcceptLanguage(acceptLanguage: string | undefined): string[] {\n const candidates: Array<{ index: number; locale: string; quality: number }> = []\n\n for (const [index, value] of (acceptLanguage ?? '').split(',').entries()) {\n const [rawLocale, rawQuality] = value.split(QUALITY_PARAM_PATTERN)\n const locale = normalizeLocale(rawLocale)\n\n if (locale === undefined) {\n continue\n }\n\n const parsedQuality =\n rawQuality === undefined ? DEFAULT_ACCEPT_LANGUAGE_QUALITY : Number(rawQuality)\n const quality = Number.isFinite(parsedQuality) ? parsedQuality : DEFAULT_ACCEPT_LANGUAGE_QUALITY\n\n if (quality > 0) {\n candidates.push({ index, locale, quality })\n }\n }\n\n return candidates\n .sort((left, right) => right.quality - left.quality || left.index - right.index)\n .map((candidate) => candidate.locale)\n}\n\nfunction getRequestLocaleCandidates(input: RequestLocaleInput): string[] {\n const parsedHeaderLocales = parseAcceptLanguage(getAcceptLanguageHeader(input))\n\n if (parsedHeaderLocales.length > 0) {\n return parsedHeaderLocales\n }\n\n if (typeof input !== 'object' || input === null) {\n return []\n }\n\n return (\n input\n .acceptsLanguages?.()\n .map(normalizeLocale)\n .filter((locale): locale is string => locale !== undefined) ?? []\n )\n}\n\n/**\n * Node-specific ContentfulOptimization SDK built on {@link CoreStateless}.\n *\n * @remarks\n * This class adapts the stateless ContentfulOptimization Core for Node runtimes by\n * applying environment-appropriate defaults (e.g., server channel, Node SDK\n * library metadata). No core runtime behavior is modified; only configuration\n * defaults differ.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const sdk = new ContentfulOptimization({\n * clientId: 'abc-123',\n * environment: 'main',\n * logLevel: 'info',\n * })\n *\n * const requestOptimization = sdk.forRequest({\n * consent: true,\n * experienceOptions: { locale: 'fr-CA' },\n * profile: { id: 'profile-id' },\n * })\n *\n * await requestOptimization.page()\n * ```\n *\n * @see {@link CoreStateless}\n *\n * @public\n */\nclass ContentfulOptimization extends CoreStateless {\n /**\n * Create an instance of the Node SDK with merged defaults.\n *\n * @param config - Partial Node-specific configuration. Any eventBuilder\n * fields provided are merged with Node's defaults.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const optimization = new ContentfulOptimization({ clientId: 'my-client-id' })\n * ```\n */\n constructor({ app, allowedEventTypes, eventBuilder, ...config }: OptimizationNodeConfig) {\n const {\n library,\n getConsent: _getConsent,\n ...eventBuilderConfig\n } = (eventBuilder ?? {}) as NodeEventBuilderConfig\n\n super({\n ...config,\n allowedEventTypes: allowedEventTypes ?? DEFAULT_NODE_ALLOWED_EVENT_TYPES,\n eventBuilder: {\n app,\n channel: 'server',\n library: {\n name: OPTIMIZATION_NODE_SDK_NAME,\n version: OPTIMIZATION_NODE_SDK_VERSION,\n ...library,\n },\n getConsent: () => false,\n ...eventBuilderConfig,\n },\n })\n }\n\n /**\n * Resolve request and Contentful locales from `Accept-Language`.\n *\n * @param input - Raw `Accept-Language` header or a request-like object.\n * @returns Event-context locale and Contentful CDA locale.\n *\n * @example\n * ```ts\n * const { eventLocale, contentfulLocale } = optimization.resolveRequestLocale(req)\n * ```\n */\n resolveRequestLocale(input: RequestLocaleInput): ResolvedRequestLocale {\n const candidates = getRequestLocaleCandidates(input)\n const eventLocale = candidates[0] ?? DEFAULT_RUNTIME_LOCALE\n const contentfulLocale =\n resolveContentfulLocale({\n candidates,\n contentfulLocales: this.config.contentfulLocales,\n }) ?? this.locale\n\n return contentfulLocale === undefined ? { eventLocale } : { eventLocale, contentfulLocale }\n }\n}\n\nexport default ContentfulOptimization\n","/**\n * Contentful ContentfulOptimization Node SDK.\n *\n * @remarks\n * Adds Node-specific defaults via the {@link ContentfulOptimization} class.\n * Core and transitive API exports are available from dedicated entrypoints:\n * `@contentful/optimization-node/core-sdk`,\n * `@contentful/optimization-node/api-client`,\n * and `@contentful/optimization-node/api-schemas`.\n *\n * @packageDocumentation\n */\n\nimport ContentfulOptimization from './ContentfulOptimization'\n\nexport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\nexport * from './ContentfulOptimization'\n\nexport default ContentfulOptimization\n"],"names":["OPTIMIZATION_NODE_SDK_VERSION","__OPTIMIZATION_VERSION__","OPTIMIZATION_NODE_SDK_NAME","__OPTIMIZATION_PACKAGE_NAME__","__webpack_require__","definition","key","Object","obj","prop","Symbol","DEFAULT_RUNTIME_LOCALE","DEFAULT_ACCEPT_LANGUAGE_QUALITY","QUALITY_PARAM_PATTERN","DEFAULT_NODE_ALLOWED_EVENT_TYPES","normalizeHeaderValue","header","Array","item","undefined","getAcceptLanguageHeader","input","headerFromGetter","headers","get","Reflect","parseAcceptLanguage","acceptLanguage","candidates","index","value","rawLocale","rawQuality","locale","normalizeLocale","parsedQuality","Number","quality","left","right","candidate","getRequestLocaleCandidates","parsedHeaderLocales","ContentfulOptimization","CoreStateless","app","allowedEventTypes","eventBuilder","config","library","_getConsent","eventBuilderConfig","eventLocale","contentfulLocale","resolveContentfulLocale"],"mappings":";;;;;;;;QAYO,MAAMA,gCACoCC;QAS1C,MAAMC,6BAEPC;;;;;;;;;;;;;;ICxBNC,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,MAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;ICIA,MAAMI,yBAAyB;IAC/B,MAAMC,kCAAkC;IACxC,MAAMC,wBAAwB;IAC9B,MAAMC,mCAAgD;QAAC;QAAY;KAAO;IAiE1E,SAASC,qBAAqBC,MAAe;QAC3C,IAAI,AAAkB,YAAlB,OAAOA,QACT,OAAOA;QAGT,OAAOC,MAAM,OAAO,CAACD,UACjBA,OAAO,MAAM,CAAC,CAACE,OAAyB,AAAgB,YAAhB,OAAOA,MAAmB,IAAI,CAAC,OACvEC;IACN;IAEA,SAASC,wBAAwBC,KAAyB;QACxD,IAAI,AAAiB,YAAjB,OAAOA,OACT,OAAOA;QAGT,IAAI,AAAiB,YAAjB,OAAOA,SAAsBA,AAAU,SAAVA,OAC/B;QAGF,MAAMC,mBAAmBD,MAAM,GAAG,GAAG;QAErC,IAAI,AAA4B,YAA5B,OAAOC,kBACT,OAAOA;QAGT,MAAM,EAAEC,OAAO,EAAE,GAAGF;QAEpB,IAAI,AAAmB,YAAnB,OAAOE,WAAwBA,AAAY,SAAZA,SACjC;QAGF,MAAMC,MAAeC,QAAQ,GAAG,CAACF,SAAS;QAC1C,MAAMP,SACJ,AAAe,cAAf,OAAOQ,MACHC,QAAQ,KAAK,CAACD,KAAKD,SAAS;YAAC;SAAkB,IAC9CE,QAAQ,GAAG,CAACF,SAAS,sBAAsBE,QAAQ,GAAG,CAACF,SAAS;QAEvE,OAAOR,qBAAqBC;IAC9B;IAEA,SAASU,oBAAoBC,cAAkC;QAC7D,MAAMC,aAAwE,EAAE;QAEhF,KAAK,MAAM,CAACC,OAAOC,MAAM,IAAKH,AAAAA,CAAAA,kBAAkB,EAAC,EAAG,KAAK,CAAC,KAAK,OAAO,GAAI;YACxE,MAAM,CAACI,WAAWC,WAAW,GAAGF,MAAM,KAAK,CAACjB;YAC5C,MAAMoB,SAASC,AAAAA,IAAAA,kCAAAA,eAAAA,AAAAA,EAAgBH;YAE/B,IAAIE,AAAWd,WAAXc,QACF;YAGF,MAAME,gBACJH,AAAeb,WAAfa,aAA2BpB,kCAAkCwB,OAAOJ;YACtE,MAAMK,UAAUD,OAAO,QAAQ,CAACD,iBAAiBA,gBAAgBvB;YAEjE,IAAIyB,UAAU,GACZT,WAAW,IAAI,CAAC;gBAAEC;gBAAOI;gBAAQI;YAAQ;QAE7C;QAEA,OAAOT,WACJ,IAAI,CAAC,CAACU,MAAMC,QAAUA,MAAM,OAAO,GAAGD,KAAK,OAAO,IAAIA,KAAK,KAAK,GAAGC,MAAM,KAAK,EAC9E,GAAG,CAAC,CAACC,YAAcA,UAAU,MAAM;IACxC;IAEA,SAASC,2BAA2BpB,KAAyB;QAC3D,MAAMqB,sBAAsBhB,oBAAoBN,wBAAwBC;QAExE,IAAIqB,oBAAoB,MAAM,GAAG,GAC/B,OAAOA;QAGT,IAAI,AAAiB,YAAjB,OAAOrB,SAAsBA,AAAU,SAAVA,OAC/B,OAAO,EAAE;QAGX,OACEA,MACG,gBAAgB,KAChB,IAAIa,kCAAAA,eAAeA,EACnB,OAAO,CAACD,SAA6BA,AAAWd,WAAXc,WAAyB,EAAE;IAEvE;IAkCA,MAAMU,+BAA+BC,kCAAAA,aAAaA;QAchD,YAAY,EAAEC,GAAG,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGC,QAAgC,CAAE;YACvF,MAAM,EACJC,OAAO,EACP,YAAYC,WAAW,EACvB,GAAGC,oBACJ,GAAIJ,gBAAgB,CAAC;YAEtB,KAAK,CAAC;gBACJ,GAAGC,MAAM;gBACT,mBAAmBF,qBAAqBhC;gBACxC,cAAc;oBACZ+B;oBACA,SAAS;oBACT,SAAS;wBACP,MAAM3C,UAAAA,0BAA0BA;wBAChC,SAASF,UAAAA,6BAA6BA;wBACtC,GAAGiD,OAAO;oBACZ;oBACA,YAAY,IAAM;oBAClB,GAAGE,kBAAkB;gBACvB;YACF;QACF;QAaA,qBAAqB9B,KAAyB,EAAyB;YACrE,MAAMO,aAAaa,2BAA2BpB;YAC9C,MAAM+B,cAAcxB,UAAU,CAAC,EAAE,IAAIjB;YACrC,MAAM0C,mBACJC,AAAAA,IAAAA,kCAAAA,uBAAAA,AAAAA,EAAwB;gBACtB1B;gBACA,mBAAmB,IAAI,CAAC,MAAM,CAAC,iBAAiB;YAClD,MAAM,IAAI,CAAC,MAAM;YAEnB,OAAOyB,AAAqBlC,WAArBkC,mBAAiC;gBAAED;YAAY,IAAI;gBAAEA;gBAAaC;YAAiB;QAC5F;IACF;IAEA,mCAAeV;IC9Of,YAAeA"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/constants.ts","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../src/ContentfulOptimization.ts","../src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/naming-convention -- Replaced at build-time\ndeclare const __OPTIMIZATION_VERSION__: string | undefined\n// eslint-disable-next-line @typescript-eslint/naming-convention -- Replaced at build-time\ndeclare const __OPTIMIZATION_PACKAGE_NAME__: string | undefined\n\n/**\n * The current version of the Optimization Node SDK, injected at build-time.\n *\n * @defaultValue `'0.0.0'` when the build-time replacement is unavailable.\n *\n * @public\n */\nexport const OPTIMIZATION_NODE_SDK_VERSION =\n typeof __OPTIMIZATION_VERSION__ === 'string' ? __OPTIMIZATION_VERSION__ : '0.0.0'\n\n/**\n * The package name of the Optimization Node SDK, injected at build-time.\n *\n * @defaultValue `'@contentful/optimization-node'` when the build-time replacement is unavailable.\n *\n * @public\n */\nexport const OPTIMIZATION_NODE_SDK_NAME =\n typeof __OPTIMIZATION_PACKAGE_NAME__ === 'string'\n ? __OPTIMIZATION_PACKAGE_NAME__\n : '@contentful/optimization-node'\n\n/**\n * Re-exports of anonymous identifier constants used by the Optimization Core.\n *\n * @remarks\n * This constant is surfaced here to provide a stable import path for Node SDK\n * consumers. It represents the cookie key used by the Optimization Framework\n * to persist an anonymous identifier for tracking optimization and insights\n * events when no explicit profile is known.\n *\n * @example\n * ```ts\n * import { ANONYMOUS_ID_COOKIE, ANONYMOUS_ID_KEY } from '@contentful/optimization-node/constants'\n * const cookieId = request.cookies[ANONYMOUS_ID_COOKIE]\n * const storageId = localStorage.getItem(ANONYMOUS_ID_KEY)\n * ```\n *\n * @see {@link ANONYMOUS_ID_COOKIE} and {@link ANONYMOUS_ID_KEY} in\n * `@contentful/optimization-core` for the\n * authoritative definition and documentation.\n *\n * @public\n */\nexport { ANONYMOUS_ID_COOKIE, ANONYMOUS_ID_KEY } from '@contentful/optimization-core/constants'\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import {\n CoreStateless,\n type CoreStatelessConfig,\n type EventType,\n} from '@contentful/optimization-core'\nimport type { App } from '@contentful/optimization-core/api-schemas'\nimport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\n\nconst DEFAULT_NODE_ALLOWED_EVENT_TYPES: EventType[] = ['identify', 'page']\n\ntype NodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app'>>\n\n/**\n * Public Node event-builder overrides accepted by {@link OptimizationNodeConfig.eventBuilder}.\n *\n * @remarks\n * Request-scoped consent is bound with {@link ContentfulOptimization.forRequest}, so `getConsent`\n * is intentionally omitted from singleton SDK configuration.\n *\n * @public\n */\nexport type PublicNodeEventBuilderConfig = Partial<\n Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app' | 'getConsent'>\n>\n\n/**\n * Configuration for the Node-specific ContentfulOptimization SDK.\n *\n * @remarks\n * This configuration extends {@link CoreStatelessConfig} but allows partial\n * overrides of the event-builder configuration. SDKs commonly inject their own\n * library metadata or channel definitions.\n *\n * @see {@link CoreStatelessConfig}\n *\n * @public\n */\nexport interface OptimizationNodeConfig extends Omit<CoreStatelessConfig, 'eventBuilder'> {\n /**\n * The application definition used to attribute events to a specific consumer app.\n *\n * @remarks\n * When not provided, events will not contain app metadata in their context.\n */\n app?: App\n\n /**\n * Partial overrides for the event builder configuration.\n *\n * @remarks\n * Any provided fields are merged with the default Node SDK metadata.\n * Request-scoped consent should be bound with `forRequest()`, not configured\n * on the SDK singleton.\n *\n * This differs from {@link CoreStatelessConfig} eventBuilder, which expects\n * a full configuration object.\n */\n eventBuilder?: PublicNodeEventBuilderConfig\n}\n\n/**\n * Node-specific ContentfulOptimization SDK built on {@link CoreStateless}.\n *\n * @remarks\n * This class adapts the stateless ContentfulOptimization Core for Node runtimes by\n * applying environment-appropriate defaults (e.g., server channel, Node SDK\n * library metadata). No core runtime behavior is modified; only configuration\n * defaults differ.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const sdk = new ContentfulOptimization({\n * clientId: 'abc-123',\n * environment: 'main',\n * logLevel: 'info',\n * })\n *\n * const requestOptimization = sdk.forRequest({\n * consent: true,\n * locale: 'fr-CA',\n * profile: { id: 'profile-id' },\n * })\n *\n * const { accepted, data } = await requestOptimization.page()\n * ```\n *\n * @see {@link CoreStateless}\n *\n * @public\n */\nclass ContentfulOptimization extends CoreStateless {\n /**\n * Create an instance of the Node SDK with merged defaults.\n *\n * @param config - Partial Node-specific configuration. Any eventBuilder\n * fields provided are merged with Node's defaults.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const optimization = new ContentfulOptimization({ clientId: 'my-client-id' })\n * ```\n */\n constructor({ app, allowedEventTypes, eventBuilder, ...config }: OptimizationNodeConfig) {\n const {\n library,\n getConsent: _getConsent,\n ...eventBuilderConfig\n } = (eventBuilder ?? {}) as NodeEventBuilderConfig\n\n super({\n ...config,\n allowedEventTypes: allowedEventTypes ?? DEFAULT_NODE_ALLOWED_EVENT_TYPES,\n eventBuilder: {\n app,\n channel: 'server',\n library: {\n name: OPTIMIZATION_NODE_SDK_NAME,\n version: OPTIMIZATION_NODE_SDK_VERSION,\n ...library,\n },\n getConsent: () => false,\n ...eventBuilderConfig,\n },\n })\n }\n}\n\nexport default ContentfulOptimization\n","/**\n * Contentful ContentfulOptimization Node SDK.\n *\n * @remarks\n * Adds Node-specific defaults via the {@link ContentfulOptimization} class.\n * Core and transitive API exports are available from dedicated entrypoints:\n * `@contentful/optimization-node/core-sdk`,\n * `@contentful/optimization-node/api-client`,\n * and `@contentful/optimization-node/api-schemas`.\n *\n * @packageDocumentation\n */\n\nimport ContentfulOptimization from './ContentfulOptimization'\n\nexport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\nexport * from './ContentfulOptimization'\n\nexport default ContentfulOptimization\n"],"names":["OPTIMIZATION_NODE_SDK_VERSION","__OPTIMIZATION_VERSION__","OPTIMIZATION_NODE_SDK_NAME","__OPTIMIZATION_PACKAGE_NAME__","__webpack_require__","definition","key","Object","obj","prop","Symbol","DEFAULT_NODE_ALLOWED_EVENT_TYPES","ContentfulOptimization","CoreStateless","app","allowedEventTypes","eventBuilder","config","library","_getConsent","eventBuilderConfig"],"mappings":";;;;;;;;QAYO,MAAMA,gCACoCC;QAS1C,MAAMC,6BAEPC;;;;;;;;;;;;;;ICxBNC,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,MAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;ICEA,MAAMI,mCAAgD;QAAC;QAAY;KAAO;IAoF1E,MAAMC,+BAA+BC,kCAAAA,aAAaA;QAchD,YAAY,EAAEC,GAAG,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGC,QAAgC,CAAE;YACvF,MAAM,EACJC,OAAO,EACP,YAAYC,WAAW,EACvB,GAAGC,oBACJ,GAAIJ,gBAAgB,CAAC;YAEtB,KAAK,CAAC;gBACJ,GAAGC,MAAM;gBACT,mBAAmBF,qBAAqBJ;gBACxC,cAAc;oBACZG;oBACA,SAAS;oBACT,SAAS;wBACP,MAAMZ,UAAAA,0BAA0BA;wBAChC,SAASF,UAAAA,6BAA6BA;wBACtC,GAAGkB,OAAO;oBACZ;oBACA,YAAY,IAAM;oBAClB,GAAGE,kBAAkB;gBACvB;YACF;QACF;IACF;IAEA,mCAAeR;ICjHf,YAAeA"}
package/dist/index.d.cts CHANGED
@@ -36,11 +36,11 @@ import { CoreStatelessConfig } from '@contentful/optimization-core';
36
36
  *
37
37
  * const requestOptimization = sdk.forRequest({
38
38
  * consent: true,
39
- * experienceOptions: { locale: 'fr-CA' },
39
+ * locale: 'fr-CA',
40
40
  * profile: { id: 'profile-id' },
41
41
  * })
42
42
  *
43
- * await requestOptimization.page()
43
+ * const { accepted, data } = await requestOptimization.page()
44
44
  * ```
45
45
  *
46
46
  * @see {@link CoreStateless}
@@ -62,29 +62,9 @@ declare class ContentfulOptimization extends CoreStateless {
62
62
  * ```
63
63
  */
64
64
  constructor({ app, allowedEventTypes, eventBuilder, ...config }: OptimizationNodeConfig);
65
- /**
66
- * Resolve request and Contentful locales from `Accept-Language`.
67
- *
68
- * @param input - Raw `Accept-Language` header or a request-like object.
69
- * @returns Event-context locale and Contentful CDA locale.
70
- *
71
- * @example
72
- * ```ts
73
- * const { eventLocale, contentfulLocale } = optimization.resolveRequestLocale(req)
74
- * ```
75
- */
76
- resolveRequestLocale(input: RequestLocaleInput): ResolvedRequestLocale;
77
65
  }
78
66
  export default ContentfulOptimization;
79
67
 
80
- declare interface HeaderRequestLike {
81
- acceptsLanguages?: () => string[];
82
- get?: (name: string) => string | null | undefined;
83
- headers?: unknown;
84
- }
85
-
86
- declare type NodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app'>>;
87
-
88
68
  /**
89
69
  * The package name of the Optimization Node SDK, injected at build-time.
90
70
  *
@@ -137,25 +117,15 @@ export declare interface OptimizationNodeConfig extends Omit<CoreStatelessConfig
137
117
  eventBuilder?: PublicNodeEventBuilderConfig;
138
118
  }
139
119
 
140
- declare type PublicNodeEventBuilderConfig = Omit<NodeEventBuilderConfig, 'getConsent'>;
141
-
142
120
  /**
143
- * Accepted inputs for {@link ContentfulOptimization.resolveRequestLocale}.
121
+ * Public Node event-builder overrides accepted by {@link OptimizationNodeConfig.eventBuilder}.
144
122
  *
145
- * @public
146
- */
147
- export declare type RequestLocaleInput = string | null | undefined | HeaderRequestLike;
148
-
149
- /**
150
- * Locale pair resolved from an incoming server request.
123
+ * @remarks
124
+ * Request-scoped consent is bound with {@link ContentfulOptimization.forRequest}, so `getConsent`
125
+ * is intentionally omitted from singleton SDK configuration.
151
126
  *
152
127
  * @public
153
128
  */
154
- export declare interface ResolvedRequestLocale {
155
- /** Locale to place on SDK event context. */
156
- readonly eventLocale: string;
157
- /** Contentful locale to use for CDA fetches and Experience API request options, when configured. */
158
- readonly contentfulLocale?: string;
159
- }
129
+ export declare type PublicNodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app' | 'getConsent'>>;
160
130
 
161
131
  export { }
package/dist/index.d.mts CHANGED
@@ -36,11 +36,11 @@ import { CoreStatelessConfig } from '@contentful/optimization-core';
36
36
  *
37
37
  * const requestOptimization = sdk.forRequest({
38
38
  * consent: true,
39
- * experienceOptions: { locale: 'fr-CA' },
39
+ * locale: 'fr-CA',
40
40
  * profile: { id: 'profile-id' },
41
41
  * })
42
42
  *
43
- * await requestOptimization.page()
43
+ * const { accepted, data } = await requestOptimization.page()
44
44
  * ```
45
45
  *
46
46
  * @see {@link CoreStateless}
@@ -62,29 +62,9 @@ declare class ContentfulOptimization extends CoreStateless {
62
62
  * ```
63
63
  */
64
64
  constructor({ app, allowedEventTypes, eventBuilder, ...config }: OptimizationNodeConfig);
65
- /**
66
- * Resolve request and Contentful locales from `Accept-Language`.
67
- *
68
- * @param input - Raw `Accept-Language` header or a request-like object.
69
- * @returns Event-context locale and Contentful CDA locale.
70
- *
71
- * @example
72
- * ```ts
73
- * const { eventLocale, contentfulLocale } = optimization.resolveRequestLocale(req)
74
- * ```
75
- */
76
- resolveRequestLocale(input: RequestLocaleInput): ResolvedRequestLocale;
77
65
  }
78
66
  export default ContentfulOptimization;
79
67
 
80
- declare interface HeaderRequestLike {
81
- acceptsLanguages?: () => string[];
82
- get?: (name: string) => string | null | undefined;
83
- headers?: unknown;
84
- }
85
-
86
- declare type NodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app'>>;
87
-
88
68
  /**
89
69
  * The package name of the Optimization Node SDK, injected at build-time.
90
70
  *
@@ -137,25 +117,15 @@ export declare interface OptimizationNodeConfig extends Omit<CoreStatelessConfig
137
117
  eventBuilder?: PublicNodeEventBuilderConfig;
138
118
  }
139
119
 
140
- declare type PublicNodeEventBuilderConfig = Omit<NodeEventBuilderConfig, 'getConsent'>;
141
-
142
120
  /**
143
- * Accepted inputs for {@link ContentfulOptimization.resolveRequestLocale}.
121
+ * Public Node event-builder overrides accepted by {@link OptimizationNodeConfig.eventBuilder}.
144
122
  *
145
- * @public
146
- */
147
- export declare type RequestLocaleInput = string | null | undefined | HeaderRequestLike;
148
-
149
- /**
150
- * Locale pair resolved from an incoming server request.
123
+ * @remarks
124
+ * Request-scoped consent is bound with {@link ContentfulOptimization.forRequest}, so `getConsent`
125
+ * is intentionally omitted from singleton SDK configuration.
151
126
  *
152
127
  * @public
153
128
  */
154
- export declare interface ResolvedRequestLocale {
155
- /** Locale to place on SDK event context. */
156
- readonly eventLocale: string;
157
- /** Contentful locale to use for CDA fetches and Experience API request options, when configured. */
158
- readonly contentfulLocale?: string;
159
- }
129
+ export declare type PublicNodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app' | 'getConsent'>>;
160
130
 
161
131
  export { }
package/dist/index.d.ts CHANGED
@@ -36,11 +36,11 @@ import { CoreStatelessConfig } from '@contentful/optimization-core';
36
36
  *
37
37
  * const requestOptimization = sdk.forRequest({
38
38
  * consent: true,
39
- * experienceOptions: { locale: 'fr-CA' },
39
+ * locale: 'fr-CA',
40
40
  * profile: { id: 'profile-id' },
41
41
  * })
42
42
  *
43
- * await requestOptimization.page()
43
+ * const { accepted, data } = await requestOptimization.page()
44
44
  * ```
45
45
  *
46
46
  * @see {@link CoreStateless}
@@ -62,29 +62,9 @@ declare class ContentfulOptimization extends CoreStateless {
62
62
  * ```
63
63
  */
64
64
  constructor({ app, allowedEventTypes, eventBuilder, ...config }: OptimizationNodeConfig);
65
- /**
66
- * Resolve request and Contentful locales from `Accept-Language`.
67
- *
68
- * @param input - Raw `Accept-Language` header or a request-like object.
69
- * @returns Event-context locale and Contentful CDA locale.
70
- *
71
- * @example
72
- * ```ts
73
- * const { eventLocale, contentfulLocale } = optimization.resolveRequestLocale(req)
74
- * ```
75
- */
76
- resolveRequestLocale(input: RequestLocaleInput): ResolvedRequestLocale;
77
65
  }
78
66
  export default ContentfulOptimization;
79
67
 
80
- declare interface HeaderRequestLike {
81
- acceptsLanguages?: () => string[];
82
- get?: (name: string) => string | null | undefined;
83
- headers?: unknown;
84
- }
85
-
86
- declare type NodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app'>>;
87
-
88
68
  /**
89
69
  * The package name of the Optimization Node SDK, injected at build-time.
90
70
  *
@@ -137,25 +117,15 @@ export declare interface OptimizationNodeConfig extends Omit<CoreStatelessConfig
137
117
  eventBuilder?: PublicNodeEventBuilderConfig;
138
118
  }
139
119
 
140
- declare type PublicNodeEventBuilderConfig = Omit<NodeEventBuilderConfig, 'getConsent'>;
141
-
142
120
  /**
143
- * Accepted inputs for {@link ContentfulOptimization.resolveRequestLocale}.
121
+ * Public Node event-builder overrides accepted by {@link OptimizationNodeConfig.eventBuilder}.
144
122
  *
145
- * @public
146
- */
147
- export declare type RequestLocaleInput = string | null | undefined | HeaderRequestLike;
148
-
149
- /**
150
- * Locale pair resolved from an incoming server request.
123
+ * @remarks
124
+ * Request-scoped consent is bound with {@link ContentfulOptimization.forRequest}, so `getConsent`
125
+ * is intentionally omitted from singleton SDK configuration.
151
126
  *
152
127
  * @public
153
128
  */
154
- export declare interface ResolvedRequestLocale {
155
- /** Locale to place on SDK event context. */
156
- readonly eventLocale: string;
157
- /** Contentful locale to use for CDA fetches and Experience API request options, when configured. */
158
- readonly contentfulLocale?: string;
159
- }
129
+ export declare type PublicNodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app' | 'getConsent'>>;
160
130
 
161
131
  export { }
package/dist/index.mjs CHANGED
@@ -1,51 +1,9 @@
1
1
  import { __rspack_external__contentful_optimization_core_7d4758c6 } from "./987.mjs";
2
2
  import { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from "./260.mjs";
3
- const DEFAULT_RUNTIME_LOCALE = 'en-US';
4
- const DEFAULT_ACCEPT_LANGUAGE_QUALITY = 1;
5
- const QUALITY_PARAM_PATTERN = /;\s*q=/;
6
3
  const DEFAULT_NODE_ALLOWED_EVENT_TYPES = [
7
4
  'identify',
8
5
  'page'
9
6
  ];
10
- function normalizeHeaderValue(header) {
11
- if ('string' == typeof header) return header;
12
- return Array.isArray(header) ? header.filter((item)=>'string' == typeof item).join(',') : void 0;
13
- }
14
- function getAcceptLanguageHeader(input) {
15
- if ('string' == typeof input) return input;
16
- if ('object' != typeof input || null === input) return;
17
- const headerFromGetter = input.get?.('accept-language');
18
- if ('string' == typeof headerFromGetter) return headerFromGetter;
19
- const { headers } = input;
20
- if ('object' != typeof headers || null === headers) return;
21
- const get = Reflect.get(headers, 'get');
22
- const header = 'function' == typeof get ? Reflect.apply(get, headers, [
23
- 'accept-language'
24
- ]) : Reflect.get(headers, 'accept-language') ?? Reflect.get(headers, 'Accept-Language');
25
- return normalizeHeaderValue(header);
26
- }
27
- function parseAcceptLanguage(acceptLanguage) {
28
- const candidates = [];
29
- for (const [index, value] of (acceptLanguage ?? '').split(',').entries()){
30
- const [rawLocale, rawQuality] = value.split(QUALITY_PARAM_PATTERN);
31
- const locale = (0, __rspack_external__contentful_optimization_core_7d4758c6.normalizeLocale)(rawLocale);
32
- if (void 0 === locale) continue;
33
- const parsedQuality = void 0 === rawQuality ? DEFAULT_ACCEPT_LANGUAGE_QUALITY : Number(rawQuality);
34
- const quality = Number.isFinite(parsedQuality) ? parsedQuality : DEFAULT_ACCEPT_LANGUAGE_QUALITY;
35
- if (quality > 0) candidates.push({
36
- index,
37
- locale,
38
- quality
39
- });
40
- }
41
- return candidates.sort((left, right)=>right.quality - left.quality || left.index - right.index).map((candidate)=>candidate.locale);
42
- }
43
- function getRequestLocaleCandidates(input) {
44
- const parsedHeaderLocales = parseAcceptLanguage(getAcceptLanguageHeader(input));
45
- if (parsedHeaderLocales.length > 0) return parsedHeaderLocales;
46
- if ('object' != typeof input || null === input) return [];
47
- return input.acceptsLanguages?.().map(__rspack_external__contentful_optimization_core_7d4758c6.normalizeLocale).filter((locale)=>void 0 !== locale) ?? [];
48
- }
49
7
  class ContentfulOptimization extends __rspack_external__contentful_optimization_core_7d4758c6.CoreStateless {
50
8
  constructor({ app, allowedEventTypes, eventBuilder, ...config }){
51
9
  const { library, getConsent: _getConsent, ...eventBuilderConfig } = eventBuilder ?? {};
@@ -65,20 +23,6 @@ class ContentfulOptimization extends __rspack_external__contentful_optimization_
65
23
  }
66
24
  });
67
25
  }
68
- resolveRequestLocale(input) {
69
- const candidates = getRequestLocaleCandidates(input);
70
- const eventLocale = candidates[0] ?? DEFAULT_RUNTIME_LOCALE;
71
- const contentfulLocale = (0, __rspack_external__contentful_optimization_core_7d4758c6.resolveContentfulLocale)({
72
- candidates,
73
- contentfulLocales: this.config.contentfulLocales
74
- }) ?? this.locale;
75
- return void 0 === contentfulLocale ? {
76
- eventLocale
77
- } : {
78
- eventLocale,
79
- contentfulLocale
80
- };
81
- }
82
26
  }
83
27
  const src_ContentfulOptimization = ContentfulOptimization;
84
28
  const src = src_ContentfulOptimization;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/ContentfulOptimization.ts","../src/index.ts"],"sourcesContent":["import {\n CoreStateless,\n normalizeLocale,\n resolveContentfulLocale,\n type CoreStatelessConfig,\n type EventType,\n} from '@contentful/optimization-core'\nimport type { App } from '@contentful/optimization-core/api-schemas'\nimport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\n\nconst DEFAULT_RUNTIME_LOCALE = 'en-US'\nconst DEFAULT_ACCEPT_LANGUAGE_QUALITY = 1\nconst QUALITY_PARAM_PATTERN = /;\\s*q=/\nconst DEFAULT_NODE_ALLOWED_EVENT_TYPES: EventType[] = ['identify', 'page']\n\ntype NodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app'>>\ntype PublicNodeEventBuilderConfig = Omit<NodeEventBuilderConfig, 'getConsent'>\n\ninterface HeaderRequestLike {\n acceptsLanguages?: () => string[]\n get?: (name: string) => string | null | undefined\n headers?: unknown\n}\n\n/**\n * Locale pair resolved from an incoming server request.\n *\n * @public\n */\nexport interface ResolvedRequestLocale {\n /** Locale to place on SDK event context. */\n readonly eventLocale: string\n /** Contentful locale to use for CDA fetches and Experience API request options, when configured. */\n readonly contentfulLocale?: string\n}\n\n/**\n * Accepted inputs for {@link ContentfulOptimization.resolveRequestLocale}.\n *\n * @public\n */\nexport type RequestLocaleInput = string | null | undefined | HeaderRequestLike\n\n/**\n * Configuration for the Node-specific ContentfulOptimization SDK.\n *\n * @remarks\n * This configuration extends {@link CoreStatelessConfig} but allows partial\n * overrides of the event-builder configuration. SDKs commonly inject their own\n * library metadata or channel definitions.\n *\n * @see {@link CoreStatelessConfig}\n *\n * @public\n */\nexport interface OptimizationNodeConfig extends Omit<CoreStatelessConfig, 'eventBuilder'> {\n /**\n * The application definition used to attribute events to a specific consumer app.\n *\n * @remarks\n * When not provided, events will not contain app metadata in their context.\n */\n app?: App\n\n /**\n * Partial overrides for the event builder configuration.\n *\n * @remarks\n * Any provided fields are merged with the default Node SDK metadata.\n * Request-scoped consent should be bound with `forRequest()`, not configured\n * on the SDK singleton.\n *\n * This differs from {@link CoreStatelessConfig} eventBuilder, which expects\n * a full configuration object.\n */\n eventBuilder?: PublicNodeEventBuilderConfig\n}\n\nfunction normalizeHeaderValue(header: unknown): string | undefined {\n if (typeof header === 'string') {\n return header\n }\n\n return Array.isArray(header)\n ? header.filter((item): item is string => typeof item === 'string').join(',')\n : undefined\n}\n\nfunction getAcceptLanguageHeader(input: RequestLocaleInput): string | undefined {\n if (typeof input === 'string') {\n return input\n }\n\n if (typeof input !== 'object' || input === null) {\n return undefined\n }\n\n const headerFromGetter = input.get?.('accept-language')\n\n if (typeof headerFromGetter === 'string') {\n return headerFromGetter\n }\n\n const { headers } = input\n\n if (typeof headers !== 'object' || headers === null) {\n return undefined\n }\n\n const get: unknown = Reflect.get(headers, 'get')\n const header: unknown =\n typeof get === 'function'\n ? Reflect.apply(get, headers, ['accept-language'])\n : (Reflect.get(headers, 'accept-language') ?? Reflect.get(headers, 'Accept-Language'))\n\n return normalizeHeaderValue(header)\n}\n\nfunction parseAcceptLanguage(acceptLanguage: string | undefined): string[] {\n const candidates: Array<{ index: number; locale: string; quality: number }> = []\n\n for (const [index, value] of (acceptLanguage ?? '').split(',').entries()) {\n const [rawLocale, rawQuality] = value.split(QUALITY_PARAM_PATTERN)\n const locale = normalizeLocale(rawLocale)\n\n if (locale === undefined) {\n continue\n }\n\n const parsedQuality =\n rawQuality === undefined ? DEFAULT_ACCEPT_LANGUAGE_QUALITY : Number(rawQuality)\n const quality = Number.isFinite(parsedQuality) ? parsedQuality : DEFAULT_ACCEPT_LANGUAGE_QUALITY\n\n if (quality > 0) {\n candidates.push({ index, locale, quality })\n }\n }\n\n return candidates\n .sort((left, right) => right.quality - left.quality || left.index - right.index)\n .map((candidate) => candidate.locale)\n}\n\nfunction getRequestLocaleCandidates(input: RequestLocaleInput): string[] {\n const parsedHeaderLocales = parseAcceptLanguage(getAcceptLanguageHeader(input))\n\n if (parsedHeaderLocales.length > 0) {\n return parsedHeaderLocales\n }\n\n if (typeof input !== 'object' || input === null) {\n return []\n }\n\n return (\n input\n .acceptsLanguages?.()\n .map(normalizeLocale)\n .filter((locale): locale is string => locale !== undefined) ?? []\n )\n}\n\n/**\n * Node-specific ContentfulOptimization SDK built on {@link CoreStateless}.\n *\n * @remarks\n * This class adapts the stateless ContentfulOptimization Core for Node runtimes by\n * applying environment-appropriate defaults (e.g., server channel, Node SDK\n * library metadata). No core runtime behavior is modified; only configuration\n * defaults differ.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const sdk = new ContentfulOptimization({\n * clientId: 'abc-123',\n * environment: 'main',\n * logLevel: 'info',\n * })\n *\n * const requestOptimization = sdk.forRequest({\n * consent: true,\n * experienceOptions: { locale: 'fr-CA' },\n * profile: { id: 'profile-id' },\n * })\n *\n * await requestOptimization.page()\n * ```\n *\n * @see {@link CoreStateless}\n *\n * @public\n */\nclass ContentfulOptimization extends CoreStateless {\n /**\n * Create an instance of the Node SDK with merged defaults.\n *\n * @param config - Partial Node-specific configuration. Any eventBuilder\n * fields provided are merged with Node's defaults.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const optimization = new ContentfulOptimization({ clientId: 'my-client-id' })\n * ```\n */\n constructor({ app, allowedEventTypes, eventBuilder, ...config }: OptimizationNodeConfig) {\n const {\n library,\n getConsent: _getConsent,\n ...eventBuilderConfig\n } = (eventBuilder ?? {}) as NodeEventBuilderConfig\n\n super({\n ...config,\n allowedEventTypes: allowedEventTypes ?? DEFAULT_NODE_ALLOWED_EVENT_TYPES,\n eventBuilder: {\n app,\n channel: 'server',\n library: {\n name: OPTIMIZATION_NODE_SDK_NAME,\n version: OPTIMIZATION_NODE_SDK_VERSION,\n ...library,\n },\n getConsent: () => false,\n ...eventBuilderConfig,\n },\n })\n }\n\n /**\n * Resolve request and Contentful locales from `Accept-Language`.\n *\n * @param input - Raw `Accept-Language` header or a request-like object.\n * @returns Event-context locale and Contentful CDA locale.\n *\n * @example\n * ```ts\n * const { eventLocale, contentfulLocale } = optimization.resolveRequestLocale(req)\n * ```\n */\n resolveRequestLocale(input: RequestLocaleInput): ResolvedRequestLocale {\n const candidates = getRequestLocaleCandidates(input)\n const eventLocale = candidates[0] ?? DEFAULT_RUNTIME_LOCALE\n const contentfulLocale =\n resolveContentfulLocale({\n candidates,\n contentfulLocales: this.config.contentfulLocales,\n }) ?? this.locale\n\n return contentfulLocale === undefined ? { eventLocale } : { eventLocale, contentfulLocale }\n }\n}\n\nexport default ContentfulOptimization\n","/**\n * Contentful ContentfulOptimization Node SDK.\n *\n * @remarks\n * Adds Node-specific defaults via the {@link ContentfulOptimization} class.\n * Core and transitive API exports are available from dedicated entrypoints:\n * `@contentful/optimization-node/core-sdk`,\n * `@contentful/optimization-node/api-client`,\n * and `@contentful/optimization-node/api-schemas`.\n *\n * @packageDocumentation\n */\n\nimport ContentfulOptimization from './ContentfulOptimization'\n\nexport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\nexport * from './ContentfulOptimization'\n\nexport default ContentfulOptimization\n"],"names":["DEFAULT_RUNTIME_LOCALE","DEFAULT_ACCEPT_LANGUAGE_QUALITY","QUALITY_PARAM_PATTERN","DEFAULT_NODE_ALLOWED_EVENT_TYPES","normalizeHeaderValue","header","Array","item","undefined","getAcceptLanguageHeader","input","headerFromGetter","headers","get","Reflect","parseAcceptLanguage","acceptLanguage","candidates","index","value","rawLocale","rawQuality","locale","normalizeLocale","parsedQuality","Number","quality","left","right","candidate","getRequestLocaleCandidates","parsedHeaderLocales","ContentfulOptimization","CoreStateless","app","allowedEventTypes","eventBuilder","config","library","_getConsent","eventBuilderConfig","OPTIMIZATION_NODE_SDK_NAME","OPTIMIZATION_NODE_SDK_VERSION","eventLocale","contentfulLocale","resolveContentfulLocale"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/ContentfulOptimization.ts","../src/index.ts"],"sourcesContent":["import {\n CoreStateless,\n type CoreStatelessConfig,\n type EventType,\n} from '@contentful/optimization-core'\nimport type { App } from '@contentful/optimization-core/api-schemas'\nimport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\n\nconst DEFAULT_NODE_ALLOWED_EVENT_TYPES: EventType[] = ['identify', 'page']\n\ntype NodeEventBuilderConfig = Partial<Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app'>>\n\n/**\n * Public Node event-builder overrides accepted by {@link OptimizationNodeConfig.eventBuilder}.\n *\n * @remarks\n * Request-scoped consent is bound with {@link ContentfulOptimization.forRequest}, so `getConsent`\n * is intentionally omitted from singleton SDK configuration.\n *\n * @public\n */\nexport type PublicNodeEventBuilderConfig = Partial<\n Omit<NonNullable<CoreStatelessConfig['eventBuilder']>, 'app' | 'getConsent'>\n>\n\n/**\n * Configuration for the Node-specific ContentfulOptimization SDK.\n *\n * @remarks\n * This configuration extends {@link CoreStatelessConfig} but allows partial\n * overrides of the event-builder configuration. SDKs commonly inject their own\n * library metadata or channel definitions.\n *\n * @see {@link CoreStatelessConfig}\n *\n * @public\n */\nexport interface OptimizationNodeConfig extends Omit<CoreStatelessConfig, 'eventBuilder'> {\n /**\n * The application definition used to attribute events to a specific consumer app.\n *\n * @remarks\n * When not provided, events will not contain app metadata in their context.\n */\n app?: App\n\n /**\n * Partial overrides for the event builder configuration.\n *\n * @remarks\n * Any provided fields are merged with the default Node SDK metadata.\n * Request-scoped consent should be bound with `forRequest()`, not configured\n * on the SDK singleton.\n *\n * This differs from {@link CoreStatelessConfig} eventBuilder, which expects\n * a full configuration object.\n */\n eventBuilder?: PublicNodeEventBuilderConfig\n}\n\n/**\n * Node-specific ContentfulOptimization SDK built on {@link CoreStateless}.\n *\n * @remarks\n * This class adapts the stateless ContentfulOptimization Core for Node runtimes by\n * applying environment-appropriate defaults (e.g., server channel, Node SDK\n * library metadata). No core runtime behavior is modified; only configuration\n * defaults differ.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const sdk = new ContentfulOptimization({\n * clientId: 'abc-123',\n * environment: 'main',\n * logLevel: 'info',\n * })\n *\n * const requestOptimization = sdk.forRequest({\n * consent: true,\n * locale: 'fr-CA',\n * profile: { id: 'profile-id' },\n * })\n *\n * const { accepted, data } = await requestOptimization.page()\n * ```\n *\n * @see {@link CoreStateless}\n *\n * @public\n */\nclass ContentfulOptimization extends CoreStateless {\n /**\n * Create an instance of the Node SDK with merged defaults.\n *\n * @param config - Partial Node-specific configuration. Any eventBuilder\n * fields provided are merged with Node's defaults.\n *\n * @example\n * ```ts\n * import ContentfulOptimization from '@contentful/optimization-node'\n *\n * const optimization = new ContentfulOptimization({ clientId: 'my-client-id' })\n * ```\n */\n constructor({ app, allowedEventTypes, eventBuilder, ...config }: OptimizationNodeConfig) {\n const {\n library,\n getConsent: _getConsent,\n ...eventBuilderConfig\n } = (eventBuilder ?? {}) as NodeEventBuilderConfig\n\n super({\n ...config,\n allowedEventTypes: allowedEventTypes ?? DEFAULT_NODE_ALLOWED_EVENT_TYPES,\n eventBuilder: {\n app,\n channel: 'server',\n library: {\n name: OPTIMIZATION_NODE_SDK_NAME,\n version: OPTIMIZATION_NODE_SDK_VERSION,\n ...library,\n },\n getConsent: () => false,\n ...eventBuilderConfig,\n },\n })\n }\n}\n\nexport default ContentfulOptimization\n","/**\n * Contentful ContentfulOptimization Node SDK.\n *\n * @remarks\n * Adds Node-specific defaults via the {@link ContentfulOptimization} class.\n * Core and transitive API exports are available from dedicated entrypoints:\n * `@contentful/optimization-node/core-sdk`,\n * `@contentful/optimization-node/api-client`,\n * and `@contentful/optimization-node/api-schemas`.\n *\n * @packageDocumentation\n */\n\nimport ContentfulOptimization from './ContentfulOptimization'\n\nexport { OPTIMIZATION_NODE_SDK_NAME, OPTIMIZATION_NODE_SDK_VERSION } from './constants'\nexport * from './ContentfulOptimization'\n\nexport default ContentfulOptimization\n"],"names":["DEFAULT_NODE_ALLOWED_EVENT_TYPES","ContentfulOptimization","CoreStateless","app","allowedEventTypes","eventBuilder","config","library","_getConsent","eventBuilderConfig","OPTIMIZATION_NODE_SDK_NAME","OPTIMIZATION_NODE_SDK_VERSION"],"mappings":";;AAQA,MAAMA,mCAAgD;IAAC;IAAY;CAAO;AAoF1E,MAAMC,+BAA+BC,yDAAAA,aAAaA;IAchD,YAAY,EAAEC,GAAG,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGC,QAAgC,CAAE;QACvF,MAAM,EACJC,OAAO,EACP,YAAYC,WAAW,EACvB,GAAGC,oBACJ,GAAIJ,gBAAgB,CAAC;QAEtB,KAAK,CAAC;YACJ,GAAGC,MAAM;YACT,mBAAmBF,qBAAqBJ;YACxC,cAAc;gBACZG;gBACA,SAAS;gBACT,SAAS;oBACP,MAAMO;oBACN,SAASC;oBACT,GAAGJ,OAAO;gBACZ;gBACA,YAAY,IAAM;gBAClB,GAAGE,kBAAkB;YACvB;QACF;IACF;AACF;AAEA,mCAAeR;ACjHf,YAAeA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/optimization-node",
3
- "version": "0.1.0-alpha14",
3
+ "version": "0.1.0-alpha15",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -75,7 +75,8 @@
75
75
  "./package.json": "./package.json"
76
76
  },
77
77
  "files": [
78
- "dist/**/*"
78
+ "dist/**/*",
79
+ "THIRD_PARTY_NOTICES.txt"
79
80
  ],
80
81
  "buildTools": {
81
82
  "bundleSize": {
@@ -87,6 +88,6 @@
87
88
  },
88
89
  "dependencies": {
89
90
  "es-toolkit": "^1.45.1",
90
- "@contentful/optimization-core": "0.1.0-alpha14"
91
+ "@contentful/optimization-core": "0.1.0-alpha15"
91
92
  }
92
93
  }