@ninetailed/experience.js-utils-contentful 3.0.1-beta.4 → 3.0.2-beta.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.cjs ADDED
@@ -0,0 +1,233 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var zod = require('zod');
6
+ var experience_jsShared = require('@ninetailed/experience.js-shared');
7
+ var experience_jsUtils = require('@ninetailed/experience.js-utils');
8
+
9
+ const EntryFields = zod.z.object({}).catchall(zod.z.unknown());
10
+
11
+ const EntryLink = zod.z.object({
12
+ type: zod.z.string(),
13
+ linkType: zod.z.string(),
14
+ id: zod.z.string()
15
+ });
16
+ const EntrySchema = zod.z.object({
17
+ sys: zod.z.object({
18
+ type: zod.z.string().optional(),
19
+ id: zod.z.string(),
20
+ createdAt: zod.z.string().optional(),
21
+ updatedAt: zod.z.string().optional(),
22
+ locale: zod.z.string().optional(),
23
+ revision: zod.z.number().optional(),
24
+ space: zod.z.object({
25
+ sys: EntryLink.extend({
26
+ linkType: zod.z.string()
27
+ })
28
+ }).optional(),
29
+ environment: zod.z.object({
30
+ sys: EntryLink.extend({
31
+ linkType: zod.z.string()
32
+ })
33
+ }).optional(),
34
+ contentType: zod.z.object({
35
+ sys: EntryLink.extend({
36
+ linkType: zod.z.string()
37
+ })
38
+ }).optional()
39
+ }),
40
+ fields: EntryFields,
41
+ metadata: zod.z.object({
42
+ tags: zod.z.array(zod.z.object({
43
+ sys: EntryLink.extend({
44
+ linkType: zod.z.string()
45
+ })
46
+ }))
47
+ }).optional()
48
+ });
49
+ const parse$1 = input => {
50
+ const output = EntrySchema.parse(input);
51
+ return Object.assign(Object.assign({}, output), {
52
+ fields: input.fields
53
+ });
54
+ };
55
+ const safeParse$1 = input => {
56
+ const output = EntrySchema.safeParse(input);
57
+ if (!output.success) {
58
+ return output;
59
+ }
60
+ return Object.assign(Object.assign({}, output), {
61
+ data: Object.assign(Object.assign({}, output.data), {
62
+ fields: input.fields
63
+ })
64
+ });
65
+ };
66
+ const Entry = Object.assign(Object.assign({}, EntrySchema), {
67
+ parse: parse$1,
68
+ safeParse: safeParse$1
69
+ });
70
+
71
+ const AudienceEntryFields = EntryFields.extend({
72
+ /**
73
+ * The name of the audience (Short Text)
74
+ */
75
+ nt_name: zod.z.string(),
76
+ /**
77
+ * The internal id of the audience (Short Text)
78
+ */
79
+ nt_audience_id: zod.z.string()
80
+ });
81
+ const AudienceEntry = EntrySchema.extend({
82
+ fields: AudienceEntryFields
83
+ });
84
+
85
+ class AudienceMapper {
86
+ static mapAudience(audience) {
87
+ return {
88
+ id: audience.fields.nt_audience_id
89
+ };
90
+ }
91
+ }
92
+ AudienceMapper.isAudienceEntry = entry => {
93
+ return AudienceEntry.safeParse(entry).success;
94
+ };
95
+
96
+ const ExperienceEntryFields = zod.z.object({
97
+ /**
98
+ * The name of the experience (Short Text)
99
+ */
100
+ nt_name: zod.z.string(),
101
+ /**
102
+ * The type if the experience (nt_experiment | nt_personalization)
103
+ */
104
+ nt_type: zod.z.union([zod.z.string(), zod.z.string()]),
105
+ /**
106
+ * The config of the experience (JSON)
107
+ */
108
+ nt_config: experience_jsUtils.Config.optional().nullable().default(null).transform(val => {
109
+ return val !== null && val !== void 0 ? val : {
110
+ traffic: 0,
111
+ distribution: [0.5, 0.5],
112
+ components: []
113
+ };
114
+ }),
115
+ /**
116
+ * The audience of the experience (Audience)
117
+ */
118
+ nt_audience: AudienceEntry.optional().nullable(),
119
+ /**
120
+ * All used variants of the experience (Contentful references to other Content Types)
121
+ */
122
+ nt_variants: zod.z.array(EntrySchema).optional()
123
+ });
124
+ const ExperienceEntrySchema = EntrySchema.extend({
125
+ fields: ExperienceEntryFields
126
+ });
127
+ const parse = input => {
128
+ const output = ExperienceEntrySchema.parse(input);
129
+ return Object.assign(Object.assign({}, output), {
130
+ fields: Object.assign(Object.assign({}, output.fields), {
131
+ nt_variants: input.fields.nt_variants || []
132
+ })
133
+ });
134
+ };
135
+ const safeParse = input => {
136
+ const output = ExperienceEntrySchema.safeParse(input);
137
+ if (!output.success) {
138
+ return output;
139
+ }
140
+ return Object.assign(Object.assign({}, output), {
141
+ data: Object.assign(Object.assign({}, output.data), {
142
+ fields: Object.assign(Object.assign({}, output.data.fields), {
143
+ nt_variants: input.fields.nt_variants || []
144
+ })
145
+ })
146
+ });
147
+ };
148
+ const ExperienceEntry = Object.assign(Object.assign({}, ExperienceEntrySchema), {
149
+ parse,
150
+ safeParse
151
+ });
152
+
153
+ const ExperimentEntry = ExperienceEntry.extend({
154
+ fields: ExperienceEntryFields.extend({
155
+ nt_type: zod.z.string().regex(/^nt_experiment$/g)
156
+ })
157
+ });
158
+
159
+ function mapAudience(ctfAudienceEntry) {
160
+ return {
161
+ id: ctfAudienceEntry.fields.nt_audience_id
162
+ };
163
+ }
164
+ function createExperience(id, fields, variants) {
165
+ const {
166
+ nt_name,
167
+ nt_type,
168
+ nt_audience,
169
+ nt_config
170
+ } = fields;
171
+ return Object.assign(Object.assign({
172
+ id,
173
+ name: nt_name,
174
+ type: nt_type
175
+ }, nt_audience ? {
176
+ audience: mapAudience(nt_audience)
177
+ } : {}), {
178
+ config: nt_config,
179
+ variants
180
+ });
181
+ }
182
+ function validateExperienceEntry(entry) {
183
+ const parsedExperience = ExperienceEntry.safeParse(entry);
184
+ if (!parsedExperience.success) {
185
+ experience_jsShared.logger.warn('[Ninetailed Contentful ExperienceMapper]', 'Error parsing experience', parsedExperience.error.format());
186
+ throw new Error(`[Ninetailed Contentful ExperienceMapper] The Experience Input is not valid. Please filter data first with "ExperienceMapper.isExperienceEntry".\n${JSON.stringify(parsedExperience.error.format(), null, 2)}`);
187
+ }
188
+ return parsedExperience.data;
189
+ }
190
+ class ExperienceMapper {
191
+ static isExperienceEntry(entry) {
192
+ return ExperienceEntry.safeParse(entry).success;
193
+ }
194
+ static mapExperience(ctfEntry) {
195
+ const {
196
+ sys,
197
+ fields
198
+ } = validateExperienceEntry(ctfEntry);
199
+ const variants = fields.nt_variants.map(variant => Object.assign(Object.assign({}, variant), {
200
+ id: variant.sys.id
201
+ }));
202
+ const experience = createExperience(sys.id, fields, variants);
203
+ return experience_jsUtils.ExperienceMapper.mapExperience(experience);
204
+ }
205
+ static mapCustomExperience(ctfEntry, mapFn) {
206
+ const {
207
+ sys,
208
+ fields
209
+ } = validateExperienceEntry(ctfEntry);
210
+ const variants = fields.nt_variants.map(variantEntry => mapFn(variantEntry));
211
+ const experience = createExperience(sys.id, fields, variants);
212
+ return experience_jsUtils.ExperienceMapper.mapExperience(experience);
213
+ }
214
+ static isExperiment(entry) {
215
+ return ExperimentEntry.safeParse(entry).success;
216
+ }
217
+ static mapExperiment(entry) {
218
+ return ExperienceMapper.mapCustomExperience(entry, () => ({
219
+ id: ''
220
+ }));
221
+ }
222
+ static mapBaselineWithExperiences(entry) {
223
+ return entry.fields.nt_experiences.filter(ExperienceMapper.isExperienceEntry).map(experience => ExperienceMapper.mapExperience(experience));
224
+ }
225
+ }
226
+
227
+ const isEntry = entry => {
228
+ return Entry.safeParse(entry).success;
229
+ };
230
+
231
+ exports.AudienceMapper = AudienceMapper;
232
+ exports.ExperienceMapper = ExperienceMapper;
233
+ exports.isEntry = isEntry;
package/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
- export * from './types';
2
- export { AudienceMapper, ExperienceMapper, isEntry, isAudienceEntry, isExperienceEntry, } from './lib';
3
- export type { MapVariant } from './lib';
1
+ export { AudienceMapper } from './lib/AudienceMapper';
2
+ export { ExperienceMapper } from './lib/ExperienceMapper';
3
+ export { isEntry } from './lib/isEntry';
4
+ export type { AudienceEntry, AudienceEntryLike, AudienceEntryFields, } from './types/AudienceEntry';
5
+ export type { BaselineWithExperiencesEntry, BaselineWithExperiencesEntryLike, } from './types/BaselineWithExperiencesEntry';
6
+ export type { Entry, EntryLike } from './types/Entry';
7
+ export type { EntryFields } from './types/EntryFields';
8
+ export type { ExperienceEntry, ExperienceEntryLike, ExperienceFields, } from './types/ExperienceEntry';
9
+ export type { ExperimentEntry, ExperimentEntryLike, } from './types/ExperimentEntry';
package/index.js ADDED
@@ -0,0 +1,227 @@
1
+ import { z } from 'zod';
2
+ import { logger } from '@ninetailed/experience.js-shared';
3
+ import { Config, ExperienceMapper as ExperienceMapper$1 } from '@ninetailed/experience.js-utils';
4
+
5
+ const EntryFields = z.object({}).catchall(z.unknown());
6
+
7
+ const EntryLink = z.object({
8
+ type: z.string(),
9
+ linkType: z.string(),
10
+ id: z.string()
11
+ });
12
+ const EntrySchema = z.object({
13
+ sys: z.object({
14
+ type: z.string().optional(),
15
+ id: z.string(),
16
+ createdAt: z.string().optional(),
17
+ updatedAt: z.string().optional(),
18
+ locale: z.string().optional(),
19
+ revision: z.number().optional(),
20
+ space: z.object({
21
+ sys: EntryLink.extend({
22
+ linkType: z.string()
23
+ })
24
+ }).optional(),
25
+ environment: z.object({
26
+ sys: EntryLink.extend({
27
+ linkType: z.string()
28
+ })
29
+ }).optional(),
30
+ contentType: z.object({
31
+ sys: EntryLink.extend({
32
+ linkType: z.string()
33
+ })
34
+ }).optional()
35
+ }),
36
+ fields: EntryFields,
37
+ metadata: z.object({
38
+ tags: z.array(z.object({
39
+ sys: EntryLink.extend({
40
+ linkType: z.string()
41
+ })
42
+ }))
43
+ }).optional()
44
+ });
45
+ const parse$1 = input => {
46
+ const output = EntrySchema.parse(input);
47
+ return Object.assign(Object.assign({}, output), {
48
+ fields: input.fields
49
+ });
50
+ };
51
+ const safeParse$1 = input => {
52
+ const output = EntrySchema.safeParse(input);
53
+ if (!output.success) {
54
+ return output;
55
+ }
56
+ return Object.assign(Object.assign({}, output), {
57
+ data: Object.assign(Object.assign({}, output.data), {
58
+ fields: input.fields
59
+ })
60
+ });
61
+ };
62
+ const Entry = Object.assign(Object.assign({}, EntrySchema), {
63
+ parse: parse$1,
64
+ safeParse: safeParse$1
65
+ });
66
+
67
+ const AudienceEntryFields = EntryFields.extend({
68
+ /**
69
+ * The name of the audience (Short Text)
70
+ */
71
+ nt_name: z.string(),
72
+ /**
73
+ * The internal id of the audience (Short Text)
74
+ */
75
+ nt_audience_id: z.string()
76
+ });
77
+ const AudienceEntry = EntrySchema.extend({
78
+ fields: AudienceEntryFields
79
+ });
80
+
81
+ class AudienceMapper {
82
+ static mapAudience(audience) {
83
+ return {
84
+ id: audience.fields.nt_audience_id
85
+ };
86
+ }
87
+ }
88
+ AudienceMapper.isAudienceEntry = entry => {
89
+ return AudienceEntry.safeParse(entry).success;
90
+ };
91
+
92
+ const ExperienceEntryFields = z.object({
93
+ /**
94
+ * The name of the experience (Short Text)
95
+ */
96
+ nt_name: z.string(),
97
+ /**
98
+ * The type if the experience (nt_experiment | nt_personalization)
99
+ */
100
+ nt_type: z.union([z.string(), z.string()]),
101
+ /**
102
+ * The config of the experience (JSON)
103
+ */
104
+ nt_config: Config.optional().nullable().default(null).transform(val => {
105
+ return val !== null && val !== void 0 ? val : {
106
+ traffic: 0,
107
+ distribution: [0.5, 0.5],
108
+ components: []
109
+ };
110
+ }),
111
+ /**
112
+ * The audience of the experience (Audience)
113
+ */
114
+ nt_audience: AudienceEntry.optional().nullable(),
115
+ /**
116
+ * All used variants of the experience (Contentful references to other Content Types)
117
+ */
118
+ nt_variants: z.array(EntrySchema).optional()
119
+ });
120
+ const ExperienceEntrySchema = EntrySchema.extend({
121
+ fields: ExperienceEntryFields
122
+ });
123
+ const parse = input => {
124
+ const output = ExperienceEntrySchema.parse(input);
125
+ return Object.assign(Object.assign({}, output), {
126
+ fields: Object.assign(Object.assign({}, output.fields), {
127
+ nt_variants: input.fields.nt_variants || []
128
+ })
129
+ });
130
+ };
131
+ const safeParse = input => {
132
+ const output = ExperienceEntrySchema.safeParse(input);
133
+ if (!output.success) {
134
+ return output;
135
+ }
136
+ return Object.assign(Object.assign({}, output), {
137
+ data: Object.assign(Object.assign({}, output.data), {
138
+ fields: Object.assign(Object.assign({}, output.data.fields), {
139
+ nt_variants: input.fields.nt_variants || []
140
+ })
141
+ })
142
+ });
143
+ };
144
+ const ExperienceEntry = Object.assign(Object.assign({}, ExperienceEntrySchema), {
145
+ parse,
146
+ safeParse
147
+ });
148
+
149
+ const ExperimentEntry = ExperienceEntry.extend({
150
+ fields: ExperienceEntryFields.extend({
151
+ nt_type: z.string().regex(/^nt_experiment$/g)
152
+ })
153
+ });
154
+
155
+ function mapAudience(ctfAudienceEntry) {
156
+ return {
157
+ id: ctfAudienceEntry.fields.nt_audience_id
158
+ };
159
+ }
160
+ function createExperience(id, fields, variants) {
161
+ const {
162
+ nt_name,
163
+ nt_type,
164
+ nt_audience,
165
+ nt_config
166
+ } = fields;
167
+ return Object.assign(Object.assign({
168
+ id,
169
+ name: nt_name,
170
+ type: nt_type
171
+ }, nt_audience ? {
172
+ audience: mapAudience(nt_audience)
173
+ } : {}), {
174
+ config: nt_config,
175
+ variants
176
+ });
177
+ }
178
+ function validateExperienceEntry(entry) {
179
+ const parsedExperience = ExperienceEntry.safeParse(entry);
180
+ if (!parsedExperience.success) {
181
+ logger.warn('[Ninetailed Contentful ExperienceMapper]', 'Error parsing experience', parsedExperience.error.format());
182
+ throw new Error(`[Ninetailed Contentful ExperienceMapper] The Experience Input is not valid. Please filter data first with "ExperienceMapper.isExperienceEntry".\n${JSON.stringify(parsedExperience.error.format(), null, 2)}`);
183
+ }
184
+ return parsedExperience.data;
185
+ }
186
+ class ExperienceMapper {
187
+ static isExperienceEntry(entry) {
188
+ return ExperienceEntry.safeParse(entry).success;
189
+ }
190
+ static mapExperience(ctfEntry) {
191
+ const {
192
+ sys,
193
+ fields
194
+ } = validateExperienceEntry(ctfEntry);
195
+ const variants = fields.nt_variants.map(variant => Object.assign(Object.assign({}, variant), {
196
+ id: variant.sys.id
197
+ }));
198
+ const experience = createExperience(sys.id, fields, variants);
199
+ return ExperienceMapper$1.mapExperience(experience);
200
+ }
201
+ static mapCustomExperience(ctfEntry, mapFn) {
202
+ const {
203
+ sys,
204
+ fields
205
+ } = validateExperienceEntry(ctfEntry);
206
+ const variants = fields.nt_variants.map(variantEntry => mapFn(variantEntry));
207
+ const experience = createExperience(sys.id, fields, variants);
208
+ return ExperienceMapper$1.mapExperience(experience);
209
+ }
210
+ static isExperiment(entry) {
211
+ return ExperimentEntry.safeParse(entry).success;
212
+ }
213
+ static mapExperiment(entry) {
214
+ return ExperienceMapper.mapCustomExperience(entry, () => ({
215
+ id: ''
216
+ }));
217
+ }
218
+ static mapBaselineWithExperiences(entry) {
219
+ return entry.fields.nt_experiences.filter(ExperienceMapper.isExperienceEntry).map(experience => ExperienceMapper.mapExperience(experience));
220
+ }
221
+ }
222
+
223
+ const isEntry = entry => {
224
+ return Entry.safeParse(entry).success;
225
+ };
226
+
227
+ export { AudienceMapper, ExperienceMapper, isEntry };
@@ -1,5 +1,51 @@
1
1
  import { Audience } from '@ninetailed/experience.js-utils';
