@ductape/sdk 0.0.4-v11 → 0.0.4-v13
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/dist/api/services/productsApi.service.d.ts +2 -0
- package/dist/api/services/productsApi.service.js +11 -0
- package/dist/api/services/productsApi.service.js.map +1 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.d.ts +1 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js +34 -1
- package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js.map +1 -1
- package/dist/index.d.ts +941 -44
- package/dist/index.js +850 -67
- package/dist/index.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +21 -0
- package/dist/processor/services/processor.service.js +117 -4
- package/dist/processor/services/processor.service.js.map +1 -1
- package/dist/products/services/products.service.d.ts +14 -2
- package/dist/products/services/products.service.js +151 -10
- package/dist/products/services/products.service.js.map +1 -1
- package/dist/products/validators/index.d.ts +2 -1
- package/dist/products/validators/index.js +3 -1
- package/dist/products/validators/index.js.map +1 -1
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.d.ts +4 -0
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js +58 -0
- package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js.map +1 -0
- package/dist/test/test.health.d.ts +1 -0
- package/dist/test/test.health.js +49 -0
- package/dist/test/test.health.js.map +1 -0
- package/dist/types/enums.d.ts +2 -1
- package/dist/types/enums.js +1 -0
- package/dist/types/enums.js.map +1 -1
- package/dist/types/index.types.d.ts +2 -3
- package/dist/types/index.types.js.map +1 -1
- package/dist/types/processor.types.d.ts +1 -1
- package/dist/types/productsBuilder.types.d.ts +21 -0
- package/dist/types/productsBuilder.types.js.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IApp, IAppAccess, IAppAction, IAppWebhook, ISample, IVersion } from '../../types/appBuilder.types';
|
|
2
2
|
import { IBuilderInit } from '../../types/index.types';
|
|
3
|
-
import { IActionDataParserInput, IActionRequest, ICreateProductsBuilder, IFeatureEvent, IFeatureInput, IFeatureSequence, IProduct, IProductApp, IProductCache, IProductDatabase, IProductDatabaseAction, IProductEnv, IProductFeature, IProductFunction, IProductJobs, IParseActionEventInput, IParseInputStringInput, IParseInputStringMetaData, IProductStorage, IDbActionRequest, INotificationRequest, IProductQuota, IProductFallback, IProductDatabaseMigration, IQuotaOptions, IFallbackOptions, IProductSession, IFetchFilesPayload, IFetchUsersPayload } from '../../types/productsBuilder.types';
|
|
3
|
+
import { IActionDataParserInput, IActionRequest, ICreateProductsBuilder, IFeatureEvent, IFeatureInput, IFeatureSequence, IProduct, IProductApp, IProductCache, IProductDatabase, IProductDatabaseAction, IProductEnv, IProductFeature, IProductFunction, IProductJobs, IParseActionEventInput, IParseInputStringInput, IParseInputStringMetaData, IProductStorage, IDbActionRequest, INotificationRequest, IProductQuota, IProductFallback, IProductDatabaseMigration, IQuotaOptions, IFallbackOptions, IProductSession, IFetchFilesPayload, IFetchUsersPayload, IProductAppHealth } from '../../types/productsBuilder.types';
|
|
4
4
|
import { KeyValuePair } from '../../imports/imports.types';
|
|
5
5
|
import { IProductNotification, INotificationEnv, IProductNotificationTemplate, IProductMessageBroker, IProductMessageBrokerTopic, IFileURLPayload } from '../../types/processor.types';
|
|
6
6
|
import { IParsedSample } from '../../types/inputs.types';
|
|
@@ -79,10 +79,15 @@ export interface IProductsBuilderService {
|
|
|
79
79
|
updateJob(tag: string, data: Partial<IProductJobs>): Promise<void>;
|
|
80
80
|
fetchJob(tag: string): IProductJobs;
|
|
81
81
|
fetchJobs(): Array<IProductJobs>;
|
|
82
|
+
createHealthcheck(data: Partial<IProductAppHealth>): Promise<void>;
|
|
83
|
+
updateHealthcheck(tag: string, data: Partial<IProductAppHealth>): Promise<void>;
|
|
84
|
+
fetchHealthcheck(access_tag: string, tag: string): IProductAppHealth | null;
|
|
85
|
+
fetchHealthchecks(access_tag: string): Array<IProductAppHealth>;
|
|
82
86
|
createAppAccessTag(app_tag: string): Promise<IAppAccess>;
|
|
83
87
|
extractStages(input: string): Array<string>;
|
|
84
88
|
updateDataValidation(tag: string, update: Partial<IParsedSample>): Promise<boolean>;
|
|
85
89
|
fetchStorageFiles(filter: IFetchFilesPayload): Promise<Array<IFileURLPayload>>;
|
|
90
|
+
fetchSessionUser(ductape_user_id: string): Promise<any>;
|
|
86
91
|
}
|
|
87
92
|
export default class ProductsBuilderService implements IProductsBuilderService {
|
|
88
93
|
private user_id;
|
|
@@ -103,7 +108,13 @@ export default class ProductsBuilderService implements IProductsBuilderService {
|
|
|
103
108
|
private inputsService;
|
|
104
109
|
private thirdPartyApps;
|
|
105
110
|
private isQuotaFallbackInput;
|
|
106
|
-
|
|
111
|
+
private redisClient?;
|
|
112
|
+
private queues;
|
|
113
|
+
constructor({ workspace_id, public_key, user_id, token, env_type, redis_client, queues }: IBuilderInit);
|
|
114
|
+
createHealthcheck(data: Partial<IProductAppHealth>): Promise<void>;
|
|
115
|
+
updateHealthcheck(tag: string, data: Partial<IProductAppHealth>): Promise<void>;
|
|
116
|
+
fetchHealthcheck(access_tag: string, tag: string, throwError?: boolean): IProductAppHealth | null;
|
|
117
|
+
fetchHealthchecks(access_tag: string, throwError?: boolean): Array<IProductAppHealth>;
|
|
107
118
|
updateDataValidation(selector: string, update: Partial<IParsedSample>): Promise<boolean>;
|
|
108
119
|
createProduct(data: ICreateProductsBuilder): Promise<void>;
|
|
109
120
|
initializeWorkspace(subCheck?: boolean): Promise<void>;
|
|
@@ -241,4 +252,5 @@ export default class ProductsBuilderService implements IProductsBuilderService {
|
|
|
241
252
|
fetchJob(tag: string, throwError?: boolean): IProductJobs | null;
|
|
242
253
|
fetchJobs(): Array<IProductJobs>;
|
|
243
254
|
private getUserAccess;
|
|
255
|
+
fetchSessionUser(ductape_user_id: string): Promise<any>;
|
|
244
256
|
}
|
|
@@ -42,7 +42,7 @@ const functions_utils_1 = require("../utils/functions.utils");
|
|
|
42
42
|
const objects_utils_2 = require("../../apps/utils/objects.utils");
|
|
43
43
|
const webhooksApi_service_1 = require("../../api/services/webhooksApi.service");
|
|
44
44
|
class ProductsBuilderService {
|
|
45
|
-
constructor({ workspace_id, public_key, user_id, token, env_type, redis_client }) {
|
|
45
|
+
constructor({ workspace_id, public_key, user_id, token, env_type, redis_client, queues }) {
|
|
46
46
|
this.workspace_id = workspace_id;
|
|
47
47
|
this.public_key = public_key;
|
|
48
48
|
this.user_id = user_id;
|
|
@@ -54,6 +54,137 @@ class ProductsBuilderService {
|
|
|
54
54
|
this.appApi = new appApi_service_1.AppApiService(env_type, redis_client);
|
|
55
55
|
this.inputsService = new inputs_service_1.default();
|
|
56
56
|
this.thirdPartyApps = [];
|
|
57
|
+
if (redis_client) {
|
|
58
|
+
this.redisClient = redis_client;
|
|
59
|
+
// Start healthcheck workers automatically
|
|
60
|
+
//this.startHealthcheckWorkers();
|
|
61
|
+
}
|
|
62
|
+
if (queues) {
|
|
63
|
+
this.queues = queues;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async createHealthcheck(data) {
|
|
67
|
+
try {
|
|
68
|
+
await validators_1.CreateProductHealthcheckSchema.validateAsync(data);
|
|
69
|
+
if (!data.tag) {
|
|
70
|
+
throw new Error('tag field is required');
|
|
71
|
+
}
|
|
72
|
+
const exists = this.fetchHealthcheck(data.app, data.tag);
|
|
73
|
+
if (!exists) {
|
|
74
|
+
const { app: access_tag, event: action } = data;
|
|
75
|
+
const app = await this.fetchThirdPartyAppByAccessTag(access_tag);
|
|
76
|
+
const version = app.versions.find((data) => data.tag === app.version);
|
|
77
|
+
if (!version) {
|
|
78
|
+
throw new Error(`Version ${app.version} not found`);
|
|
79
|
+
}
|
|
80
|
+
const event = version.actions.find((act) => act.tag === action);
|
|
81
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
82
|
+
const exists = this.fetchEnv(env.slug);
|
|
83
|
+
if (!exists) {
|
|
84
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
85
|
+
}
|
|
86
|
+
await this.validateActionDataInput({ input: env.input }, event, env.input, 0, 0);
|
|
87
|
+
env.input = (0, processor_utils_1.encrypt)(JSON.stringify(env.input), this.fetchProduct().private_key);
|
|
88
|
+
console.log("INPUT", env);
|
|
89
|
+
return env;
|
|
90
|
+
}));
|
|
91
|
+
const envs = this.fetchEnvs();
|
|
92
|
+
console.log("ENVS ===>>>>", envs);
|
|
93
|
+
console.log("DBENVS ====>>>>", data.envs);
|
|
94
|
+
envs.map((env) => {
|
|
95
|
+
const exists = data.envs.findIndex((dbEnv) => dbEnv.slug === env.slug);
|
|
96
|
+
if (exists === -1) {
|
|
97
|
+
throw new Error(`Product env ${env.slug} is not defined, please provide details`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
console.log("UPDATING VALUE", data);
|
|
101
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { action: enums_1.RequestAction.CREATE, component: enums_1.ProductComponents.HEALTHCHECK }), this.getUserAccess());
|
|
102
|
+
await this.initializeProduct(this.product_id);
|
|
103
|
+
data.envs.map(async (env) => {
|
|
104
|
+
const payload = {
|
|
105
|
+
app: data.app,
|
|
106
|
+
event: data.event,
|
|
107
|
+
input: env.input,
|
|
108
|
+
env: env.slug,
|
|
109
|
+
product: this.product.tag,
|
|
110
|
+
retries: data.retries,
|
|
111
|
+
};
|
|
112
|
+
const jobId = `healthcheck-${data.tag}`;
|
|
113
|
+
const job = await this.queues.health.getJob(jobId);
|
|
114
|
+
if (job) {
|
|
115
|
+
await job.remove();
|
|
116
|
+
}
|
|
117
|
+
await this.queues.health.add(jobId, payload, { jobId, repeat: { every: data.interval } });
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
console.log(e);
|
|
123
|
+
throw e;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async updateHealthcheck(tag, data) {
|
|
127
|
+
try {
|
|
128
|
+
// 1. Fetch the existing healthcheck
|
|
129
|
+
const healthcheck = this.fetchHealthcheck(data.app, tag);
|
|
130
|
+
if (!healthcheck) {
|
|
131
|
+
throw new Error(`Healthcheck with tag: ${tag} not found`);
|
|
132
|
+
}
|
|
133
|
+
// 2. Validate the incoming data
|
|
134
|
+
await validators_1.CreateProductHealthcheckSchema.validateAsync(data); // No Update schema, use Create
|
|
135
|
+
// 3. Check for tag conflicts
|
|
136
|
+
if (data.tag && data.tag !== tag && this.fetchHealthcheck(data.app, data.tag)) {
|
|
137
|
+
throw new Error(`Healthcheck with tag ${data.tag} already exists`);
|
|
138
|
+
}
|
|
139
|
+
// 4. Validate and process envs
|
|
140
|
+
if (data.envs) {
|
|
141
|
+
data.envs = await Promise.all(data.envs.map(async (env) => {
|
|
142
|
+
const exists = this.fetchEnv(env.slug);
|
|
143
|
+
if (!exists) {
|
|
144
|
+
throw new Error(`Env ${env.slug} does not exist`);
|
|
145
|
+
}
|
|
146
|
+
// Validate input if present
|
|
147
|
+
if (env.input) {
|
|
148
|
+
const app = await this.fetchThirdPartyAppByAccessTag(data.app);
|
|
149
|
+
const version = app.versions.find((v) => v.tag === app.version);
|
|
150
|
+
if (!version) {
|
|
151
|
+
throw new Error(`Version ${app.version} not found`);
|
|
152
|
+
}
|
|
153
|
+
const event = version.actions.find((act) => act.tag === data.event);
|
|
154
|
+
await this.validateActionDataInput({ input: env.input }, event, env.input, 0, 0);
|
|
155
|
+
env.input = (0, processor_utils_1.encrypt)(JSON.stringify(env.input), this.fetchProduct().private_key);
|
|
156
|
+
}
|
|
157
|
+
return env;
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
// 5. Ensure all product envs are covered
|
|
161
|
+
const envs = this.fetchEnvs();
|
|
162
|
+
envs.map((env) => {
|
|
163
|
+
var _a;
|
|
164
|
+
const exists = (_a = data.envs) === null || _a === void 0 ? void 0 : _a.findIndex((dbEnv) => dbEnv.slug === env.slug);
|
|
165
|
+
if (exists === -1) {
|
|
166
|
+
throw new Error(`Product env ${env.slug} is not defined, please provide details`);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
// 6. Update the healthcheck
|
|
170
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign(Object.assign({}, healthcheck), data), { tag, component: enums_1.ProductComponents.HEALTHCHECK, action: enums_1.RequestAction.UPDATE }), this.getUserAccess());
|
|
171
|
+
await this.initializeProduct(this.product_id);
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
throw e;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
fetchHealthcheck(access_tag, tag, throwError = false) {
|
|
178
|
+
const health = this.product.healthchecks.find((data) => data.tag === tag && data.app === access_tag);
|
|
179
|
+
if (!health && throwError)
|
|
180
|
+
throw new Error(`Healthcheck ${tag} not found`);
|
|
181
|
+
return health;
|
|
182
|
+
}
|
|
183
|
+
fetchHealthchecks(access_tag, throwError = false) {
|
|
184
|
+
const health = this.product.healthchecks.filter((data) => data.app === access_tag);
|
|
185
|
+
if (!health && throwError)
|
|
186
|
+
throw new Error(`Access tag ${access_tag} not found`);
|
|
187
|
+
return health;
|
|
57
188
|
}
|
|
58
189
|
async updateDataValidation(selector, update) {
|
|
59
190
|
if (!selector.startsWith('$Data{') && !selector.startsWith('$Filter')) {
|
|
@@ -157,6 +288,7 @@ class ProductsBuilderService {
|
|
|
157
288
|
async initializeProductByTag(tag) {
|
|
158
289
|
try {
|
|
159
290
|
this.product = await this.productApi.fetchProductByTag(tag, this.getUserAccess());
|
|
291
|
+
console.error(this.product, tag);
|
|
160
292
|
this.product_id = this.product._id;
|
|
161
293
|
}
|
|
162
294
|
catch (e) {
|
|
@@ -1219,7 +1351,7 @@ class ProductsBuilderService {
|
|
|
1219
1351
|
throw new Error(`App ${app.access_tag} not found`);
|
|
1220
1352
|
}
|
|
1221
1353
|
const cleanedAppData = await this.validateAppData(appData, app);
|
|
1222
|
-
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, cleanedAppData), { component: enums_1.ProductComponents.APP, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1354
|
+
await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, cleanedAppData), { app_tag: appData.tag, component: enums_1.ProductComponents.APP, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
|
|
1223
1355
|
await this.initializeProduct(this.product_id);
|
|
1224
1356
|
}
|
|
1225
1357
|
else {
|
|
@@ -1277,7 +1409,7 @@ class ProductsBuilderService {
|
|
|
1277
1409
|
return this.product.apps;
|
|
1278
1410
|
}
|
|
1279
1411
|
fetchApp(tag, throwErrorIfExists = false) {
|
|
1280
|
-
const app = this.product.apps.find((data) => data.access_tag === tag);
|
|
1412
|
+
const app = this.product.apps.find((data) => data.app_tag === tag || data.access_tag === tag);
|
|
1281
1413
|
if (!app && throwErrorIfExists)
|
|
1282
1414
|
throw new Error(`App ${tag} not found`);
|
|
1283
1415
|
return app;
|
|
@@ -2018,7 +2150,7 @@ class ProductsBuilderService {
|
|
|
2018
2150
|
});
|
|
2019
2151
|
}
|
|
2020
2152
|
async validateActionInputData(data, skipSample = false, option = false, optionIndex = 0) {
|
|
2021
|
-
var _a;
|
|
2153
|
+
var _a, _b;
|
|
2022
2154
|
const { obj } = data, base_data = __rest(data, ["obj"]);
|
|
2023
2155
|
if (!data.sample && Object.keys(obj).length === 0) {
|
|
2024
2156
|
return;
|
|
@@ -2026,8 +2158,8 @@ class ProductsBuilderService {
|
|
|
2026
2158
|
if (!data.sample) {
|
|
2027
2159
|
throw new Error('Something unexpected happened in validating action input');
|
|
2028
2160
|
}
|
|
2029
|
-
const sequence = data.feature.sequence[data.sequence_index];
|
|
2030
|
-
if (obj === undefined || obj === null) {
|
|
2161
|
+
const sequence = data.feature.sequence ? (_a = data.feature) === null || _a === void 0 ? void 0 : _a.sequence[data.sequence_index] : null;
|
|
2162
|
+
if ((obj === undefined || obj === null) && sequence) {
|
|
2031
2163
|
if (!option) {
|
|
2032
2164
|
throw new Error(`sequence ${sequence.tag} event ${sequence.events[data.event_index].event} ${data.type} should not be ${obj}`);
|
|
2033
2165
|
}
|
|
@@ -2035,7 +2167,7 @@ class ProductsBuilderService {
|
|
|
2035
2167
|
throw new Error(`option event index ${optionIndex}, ${data.type} should not be ${obj}`);
|
|
2036
2168
|
}
|
|
2037
2169
|
}
|
|
2038
|
-
if (Object.values(obj).length > 0 && ((
|
|
2170
|
+
if (sequence && (Object.values(obj).length > 0 && ((_b = data.sample.data) === null || _b === void 0 ? void 0 : _b.length) === 0)) {
|
|
2039
2171
|
if (!option) {
|
|
2040
2172
|
throw new Error(`sequence ${sequence.tag} event ${sequence.events[data.event_index].event} ${data.type} should be an empty object`);
|
|
2041
2173
|
}
|
|
@@ -2046,7 +2178,7 @@ class ProductsBuilderService {
|
|
|
2046
2178
|
if (Object.values(obj).length === 0 && data.sample.data.length === 0 /*data.sample?.data?.length === 0*/) {
|
|
2047
2179
|
return;
|
|
2048
2180
|
}
|
|
2049
|
-
if (Object.values(obj).length === 0 && data.sample.data.length > 0 && !skipSample) {
|
|
2181
|
+
if (sequence && Object.values(obj).length === 0 && data.sample.data.length > 0 && !skipSample) {
|
|
2050
2182
|
//console.log("validity err: ",obj, data.sample)
|
|
2051
2183
|
if (!option) {
|
|
2052
2184
|
throw new Error(`sequence ${sequence.tag} event ${sequence.events[data.event_index].event} ${data.type} should not be an empty object`);
|
|
@@ -2574,9 +2706,10 @@ class ProductsBuilderService {
|
|
|
2574
2706
|
return found;
|
|
2575
2707
|
}
|
|
2576
2708
|
validateActionKeyPlacement(data) {
|
|
2709
|
+
var _a;
|
|
2577
2710
|
const actionData = data.sample.data;
|
|
2578
2711
|
const { indexes } = data;
|
|
2579
|
-
const sequence = data.feature.sequence[data.sequence_index];
|
|
2712
|
+
const sequence = data.feature.sequence ? (_a = data.feature) === null || _a === void 0 ? void 0 : _a.sequence[data.sequence_index] : null;
|
|
2580
2713
|
const datapoint = actionData.find((item) => {
|
|
2581
2714
|
return (item.parent_key === indexes.parent_key && item.key === data.key && item.level === indexes.level //&&
|
|
2582
2715
|
//indexes.index === item.index
|
|
@@ -2584,7 +2717,12 @@ class ProductsBuilderService {
|
|
|
2584
2717
|
});
|
|
2585
2718
|
if (!datapoint) {
|
|
2586
2719
|
console.log('VALIDATE', data.key, data.value, actionData, indexes);
|
|
2587
|
-
|
|
2720
|
+
if (sequence) {
|
|
2721
|
+
throw new Error(`Key ${data.key} not found for ${data.type} for sequence ${sequence.tag} event ${sequence.events[data.event_index].event}`);
|
|
2722
|
+
}
|
|
2723
|
+
else {
|
|
2724
|
+
throw new Error(`Key ${data.key} not found`);
|
|
2725
|
+
}
|
|
2588
2726
|
}
|
|
2589
2727
|
return datapoint;
|
|
2590
2728
|
}
|
|
@@ -3058,6 +3196,9 @@ class ProductsBuilderService {
|
|
|
3058
3196
|
public_key: this.public_key,
|
|
3059
3197
|
};
|
|
3060
3198
|
}
|
|
3199
|
+
async fetchSessionUser(ductape_user_id) {
|
|
3200
|
+
return await this.productApi.fetchProductSessionUser(ductape_user_id, this.getUserAccess());
|
|
3201
|
+
}
|
|
3061
3202
|
}
|
|
3062
3203
|
exports.default = ProductsBuilderService;
|
|
3063
3204
|
//# sourceMappingURL=products.service.js.map
|