@contentful/optimization-node 0.1.0-alpha
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/LICENSE +21 -0
- package/README.md +289 -0
- package/dist/index.cjs +112 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.mjs +31 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +24 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2026 Contentful Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://www.contentful.com/developers/docs/personalization/">
|
|
3
|
+
<img alt="Contentful Logo" title="Contentful" src="../../../contentful-icon.png" width="150">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">Contentful Personalization & Analytics</h1>
|
|
8
|
+
|
|
9
|
+
<h3 align="center">Optimization Node SDK</h3>
|
|
10
|
+
|
|
11
|
+
<div align="center">
|
|
12
|
+
|
|
13
|
+
[Readme](./README.md) · [Reference](https://contentful.github.io/optimization) ·
|
|
14
|
+
[Contributing](/CONTRIBUTING.md)
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
> [!WARNING]
|
|
19
|
+
>
|
|
20
|
+
> The Optimization SDK Suite is currently ALPHA! Breaking changes may be published at any time.
|
|
21
|
+
|
|
22
|
+
The Optimization Node SDK implements functionality specific to Node environments, based on the
|
|
23
|
+
[Optimization Core Library](/universal/core/README.md). This SDK is part of the
|
|
24
|
+
[Contentful Optimization SDK Suite](/README.md).
|
|
25
|
+
|
|
26
|
+
<details>
|
|
27
|
+
<summary>Table of Contents</summary>
|
|
28
|
+
<!-- mtoc-start -->
|
|
29
|
+
|
|
30
|
+
- [Getting Started](#getting-started)
|
|
31
|
+
- [Reference Implementations](#reference-implementations)
|
|
32
|
+
- [Configuration](#configuration)
|
|
33
|
+
- [Top-level Configuration Options](#top-level-configuration-options)
|
|
34
|
+
- [Analytics Options](#analytics-options)
|
|
35
|
+
- [Event Builder Options](#event-builder-options)
|
|
36
|
+
- [Fetch Options](#fetch-options)
|
|
37
|
+
- [Personalization Options](#personalization-options)
|
|
38
|
+
- [Optimization Methods](#optimization-methods)
|
|
39
|
+
- [Personalization Data Resolution Methods](#personalization-data-resolution-methods)
|
|
40
|
+
- [`getCustomFlag`](#getcustomflag)
|
|
41
|
+
- [`personalizeEntry`](#personalizeentry)
|
|
42
|
+
- [`getMergeTagValue`](#getmergetagvalue)
|
|
43
|
+
- [Personalization and Analytics Event Methods](#personalization-and-analytics-event-methods)
|
|
44
|
+
- [`identify`](#identify)
|
|
45
|
+
- [`page`](#page)
|
|
46
|
+
- [`track`](#track)
|
|
47
|
+
- [`trackComponentView`](#trackcomponentview)
|
|
48
|
+
- [`trackFlagView`](#trackflagview)
|
|
49
|
+
- [Interceptors](#interceptors)
|
|
50
|
+
- [Life-cycle Interceptors](#life-cycle-interceptors)
|
|
51
|
+
|
|
52
|
+
<!-- mtoc-end -->
|
|
53
|
+
</details>
|
|
54
|
+
|
|
55
|
+
## Getting Started
|
|
56
|
+
|
|
57
|
+
Install using an NPM-compatible package manager, pnpm for example:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
pnpm install @contentful/optimization-node
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Import the Optimization class; both CJS and ESM module systems are supported, ESM preferred:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import Optimization from '@contentful/optimization-node'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Configure and initialize the Optimization Node SDK:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const optimization = new Optimization({ clientId: 'abc123' })
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Reference Implementations
|
|
76
|
+
|
|
77
|
+
Reference implementations illustrate how the SDK may be used under common scenarios, as well as
|
|
78
|
+
select less-common scenarios, with the most basic example solution possible.
|
|
79
|
+
|
|
80
|
+
- [Node SSR Only](/implementations/node-ssr-only/README.md): Example application that uses the Node
|
|
81
|
+
SDK to render a personalized Web page
|
|
82
|
+
- [Node SSR + Web Vanilla](/implementations/node-ssr-web-vanilla/README.md): Example application
|
|
83
|
+
demonstrating simple profile synchronization between the Node and [Web](../web/README.md) SDKs via
|
|
84
|
+
cookie
|
|
85
|
+
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
### Top-level Configuration Options
|
|
89
|
+
|
|
90
|
+
| Option | Required? | Default | Description |
|
|
91
|
+
| ----------------- | --------- | ----------------------------- | ------------------------------------------------------------------------------ |
|
|
92
|
+
| `analytics` | No | See "Analytics Options" | Configuration specific to the Analytics/Insights API |
|
|
93
|
+
| `app` | No | `undefined` | The application definition used to attribute events to a specific consumer app |
|
|
94
|
+
| `clientId` | Yes | N/A | The Ninetailed API Key which can be found in the Ninetailed Admin app |
|
|
95
|
+
| `environment` | No | `'main'` | The Ninetailed environment configured in the Ninetailed Admin app |
|
|
96
|
+
| `eventBuilder` | No | See "Event Builder Options" | Event builder configuration (channel/library metadata, etc.) |
|
|
97
|
+
| `fetchOptions` | No | See "Fetch Options" | Configuration for Fetch timeout and retry functionality |
|
|
98
|
+
| `logLevel` | No | `'error'` | Minimum log level for the default console sin |
|
|
99
|
+
| `personalization` | No | See "Personalization Options" | Configuration specific to the Personalization/Experience API |
|
|
100
|
+
|
|
101
|
+
### Analytics Options
|
|
102
|
+
|
|
103
|
+
| Option | Required? | Default | Description |
|
|
104
|
+
| --------- | --------- | ------------------------------------------ | ----------------------------- |
|
|
105
|
+
| `baseUrl` | No | `'https://ingest.insights.ninetailed.co/'` | Base URL for the Insights API |
|
|
106
|
+
|
|
107
|
+
### Event Builder Options
|
|
108
|
+
|
|
109
|
+
Event builder options should only be supplied when building an SDK on top of the Optimization Node
|
|
110
|
+
SDK or any of its descendent SDKs.
|
|
111
|
+
|
|
112
|
+
| Option | Required? | Default | Description |
|
|
113
|
+
| --------- | --------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
114
|
+
| `channel` | No | `'server'` | The channel that identifies where events originate from (e.g. `'web'`, `'mobile'`) |
|
|
115
|
+
| `library` | No | `{ name: 'Optimization Node API', version: '0.0.0' }` | The client library metadata that is attached to all events |
|
|
116
|
+
|
|
117
|
+
### Fetch Options
|
|
118
|
+
|
|
119
|
+
Fetch options allow for configuration of a Fetch API-compatible fetch method and the retry/timeout
|
|
120
|
+
logic integrated into the Optimization API Client. Specify the `fetchMethod` when the host
|
|
121
|
+
application environment does not offer a `fetch` method that is compatible with the standard Fetch
|
|
122
|
+
API in its global scope.
|
|
123
|
+
|
|
124
|
+
| Option | Required? | Default | Description |
|
|
125
|
+
| ------------------ | --------- | ----------- | --------------------------------------------------------------------- |
|
|
126
|
+
| `fetchMethod` | No | `undefined` | Signature of a fetch method used by the API clients |
|
|
127
|
+
| `intervalTimeout` | No | `0` | Delay (in milliseconds) between retry attempts |
|
|
128
|
+
| `onFailedAttempt` | No | `undefined` | Callback invoked whenever a retry attempt fails |
|
|
129
|
+
| `onRequestTimeout` | No | `undefined` | Callback invoked when a request exceeds the configured timeout |
|
|
130
|
+
| `requestTimeout` | No | `3000` | Maximum time (in milliseconds) to wait for a response before aborting |
|
|
131
|
+
| `retries` | No | `1` | Maximum number of retry attempts |
|
|
132
|
+
|
|
133
|
+
Configuration method signatures:
|
|
134
|
+
|
|
135
|
+
- `fetchMethod`: `(url: string | URL, init: RequestInit) => Promise<Response>`
|
|
136
|
+
- `onFailedAttempt` and `onRequestTimeout`: `(options: FetchMethodCallbackOptions) => void`
|
|
137
|
+
|
|
138
|
+
### Personalization Options
|
|
139
|
+
|
|
140
|
+
| Option | Required? | Default | Description |
|
|
141
|
+
| ----------------- | --------- | ------------------------------------- | ------------------------------------------------------------------- |
|
|
142
|
+
| `baseUrl` | No | `'https://experience.ninetailed.co/'` | Base URL for the Experience API |
|
|
143
|
+
| `enabledFeatures` | No | `['ip-enrichment', 'location']` | Enabled features which the API may use for each request |
|
|
144
|
+
| `ip` | No | `undefined` | IP address to override the API behavior for IP analysis |
|
|
145
|
+
| `locale` | No | `'en-US'` (in API) | Locale used to translate `location.city` and `location.country` |
|
|
146
|
+
| `plainText` | No | `false` | Sends performance-critical endpoints in plain text |
|
|
147
|
+
| `preflight` | No | `false` | Instructs the API to aggregate a new profile state but not store it |
|
|
148
|
+
|
|
149
|
+
## Optimization Methods
|
|
150
|
+
|
|
151
|
+
Arguments marked with an asterisk (\*) are always required.
|
|
152
|
+
|
|
153
|
+
### Personalization Data Resolution Methods
|
|
154
|
+
|
|
155
|
+
#### `getCustomFlag`
|
|
156
|
+
|
|
157
|
+
Get the specified Custom Flag's value from the provided changes array.
|
|
158
|
+
|
|
159
|
+
Arguments:
|
|
160
|
+
|
|
161
|
+
- `name`\*: The name/key of the Custom Flag
|
|
162
|
+
- `changes`: Changes array
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
|
|
166
|
+
- The resolved value for the specified Custom Flag, or `undefined` if it cannot be found.
|
|
167
|
+
|
|
168
|
+
> [!NOTE]
|
|
169
|
+
>
|
|
170
|
+
> If the `changes` argument is omitted, the method will return `undefined`.
|
|
171
|
+
|
|
172
|
+
#### `personalizeEntry`
|
|
173
|
+
|
|
174
|
+
Resolve a baseline Contentful entry to a personalized variant using the provided selected
|
|
175
|
+
personalizations.
|
|
176
|
+
|
|
177
|
+
Type arguments:
|
|
178
|
+
|
|
179
|
+
- `S`: Entry skeleton type
|
|
180
|
+
- `M`: Chain modifiers
|
|
181
|
+
- `L`: Locale code
|
|
182
|
+
|
|
183
|
+
Arguments:
|
|
184
|
+
|
|
185
|
+
- `entry`\*: The entry to personalize
|
|
186
|
+
- `personalizations`: Selected personalizations
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
|
|
190
|
+
- The resolved personalized entry variant, or the supplied baseline entry if baseline is the
|
|
191
|
+
selected variant or a variant cannot be found.
|
|
192
|
+
|
|
193
|
+
> [!NOTE]
|
|
194
|
+
>
|
|
195
|
+
> If the `personalizations` argument is omitted, the method will return the baseline entry.
|
|
196
|
+
|
|
197
|
+
#### `getMergeTagValue`
|
|
198
|
+
|
|
199
|
+
Resolve a "Merge Tag" to a value based on the provided profile. A "Merge Tag" is a special Rich Text
|
|
200
|
+
fragment supported by Contentful that specifies a profile data member to be injected into the Rich
|
|
201
|
+
Text when rendered.
|
|
202
|
+
|
|
203
|
+
Arguments:
|
|
204
|
+
|
|
205
|
+
- `embeddedNodeEntryTarget`\*: The merge tag entry node to resolve
|
|
206
|
+
- `profile`: The user profile
|
|
207
|
+
|
|
208
|
+
> [!NOTE]
|
|
209
|
+
>
|
|
210
|
+
> If the `profile` argument is omitted, the method will return the merge tag's fallback value.
|
|
211
|
+
|
|
212
|
+
### Personalization and Analytics Event Methods
|
|
213
|
+
|
|
214
|
+
Each method except `trackFlagView` may return an `OptimizationData` object containing:
|
|
215
|
+
|
|
216
|
+
- `changes`: Currently used for Custom Flags
|
|
217
|
+
- `personalizations`: Selected personalizations for the profile
|
|
218
|
+
- `profile`: Profile associated with the evaluated events
|
|
219
|
+
|
|
220
|
+
#### `identify`
|
|
221
|
+
|
|
222
|
+
Identify the current profile/visitor to associate traits with a profile.
|
|
223
|
+
|
|
224
|
+
Arguments:
|
|
225
|
+
|
|
226
|
+
- `payload`\*: Identify event builder arguments object, including an optional `profile` property
|
|
227
|
+
with a `PartialProfile` value that requires only an `id`
|
|
228
|
+
|
|
229
|
+
#### `page`
|
|
230
|
+
|
|
231
|
+
Record a personalization page view.
|
|
232
|
+
|
|
233
|
+
Arguments:
|
|
234
|
+
|
|
235
|
+
- `payload`\*: Page view event builder arguments object, including an optional `profile` property
|
|
236
|
+
with a `PartialProfile` value that requires only an `id`
|
|
237
|
+
|
|
238
|
+
#### `track`
|
|
239
|
+
|
|
240
|
+
Record a personalization custom track event.
|
|
241
|
+
|
|
242
|
+
Arguments:
|
|
243
|
+
|
|
244
|
+
- `payload`\*: Track event builder arguments object, including an optional `profile` property with a
|
|
245
|
+
`PartialProfile` value that requires only an `id`
|
|
246
|
+
|
|
247
|
+
#### `trackComponentView`
|
|
248
|
+
|
|
249
|
+
Record an analytics component view event. When the payload marks the component as "sticky", an
|
|
250
|
+
additional personalization component view is recorded. This method only returns `OptimizationData`
|
|
251
|
+
when the component is marked as "sticky".
|
|
252
|
+
|
|
253
|
+
Arguments:
|
|
254
|
+
|
|
255
|
+
- `payload`\*: Component view event builder arguments object, including an optional `profile`
|
|
256
|
+
property with a `PartialProfile` value that requires only an `id`
|
|
257
|
+
|
|
258
|
+
#### `trackFlagView`
|
|
259
|
+
|
|
260
|
+
Track a feature flag view via analytics. This is functionally the same as a non-sticky component
|
|
261
|
+
view event.
|
|
262
|
+
|
|
263
|
+
Arguments:
|
|
264
|
+
|
|
265
|
+
- `payload`\*: Component view event builder arguments object, including an optional `profile`
|
|
266
|
+
property with a `PartialProfile` value that requires only an `id`
|
|
267
|
+
|
|
268
|
+
## Interceptors
|
|
269
|
+
|
|
270
|
+
Interceptors may be used to read and/or modify data flowing through the Core SDK.
|
|
271
|
+
|
|
272
|
+
### Life-cycle Interceptors
|
|
273
|
+
|
|
274
|
+
- `event`: Intercepts an event's data _before_ it is queued and/or emitted
|
|
275
|
+
- `state`: Intercepts state data retrieved from an Experience API call _before_ updating the SDK's
|
|
276
|
+
internal state
|
|
277
|
+
|
|
278
|
+
Example interceptor usage:
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
optimization.interceptors.event((event) => {
|
|
282
|
+
event.properties.timestamp = new Date().toISOString()
|
|
283
|
+
})
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
> [!WARNING]
|
|
287
|
+
>
|
|
288
|
+
> Interceptors are intended to enable low-level interoperability; to simply read and react to
|
|
289
|
+
> Optimization SDK events, use the `states` observables.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_modules__ = {
|
|
3
|
+
"./src/Optimization.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
4
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
5
|
+
A: ()=>src_Optimization
|
|
6
|
+
});
|
|
7
|
+
var optimization_core_ = __webpack_require__("@contentful/optimization-core");
|
|
8
|
+
const external_es_toolkit_namespaceObject = require("es-toolkit");
|
|
9
|
+
var global_constants = __webpack_require__("./src/global-constants.ts");
|
|
10
|
+
function mergeConfig(config) {
|
|
11
|
+
const { app, ...restConfig } = config;
|
|
12
|
+
const defaultConfig = {
|
|
13
|
+
eventBuilder: {
|
|
14
|
+
app,
|
|
15
|
+
channel: 'server',
|
|
16
|
+
library: {
|
|
17
|
+
name: 'Optimization Node API',
|
|
18
|
+
version: global_constants.R
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return (0, external_es_toolkit_namespaceObject.merge)(defaultConfig, restConfig);
|
|
23
|
+
}
|
|
24
|
+
class Optimization extends optimization_core_.CoreStateless {
|
|
25
|
+
constructor(config){
|
|
26
|
+
const mergedConfig = mergeConfig(config);
|
|
27
|
+
super(mergedConfig);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const src_Optimization = Optimization;
|
|
31
|
+
},
|
|
32
|
+
"./src/global-constants.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
33
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
34
|
+
R: ()=>OPTIMIZATION_NODE_SDK_VERSION,
|
|
35
|
+
T: ()=>_contentful_optimization_core__rspack_import_0.ANONYMOUS_ID_COOKIE
|
|
36
|
+
});
|
|
37
|
+
var _contentful_optimization_core__rspack_import_0 = __webpack_require__("@contentful/optimization-core");
|
|
38
|
+
const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha";
|
|
39
|
+
},
|
|
40
|
+
"@contentful/optimization-core" (module) {
|
|
41
|
+
module.exports = require("@contentful/optimization-core");
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var __webpack_module_cache__ = {};
|
|
45
|
+
function __webpack_require__(moduleId) {
|
|
46
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
47
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
48
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
49
|
+
exports: {}
|
|
50
|
+
};
|
|
51
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
52
|
+
return module.exports;
|
|
53
|
+
}
|
|
54
|
+
(()=>{
|
|
55
|
+
__webpack_require__.n = (module)=>{
|
|
56
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
57
|
+
__webpack_require__.d(getter, {
|
|
58
|
+
a: getter
|
|
59
|
+
});
|
|
60
|
+
return getter;
|
|
61
|
+
};
|
|
62
|
+
})();
|
|
63
|
+
(()=>{
|
|
64
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
65
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
get: definition[key]
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
})();
|
|
71
|
+
(()=>{
|
|
72
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
73
|
+
})();
|
|
74
|
+
(()=>{
|
|
75
|
+
__webpack_require__.r = (exports1)=>{
|
|
76
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
77
|
+
value: 'Module'
|
|
78
|
+
});
|
|
79
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
80
|
+
value: true
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
})();
|
|
84
|
+
var __webpack_exports__ = {};
|
|
85
|
+
(()=>{
|
|
86
|
+
__webpack_require__.r(__webpack_exports__);
|
|
87
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
88
|
+
ANONYMOUS_ID_COOKIE: ()=>_global_constants__rspack_import_2.T,
|
|
89
|
+
OPTIMIZATION_NODE_SDK_VERSION: ()=>_global_constants__rspack_import_2.R,
|
|
90
|
+
default: ()=>__rspack_default_export
|
|
91
|
+
});
|
|
92
|
+
var _Optimization__rspack_import_0 = __webpack_require__("./src/Optimization.ts");
|
|
93
|
+
var _contentful_optimization_core__rspack_import_1 = __webpack_require__("@contentful/optimization-core");
|
|
94
|
+
var __rspack_reexport = {};
|
|
95
|
+
for(const __rspack_import_key in _contentful_optimization_core__rspack_import_1)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_contentful_optimization_core__rspack_import_1[__rspack_import_key];
|
|
96
|
+
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
97
|
+
var _global_constants__rspack_import_2 = __webpack_require__("./src/global-constants.ts");
|
|
98
|
+
const __rspack_default_export = _Optimization__rspack_import_0.A;
|
|
99
|
+
})();
|
|
100
|
+
exports.ANONYMOUS_ID_COOKIE = __webpack_exports__.ANONYMOUS_ID_COOKIE;
|
|
101
|
+
exports.OPTIMIZATION_NODE_SDK_VERSION = __webpack_exports__.OPTIMIZATION_NODE_SDK_VERSION;
|
|
102
|
+
exports["default"] = __webpack_exports__["default"];
|
|
103
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
104
|
+
"ANONYMOUS_ID_COOKIE",
|
|
105
|
+
"OPTIMIZATION_NODE_SDK_VERSION",
|
|
106
|
+
"default"
|
|
107
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
108
|
+
Object.defineProperty(exports, '__esModule', {
|
|
109
|
+
value: true
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/Optimization.ts","../src/global-constants.ts","webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../src/index.ts"],"sourcesContent":["import { type App, type CoreStatelessConfig, CoreStateless } from '@contentful/optimization-core'\nimport { merge } from 'es-toolkit'\nimport { OPTIMIZATION_NODE_SDK_VERSION } from './global-constants'\n\n/**\n * Configuration for the Node-specific Optimization SDK.\n *\n * @public\n * @remarks\n * This configuration extends {@link CoreConfig} but allows partial overrides\n * of the event-builder configuration. SDKs commonly inject their own library\n * metadata or channel definitions.\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 * This differs from {@link CoreConfig.eventBuilder}, which expects a\n * full configuration object.\n */\n eventBuilder?: Partial<Omit<CoreStatelessConfig['eventBuilder'], 'app'>>\n}\n\n/**\n * Merge user-supplied configuration with defaults for the Node SDK.\n *\n * @param config - The input configuration supplied by the caller.\n * @returns A fully composed {@link CoreConfig} object suitable for\n * constructing the core runtime.\n *\n * @internal\n * @remarks\n * Ensures that the Node SDK always identifies itself via a `server` channel\n * and a `library` metadata block unless explicitly overridden.\n */\nfunction mergeConfig(config: OptimizationNodeConfig): CoreStatelessConfig {\n const { app, ...restConfig } = config\n\n const defaultConfig: Partial<CoreStatelessConfig> = {\n eventBuilder: {\n app,\n channel: 'server',\n library: { name: 'Optimization Node API', version: OPTIMIZATION_NODE_SDK_VERSION },\n },\n }\n return merge(defaultConfig, restConfig)\n}\n\n/**\n * Node-specific Optimization SDK built on {@link CoreStateless}.\n *\n * @public\n * @remarks\n * This class adapts the stateless Optimization Core for Node runtimes by\n * applying environment-appropriate defaults (e.g., server channel, Node SDK\n * library metadata). No analytics or personalization behavior is modified—\n * only configuration defaults differ.\n *\n * @example\n * ```ts\n * import Optimization from '@contentful/optimization-node'\n *\n * const sdk = new Optimization({\n * clientId: 'abc-123',\n * environment: 'main',\n * logLevel: 'info',\n * })\n *\n * await sdk.track({ event: 'server_event', properties: { id: 1 } })\n * ```\n */\nclass Optimization 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 constructor(config: OptimizationNodeConfig) {\n const mergedConfig: CoreStatelessConfig = mergeConfig(config)\n\n super(mergedConfig)\n }\n}\n\nexport default Optimization\n","// eslint-disable-next-line @typescript-eslint/naming-convention -- Replaced at build-time\ndeclare const __OPTIMIZATION_VERSION__: string | undefined\n\nexport const OPTIMIZATION_NODE_SDK_VERSION =\n typeof __OPTIMIZATION_VERSION__ === 'string' ? __OPTIMIZATION_VERSION__ : '0.0.0'\n\n/**\n * Re-export of the anonymous-ID cookie name used by the Optimization Core.\n *\n * @public\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 personalization and analytics\n * events when no explicit profile is known.\n *\n * @see {@link ANONYMOUS_ID_COOKIE} in `@contentful/optimization-core` for the\n * authoritative definition and documentation.\n *\n * @example\n * ```ts\n * import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-node'\n * const id = request.cookies[ANONYMOUS_ID_COOKIE]\n * ```\n */\nexport { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core'\n","// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\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 Optimization from './Optimization'\n\nexport * from '@contentful/optimization-core'\n\nexport * from './global-constants'\nexport * from './Optimization'\n\nexport default Optimization\n"],"names":["mergeConfig","config","app","restConfig","defaultConfig","OPTIMIZATION_NODE_SDK_VERSION","merge","Optimization","CoreStateless","mergedConfig","__OPTIMIZATION_VERSION__","__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol"],"mappings":";;;;;;;;;QA6CA,SAASA,YAAYC,MAA8B;YACjD,MAAM,EAAEC,GAAG,EAAE,GAAGC,YAAY,GAAGF;YAE/B,MAAMG,gBAA8C;gBAClD,cAAc;oBACZF;oBACA,SAAS;oBACT,SAAS;wBAAE,MAAM;wBAAyB,SAASG,iBAAAA,CAA6BA;oBAAC;gBACnF;YACF;YACA,OAAOC,AAAAA,IAAAA,oCAAAA,KAAAA,AAAAA,EAAMF,eAAeD;QAC9B;QAyBA,MAAMI,qBAAqBC,mBAAAA,aAAaA;YAOtC,YAAYP,MAA8B,CAAE;gBAC1C,MAAMQ,eAAoCT,YAAYC;gBAEtD,KAAK,CAACQ;YACR;QACF;QAEA,yBAAeF;;;;;;;;QC5FR,MAAMF,gCACoCK;;;;;;;;;;;;;;;;;ICHjDC,oBAAoB,CAAC,GAAG,CAACC;QACxB,IAAIC,SAASD,UAAUA,OAAO,UAAU,GACvC,IAAOA,MAAM,CAAC,UAAU,GACxB,IAAOA;QACRD,oBAAoB,CAAC,CAACE,QAAQ;YAAE,GAAGA;QAAO;QAC1C,OAAOA;IACR;;;ICPAF,oBAAoB,CAAC,GAAG,CAAC,UAASG;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGH,oBAAoB,CAAC,CAACG,YAAYC,QAAQ,CAACJ,oBAAoB,CAAC,CAAC,UAASI,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAJ,oBAAoB,CAAC,GAAG,CAACM,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFP,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,MAAlB,OAAOQ,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;;;ICCA,gCAAeT,+BAAAA,CAAYA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core';
|
|
2
|
+
import { App } from '@contentful/optimization-core';
|
|
3
|
+
import { CoreStateless } from '@contentful/optimization-core';
|
|
4
|
+
import { CoreStatelessConfig } from '@contentful/optimization-core';
|
|
5
|
+
|
|
6
|
+
export { ANONYMOUS_ID_COOKIE }
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Node-specific Optimization SDK built on {@link CoreStateless}.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
* @remarks
|
|
13
|
+
* This class adapts the stateless Optimization Core for Node runtimes by
|
|
14
|
+
* applying environment-appropriate defaults (e.g., server channel, Node SDK
|
|
15
|
+
* library metadata). No analytics or personalization behavior is modified—
|
|
16
|
+
* only configuration defaults differ.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import Optimization from '@contentful/optimization-node'
|
|
21
|
+
*
|
|
22
|
+
* const sdk = new Optimization({
|
|
23
|
+
* clientId: 'abc-123',
|
|
24
|
+
* environment: 'main',
|
|
25
|
+
* logLevel: 'info',
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* await sdk.track({ event: 'server_event', properties: { id: 1 } })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
declare class Optimization extends CoreStateless {
|
|
32
|
+
/**
|
|
33
|
+
* Create an instance of the Node SDK with merged defaults.
|
|
34
|
+
*
|
|
35
|
+
* @param config - Partial Node-specific configuration. Any eventBuilder
|
|
36
|
+
* fields provided are merged with Node's defaults.
|
|
37
|
+
*/
|
|
38
|
+
constructor(config: OptimizationNodeConfig);
|
|
39
|
+
}
|
|
40
|
+
export default Optimization;
|
|
41
|
+
|
|
42
|
+
export declare const OPTIMIZATION_NODE_SDK_VERSION: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Configuration for the Node-specific Optimization SDK.
|
|
46
|
+
*
|
|
47
|
+
* @public
|
|
48
|
+
* @remarks
|
|
49
|
+
* This configuration extends {@link CoreConfig} but allows partial overrides
|
|
50
|
+
* of the event-builder configuration. SDKs commonly inject their own library
|
|
51
|
+
* metadata or channel definitions.
|
|
52
|
+
*/
|
|
53
|
+
export declare interface OptimizationNodeConfig extends Omit<CoreStatelessConfig, 'eventBuilder'> {
|
|
54
|
+
/**
|
|
55
|
+
* The application definition used to attribute events to a specific consumer app.
|
|
56
|
+
*
|
|
57
|
+
* @remarks
|
|
58
|
+
* When not provided, events will not contain app metadata in their context.
|
|
59
|
+
*/
|
|
60
|
+
app?: App;
|
|
61
|
+
/**
|
|
62
|
+
* Partial overrides for the event builder configuration.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Any provided fields are merged with the default Node SDK metadata.
|
|
66
|
+
* This differs from {@link CoreConfig.eventBuilder}, which expects a
|
|
67
|
+
* full configuration object.
|
|
68
|
+
*/
|
|
69
|
+
eventBuilder?: Partial<Omit<CoreStatelessConfig['eventBuilder'], 'app'>>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
export * from "@contentful/optimization-core";
|
|
74
|
+
|
|
75
|
+
export { }
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as __rspack_external__contentful_optimization_core_7d4758c6 from "@contentful/optimization-core";
|
|
2
|
+
import { merge } from "es-toolkit";
|
|
3
|
+
const OPTIMIZATION_NODE_SDK_VERSION = "0.1.0-alpha";
|
|
4
|
+
function mergeConfig(config) {
|
|
5
|
+
const { app, ...restConfig } = config;
|
|
6
|
+
const defaultConfig = {
|
|
7
|
+
eventBuilder: {
|
|
8
|
+
app,
|
|
9
|
+
channel: 'server',
|
|
10
|
+
library: {
|
|
11
|
+
name: 'Optimization Node API',
|
|
12
|
+
version: OPTIMIZATION_NODE_SDK_VERSION
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
return merge(defaultConfig, restConfig);
|
|
17
|
+
}
|
|
18
|
+
class Optimization extends __rspack_external__contentful_optimization_core_7d4758c6.CoreStateless {
|
|
19
|
+
constructor(config){
|
|
20
|
+
const mergedConfig = mergeConfig(config);
|
|
21
|
+
super(mergedConfig);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const src_Optimization = Optimization;
|
|
25
|
+
const src = src_Optimization;
|
|
26
|
+
var ANONYMOUS_ID_COOKIE = __rspack_external__contentful_optimization_core_7d4758c6.ANONYMOUS_ID_COOKIE;
|
|
27
|
+
export * from "@contentful/optimization-core";
|
|
28
|
+
export default src;
|
|
29
|
+
export { ANONYMOUS_ID_COOKIE, OPTIMIZATION_NODE_SDK_VERSION };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/global-constants.ts","../src/Optimization.ts","../src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/naming-convention -- Replaced at build-time\ndeclare const __OPTIMIZATION_VERSION__: string | undefined\n\nexport const OPTIMIZATION_NODE_SDK_VERSION =\n typeof __OPTIMIZATION_VERSION__ === 'string' ? __OPTIMIZATION_VERSION__ : '0.0.0'\n\n/**\n * Re-export of the anonymous-ID cookie name used by the Optimization Core.\n *\n * @public\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 personalization and analytics\n * events when no explicit profile is known.\n *\n * @see {@link ANONYMOUS_ID_COOKIE} in `@contentful/optimization-core` for the\n * authoritative definition and documentation.\n *\n * @example\n * ```ts\n * import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-node'\n * const id = request.cookies[ANONYMOUS_ID_COOKIE]\n * ```\n */\nexport { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core'\n","import { type App, type CoreStatelessConfig, CoreStateless } from '@contentful/optimization-core'\nimport { merge } from 'es-toolkit'\nimport { OPTIMIZATION_NODE_SDK_VERSION } from './global-constants'\n\n/**\n * Configuration for the Node-specific Optimization SDK.\n *\n * @public\n * @remarks\n * This configuration extends {@link CoreConfig} but allows partial overrides\n * of the event-builder configuration. SDKs commonly inject their own library\n * metadata or channel definitions.\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 * This differs from {@link CoreConfig.eventBuilder}, which expects a\n * full configuration object.\n */\n eventBuilder?: Partial<Omit<CoreStatelessConfig['eventBuilder'], 'app'>>\n}\n\n/**\n * Merge user-supplied configuration with defaults for the Node SDK.\n *\n * @param config - The input configuration supplied by the caller.\n * @returns A fully composed {@link CoreConfig} object suitable for\n * constructing the core runtime.\n *\n * @internal\n * @remarks\n * Ensures that the Node SDK always identifies itself via a `server` channel\n * and a `library` metadata block unless explicitly overridden.\n */\nfunction mergeConfig(config: OptimizationNodeConfig): CoreStatelessConfig {\n const { app, ...restConfig } = config\n\n const defaultConfig: Partial<CoreStatelessConfig> = {\n eventBuilder: {\n app,\n channel: 'server',\n library: { name: 'Optimization Node API', version: OPTIMIZATION_NODE_SDK_VERSION },\n },\n }\n return merge(defaultConfig, restConfig)\n}\n\n/**\n * Node-specific Optimization SDK built on {@link CoreStateless}.\n *\n * @public\n * @remarks\n * This class adapts the stateless Optimization Core for Node runtimes by\n * applying environment-appropriate defaults (e.g., server channel, Node SDK\n * library metadata). No analytics or personalization behavior is modified—\n * only configuration defaults differ.\n *\n * @example\n * ```ts\n * import Optimization from '@contentful/optimization-node'\n *\n * const sdk = new Optimization({\n * clientId: 'abc-123',\n * environment: 'main',\n * logLevel: 'info',\n * })\n *\n * await sdk.track({ event: 'server_event', properties: { id: 1 } })\n * ```\n */\nclass Optimization 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 constructor(config: OptimizationNodeConfig) {\n const mergedConfig: CoreStatelessConfig = mergeConfig(config)\n\n super(mergedConfig)\n }\n}\n\nexport default Optimization\n","import Optimization from './Optimization'\n\nexport * from '@contentful/optimization-core'\n\nexport * from './global-constants'\nexport * from './Optimization'\n\nexport default Optimization\n"],"names":["OPTIMIZATION_NODE_SDK_VERSION","__OPTIMIZATION_VERSION__","mergeConfig","config","app","restConfig","defaultConfig","merge","Optimization","CoreStateless","mergedConfig"],"mappings":";;AAGO,MAAMA,gCACoCC;ACyCjD,SAASC,YAAYC,MAA8B;IACjD,MAAM,EAAEC,GAAG,EAAE,GAAGC,YAAY,GAAGF;IAE/B,MAAMG,gBAA8C;QAClD,cAAc;YACZF;YACA,SAAS;YACT,SAAS;gBAAE,MAAM;gBAAyB,SAASJ;YAA8B;QACnF;IACF;IACA,OAAOO,MAAMD,eAAeD;AAC9B;AAyBA,MAAMG,qBAAqBC,yDAAAA,aAAaA;IAOtC,YAAYN,MAA8B,CAAE;QAC1C,MAAMO,eAAoCR,YAAYC;QAEtD,KAAK,CAACO;IACR;AACF;AAEA,yBAAeF;ACxFf,YAAeA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contentful/optimization-node",
|
|
3
|
+
"version": "0.1.0-alpha",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"import": "./dist/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist/**/*"
|
|
19
|
+
],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"es-toolkit": "^1.39.10",
|
|
22
|
+
"@contentful/optimization-core": "0.1.0-alpha"
|
|
23
|
+
}
|
|
24
|
+
}
|