2
2
  import { AudienceEntry } from '../types/AudienceEntry';
3
+ import type { AudienceEntryLike } from '../types/AudienceEntry';
3
4
  export declare class AudienceMapper {
5
+ static isAudienceEntry: (entry: AudienceEntryLike) => entry is {
6
+ metadata?: {
7
+ tags: {
8
+ sys: {
9
+ type: string;
10
+ id: string;
11
+ linkType: string;
12
+ };
13
+ }[];
14
+ } | undefined;
15
+ sys: {
16
+ type?: string | undefined;
17
+ createdAt?: string | undefined;
18
+ updatedAt?: string | undefined;
19
+ locale?: string | undefined;
20
+ revision?: number | undefined;
21
+ space?: {
22
+ sys: {
23
+ type: string;
24
+ id: string;
25
+ linkType: string;
26
+ };
27
+ } | undefined;
28
+ environment?: {
29
+ sys: {
30
+ type: string;
31
+ id: string;
32
+ linkType: string;
33
+ };
34
+ } | undefined;
35
+ contentType?: {
36
+ sys: {
37
+ type: string;
38
+ id: string;
39
+ linkType: string;
40
+ };
41
+ } | undefined;
42
+ id: string;
43
+ };
44
+ fields: {
45
+ [x: string]: unknown;
46
+ nt_name: string;
47
+ nt_audience_id: string;
48
+ };
49
+ };
4
50
  static mapAudience(audience: AudienceEntry): Audience;
5
51
  }
