@ninetailed/experience.js-utils-contentful 2.1.2-beta.1 → 2.2.0

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.esm.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { Config, ExperienceMapper as ExperienceMapper$1 } from '@ninetailed/experience.js-utils';
2
3
 
3
4
  const EntryLink = z.object({
4
5
  type: z.literal('Link'),
@@ -29,7 +30,7 @@ const Entry = z.object({
29
30
  })
30
31
  }).optional()
31
32
  }),
32
- fields: z.object({}),
33
+ fields: z.object({}).passthrough(),
33
34
  metadata: z.object({
34
35
  tags: z.array(z.object({
35
36
  sys: EntryLink.extend({
@@ -68,19 +69,7 @@ const ExperienceFields = z.object({
68
69
  /**
69
70
  * The config of the experience (JSON)
70
71
  */
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(),
72
+ nt_config: Config,
84
73
 
85
74
  /**
86
75
  * The audience of the experience (Audience)
@@ -96,6 +85,12 @@ const ExperienceEntry = Entry.extend({
96
85
  fields: ExperienceFields
97
86
  });
98
87
 
88
+ const ExperimentEntry = ExperienceEntry.extend({
89
+ fields: ExperienceFields.extend({
90
+ nt_type: z.literal('nt_experiment')
91
+ })
92
+ });
93
+
99
94
  class AudienceMapper {
100
95
  static mapAudience(audience) {
101
96
  return {
@@ -114,71 +109,54 @@ const isEntry = entry => {
114
109
  }
115
110
  };
116
111
 
117
- const defaultMapVariant = (variant, {
118
- hidden
119
- }) => Object.assign(Object.assign({}, variant), {
120
- id: variant.sys.id,
121
- hidden: hidden
112
+ const defaultMapVariant = variant => Object.assign(Object.assign({}, variant), {
113
+ id: variant.sys.id
122
114
  });
123
115
 
124
116
  class ExperienceMapper {
117
+ static isExperienceEntry(entry) {
118
+ return ExperienceEntry.safeParse(entry).success;
119
+ }
120
+
125
121
  static mapExperience(entry, options) {
126
122
  const _mapVariant = (options === null || options === void 0 ? void 0 : options.mapVariant) || defaultMapVariant;
127
123
 
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
- });
124
+ const parsedExperience = ExperienceEntry.safeParse(entry);
125
+
126
+ if (!parsedExperience.success) {
127
+ throw new Error('The Experience Input is not valid. Please filter data first with `ExperienceMapper.isExperienceEntry`.');
128
+ }
129
+
130
+ const {
131
+ sys: {
132
+ id
133
+ },
134
+ fields: {
135
+ nt_type,
136
+ nt_name,
137
+ nt_config,
138
+ nt_audience,
139
+ nt_variants
140
+ }
141
+ } = parsedExperience.data;
142
+ return ExperienceMapper$1.mapExperience(Object.assign(Object.assign({
143
+ id,
144
+ type: nt_type,
145
+ name: nt_name
146
+ }, nt_audience ? AudienceMapper.mapAudience(nt_audience) : {}), {
147
+ config: nt_config,
148
+ variants: nt_variants.map(variant => _mapVariant(variant))
149
+ }));
150
+ }
151
+
152
+ static isExperiment(entry) {
153
+ return ExperimentEntry.safeParse(entry).success;
175
154
  }
176
155
 
177
156
  static mapExperiment(entry) {
178
157
  return ExperienceMapper.mapExperience(entry, {
179
158
  mapVariant: () => ({
180
- id: '',
181
- hidden: false
159
+ id: ''
182
160
  })
183
161
  });
184
162
  }
@@ -190,22 +168,11 @@ class ExperienceMapper {
190
168
  }
191
169
 
192
170
  const isAudienceEntry = entry => {
193
- try {
194
- AudienceEntry.parse(entry);
195
- return true;
196
- } catch (error) {
197
- return false;
198
- }
171
+ return AudienceEntry.safeParse(entry).success;
199
172
  };
200
173
 
201
174
  const isExperienceEntry = entry => {
202
- try {
203
- ExperienceEntry.parse(entry);
204
- return true;
205
- } catch (error) {
206
- console.error(error);
207
- return false;
208
- }
175
+ return ExperienceEntry.safeParse(entry).success;
209
176
  };
210
177
 
211
- export { AudienceEntry, AudienceMapper, Entry, ExperienceEntry, ExperienceMapper, isAudienceEntry, isEntry, isExperienceEntry };
178
+ export { AudienceEntry, AudienceMapper, Entry, ExperienceEntry, ExperienceMapper, ExperimentEntry, isAudienceEntry, isEntry, isExperienceEntry };
package/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
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';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('zod'), require('@ninetailed/experience.js-utils')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'zod', '@ninetailed/experience.js-utils'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.UtilsContentful = {}, global.zod, global.experience_jsUtils));
5
+ })(this, (function (exports, zod, experience_jsUtils) { 'use strict';
6
6
 
7
7
  var EntryLink = zod.z.object({
8
8
  type: zod.z.literal('Link'),
@@ -33,7 +33,7 @@
33
33
  })
34
34
  }).optional()
35
35
  }),
36
- fields: zod.z.object({}),
36
+ fields: zod.z.object({}).passthrough(),
37
37
  metadata: zod.z.object({
38
38
  tags: zod.z.array(zod.z.object({
39
39
  sys: EntryLink.extend({
@@ -72,19 +72,7 @@
72
72
  /**
73
73
  * The config of the experience (JSON)
74
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(),
75
+ nt_config: experience_jsUtils.Config,
88
76
 
89
77
  /**
90
78
  * The audience of the experience (Audience)
@@ -100,6 +88,12 @@
100
88
  fields: ExperienceFields
101
89
  });
102
90
 
91
+ var ExperimentEntry = ExperienceEntry.extend({
92
+ fields: ExperienceFields.extend({
93
+ nt_type: zod.z.literal('nt_experiment')
94
+ })
95
+ });
96
+
103
97
  var AudienceMapper =
104
98
  /** @class */
105
99
  function () {
@@ -149,11 +143,9 @@
149
143
  }
150
144
  };
151
145
 
152
- var defaultMapVariant = function (variant, _a) {
153
- var hidden = _a.hidden;
146
+ var defaultMapVariant = function (variant) {
154
147
  return __assign(__assign({}, variant), {
155
- id: variant.sys.id,
156
- hidden: hidden
148
+ id: variant.sys.id
157
149
  });
158
150
  };
159
151
 
@@ -162,75 +154,48 @@
162
154
  function () {
163
155
  function ExperienceMapper() {}
164
156
 
157
+ ExperienceMapper.isExperienceEntry = function (entry) {
158
+ return ExperienceEntry.safeParse(entry).success;
159
+ };
160
+
165
161
  ExperienceMapper.mapExperience = function (entry, options) {
166
162
  var _mapVariant = (options === null || options === void 0 ? void 0 : options.mapVariant) || defaultMapVariant;
167
163
 
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
- };
164
+ var parsedExperience = ExperienceEntry.safeParse(entry);
165
+
166
+ if (!parsedExperience.success) {
167
+ throw new Error('The Experience Input is not valid. Please filter data first with `ExperienceMapper.isExperienceEntry`.');
168
+ }
169
+
170
+ var _a = parsedExperience.data,
171
+ id = _a.sys.id,
172
+ _b = _a.fields,
173
+ nt_type = _b.nt_type,
174
+ nt_name = _b.nt_name,
175
+ nt_config = _b.nt_config,
176
+ nt_audience = _b.nt_audience,
177
+ nt_variants = _b.nt_variants;
178
+ return experience_jsUtils.ExperienceMapper.mapExperience(__assign(__assign({
179
+ id: id,
180
+ type: nt_type,
181
+ name: nt_name
182
+ }, nt_audience ? AudienceMapper.mapAudience(nt_audience) : {}), {
183
+ config: nt_config,
184
+ variants: nt_variants.map(function (variant) {
185
+ return _mapVariant(variant);
224
186
  })
225
- });
187
+ }));
188
+ };
189
+
190
+ ExperienceMapper.isExperiment = function (entry) {
191
+ return ExperimentEntry.safeParse(entry).success;
226
192
  };
227
193
 
228
194
  ExperienceMapper.mapExperiment = function (entry) {
229
195
  return ExperienceMapper.mapExperience(entry, {
230
196
  mapVariant: function () {
231
197
  return {
232
- id: '',
233
- hidden: false
198
+ id: ''
234
199
  };
235
200
  }
236
201
  });
@@ -246,22 +211,11 @@
246
211
  }();
247
212
 
248
213
  var isAudienceEntry = function (entry) {
249
- try {
250
- AudienceEntry.parse(entry);
251
- return true;
252
- } catch (error) {
253
- return false;
254
- }
214
+ return AudienceEntry.safeParse(entry).success;
255
215
  };
256
216
 
257
217
  var isExperienceEntry = function (entry) {
258
- try {
259
- ExperienceEntry.parse(entry);
260
- return true;
261
- } catch (error) {
262
- console.error(error);
263
- return false;
264
- }
218
+ return ExperienceEntry.safeParse(entry).success;
265
219
  };
266
220
 
267
221
  exports.AudienceEntry = AudienceEntry;
@@ -269,6 +223,7 @@
269
223
  exports.Entry = Entry;
270
224
  exports.ExperienceEntry = ExperienceEntry;
271
225
  exports.ExperienceMapper = ExperienceMapper;
226
+ exports.ExperimentEntry = ExperimentEntry;
272
227
  exports.isAudienceEntry = isAudienceEntry;
273
228
  exports.isEntry = isEntry;
274
229
  exports.isExperienceEntry = isExperienceEntry;
@@ -1,6 +1,5 @@
1
+ import { Audience } from '@ninetailed/experience.js-utils';
1
2
  import { AudienceEntry } from '../types/AudienceEntry';
2
3
  export declare class AudienceMapper {
3
- static mapAudience(audience: AudienceEntry): {
4
- id: string;
5
- };
4
+ static mapAudience(audience: AudienceEntry): Audience;
6
5
  }
@@ -1,15 +1,15 @@
1
- import { Variant, ExperienceConfiguration } from '@ninetailed/experience.js';
2
- import { ExperienceEntry, Entry } from '../types';
1
+ import { ExperienceConfiguration } from '@ninetailed/experience.js';
2
+ import { Variant } from '@ninetailed/experience.js-utils';
3
+ import { ExperienceEntry, Entry, ExperimentEntry } from '../types';
3
4
  import { BaselineWithExperiencesEntry } from '../types/BaselineWithExperiencesEntry';
4
- declare type MapVariantOptions = {
5
- hidden: boolean;
6
- };
7
- declare type MapVariant<VariantType = Entry> = (variant: VariantType, options: MapVariantOptions) => Variant;
5
+ declare type MapVariant<VariantType = Entry> = (variant: VariantType) => Variant;
8
6
  declare type MapExperienceOptions<VariantType = Entry> = {
9
7
  mapVariant?: MapVariant<VariantType>;
10
8
  };
11
9
  export declare class ExperienceMapper {
10
+ static isExperienceEntry(entry: Entry): entry is ExperienceEntry;
12
11
  static mapExperience(entry: ExperienceEntry, options?: MapExperienceOptions): ExperienceConfiguration;
12
+ static isExperiment(entry: Entry): entry is ExperimentEntry;
13
13
  static mapExperiment(entry: ExperienceEntry): ExperienceConfiguration;
14
14
  static mapBaselineWithExperiences(entry: BaselineWithExperiencesEntry): ExperienceConfiguration[];
15
15
  }
@@ -1,5 +1,18 @@
1
1
  export declare const isAudienceEntry: (entry?: {
2
+ metadata?: {
3
+ tags: {
4
+ sys: {
5
+ type: "Link";
6
+ id: string;
7
+ linkType: "Tag";
8
+ };
9
+ }[];
10
+ } | undefined;
2
11
  sys: {
12
+ type?: string | undefined;
13
+ createdAt?: string | undefined;
14
+ updatedAt?: string | undefined;
15
+ locale?: string | undefined;
3
16
  revision?: number | undefined;
4
17
  space?: {
5
18
  sys: {
@@ -15,21 +28,18 @@ export declare const isAudienceEntry: (entry?: {
15
28
  linkType: "Environment";
16
29
  };
17
30
  } | undefined;
18
- type: string;
19
- id: string;
20
- createdAt: string;
21
- updatedAt: string;
22
- locale: string;
23
- contentType: {
31
+ contentType?: {
24
32
  sys: {
25
33
  type: "Link";
26
34
  id: string;
27
35
  linkType: "ContentType";
28
36
  };
29
- };
37
+ } | undefined;
38
+ id: string;
30
39
  };
31
40
  fields: {};
32
- metadata: {
41
+ } | undefined) => entry is {
42
+ metadata?: {
33
43
  tags: {
34
44
  sys: {
35
45
  type: "Link";
@@ -37,9 +47,12 @@ export declare const isAudienceEntry: (entry?: {
37
47
  linkType: "Tag";
38
48
  };
39
49
  }[];
40
- };
41
- } | undefined) => entry is {
50
+ } | undefined;
42
51
  sys: {
52
+ type?: string | undefined;
53
+ createdAt?: string | undefined;
54
+ updatedAt?: string | undefined;
55
+ locale?: string | undefined;
43
56
  revision?: number | undefined;
44
57
  space?: {
45
58
  sys: {
@@ -55,30 +68,17 @@ export declare const isAudienceEntry: (entry?: {
55
68
  linkType: "Environment";
56
69
  };
57
70
  } | undefined;
58
- type: string;
59
- id: string;
60
- createdAt: string;
61
- updatedAt: string;
62
- locale: string;
63
- contentType: {
71
+ contentType?: {
64
72
  sys: {
65
73
  type: "Link";
66
74
  id: string;
67
75
  linkType: "ContentType";
68
76
  };
69
- };
77
+ } | undefined;
78
+ id: string;
70
79
  };
71
80
  fields: {
72
81
  nt_name: string;
73
82
  nt_audience_id: string;
74
83
  };
75
- metadata: {
76
- tags: {
77
- sys: {
78
- type: "Link";
79
- id: string;
80
- linkType: "Tag";
81
- };
82
- }[];
83
- };
84
84
  };
package/lib/isEntry.d.ts CHANGED
@@ -1,5 +1,18 @@
1
1
  export declare const isEntry: (entry?: {
2
+ metadata?: {
3
+ tags: {
4
+ sys: {
5
+ type: "Link";
6
+ id: string;
7
+ linkType: "Tag";
8
+ };
9
+ }[];
10
+ } | undefined;
2
11
  sys: {
12
+ type?: string | undefined;
13
+ createdAt?: string | undefined;
14
+ updatedAt?: string | undefined;
15
+ locale?: string | undefined;
3
16
  revision?: number | undefined;
4
17
  space?: {
5
18
  sys: {
@@ -15,21 +28,18 @@ export declare const isEntry: (entry?: {
15
28
  linkType: "Environment";
16
29
  };
17
30
  } | undefined;
18
- type: string;
19
- id: string;
20
- createdAt: string;
21
- updatedAt: string;
22
- locale: string;
23
- contentType: {
31
+ contentType?: {
24
32
  sys: {
25
33
  type: "Link";
26
34
  id: string;
27
35
  linkType: "ContentType";
28
36
  };
29
- };
37
+ } | undefined;
38
+ id: string;
30
39
  };
31
40
  fields: {};
32
- metadata: {
41
+ } | undefined) => entry is {
42
+ metadata?: {
33
43
  tags: {
34
44
  sys: {
35
45
  type: "Link";
@@ -37,9 +47,12 @@ export declare const isEntry: (entry?: {
37
47
  linkType: "Tag";
38
48
  };
39
49
  }[];
40
- };
41
- } | undefined) => entry is {
50
+ } | undefined;
42
51
  sys: {
52
+ type?: string | undefined;
53
+ createdAt?: string | undefined;
54
+ updatedAt?: string | undefined;
55
+ locale?: string | undefined;
43
56
  revision?: number | undefined;
44
57
  space?: {
45
58
  sys: {
@@ -55,27 +68,14 @@ export declare const isEntry: (entry?: {
55
68
  linkType: "Environment";
56
69
  };
57
70
  } | undefined;
58
- type: string;
59
- id: string;
60
- createdAt: string;
61
- updatedAt: string;
62
- locale: string;
63
- contentType: {
71
+ contentType?: {
64
72
  sys: {
65
73
  type: "Link";
66
74
  id: string;
67
75
  linkType: "ContentType";
68
76
  };
69
- };
77
+ } | undefined;
78
+ id: string;
70
79
  };
71
80
  fields: {};
72
- metadata: {
73
- tags: {
74
- sys: {
75
- type: "Link";
76
- id: string;
77
- linkType: "Tag";
78
- };
79
- }[];
80
- };
81
81
  };