@ninetailed/experience.js-utils-contentful 2.0.0-beta.8 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './types';
2
+ export { AudienceMapper, ExperienceMapper, isEntry, isAudienceEntry, isExperienceEntry, } from './lib';
package/index.esm.js ADDED
@@ -0,0 +1,211 @@
1
+ import { z } from 'zod';
2
+
3
+ const EntryLink = z.object({
4
+ type: z.literal('Link'),
5
+ linkType: z.string(),
6
+ id: z.string()
7
+ });
8
+ const Entry = z.object({
9
+ sys: z.object({
10
+ type: z.string(),
11
+ id: z.string(),
12
+ createdAt: z.string(),
13
+ updatedAt: z.string(),
14
+ locale: z.string(),
15
+ revision: z.number().optional(),
16
+ space: z.object({
17
+ sys: EntryLink.extend({
18
+ linkType: z.literal('Space')
19
+ })
20
+ }).optional(),
21
+ environment: z.object({
22
+ sys: EntryLink.extend({
23
+ linkType: z.literal('Environment')
24
+ })
25
+ }).optional(),
26
+ contentType: z.object({
27
+ sys: EntryLink.extend({
28
+ linkType: z.literal('ContentType')
29
+ })
30
+ })
31
+ }),
32
+ fields: z.object({}),
33
+ metadata: z.object({
34
+ tags: z.array(z.object({
35
+ sys: EntryLink.extend({
36
+ linkType: z.literal('Tag')
37
+ })
38
+ }))
39
+ })
40
+ });
41
+
42
+ const AudienceFields = z.object({
43
+ /**
44
+ * The name of the audience (Short Text)
45
+ */
46
+ nt_name: z.string(),
47
+
48
+ /**
49
+ * The internal id of the audience (Short Text)
50
+ */
51
+ nt_audience_id: z.string()
52
+ });
53
+ const AudienceEntry = Entry.extend({
54
+ fields: AudienceFields
55
+ });
56
+
57
+ const ExperienceFields = z.object({
58
+ /**
59
+ * The name of the experience (Short Text)
60
+ */
61
+ nt_name: z.string(),
62
+
63
+ /**
64
+ * The type if the experience (nt_experiment | nt_personalization)
65
+ */
66
+ nt_type: z.union([z.literal('nt_experiment'), z.literal('nt_personalization')]),
67
+
68
+ /**
69
+ * The config of the experience (JSON)
70
+ */
71
+ nt_config: z.object({
72
+ distribution: z.array(z.number()),
73
+ traffic: z.number(),
74
+ components: z.array(z.object({
75
+ baseline: z.object({
76
+ id: z.string()
77
+ }),
78
+ variants: z.array(z.object({
79
+ id: z.string(),
80
+ hidden: z.boolean()
81
+ }))
82
+ }))
83
+ }).optional().nullable(),
84
+
85
+ /**
86
+ * The audience of the experience (Audience)
87
+ */
88
+ nt_audience: AudienceEntry.optional().nullable(),
89
+
90
+ /**
91
+ * All used variants of the experience (Contentful references to other Content Types)
92
+ */
93
+ nt_variants: z.array(Entry).default([])
94
+ });
95
+ const ExperienceEntry = Entry.extend({
96
+ fields: ExperienceFields
97
+ });
98
+
99
+ class AudienceMapper {
100
+ static mapAudience(audience) {
101
+ return {
102
+ id: audience.sys.id
103
+ };
104
+ }
105
+
106
+ }
107
+
108
+ const isEntry = entry => {
109
+ try {
110
+ Entry.parse(entry);
111
+ return true;
112
+ } catch (error) {
113
+ return false;
114
+ }
115
+ };
116
+
117
+ const defaultMapVariant = (variant, {
118
+ hidden
119
+ }) => Object.assign(Object.assign({}, variant), {
120
+ id: variant.sys.id,
121
+ hidden: hidden
122
+ });
123
+
124
+ class ExperienceMapper {
125
+ static mapExperience(entry, options) {
126
+ const _mapVariant = (options === null || options === void 0 ? void 0 : options.mapVariant) || defaultMapVariant;
127
+
128
+ const config = Object.assign({
129
+ traffic: 0,
130
+ distribution: [0.5, 0.5],
131
+ components: [{
132
+ baseline: {
133
+ id: ''
134
+ },
135
+ variants: [{
136
+ id: '',
137
+ hidden: false
138
+ }]
139
+ }]
140
+ }, entry.fields.nt_config);
141
+ const variantReferences = (entry.fields.nt_variants || []).filter(isEntry);
142
+ return Object.assign(Object.assign({
143
+ id: entry.sys.id,
144
+ type: entry.fields.nt_type
145
+ }, entry.fields.nt_audience ? {
146
+ audience: AudienceMapper.mapAudience(entry.fields.nt_audience)
147
+ } : {}), {
148
+ trafficAllocation: config.traffic,
149
+ distribution: config.distribution.map((percentage, index) => ({
150
+ index,
151
+ start: config.distribution.slice(0, index).reduce((a, b) => a + b, 0),
152
+ end: config.distribution.slice(0, index + 1).reduce((a, b) => a + b, 0)
153
+ })),
154
+ components: config.components.map(component => {
155
+ return {
156
+ baseline: component.baseline,
157
+ variants: component.variants.map(variant => {
158
+ if (variant.hidden) {
159
+ return variant;
160
+ }
161
+
162
+ const matchingVariant = variantReferences.find(variantReference => variantReference.sys.id === variant.id);
163
+
164
+ if (!matchingVariant) {
165
+ return null;
166
+ }
167
+
168
+ return _mapVariant(matchingVariant, {
169
+ hidden: variant.hidden
170
+ });
171
+ }).filter(variant => variant !== null)
172
+ };
173
+ })
174
+ });
175
+ }
176
+
177
+ static mapExperiment(entry) {
178
+ return ExperienceMapper.mapExperience(entry, {
179
+ mapVariant: () => ({
180
+ id: '',
181
+ hidden: false
182
+ })
183
+ });
184
+ }
185
+
186
+ static mapBaselineWithExperiences(entry) {
187
+ return entry.fields.nt_experiences.filter(isEntry).map(experience => ExperienceMapper.mapExperience(experience));
188
+ }
189
+
190
+ }
191
+
192
+ const isAudienceEntry = entry => {
193
+ try {
194
+ AudienceEntry.parse(entry);
195
+ return true;
196
+ } catch (error) {
197
+ return false;
198
+ }
199
+ };
200
+
201
+ const isExperienceEntry = entry => {
202
+ try {
203
+ ExperienceEntry.parse(entry);
204
+ return true;
205
+ } catch (error) {
206
+ console.error(error);
207
+ return false;
208
+ }
209
+ };
210
+
211
+ export { AudienceEntry, AudienceMapper, Entry, ExperienceEntry, ExperienceMapper, isAudienceEntry, isEntry, isExperienceEntry };
package/index.umd.js ADDED
@@ -0,0 +1,278 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('zod')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'zod'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.UtilsContentful = {}, global.zod));
5
+ })(this, (function (exports, zod) { 'use strict';
6
+
7
+ var EntryLink = zod.z.object({
8
+ type: zod.z.literal('Link'),
9
+ linkType: zod.z.string(),
10
+ id: zod.z.string()
11
+ });
12
+ var Entry = zod.z.object({
13
+ sys: zod.z.object({
14
+ type: zod.z.string(),
15
+ id: zod.z.string(),
16
+ createdAt: zod.z.string(),
17
+ updatedAt: zod.z.string(),
18
+ locale: zod.z.string(),
19
+ revision: zod.z.number().optional(),
20
+ space: zod.z.object({
21
+ sys: EntryLink.extend({
22
+ linkType: zod.z.literal('Space')
23
+ })
24
+ }).optional(),
25
+ environment: zod.z.object({
26
+ sys: EntryLink.extend({
27
+ linkType: zod.z.literal('Environment')
28
+ })
29
+ }).optional(),
30
+ contentType: zod.z.object({
31
+ sys: EntryLink.extend({
32
+ linkType: zod.z.literal('ContentType')
33
+ })
34
+ })
35
+ }),
36
+ fields: zod.z.object({}),
37
+ metadata: zod.z.object({
38
+ tags: zod.z.array(zod.z.object({
39
+ sys: EntryLink.extend({
40
+ linkType: zod.z.literal('Tag')
41
+ })
42
+ }))
43
+ })
44
+ });
45
+
46
+ var AudienceFields = zod.z.object({
47
+ /**
48
+ * The name of the audience (Short Text)
49
+ */
50
+ nt_name: zod.z.string(),
51
+
52
+ /**
53
+ * The internal id of the audience (Short Text)
54
+ */
55
+ nt_audience_id: zod.z.string()
56
+ });
57
+ var AudienceEntry = Entry.extend({
58
+ fields: AudienceFields
59
+ });
60
+
61
+ var ExperienceFields = zod.z.object({
62
+ /**
63
+ * The name of the experience (Short Text)
64
+ */
65
+ nt_name: zod.z.string(),
66
+
67
+ /**
68
+ * The type if the experience (nt_experiment | nt_personalization)
69
+ */
70
+ nt_type: zod.z.union([zod.z.literal('nt_experiment'), zod.z.literal('nt_personalization')]),
71
+
72
+ /**
73
+ * The config of the experience (JSON)
74
+ */
75
+ nt_config: zod.z.object({
76
+ distribution: zod.z.array(zod.z.number()),
77
+ traffic: zod.z.number(),
78
+ components: zod.z.array(zod.z.object({
79
+ baseline: zod.z.object({
80
+ id: zod.z.string()
81
+ }),
82
+ variants: zod.z.array(zod.z.object({
83
+ id: zod.z.string(),
84
+ hidden: zod.z.boolean()
85
+ }))
86
+ }))
87
+ }).optional().nullable(),
88
+
89
+ /**
90
+ * The audience of the experience (Audience)
91
+ */
92
+ nt_audience: AudienceEntry.optional().nullable(),
93
+
94
+ /**
95
+ * All used variants of the experience (Contentful references to other Content Types)
96
+ */
97
+ nt_variants: zod.z.array(Entry).default([])
98
+ });
99
+ var ExperienceEntry = Entry.extend({
100
+ fields: ExperienceFields
101
+ });
102
+
103
+ var AudienceMapper =
104
+ /** @class */
105
+ function () {
106
+ function AudienceMapper() {}
107
+
108
+ AudienceMapper.mapAudience = function (audience) {
109
+ return {
110
+ id: audience.sys.id
111
+ };
112
+ };
113
+
114
+ return AudienceMapper;
115
+ }();
116
+
117
+ /*! *****************************************************************************
118
+ Copyright (c) Microsoft Corporation.
119
+
120
+ Permission to use, copy, modify, and/or distribute this software for any
121
+ purpose with or without fee is hereby granted.
122
+
123
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
124
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
125
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
126
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
127
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
128
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
129
+ PERFORMANCE OF THIS SOFTWARE.
130
+ ***************************************************************************** */
131
+
132
+ var __assign = function() {
133
+ __assign = Object.assign || function __assign(t) {
134
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
135
+ s = arguments[i];
136
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
137
+ }
138
+ return t;
139
+ };
140
+ return __assign.apply(this, arguments);
141
+ };
142
+
143
+ var isEntry = function (entry) {
144
+ try {
145
+ Entry.parse(entry);
146
+ return true;
147
+ } catch (error) {
148
+ return false;
149
+ }
150
+ };
151
+
152
+ var defaultMapVariant = function (variant, _a) {
153
+ var hidden = _a.hidden;
154
+ return __assign(__assign({}, variant), {
155
+ id: variant.sys.id,
156
+ hidden: hidden
157
+ });
158
+ };
159
+
160
+ var ExperienceMapper =
161
+ /** @class */
162
+ function () {
163
+ function ExperienceMapper() {}
164
+
165
+ ExperienceMapper.mapExperience = function (entry, options) {
166
+ var _mapVariant = (options === null || options === void 0 ? void 0 : options.mapVariant) || defaultMapVariant;
167
+
168
+ var config = __assign({
169
+ traffic: 0,
170
+ distribution: [0.5, 0.5],
171
+ components: [{
172
+ baseline: {
173
+ id: ''
174
+ },
175
+ variants: [{
176
+ id: '',
177
+ hidden: false
178
+ }]
179
+ }]
180
+ }, entry.fields.nt_config);
181
+
182
+ var variantReferences = (entry.fields.nt_variants || []).filter(isEntry);
183
+ return __assign(__assign({
184
+ id: entry.sys.id,
185
+ type: entry.fields.nt_type
186
+ }, entry.fields.nt_audience ? {
187
+ audience: AudienceMapper.mapAudience(entry.fields.nt_audience)
188
+ } : {}), {
189
+ trafficAllocation: config.traffic,
190
+ distribution: config.distribution.map(function (percentage, index) {
191
+ return {
192
+ index: index,
193
+ start: config.distribution.slice(0, index).reduce(function (a, b) {
194
+ return a + b;
195
+ }, 0),
196
+ end: config.distribution.slice(0, index + 1).reduce(function (a, b) {
197
+ return a + b;
198
+ }, 0)
199
+ };
200
+ }),
201
+ components: config.components.map(function (component) {
202
+ return {
203
+ baseline: component.baseline,
204
+ variants: component.variants.map(function (variant) {
205
+ if (variant.hidden) {
206
+ return variant;
207
+ }
208
+
209
+ var matchingVariant = variantReferences.find(function (variantReference) {
210
+ return variantReference.sys.id === variant.id;
211
+ });
212
+
213
+ if (!matchingVariant) {
214
+ return null;
215
+ }
216
+
217
+ return _mapVariant(matchingVariant, {
218
+ hidden: variant.hidden
219
+ });
220
+ }).filter(function (variant) {
221
+ return variant !== null;
222
+ })
223
+ };
224
+ })
225
+ });
226
+ };
227
+
228
+ ExperienceMapper.mapExperiment = function (entry) {
229
+ return ExperienceMapper.mapExperience(entry, {
230
+ mapVariant: function () {
231
+ return {
232
+ id: '',
233
+ hidden: false
234
+ };
235
+ }
236
+ });
237
+ };
238
+
239
+ ExperienceMapper.mapBaselineWithExperiences = function (entry) {
240
+ return entry.fields.nt_experiences.filter(isEntry).map(function (experience) {
241
+ return ExperienceMapper.mapExperience(experience);
242
+ });
243
+ };
244
+
245
+ return ExperienceMapper;
246
+ }();
247
+
248
+ var isAudienceEntry = function (entry) {
249
+ try {
250
+ AudienceEntry.parse(entry);
251
+ return true;
252
+ } catch (error) {
253
+ return false;
254
+ }
255
+ };
256
+
257
+ var isExperienceEntry = function (entry) {
258
+ try {
259
+ ExperienceEntry.parse(entry);
260
+ return true;
261
+ } catch (error) {
262
+ console.error(error);
263
+ return false;
264
+ }
265
+ };
266
+
267
+ exports.AudienceEntry = AudienceEntry;
268
+ exports.AudienceMapper = AudienceMapper;
269
+ exports.Entry = Entry;
270
+ exports.ExperienceEntry = ExperienceEntry;
271
+ exports.ExperienceMapper = ExperienceMapper;
272
+ exports.isAudienceEntry = isAudienceEntry;
273
+ exports.isEntry = isEntry;
274
+ exports.isExperienceEntry = isExperienceEntry;
275
+
276
+ Object.defineProperty(exports, '__esModule', { value: true });
277
+
278
+ }));
@@ -1,6 +1,6 @@
1
- import { AudienceEntry } from '../types/AudienceEntry';
2
- export declare class AudienceMapper {
3
- static mapAudience(audience: AudienceEntry): {
4
- id: string;
5
- };
6
- }
1
+ import { AudienceEntry } from '../types/AudienceEntry';
2
+ export declare class AudienceMapper {
3
+ static mapAudience(audience: AudienceEntry): {
4
+ id: string;
5
+ };
6
+ }
@@ -0,0 +1,16 @@
1
+ import { Variant, ExperienceConfiguration } from '@ninetailed/experience.js';
2
+ import { ExperienceEntry, Entry } from '../types';
3
+ import { BaselineWithExperiencesEntry } from '../types/BaselineWithExperiencesEntry';
4
+ declare type MapVariantOptions = {
5
+ hidden: boolean;
6
+ };
7
+ declare type MapVariant<VariantType = Entry> = (variant: VariantType, options: MapVariantOptions) => Variant;
8
+ declare type MapExperienceOptions<VariantType = Entry> = {
9
+ mapVariant?: MapVariant<VariantType>;
10
+ };
11
+ export declare class ExperienceMapper {
12
+ static mapExperience(entry: ExperienceEntry, options?: MapExperienceOptions): ExperienceConfiguration;
13
+ static mapExperiment(entry: ExperienceEntry): ExperienceConfiguration;
14
+ static mapBaselineWithExperiences(entry: BaselineWithExperiencesEntry): ExperienceConfiguration[];
15
+ }
16
+ export {};
package/lib/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { AudienceMapper } from './AudienceMapper';
2
+ export { ExperienceMapper } from './ExperienceMapper';
3
+ export { isEntry } from './isEntry';
4
+ export { isAudienceEntry } from './isAudienceEntry';
5
+ export { isExperienceEntry } from './isExperienceEntry';
@@ -0,0 +1,84 @@
1
+ export declare const isAudienceEntry: (entry?: {
2
+ sys: {
3
+ revision?: number | undefined;
4
+ space?: {
5
+ sys: {
6
+ type: "Link";
7
+ id: string;
8
+ linkType: "Space";
9
+ };
10
+ } | undefined;
11
+ environment?: {
12
+ sys: {
13
+ type: "Link";
14
+ id: string;
15
+ linkType: "Environment";
16
+ };
17
+ } | undefined;
18
+ type: string;
19
+ id: string;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ locale: string;
23
+ contentType: {
24
+ sys: {
25
+ type: "Link";
26
+ id: string;
27
+ linkType: "ContentType";
28
+ };
29
+ };
30
+ };
31
+ fields: {};
32
+ metadata: {
33
+ tags: {
34
+ sys: {
35
+ type: "Link";
36
+ id: string;
37
+ linkType: "Tag";
38
+ };
39
+ }[];
40
+ };
41
+ } | undefined) => entry is {
42
+ sys: {
43
+ revision?: number | undefined;
44
+ space?: {
45
+ sys: {
46
+ type: "Link";
47
+ id: string;
48
+ linkType: "Space";
49
+ };
50
+ } | undefined;
51
+ environment?: {
52
+ sys: {
53
+ type: "Link";
54
+ id: string;
55
+ linkType: "Environment";
56
+ };
57
+ } | undefined;
58
+ type: string;
59
+ id: string;
60
+ createdAt: string;
61
+ updatedAt: string;
62
+ locale: string;
63
+ contentType: {
64
+ sys: {
65
+ type: "Link";
66
+ id: string;
67
+ linkType: "ContentType";
68
+ };
69
+ };
70
+ };
71
+ fields: {
72
+ nt_name: string;
73
+ nt_audience_id: string;
74
+ };
75
+ metadata: {
76
+ tags: {
77
+ sys: {
78
+ type: "Link";
79
+ id: string;
80
+ linkType: "Tag";
81
+ };
82
+ }[];
83
+ };
84
+ };
@@ -0,0 +1,81 @@
1
+ export declare const isEntry: (entry?: {
2
+ sys: {
3
+ revision?: number | undefined;
4
+ space?: {
5
+ sys: {
6
+ type: "Link";
7
+ id: string;
8
+ linkType: "Space";
9
+ };
10
+ } | undefined;
11
+ environment?: {
12
+ sys: {
13
+ type: "Link";
14
+ id: string;
15
+ linkType: "Environment";
16
+ };
17
+ } | undefined;
18
+ type: string;
19
+ id: string;
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ locale: string;
23
+ contentType: {
24
+ sys: {
25
+ type: "Link";
26
+ id: string;
27
+ linkType: "ContentType";
28
+ };
29
+ };
30
+ };
31
+ fields: {};
32
+ metadata: {
33
+ tags: {
34
+ sys: {
35
+ type: "Link";
36
+ id: string;
37
+ linkType: "Tag";
38
+ };
39
+ }[];
40
+ };
41
+ } | undefined) => entry is {
42
+ sys: {
43
+ revision?: number | undefined;
44
+ space?: {
45
+ sys: {
46
+ type: "Link";
47
+ id: string;
48
+ linkType: "Space";
49
+ };
50
+ } | undefined;
51
+ environment?: {
52
+ sys: {
53
+ type: "Link";
54
+ id: string;
55
+ linkType: "Environment";
56
+ };
57
+ } | undefined;
58
+ type: string;
59
+ id: string;
60
+ createdAt: string;
61
+ updatedAt: string;
62
+ locale: string;
63
+ contentType: {
64
+ sys: {
65
+ type: "Link";
66
+ id: string;
67
+ linkType: "ContentType";
68
+ };
69
+ };
70
+ };
71
+ fields: {};
72
+ metadata: {
73
+ tags: {
74
+ sys: {
75
+ type: "Link";
76
+ id: string;
77
+ linkType: "Tag";
78
+ };
79
+ }[];
80
+ };
81
+ };