@@ -1,16 +1,101 @@
1
- import { ExperienceConfiguration } from '@ninetailed/experience.js';
2
- import { Variant } from '@ninetailed/experience.js-utils';
3
- import { ExperienceEntry, Entry, ExperimentEntry } from '../types';
1
+ import { Reference } from '@ninetailed/experience.js';
4
2
  import { BaselineWithExperiencesEntry } from '../types/BaselineWithExperiencesEntry';
5
- export declare type MapVariant<VariantType extends Entry = Entry> = (variant: VariantType) => Variant;
6
- declare type MapExperienceOptions = {
7
- mapVariant?: MapVariant;
8
- };
3
+ import { EntryLike } from '../types/Entry';
4
+ import type { EntryFields } from '../types/EntryFields';
5
+ import { ExperienceEntry, ExperienceEntryLike } from '../types/ExperienceEntry';
6
+ import { ExperimentEntry } from '../types/ExperimentEntry';
7
+ export declare type MapVariantFunction<In extends EntryFields, Out extends Reference> = (input: EntryLike<In> & {
8
+ fields: In;
9
+ }) => Out;
9
10
  export declare class ExperienceMapper {
10
- static isExperienceEntry(entry: unknown): entry is ExperienceEntry;
11
- static mapExperience(entry: ExperienceEntry, options?: MapExperienceOptions): ExperienceConfiguration;
12
- static isExperiment(entry: Entry): entry is ExperimentEntry;
13
- static mapExperiment(entry: ExperienceEntry): ExperienceConfiguration;
14
- static mapBaselineWithExperiences(entry: BaselineWithExperiencesEntry): ExperienceConfiguration[];
11
+ static isExperienceEntry<VariantFields extends EntryFields>(entry: ExperienceEntryLike<VariantFields>): entry is ExperienceEntry<VariantFields>;
12
+ static mapExperience<VariantFields extends EntryFields>(ctfEntry: ExperienceEntryLike<VariantFields>): import("@ninetailed/experience.js").ExperienceConfiguration<{
13
+ id: string;
14
+ sys: {
15
+ type?: string | undefined;
16
+ createdAt?: string | undefined;
17
+ updatedAt?: string | undefined;
18
+ locale?: string | undefined;
19
+ revision?: number | undefined;
20
+ space?: {
21
+ sys: {
22
+ type: string;
23
+ id: string;
24
+ linkType: string;
25
+ };
26
+ } | undefined;
27
+ environment?: {
28
+ sys: {
29
+ type: string;
30
+ id: string;
31
+ linkType: string;
32
+ };
33
+ } | undefined;
34
+ contentType?: {
35
+ sys: {
36
+ type: string;
37
+ id: string;
38
+ linkType: string;
39
+ };
40
+ } | undefined;
41
+ id: string;
42
+ };
43
+ metadata?: {
44
+ tags: {
45
+ sys: {
46
+ type: string;
47
+ id: string;
48
+ linkType: string;
49
+ };
50
+ }[];
51
+ } | undefined;
52
+ fields: VariantFields;
53
+ }>;
54
+ static mapCustomExperience<Variant extends Reference, VariantFields extends EntryFields>(ctfEntry: ExperienceEntryLike<VariantFields>, mapFn: MapVariantFunction<VariantFields, Variant>): import("@ninetailed/experience.js").ExperienceConfiguration<Variant>;
55
+ static isExperiment(entry: ExperienceEntryLike): entry is ExperimentEntry;
56
+ static mapExperiment(entry: ExperienceEntryLike): import("@ninetailed/experience.js").ExperienceConfiguration<{
57
+ id: string;
58
+ }>;
59
+ static mapBaselineWithExperiences<Fields extends EntryFields>(entry: BaselineWithExperiencesEntry<Fields>): import("@ninetailed/experience.js").ExperienceConfiguration<{
60
+ id: string;
61
+ sys: {
62
+ type?: string | undefined;
63
+ createdAt?: string | undefined;
64
+ updatedAt?: string | undefined;
65
+ locale?: string | undefined;
66
+ revision?: number | undefined;
67
+ space?: {
68
+ sys: {
69
+ type: string;
70
+ id: string;
71
+ linkType: string;
72
+ };
73
+ } | undefined;
74
+ environment?: {
75
+ sys: {
76
+ type: string;
77
+ id: string;
78
+ linkType: string;
79
+ };
80
+ } | undefined;
81
+ contentType?: {
82
+ sys: {
83
+ type: string;
84
+ id: string;
85
+ linkType: string;
86
+ };
87
+ } | undefined;
88
+ id: string;
89
+ };
90
+ metadata?: {
91
+ tags: {
92
+ sys: {
93
+ type: string;
94
+ id: string;
95
+ linkType: string;
96
+ };
97
+ }[];
98
+ } | undefined;
99
+ fields: object;
100
+ }>[];
15
101
  }
16
- export {};