@ng-formworks/core 15.2.7
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/karma.conf.js +46 -0
- package/ng-package.json +11 -0
- package/package.json +54 -0
- package/src/lib/framework-library/framework-library.service.ts +195 -0
- package/src/lib/framework-library/framework.ts +11 -0
- package/src/lib/framework-library/no-framework.component.html +2 -0
- package/src/lib/framework-library/no-framework.component.ts +11 -0
- package/src/lib/framework-library/no-framework.module.ts +18 -0
- package/src/lib/framework-library/no.framework.ts +11 -0
- package/src/lib/json-schema-form.component.html +7 -0
- package/src/lib/json-schema-form.component.ts +809 -0
- package/src/lib/json-schema-form.module.ts +17 -0
- package/src/lib/json-schema-form.service.ts +907 -0
- package/src/lib/locale/de-validation-messages.ts +58 -0
- package/src/lib/locale/en-validation-messages.ts +58 -0
- package/src/lib/locale/es-validation-messages.ts +55 -0
- package/src/lib/locale/fr-validation-messages.ts +58 -0
- package/src/lib/locale/index.ts +7 -0
- package/src/lib/locale/it-validation-messages.ts +58 -0
- package/src/lib/locale/pt-validation-messages.ts +58 -0
- package/src/lib/locale/zh-validation-messages.ts +58 -0
- package/src/lib/locale-dates/en-US.ts +5 -0
- package/src/lib/shared/convert-schema-to-draft6.function.ts +321 -0
- package/src/lib/shared/form-group.functions.ts +522 -0
- package/src/lib/shared/format-regex.constants.ts +73 -0
- package/src/lib/shared/index.ts +40 -0
- package/src/lib/shared/json-schema.functions.ts +788 -0
- package/src/lib/shared/json.validators.ts +878 -0
- package/src/lib/shared/jsonpointer.functions.ts +1012 -0
- package/src/lib/shared/jspointer.functions.json.spec.ts +103 -0
- package/src/lib/shared/layout.functions.ts +1233 -0
- package/src/lib/shared/merge-schemas.function.ts +329 -0
- package/src/lib/shared/utility.functions.ts +373 -0
- package/src/lib/shared/validator.functions.spec.ts +55 -0
- package/src/lib/shared/validator.functions.ts +601 -0
- package/src/lib/widget-library/add-reference.component.ts +59 -0
- package/src/lib/widget-library/button.component.ts +54 -0
- package/src/lib/widget-library/checkbox.component.ts +74 -0
- package/src/lib/widget-library/checkboxes.component.ts +104 -0
- package/src/lib/widget-library/file.component.ts +36 -0
- package/src/lib/widget-library/hidden.component.ts +39 -0
- package/src/lib/widget-library/index.ts +56 -0
- package/src/lib/widget-library/input.component.ts +76 -0
- package/src/lib/widget-library/message.component.ts +29 -0
- package/src/lib/widget-library/none.component.ts +12 -0
- package/src/lib/widget-library/number.component.ts +79 -0
- package/src/lib/widget-library/one-of.component.ts +36 -0
- package/src/lib/widget-library/orderable.directive.ts +130 -0
- package/src/lib/widget-library/radios.component.ts +101 -0
- package/src/lib/widget-library/root.component.ts +78 -0
- package/src/lib/widget-library/section.component.ts +133 -0
- package/src/lib/widget-library/select-framework.component.ts +50 -0
- package/src/lib/widget-library/select-widget.component.ts +46 -0
- package/src/lib/widget-library/select.component.ts +96 -0
- package/src/lib/widget-library/submit.component.ts +68 -0
- package/src/lib/widget-library/tab.component.ts +29 -0
- package/src/lib/widget-library/tabs.component.ts +83 -0
- package/src/lib/widget-library/template.component.ts +52 -0
- package/src/lib/widget-library/textarea.component.ts +68 -0
- package/src/lib/widget-library/widget-library.module.ts +13 -0
- package/src/lib/widget-library/widget-library.service.ts +234 -0
- package/src/public_api.ts +21 -0
- package/src/test.ts +18 -0
- package/tsconfig.lib.json +25 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +17 -0
- package/tslint.json +11 -0
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
2
|
+
import filter from 'lodash/filter';
|
|
3
|
+
import map from 'lodash/map';
|
|
4
|
+
import {
|
|
5
|
+
AbstractControl,
|
|
6
|
+
UntypedFormArray,
|
|
7
|
+
UntypedFormControl,
|
|
8
|
+
UntypedFormGroup,
|
|
9
|
+
ValidatorFn
|
|
10
|
+
} from '@angular/forms';
|
|
11
|
+
import { forEach, hasOwn } from './utility.functions';
|
|
12
|
+
import { getControlValidators, removeRecursiveReferences } from './json-schema.functions';
|
|
13
|
+
import {
|
|
14
|
+
hasValue,
|
|
15
|
+
inArray,
|
|
16
|
+
isArray,
|
|
17
|
+
isDate,
|
|
18
|
+
isDefined,
|
|
19
|
+
isEmpty,
|
|
20
|
+
isObject,
|
|
21
|
+
isPrimitive,
|
|
22
|
+
SchemaPrimitiveType,
|
|
23
|
+
toJavaScriptType,
|
|
24
|
+
toSchemaType
|
|
25
|
+
} from './validator.functions';
|
|
26
|
+
import { JsonPointer, Pointer } from './jsonpointer.functions';
|
|
27
|
+
import { JsonValidators } from './json.validators';
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* FormGroup function library:
|
|
33
|
+
*
|
|
34
|
+
* buildFormGroupTemplate: Builds a FormGroupTemplate from schema
|
|
35
|
+
*
|
|
36
|
+
* buildFormGroup: Builds an Angular FormGroup from a FormGroupTemplate
|
|
37
|
+
*
|
|
38
|
+
* mergeValues:
|
|
39
|
+
*
|
|
40
|
+
* setRequiredFields:
|
|
41
|
+
*
|
|
42
|
+
* formatFormData:
|
|
43
|
+
*
|
|
44
|
+
* getControl:
|
|
45
|
+
*
|
|
46
|
+
* ---- TODO: ----
|
|
47
|
+
* TODO: add buildFormGroupTemplateFromLayout function
|
|
48
|
+
* buildFormGroupTemplateFromLayout: Builds a FormGroupTemplate from a form layout
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 'buildFormGroupTemplate' function
|
|
53
|
+
*
|
|
54
|
+
* Builds a template for an Angular FormGroup from a JSON Schema.
|
|
55
|
+
*
|
|
56
|
+
* TODO: add support for pattern properties
|
|
57
|
+
* https://spacetelescope.github.io/understanding-json-schema/reference/object.html
|
|
58
|
+
*
|
|
59
|
+
* // {any} jsf -
|
|
60
|
+
* // {any = null} nodeValue -
|
|
61
|
+
* // {boolean = true} mapArrays -
|
|
62
|
+
* // {string = ''} schemaPointer -
|
|
63
|
+
* // {string = ''} dataPointer -
|
|
64
|
+
* // {any = ''} templatePointer -
|
|
65
|
+
* // {any} -
|
|
66
|
+
*/
|
|
67
|
+
export function buildFormGroupTemplate(
|
|
68
|
+
jsf: any, nodeValue: any = null, setValues = true,
|
|
69
|
+
schemaPointer = '', dataPointer = '', templatePointer = ''
|
|
70
|
+
) {
|
|
71
|
+
const schema = JsonPointer.get(jsf.schema, schemaPointer);
|
|
72
|
+
if (setValues) {
|
|
73
|
+
if (!isDefined(nodeValue) && (
|
|
74
|
+
jsf.formOptions.setSchemaDefaults === true ||
|
|
75
|
+
(jsf.formOptions.setSchemaDefaults === 'auto' && isEmpty(jsf.formValues))
|
|
76
|
+
)) {
|
|
77
|
+
nodeValue = JsonPointer.get(jsf.schema, schemaPointer + '/default');
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
nodeValue = null;
|
|
81
|
+
}
|
|
82
|
+
// TODO: If nodeValue still not set, check layout for default value
|
|
83
|
+
const schemaType: string | string[] = JsonPointer.get(schema, '/type');
|
|
84
|
+
const controlType =
|
|
85
|
+
(hasOwn(schema, 'properties') || hasOwn(schema, 'additionalProperties')) &&
|
|
86
|
+
schemaType === 'object' ? 'FormGroup' :
|
|
87
|
+
(hasOwn(schema, 'items') || hasOwn(schema, 'additionalItems')) &&
|
|
88
|
+
schemaType === 'array' ? 'FormArray' :
|
|
89
|
+
!schemaType && hasOwn(schema, '$ref') ? '$ref' : 'FormControl';
|
|
90
|
+
const shortDataPointer =
|
|
91
|
+
removeRecursiveReferences(dataPointer, jsf.dataRecursiveRefMap, jsf.arrayMap);
|
|
92
|
+
if (!jsf.dataMap.has(shortDataPointer)) {
|
|
93
|
+
jsf.dataMap.set(shortDataPointer, new Map());
|
|
94
|
+
}
|
|
95
|
+
const nodeOptions = jsf.dataMap.get(shortDataPointer);
|
|
96
|
+
if (!nodeOptions.has('schemaType')) {
|
|
97
|
+
nodeOptions.set('schemaPointer', schemaPointer);
|
|
98
|
+
nodeOptions.set('schemaType', schema.type);
|
|
99
|
+
if (schema.format) {
|
|
100
|
+
nodeOptions.set('schemaFormat', schema.format);
|
|
101
|
+
if (!schema.type) { nodeOptions.set('schemaType', 'string'); }
|
|
102
|
+
}
|
|
103
|
+
if (controlType) {
|
|
104
|
+
nodeOptions.set('templatePointer', templatePointer);
|
|
105
|
+
nodeOptions.set('templateType', controlType);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
let controls: any;
|
|
109
|
+
const validators = getControlValidators(schema);
|
|
110
|
+
switch (controlType) {
|
|
111
|
+
|
|
112
|
+
case 'FormGroup':
|
|
113
|
+
controls = {};
|
|
114
|
+
if (hasOwn(schema, 'ui:order') || hasOwn(schema, 'properties')) {
|
|
115
|
+
const propertyKeys = schema['ui:order'] || Object.keys(schema.properties);
|
|
116
|
+
if (propertyKeys.includes('*') && !hasOwn(schema.properties, '*')) {
|
|
117
|
+
const unnamedKeys = Object.keys(schema.properties)
|
|
118
|
+
.filter(key => !propertyKeys.includes(key));
|
|
119
|
+
for (let i = propertyKeys.length - 1; i >= 0; i--) {
|
|
120
|
+
if (propertyKeys[i] === '*') {
|
|
121
|
+
propertyKeys.splice(i, 1, ...unnamedKeys);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
propertyKeys
|
|
126
|
+
.filter(key => hasOwn(schema.properties, key) ||
|
|
127
|
+
hasOwn(schema, 'additionalProperties')
|
|
128
|
+
)
|
|
129
|
+
.forEach(key => controls[key] = buildFormGroupTemplate(
|
|
130
|
+
jsf, JsonPointer.get(nodeValue, [<string>key]), setValues,
|
|
131
|
+
schemaPointer + (hasOwn(schema.properties, key) ?
|
|
132
|
+
'/properties/' + key : '/additionalProperties'
|
|
133
|
+
),
|
|
134
|
+
dataPointer + '/' + key,
|
|
135
|
+
templatePointer + '/controls/' + key
|
|
136
|
+
));
|
|
137
|
+
jsf.formOptions.fieldsRequired = setRequiredFields(schema, controls);
|
|
138
|
+
}
|
|
139
|
+
return { controlType, controls, validators };
|
|
140
|
+
|
|
141
|
+
case 'FormArray':
|
|
142
|
+
controls = [];
|
|
143
|
+
const minItems =
|
|
144
|
+
Math.max(schema.minItems || 0, nodeOptions.get('minItems') || 0);
|
|
145
|
+
const maxItems =
|
|
146
|
+
Math.min(schema.maxItems || 1000, nodeOptions.get('maxItems') || 1000);
|
|
147
|
+
let additionalItemsPointer: string = null;
|
|
148
|
+
if (isArray(schema.items)) { // 'items' is an array = tuple items
|
|
149
|
+
const tupleItems = nodeOptions.get('tupleItems') ||
|
|
150
|
+
(isArray(schema.items) ? Math.min(schema.items.length, maxItems) : 0);
|
|
151
|
+
for (let i = 0; i < tupleItems; i++) {
|
|
152
|
+
if (i < minItems) {
|
|
153
|
+
controls.push(buildFormGroupTemplate(
|
|
154
|
+
jsf, isArray(nodeValue) ? nodeValue[i] : nodeValue, setValues,
|
|
155
|
+
schemaPointer + '/items/' + i,
|
|
156
|
+
dataPointer + '/' + i,
|
|
157
|
+
templatePointer + '/controls/' + i
|
|
158
|
+
));
|
|
159
|
+
} else {
|
|
160
|
+
const schemaRefPointer = removeRecursiveReferences(
|
|
161
|
+
schemaPointer + '/items/' + i, jsf.schemaRecursiveRefMap
|
|
162
|
+
);
|
|
163
|
+
const itemRefPointer = removeRecursiveReferences(
|
|
164
|
+
shortDataPointer + '/' + i, jsf.dataRecursiveRefMap, jsf.arrayMap
|
|
165
|
+
);
|
|
166
|
+
const itemRecursive = itemRefPointer !== shortDataPointer + '/' + i;
|
|
167
|
+
if (!hasOwn(jsf.templateRefLibrary, itemRefPointer)) {
|
|
168
|
+
jsf.templateRefLibrary[itemRefPointer] = null;
|
|
169
|
+
jsf.templateRefLibrary[itemRefPointer] = buildFormGroupTemplate(
|
|
170
|
+
jsf, null, setValues,
|
|
171
|
+
schemaRefPointer,
|
|
172
|
+
itemRefPointer,
|
|
173
|
+
templatePointer + '/controls/' + i
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
controls.push(
|
|
177
|
+
isArray(nodeValue) ?
|
|
178
|
+
buildFormGroupTemplate(
|
|
179
|
+
jsf, nodeValue[i], setValues,
|
|
180
|
+
schemaPointer + '/items/' + i,
|
|
181
|
+
dataPointer + '/' + i,
|
|
182
|
+
templatePointer + '/controls/' + i
|
|
183
|
+
) :
|
|
184
|
+
itemRecursive ?
|
|
185
|
+
null : cloneDeep(jsf.templateRefLibrary[itemRefPointer])
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// If 'additionalItems' is an object = additional list items (after tuple items)
|
|
191
|
+
if (schema.items.length < maxItems && isObject(schema.additionalItems)) {
|
|
192
|
+
additionalItemsPointer = schemaPointer + '/additionalItems';
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// If 'items' is an object = list items only (no tuple items)
|
|
196
|
+
} else {
|
|
197
|
+
additionalItemsPointer = schemaPointer + '/items';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (additionalItemsPointer) {
|
|
201
|
+
const schemaRefPointer = removeRecursiveReferences(
|
|
202
|
+
additionalItemsPointer, jsf.schemaRecursiveRefMap
|
|
203
|
+
);
|
|
204
|
+
const itemRefPointer = removeRecursiveReferences(
|
|
205
|
+
shortDataPointer + '/-', jsf.dataRecursiveRefMap, jsf.arrayMap
|
|
206
|
+
);
|
|
207
|
+
const itemRecursive = itemRefPointer !== shortDataPointer + '/-';
|
|
208
|
+
if (!hasOwn(jsf.templateRefLibrary, itemRefPointer)) {
|
|
209
|
+
jsf.templateRefLibrary[itemRefPointer] = null;
|
|
210
|
+
jsf.templateRefLibrary[itemRefPointer] = buildFormGroupTemplate(
|
|
211
|
+
jsf, null, setValues,
|
|
212
|
+
schemaRefPointer,
|
|
213
|
+
itemRefPointer,
|
|
214
|
+
templatePointer + '/controls/-'
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
// const itemOptions = jsf.dataMap.get(itemRefPointer) || new Map();
|
|
218
|
+
const itemOptions = nodeOptions;
|
|
219
|
+
if (!itemRecursive || hasOwn(validators, 'required')) {
|
|
220
|
+
const arrayLength = Math.min(Math.max(
|
|
221
|
+
itemRecursive ? 0 :
|
|
222
|
+
(itemOptions.get('tupleItems') + itemOptions.get('listItems')) || 0,
|
|
223
|
+
isArray(nodeValue) ? nodeValue.length : 0
|
|
224
|
+
), maxItems);
|
|
225
|
+
for (let i = controls.length; i < arrayLength; i++) {
|
|
226
|
+
controls.push(
|
|
227
|
+
isArray(nodeValue) ?
|
|
228
|
+
buildFormGroupTemplate(
|
|
229
|
+
jsf, nodeValue[i], setValues,
|
|
230
|
+
schemaRefPointer,
|
|
231
|
+
dataPointer + '/-',
|
|
232
|
+
templatePointer + '/controls/-'
|
|
233
|
+
) :
|
|
234
|
+
itemRecursive ?
|
|
235
|
+
null : cloneDeep(jsf.templateRefLibrary[itemRefPointer])
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return { controlType, controls, validators };
|
|
241
|
+
|
|
242
|
+
case '$ref':
|
|
243
|
+
const schemaRef = JsonPointer.compile(schema.$ref);
|
|
244
|
+
const dataRef = JsonPointer.toDataPointer(schemaRef, schema);
|
|
245
|
+
const refPointer = removeRecursiveReferences(
|
|
246
|
+
dataRef, jsf.dataRecursiveRefMap, jsf.arrayMap
|
|
247
|
+
);
|
|
248
|
+
if (refPointer && !hasOwn(jsf.templateRefLibrary, refPointer)) {
|
|
249
|
+
// Set to null first to prevent recursive reference from causing endless loop
|
|
250
|
+
jsf.templateRefLibrary[refPointer] = null;
|
|
251
|
+
const newTemplate = buildFormGroupTemplate(jsf, setValues, setValues, schemaRef);
|
|
252
|
+
if (newTemplate) {
|
|
253
|
+
jsf.templateRefLibrary[refPointer] = newTemplate;
|
|
254
|
+
} else {
|
|
255
|
+
delete jsf.templateRefLibrary[refPointer];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
|
|
260
|
+
case 'FormControl':
|
|
261
|
+
const value = {
|
|
262
|
+
value: setValues && isPrimitive(nodeValue) ? nodeValue : null,
|
|
263
|
+
disabled: nodeOptions.get('disabled') || false
|
|
264
|
+
};
|
|
265
|
+
return { controlType, value, validators };
|
|
266
|
+
|
|
267
|
+
default:
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* 'buildFormGroup' function
|
|
274
|
+
*
|
|
275
|
+
* // {any} template -
|
|
276
|
+
* // {AbstractControl}
|
|
277
|
+
*/
|
|
278
|
+
export function buildFormGroup(template: any): AbstractControl {
|
|
279
|
+
const validatorFns: ValidatorFn[] = [];
|
|
280
|
+
let validatorFn: ValidatorFn = null;
|
|
281
|
+
if (hasOwn(template, 'validators')) {
|
|
282
|
+
forEach(template.validators, (parameters, validator) => {
|
|
283
|
+
if (typeof JsonValidators[validator] === 'function') {
|
|
284
|
+
validatorFns.push(JsonValidators[validator].apply(null, parameters));
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
if (validatorFns.length &&
|
|
288
|
+
inArray(template.controlType, ['FormGroup', 'FormArray'])
|
|
289
|
+
) {
|
|
290
|
+
validatorFn = validatorFns.length > 1 ?
|
|
291
|
+
JsonValidators.compose(validatorFns) : validatorFns[0];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (hasOwn(template, 'controlType')) {
|
|
295
|
+
switch (template.controlType) {
|
|
296
|
+
case 'FormGroup':
|
|
297
|
+
const groupControls: { [key: string]: AbstractControl } = {};
|
|
298
|
+
forEach(template.controls, (controls, key) => {
|
|
299
|
+
const newControl: AbstractControl = buildFormGroup(controls);
|
|
300
|
+
if (newControl) { groupControls[key] = newControl; }
|
|
301
|
+
});
|
|
302
|
+
return new UntypedFormGroup(groupControls, validatorFn);
|
|
303
|
+
case 'FormArray':
|
|
304
|
+
return new UntypedFormArray(filter(map(template.controls,
|
|
305
|
+
controls => buildFormGroup(controls)
|
|
306
|
+
)), validatorFn);
|
|
307
|
+
case 'FormControl':
|
|
308
|
+
return new UntypedFormControl(template.value, validatorFns);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* 'mergeValues' function
|
|
316
|
+
*
|
|
317
|
+
* // {any[]} ...valuesToMerge - Multiple values to merge
|
|
318
|
+
* // {any} - Merged values
|
|
319
|
+
*/
|
|
320
|
+
export function mergeValues(...valuesToMerge) {
|
|
321
|
+
let mergedValues: any = null;
|
|
322
|
+
for (const currentValue of valuesToMerge) {
|
|
323
|
+
if (!isEmpty(currentValue)) {
|
|
324
|
+
if (typeof currentValue === 'object' &&
|
|
325
|
+
(isEmpty(mergedValues) || typeof mergedValues !== 'object')
|
|
326
|
+
) {
|
|
327
|
+
if (isArray(currentValue)) {
|
|
328
|
+
mergedValues = [...currentValue];
|
|
329
|
+
} else if (isObject(currentValue)) {
|
|
330
|
+
mergedValues = { ...currentValue };
|
|
331
|
+
}
|
|
332
|
+
} else if (typeof currentValue !== 'object') {
|
|
333
|
+
mergedValues = currentValue;
|
|
334
|
+
} else if (isObject(mergedValues) && isObject(currentValue)) {
|
|
335
|
+
Object.assign(mergedValues, currentValue);
|
|
336
|
+
} else if (isObject(mergedValues) && isArray(currentValue)) {
|
|
337
|
+
const newValues = [];
|
|
338
|
+
for (const value of currentValue) {
|
|
339
|
+
newValues.push(mergeValues(mergedValues, value));
|
|
340
|
+
}
|
|
341
|
+
mergedValues = newValues;
|
|
342
|
+
} else if (isArray(mergedValues) && isObject(currentValue)) {
|
|
343
|
+
const newValues = [];
|
|
344
|
+
for (const value of mergedValues) {
|
|
345
|
+
newValues.push(mergeValues(value, currentValue));
|
|
346
|
+
}
|
|
347
|
+
mergedValues = newValues;
|
|
348
|
+
} else if (isArray(mergedValues) && isArray(currentValue)) {
|
|
349
|
+
const newValues = [];
|
|
350
|
+
for (let i = 0; i < Math.max(mergedValues.length, currentValue.length); i++) {
|
|
351
|
+
if (i < mergedValues.length && i < currentValue.length) {
|
|
352
|
+
newValues.push(mergeValues(mergedValues[i], currentValue[i]));
|
|
353
|
+
} else if (i < mergedValues.length) {
|
|
354
|
+
newValues.push(mergedValues[i]);
|
|
355
|
+
} else if (i < currentValue.length) {
|
|
356
|
+
newValues.push(currentValue[i]);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
mergedValues = newValues;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return mergedValues;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* 'setRequiredFields' function
|
|
368
|
+
*
|
|
369
|
+
* // {schema} schema - JSON Schema
|
|
370
|
+
* // {object} formControlTemplate - Form Control Template object
|
|
371
|
+
* // {boolean} - true if any fields have been set to required, false if not
|
|
372
|
+
*/
|
|
373
|
+
export function setRequiredFields(schema: any, formControlTemplate: any): boolean {
|
|
374
|
+
let fieldsRequired = false;
|
|
375
|
+
if (hasOwn(schema, 'required') && !isEmpty(schema.required)) {
|
|
376
|
+
fieldsRequired = true;
|
|
377
|
+
let requiredArray = isArray(schema.required) ? schema.required : [schema.required];
|
|
378
|
+
requiredArray = forEach(requiredArray,
|
|
379
|
+
key => JsonPointer.set(formControlTemplate, '/' + key + '/validators/required', [])
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
return fieldsRequired;
|
|
383
|
+
|
|
384
|
+
// TODO: Add support for patternProperties
|
|
385
|
+
// https://spacetelescope.github.io/understanding-json-schema/reference/object.html#pattern-properties
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* 'formatFormData' function
|
|
390
|
+
*
|
|
391
|
+
* // {any} formData - Angular FormGroup data object
|
|
392
|
+
* // {Map<string, any>} dataMap -
|
|
393
|
+
* // {Map<string, string>} recursiveRefMap -
|
|
394
|
+
* // {Map<string, number>} arrayMap -
|
|
395
|
+
* // {boolean = false} fixErrors - if TRUE, tries to fix data
|
|
396
|
+
* // {any} - formatted data object
|
|
397
|
+
*/
|
|
398
|
+
export function formatFormData(
|
|
399
|
+
formData: any, dataMap: Map<string, any>,
|
|
400
|
+
recursiveRefMap: Map<string, string>, arrayMap: Map<string, number>,
|
|
401
|
+
returnEmptyFields = false, fixErrors = false
|
|
402
|
+
): any {
|
|
403
|
+
if (formData === null || typeof formData !== 'object') { return formData; }
|
|
404
|
+
const formattedData = isArray(formData) ? [] : {};
|
|
405
|
+
JsonPointer.forEachDeep(formData, (value, dataPointer) => {
|
|
406
|
+
|
|
407
|
+
// If returnEmptyFields === true,
|
|
408
|
+
// add empty arrays and objects to all allowed keys
|
|
409
|
+
if (returnEmptyFields && isArray(value)) {
|
|
410
|
+
JsonPointer.set(formattedData, dataPointer, []);
|
|
411
|
+
} else if (returnEmptyFields && isObject(value) && !isDate(value)) {
|
|
412
|
+
JsonPointer.set(formattedData, dataPointer, {});
|
|
413
|
+
} else {
|
|
414
|
+
const genericPointer =
|
|
415
|
+
JsonPointer.has(dataMap, [dataPointer, 'schemaType']) ? dataPointer :
|
|
416
|
+
removeRecursiveReferences(dataPointer, recursiveRefMap, arrayMap);
|
|
417
|
+
if (JsonPointer.has(dataMap, [genericPointer, 'schemaType'])) {
|
|
418
|
+
const schemaType: SchemaPrimitiveType | SchemaPrimitiveType[] =
|
|
419
|
+
dataMap.get(genericPointer).get('schemaType');
|
|
420
|
+
if (schemaType === 'null') {
|
|
421
|
+
JsonPointer.set(formattedData, dataPointer, null);
|
|
422
|
+
} else if ((hasValue(value) || returnEmptyFields) &&
|
|
423
|
+
inArray(schemaType, ['string', 'integer', 'number', 'boolean'])
|
|
424
|
+
) {
|
|
425
|
+
const newValue = (fixErrors || (value === null && returnEmptyFields)) ?
|
|
426
|
+
toSchemaType(value, schemaType) : toJavaScriptType(value, schemaType);
|
|
427
|
+
if (isDefined(newValue) || returnEmptyFields) {
|
|
428
|
+
JsonPointer.set(formattedData, dataPointer, newValue);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Finish incomplete 'date-time' entries
|
|
433
|
+
if (dataMap.get(genericPointer).get('schemaFormat') === 'date-time') {
|
|
434
|
+
// "2000-03-14T01:59:26.535" -> "2000-03-14T01:59:26.535Z" (add "Z")
|
|
435
|
+
if (/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?$/i.test(value)) {
|
|
436
|
+
JsonPointer.set(formattedData, dataPointer, `${value}Z`);
|
|
437
|
+
// "2000-03-14T01:59" -> "2000-03-14T01:59:00Z" (add ":00Z")
|
|
438
|
+
} else if (/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d$/i.test(value)) {
|
|
439
|
+
JsonPointer.set(formattedData, dataPointer, `${value}:00Z`);
|
|
440
|
+
// "2000-03-14" -> "2000-03-14T00:00:00Z" (add "T00:00:00Z")
|
|
441
|
+
} else if (fixErrors && /^\d\d\d\d-[0-1]\d-[0-3]\d$/i.test(value)) {
|
|
442
|
+
JsonPointer.set(formattedData, dataPointer, `${value}:00:00:00Z`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
} else if (typeof value !== 'object' || isDate(value) ||
|
|
446
|
+
(value === null && returnEmptyFields)
|
|
447
|
+
) {
|
|
448
|
+
console.error('formatFormData error: ' +
|
|
449
|
+
`Schema type not found for form value at ${genericPointer}`);
|
|
450
|
+
console.error('dataMap', dataMap);
|
|
451
|
+
console.error('recursiveRefMap', recursiveRefMap);
|
|
452
|
+
console.error('genericPointer', genericPointer);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
return formattedData;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* 'getControl' function
|
|
461
|
+
*
|
|
462
|
+
* Uses a JSON Pointer for a data object to retrieve a control from
|
|
463
|
+
* an Angular formGroup or formGroup template. (Note: though a formGroup
|
|
464
|
+
* template is much simpler, its basic structure is idential to a formGroup).
|
|
465
|
+
*
|
|
466
|
+
* If the optional third parameter 'returnGroup' is set to TRUE, the group
|
|
467
|
+
* containing the control is returned, rather than the control itself.
|
|
468
|
+
*
|
|
469
|
+
* // {FormGroup} formGroup - Angular FormGroup to get value from
|
|
470
|
+
* // {Pointer} dataPointer - JSON Pointer (string or array)
|
|
471
|
+
* // {boolean = false} returnGroup - If true, return group containing control
|
|
472
|
+
* // {group} - Located value (or null, if no control found)
|
|
473
|
+
*/
|
|
474
|
+
export function getControl(
|
|
475
|
+
formGroup: any, dataPointer: Pointer, returnGroup = false
|
|
476
|
+
): any {
|
|
477
|
+
if (!isObject(formGroup) || !JsonPointer.isJsonPointer(dataPointer)) {
|
|
478
|
+
if (!JsonPointer.isJsonPointer(dataPointer)) {
|
|
479
|
+
// If dataPointer input is not a valid JSON pointer, check to
|
|
480
|
+
// see if it is instead a valid object path, using dot notaion
|
|
481
|
+
if (typeof dataPointer === 'string') {
|
|
482
|
+
const formControl = formGroup.get(dataPointer);
|
|
483
|
+
if (formControl) { return formControl; }
|
|
484
|
+
}
|
|
485
|
+
console.error(`getControl error: Invalid JSON Pointer: ${dataPointer}`);
|
|
486
|
+
}
|
|
487
|
+
if (!isObject(formGroup)) {
|
|
488
|
+
console.error(`getControl error: Invalid formGroup: ${formGroup}`);
|
|
489
|
+
}
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
let dataPointerArray = JsonPointer.parse(dataPointer);
|
|
493
|
+
if (returnGroup) { dataPointerArray = dataPointerArray.slice(0, -1); }
|
|
494
|
+
|
|
495
|
+
// If formGroup input is a real formGroup (not a formGroup template)
|
|
496
|
+
// try using formGroup.get() to return the control
|
|
497
|
+
if (typeof formGroup.get === 'function' &&
|
|
498
|
+
dataPointerArray.every(key => key.indexOf('.') === -1)
|
|
499
|
+
) {
|
|
500
|
+
const formControl = formGroup.get(dataPointerArray.join('.'));
|
|
501
|
+
if (formControl) { return formControl; }
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// If formGroup input is a formGroup template,
|
|
505
|
+
// or formGroup.get() failed to return the control,
|
|
506
|
+
// search the formGroup object for dataPointer's control
|
|
507
|
+
let subGroup = formGroup;
|
|
508
|
+
for (const key of dataPointerArray) {
|
|
509
|
+
if (hasOwn(subGroup, 'controls')) { subGroup = subGroup.controls; }
|
|
510
|
+
if (isArray(subGroup) && (key === '-')) {
|
|
511
|
+
subGroup = subGroup[subGroup.length - 1];
|
|
512
|
+
} else if (hasOwn(subGroup, key)) {
|
|
513
|
+
subGroup = subGroup[key];
|
|
514
|
+
} else {
|
|
515
|
+
console.error(`getControl error: Unable to find "${key}" item in FormGroup.`);
|
|
516
|
+
console.error(dataPointer);
|
|
517
|
+
console.error(formGroup);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return subGroup;
|
|
522
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// updated from AJV fast format regular expressions:
|
|
2
|
+
// https://github.com/epoberezkin/ajv/blob/master/lib/compile/formats.js
|
|
3
|
+
|
|
4
|
+
export const jsonSchemaFormatTests = {
|
|
5
|
+
|
|
6
|
+
'date': /^\d\d\d\d-[0-1]\d-[0-3]\d$/,
|
|
7
|
+
|
|
8
|
+
'time': /^[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i,
|
|
9
|
+
|
|
10
|
+
// Modified to allow incomplete entries, such as
|
|
11
|
+
// "2000-03-14T01:59:26.535" (needs "Z") or "2000-03-14T01:59" (needs ":00Z")
|
|
12
|
+
'date-time': /^\d\d\d\d-[0-1]\d-[0-3]\d[t\s][0-2]\d:[0-5]\d(?::[0-5]\d)?(?:\.\d+)?(?:z|[+-]\d\d:\d\d)?$/i,
|
|
13
|
+
|
|
14
|
+
// email (sources from jsen validator):
|
|
15
|
+
// http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363
|
|
16
|
+
// http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'willful violation')
|
|
17
|
+
'email': /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i,
|
|
18
|
+
|
|
19
|
+
'hostname': /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*$/i,
|
|
20
|
+
|
|
21
|
+
// optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html
|
|
22
|
+
'ipv4': /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
|
|
23
|
+
|
|
24
|
+
// optimized http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
|
|
25
|
+
// tslint:disable-next-line:max-line-length
|
|
26
|
+
'ipv6': /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i,
|
|
27
|
+
|
|
28
|
+
// uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js
|
|
29
|
+
'uri': /^(?:[a-z][a-z0-9+-.]*)(?::|\/)\/?[^\s]*$/i,
|
|
30
|
+
|
|
31
|
+
// uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A
|
|
32
|
+
'uri-reference': /^(?:(?:[a-z][a-z0-9+-.]*:)?\/\/)?[^\s]*$/i,
|
|
33
|
+
|
|
34
|
+
// uri-template: https://tools.ietf.org/html/rfc6570
|
|
35
|
+
// tslint:disable-next-line:max-line-length
|
|
36
|
+
'uri-template': /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,
|
|
37
|
+
|
|
38
|
+
// For the source: https://gist.github.com/dperini/729294
|
|
39
|
+
// For test cases: https://mathiasbynens.be/demo/url-regex
|
|
40
|
+
// tslint:disable-next-line:max-line-length
|
|
41
|
+
// @todo Delete current URL in favour of the commented out URL rule when this ajv issue is fixed https://github.com/eslint/eslint/issues/7983.
|
|
42
|
+
// tslint:disable-next-line:max-line-length
|
|
43
|
+
// URL: /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,
|
|
44
|
+
// tslint:disable-next-line:max-line-length
|
|
45
|
+
'url': /^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-?)*(?:[0-9KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[KSa-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i,
|
|
46
|
+
|
|
47
|
+
// uuid: http://tools.ietf.org/html/rfc4122
|
|
48
|
+
'uuid': /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,
|
|
49
|
+
|
|
50
|
+
// optimized https://gist.github.com/olmokramer/82ccce673f86db7cda5e
|
|
51
|
+
// tslint:disable-next-line:max-line-length
|
|
52
|
+
'color': /^\s*(#(?:[\da-f]{3}){1,2}|rgb\((?:\d{1,3},\s*){2}\d{1,3}\)|rgba\((?:\d{1,3},\s*){3}\d*\.?\d+\)|hsl\(\d{1,3}(?:,\s*\d{1,3}%){2}\)|hsla\(\d{1,3}(?:,\s*\d{1,3}%){2},\s*\d*\.?\d+\))\s*$/gi,
|
|
53
|
+
|
|
54
|
+
// JSON-pointer: https://tools.ietf.org/html/rfc6901
|
|
55
|
+
'json-pointer': /^(?:\/(?:[^~/]|~0|~1)*)*$|^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,
|
|
56
|
+
|
|
57
|
+
'relative-json-pointer': /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,
|
|
58
|
+
|
|
59
|
+
'regex': function (str) {
|
|
60
|
+
if (/[^\\]\\Z/.test(str)) { return false; }
|
|
61
|
+
try {
|
|
62
|
+
return true;
|
|
63
|
+
} catch (e) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type JsonSchemaFormatNames =
|
|
71
|
+
'date' | 'time' | 'date-time' | 'email' | 'hostname' | 'ipv4' | 'ipv6' |
|
|
72
|
+
'uri' | 'uri-reference' | 'uri-template' | 'url' | 'uuid' | 'color' |
|
|
73
|
+
'json-pointer' | 'relative-json-pointer' | 'regex';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Warning: Changing the following order may cause errors if the new order
|
|
2
|
+
// causes a library to be imported before another library it depends on.
|
|
3
|
+
|
|
4
|
+
export {
|
|
5
|
+
_executeValidators, _executeAsyncValidators, _mergeObjects, _mergeErrors,
|
|
6
|
+
isDefined, hasValue, isEmpty, isString, isNumber, isInteger, isBoolean,
|
|
7
|
+
isFunction, isObject, isArray, isDate, isMap, isSet, isPromise, isObservable,
|
|
8
|
+
getType, isType, isPrimitive, toJavaScriptType, toSchemaType, _toPromise,
|
|
9
|
+
toObservable, inArray, xor, SchemaPrimitiveType, SchemaType, JavaScriptPrimitiveType,
|
|
10
|
+
JavaScriptType, PrimitiveValue, PlainObject, IValidatorFn, AsyncIValidatorFn
|
|
11
|
+
} from './validator.functions';
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
addClasses, copy, forEach, forEachCopy, hasOwn, mergeFilteredObject,
|
|
15
|
+
uniqueItems, commonItems, fixTitle, toTitleCase
|
|
16
|
+
} from './utility.functions';
|
|
17
|
+
|
|
18
|
+
export { Pointer, JsonPointer } from './jsonpointer.functions';
|
|
19
|
+
|
|
20
|
+
export { JsonValidators } from './json.validators';
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
buildSchemaFromLayout, buildSchemaFromData, getFromSchema,
|
|
24
|
+
removeRecursiveReferences, getInputType, checkInlineType, isInputRequired,
|
|
25
|
+
updateInputOptions, getTitleMapFromOneOf, getControlValidators,
|
|
26
|
+
resolveSchemaReferences, getSubSchema, combineAllOf, fixRequiredArrayProperties
|
|
27
|
+
} from './json-schema.functions';
|
|
28
|
+
|
|
29
|
+
export { convertSchemaToDraft6 } from './convert-schema-to-draft6.function';
|
|
30
|
+
|
|
31
|
+
export { mergeSchemas } from './merge-schemas.function';
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
buildFormGroupTemplate, buildFormGroup, formatFormData,
|
|
35
|
+
getControl, setRequiredFields
|
|
36
|
+
} from './form-group.functions';
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
buildLayout, buildLayoutFromSchema, mapLayout, getLayoutNode, buildTitleMap
|
|
40
|
+
} from './layout.functions';
|