@eventvisor/core 0.0.2
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/LICENSE +21 -0
- package/README.md +9 -0
- package/jest.config.js +4 -0
- package/lib/builder/buildProject.d.ts +21 -0
- package/lib/builder/buildProject.js +153 -0
- package/lib/builder/buildProject.js.map +1 -0
- package/lib/builder/hashes.d.ts +2 -0
- package/lib/builder/hashes.js +59 -0
- package/lib/builder/hashes.js.map +1 -0
- package/lib/builder/index.d.ts +1 -0
- package/lib/builder/index.js +18 -0
- package/lib/builder/index.js.map +1 -0
- package/lib/cli/cli.d.ts +26 -0
- package/lib/cli/cli.js +69 -0
- package/lib/cli/cli.js.map +1 -0
- package/lib/cli/index.d.ts +1 -0
- package/lib/cli/index.js +18 -0
- package/lib/cli/index.js.map +1 -0
- package/lib/cli/plugins.d.ts +4 -0
- package/lib/cli/plugins.js +12 -0
- package/lib/cli/plugins.js.map +1 -0
- package/lib/config/index.d.ts +2 -0
- package/lib/config/index.js +19 -0
- package/lib/config/index.js.map +1 -0
- package/lib/config/parsers.d.ts +15 -0
- package/lib/config/parsers.js +65 -0
- package/lib/config/parsers.js.map +1 -0
- package/lib/config/projectConfig.d.ts +42 -0
- package/lib/config/projectConfig.js +137 -0
- package/lib/config/projectConfig.js.map +1 -0
- package/lib/datasource/adapter.d.ts +16 -0
- package/lib/datasource/adapter.js +7 -0
- package/lib/datasource/adapter.js.map +1 -0
- package/lib/datasource/datasource.d.ts +48 -0
- package/lib/datasource/datasource.js +117 -0
- package/lib/datasource/datasource.js.map +1 -0
- package/lib/datasource/filesystemAdapter.d.ts +29 -0
- package/lib/datasource/filesystemAdapter.js +192 -0
- package/lib/datasource/filesystemAdapter.js.map +1 -0
- package/lib/datasource/index.d.ts +3 -0
- package/lib/datasource/index.js +20 -0
- package/lib/datasource/index.js.map +1 -0
- package/lib/dependencies.d.ts +11 -0
- package/lib/dependencies.js +3 -0
- package/lib/dependencies.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +21 -0
- package/lib/index.js.map +1 -0
- package/lib/index.spec.d.ts +0 -0
- package/lib/index.spec.js +6 -0
- package/lib/index.spec.js.map +1 -0
- package/lib/init/index.d.ts +8 -0
- package/lib/init/index.js +90 -0
- package/lib/init/index.js.map +1 -0
- package/lib/linter/attributeSchema.d.ts +5 -0
- package/lib/linter/attributeSchema.js +55 -0
- package/lib/linter/attributeSchema.js.map +1 -0
- package/lib/linter/conditionsSchema.d.ts +303 -0
- package/lib/linter/conditionsSchema.js +106 -0
- package/lib/linter/conditionsSchema.js.map +1 -0
- package/lib/linter/destinationSchema.d.ts +5 -0
- package/lib/linter/destinationSchema.js +57 -0
- package/lib/linter/destinationSchema.js.map +1 -0
- package/lib/linter/effectSchema.d.ts +1257 -0
- package/lib/linter/effectSchema.js +77 -0
- package/lib/linter/effectSchema.js.map +1 -0
- package/lib/linter/eventSchema.d.ts +5 -0
- package/lib/linter/eventSchema.js +70 -0
- package/lib/linter/eventSchema.js.map +1 -0
- package/lib/linter/index.d.ts +1 -0
- package/lib/linter/index.js +18 -0
- package/lib/linter/index.js.map +1 -0
- package/lib/linter/jsonSchema.d.ts +25 -0
- package/lib/linter/jsonSchema.js +487 -0
- package/lib/linter/jsonSchema.js.map +1 -0
- package/lib/linter/jsonSchema.spec.d.ts +1 -0
- package/lib/linter/jsonSchema.spec.js +875 -0
- package/lib/linter/jsonSchema.spec.js.map +1 -0
- package/lib/linter/lintProject.d.ts +2 -0
- package/lib/linter/lintProject.js +141 -0
- package/lib/linter/lintProject.js.map +1 -0
- package/lib/linter/persistSchema.d.ts +609 -0
- package/lib/linter/persistSchema.js +52 -0
- package/lib/linter/persistSchema.js.map +1 -0
- package/lib/linter/printError.d.ts +9 -0
- package/lib/linter/printError.js +75 -0
- package/lib/linter/printError.js.map +1 -0
- package/lib/linter/sampleSchema.d.ts +331 -0
- package/lib/linter/sampleSchema.js +70 -0
- package/lib/linter/sampleSchema.js.map +1 -0
- package/lib/linter/sourceSchema.d.ts +11 -0
- package/lib/linter/sourceSchema.js +73 -0
- package/lib/linter/sourceSchema.js.map +1 -0
- package/lib/linter/tagsSchema.d.ts +3 -0
- package/lib/linter/tagsSchema.js +44 -0
- package/lib/linter/tagsSchema.js.map +1 -0
- package/lib/linter/testSchema.d.ts +5 -0
- package/lib/linter/testSchema.js +44 -0
- package/lib/linter/testSchema.js.map +1 -0
- package/lib/linter/transformsSchema.d.ts +29 -0
- package/lib/linter/transformsSchema.js +66 -0
- package/lib/linter/transformsSchema.js.map +1 -0
- package/lib/tester/createTestInstance.d.ts +16 -0
- package/lib/tester/createTestInstance.js +158 -0
- package/lib/tester/createTestInstance.js.map +1 -0
- package/lib/tester/executeTest.d.ts +24 -0
- package/lib/tester/executeTest.js +305 -0
- package/lib/tester/executeTest.js.map +1 -0
- package/lib/tester/index.d.ts +1 -0
- package/lib/tester/index.js +18 -0
- package/lib/tester/index.js.map +1 -0
- package/lib/tester/printTestResult.d.ts +10 -0
- package/lib/tester/printTestResult.js +80 -0
- package/lib/tester/printTestResult.js.map +1 -0
- package/lib/tester/testProject.d.ts +12 -0
- package/lib/tester/testProject.js +93 -0
- package/lib/tester/testProject.js.map +1 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +18 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/prettyDuration.d.ts +1 -0
- package/lib/utils/prettyDuration.js +27 -0
- package/lib/utils/prettyDuration.js.map +1 -0
- package/package.json +42 -0
- package/src/builder/buildProject.ts +222 -0
- package/src/builder/hashes.ts +30 -0
- package/src/builder/index.ts +1 -0
- package/src/cli/cli.ts +110 -0
- package/src/cli/index.ts +1 -0
- package/src/cli/plugins.ts +13 -0
- package/src/config/index.ts +2 -0
- package/src/config/parsers.ts +40 -0
- package/src/config/projectConfig.ts +158 -0
- package/src/datasource/adapter.ts +23 -0
- package/src/datasource/datasource.ts +164 -0
- package/src/datasource/filesystemAdapter.ts +206 -0
- package/src/datasource/index.ts +3 -0
- package/src/dependencies.ts +13 -0
- package/src/index.spec.ts +5 -0
- package/src/index.ts +4 -0
- package/src/init/index.ts +65 -0
- package/src/linter/attributeSchema.ts +23 -0
- package/src/linter/conditionsSchema.ts +89 -0
- package/src/linter/destinationSchema.ts +25 -0
- package/src/linter/effectSchema.ts +49 -0
- package/src/linter/eventSchema.ts +40 -0
- package/src/linter/index.ts +1 -0
- package/src/linter/jsonSchema.spec.ts +934 -0
- package/src/linter/jsonSchema.ts +533 -0
- package/src/linter/lintProject.ts +182 -0
- package/src/linter/persistSchema.ts +21 -0
- package/src/linter/printError.ts +50 -0
- package/src/linter/sampleSchema.ts +45 -0
- package/src/linter/sourceSchema.ts +42 -0
- package/src/linter/tagsSchema.ts +12 -0
- package/src/linter/testSchema.ts +9 -0
- package/src/linter/transformsSchema.ts +35 -0
- package/src/tester/createTestInstance.ts +209 -0
- package/src/tester/executeTest.ts +436 -0
- package/src/tester/index.ts +1 -0
- package/src/tester/printTestResult.ts +60 -0
- package/src/tester/testProject.ts +129 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/prettyDuration.ts +27 -0
- package/tsconfig.cjs.json +11 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
|
|
4
|
+
import type { DatafileContent, EntityType } from "@eventvisor/types";
|
|
5
|
+
|
|
6
|
+
import { Adapter, DatafileOptions } from "./adapter";
|
|
7
|
+
import { ProjectConfig, CustomParser } from "../config";
|
|
8
|
+
|
|
9
|
+
export function getRevisionFilePath(projectConfig: ProjectConfig): string {
|
|
10
|
+
return path.join(projectConfig.systemDirectoryPath, `REVISION`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getAllEntityFilePathsRecursively(directoryPath, extension) {
|
|
14
|
+
let entities: string[] = [];
|
|
15
|
+
|
|
16
|
+
if (!fs.existsSync(directoryPath)) {
|
|
17
|
+
return entities;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const files = fs.readdirSync(directoryPath);
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < files.length; i++) {
|
|
23
|
+
const file = files[i];
|
|
24
|
+
const filePath = path.join(directoryPath, file);
|
|
25
|
+
|
|
26
|
+
if (fs.statSync(filePath).isDirectory()) {
|
|
27
|
+
entities = entities.concat(getAllEntityFilePathsRecursively(filePath, extension));
|
|
28
|
+
} else if (file.endsWith(`.${extension}`)) {
|
|
29
|
+
entities.push(filePath);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return entities;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class FilesystemAdapter extends Adapter {
|
|
37
|
+
private parser: CustomParser;
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
private config: ProjectConfig,
|
|
41
|
+
private rootDirectoryPath?: string,
|
|
42
|
+
) {
|
|
43
|
+
super();
|
|
44
|
+
|
|
45
|
+
this.parser = config.parser as CustomParser;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getEntityDirectoryPath(entityType: EntityType): string {
|
|
49
|
+
if (entityType === "event") {
|
|
50
|
+
return this.config.eventsDirectoryPath;
|
|
51
|
+
} else if (entityType === "attribute") {
|
|
52
|
+
return this.config.attributesDirectoryPath;
|
|
53
|
+
} else if (entityType === "destination") {
|
|
54
|
+
return this.config.destinationsDirectoryPath;
|
|
55
|
+
} else if (entityType === "state") {
|
|
56
|
+
return this.config.statesDirectoryPath;
|
|
57
|
+
} else if (entityType === "effect") {
|
|
58
|
+
return this.config.effectsDirectoryPath;
|
|
59
|
+
} else if (entityType === "test") {
|
|
60
|
+
return this.config.testsDirectoryPath;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
throw new Error(`Unknown entity type: ${entityType}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
getEntityPath(entityType: EntityType, entityKey: string): string {
|
|
67
|
+
const basePath = this.getEntityDirectoryPath(entityType);
|
|
68
|
+
|
|
69
|
+
// taking care of windows paths
|
|
70
|
+
const relativeEntityPath = entityKey.replace(/\//g, path.sep);
|
|
71
|
+
|
|
72
|
+
return path.join(basePath, `${relativeEntityPath}.${this.parser.extension}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async listEntities(entityType: EntityType): Promise<string[]> {
|
|
76
|
+
const directoryPath = this.getEntityDirectoryPath(entityType);
|
|
77
|
+
const filePaths = getAllEntityFilePathsRecursively(directoryPath, this.parser.extension);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
filePaths
|
|
81
|
+
// keep only the files with the right extension
|
|
82
|
+
.filter((filterPath) => filterPath.endsWith(`.${this.parser.extension}`))
|
|
83
|
+
|
|
84
|
+
// remove the entity directory path from beginning
|
|
85
|
+
.map((filePath) => filePath.replace(directoryPath + path.sep, ""))
|
|
86
|
+
|
|
87
|
+
// remove the extension from the end
|
|
88
|
+
.map((filterPath) => filterPath.replace(`.${this.parser.extension}`, ""))
|
|
89
|
+
|
|
90
|
+
// take care of windows paths
|
|
91
|
+
.map((filterPath) => filterPath.replace(/\\/g, "/"))
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async entityExists(entityType: EntityType, entityKey: string): Promise<boolean> {
|
|
96
|
+
const entityPath = this.getEntityPath(entityType, entityKey);
|
|
97
|
+
|
|
98
|
+
return fs.existsSync(entityPath);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async readEntity<T>(entityType: EntityType, entityKey: string): Promise<T> {
|
|
102
|
+
const filePath = this.getEntityPath(entityType, entityKey);
|
|
103
|
+
const entityContent = fs.readFileSync(filePath, "utf8");
|
|
104
|
+
|
|
105
|
+
return this.parser.parse<T>(entityContent, filePath);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async writeEntity<T>(entityType: EntityType, entityKey: string, entity: T): Promise<T> {
|
|
109
|
+
const filePath = this.getEntityPath(entityType, entityKey);
|
|
110
|
+
|
|
111
|
+
if (!fs.existsSync(this.getEntityDirectoryPath(entityType))) {
|
|
112
|
+
fs.mkdirSync(this.getEntityDirectoryPath(entityType), { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
fs.writeFileSync(filePath, this.parser.stringify(entity));
|
|
116
|
+
|
|
117
|
+
return entity;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async deleteEntity(entityType: EntityType, entityKey: string): Promise<void> {
|
|
121
|
+
const filePath = this.getEntityPath(entityType, entityKey);
|
|
122
|
+
|
|
123
|
+
if (!fs.existsSync(filePath)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
fs.unlinkSync(filePath);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Revision
|
|
132
|
+
*/
|
|
133
|
+
async readRevision(): Promise<string> {
|
|
134
|
+
const filePath = getRevisionFilePath(this.config);
|
|
135
|
+
|
|
136
|
+
if (fs.existsSync(filePath)) {
|
|
137
|
+
return fs.readFileSync(filePath, "utf8");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// maintain backwards compatibility
|
|
141
|
+
try {
|
|
142
|
+
const pkg = require(path.join(this.rootDirectoryPath as string, "package.json"));
|
|
143
|
+
const pkgVersion = pkg.version;
|
|
144
|
+
|
|
145
|
+
if (pkgVersion) {
|
|
146
|
+
return pkgVersion;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return "0";
|
|
150
|
+
// eslint-disable-next-line
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return "0";
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async writeRevision(revision: string): Promise<void> {
|
|
157
|
+
const filePath = getRevisionFilePath(this.config);
|
|
158
|
+
|
|
159
|
+
if (!fs.existsSync(this.config.systemDirectoryPath)) {
|
|
160
|
+
fs.mkdirSync(this.config.systemDirectoryPath, { recursive: true });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
fs.writeFileSync(filePath, revision);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Datafile
|
|
168
|
+
*/
|
|
169
|
+
getDatafilePath(options: DatafileOptions): string {
|
|
170
|
+
const pattern = this.config.datafileNamePattern || "eventvisor-%s.json";
|
|
171
|
+
|
|
172
|
+
const fileName = pattern.replace("%s", `tag-${options.tag}`);
|
|
173
|
+
const dir = options.datafilesDir || this.config.datafilesDirectoryPath;
|
|
174
|
+
|
|
175
|
+
return path.join(dir, fileName);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async readDatafile(options: DatafileOptions): Promise<DatafileContent> {
|
|
179
|
+
const filePath = this.getDatafilePath(options);
|
|
180
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
181
|
+
const datafileContent = JSON.parse(content);
|
|
182
|
+
|
|
183
|
+
return datafileContent;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async writeDatafile(datafileContent: DatafileContent, options: DatafileOptions): Promise<void> {
|
|
187
|
+
const dir = options.datafilesDir || this.config.datafilesDirectoryPath;
|
|
188
|
+
|
|
189
|
+
const outputEnvironmentDirPath = dir;
|
|
190
|
+
fs.mkdirSync(outputEnvironmentDirPath, { recursive: true });
|
|
191
|
+
|
|
192
|
+
const outputFilePath = this.getDatafilePath(options);
|
|
193
|
+
|
|
194
|
+
fs.writeFileSync(
|
|
195
|
+
outputFilePath,
|
|
196
|
+
this.config.prettyDatafile
|
|
197
|
+
? JSON.stringify(datafileContent, null, 2)
|
|
198
|
+
: JSON.stringify(datafileContent),
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const root = path.resolve(dir, "..");
|
|
202
|
+
|
|
203
|
+
const shortPath = outputFilePath.replace(root + path.sep, "");
|
|
204
|
+
console.log(` Datafile generated: ${shortPath}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProjectConfig } from "./config";
|
|
2
|
+
import { Datasource } from "./datasource";
|
|
3
|
+
|
|
4
|
+
export interface Options {
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Dependencies {
|
|
9
|
+
rootDirectoryPath: string;
|
|
10
|
+
projectConfig: ProjectConfig;
|
|
11
|
+
datasource: Datasource;
|
|
12
|
+
options: Options;
|
|
13
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import * as tar from "tar";
|
|
3
|
+
|
|
4
|
+
import { Plugin } from "../cli";
|
|
5
|
+
|
|
6
|
+
export const DEFAULT_PROJECT = "yml";
|
|
7
|
+
|
|
8
|
+
export const PROJECTS_ORG_NAME = "eventvisor";
|
|
9
|
+
export const PROJECTS_REPO_NAME = "eventvisor";
|
|
10
|
+
export const PROJECTS_BRANCH_NAME = "main";
|
|
11
|
+
|
|
12
|
+
export const PROJECTS_TAR_URL = `https://codeload.github.com/${PROJECTS_ORG_NAME}/${PROJECTS_REPO_NAME}/tar.gz/${PROJECTS_BRANCH_NAME}`;
|
|
13
|
+
|
|
14
|
+
function getProjectPath(projectName: string) {
|
|
15
|
+
return `${PROJECTS_REPO_NAME}-${PROJECTS_BRANCH_NAME}/projects/project-${projectName}/`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function initProject(
|
|
19
|
+
directoryPath: string,
|
|
20
|
+
projectName: string = DEFAULT_PROJECT,
|
|
21
|
+
): Promise<boolean> {
|
|
22
|
+
return new Promise(function (resolve) {
|
|
23
|
+
axios.get(PROJECTS_TAR_URL, { responseType: "stream" }).then((response) => {
|
|
24
|
+
response.data
|
|
25
|
+
.pipe(
|
|
26
|
+
tar.x({
|
|
27
|
+
C: directoryPath,
|
|
28
|
+
filter: (path) => path.indexOf(getProjectPath(projectName)) === 0,
|
|
29
|
+
strip: 3,
|
|
30
|
+
}),
|
|
31
|
+
)
|
|
32
|
+
.on("error", (e) => {
|
|
33
|
+
console.error(e);
|
|
34
|
+
|
|
35
|
+
resolve(false);
|
|
36
|
+
})
|
|
37
|
+
.on("finish", () => {
|
|
38
|
+
console.log(`Project scaffolded in ${directoryPath}`);
|
|
39
|
+
console.log(``);
|
|
40
|
+
console.log(`Please run "npm install" in the directory above.`);
|
|
41
|
+
|
|
42
|
+
resolve(true);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const initPlugin: Plugin = {
|
|
49
|
+
command: "init",
|
|
50
|
+
handler: async function (options) {
|
|
51
|
+
const { rootDirectoryPath, parsed } = options;
|
|
52
|
+
|
|
53
|
+
await initProject(rootDirectoryPath, parsed.project);
|
|
54
|
+
},
|
|
55
|
+
examples: [
|
|
56
|
+
{
|
|
57
|
+
command: "init",
|
|
58
|
+
description: "scaffold a new project in current directory",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
command: "init --project=projectName",
|
|
62
|
+
description: "scaffold a new project in current directory from known example",
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { Dependencies } from "../dependencies";
|
|
3
|
+
|
|
4
|
+
import { JSONZodSchema } from "./jsonSchema";
|
|
5
|
+
import { getTagsSchema } from "./tagsSchema";
|
|
6
|
+
import { getTransformsSchema } from "./transformsSchema";
|
|
7
|
+
import { getPersistSchema } from "./persistSchema";
|
|
8
|
+
|
|
9
|
+
export function getAttributeSchema(deps: Dependencies) {
|
|
10
|
+
return z
|
|
11
|
+
.object({
|
|
12
|
+
...JSONZodSchema.shape,
|
|
13
|
+
|
|
14
|
+
archived: z.boolean().optional(),
|
|
15
|
+
deprecated: z.boolean().optional(),
|
|
16
|
+
description: z.string(),
|
|
17
|
+
tags: getTagsSchema(deps),
|
|
18
|
+
|
|
19
|
+
transforms: getTransformsSchema(deps).optional(),
|
|
20
|
+
persist: getPersistSchema(deps).optional(),
|
|
21
|
+
})
|
|
22
|
+
.strict();
|
|
23
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
|
|
3
|
+
import { Dependencies } from "../dependencies";
|
|
4
|
+
import { getSourceBaseRefine, getSourceBaseSchema } from "./sourceSchema";
|
|
5
|
+
|
|
6
|
+
export function getConditionsSchema(deps: Dependencies) {
|
|
7
|
+
const sourceBase = getSourceBaseSchema(deps);
|
|
8
|
+
|
|
9
|
+
const plainConditionSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
...sourceBase.shape,
|
|
12
|
+
operator: z.enum([
|
|
13
|
+
"equals",
|
|
14
|
+
"notEquals",
|
|
15
|
+
"exists",
|
|
16
|
+
"notExists",
|
|
17
|
+
|
|
18
|
+
// numeric
|
|
19
|
+
"greaterThan",
|
|
20
|
+
"greaterThanOrEquals",
|
|
21
|
+
"lessThan",
|
|
22
|
+
"lessThanOrEquals",
|
|
23
|
+
|
|
24
|
+
// string
|
|
25
|
+
"contains",
|
|
26
|
+
"notContains",
|
|
27
|
+
"startsWith",
|
|
28
|
+
"endsWith",
|
|
29
|
+
|
|
30
|
+
// semver (string)
|
|
31
|
+
"semverEquals",
|
|
32
|
+
"semverNotEquals",
|
|
33
|
+
"semverGreaterThan",
|
|
34
|
+
"semverGreaterThanOrEquals",
|
|
35
|
+
"semverLessThan",
|
|
36
|
+
"semverLessThanOrEquals",
|
|
37
|
+
|
|
38
|
+
// date comparisons
|
|
39
|
+
"before",
|
|
40
|
+
"after",
|
|
41
|
+
|
|
42
|
+
// array of strings
|
|
43
|
+
"includes",
|
|
44
|
+
"notIncludes",
|
|
45
|
+
|
|
46
|
+
// regex
|
|
47
|
+
"matches",
|
|
48
|
+
"notMatches",
|
|
49
|
+
|
|
50
|
+
// array of strings
|
|
51
|
+
"in",
|
|
52
|
+
"notIn",
|
|
53
|
+
]),
|
|
54
|
+
value: z.any().optional(),
|
|
55
|
+
})
|
|
56
|
+
.refine(...getSourceBaseRefine())
|
|
57
|
+
// @TODO: refine "value" type against each "operator"
|
|
58
|
+
.refine(
|
|
59
|
+
(data) => {
|
|
60
|
+
if (data.operator === "exists" || data.operator === "notExists") {
|
|
61
|
+
return data.value === undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return data.value !== undefined;
|
|
65
|
+
},
|
|
66
|
+
{ message: "Value is required for all operators except exists and notExists" },
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const andConditionSchema = z.object({
|
|
70
|
+
and: z.array(plainConditionSchema),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const orConditionSchema = z.object({
|
|
74
|
+
or: z.array(plainConditionSchema),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const notConditionSchema = z.object({
|
|
78
|
+
not: z.array(plainConditionSchema),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const conditionSchema = z.union([
|
|
82
|
+
plainConditionSchema,
|
|
83
|
+
andConditionSchema,
|
|
84
|
+
orConditionSchema,
|
|
85
|
+
notConditionSchema,
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
return z.union([conditionSchema, z.array(conditionSchema)]);
|
|
89
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { Dependencies } from "../dependencies";
|
|
3
|
+
|
|
4
|
+
import { JSONZodSchema } from "./jsonSchema";
|
|
5
|
+
import { getTagsSchema } from "./tagsSchema";
|
|
6
|
+
import { getConditionsSchema } from "./conditionsSchema";
|
|
7
|
+
import { getSampleSchema } from "./sampleSchema";
|
|
8
|
+
import { getTransformsSchema } from "./transformsSchema";
|
|
9
|
+
|
|
10
|
+
export function getDestinationSchema(deps: Dependencies) {
|
|
11
|
+
return z
|
|
12
|
+
.object({
|
|
13
|
+
...JSONZodSchema.shape,
|
|
14
|
+
|
|
15
|
+
archived: z.boolean().optional(),
|
|
16
|
+
description: z.string(),
|
|
17
|
+
tags: getTagsSchema(deps),
|
|
18
|
+
|
|
19
|
+
transport: z.string(),
|
|
20
|
+
conditions: getConditionsSchema(deps).optional(),
|
|
21
|
+
sample: getSampleSchema(deps).optional(),
|
|
22
|
+
transforms: getTransformsSchema(deps).optional(),
|
|
23
|
+
})
|
|
24
|
+
.strict();
|
|
25
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
|
|
3
|
+
import { Dependencies } from "../dependencies";
|
|
4
|
+
import { getConditionsSchema } from "./conditionsSchema";
|
|
5
|
+
import { getTagsSchema } from "./tagsSchema";
|
|
6
|
+
import { getTransformsSchema } from "./transformsSchema";
|
|
7
|
+
import { getPersistSchema } from "./persistSchema";
|
|
8
|
+
|
|
9
|
+
export function getEffectSchema(deps: Dependencies) {
|
|
10
|
+
const effectOnType = z.enum(["event_tracked", "attribute_set"]);
|
|
11
|
+
const effectOnRecord = z
|
|
12
|
+
.object({
|
|
13
|
+
event_tracked: z.array(z.string()).optional(),
|
|
14
|
+
attribute_set: z.array(z.string()).optional(),
|
|
15
|
+
})
|
|
16
|
+
.refine(
|
|
17
|
+
(data) => {
|
|
18
|
+
return Object.values(data).some((value) => value !== undefined);
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
message: "Either event_tracked or attribute_set must be provided",
|
|
22
|
+
path: ["event_tracked", "attribute_set"],
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
const effectOn = z.union([z.array(effectOnType), effectOnRecord]);
|
|
26
|
+
|
|
27
|
+
const step = z.object({
|
|
28
|
+
description: z.string().optional(),
|
|
29
|
+
handler: z.string().optional(),
|
|
30
|
+
conditions: getConditionsSchema(deps).optional(),
|
|
31
|
+
params: z.record(z.string(), z.any()).optional(),
|
|
32
|
+
transforms: getTransformsSchema(deps).optional(),
|
|
33
|
+
continueOnError: z.boolean().optional(),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return z
|
|
37
|
+
.object({
|
|
38
|
+
archived: z.boolean().optional(),
|
|
39
|
+
description: z.string(),
|
|
40
|
+
tags: getTagsSchema(deps),
|
|
41
|
+
|
|
42
|
+
on: effectOn,
|
|
43
|
+
state: z.any().optional(),
|
|
44
|
+
conditions: getConditionsSchema(deps).optional(),
|
|
45
|
+
steps: z.array(step),
|
|
46
|
+
persist: getPersistSchema(deps).optional(),
|
|
47
|
+
})
|
|
48
|
+
.strict();
|
|
49
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { Dependencies } from "../dependencies";
|
|
3
|
+
|
|
4
|
+
import { JSONZodSchema } from "./jsonSchema";
|
|
5
|
+
import { getTagsSchema } from "./tagsSchema";
|
|
6
|
+
import { getConditionsSchema } from "./conditionsSchema";
|
|
7
|
+
import { getTransformsSchema } from "./transformsSchema";
|
|
8
|
+
import { getSampleSchema } from "./sampleSchema";
|
|
9
|
+
|
|
10
|
+
export function getEventSchema(deps: Dependencies) {
|
|
11
|
+
return z
|
|
12
|
+
.object({
|
|
13
|
+
...JSONZodSchema.shape,
|
|
14
|
+
|
|
15
|
+
archived: z.boolean().optional(),
|
|
16
|
+
deprecated: z.boolean().optional(),
|
|
17
|
+
description: z.string(),
|
|
18
|
+
tags: getTagsSchema(deps),
|
|
19
|
+
|
|
20
|
+
level: z.enum(["fatal", "error", "warning", "log", "info", "debug"]).optional(),
|
|
21
|
+
requiredAttributes: z.array(z.string()).optional(),
|
|
22
|
+
conditions: getConditionsSchema(deps).optional(),
|
|
23
|
+
sample: getSampleSchema(deps).optional(),
|
|
24
|
+
transforms: getTransformsSchema(deps).optional(),
|
|
25
|
+
destinations: z
|
|
26
|
+
.record(
|
|
27
|
+
z.string(), // @TODO: get real destination names here
|
|
28
|
+
z.union([
|
|
29
|
+
z.boolean(),
|
|
30
|
+
z.object({
|
|
31
|
+
conditions: getConditionsSchema(deps).optional(),
|
|
32
|
+
sample: getSampleSchema(deps).optional(),
|
|
33
|
+
transforms: getTransformsSchema(deps).optional(),
|
|
34
|
+
}),
|
|
35
|
+
]),
|
|
36
|
+
)
|
|
37
|
+
.optional(),
|
|
38
|
+
})
|
|
39
|
+
.strict();
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./lintProject";
|