@beseif-solutions/prow-core 1.0.6 → 1.1.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/dist/core.d.ts CHANGED
@@ -4,6 +4,7 @@ import lodash from "lodash";
4
4
  import moment from "moment-timezone";
5
5
  import { FromCatalog, FromDirectory, T } from "./minified-utils/locales";
6
6
  import { SourceConfig } from "./entities/source";
7
+ import { File } from "./minified-utils/fields";
7
8
  export type SourceFunctions = {
8
9
  register: <SC extends SourceConfig = SourceConfig>(source: SC[`id`], sandbox: boolean, data: SC[`fields`]) => Promise<{
9
10
  id: string;
@@ -14,6 +15,10 @@ export type SourceFunctions = {
14
15
  }[]>;
15
16
  unregister: <SC extends SourceConfig = SourceConfig>(source: SC[`id`], sandbox: boolean, id: string) => Promise<void>;
16
17
  };
18
+ export type StorageFunctions = {
19
+ read: (id: string) => Promise<string>;
20
+ store: (file: File) => Promise<File>;
21
+ };
17
22
  export type Core = {
18
23
  axios: AxiosInstance;
19
24
  moment: typeof moment;
@@ -22,11 +27,13 @@ export type Core = {
22
27
  joi: Joi.Root;
23
28
  sources?: SourceFunctions;
24
29
  t: T;
30
+ files: StorageFunctions;
25
31
  };
26
32
  type CoreOptions = {
33
+ localization: FromDirectory | FromCatalog;
34
+ files: StorageFunctions;
27
35
  env?: Record<string, any>;
28
36
  sources?: SourceFunctions;
29
- localization: FromDirectory | FromCatalog;
30
37
  };
31
38
  export declare const core: (options: CoreOptions) => Promise<Core>;
32
39
  export {};
package/dist/core.js CHANGED
@@ -30,5 +30,6 @@ const core = async (options) => ({
30
30
  joi: joi_1.default,
31
31
  sources: options.sources || FALLBACK_SOURCES,
32
32
  t: (0, locales_1.i18n)(options.localization).t,
33
+ files: options.files,
33
34
  });
34
35
  exports.core = core;
package/dist/index.d.ts CHANGED
@@ -1,12 +1,11 @@
1
- export { Core, core } from './core';
1
+ export { Core, core, SourceFunctions, StorageFunctions } from './core';
2
2
  export { CoreFunction, idSchema } from './entities/commons';
3
3
  export { Credentials, credentialsSchema, OAuthCredentials, oauthCredentialsSchema, SessionCredentials, sessionCredentialsSchema, StaticCredentials, staticCredentialsSchema } from './entities/credentials';
4
4
  export { Action, actionOutputSchema, actionSchema, AsyncAction, Event, eventSchema, ImmediateTrigger, immediateTriggerSchema, Request, ScheduledTrigger, scheduledTriggerSchema, SyncAction, syncActionSchema, Trigger, triggerOutputSchema, triggerSchema } from './entities/events';
5
5
  export { Provider, providerSchema } from './entities/provider';
6
6
  export { Source } from './entities/source';
7
7
  export { getPath, hasExpression, isDynamic, isExpression, split } from './minified-utils/context';
8
- export { alter, extract, fieldSchema, fieldsSchema, validate, ValidationResult } from './minified-utils/validation';
9
8
  export { Condition, Field, File, SelectFieldChoice } from './minified-utils/fields';
10
9
  export { DEFAULT_LOCALE, i18n, LocalizedField, LocalizedProperties, localizeFields, localizeGroup, localizeInputs, localizeOutputs, localizeProperties } from './minified-utils/locales';
11
10
  export { Properties } from './minified-utils/properties';
12
- export { Protocol } from './minified-utils/protocol';
11
+ export { alter, extract, fieldSchema, fieldsSchema, validate, ValidationOptions, ValidationResult } from './minified-utils/validation';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Protocol = exports.Properties = exports.localizeProperties = exports.localizeOutputs = exports.localizeInputs = exports.localizeGroup = exports.localizeFields = exports.i18n = exports.DEFAULT_LOCALE = exports.validate = exports.fieldsSchema = exports.fieldSchema = exports.extract = exports.alter = exports.split = exports.isExpression = exports.isDynamic = exports.hasExpression = exports.getPath = exports.providerSchema = exports.triggerSchema = exports.triggerOutputSchema = exports.syncActionSchema = exports.scheduledTriggerSchema = exports.immediateTriggerSchema = exports.eventSchema = exports.actionSchema = exports.actionOutputSchema = exports.staticCredentialsSchema = exports.sessionCredentialsSchema = exports.oauthCredentialsSchema = exports.credentialsSchema = exports.idSchema = exports.core = void 0;
3
+ exports.validate = exports.fieldsSchema = exports.fieldSchema = exports.extract = exports.alter = exports.Properties = exports.localizeProperties = exports.localizeOutputs = exports.localizeInputs = exports.localizeGroup = exports.localizeFields = exports.i18n = exports.DEFAULT_LOCALE = exports.split = exports.isExpression = exports.isDynamic = exports.hasExpression = exports.getPath = exports.providerSchema = exports.triggerSchema = exports.triggerOutputSchema = exports.syncActionSchema = exports.scheduledTriggerSchema = exports.immediateTriggerSchema = exports.eventSchema = exports.actionSchema = exports.actionOutputSchema = exports.staticCredentialsSchema = exports.sessionCredentialsSchema = exports.oauthCredentialsSchema = exports.credentialsSchema = exports.idSchema = exports.core = void 0;
4
4
  var core_1 = require("./core");
5
5
  Object.defineProperty(exports, "core", { enumerable: true, get: function () { return core_1.core; } });
6
6
  var commons_1 = require("./entities/commons");
@@ -27,12 +27,6 @@ Object.defineProperty(exports, "hasExpression", { enumerable: true, get: functio
27
27
  Object.defineProperty(exports, "isDynamic", { enumerable: true, get: function () { return context_1.isDynamic; } });
28
28
  Object.defineProperty(exports, "isExpression", { enumerable: true, get: function () { return context_1.isExpression; } });
29
29
  Object.defineProperty(exports, "split", { enumerable: true, get: function () { return context_1.split; } });
30
- var validation_1 = require("./minified-utils/validation");
31
- Object.defineProperty(exports, "alter", { enumerable: true, get: function () { return validation_1.alter; } });
32
- Object.defineProperty(exports, "extract", { enumerable: true, get: function () { return validation_1.extract; } });
33
- Object.defineProperty(exports, "fieldSchema", { enumerable: true, get: function () { return validation_1.fieldSchema; } });
34
- Object.defineProperty(exports, "fieldsSchema", { enumerable: true, get: function () { return validation_1.fieldsSchema; } });
35
- Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validation_1.validate; } });
36
30
  var locales_1 = require("./minified-utils/locales");
37
31
  Object.defineProperty(exports, "DEFAULT_LOCALE", { enumerable: true, get: function () { return locales_1.DEFAULT_LOCALE; } });
38
32
  Object.defineProperty(exports, "i18n", { enumerable: true, get: function () { return locales_1.i18n; } });
@@ -43,5 +37,9 @@ Object.defineProperty(exports, "localizeOutputs", { enumerable: true, get: funct
43
37
  Object.defineProperty(exports, "localizeProperties", { enumerable: true, get: function () { return locales_1.localizeProperties; } });
44
38
  var properties_1 = require("./minified-utils/properties");
45
39
  Object.defineProperty(exports, "Properties", { enumerable: true, get: function () { return properties_1.Properties; } });
46
- var protocol_1 = require("./minified-utils/protocol");
47
- Object.defineProperty(exports, "Protocol", { enumerable: true, get: function () { return protocol_1.Protocol; } });
40
+ var validation_1 = require("./minified-utils/validation");
41
+ Object.defineProperty(exports, "alter", { enumerable: true, get: function () { return validation_1.alter; } });
42
+ Object.defineProperty(exports, "extract", { enumerable: true, get: function () { return validation_1.extract; } });
43
+ Object.defineProperty(exports, "fieldSchema", { enumerable: true, get: function () { return validation_1.fieldSchema; } });
44
+ Object.defineProperty(exports, "fieldsSchema", { enumerable: true, get: function () { return validation_1.fieldsSchema; } });
45
+ Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validation_1.validate; } });
@@ -47,7 +47,7 @@ class Context {
47
47
  let serialized = false;
48
48
  let unresolved;
49
49
  const dynamicSource = field.type === `dict` && field.items && (0, exports.isDynamic)(source, false);
50
- if (((lodash_1.default.isObject(source) || lodash_1.default.isArray(source)) && field.type === `dict` && !field.items) || dynamicSource) {
50
+ if (((lodash_1.default.isObject(source) || lodash_1.default.isArray(source)) && ((field.type === `dict` && !field.items) || (field.type === `file`))) || dynamicSource) {
51
51
  serialized = true;
52
52
  unresolved = JSON.stringify(source);
53
53
  }
@@ -112,7 +112,9 @@ class Context {
112
112
  }
113
113
  const prop = lodash_1.default.get(i, map.value);
114
114
  if (typeof prop !== `undefined`) {
115
- if (shouldInfer(child, prop)) {
115
+ if (prop === null) {
116
+ }
117
+ else if (shouldInfer(child, prop)) {
116
118
  item[key] = prop;
117
119
  }
118
120
  else {
@@ -1,5 +1,6 @@
1
1
  import Joi from "joi";
2
2
  import { Field } from "./fields";
3
+ import { StorageFunctions } from "../core";
3
4
  type ValidationExtended = {
4
5
  original: any;
5
6
  value: any;
@@ -15,16 +16,18 @@ type ValidationExtended = {
15
16
  });
16
17
  export declare const fieldSchema: () => Joi.ObjectSchema<any>;
17
18
  export declare const fieldsSchema: () => Joi.ArraySchema<any[]>;
19
+ export type ValidationOptions = {
20
+ files: StorageFunctions;
21
+ secure?: boolean;
22
+ break?: boolean;
23
+ context?: Record<string, any>;
24
+ };
18
25
  export type ValidationResult<Extended = Record<string, never>> = {
19
26
  valid: boolean;
20
27
  fields: Field<Extended & ValidationExtended>[];
21
28
  };
22
29
  export declare const alter: (field: Field, relative: string, data: Record<string, any>) => Field;
23
- export declare const validate: <I>(fields: Field<I>[], data: Record<string, any>, options?: {
24
- secure?: boolean;
25
- break?: boolean;
26
- context?: Record<string, any>;
27
- }) => Promise<ValidationResult<I>>;
30
+ export declare const validate: <I>(fields: Field<I>[], data: Record<string, any>, options: ValidationOptions) => Promise<ValidationResult<I>>;
28
31
  export declare const extract: (validation: Field<ValidationExtended>[], options?: {
29
32
  original?: boolean;
30
33
  }) => Promise<Record<string, any>>;
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.extract = exports.validate = exports.alter = exports.fieldsSchema = exports.fieldSchema = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
7
8
  const joi_1 = __importDefault(require("joi"));
8
9
  const lodash_1 = __importDefault(require("lodash"));
9
10
  const moment_timezone_1 = __importDefault(require("moment-timezone"));
@@ -165,31 +166,6 @@ const fileSchema = () => joi_1.default.object({
165
166
  type: joi_1.default.string().required(),
166
167
  content: joi_1.default.string().required(),
167
168
  });
168
- const fileReplacer = (field) => ({
169
- key: field.key,
170
- type: `dict`,
171
- unknown: true,
172
- items: [
173
- {
174
- key: `name`,
175
- type: `string`,
176
- required: true,
177
- },
178
- {
179
- key: `type`,
180
- type: `string`,
181
- required: true,
182
- },
183
- {
184
- key: `content`,
185
- type: `string`,
186
- required: true,
187
- },
188
- ],
189
- default: field.default,
190
- ...lodash_1.default.pick(field, [`altered_by`, `disabled`, `required`, `as_password`, `show`, `as_array`, `array_min`, `array_max`, `array_length`]),
191
- ...Object.assign({}, ...Object.entries(field).map(([k, v]) => k.startsWith(`experimental_`) ? { [k]: v } : {})),
192
- });
193
169
  const fileInputFieldSchema = () => joi_1.default.object({
194
170
  default: defaultSchema(fileSchema()),
195
171
  accept: joi_1.default.alternatives(joi_1.default.string(), joi_1.default.array().items(joi_1.default.string())).optional(),
@@ -242,7 +218,7 @@ const fieldSchema = () => inputFieldBaseSchema()
242
218
  exports.fieldSchema = fieldSchema;
243
219
  const fieldsSchema = () => joi_1.default.array().items((0, exports.fieldSchema)());
244
220
  exports.fieldsSchema = fieldsSchema;
245
- const getSimpleFieldSchema = (field) => {
221
+ const getSimpleFieldSchema = (field, configuration) => {
246
222
  if (field.as_array) {
247
223
  throw new Error(`Cannot use as_array with simple field schema generator`);
248
224
  }
@@ -334,7 +310,26 @@ const getSimpleFieldSchema = (field) => {
334
310
  typeSchema = joi_1.default.object().unknown(true);
335
311
  break;
336
312
  case `file`:
337
- typeSchema = fileSchema();
313
+ typeSchema = fileSchema()
314
+ .external(async (value) => {
315
+ if (value.content.startsWith(`http://`) || value.content.startsWith(`https://`)) {
316
+ try {
317
+ const { data: content } = await axios_1.default.get(value.content, { responseType: `arraybuffer` });
318
+ value.content = Buffer.from(content).toString(`base64`);
319
+ }
320
+ catch (e) {
321
+ console.log(e);
322
+ throw new Error(`Could not fetch file from URL`);
323
+ }
324
+ }
325
+ else if (value.content.startsWith(`id:`)) {
326
+ const id = value.content.replace(`id:`, ``);
327
+ value.content = await configuration.files.read(id);
328
+ }
329
+ else {
330
+ }
331
+ return value;
332
+ });
338
333
  break;
339
334
  }
340
335
  if (`format` in field && field.format === `select`) {
@@ -447,9 +442,6 @@ const recursive_schema = async (field, data, options) => {
447
442
  }
448
443
  }
449
444
  const alteredField = lodash_1.default.cloneDeep(newField);
450
- if (newField.type === `file`) {
451
- newField = fileReplacer(newField);
452
- }
453
445
  const relativeKey = options.relative ?
454
446
  options.relative.endsWith(`]`) ?
455
447
  options.array ? options.relative : `${options.relative}.${newField.key}`
@@ -475,7 +467,7 @@ const recursive_schema = async (field, data, options) => {
475
467
  const itemSchemas = [];
476
468
  if (lodash_1.default.isArray(resolved)) {
477
469
  for (let i = 0; i < (resolved || []).length; i++) {
478
- const { schema: itemSchema } = await recursive_schema(noArrayField, data, { alter: false, relative: `${relativeKey}[${i}]`, array: true, context: options.context });
470
+ const { schema: itemSchema } = await recursive_schema(noArrayField, data, { files: options.files, alter: false, relative: `${relativeKey}[${i}]`, array: true, context: options.context });
479
471
  if (itemSchema) {
480
472
  itemSchemas.push(itemSchema);
481
473
  }
@@ -490,7 +482,7 @@ const recursive_schema = async (field, data, options) => {
490
482
  if (noArrayField.type === `dict` && noArrayField.items) {
491
483
  const items = [];
492
484
  for (const item of noArrayField.items) {
493
- const recursive = await recursive_schema(item, data, { alter: options.alter && true, relative: `${relativeKey}[0]`, context: options.context, no_undefined: true });
485
+ const recursive = await recursive_schema(item, data, { files: options.files, alter: options.alter && true, relative: `${relativeKey}[0]`, context: options.context, no_undefined: true });
494
486
  if (recursive) {
495
487
  items.push({ key: item.key, schema: recursive.schema, field: recursive.field });
496
488
  }
@@ -499,7 +491,7 @@ const recursive_schema = async (field, data, options) => {
499
491
  noArrayField.items = items.map((i) => i.field);
500
492
  }
501
493
  else {
502
- genericItemSchema = getSimpleFieldSchema(noArrayField);
494
+ genericItemSchema = getSimpleFieldSchema(noArrayField, { files: options.files });
503
495
  }
504
496
  calculatedSchema = getItemsArrayFieldSchema(newField, [genericItemSchema]);
505
497
  }
@@ -508,7 +500,7 @@ const recursive_schema = async (field, data, options) => {
508
500
  if (resolved || newField.required) {
509
501
  const items = [];
510
502
  for (const item of newField.items) {
511
- const recursive = await recursive_schema(item, data, { alter: options.alter && true, relative: relativeKey, context: options.context });
503
+ const recursive = await recursive_schema(item, data, { files: options.files, alter: options.alter && true, relative: relativeKey, context: options.context });
512
504
  if (recursive) {
513
505
  items.push({ key: item.key, schema: recursive.schema, field: recursive.field });
514
506
  }
@@ -518,11 +510,11 @@ const recursive_schema = async (field, data, options) => {
518
510
  }
519
511
  else {
520
512
  delete newField.items;
521
- calculatedSchema = getSimpleFieldSchema(newField);
513
+ calculatedSchema = getSimpleFieldSchema(newField, { files: options.files });
522
514
  }
523
515
  }
524
516
  else {
525
- calculatedSchema = getSimpleFieldSchema(newField);
517
+ calculatedSchema = getSimpleFieldSchema(newField, { files: options.files });
526
518
  }
527
519
  if (!calculatedSchema) {
528
520
  throw new Error(`Could not resolve schema for field ${newField.key}`);
@@ -542,7 +534,7 @@ const validate_internal = async (fields, data, options) => {
542
534
  for (const field of fields) {
543
535
  const value = lodash_1.default.get(data, field.key, field.default);
544
536
  const cloned = lodash_1.default.cloneDeep(data);
545
- const recursive = await recursive_schema(field, cloned, { alter: true, context: options.context });
537
+ const recursive = await recursive_schema(field, cloned, { files: options.files, alter: true, context: options.context });
546
538
  if (!recursive) {
547
539
  continue;
548
540
  }
@@ -594,7 +586,7 @@ const validate_internal = async (fields, data, options) => {
594
586
  throw e;
595
587
  }
596
588
  };
597
- const validate = async (fields, data, options = {}) => {
589
+ const validate = async (fields, data, options) => {
598
590
  try {
599
591
  const { error } = (0, exports.fieldsSchema)().validate(fields);
600
592
  if (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beseif-solutions/prow-core",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "Prow core functionalities and classes",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/core.ts CHANGED
@@ -4,6 +4,7 @@ import lodash from "lodash";
4
4
  import moment from "moment-timezone";
5
5
  import { FromCatalog, FromDirectory, i18n, T } from "./minified-utils/locales";
6
6
  import { SourceConfig } from "./entities/source";
7
+ import { File } from "./minified-utils/fields";
7
8
 
8
9
  export type SourceFunctions = {
9
10
  register: <SC extends SourceConfig = SourceConfig>(source: SC[`id`], sandbox: boolean, data: SC[`fields`]) => Promise<{ id: string }>,
@@ -11,6 +12,11 @@ export type SourceFunctions = {
11
12
  unregister: <SC extends SourceConfig = SourceConfig>(source: SC[`id`], sandbox: boolean, id: string) => Promise<void>,
12
13
  };
13
14
 
15
+ export type StorageFunctions = {
16
+ read: (id: string) => Promise<string>,
17
+ store: (file: File) => Promise<File>,
18
+ };
19
+
14
20
  const FALLBACK_SOURCES: SourceFunctions = {
15
21
  register: async () => {
16
22
  throw new Error(`Sources not available: valid implementation not provided`);
@@ -31,12 +37,14 @@ export type Core = {
31
37
  joi: Joi.Root,
32
38
  sources?: SourceFunctions,
33
39
  t: T,
40
+ files: StorageFunctions,
34
41
  };
35
42
 
36
43
  type CoreOptions = {
44
+ localization: FromDirectory | FromCatalog,
45
+ files: StorageFunctions,
37
46
  env?: Record<string, any>,
38
47
  sources?: SourceFunctions,
39
- localization: FromDirectory | FromCatalog,
40
48
  };
41
49
 
42
50
  /* eslint-disable @typescript-eslint/unbound-method */
@@ -51,4 +59,5 @@ export const core = async (options: CoreOptions): Promise<Core> => ({
51
59
  joi: Joi,
52
60
  sources: options.sources || FALLBACK_SOURCES,
53
61
  t: i18n(options.localization).t,
62
+ files: options.files,
54
63
  });
package/src/index.ts CHANGED
@@ -1,12 +1,11 @@
1
- export { Core, core } from './core';
1
+ export { Core, core, SourceFunctions, StorageFunctions } from './core';
2
2
  export { CoreFunction, idSchema } from './entities/commons';
3
3
  export { Credentials, credentialsSchema, OAuthCredentials, oauthCredentialsSchema, SessionCredentials, sessionCredentialsSchema, StaticCredentials, staticCredentialsSchema } from './entities/credentials';
4
4
  export { Action, actionOutputSchema, actionSchema, AsyncAction, Event, eventSchema, ImmediateTrigger, immediateTriggerSchema, Request, ScheduledTrigger, scheduledTriggerSchema, SyncAction, syncActionSchema, Trigger, triggerOutputSchema, triggerSchema } from './entities/events';
5
5
  export { Provider, providerSchema } from './entities/provider';
6
6
  export { Source } from './entities/source';
7
7
  export { getPath, hasExpression, isDynamic, isExpression, split } from './minified-utils/context';
8
- export { alter, extract, fieldSchema, fieldsSchema, validate, ValidationResult } from './minified-utils/validation';
9
8
  export { Condition, Field, File, SelectFieldChoice } from './minified-utils/fields';
10
9
  export { DEFAULT_LOCALE, i18n, LocalizedField, LocalizedProperties, localizeFields, localizeGroup, localizeInputs, localizeOutputs, localizeProperties } from './minified-utils/locales';
11
10
  export { Properties } from './minified-utils/properties';
12
- export { Protocol } from './minified-utils/protocol';
11
+ export { alter, extract, fieldSchema, fieldsSchema, validate, ValidationOptions, ValidationResult } from './minified-utils/validation';
@@ -60,7 +60,7 @@ class Context {
60
60
 
61
61
  const dynamicSource = field.type === `dict` && field.items && isDynamic(source, false);
62
62
 
63
- if (((_.isObject(source) || _.isArray(source)) && field.type === `dict` && !field.items) || dynamicSource) {
63
+ if (((_.isObject(source) || _.isArray(source)) && ((field.type === `dict` && !field.items) || (field.type === `file`))) || dynamicSource) {
64
64
  serialized = true;
65
65
  unresolved = JSON.stringify(source);
66
66
  } else if (typeof source === `string`) {
@@ -125,7 +125,9 @@ class Context {
125
125
 
126
126
  const prop = _.get(i, map.value);
127
127
  if (typeof prop !== `undefined`) {
128
- if (shouldInfer(child, prop)) {
128
+ if (prop === null) {
129
+ // treat as empty value
130
+ } else if (shouldInfer(child, prop)) {
129
131
  item[key] = prop;
130
132
  } else {
131
133
  item[key] = _.toString(prop);
@@ -1,9 +1,11 @@
1
+ import axios from "axios";
1
2
  import Joi, { DateSchema, NumberSchema, StringSchema } from "joi";
2
3
  import _ from "lodash";
3
4
  import moment from "moment-timezone";
4
5
  import context from "./context";
6
+ import { Field, File, SelectFieldChoice } from "./fields";
5
7
  import { where, Where } from "./where";
6
- import { CommonField, Field, FileInputField, SelectFieldChoice } from "./fields";
8
+ import { StorageFunctions } from "../core";
7
9
 
8
10
  type ValidationExtended = {
9
11
  original: any,
@@ -218,32 +220,32 @@ const fileSchema = () => Joi.object({
218
220
  content: Joi.string().required(), // base64 encoded content
219
221
  });
220
222
 
221
- // ÑAPA: translate file to structured dict
222
- const fileReplacer = (field: CommonField & FileInputField): Field => ({
223
- key: field.key,
224
- type: `dict`,
225
- unknown: true,
226
- items: [
227
- {
228
- key: `name`,
229
- type: `string`,
230
- required: true,
231
- },
232
- {
233
- key: `type`,
234
- type: `string`,
235
- required: true,
236
- },
237
- {
238
- key: `content`,
239
- type: `string`,
240
- required: true,
241
- },
242
- ],
243
- default: field.default,
244
- ..._.pick(field, [`altered_by`, `disabled`, `required`, `as_password`, `show`, `as_array`, `array_min`, `array_max`, `array_length`]),
245
- ...Object.assign({}, ...Object.entries(field).map(([k, v]) => k.startsWith(`experimental_`) ? { [k]: v } : {})),
246
- }) as Field;
223
+ // // ÑAPA: translate file to structured dict
224
+ // const fileReplacer = (field: CommonField & FileInputField): Field => ({
225
+ // key: field.key,
226
+ // type: `dict`,
227
+ // unknown: true,
228
+ // items: [
229
+ // {
230
+ // key: `name`,
231
+ // type: `string`,
232
+ // required: true,
233
+ // },
234
+ // {
235
+ // key: `type`,
236
+ // type: `string`,
237
+ // required: true,
238
+ // },
239
+ // {
240
+ // key: `content`,
241
+ // type: `string`,
242
+ // required: true,
243
+ // },
244
+ // ],
245
+ // default: field.default,
246
+ // ..._.pick(field, [`altered_by`, `disabled`, `required`, `as_password`, `show`, `as_array`, `array_min`, `array_max`, `array_length`]),
247
+ // ...Object.assign({}, ...Object.entries(field).map(([k, v]) => k.startsWith(`experimental_`) ? { [k]: v } : {})),
248
+ // }) as Field;
247
249
 
248
250
  const fileInputFieldSchema = () =>
249
251
  Joi.object({
@@ -307,7 +309,7 @@ export const fieldSchema = () =>
307
309
  export const fieldsSchema = () =>
308
310
  Joi.array().items(fieldSchema());
309
311
 
310
- const getSimpleFieldSchema = (field: Field) => {
312
+ const getSimpleFieldSchema = (field: Field, configuration: { files: StorageFunctions }) => {
311
313
  if (field.as_array) { throw new Error(`Cannot use as_array with simple field schema generator`); }
312
314
 
313
315
  let typeSchema: Joi.Schema;
@@ -378,7 +380,28 @@ const getSimpleFieldSchema = (field: Field) => {
378
380
  typeSchema = Joi.object().unknown(true);
379
381
  break;
380
382
  case `file`:
381
- typeSchema = fileSchema();
383
+ typeSchema = fileSchema()
384
+ .external(async (value: File) => {
385
+ if (value.content.startsWith(`http://`) || value.content.startsWith(`https://`)) {
386
+ try {
387
+ // get content from public URL
388
+ const { data: content } = await axios.get(value.content, { responseType: `arraybuffer` });
389
+ // content to base64
390
+ value.content = Buffer.from(content).toString(`base64`);
391
+ } catch (e) {
392
+ console.log(e);
393
+ throw new Error(`Could not fetch file from URL`);
394
+ }
395
+ } else if (value.content.startsWith(`id:`)) {
396
+ const id = value.content.replace(`id:`, ``);
397
+ // get content from internal storage
398
+ value.content = await configuration.files.read(id);
399
+ } else {
400
+ // content as base64
401
+ }
402
+
403
+ return value;
404
+ });
382
405
  break;
383
406
  }
384
407
 
@@ -447,6 +470,13 @@ const convertPath = (parts: (string | number)[]): string =>
447
470
  const secure = async (field: Field, validation: ValidationExtended): Promise<ValidationExtended> =>
448
471
  field.as_password ? _.omit(validation, [`value`, `original`]) as any : validation;
449
472
 
473
+ export type ValidationOptions = {
474
+ files: StorageFunctions,
475
+ secure?: boolean,
476
+ break?: boolean,
477
+ context?: Record<string, any>,
478
+ };
479
+
450
480
  export type ValidationResult<Extended = Record<string, never>> = {
451
481
  valid: boolean,
452
482
  fields: Field<Extended & ValidationExtended>[],
@@ -478,7 +508,7 @@ export const alter = (field: Field, relative: string, data: Record<string, any>)
478
508
  return cloned;
479
509
  };
480
510
 
481
- const recursive_schema = async (field: Field, data: Record<string, any>, options: { alter: boolean, context: Record<string, any>, relative?: string, array?: boolean, no_undefined?: boolean }): Promise<{ schema: Joi.Schema, field: Field }> => {
511
+ const recursive_schema = async (field: Field, data: Record<string, any>, options: { files: StorageFunctions, alter: boolean, context: Record<string, any>, relative?: string, array?: boolean, no_undefined?: boolean }): Promise<{ schema: Joi.Schema, field: Field }> => {
482
512
  try {
483
513
  let newField: Field = _.cloneDeep(field);
484
514
 
@@ -495,7 +525,7 @@ const recursive_schema = async (field: Field, data: Record<string, any>, options
495
525
  const alteredField: Field = _.cloneDeep(newField);
496
526
 
497
527
  // ÑAPA: if the field is a file, replace it
498
- if (newField.type === `file`) { newField = fileReplacer(newField); }
528
+ // if (newField.type === `file`) { newField = fileReplacer(newField); }
499
529
 
500
530
  const relativeKey = options.relative ?
501
531
  options.relative.endsWith(`]`) ?
@@ -528,7 +558,7 @@ const recursive_schema = async (field: Field, data: Record<string, any>, options
528
558
  const itemSchemas: Joi.Schema[] = [];
529
559
  if (_.isArray(resolved)) {
530
560
  for (let i = 0; i < (resolved || []).length; i++) {
531
- const { schema: itemSchema } = await recursive_schema(noArrayField, data, { alter: false, relative: `${relativeKey}[${i}]`, array: true, context: options.context });
561
+ const { schema: itemSchema } = await recursive_schema(noArrayField, data, { files: options.files, alter: false, relative: `${relativeKey}[${i}]`, array: true, context: options.context });
532
562
  if (itemSchema) { itemSchemas.push(itemSchema); }
533
563
  }
534
564
 
@@ -544,14 +574,14 @@ const recursive_schema = async (field: Field, data: Record<string, any>, options
544
574
  const items: { key: string, schema: Joi.Schema, field: Field }[] = [];
545
575
 
546
576
  for (const item of noArrayField.items) {
547
- const recursive = await recursive_schema(item, data, { alter: options.alter && true, relative: `${relativeKey}[0]`, context: options.context, no_undefined: true });
577
+ const recursive = await recursive_schema(item, data, { files: options.files, alter: options.alter && true, relative: `${relativeKey}[0]`, context: options.context, no_undefined: true });
548
578
  if (recursive) { items.push({ key: item.key, schema: recursive.schema, field: recursive.field }); }
549
579
  }
550
580
 
551
581
  genericItemSchema = getObjectFieldSchema(noArrayField, items);
552
582
  noArrayField.items = items.map((i) => i.field);
553
583
  } else {
554
- genericItemSchema = getSimpleFieldSchema(noArrayField);
584
+ genericItemSchema = getSimpleFieldSchema(noArrayField, { files: options.files });
555
585
  }
556
586
 
557
587
  calculatedSchema = getItemsArrayFieldSchema(newField, [genericItemSchema]);
@@ -561,7 +591,7 @@ const recursive_schema = async (field: Field, data: Record<string, any>, options
561
591
  const items: { key: string, schema: Joi.Schema, field: Field }[] = [];
562
592
 
563
593
  for (const item of newField.items) {
564
- const recursive = await recursive_schema(item, data, { alter: options.alter && true, relative: relativeKey, context: options.context });
594
+ const recursive = await recursive_schema(item, data, { files: options.files, alter: options.alter && true, relative: relativeKey, context: options.context });
565
595
  if (recursive) { items.push({ key: item.key, schema: recursive.schema, field: recursive.field }); }
566
596
  }
567
597
 
@@ -569,10 +599,10 @@ const recursive_schema = async (field: Field, data: Record<string, any>, options
569
599
  newField.items = items.map((i) => i.field);
570
600
  } else {
571
601
  delete newField.items;
572
- calculatedSchema = getSimpleFieldSchema(newField);
602
+ calculatedSchema = getSimpleFieldSchema(newField, { files: options.files });
573
603
  }
574
604
  } else {
575
- calculatedSchema = getSimpleFieldSchema(newField);
605
+ calculatedSchema = getSimpleFieldSchema(newField, { files: options.files });
576
606
  }
577
607
 
578
608
  if (!calculatedSchema) { throw new Error(`Could not resolve schema for field ${newField.key}`); }
@@ -584,7 +614,7 @@ const recursive_schema = async (field: Field, data: Record<string, any>, options
584
614
  } catch (e) { throw e; }
585
615
  };
586
616
 
587
- const validate_internal = async (fields: Field[], data: Record<string, any>, options: { secure: boolean, break: boolean, context: Record<string, any> }): Promise<ValidationResult> => {
617
+ const validate_internal = async (fields: Field[], data: Record<string, any>, options: { files: StorageFunctions, secure: boolean, break: boolean, context: Record<string, any> }): Promise<ValidationResult> => {
588
618
  try {
589
619
  const response: ValidationResult<{}> = { valid: true, fields: [] };
590
620
 
@@ -594,7 +624,7 @@ const validate_internal = async (fields: Field[], data: Record<string, any>, opt
594
624
 
595
625
  const cloned = _.cloneDeep(data);
596
626
 
597
- const recursive = await recursive_schema(field, cloned, { alter: true, context: options.context });
627
+ const recursive = await recursive_schema(field, cloned, { files: options.files, alter: true, context: options.context });
598
628
  if (!recursive) { continue; }
599
629
 
600
630
  const resolved = _.get(cloned, field.key, field.default);
@@ -644,7 +674,7 @@ const validate_internal = async (fields: Field[], data: Record<string, any>, opt
644
674
  } catch (e) { throw e; }
645
675
  };
646
676
 
647
- export const validate = async <I>(fields: Field<I>[], data: Record<string, any>, options: { secure?: boolean, break?: boolean, context?: Record<string, any> } = {}): Promise<ValidationResult<I>> => {
677
+ export const validate = async <I>(fields: Field<I>[], data: Record<string, any>, options: ValidationOptions): Promise<ValidationResult<I>> => {
648
678
  try {
649
679
  const { error } = fieldsSchema().validate(fields);
650
680
  if (error) { throw new Error(`Invalid fields definition: ${error.message}`); }
@@ -1,52 +0,0 @@
1
- import { Provider } from "../entities/provider";
2
- export declare class Protocol {
3
- private readonly provider;
4
- private readonly configuration;
5
- constructor(provider: Provider, configuration: Protocol.Configuration);
6
- evaluate: (req: Protocol.Command) => Promise<any>;
7
- }
8
- export declare namespace Protocol {
9
- type Model = `action` | `trigger` | `credential`;
10
- type Invoke = {
11
- command: `invoke`;
12
- model: Protocol.Model;
13
- id: string;
14
- params: {
15
- function: string;
16
- configuration: Record<string, any>;
17
- };
18
- context: {
19
- organization: string;
20
- workspace: number;
21
- environment: Record<string, any>;
22
- localization: {
23
- locale: string;
24
- catalog: Record<string, any>;
25
- };
26
- };
27
- };
28
- type CredentialList = {
29
- command: `list:credentials`;
30
- };
31
- type ActionList = {
32
- command: `list:actions`;
33
- };
34
- type TriggerList = {
35
- command: `list:triggers`;
36
- };
37
- type SourceList = {
38
- command: `list:sources`;
39
- };
40
- type LocaleList = {
41
- command: `list:locales`;
42
- };
43
- type Command = Invoke | CredentialList | ActionList | TriggerList | SourceList | LocaleList;
44
- type SourcesConfiguration = {
45
- host: string;
46
- token: string;
47
- };
48
- type Configuration = {
49
- path: string;
50
- sources: SourcesConfiguration;
51
- };
52
- }
@@ -1,187 +0,0 @@
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
- exports.Protocol = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- const joi_1 = __importDefault(require("joi"));
9
- const lodash_1 = __importDefault(require("lodash"));
10
- const core_1 = require("../core");
11
- const provider_1 = require("../entities/provider");
12
- const locales_1 = require("./locales");
13
- const invokeSchema = joi_1.default.object({
14
- command: joi_1.default.string().valid(`invoke`).required(),
15
- model: joi_1.default.string().valid(`action`, `trigger`, `credential`).required(),
16
- id: joi_1.default.string().required(),
17
- params: joi_1.default.object({
18
- function: joi_1.default.string().required(),
19
- configuration: joi_1.default.object().required(),
20
- }).required(),
21
- context: joi_1.default.object({
22
- organization: joi_1.default.string().required(),
23
- workspace: joi_1.default.number().required(),
24
- environment: joi_1.default.object().required(),
25
- localization: joi_1.default.object({
26
- locale: joi_1.default.string().required(),
27
- catalog: joi_1.default.object().required(),
28
- }).required(),
29
- }).required(),
30
- }).required();
31
- const credentialListSchema = joi_1.default.object({
32
- command: joi_1.default.string().valid(`list:credentials`).required(),
33
- }).required();
34
- const actionListSchema = joi_1.default.object({
35
- command: joi_1.default.string().valid(`list:actions`).required(),
36
- }).required();
37
- const triggerListSchema = joi_1.default.object({
38
- command: joi_1.default.string().valid(`list:triggers`).required(),
39
- }).required();
40
- const sourceListSchema = joi_1.default.object({
41
- command: joi_1.default.string().valid(`list:sources`).required(),
42
- }).required();
43
- const localeListSchema = joi_1.default.object({
44
- command: joi_1.default.string().valid(`list:locales`).required(),
45
- }).required();
46
- const commandSchema = joi_1.default.alternatives(invokeSchema, credentialListSchema, actionListSchema, triggerListSchema, sourceListSchema, localeListSchema);
47
- const API_SOURCES = (provider, configuration, context) => {
48
- const REQ_CONFIG = {
49
- baseURL: configuration.host,
50
- headers: {
51
- "x-prow-provider": provider.id,
52
- "x-prow-version": provider.version,
53
- "x-prow-token": configuration.token,
54
- "x-prow-organization": context.organization,
55
- "x-active-workspace": `${context.workspace}`,
56
- },
57
- };
58
- return {
59
- register: async (source, sandbox, data) => {
60
- try {
61
- const { data: [created] } = await axios_1.default.post(`/feu/v1/sources`, {
62
- provider: provider.id,
63
- version: provider.version,
64
- source: source,
65
- sandbox: sandbox,
66
- data: data,
67
- }, REQ_CONFIG);
68
- if (!created || !created.uuid) {
69
- throw new Error(`Source registration failed`);
70
- }
71
- return { id: created.uuid };
72
- }
73
- catch (e) {
74
- throw e;
75
- }
76
- },
77
- unregister: async (source, sandbox, id) => {
78
- try {
79
- const { data: [get] } = await axios_1.default.post(`/feu/v1/sources/list`, {
80
- provider: provider.id,
81
- version: provider.version,
82
- source: source,
83
- sandbox: sandbox,
84
- uuid: id,
85
- }, REQ_CONFIG);
86
- if (!get) {
87
- throw new Error(`Source with ID ${id} not found`);
88
- }
89
- await axios_1.default.delete(`/feu/v1/sources/${get.id}`, REQ_CONFIG);
90
- }
91
- catch (e) {
92
- throw e;
93
- }
94
- },
95
- consume: async (source, sandbox) => {
96
- try {
97
- const { data: sources } = await axios_1.default.post(`/feu/v1/sources/list`, {
98
- provider: provider.id,
99
- version: provider.version,
100
- source: source,
101
- sandbox: sandbox,
102
- }, REQ_CONFIG);
103
- return sources.map((s) => ({
104
- id: s.uuid,
105
- data: s.data,
106
- }));
107
- }
108
- catch (e) {
109
- throw e;
110
- }
111
- },
112
- };
113
- };
114
- class Protocol {
115
- constructor(provider, configuration) {
116
- this.evaluate = async (req) => {
117
- try {
118
- const validation = commandSchema.validate(req);
119
- if (validation.error) {
120
- throw new Error(`Invalid request: ${validation.error.message}`);
121
- }
122
- const serialize = (elem) => ({
123
- ...lodash_1.default.omit(elem, [`functions`, `helpers`]),
124
- functions: Object.keys(elem.functions),
125
- helpers: Object.keys(elem.helpers),
126
- });
127
- let response;
128
- switch (req.command) {
129
- case `list:actions`:
130
- response = Object.values(this.provider.actions || {}).map(serialize);
131
- break;
132
- case `list:triggers`:
133
- response = Object.values(this.provider.triggers || {}).map(serialize);
134
- break;
135
- case `list:credentials`:
136
- response = Object.values(this.provider.credentials || {}).map(serialize);
137
- break;
138
- case `list:sources`:
139
- response = Object.values(this.provider.sources || {});
140
- break;
141
- case `list:locales`:
142
- const i18nInstance = (0, locales_1.i18n)({ directory: `${this.configuration.path}/locales` });
143
- response = i18nInstance.i18n.getLocales().map((l) => {
144
- i18nInstance.i18n.setLocale(l);
145
- return {
146
- code: l,
147
- catalog: i18nInstance.i18n.getCatalog(),
148
- };
149
- });
150
- break;
151
- case `invoke`:
152
- const elem = lodash_1.default.get(this.provider, `${req.model}s.${req.id}`);
153
- if (!elem) {
154
- throw new Error(`Could not find ${req.model} with ID ${req.id}`);
155
- }
156
- const func = lodash_1.default.get(elem, req.params.function);
157
- if (!func || typeof func !== `function`) {
158
- throw new Error(`Invalid function ${req.params.function}`);
159
- }
160
- const invokeInstance = await (0, core_1.core)({
161
- env: req.context.environment,
162
- localization: req.context.localization,
163
- sources: API_SOURCES(this.provider, this.configuration.sources, {
164
- organization: req.context.organization,
165
- workspace: req.context.workspace,
166
- }),
167
- });
168
- response = await func(invokeInstance, req.params.configuration);
169
- break;
170
- default:
171
- throw new Error(`Invalid command`);
172
- }
173
- return response;
174
- }
175
- catch (e) {
176
- throw e;
177
- }
178
- };
179
- const providerValidation = (0, provider_1.providerSchema)().validate(provider);
180
- if (providerValidation.error) {
181
- throw new Error(`Invalid provider for protocol`);
182
- }
183
- this.provider = provider;
184
- this.configuration = configuration;
185
- }
186
- }
187
- exports.Protocol = Protocol;
@@ -1,244 +0,0 @@
1
- import axios from "axios";
2
- import Joi from "joi";
3
- import _ from "lodash";
4
- import { core, SourceFunctions } from "../core";
5
- import { Credentials } from "../entities/credentials";
6
- import { Action, Trigger } from "../entities/events";
7
- import { Provider, providerSchema } from "../entities/provider";
8
- import { i18n } from "./locales";
9
-
10
- const invokeSchema = Joi.object({
11
- command: Joi.string().valid(`invoke`).required(),
12
- model: Joi.string().valid(`action`, `trigger`, `credential`).required(),
13
- id: Joi.string().required(),
14
- params: Joi.object({
15
- function: Joi.string().required(),
16
- configuration: Joi.object().required(),
17
- }).required(),
18
- context: Joi.object({
19
- organization: Joi.string().required(),
20
- workspace: Joi.number().required(),
21
- environment: Joi.object().required(),
22
- localization: Joi.object({
23
- locale: Joi.string().required(),
24
- catalog: Joi.object().required(),
25
- }).required(),
26
- }).required(),
27
- }).required();
28
-
29
- const credentialListSchema = Joi.object({
30
- command: Joi.string().valid(`list:credentials`).required(),
31
- }).required();
32
-
33
- const actionListSchema = Joi.object({
34
- command: Joi.string().valid(`list:actions`).required(),
35
- }).required();
36
-
37
- const triggerListSchema = Joi.object({
38
- command: Joi.string().valid(`list:triggers`).required(),
39
- }).required();
40
-
41
- const sourceListSchema = Joi.object({
42
- command: Joi.string().valid(`list:sources`).required(),
43
- }).required();
44
-
45
- const localeListSchema = Joi.object({
46
- command: Joi.string().valid(`list:locales`).required(),
47
- }).required();
48
-
49
- const commandSchema = Joi.alternatives(
50
- invokeSchema,
51
- credentialListSchema,
52
- actionListSchema,
53
- triggerListSchema,
54
- sourceListSchema,
55
- localeListSchema,
56
- );
57
-
58
- const API_SOURCES = (provider: Provider, configuration: Protocol.SourcesConfiguration, context: { organization: string, workspace: number }): SourceFunctions => {
59
-
60
- const REQ_CONFIG = {
61
- baseURL: configuration.host,
62
- headers: {
63
- "x-prow-provider": provider.id,
64
- "x-prow-version": provider.version,
65
- "x-prow-token": configuration.token,
66
- "x-prow-organization": context.organization,
67
- "x-active-workspace": `${context.workspace}`,
68
- },
69
- };
70
-
71
- return {
72
- register: async (source, sandbox, data) => {
73
- try {
74
- const { data: [created] } = await axios.post(`/feu/v1/sources`, {
75
- provider: provider.id,
76
- version: provider.version,
77
- source: source,
78
- sandbox: sandbox,
79
- data: data,
80
- }, REQ_CONFIG);
81
- if (!created || !created.uuid) { throw new Error(`Source registration failed`); }
82
- return { id: created.uuid };
83
- } catch (e) { throw e; }
84
- },
85
- unregister: async (source, sandbox, id) => {
86
- try {
87
- const { data: [get] } = await axios.post(`/feu/v1/sources/list`, {
88
- provider: provider.id,
89
- version: provider.version,
90
- source: source,
91
- sandbox: sandbox,
92
- uuid: id,
93
- }, REQ_CONFIG);
94
- if (!get) { throw new Error(`Source with ID ${id} not found`); }
95
-
96
- await axios.delete(`/feu/v1/sources/${get.id}`, REQ_CONFIG);
97
- } catch (e) { throw e; }
98
- },
99
- consume: async (source, sandbox) => {
100
- try {
101
- const { data: sources } = await axios.post(`/feu/v1/sources/list`, {
102
- provider: provider.id,
103
- version: provider.version,
104
- source: source,
105
- sandbox: sandbox,
106
- }, REQ_CONFIG);
107
- return sources.map((s) => ({
108
- id: s.uuid,
109
- data: s.data,
110
- }));
111
- } catch (e) { throw e; }
112
- },
113
- };
114
- };
115
-
116
- export class Protocol {
117
-
118
- private readonly provider: Provider;
119
- private readonly configuration: Protocol.Configuration;
120
-
121
- constructor(provider: Provider, configuration: Protocol.Configuration) {
122
- const providerValidation = providerSchema().validate(provider);
123
- if (providerValidation.error) { throw new Error(`Invalid provider for protocol`); }
124
- this.provider = provider;
125
- this.configuration = configuration;
126
- }
127
-
128
- public evaluate = async (req: Protocol.Command): Promise<any> => {
129
- try {
130
- const validation = commandSchema.validate(req);
131
- if (validation.error) { throw new Error(`Invalid request: ${validation.error.message}`); }
132
-
133
- const serialize = (elem: Action | Trigger | Credentials) => ({
134
- ..._.omit(elem, [`functions`, `helpers`]),
135
- functions: Object.keys(elem.functions),
136
- helpers: Object.keys(elem.helpers),
137
- });
138
-
139
- let response: any;
140
- switch (req.command) {
141
- case `list:actions`:
142
- response = Object.values(this.provider.actions || {}).map(serialize);
143
- break;
144
- case `list:triggers`:
145
- response = Object.values(this.provider.triggers || {}).map(serialize);
146
- break;
147
- case `list:credentials`:
148
- response = Object.values(this.provider.credentials || {}).map(serialize);
149
- break;
150
- case `list:sources`:
151
- response = Object.values(this.provider.sources || {});
152
- break;
153
- case `list:locales`:
154
- const i18nInstance = i18n({ directory: `${this.configuration.path}/locales` });
155
- response = i18nInstance.i18n.getLocales().map((l) => {
156
- i18nInstance.i18n.setLocale(l);
157
- return {
158
- code: l,
159
- catalog: i18nInstance.i18n.getCatalog(),
160
- };
161
- });
162
- break;
163
- case `invoke`:
164
- const elem = _.get(this.provider, `${req.model}s.${req.id}`);
165
- if (!elem) { throw new Error(`Could not find ${req.model} with ID ${req.id}`); }
166
-
167
- const func = _.get(elem, req.params.function);
168
- if (!func || typeof func !== `function`) { throw new Error(`Invalid function ${req.params.function}`); }
169
-
170
- const invokeInstance = await core({
171
- env: req.context.environment,
172
- localization: req.context.localization,
173
- sources: API_SOURCES(this.provider, this.configuration.sources, {
174
- organization: req.context.organization,
175
- workspace: req.context.workspace,
176
- }),
177
- });
178
-
179
- response = await func(invokeInstance, req.params.configuration);
180
- break;
181
- default:
182
- throw new Error(`Invalid command`);
183
- }
184
-
185
- return response;
186
- } catch (e) { throw e; }
187
- };
188
- }
189
-
190
- export namespace Protocol {
191
-
192
- export type Model = `action` | `trigger` | `credential`;
193
-
194
- export type Invoke = {
195
- command: `invoke`,
196
- model: Protocol.Model,
197
- id: string,
198
- params: {
199
- function: string,
200
- configuration: Record<string, any>,
201
- },
202
- context: {
203
- organization: string,
204
- workspace: number,
205
- environment: Record<string, any>,
206
- localization: {
207
- locale: string,
208
- catalog: Record<string, any>,
209
- },
210
- },
211
- };
212
-
213
- export type CredentialList = {
214
- command: `list:credentials`,
215
- };
216
-
217
- export type ActionList = {
218
- command: `list:actions`,
219
- };
220
-
221
- export type TriggerList = {
222
- command: `list:triggers`,
223
- };
224
-
225
- export type SourceList = {
226
- command: `list:sources`,
227
- };
228
-
229
- export type LocaleList = {
230
- command: `list:locales`,
231
- };
232
-
233
- export type Command = Invoke | CredentialList | ActionList | TriggerList | SourceList | LocaleList;
234
-
235
- export type SourcesConfiguration = {
236
- host: string,
237
- token: string,
238
- };
239
-
240
- export type Configuration = {
241
- path: string,
242
- sources: SourcesConfiguration,
243
- };
244
- }