@forzalabs/remora 0.0.12
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/Constants.js +8 -0
- package/actions/automap.js +73 -0
- package/actions/compile.js +57 -0
- package/actions/debug.js +61 -0
- package/actions/deploy.js +95 -0
- package/actions/discover.js +36 -0
- package/actions/init.js +78 -0
- package/actions/run.js +51 -0
- package/auth/AdminManager.js +48 -0
- package/auth/ApiKeysManager.js +45 -0
- package/auth/JWTManager.js +56 -0
- package/core/Affirm.js +42 -0
- package/core/Algo.js +155 -0
- package/core/dste/DSTE.js +113 -0
- package/core/logger/DebugLogService.js +48 -0
- package/core/logger/DevelopmentLogService.js +70 -0
- package/core/logger/LocalLogService.js +70 -0
- package/core/logger/Logger.js +54 -0
- package/database/DatabaseEngine.js +119 -0
- package/database/DatabaseInitializer.js +80 -0
- package/database/DatabaseStructure.js +27 -0
- package/definitions/agents/DestinationDriver.js +2 -0
- package/definitions/agents/SourceDriver.js +2 -0
- package/definitions/cli.js +2 -0
- package/definitions/database/ApiKeys.js +2 -0
- package/definitions/database/Stored.js +7 -0
- package/definitions/database/UsageStat.js +2 -0
- package/definitions/database/User.js +2 -0
- package/definitions/json_schemas/consumer-schema.json +423 -0
- package/definitions/json_schemas/producer-schema.json +236 -0
- package/definitions/json_schemas/project-schema.json +59 -0
- package/definitions/json_schemas/source-schema.json +109 -0
- package/definitions/requests/ConsumerRequest.js +2 -0
- package/definitions/requests/Developer.js +2 -0
- package/definitions/requests/Mapping.js +2 -0
- package/definitions/requests/ProducerRequest.js +2 -0
- package/definitions/requests/Request.js +2 -0
- package/definitions/resources/Compiled.js +2 -0
- package/definitions/resources/Consumer.js +2 -0
- package/definitions/resources/Environment.js +2 -0
- package/definitions/resources/Library.js +2 -0
- package/definitions/resources/Producer.js +2 -0
- package/definitions/resources/Project.js +2 -0
- package/definitions/resources/Schema.js +2 -0
- package/definitions/resources/Source.js +2 -0
- package/documentation/README.md +123 -0
- package/documentation/default_resources/consumer.json +52 -0
- package/documentation/default_resources/producer.json +32 -0
- package/documentation/default_resources/project.json +14 -0
- package/documentation/default_resources/schema.json +36 -0
- package/documentation/default_resources/source.json +15 -0
- package/drivers/DriverFactory.js +56 -0
- package/drivers/LocalDriver.js +122 -0
- package/drivers/RedshiftDriver.js +179 -0
- package/drivers/S3Driver.js +47 -0
- package/drivers/S3SourceDriver.js +127 -0
- package/engines/CryptoEngine.js +46 -0
- package/engines/Environment.js +139 -0
- package/engines/ParseManager.js +38 -0
- package/engines/ProducerEngine.js +150 -0
- package/engines/UsageManager.js +61 -0
- package/engines/UserManager.js +43 -0
- package/engines/Validator.js +154 -0
- package/engines/ai/AutoMapperEngine.js +37 -0
- package/engines/ai/DeveloperEngine.js +70 -0
- package/engines/ai/LLM.js +299 -0
- package/engines/consumer/ConsumerEngine.js +204 -0
- package/engines/consumer/ConsumerManager.js +155 -0
- package/engines/consumer/PostProcessor.js +143 -0
- package/engines/deployment/DeploymentPlanner.js +46 -0
- package/engines/execution/ExecutionEnvironment.js +114 -0
- package/engines/execution/ExecutionPlanner.js +92 -0
- package/engines/execution/RequestExecutor.js +100 -0
- package/engines/file/FileCompiler.js +28 -0
- package/engines/file/FileExporter.js +116 -0
- package/engines/schema/SchemaEngine.js +33 -0
- package/engines/schema/SchemaValidator.js +67 -0
- package/engines/sql/SQLBuilder.js +96 -0
- package/engines/sql/SQLCompiler.js +140 -0
- package/engines/sql/SQLUtils.js +22 -0
- package/engines/validation/Validator.js +151 -0
- package/helper/Helper.js +64 -0
- package/helper/Settings.js +13 -0
- package/index.js +63 -0
- package/package.json +77 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const AdminManager_1 = __importDefault(require("../auth/AdminManager"));
|
|
16
|
+
const Affirm_1 = __importDefault(require("../core/Affirm"));
|
|
17
|
+
const UserManager_1 = __importDefault(require("../engines/UserManager"));
|
|
18
|
+
const Helper_1 = __importDefault(require("../helper/Helper"));
|
|
19
|
+
const DatabaseEngine_1 = __importDefault(require("./DatabaseEngine"));
|
|
20
|
+
const DatabaseStructure_1 = __importDefault(require("./DatabaseStructure"));
|
|
21
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
22
|
+
class DatabaseInitializerClass {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.initialize = () => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
try {
|
|
26
|
+
yield DatabaseEngine_1.default.connect();
|
|
27
|
+
yield this.createCollections();
|
|
28
|
+
yield this.primeCollections();
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('Error initializing database:', error);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
this.createCollections = () => __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const db = DatabaseEngine_1.default.db();
|
|
37
|
+
// Get list of existing collections
|
|
38
|
+
const collections = yield db.listCollections().toArray();
|
|
39
|
+
const existingCollections = collections.map(col => col.name);
|
|
40
|
+
// Check and create required collections from SETTINGS
|
|
41
|
+
for (const collection of DatabaseStructure_1.default.collections) {
|
|
42
|
+
const name = collection.name;
|
|
43
|
+
if (!existingCollections.includes(name)) {
|
|
44
|
+
console.log(`Creating collection: ${name}`);
|
|
45
|
+
yield db.createCollection(name);
|
|
46
|
+
for (const index of collection.indexes) {
|
|
47
|
+
console.log(`Setting up index ${JSON.stringify(index)}`);
|
|
48
|
+
yield db.collection(name).createIndex(index);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
console.log('Collections creation completed');
|
|
53
|
+
});
|
|
54
|
+
this.primeCollections = () => __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
// Create the default user of the system
|
|
56
|
+
(0, Affirm_1.default)(process.env.ROOT_TEMP_PASSWORD, 'Wrong system config: missing root user temp password');
|
|
57
|
+
const rootUser = yield DatabaseEngine_1.default.findOne(AdminManager_1.default.COLLECTION, { isRoot: true });
|
|
58
|
+
if (!rootUser) {
|
|
59
|
+
const salt = yield bcryptjs_1.default.genSalt(10);
|
|
60
|
+
const passHash = yield bcryptjs_1.default.hash(process.env.ROOT_TEMP_PASSWORD, salt);
|
|
61
|
+
const newRootUser = {
|
|
62
|
+
_id: Helper_1.default.uuid(),
|
|
63
|
+
_signature: '',
|
|
64
|
+
auth: { oid: null, provider: 'password' },
|
|
65
|
+
email: 'root@remora.com',
|
|
66
|
+
lastLogin: new Date().toJSON(),
|
|
67
|
+
name: 'Root',
|
|
68
|
+
roles: ['root'],
|
|
69
|
+
isRoot: true,
|
|
70
|
+
rootPasswordHash: passHash
|
|
71
|
+
};
|
|
72
|
+
console.log('Creating the default root user');
|
|
73
|
+
yield UserManager_1.default.update(newRootUser);
|
|
74
|
+
}
|
|
75
|
+
console.log('Collections priming completed');
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const DatabaseInitializer = new DatabaseInitializerClass();
|
|
80
|
+
exports.default = DatabaseInitializer;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const Settings_1 = __importDefault(require("../helper/Settings"));
|
|
7
|
+
const DATABASE_STRUCTURE = {
|
|
8
|
+
collections: [
|
|
9
|
+
{
|
|
10
|
+
name: Settings_1.default.db.collections.usage,
|
|
11
|
+
indexes: [
|
|
12
|
+
{ consumer: 1 },
|
|
13
|
+
{ startedAt: 1 },
|
|
14
|
+
{ status: 1 }
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: Settings_1.default.db.collections.users,
|
|
19
|
+
indexes: []
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: Settings_1.default.db.collections.apiKeys,
|
|
23
|
+
indexes: []
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
};
|
|
27
|
+
exports.default = DATABASE_STRUCTURE;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TODO: these are the documents that are stored in the database.
|
|
4
|
+
* TODO: I need to register all the events and usage around these resources (producers and consumers).
|
|
5
|
+
* Like all the executions, who executed, for how long and others...
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Consumer Schema",
|
|
4
|
+
"description": "Schema for defining data consumers",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"$schema": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"format": "uri"
|
|
10
|
+
},
|
|
11
|
+
"name": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "The name of the consumer"
|
|
14
|
+
},
|
|
15
|
+
"description": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "Optional description of the consumer"
|
|
18
|
+
},
|
|
19
|
+
"producers": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"description": "The 'FROM' elements of the SQL query (only the first one is in the FROM clause, others are joined in)",
|
|
22
|
+
"items": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"properties": {
|
|
25
|
+
"name": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "The name of an available producer/consumer"
|
|
28
|
+
},
|
|
29
|
+
"joins": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"properties": {
|
|
34
|
+
"otherName": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "The name of the other producer to JOIN with from the list of producers"
|
|
37
|
+
},
|
|
38
|
+
"relationship": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"enum": [
|
|
41
|
+
"one-to-one",
|
|
42
|
+
"one-to-many",
|
|
43
|
+
"many-to-one"
|
|
44
|
+
],
|
|
45
|
+
"description": "The type of join relationship"
|
|
46
|
+
},
|
|
47
|
+
"sql": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "The SQL to use to perform the join"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"required": [
|
|
53
|
+
"otherName",
|
|
54
|
+
"relationship",
|
|
55
|
+
"sql"
|
|
56
|
+
],
|
|
57
|
+
"additionalProperties": false
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"custom": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"description": "Custom code to extract fields from producers, transform them, and return results",
|
|
63
|
+
"properties": {
|
|
64
|
+
"language": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"enum": [
|
|
67
|
+
"js",
|
|
68
|
+
"python"
|
|
69
|
+
],
|
|
70
|
+
"description": "The language of the custom code"
|
|
71
|
+
},
|
|
72
|
+
"code": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"description": "The custom code to execute"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"required": [
|
|
78
|
+
"language",
|
|
79
|
+
"code"
|
|
80
|
+
],
|
|
81
|
+
"additionalProperties": false
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"required": [
|
|
85
|
+
"name"
|
|
86
|
+
],
|
|
87
|
+
"additionalProperties": false
|
|
88
|
+
},
|
|
89
|
+
"minItems": 1
|
|
90
|
+
},
|
|
91
|
+
"fields": {
|
|
92
|
+
"type": "array",
|
|
93
|
+
"description": "The fields to include in the consumer",
|
|
94
|
+
"items": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"properties": {
|
|
97
|
+
"key": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"description": "The dimension/measure of the producer OR '*'. If '*' then return all dimensions"
|
|
100
|
+
},
|
|
101
|
+
"alias": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"description": "If set, changes the key returned by the consumer to this alias"
|
|
104
|
+
},
|
|
105
|
+
"from": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"description": "If the key is ambiguous, set a 'from' with the name of the producer/consumer to get the key from"
|
|
108
|
+
},
|
|
109
|
+
"grouping": {
|
|
110
|
+
"type": "object",
|
|
111
|
+
"description": "If set, group resulting items that have the same value for the 'groupingKey'",
|
|
112
|
+
"properties": {
|
|
113
|
+
"groupingKey": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"description": "Used to create hierarchical data structure (parent -> children)"
|
|
116
|
+
},
|
|
117
|
+
"subFields": {
|
|
118
|
+
"type": "array",
|
|
119
|
+
"description": "Recursive structure defining fields that should be pulled inside this grouped field",
|
|
120
|
+
"items": {
|
|
121
|
+
"$ref": "#/definitions/consumerField"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"required": [
|
|
126
|
+
"groupingKey",
|
|
127
|
+
"subFields"
|
|
128
|
+
],
|
|
129
|
+
"additionalProperties": false
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"required": [
|
|
133
|
+
"key"
|
|
134
|
+
],
|
|
135
|
+
"additionalProperties": false
|
|
136
|
+
},
|
|
137
|
+
"minItems": 1
|
|
138
|
+
},
|
|
139
|
+
"outputs": {
|
|
140
|
+
"type": "array",
|
|
141
|
+
"description": "Output formats and configurations for the consumer",
|
|
142
|
+
"items": {
|
|
143
|
+
"type": "object",
|
|
144
|
+
"properties": {
|
|
145
|
+
"format": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"enum": [
|
|
148
|
+
"SQL",
|
|
149
|
+
"API",
|
|
150
|
+
"CSV",
|
|
151
|
+
"PARQUET",
|
|
152
|
+
"JSON"
|
|
153
|
+
],
|
|
154
|
+
"description": "The output format of the consumer"
|
|
155
|
+
},
|
|
156
|
+
"accellerated": {
|
|
157
|
+
"type": "boolean",
|
|
158
|
+
"description": "If true and supported, the consumer will be materialized to improve query performance"
|
|
159
|
+
},
|
|
160
|
+
"direct": {
|
|
161
|
+
"type": "boolean",
|
|
162
|
+
"description": "If true, no view is created on the consumer side due to permission limitations"
|
|
163
|
+
},
|
|
164
|
+
"exportDestination": {
|
|
165
|
+
"type": "string",
|
|
166
|
+
"description": "The name of the source where the consumer will export its data when deployed/run"
|
|
167
|
+
},
|
|
168
|
+
"trigger": {
|
|
169
|
+
"type": "object",
|
|
170
|
+
"description": "Triggers to perform the export (not just the usual 'Deploy')",
|
|
171
|
+
"properties": {
|
|
172
|
+
"type": {
|
|
173
|
+
"type": "string",
|
|
174
|
+
"enum": [
|
|
175
|
+
"CRON",
|
|
176
|
+
"API"
|
|
177
|
+
],
|
|
178
|
+
"description": "The type of trigger schedule"
|
|
179
|
+
},
|
|
180
|
+
"value": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"description": "The value for the trigger (e.g., cron expression or API endpoint)"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"required": [
|
|
186
|
+
"type",
|
|
187
|
+
"value"
|
|
188
|
+
],
|
|
189
|
+
"additionalProperties": false
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
"required": [
|
|
193
|
+
"format"
|
|
194
|
+
],
|
|
195
|
+
"additionalProperties": false
|
|
196
|
+
},
|
|
197
|
+
"minItems": 1
|
|
198
|
+
},
|
|
199
|
+
"filters": {
|
|
200
|
+
"type": "array",
|
|
201
|
+
"description": "Filters to apply to the consumer data",
|
|
202
|
+
"items": {
|
|
203
|
+
"type": "object",
|
|
204
|
+
"properties": {
|
|
205
|
+
"sql": {
|
|
206
|
+
"type": "string",
|
|
207
|
+
"description": "The SQL to use to filter on the included dimension"
|
|
208
|
+
},
|
|
209
|
+
"rule": {
|
|
210
|
+
"type": "object",
|
|
211
|
+
"description": "Non-SQL based filtering logic",
|
|
212
|
+
"properties": {
|
|
213
|
+
"member": {
|
|
214
|
+
"type": "string",
|
|
215
|
+
"description": "The field to filter on"
|
|
216
|
+
},
|
|
217
|
+
"operator": {
|
|
218
|
+
"type": "string",
|
|
219
|
+
"enum": [
|
|
220
|
+
"equals",
|
|
221
|
+
"notEquals",
|
|
222
|
+
"contains",
|
|
223
|
+
"notContains",
|
|
224
|
+
"startsWith",
|
|
225
|
+
"endsWith",
|
|
226
|
+
"greaterThan",
|
|
227
|
+
"greaterThanOrEquals",
|
|
228
|
+
"lessThan",
|
|
229
|
+
"lessThanOrEquals",
|
|
230
|
+
"in",
|
|
231
|
+
"notIn",
|
|
232
|
+
"between",
|
|
233
|
+
"notBetween",
|
|
234
|
+
"isNull",
|
|
235
|
+
"isNotNull",
|
|
236
|
+
"true",
|
|
237
|
+
"false",
|
|
238
|
+
"matches",
|
|
239
|
+
"notMatches",
|
|
240
|
+
"sql"
|
|
241
|
+
],
|
|
242
|
+
"description": "The filter operator to apply"
|
|
243
|
+
},
|
|
244
|
+
"values": {
|
|
245
|
+
"type": "array",
|
|
246
|
+
"items": {
|
|
247
|
+
"type": "string"
|
|
248
|
+
},
|
|
249
|
+
"description": "The values to filter against"
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
"required": [
|
|
253
|
+
"member",
|
|
254
|
+
"operator",
|
|
255
|
+
"values"
|
|
256
|
+
],
|
|
257
|
+
"additionalProperties": false
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
"additionalProperties": false
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"metadata": {
|
|
264
|
+
"type": "object",
|
|
265
|
+
"description": "Any tags to add to this consumer for sorting and organizing",
|
|
266
|
+
"additionalProperties": {
|
|
267
|
+
"type": "string"
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
"project": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"description": "Tag that groups consumers together to make them accessible by a singular api_key"
|
|
273
|
+
},
|
|
274
|
+
"schema": {
|
|
275
|
+
"type": "string",
|
|
276
|
+
"description": "The name of the JSON schema in this project that this consumer needs to adhere to"
|
|
277
|
+
},
|
|
278
|
+
"_version": {
|
|
279
|
+
"type": "number",
|
|
280
|
+
"description": "Version number of the consumer configuration"
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
"required": [
|
|
284
|
+
"name",
|
|
285
|
+
"producers",
|
|
286
|
+
"fields",
|
|
287
|
+
"outputs",
|
|
288
|
+
"_version"
|
|
289
|
+
],
|
|
290
|
+
"additionalProperties": false,
|
|
291
|
+
"definitions": {
|
|
292
|
+
"consumerField": {
|
|
293
|
+
"type": "object",
|
|
294
|
+
"properties": {
|
|
295
|
+
"key": {
|
|
296
|
+
"type": "string",
|
|
297
|
+
"description": "The dimension/measure of the producer OR '*'. If '*' then return all dimensions"
|
|
298
|
+
},
|
|
299
|
+
"alias": {
|
|
300
|
+
"type": "string",
|
|
301
|
+
"description": "If set, changes the key returned by the consumer to this alias"
|
|
302
|
+
},
|
|
303
|
+
"from": {
|
|
304
|
+
"type": "string",
|
|
305
|
+
"description": "If the key is ambiguous, set a 'from' with the name of the producer/consumer to get the key from"
|
|
306
|
+
},
|
|
307
|
+
"grouping": {
|
|
308
|
+
"type": "object",
|
|
309
|
+
"description": "If set, group resulting items that have the same value for the 'groupingKey'",
|
|
310
|
+
"properties": {
|
|
311
|
+
"groupingKey": {
|
|
312
|
+
"type": "string",
|
|
313
|
+
"description": "Used to create hierarchical data structure (parent -> children)"
|
|
314
|
+
},
|
|
315
|
+
"subFields": {
|
|
316
|
+
"type": "array",
|
|
317
|
+
"description": "Recursive structure defining fields that should be pulled inside this grouped field",
|
|
318
|
+
"items": {
|
|
319
|
+
"$ref": "#/definitions/consumerField"
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
"required": [
|
|
324
|
+
"groupingKey",
|
|
325
|
+
"subFields"
|
|
326
|
+
],
|
|
327
|
+
"additionalProperties": false
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
"required": [
|
|
331
|
+
"key"
|
|
332
|
+
],
|
|
333
|
+
"additionalProperties": false
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
"examples": [
|
|
337
|
+
{
|
|
338
|
+
"name": "UserOrderAnalytics",
|
|
339
|
+
"description": "Consumer that combines user data with their order history",
|
|
340
|
+
"producers": [
|
|
341
|
+
{
|
|
342
|
+
"name": "UserData",
|
|
343
|
+
"joins": [
|
|
344
|
+
{
|
|
345
|
+
"otherName": "OrderData",
|
|
346
|
+
"relationship": "one-to-many",
|
|
347
|
+
"sql": "${P.id} = ${OrderData.user_id}"
|
|
348
|
+
}
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"name": "OrderData"
|
|
353
|
+
}
|
|
354
|
+
],
|
|
355
|
+
"fields": [
|
|
356
|
+
{
|
|
357
|
+
"key": "id",
|
|
358
|
+
"from": "UserData"
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"key": "name",
|
|
362
|
+
"alias": "user_name",
|
|
363
|
+
"from": "UserData"
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"key": "email",
|
|
367
|
+
"from": "UserData"
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"key": "orders",
|
|
371
|
+
"grouping": {
|
|
372
|
+
"groupingKey": "order_items",
|
|
373
|
+
"subFields": [
|
|
374
|
+
{
|
|
375
|
+
"key": "id",
|
|
376
|
+
"from": "OrderData",
|
|
377
|
+
"alias": "order_id"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"key": "created_at",
|
|
381
|
+
"from": "OrderData"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"key": "total_amount",
|
|
385
|
+
"from": "OrderData"
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
],
|
|
391
|
+
"outputs": [
|
|
392
|
+
{
|
|
393
|
+
"format": "API"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"format": "JSON",
|
|
397
|
+
"exportDestination": "Data Lake",
|
|
398
|
+
"trigger": {
|
|
399
|
+
"type": "CRON",
|
|
400
|
+
"value": "0 0 * * *"
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
],
|
|
404
|
+
"filters": [
|
|
405
|
+
{
|
|
406
|
+
"rule": {
|
|
407
|
+
"member": "total_amount",
|
|
408
|
+
"operator": "greaterThan",
|
|
409
|
+
"values": [
|
|
410
|
+
"100"
|
|
411
|
+
]
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
],
|
|
415
|
+
"metadata": {
|
|
416
|
+
"department": "Sales",
|
|
417
|
+
"owner": "analytics-team"
|
|
418
|
+
},
|
|
419
|
+
"project": "sales-analytics",
|
|
420
|
+
"_version": 1
|
|
421
|
+
}
|
|
422
|
+
]
|
|
423
|
+
}
|