@eventvisor/core 0.23.0 → 0.25.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/CHANGELOG.md +19 -0
- package/lib/linter/conditionsSchema.d.ts +1 -301
- package/lib/linter/conditionsSchema.js +8 -14
- package/lib/linter/conditionsSchema.js.map +1 -1
- package/lib/linter/destinationSchema.d.ts +89 -1
- package/lib/linter/destinationSchema.js +0 -2
- package/lib/linter/destinationSchema.js.map +1 -1
- package/lib/linter/effectSchema.d.ts +9 -1209
- package/lib/linter/effectSchema.js +6 -3
- package/lib/linter/effectSchema.js.map +1 -1
- package/lib/linter/entitySchemas.spec.d.ts +1 -0
- package/lib/linter/entitySchemas.spec.js +169 -0
- package/lib/linter/entitySchemas.spec.js.map +1 -0
- package/lib/linter/eventSchema.js +5 -3
- package/lib/linter/eventSchema.js.map +1 -1
- package/lib/linter/lintProject.d.ts +5 -0
- package/lib/linter/lintProject.js +141 -5
- package/lib/linter/lintProject.js.map +1 -1
- package/lib/linter/lintProject.spec.d.ts +1 -0
- package/lib/linter/lintProject.spec.js +103 -0
- package/lib/linter/lintProject.spec.js.map +1 -0
- package/lib/linter/persistSchema.d.ts +4 -604
- package/lib/linter/persistSchema.js +4 -2
- package/lib/linter/persistSchema.js.map +1 -1
- package/lib/linter/printError.js +4 -0
- package/lib/linter/printError.js.map +1 -1
- package/lib/linter/sampleSchema.d.ts +13 -285
- package/lib/linter/sampleSchema.js +2 -1
- package/lib/linter/sampleSchema.js.map +1 -1
- package/lib/linter/semanticValidation.d.ts +11 -0
- package/lib/linter/semanticValidation.js +592 -0
- package/lib/linter/semanticValidation.js.map +1 -0
- package/lib/linter/semanticValidation.spec.d.ts +1 -0
- package/lib/linter/semanticValidation.spec.js +190 -0
- package/lib/linter/semanticValidation.spec.js.map +1 -0
- package/lib/linter/testSchema.d.ts +64 -3
- package/lib/linter/testSchema.js +81 -4
- package/lib/linter/testSchema.js.map +1 -1
- package/lib/linter/testSchema.spec.d.ts +1 -0
- package/lib/linter/testSchema.spec.js +260 -0
- package/lib/linter/testSchema.spec.js.map +1 -0
- package/package.json +5 -5
- package/src/linter/conditionsSchema.ts +12 -18
- package/src/linter/destinationSchema.ts +0 -3
- package/src/linter/effectSchema.ts +12 -9
- package/src/linter/entitySchemas.spec.ts +212 -0
- package/src/linter/eventSchema.ts +8 -6
- package/src/linter/lintProject.spec.ts +112 -0
- package/src/linter/lintProject.ts +134 -6
- package/src/linter/persistSchema.ts +6 -4
- package/src/linter/printError.ts +3 -0
- package/src/linter/sampleSchema.ts +3 -1
- package/src/linter/semanticValidation.spec.ts +239 -0
- package/src/linter/semanticValidation.ts +953 -0
- package/src/linter/testSchema.spec.ts +279 -0
- package/src/linter/testSchema.ts +89 -4
|
@@ -14,7 +14,7 @@ export function getSampleSchema(deps: Dependencies) {
|
|
|
14
14
|
|
|
15
15
|
const sampleBy = z.union([sampleBySingle, sampleByMultiple, sampleByOr]);
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const sampleSchema = z
|
|
18
18
|
.object({
|
|
19
19
|
by: sampleBy,
|
|
20
20
|
conditions: getConditionsSchema(deps).optional(),
|
|
@@ -42,4 +42,6 @@ export function getSampleSchema(deps: Dependencies) {
|
|
|
42
42
|
path: [],
|
|
43
43
|
},
|
|
44
44
|
);
|
|
45
|
+
|
|
46
|
+
return z.union([sampleSchema, z.array(sampleSchema)]);
|
|
45
47
|
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { getSemanticIssues, type LintContext } from "./semanticValidation";
|
|
2
|
+
|
|
3
|
+
describe("semantic lint validation", () => {
|
|
4
|
+
function createContext(): LintContext {
|
|
5
|
+
return {
|
|
6
|
+
attributes: {
|
|
7
|
+
userId: {
|
|
8
|
+
description: "User ID",
|
|
9
|
+
tags: ["web"],
|
|
10
|
+
type: "string",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
events: {
|
|
14
|
+
page_view: {
|
|
15
|
+
description: "Page view",
|
|
16
|
+
tags: ["web"],
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
url: { type: "string" },
|
|
20
|
+
},
|
|
21
|
+
required: ["url"],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
destinations: {
|
|
25
|
+
console: {
|
|
26
|
+
description: "Console",
|
|
27
|
+
tags: ["web"],
|
|
28
|
+
transport: "console",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
effects: {
|
|
32
|
+
sync_user: {
|
|
33
|
+
description: "Sync user",
|
|
34
|
+
tags: ["web"],
|
|
35
|
+
on: {
|
|
36
|
+
event_tracked: ["page_view"],
|
|
37
|
+
},
|
|
38
|
+
state: {
|
|
39
|
+
synced: false,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
it("reports missing cross-entity references", () => {
|
|
47
|
+
const issues = getSemanticIssues(
|
|
48
|
+
"event",
|
|
49
|
+
{
|
|
50
|
+
description: "Broken event",
|
|
51
|
+
tags: ["web"],
|
|
52
|
+
type: "object",
|
|
53
|
+
requiredAttributes: ["missingAttribute"],
|
|
54
|
+
destinations: {
|
|
55
|
+
missingDestination: true,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
createContext(),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
expect(issues.map((issue) => issue.message)).toEqual(
|
|
62
|
+
expect.arrayContaining([
|
|
63
|
+
'requiredAttributes references missing attribute "missingAttribute"',
|
|
64
|
+
'destinations references missing destination "missingDestination"',
|
|
65
|
+
]),
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("reports invalid payload paths and unsupported source arrays", () => {
|
|
70
|
+
const issues = getSemanticIssues(
|
|
71
|
+
"attribute",
|
|
72
|
+
{
|
|
73
|
+
description: "Broken attribute",
|
|
74
|
+
tags: ["web"],
|
|
75
|
+
type: "object",
|
|
76
|
+
properties: {
|
|
77
|
+
userId: { type: "string" },
|
|
78
|
+
},
|
|
79
|
+
transforms: [
|
|
80
|
+
{
|
|
81
|
+
type: "trim",
|
|
82
|
+
target: "userId",
|
|
83
|
+
payload: "unknownField",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: "set",
|
|
87
|
+
source: ["payload.userId"],
|
|
88
|
+
target: "copy",
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
createContext(),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
expect(issues.map((issue) => issue.message)).toEqual(
|
|
96
|
+
expect.arrayContaining([
|
|
97
|
+
'Payload reference "unknownField" references payload path "unknownField" that is not defined in the referenced schema',
|
|
98
|
+
'The "source" field does not support arrays; use "payload" for multi-source payload references',
|
|
99
|
+
]),
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("reports invalid transform targets against declared schema paths", () => {
|
|
104
|
+
const issues = getSemanticIssues(
|
|
105
|
+
"event",
|
|
106
|
+
{
|
|
107
|
+
description: "Banner click",
|
|
108
|
+
tags: ["web"],
|
|
109
|
+
type: "object",
|
|
110
|
+
properties: {
|
|
111
|
+
screen: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: {
|
|
114
|
+
width: {
|
|
115
|
+
type: "number",
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
transforms: [
|
|
121
|
+
{
|
|
122
|
+
type: "set",
|
|
123
|
+
lookup: "browser.screen.width",
|
|
124
|
+
target: "screen.width123",
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
createContext(),
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
expect(issues.map((issue) => issue.message)).toContain(
|
|
132
|
+
'Transform target "screen.width123" references payload path "screen.width123" that is not defined in the referenced schema',
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("reports invalid source origins for effect transforms and missing trigger references", () => {
|
|
137
|
+
const issues = getSemanticIssues(
|
|
138
|
+
"effect",
|
|
139
|
+
{
|
|
140
|
+
description: "Broken effect",
|
|
141
|
+
tags: ["web"],
|
|
142
|
+
on: {
|
|
143
|
+
event_tracked: ["missing_event"],
|
|
144
|
+
},
|
|
145
|
+
state: {
|
|
146
|
+
synced: false,
|
|
147
|
+
},
|
|
148
|
+
steps: [
|
|
149
|
+
{
|
|
150
|
+
transforms: [
|
|
151
|
+
{
|
|
152
|
+
type: "set",
|
|
153
|
+
source: "payload.url",
|
|
154
|
+
target: "synced",
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
createContext(),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
expect(issues.map((issue) => issue.message)).toEqual(
|
|
164
|
+
expect.arrayContaining([
|
|
165
|
+
'Effect trigger references missing event "missing_event"',
|
|
166
|
+
'Source origin "payload" is not available in this context',
|
|
167
|
+
]),
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("reports invalid references inside test specs", () => {
|
|
172
|
+
const issues = getSemanticIssues(
|
|
173
|
+
"test",
|
|
174
|
+
{
|
|
175
|
+
event: "missing_event",
|
|
176
|
+
assertions: [
|
|
177
|
+
{
|
|
178
|
+
expectedDestinations: ["missing_destination"],
|
|
179
|
+
actions: [
|
|
180
|
+
{
|
|
181
|
+
type: "track",
|
|
182
|
+
name: "missing_event",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
type: "setAttribute",
|
|
186
|
+
name: "missing_attribute",
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
createContext(),
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
expect(issues.map((issue) => issue.message)).toEqual(
|
|
196
|
+
expect.arrayContaining([
|
|
197
|
+
'Test references missing event "missing_event"',
|
|
198
|
+
'expectedDestinations references missing destination "missing_destination"',
|
|
199
|
+
'Action references missing event "missing_event"',
|
|
200
|
+
'Action references missing attribute "missing_attribute"',
|
|
201
|
+
]),
|
|
202
|
+
);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("allows runtime map sources and transport-name expected destinations", () => {
|
|
206
|
+
const attributeSourceIssues = getSemanticIssues(
|
|
207
|
+
"destination",
|
|
208
|
+
{
|
|
209
|
+
description: "Console",
|
|
210
|
+
tags: ["web"],
|
|
211
|
+
transport: "console",
|
|
212
|
+
transforms: [
|
|
213
|
+
{
|
|
214
|
+
type: "set",
|
|
215
|
+
source: "attributes",
|
|
216
|
+
target: "attributes",
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
createContext(),
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
const expectedDestinationIssues = getSemanticIssues(
|
|
224
|
+
"test",
|
|
225
|
+
{
|
|
226
|
+
event: "page_view",
|
|
227
|
+
assertions: [
|
|
228
|
+
{
|
|
229
|
+
expectedDestinations: ["console"],
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
createContext(),
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
expect(attributeSourceIssues).toHaveLength(0);
|
|
237
|
+
expect(expectedDestinationIssues).toHaveLength(0);
|
|
238
|
+
});
|
|
239
|
+
});
|