@beseif-solutions/prow-core 0.0.39 → 0.2.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 +3 -3
- package/dist/entities/commons.d.ts +1 -1
- package/dist/entities/events.d.ts +118 -22
- package/dist/entities/events.js +33 -4
- package/dist/entities/source.d.ts +1 -0
- package/dist/entities/source.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/minified-utils/fields.d.ts +11 -10
- package/dist/minified-utils/fields.js +69 -43
- package/dist/minified-utils/protocol.js +6 -3
- package/dist/minified-utils/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/core.ts +3 -3
- package/src/entities/commons.ts +1 -1
- package/src/entities/events.ts +123 -26
- package/src/entities/source.ts +2 -0
- package/src/index.ts +2 -2
- package/src/minified-utils/fields.ts +79 -60
- package/src/minified-utils/protocol.ts +6 -3
- package/src/minified-utils/types.ts +3 -1
- package/tsconfig.json +1 -2
|
@@ -2,15 +2,12 @@ import Joi, { DateSchema, NumberSchema, StringSchema } from "joi";
|
|
|
2
2
|
import _ from "lodash";
|
|
3
3
|
import moment from "moment-timezone";
|
|
4
4
|
import context from "./context";
|
|
5
|
-
import { OneOf } from "./types";
|
|
6
5
|
import { where, Where } from "./where";
|
|
7
6
|
|
|
8
7
|
export type Condition = {
|
|
9
8
|
condition: Where,
|
|
10
|
-
} & OneOf<{
|
|
11
9
|
overrides: Partial<Field>,
|
|
12
|
-
|
|
13
|
-
}>;
|
|
10
|
+
};
|
|
14
11
|
|
|
15
12
|
type Common = {
|
|
16
13
|
key: string,
|
|
@@ -18,6 +15,7 @@ type Common = {
|
|
|
18
15
|
disabled?: boolean,
|
|
19
16
|
required?: boolean,
|
|
20
17
|
as_password?: boolean,
|
|
18
|
+
show?: boolean,
|
|
21
19
|
show_label?: boolean,
|
|
22
20
|
} & ({
|
|
23
21
|
as_array?: false,
|
|
@@ -47,6 +45,7 @@ type Any = string | number | boolean | Any[] | { [key: string]: Any };
|
|
|
47
45
|
type AnyInputField<Extend = Record<never, never>> = {
|
|
48
46
|
type: `any`,
|
|
49
47
|
default?: Any | Any[],
|
|
48
|
+
allow_nullish?: boolean, // allow null values
|
|
50
49
|
} & (
|
|
51
50
|
| SelectField<Any, Extend>
|
|
52
51
|
| {}
|
|
@@ -62,8 +61,8 @@ type StringInputField<Extend = Record<never, never>> = {
|
|
|
62
61
|
pattern?: `email` | `uri`,
|
|
63
62
|
} & (
|
|
64
63
|
| SelectField<string, Extend>
|
|
65
|
-
|
|
|
66
|
-
|
|
|
64
|
+
| CustomDisplayTextField
|
|
65
|
+
| IDETextField
|
|
67
66
|
| {}
|
|
68
67
|
);
|
|
69
68
|
|
|
@@ -74,7 +73,7 @@ type NumberInputField<Extend = Record<never, never>> = {
|
|
|
74
73
|
max?: number,
|
|
75
74
|
} & (
|
|
76
75
|
| { float: true, decimals?: number }
|
|
77
|
-
| { float
|
|
76
|
+
| { float?: false }
|
|
78
77
|
) & (
|
|
79
78
|
| SelectField<number, Extend>
|
|
80
79
|
| {}
|
|
@@ -155,14 +154,14 @@ export type SelectFieldChoice<Values = string | number | boolean | File, Extend
|
|
|
155
154
|
value: Values,
|
|
156
155
|
} & Extend;
|
|
157
156
|
|
|
158
|
-
/*
|
|
159
|
-
type
|
|
160
|
-
format: `textarea`,
|
|
157
|
+
/* custom display configuration */
|
|
158
|
+
type CustomDisplayTextField = {
|
|
159
|
+
format: `textarea` | `rich-text` | `markdown`,
|
|
161
160
|
};
|
|
162
161
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
type IDETextField = {
|
|
163
|
+
format: `code`,
|
|
164
|
+
language?: string, // language for code highlighting
|
|
166
165
|
};
|
|
167
166
|
|
|
168
167
|
type ValidationExtended = {
|
|
@@ -181,10 +180,9 @@ type ValidationExtended = {
|
|
|
181
180
|
|
|
182
181
|
const conditionSchema = () =>
|
|
183
182
|
Joi.object({
|
|
184
|
-
condition: Joi.object(),
|
|
185
|
-
overrides: Joi.object(),
|
|
186
|
-
|
|
187
|
-
}).xor(`overrides`, `show`);
|
|
183
|
+
condition: Joi.object().required(),
|
|
184
|
+
overrides: Joi.object().required(),
|
|
185
|
+
});
|
|
188
186
|
|
|
189
187
|
const commonFieldSchema = () =>
|
|
190
188
|
Joi.object({
|
|
@@ -193,6 +191,7 @@ const commonFieldSchema = () =>
|
|
|
193
191
|
disabled: Joi.bool(),
|
|
194
192
|
required: Joi.bool(),
|
|
195
193
|
as_password: Joi.bool(),
|
|
194
|
+
show: Joi.bool(),
|
|
196
195
|
show_label: Joi.bool().default(true),
|
|
197
196
|
as_array: Joi.bool(),
|
|
198
197
|
array_min: Joi.when(`as_array`, {
|
|
@@ -275,12 +274,17 @@ const stringInputFieldSchema = () =>
|
|
|
275
274
|
})
|
|
276
275
|
.concat(
|
|
277
276
|
Joi.object({
|
|
278
|
-
format: Joi.string().valid(`select`, `textarea`, `rich-text`),
|
|
277
|
+
format: Joi.string().valid(`select`, `textarea`, `rich-text`, `markdown`, `code`),
|
|
279
278
|
choices: Joi.when(`format`, {
|
|
280
279
|
is: `select`,
|
|
281
280
|
then: choicesSchema(Joi.string()).required(),
|
|
282
281
|
otherwise: Joi.forbidden(),
|
|
283
282
|
}),
|
|
283
|
+
language: Joi.when(`format`, {
|
|
284
|
+
is: `code`,
|
|
285
|
+
then: Joi.string(),
|
|
286
|
+
otherwise: Joi.forbidden(),
|
|
287
|
+
}),
|
|
284
288
|
})
|
|
285
289
|
);
|
|
286
290
|
|
|
@@ -385,7 +389,7 @@ const fileReplacer = (field: Common & FileInputField): Field => ({
|
|
|
385
389
|
},
|
|
386
390
|
],
|
|
387
391
|
default: field.default,
|
|
388
|
-
..._.pick(field, [`altered_by`, `disabled`, `required`, `as_password`, `show_label`, `as_array`, `array_min`, `array_max`, `array_length`]),
|
|
392
|
+
..._.pick(field, [`altered_by`, `disabled`, `required`, `as_password`, `show`, `show_label`, `as_array`, `array_min`, `array_max`, `array_length`]),
|
|
389
393
|
}) as Field;
|
|
390
394
|
|
|
391
395
|
const fileInputFieldSchema = () =>
|
|
@@ -457,6 +461,8 @@ const getSimpleFieldSchema = (field: Field) => {
|
|
|
457
461
|
switch (field.type) {
|
|
458
462
|
case `any`:
|
|
459
463
|
typeSchema = anySchema();
|
|
464
|
+
// allow null values for any type
|
|
465
|
+
if (field.allow_nullish) { typeSchema = typeSchema.allow(null, ``, 0, undefined); }
|
|
460
466
|
break;
|
|
461
467
|
case `boolean`:
|
|
462
468
|
typeSchema = Joi.bool();
|
|
@@ -506,11 +512,15 @@ const getSimpleFieldSchema = (field: Field) => {
|
|
|
506
512
|
typeSchema = Joi.number();
|
|
507
513
|
if (field.min) { typeSchema = (typeSchema as NumberSchema).min(field.min); }
|
|
508
514
|
if (field.max) { typeSchema = (typeSchema as NumberSchema).max(field.max); }
|
|
509
|
-
if
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
515
|
+
// don't check precision if float is not set
|
|
516
|
+
if (typeof field.float === `boolean`) {
|
|
517
|
+
if (field.float) {
|
|
518
|
+
typeSchema = (typeSchema as NumberSchema).precision(field.decimals || 2);
|
|
519
|
+
} else {
|
|
520
|
+
typeSchema = (typeSchema as NumberSchema).precision(0);
|
|
521
|
+
}
|
|
513
522
|
}
|
|
523
|
+
|
|
514
524
|
break;
|
|
515
525
|
case `dict`:
|
|
516
526
|
if (field.items) { throw new Error(`No simple field`); }
|
|
@@ -563,8 +573,9 @@ const getObjectFieldSchema = (field: Field, items: { key: string, schema: Joi.Sc
|
|
|
563
573
|
};
|
|
564
574
|
|
|
565
575
|
const getGeneralSchema = (field: Field, schema: Joi.Schema): Joi.Schema => {
|
|
576
|
+
if (field.required) { schema = schema.required(); }
|
|
566
577
|
if (field.disabled) { schema = schema.forbidden(); }
|
|
567
|
-
return
|
|
578
|
+
return schema;
|
|
568
579
|
};
|
|
569
580
|
|
|
570
581
|
const convertPath = (parts: (string | number)[]): string =>
|
|
@@ -593,10 +604,33 @@ const relative_condition = (condition: Where, relative: string): typeof conditio
|
|
|
593
604
|
} catch (e) { throw e; }
|
|
594
605
|
};
|
|
595
606
|
|
|
596
|
-
const
|
|
607
|
+
export const alter = (field: Field, relative: string, data: Record<string, any>) => {
|
|
608
|
+
const cloned = _.cloneDeep(field);
|
|
609
|
+
for (const alteration of cloned.altered_by) {
|
|
610
|
+
const condition = relative_condition(alteration.condition, relative);
|
|
611
|
+
|
|
612
|
+
const matches = where(data, [condition]);
|
|
613
|
+
if (matches) { _.assign(cloned, alteration.overrides); }
|
|
614
|
+
}
|
|
615
|
+
return cloned;
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const recursive_schema = async (field: Field, data: Record<string, any>, options: { alter: boolean, relative?: string, array?: boolean, context: Record<string, any> }): Promise<{ schema: Joi.Schema, field: Field }> => {
|
|
597
619
|
try {
|
|
620
|
+
let newField: Field = _.cloneDeep(field);
|
|
621
|
+
|
|
622
|
+
// alterations over already resolved data (previous fields)
|
|
623
|
+
if (newField.altered_by?.length > 0) {
|
|
624
|
+
newField = alter(newField, options.relative, data);
|
|
625
|
+
|
|
626
|
+
// remove altered_by only if it's not an array -> array alterations must be kept for front-end rendering
|
|
627
|
+
if (options.alter) { delete newField.altered_by; }
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const alteredField: Field = _.cloneDeep(newField);
|
|
631
|
+
|
|
598
632
|
// ÑAPA: if the field is a file, replace it
|
|
599
|
-
|
|
633
|
+
if (newField.type === `file`) { newField = fileReplacer(newField); }
|
|
600
634
|
|
|
601
635
|
const relativeKey = options.relative ?
|
|
602
636
|
options.relative.endsWith(`]`) ?
|
|
@@ -613,61 +647,45 @@ const recursive_schema = async (field: Field, data: Record<string, any>, options
|
|
|
613
647
|
// get schema for field with data
|
|
614
648
|
let calculatedSchema: Joi.Schema;
|
|
615
649
|
if (newField.as_array && resolved) {
|
|
616
|
-
|
|
617
650
|
const itemSchemas: Joi.Schema[] = [];
|
|
618
651
|
if (_.isArray(resolved)) {
|
|
619
652
|
for (let i = 0; i < (resolved || []).length; i++) {
|
|
620
|
-
const itemSchema = await recursive_schema(
|
|
653
|
+
const { schema: itemSchema } = await recursive_schema(
|
|
621
654
|
_.omit(newField, [`as_array`, `array_min`, `array_max`, `array_length`]) as Field,
|
|
622
|
-
data, { relative: `${relativeKey}[${i}]`, array: true, context: options.context });
|
|
655
|
+
data, { alter: false, relative: `${relativeKey}[${i}]`, array: true, context: options.context });
|
|
623
656
|
if (itemSchema) { itemSchemas.push(itemSchema); }
|
|
624
657
|
}
|
|
625
658
|
}
|
|
626
659
|
|
|
627
660
|
calculatedSchema = getArrayFieldSchema(newField, itemSchemas);
|
|
628
661
|
} else if (newField.type === `dict` && newField.items) {
|
|
629
|
-
const
|
|
662
|
+
const items: { key: string, schema: Joi.Schema, field: Field }[] = [];
|
|
630
663
|
|
|
631
664
|
if (_.isObject(resolved)) {
|
|
632
665
|
for (const item of newField.items) {
|
|
633
|
-
const
|
|
634
|
-
if (
|
|
666
|
+
const recursive = await recursive_schema(item, data, { alter: options.alter && true, relative: relativeKey, context: options.context });
|
|
667
|
+
if (recursive) { items.push({ key: item.key, schema: recursive.schema, field: recursive.field }); }
|
|
635
668
|
}
|
|
636
669
|
}
|
|
637
670
|
|
|
638
|
-
calculatedSchema = getObjectFieldSchema(newField,
|
|
671
|
+
calculatedSchema = getObjectFieldSchema(newField, items);
|
|
672
|
+
newField.items = items.map((i) => i.field);
|
|
639
673
|
} else {
|
|
640
674
|
calculatedSchema = getSimpleFieldSchema(newField);
|
|
641
675
|
}
|
|
642
676
|
|
|
643
677
|
if (!calculatedSchema) { throw new Error(`Could not resolve schema for field ${newField.key}`); }
|
|
644
678
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
if (matches) {
|
|
653
|
-
if (`overrides` in alteration) {
|
|
654
|
-
_.assign(newField, alteration.overrides);
|
|
655
|
-
} else if (`show` in alteration) {
|
|
656
|
-
hide = !alteration.show;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
delete newField.altered_by;
|
|
662
|
-
|
|
663
|
-
if (hide) {
|
|
664
|
-
// if the field is hidden, we don't need to validate it
|
|
665
|
-
_.unset(data, relativeKey);
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
679
|
+
if (typeof newField.show === `boolean` && !newField.show) {
|
|
680
|
+
// if the field is hidden, we don't need to validate it
|
|
681
|
+
_.unset(data, relativeKey);
|
|
682
|
+
return;
|
|
683
|
+
} else if (newField.disabled) {
|
|
684
|
+
// TODO: check this
|
|
685
|
+
_.unset(data, relativeKey);
|
|
668
686
|
}
|
|
669
687
|
|
|
670
|
-
return calculatedSchema;
|
|
688
|
+
return { schema: calculatedSchema, field: field.type === `file` ? alteredField : newField };
|
|
671
689
|
} catch (e) { throw e; }
|
|
672
690
|
};
|
|
673
691
|
|
|
@@ -681,14 +699,15 @@ const validate_internal = async (fields: Field[], data: Record<string, any>, opt
|
|
|
681
699
|
|
|
682
700
|
const cloned = _.cloneDeep(data);
|
|
683
701
|
|
|
684
|
-
const
|
|
702
|
+
const recursive = await recursive_schema(field, cloned, { alter: true, context: options.context });
|
|
703
|
+
if (!recursive) { continue; }
|
|
685
704
|
|
|
686
705
|
const resolved = _.get(cloned, field.key, field.default);
|
|
687
706
|
|
|
688
707
|
let validation: any;
|
|
689
708
|
let error: any;
|
|
690
709
|
try {
|
|
691
|
-
validation = await schema.validateAsync(resolved, { abortEarly: false });
|
|
710
|
+
validation = await recursive.schema.validateAsync(resolved, { abortEarly: false });
|
|
692
711
|
} catch (e) { error = e; }
|
|
693
712
|
|
|
694
713
|
let extended: ValidationExtended;
|
|
@@ -713,7 +732,7 @@ const validate_internal = async (fields: Field[], data: Record<string, any>, opt
|
|
|
713
732
|
|
|
714
733
|
response.valid &&= error ? false : true;
|
|
715
734
|
response.fields.push({
|
|
716
|
-
...field as any,
|
|
735
|
+
...recursive.field as any,
|
|
717
736
|
...options.secure ? await secure(field, extended) : extended,
|
|
718
737
|
});
|
|
719
738
|
|
|
@@ -55,7 +55,7 @@ const commandSchema = Joi.alternatives(
|
|
|
55
55
|
);
|
|
56
56
|
|
|
57
57
|
const API_SOURCES = (provider: Provider, configuration: Protocol.SourcesConfiguration, context: { organization: string, workspace: number }): SourceFunctions => ({
|
|
58
|
-
register: async (source, data) => {
|
|
58
|
+
register: async (source, sandbox, data) => {
|
|
59
59
|
try {
|
|
60
60
|
const { data: [created] } = await axios.post(`/api/v1/sources`, {
|
|
61
61
|
organization: context.organization,
|
|
@@ -63,6 +63,7 @@ const API_SOURCES = (provider: Provider, configuration: Protocol.SourcesConfigur
|
|
|
63
63
|
provider: provider.id,
|
|
64
64
|
version: provider.version,
|
|
65
65
|
source: source,
|
|
66
|
+
sandbox: sandbox,
|
|
66
67
|
data: data,
|
|
67
68
|
created_date: moment().format(`YYYY-MM-DDTHH:mm:ssZ`),
|
|
68
69
|
}, {
|
|
@@ -75,7 +76,7 @@ const API_SOURCES = (provider: Provider, configuration: Protocol.SourcesConfigur
|
|
|
75
76
|
return { id: created.uuid };
|
|
76
77
|
} catch (e) { throw e; }
|
|
77
78
|
},
|
|
78
|
-
unregister: async (source, id) => {
|
|
79
|
+
unregister: async (source, sandbox, id) => {
|
|
79
80
|
try {
|
|
80
81
|
const { data: [get] } = await axios.post(`/api/v1/sources/list`, {
|
|
81
82
|
organization: context.organization,
|
|
@@ -83,6 +84,7 @@ const API_SOURCES = (provider: Provider, configuration: Protocol.SourcesConfigur
|
|
|
83
84
|
provider: provider.id,
|
|
84
85
|
version: provider.version,
|
|
85
86
|
source: source,
|
|
87
|
+
sandbox: sandbox,
|
|
86
88
|
uuid: id,
|
|
87
89
|
}, {
|
|
88
90
|
baseURL: configuration.host,
|
|
@@ -100,7 +102,7 @@ const API_SOURCES = (provider: Provider, configuration: Protocol.SourcesConfigur
|
|
|
100
102
|
});
|
|
101
103
|
} catch (e) { throw e; }
|
|
102
104
|
},
|
|
103
|
-
consume: async (source) => {
|
|
105
|
+
consume: async (source, sandbox) => {
|
|
104
106
|
try {
|
|
105
107
|
const { data: sources } = await axios.post(`/api/v1/sources/list`, {
|
|
106
108
|
organization: context.organization,
|
|
@@ -108,6 +110,7 @@ const API_SOURCES = (provider: Provider, configuration: Protocol.SourcesConfigur
|
|
|
108
110
|
provider: provider.id,
|
|
109
111
|
version: provider.version,
|
|
110
112
|
source: source,
|
|
113
|
+
sandbox: sandbox,
|
|
111
114
|
}, {
|
|
112
115
|
baseURL: configuration.host,
|
|
113
116
|
headers: {
|
|
@@ -15,4 +15,6 @@ export type DeepPartial<T extends Record<string, any>> = {
|
|
|
15
15
|
export type AsyncReturnType<T extends (...args: any[]) => any> =
|
|
16
16
|
T extends (...args: any[]) => Promise<infer U> ? U :
|
|
17
17
|
T extends (...args: any[]) => infer U ? U :
|
|
18
|
-
any;
|
|
18
|
+
any;
|
|
19
|
+
|
|
20
|
+
export type OneOrArray<T> = T | T[];
|