@ninetailed/experience.js-utils 3.0.1-beta.3 → 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 +197 -0
- package/index.d.ts +11 -2
- package/{index.esm.js → index.js} +68 -41
- package/lib/ExperienceMapper.d.ts +7 -10
- package/package.json +8 -14
- package/types/Audience.d.ts +1 -0
- package/types/Config.d.ts +6 -0
- package/types/Experience.d.ts +2257 -12
- package/types/Experiment.d.ts +1999 -13
- package/types/Variant.d.ts +4 -1
- package/types/zodArrayIgnoreUnknown.d.ts +1 -1
- package/index.umd.js +0 -217
- package/lib/index.d.ts +0 -1
- package/types/index.d.ts +0 -5
package/index.cjs
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var experience_jsShared = require('@ninetailed/experience.js-shared');
|
|
6
|
+
var zod = require('zod');
|
|
7
|
+
|
|
8
|
+
const Audience = zod.z.object({
|
|
9
|
+
id: zod.z.string()
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const Config = zod.z.object({
|
|
13
|
+
distribution: zod.z.array(zod.z.number()).default([0.5, 0.5]),
|
|
14
|
+
traffic: zod.z.number().default(0),
|
|
15
|
+
components: zod.z.array(zod.z.object({
|
|
16
|
+
baseline: zod.z.object({
|
|
17
|
+
id: zod.z.string().default('')
|
|
18
|
+
}),
|
|
19
|
+
variants: zod.z.array(zod.z.object({
|
|
20
|
+
id: zod.z.string().default(''),
|
|
21
|
+
hidden: zod.z.boolean().default(false)
|
|
22
|
+
}))
|
|
23
|
+
})).default([{
|
|
24
|
+
baseline: {
|
|
25
|
+
id: ''
|
|
26
|
+
},
|
|
27
|
+
variants: [{
|
|
28
|
+
id: '',
|
|
29
|
+
hidden: false
|
|
30
|
+
}]
|
|
31
|
+
}])
|
|
32
|
+
});
|
|
33
|
+
// export interface Config {
|
|
34
|
+
// distribution: number[];
|
|
35
|
+
// traffic: number;
|
|
36
|
+
// components: BaselineWithVariantRefs[];
|
|
37
|
+
// }
|
|
38
|
+
|
|
39
|
+
const Variant = zod.z.object({
|
|
40
|
+
id: zod.z.string()
|
|
41
|
+
}).catchall(zod.z.unknown());
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Zod helper for parsing arrays and ignore items not specified in the schema
|
|
45
|
+
*
|
|
46
|
+
* @param zodUnion - union of known types
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* const binaryArraySchema = arrayIgnoreUnknown(z.union([z.literal('0'), z.literal('1')]))
|
|
50
|
+
* type BinaryArray = z.TypeOf<typeof binaryArraySchema>
|
|
51
|
+
*
|
|
52
|
+
* const binaryArray: BinaryArray = binaryArraySchema.parse(['0', '1', '2', '0'])
|
|
53
|
+
* console.log(binaryArray) // ['0', '1', '0']
|
|
54
|
+
*/
|
|
55
|
+
function zodArrayIgnoreUnknown(zodType) {
|
|
56
|
+
const isKnownItem = item => zodType.safeParse(item).success;
|
|
57
|
+
return zod.z.preprocess(val => toSafeArray(val).filter(isKnownItem), zod.z.array(zodType));
|
|
58
|
+
}
|
|
59
|
+
function toSafeArray(item) {
|
|
60
|
+
if (isArray(item)) {
|
|
61
|
+
return item;
|
|
62
|
+
}
|
|
63
|
+
return [item];
|
|
64
|
+
}
|
|
65
|
+
function isArray(item) {
|
|
66
|
+
return Array.isArray(item);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const ExperienceSchema = zod.z.object({
|
|
70
|
+
id: zod.z.string(),
|
|
71
|
+
/**
|
|
72
|
+
* The name of the experience (Short Text)
|
|
73
|
+
*/
|
|
74
|
+
name: zod.z.string(),
|
|
75
|
+
/**
|
|
76
|
+
* The type if the experience (nt_experiment | nt_personalization)
|
|
77
|
+
*/
|
|
78
|
+
type: zod.z.union([zod.z.string().regex(/^nt_experiment$/g), zod.z.string().regex(/^nt_personalization$/g)]),
|
|
79
|
+
/**
|
|
80
|
+
* The config of the experience (JSON)
|
|
81
|
+
*/
|
|
82
|
+
config: Config.default({}),
|
|
83
|
+
/**
|
|
84
|
+
* The audience of the experience (Audience)
|
|
85
|
+
*/
|
|
86
|
+
audience: Audience.optional().nullable(),
|
|
87
|
+
/**
|
|
88
|
+
* All used variants of the experience (References to other Content Types)
|
|
89
|
+
*/
|
|
90
|
+
variants: zodArrayIgnoreUnknown(Variant).default([])
|
|
91
|
+
});
|
|
92
|
+
const parse$1 = input => {
|
|
93
|
+
const output = ExperienceSchema.parse(input);
|
|
94
|
+
return Object.assign(Object.assign({}, output), {
|
|
95
|
+
variants: input.variants
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
const safeParse$1 = input => {
|
|
99
|
+
const output = ExperienceSchema.safeParse(input);
|
|
100
|
+
if (!output.success) {
|
|
101
|
+
return output;
|
|
102
|
+
}
|
|
103
|
+
return Object.assign(Object.assign({}, output), {
|
|
104
|
+
data: Object.assign(Object.assign({}, output.data), {
|
|
105
|
+
variants: input.variants
|
|
106
|
+
})
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
const Experience = Object.assign(Object.assign({}, ExperienceSchema), {
|
|
110
|
+
parse: parse$1,
|
|
111
|
+
safeParse: safeParse$1
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const ExperimentSchema = ExperienceSchema.extend({
|
|
115
|
+
type: zod.z.string().regex(/^nt_experiment$/g)
|
|
116
|
+
});
|
|
117
|
+
const parse = input => {
|
|
118
|
+
const output = ExperimentSchema.parse(input);
|
|
119
|
+
return Object.assign(Object.assign({}, output), {
|
|
120
|
+
variants: input.variants
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
const safeParse = input => {
|
|
124
|
+
const output = ExperimentSchema.safeParse(input);
|
|
125
|
+
if (!output.success) {
|
|
126
|
+
return output;
|
|
127
|
+
}
|
|
128
|
+
return Object.assign(Object.assign({}, output), {
|
|
129
|
+
data: Object.assign(Object.assign({}, output.data), {
|
|
130
|
+
variants: input.variants
|
|
131
|
+
})
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
const Experiment = Object.assign(Object.assign({}, ExperimentSchema), {
|
|
135
|
+
parse,
|
|
136
|
+
safeParse
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
class ExperienceMapper {
|
|
140
|
+
static isExperienceEntry(experience) {
|
|
141
|
+
return Experience.safeParse(experience).success;
|
|
142
|
+
}
|
|
143
|
+
static mapExperience(experience) {
|
|
144
|
+
const parsedExperience = Experience.safeParse(experience);
|
|
145
|
+
if (!parsedExperience.success) {
|
|
146
|
+
experience_jsShared.logger.warn('[Ninetailed ExperienceMapper]', 'Error parsing experience', parsedExperience.error.format());
|
|
147
|
+
throw new Error(`[Ninetailed ExperienceMapper] The Experience Input is not valid. Please filter data first with "ExperienceMapper.isExperienceEntry".\n${JSON.stringify(parsedExperience.error.format(), null, 2)}`);
|
|
148
|
+
}
|
|
149
|
+
const {
|
|
150
|
+
id,
|
|
151
|
+
type,
|
|
152
|
+
audience,
|
|
153
|
+
config,
|
|
154
|
+
variants
|
|
155
|
+
} = parsedExperience.data;
|
|
156
|
+
const {
|
|
157
|
+
components,
|
|
158
|
+
traffic
|
|
159
|
+
} = config;
|
|
160
|
+
return Object.assign(Object.assign({
|
|
161
|
+
id,
|
|
162
|
+
type: type
|
|
163
|
+
}, audience ? {
|
|
164
|
+
audience
|
|
165
|
+
} : {}), {
|
|
166
|
+
trafficAllocation: traffic,
|
|
167
|
+
distribution: config.distribution.map((percentage, index) => ({
|
|
168
|
+
index,
|
|
169
|
+
start: config.distribution.slice(0, index).reduce((a, b) => a + b, 0),
|
|
170
|
+
end: config.distribution.slice(0, index + 1).reduce((a, b) => a + b, 0)
|
|
171
|
+
})),
|
|
172
|
+
components: components.map(component => ({
|
|
173
|
+
baseline: component.baseline,
|
|
174
|
+
variants: component.variants.map(variantRef => {
|
|
175
|
+
if (variantRef.hidden) {
|
|
176
|
+
return variantRef;
|
|
177
|
+
}
|
|
178
|
+
const matchingVariant = variants.find(variant => variant.id === variantRef.id);
|
|
179
|
+
return matchingVariant !== null && matchingVariant !== void 0 ? matchingVariant : null;
|
|
180
|
+
}).filter(variant => variant !== null)
|
|
181
|
+
}))
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
static isExperimentEntry(experiment) {
|
|
185
|
+
return Experiment.safeParse(experiment).success;
|
|
186
|
+
}
|
|
187
|
+
static mapExperiment(experiment) {
|
|
188
|
+
return ExperienceMapper.mapExperience(experiment);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
exports.Audience = Audience;
|
|
193
|
+
exports.Config = Config;
|
|
194
|
+
exports.Experience = Experience;
|
|
195
|
+
exports.ExperienceMapper = ExperienceMapper;
|
|
196
|
+
exports.Experiment = Experiment;
|
|
197
|
+
exports.Variant = Variant;
|
package/index.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
export { ExperienceMapper } from './lib';
|
|
2
|
-
export {
|
|
1
|
+
export { ExperienceMapper } from './lib/ExperienceMapper';
|
|
2
|
+
export { Audience } from './types/Audience';
|
|
3
|
+
export { Config } from './types/Config';
|
|
4
|
+
export { Experience } from './types/Experience';
|
|
5
|
+
export { Experiment } from './types/Experiment';
|
|
6
|
+
export { Variant } from './types/Variant';
|
|
7
|
+
export type { AudienceLike } from './types/Audience';
|
|
8
|
+
export type { ConfigLike } from './types/Config';
|
|
9
|
+
export type { ExperienceLike } from './types/Experience';
|
|
10
|
+
export type { ExperimentLike } from './types/Experiment';
|
|
11
|
+
export type { VariantLike } from './types/Variant';
|
|
@@ -26,10 +26,15 @@ const Config = z.object({
|
|
|
26
26
|
}]
|
|
27
27
|
}])
|
|
28
28
|
});
|
|
29
|
+
// export interface Config {
|
|
30
|
+
// distribution: number[];
|
|
31
|
+
// traffic: number;
|
|
32
|
+
// components: BaselineWithVariantRefs[];
|
|
33
|
+
// }
|
|
29
34
|
|
|
30
35
|
const Variant = z.object({
|
|
31
36
|
id: z.string()
|
|
32
|
-
}).
|
|
37
|
+
}).catchall(z.unknown());
|
|
33
38
|
|
|
34
39
|
/**
|
|
35
40
|
* Zod helper for parsing arrays and ignore items not specified in the schema
|
|
@@ -43,71 +48,100 @@ const Variant = z.object({
|
|
|
43
48
|
* const binaryArray: BinaryArray = binaryArraySchema.parse(['0', '1', '2', '0'])
|
|
44
49
|
* console.log(binaryArray) // ['0', '1', '0']
|
|
45
50
|
*/
|
|
46
|
-
|
|
47
51
|
function zodArrayIgnoreUnknown(zodType) {
|
|
48
52
|
const isKnownItem = item => zodType.safeParse(item).success;
|
|
49
|
-
|
|
50
53
|
return z.preprocess(val => toSafeArray(val).filter(isKnownItem), z.array(zodType));
|
|
51
54
|
}
|
|
52
|
-
|
|
53
55
|
function toSafeArray(item) {
|
|
54
56
|
if (isArray(item)) {
|
|
55
57
|
return item;
|
|
56
58
|
}
|
|
57
|
-
|
|
58
59
|
return [item];
|
|
59
60
|
}
|
|
60
|
-
|
|
61
61
|
function isArray(item) {
|
|
62
62
|
return Array.isArray(item);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
const
|
|
65
|
+
const ExperienceSchema = z.object({
|
|
66
66
|
id: z.string(),
|
|
67
|
-
|
|
68
67
|
/**
|
|
69
68
|
* The name of the experience (Short Text)
|
|
70
69
|
*/
|
|
71
70
|
name: z.string(),
|
|
72
|
-
|
|
73
71
|
/**
|
|
74
72
|
* The type if the experience (nt_experiment | nt_personalization)
|
|
75
73
|
*/
|
|
76
|
-
type: z.union([z.
|
|
77
|
-
|
|
74
|
+
type: z.union([z.string().regex(/^nt_experiment$/g), z.string().regex(/^nt_personalization$/g)]),
|
|
78
75
|
/**
|
|
79
76
|
* The config of the experience (JSON)
|
|
80
77
|
*/
|
|
81
78
|
config: Config.default({}),
|
|
82
|
-
|
|
83
79
|
/**
|
|
84
80
|
* The audience of the experience (Audience)
|
|
85
81
|
*/
|
|
86
82
|
audience: Audience.optional().nullable(),
|
|
87
|
-
|
|
88
83
|
/**
|
|
89
84
|
* All used variants of the experience (References to other Content Types)
|
|
90
85
|
*/
|
|
91
86
|
variants: zodArrayIgnoreUnknown(Variant).default([])
|
|
92
87
|
});
|
|
88
|
+
const parse$1 = input => {
|
|
89
|
+
const output = ExperienceSchema.parse(input);
|
|
90
|
+
return Object.assign(Object.assign({}, output), {
|
|
91
|
+
variants: input.variants
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
const safeParse$1 = input => {
|
|
95
|
+
const output = ExperienceSchema.safeParse(input);
|
|
96
|
+
if (!output.success) {
|
|
97
|
+
return output;
|
|
98
|
+
}
|
|
99
|
+
return Object.assign(Object.assign({}, output), {
|
|
100
|
+
data: Object.assign(Object.assign({}, output.data), {
|
|
101
|
+
variants: input.variants
|
|
102
|
+
})
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
const Experience = Object.assign(Object.assign({}, ExperienceSchema), {
|
|
106
|
+
parse: parse$1,
|
|
107
|
+
safeParse: safeParse$1
|
|
108
|
+
});
|
|
93
109
|
|
|
94
|
-
const
|
|
95
|
-
type: z.
|
|
110
|
+
const ExperimentSchema = ExperienceSchema.extend({
|
|
111
|
+
type: z.string().regex(/^nt_experiment$/g)
|
|
112
|
+
});
|
|
113
|
+
const parse = input => {
|
|
114
|
+
const output = ExperimentSchema.parse(input);
|
|
115
|
+
return Object.assign(Object.assign({}, output), {
|
|
116
|
+
variants: input.variants
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
const safeParse = input => {
|
|
120
|
+
const output = ExperimentSchema.safeParse(input);
|
|
121
|
+
if (!output.success) {
|
|
122
|
+
return output;
|
|
123
|
+
}
|
|
124
|
+
return Object.assign(Object.assign({}, output), {
|
|
125
|
+
data: Object.assign(Object.assign({}, output.data), {
|
|
126
|
+
variants: input.variants
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
const Experiment = Object.assign(Object.assign({}, ExperimentSchema), {
|
|
131
|
+
parse,
|
|
132
|
+
safeParse
|
|
96
133
|
});
|
|
97
134
|
|
|
98
135
|
class ExperienceMapper {
|
|
99
136
|
static isExperienceEntry(experience) {
|
|
100
137
|
return Experience.safeParse(experience).success;
|
|
101
138
|
}
|
|
102
|
-
|
|
103
139
|
static mapExperience(experience) {
|
|
104
140
|
const parsedExperience = Experience.safeParse(experience);
|
|
105
|
-
|
|
106
141
|
if (!parsedExperience.success) {
|
|
107
142
|
logger.warn('[Ninetailed ExperienceMapper]', 'Error parsing experience', parsedExperience.error.format());
|
|
108
143
|
throw new Error(`[Ninetailed ExperienceMapper] The Experience Input is not valid. Please filter data first with "ExperienceMapper.isExperienceEntry".\n${JSON.stringify(parsedExperience.error.format(), null, 2)}`);
|
|
109
144
|
}
|
|
110
|
-
|
|
111
145
|
const {
|
|
112
146
|
id,
|
|
113
147
|
type,
|
|
@@ -115,47 +149,40 @@ class ExperienceMapper {
|
|
|
115
149
|
config,
|
|
116
150
|
variants
|
|
117
151
|
} = parsedExperience.data;
|
|
152
|
+
const {
|
|
153
|
+
components,
|
|
154
|
+
traffic
|
|
155
|
+
} = config;
|
|
118
156
|
return Object.assign(Object.assign({
|
|
119
157
|
id,
|
|
120
|
-
type
|
|
158
|
+
type: type
|
|
121
159
|
}, audience ? {
|
|
122
160
|
audience
|
|
123
161
|
} : {}), {
|
|
124
|
-
trafficAllocation:
|
|
162
|
+
trafficAllocation: traffic,
|
|
125
163
|
distribution: config.distribution.map((percentage, index) => ({
|
|
126
164
|
index,
|
|
127
165
|
start: config.distribution.slice(0, index).reduce((a, b) => a + b, 0),
|
|
128
166
|
end: config.distribution.slice(0, index + 1).reduce((a, b) => a + b, 0)
|
|
129
167
|
})),
|
|
130
|
-
components:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (!matchingVariant) {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return matchingVariant;
|
|
145
|
-
}).filter(variant => variant !== null)
|
|
146
|
-
};
|
|
147
|
-
})
|
|
168
|
+
components: components.map(component => ({
|
|
169
|
+
baseline: component.baseline,
|
|
170
|
+
variants: component.variants.map(variantRef => {
|
|
171
|
+
if (variantRef.hidden) {
|
|
172
|
+
return variantRef;
|
|
173
|
+
}
|
|
174
|
+
const matchingVariant = variants.find(variant => variant.id === variantRef.id);
|
|
175
|
+
return matchingVariant !== null && matchingVariant !== void 0 ? matchingVariant : null;
|
|
176
|
+
}).filter(variant => variant !== null)
|
|
177
|
+
}))
|
|
148
178
|
});
|
|
149
179
|
}
|
|
150
|
-
|
|
151
180
|
static isExperimentEntry(experiment) {
|
|
152
181
|
return Experiment.safeParse(experiment).success;
|
|
153
182
|
}
|
|
154
|
-
|
|
155
183
|
static mapExperiment(experiment) {
|
|
156
184
|
return ExperienceMapper.mapExperience(experiment);
|
|
157
185
|
}
|
|
158
|
-
|
|
159
186
|
}
|
|
160
187
|
|
|
161
188
|
export { Audience, Config, Experience, ExperienceMapper, Experiment, Variant };
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { ExperienceConfiguration } from '@ninetailed/experience.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
declare type ExperienceEntry = z.input<typeof Experience>;
|
|
5
|
-
declare type ExperimentEntry = z.input<typeof Experiment>;
|
|
1
|
+
import { ExperienceConfiguration, Reference } from '@ninetailed/experience.js';
|
|
2
|
+
import { Experience, ExperienceLike } from '../types/Experience';
|
|
3
|
+
import { ExperimentLike } from '../types/Experiment';
|
|
6
4
|
export declare class ExperienceMapper {
|
|
7
|
-
static isExperienceEntry(experience:
|
|
8
|
-
static mapExperience(experience:
|
|
9
|
-
static isExperimentEntry(experiment:
|
|
10
|
-
static mapExperiment(experiment:
|
|
5
|
+
static isExperienceEntry<Variant extends Reference>(experience: ExperienceLike<Variant>): experience is Experience<Variant>;
|
|
6
|
+
static mapExperience<Variant extends Reference>(experience: ExperienceLike<Variant>): ExperienceConfiguration<Variant>;
|
|
7
|
+
static isExperimentEntry<Variant extends Reference>(experiment: ExperimentLike<Variant>): experiment is ExperimentLike<Variant>;
|
|
8
|
+
static mapExperiment<Variant extends Reference>(experiment: ExperimentLike<Variant>): ExperienceConfiguration<Variant>;
|
|
11
9
|
}
|
|
12
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ninetailed/experience.js-utils",
|
|
3
|
-
"version": "3.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
3
|
+
"version": "3.0.2-beta.0",
|
|
4
|
+
"module": "./index.js",
|
|
5
|
+
"main": "./index.cjs",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "./index.d.ts",
|
|
7
8
|
"dependencies": {
|
|
8
|
-
"@ninetailed/experience.js": "3.0.
|
|
9
|
-
"@ninetailed/experience.js-shared": "3.0.
|
|
10
|
-
"
|
|
11
|
-
"diary": "^0.3.1",
|
|
12
|
-
"zod": "^3.18.0",
|
|
13
|
-
"locale-enum": "^1.1.1",
|
|
14
|
-
"i18n-iso-countries": "^7.3.0",
|
|
15
|
-
"analytics": "^0.8.0",
|
|
16
|
-
"lodash": "^4.17.21",
|
|
17
|
-
"murmurhash-js": "^1.0.0"
|
|
9
|
+
"@ninetailed/experience.js": "3.0.2-beta.0",
|
|
10
|
+
"@ninetailed/experience.js-shared": "3.0.2-beta.0",
|
|
11
|
+
"zod": "3.20.2"
|
|
18
12
|
},
|
|
19
13
|
"peerDependencies": {}
|
|
20
14
|
}
|
package/types/Audience.d.ts
CHANGED
package/types/Config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Baseline, VariantRef } from '@ninetailed/experience.js';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
export declare const Config: z.ZodObject<{
|
|
3
4
|
distribution: z.ZodDefault<z.ZodArray<z.ZodNumber, "many">>;
|
|
@@ -62,4 +63,9 @@ export declare const Config: z.ZodObject<{
|
|
|
62
63
|
}[];
|
|
63
64
|
}[] | undefined;
|
|
64
65
|
}>;
|
|
66
|
+
export declare type ConfigLike = z.input<typeof Config>;
|
|
65
67
|
export declare type Config = z.infer<typeof Config>;
|
|
68
|
+
export interface BaselineWithVariantRefs {
|
|
69
|
+
baseline: Baseline;
|
|
70
|
+
variants: VariantRef[];
|
|
71
|
+
}
|