@ductape/sdk 0.0.4-v11 → 0.0.4-v12

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.
Files changed (32) hide show
  1. package/dist/api/services/productsApi.service.d.ts +2 -0
  2. package/dist/api/services/productsApi.service.js +11 -0
  3. package/dist/api/services/productsApi.service.js.map +1 -1
  4. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.d.ts +1 -1
  5. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js +34 -1
  6. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js.map +1 -1
  7. package/dist/index.d.ts +941 -44
  8. package/dist/index.js +847 -67
  9. package/dist/index.js.map +1 -1
  10. package/dist/processor/services/processor.service.d.ts +21 -0
  11. package/dist/processor/services/processor.service.js +116 -3
  12. package/dist/processor/services/processor.service.js.map +1 -1
  13. package/dist/products/services/products.service.d.ts +14 -2
  14. package/dist/products/services/products.service.js +151 -10
  15. package/dist/products/services/products.service.js.map +1 -1
  16. package/dist/products/validators/index.d.ts +2 -1
  17. package/dist/products/validators/index.js +3 -1
  18. package/dist/products/validators/index.js.map +1 -1
  19. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.d.ts +4 -0
  20. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js +58 -0
  21. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js.map +1 -0
  22. package/dist/test/test.health.d.ts +1 -0
  23. package/dist/test/test.health.js +49 -0
  24. package/dist/test/test.health.js.map +1 -0
  25. package/dist/types/enums.d.ts +2 -1
  26. package/dist/types/enums.js +1 -0
  27. package/dist/types/enums.js.map +1 -1
  28. package/dist/types/productsBuilder.types.d.ts +21 -0
  29. package/dist/types/productsBuilder.types.js.map +1 -1
  30. package/dist/utils/index.js +1 -1
  31. package/dist/utils/index.js.map +1 -1
  32. 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
- constructor({ workspace_id, public_key, user_id, token, env_type, redis_client }: IBuilderInit);
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);
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 && ((_a = data.sample.data) === null || _a === void 0 ? void 0 : _a.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
- throw new Error(`Key ${data.key} not found for ${data.type} for sequence ${sequence.tag} event ${sequence.events[data.event_index].event}`);
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