swagger-typescript-api 11.1.3 → 12.0.1

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.
@@ -2,6 +2,9 @@ const { SCHEMA_TYPES } = require("../constants.js");
2
2
  const _ = require("lodash");
3
3
  const { SchemaFormatters } = require("./schema-formatters");
4
4
  const { internalCase } = require("../util/internal-case");
5
+ const { SchemaUtils } = require("./schema-utils");
6
+ const { camelCase } = require("lodash");
7
+ const { pascalCase } = require("../util/pascal-case");
5
8
 
6
9
  class SchemaParser {
7
10
  /**
@@ -22,42 +25,53 @@ class SchemaParser {
22
25
  */
23
26
  schemaFormatters;
24
27
 
28
+ /**
29
+ * @type {SchemaUtils}
30
+ */
31
+ schemaUtils;
32
+
33
+ $processingSchemaPath = [];
34
+
25
35
  constructor(config, logger, templates, schemaComponentsMap, typeName) {
26
36
  this.config = config;
27
37
  this.schemaComponentsMap = schemaComponentsMap;
28
38
  this.typeName = typeName;
29
39
  this.schemaFormatters = new SchemaFormatters(config, logger, this, templates);
40
+ this.schemaUtils = new SchemaUtils(config, schemaComponentsMap);
30
41
  }
31
42
 
32
43
  complexSchemaParsers = {
33
44
  // T1 | T2
34
45
  [SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema) => {
46
+ const ignoreTypes = [this.config.Ts.Keyword.Any];
35
47
  const combined = _.map(schema.oneOf, (childSchema) =>
36
- this.getInlineParseContent(this.makeAddRequiredToChildSchema(schema, childSchema)),
48
+ this.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema)),
37
49
  );
38
- const filtered = this.filterContents(combined, [this.config.Ts.Keyword.Any]);
50
+ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
39
51
 
40
52
  const type = this.config.Ts.UnionType(filtered);
41
53
 
42
- return this.checkAndAddNull(schema, type);
54
+ return this.schemaUtils.safeAddNullToType(schema, type);
43
55
  },
44
56
  // T1 & T2
45
57
  [SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema) => {
58
+ const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
46
59
  const combined = _.map(schema.allOf, (childSchema) =>
47
- this.getInlineParseContent(this.makeAddRequiredToChildSchema(schema, childSchema)),
60
+ this.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema)),
48
61
  );
49
- const filtered = this.filterContents(combined, [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any]);
62
+ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
50
63
 
51
64
  const type = this.config.Ts.IntersectionType(filtered);
52
65
 
53
- return this.checkAndAddNull(schema, type);
66
+ return this.schemaUtils.safeAddNullToType(schema, type);
54
67
  },
55
68
  // T1 | T2 | (T1 & T2)
56
69
  [SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema) => {
70
+ const ignoreTypes = [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any];
57
71
  const combined = _.map(schema.anyOf, (childSchema) =>
58
- this.getInlineParseContent(this.makeAddRequiredToChildSchema(schema, childSchema)),
72
+ this.getInlineParseContent(this.schemaUtils.makeAddRequiredToChildSchema(schema, childSchema)),
59
73
  );
60
- const filtered = this.filterContents(combined, [...this.config.jsPrimitiveTypes, this.config.Ts.Keyword.Any]);
74
+ const filtered = this.schemaUtils.filterSchemaContents(combined, (content) => !ignoreTypes.includes(content));
61
75
 
62
76
  const type = this.config.Ts.UnionType(
63
77
  _.compact([
@@ -66,7 +80,7 @@ class SchemaParser {
66
80
  ]),
67
81
  );
68
82
 
69
- return this.checkAndAddNull(schema, type);
83
+ return this.schemaUtils.safeAddNullToType(schema, type);
70
84
  },
71
85
  // TODO
72
86
  [SCHEMA_TYPES.COMPLEX_NOT]: (schema) => {
@@ -77,23 +91,39 @@ class SchemaParser {
77
91
 
78
92
  baseSchemaParsers = {
79
93
  [SCHEMA_TYPES.ENUM]: (schema, typeName) => {
80
- const refType = this.getRefType(schema);
94
+ if (this.config.extractEnums && !typeName) {
95
+ const generatedTypeName = this.config.componentTypeNameResolver.resolve([this.buildTypeNameFromPath()]);
96
+ const schemaComponent = this.schemaComponentsMap.createComponent("schemas", generatedTypeName, { ...schema });
97
+ return this.parseSchema(schemaComponent, generatedTypeName);
98
+ }
99
+
100
+ const refType = this.schemaUtils.getSchemaRefType(schema);
81
101
  const $ref = (refType && refType.$ref) || null;
82
- const enumNamesAsValues = this.config.enumNamesAsValues;
83
- const keyType = this.getType(schema);
84
- const enumNames = this.getEnumNames(schema);
85
- const isIntegerOrBooleanEnum =
86
- keyType === this.getTypeAlias({ type: "number" }) || keyType === this.getTypeAlias({ type: "boolean" });
102
+
103
+ if (Array.isArray(schema.enum) && Array.isArray(schema.enum[0])) {
104
+ return this.parseSchema(
105
+ {
106
+ oneOf: schema.enum.map((enumNames) => ({
107
+ type: "array",
108
+ items: enumNames.map((enumName) => ({ type: "string", enum: [enumName] })),
109
+ })),
110
+ },
111
+ typeName,
112
+ );
113
+ }
114
+
115
+ const keyType = this.getSchemaType(schema);
116
+ const enumNames = this.schemaUtils.getEnumNames(schema);
87
117
  let content = null;
88
118
 
89
119
  const formatValue = (value) => {
90
120
  if (value === null) {
91
121
  return this.config.Ts.NullValue(value);
92
122
  }
93
- if (keyType === this.getTypeAlias({ type: "number" })) {
123
+ if (keyType === this.getSchemaType({ type: "number" })) {
94
124
  return this.config.Ts.NumberValue(value);
95
125
  }
96
- if (keyType === this.getTypeAlias({ type: "boolean" })) {
126
+ if (keyType === this.getSchemaType({ type: "boolean" })) {
97
127
  return this.config.Ts.BooleanValue(value);
98
128
  }
99
129
 
@@ -104,10 +134,15 @@ class SchemaParser {
104
134
  content = _.map(enumNames, (enumName, index) => {
105
135
  const enumValue = _.get(schema.enum, index);
106
136
  const formattedKey =
107
- (enumName && this.typeName.format(enumName, { ignorePrefix: true, ignoreSuffix: true })) ||
108
- this.typeName.format(enumValue, { ignorePrefix: true, ignoreSuffix: true });
109
-
110
- if (enumNamesAsValues || _.isUndefined(enumValue)) {
137
+ (enumName &&
138
+ this.typeName.format(enumName, {
139
+ type: "enum-key",
140
+ })) ||
141
+ this.typeName.format(`${enumValue}`, {
142
+ type: "enum-key",
143
+ });
144
+
145
+ if (this.config.enumNamesAsValues || _.isUndefined(enumValue)) {
111
146
  return {
112
147
  key: formattedKey,
113
148
  type: this.config.Ts.Keyword.String,
@@ -124,14 +159,16 @@ class SchemaParser {
124
159
  } else {
125
160
  content = _.map(schema.enum, (key) => {
126
161
  return {
127
- key: isIntegerOrBooleanEnum ? key : this.typeName.format(key, { ignorePrefix: true, ignoreSuffix: true }),
162
+ key: this.typeName.format(`${key}`, {
163
+ type: "enum-key",
164
+ }),
128
165
  type: keyType,
129
166
  value: formatValue(key),
130
167
  };
131
168
  });
132
169
  }
133
170
 
134
- return this.attachParsedRef(schema, {
171
+ return {
135
172
  ...(_.isObject(schema) ? schema : {}),
136
173
  $ref: $ref,
137
174
  typeName: typeName || ($ref && refType.typeName) || null,
@@ -139,19 +176,16 @@ class SchemaParser {
139
176
  schemaType: SCHEMA_TYPES.ENUM,
140
177
  type: SCHEMA_TYPES.ENUM,
141
178
  keyType: keyType,
142
- typeIdentifier:
143
- this.config.generateUnionEnums || (!enumNames && isIntegerOrBooleanEnum)
144
- ? this.config.Ts.Keyword.Type
145
- : this.config.Ts.Keyword.Enum,
179
+ typeIdentifier: this.config.generateUnionEnums ? this.config.Ts.Keyword.Type : this.config.Ts.Keyword.Enum,
146
180
  name: typeName,
147
181
  description: this.schemaFormatters.formatDescription(schema.description),
148
182
  content,
149
- });
183
+ };
150
184
  },
151
185
  [SCHEMA_TYPES.OBJECT]: (schema, typeName) => {
152
186
  const contentProperties = this.getObjectSchemaContent(schema);
153
187
 
154
- return this.attachParsedRef(schema, {
188
+ return {
155
189
  ...(_.isObject(schema) ? schema : {}),
156
190
  $parsedSchema: true,
157
191
  schemaType: SCHEMA_TYPES.OBJECT,
@@ -161,14 +195,14 @@ class SchemaParser {
161
195
  description: this.schemaFormatters.formatDescription(schema.description),
162
196
  allFieldsAreOptional: !_.some(_.values(contentProperties), (part) => part.isRequired),
163
197
  content: contentProperties,
164
- });
198
+ };
165
199
  },
166
200
  [SCHEMA_TYPES.COMPLEX]: (schema, typeName) => {
167
201
  const complexType = this.getComplexType(schema);
168
202
  const simpleSchema = _.omit(_.clone(schema), _.keys(this.complexSchemaParsers));
169
203
  const complexSchemaContent = this.complexSchemaParsers[complexType](schema);
170
204
 
171
- return this.attachParsedRef(schema, {
205
+ return {
172
206
  ...(_.isObject(schema) ? schema : {}),
173
207
  $parsedSchema: true,
174
208
  schemaType: SCHEMA_TYPES.COMPLEX,
@@ -186,11 +220,11 @@ class SchemaParser {
186
220
  this.config.Ts.ExpressionGroup(this.getInlineParseContent(simpleSchema)),
187
221
  ]),
188
222
  ) || this.config.Ts.Keyword.Any,
189
- });
223
+ };
190
224
  },
191
225
  [SCHEMA_TYPES.PRIMITIVE]: (schema, typeName) => {
192
226
  let contentType = null;
193
- const { additionalProperties, type, description, $$requiredKeys } = schema || {};
227
+ const { additionalProperties, type, description, items } = schema || {};
194
228
 
195
229
  if (type === this.config.Ts.Keyword.Object && additionalProperties) {
196
230
  const fieldType = _.isObject(additionalProperties)
@@ -206,7 +240,11 @@ class SchemaParser {
206
240
  });
207
241
  }
208
242
 
209
- return this.attachParsedRef(schema, {
243
+ if (_.isArray(items) && type === SCHEMA_TYPES.ARRAY) {
244
+ contentType = this.config.Ts.Tuple(items.map((item) => this.getInlineParseContent(item)));
245
+ }
246
+
247
+ return {
210
248
  ...(_.isObject(schema) ? schema : {}),
211
249
  $parsedSchema: true,
212
250
  schemaType: SCHEMA_TYPES.PRIMITIVE,
@@ -215,192 +253,67 @@ class SchemaParser {
215
253
  name: typeName,
216
254
  description: this.schemaFormatters.formatDescription(description),
217
255
  // TODO: probably it should be refactored. `type === 'null'` is not flexible
218
- content: type === this.config.Ts.Keyword.Null ? type : contentType || this.getType(schema),
219
- });
220
- },
221
- };
222
-
223
- filterContents = (contents, types) => _.uniq(_.filter(contents, (type) => !_.includes(types, type)));
224
-
225
- makeAddRequiredToChildSchema = (parentSchema, childSchema) => {
226
- if (!childSchema) return childSchema;
227
-
228
- const required = _.uniq([...(parentSchema.required || []), ...(childSchema.required || [])]);
229
-
230
- const refData = this.getRefType(childSchema);
231
-
232
- if (refData) {
233
- const refObjectProperties = _.keys((refData.rawTypeData && refData.rawTypeData.properties) || {});
234
- const existedRequiredKeys = refObjectProperties.filter((key) => required.includes(key));
235
-
236
- if (!existedRequiredKeys.length) return childSchema;
237
-
238
- return {
239
- ...childSchema,
240
- $$requiredKeys: existedRequiredKeys,
256
+ content: type === this.config.Ts.Keyword.Null ? type : contentType || this.getSchemaType(schema),
241
257
  };
242
- } else if (childSchema.properties) {
243
- const childSchemaProperties = _.keys(childSchema.properties);
244
- const existedRequiredKeys = childSchemaProperties.filter((key) => required.includes(key));
245
-
246
- if (!existedRequiredKeys.length) return childSchema;
247
-
248
- return {
249
- required: _.uniq([...(childSchema.required || []), ...existedRequiredKeys]),
250
- ...childSchema,
251
- };
252
- }
253
-
254
- return childSchema;
255
- };
256
-
257
- attachParsedRef = (originalSchema, parsedSchema) => {
258
- const parsedSchemaAfterHook = this.config.hooks.onParseSchema(originalSchema, parsedSchema) || parsedSchema;
259
-
260
- if (originalSchema) {
261
- originalSchema.$parsed = parsedSchemaAfterHook;
262
- }
263
-
264
- return parsedSchemaAfterHook;
265
- };
266
-
267
- stealTypeFromSchema = (rawSchema) => {
268
- const schema = rawSchema || {};
269
-
270
- if (schema.type) {
271
- return schema.type;
272
- }
273
- if (schema.enum) {
274
- const enumFieldType = typeof schema.enum[0];
275
- if (enumFieldType === this.config.Ts.Keyword.Undefined) return;
276
-
277
- return enumFieldType;
278
- }
279
- if (_.keys(schema.properties).length) {
280
- return SCHEMA_TYPES.OBJECT;
281
- }
282
- if (!!schema.items) {
283
- return SCHEMA_TYPES.ARRAY;
284
- }
285
- };
286
-
287
- getTypeAlias = (rawSchema) => {
288
- const schema = rawSchema || {};
289
- const type = internalCase(this.stealTypeFromSchema(schema));
290
- const typeAlias =
291
- _.get(this.config.primitiveTypes, [type, schema.format]) ||
292
- _.get(this.config.primitiveTypes, [type, "$default"]) ||
293
- this.config.primitiveTypes[type];
294
-
295
- if (_.isFunction(typeAlias)) {
296
- return typeAlias(schema, this);
297
- }
298
-
299
- return typeAlias || type;
300
- };
301
-
302
- getEnumNames = (schema) => {
303
- return schema["x-enumNames"] || schema["xEnumNames"] || schema["x-enumnames"] || schema["x-enum-varnames"];
258
+ },
304
259
  };
305
260
 
306
261
  getInternalSchemaType = (schema) => {
307
- if (!_.isEmpty(schema.enum) || !_.isEmpty(this.getEnumNames(schema))) return SCHEMA_TYPES.ENUM;
262
+ if (!_.isEmpty(schema.enum) || !_.isEmpty(this.schemaUtils.getEnumNames(schema))) return SCHEMA_TYPES.ENUM;
308
263
  if (schema.allOf || schema.oneOf || schema.anyOf || schema.not) return SCHEMA_TYPES.COMPLEX;
309
264
  if (!_.isEmpty(schema.properties)) return SCHEMA_TYPES.OBJECT;
310
265
 
311
266
  return SCHEMA_TYPES.PRIMITIVE;
312
267
  };
313
268
 
314
- isNeedToAddNull = (contract, value) => {
315
- const { nullable, type } = contract || {};
316
- return (
317
- (nullable || !!_.get(contract, "x-nullable") || type === this.config.Ts.Keyword.Null) &&
318
- (!_.isString(value) ||
319
- (!value.includes(` ${this.config.Ts.Keyword.Null}`) && !value.includes(`${this.config.Ts.Keyword.Null} `)))
320
- );
321
- };
322
-
323
- checkAndAddRequiredKeys = (schema, resultType) => {
324
- if ("$$requiredKeys" in schema && schema.$$requiredKeys.length) {
325
- this.config.update({
326
- internalTemplateOptions: {
327
- addUtilRequiredKeysType: true,
328
- },
329
- });
330
- return this.config.Ts.TypeWithGeneric(this.config.Ts.CodeGenKeyword.UtilRequiredKeys, [
331
- resultType,
332
- this.config.Ts.UnionType(schema.$$requiredKeys.map(this.config.Ts.StringValue)),
333
- ]);
334
- }
335
-
336
- return resultType;
337
- };
338
-
339
- checkAndAddNull = (schema, value) => {
340
- const { nullable, type } = schema || {};
341
- return (nullable || !!_.get(schema, "x-nullable") || type === this.config.Ts.Keyword.Null) &&
342
- _.isString(value) &&
343
- !value.includes(` ${this.config.Ts.Keyword.Null}`) &&
344
- !value.includes(`${this.config.Ts.Keyword.Null} `)
345
- ? this.config.Ts.UnionType([value, this.config.Ts.Keyword.Null])
346
- : value;
347
- };
348
-
349
- isRef = (property) => {
350
- return !!(property && property["$ref"]);
351
- };
352
-
353
- getRefType = (schema) => {
354
- const ref = schema && schema["$ref"];
355
- return this.schemaComponentsMap.get(ref);
356
- };
357
-
358
- getType = (schema) => {
269
+ getSchemaType = (schema) => {
359
270
  if (!schema) return this.config.Ts.Keyword.Any;
360
271
 
361
- const refTypeInfo = this.getRefType(schema);
272
+ const refTypeInfo = this.schemaUtils.getSchemaRefType(schema);
362
273
 
363
274
  if (refTypeInfo) {
364
- return this.checkAndAddRequiredKeys(
275
+ return this.schemaUtils.checkAndAddRequiredKeys(
365
276
  schema,
366
- this.checkAndAddNull(schema, this.typeName.format(refTypeInfo.typeName)),
277
+ this.schemaUtils.safeAddNullToType(schema, this.typeName.format(refTypeInfo.typeName)),
367
278
  );
368
279
  }
369
280
 
370
- const primitiveType = this.getTypeAlias(schema);
371
- return primitiveType
372
- ? this.checkAndAddRequiredKeys(schema, this.checkAndAddNull(schema, primitiveType))
373
- : this.config.Ts.Keyword.Any;
374
- };
281
+ const primitiveType = this.schemaUtils.getSchemaPrimitiveType(schema);
375
282
 
376
- isRequired = (property, name, requiredProperties) => {
377
- if (property["x-omitempty"] === false) {
378
- return true;
379
- }
283
+ if (primitiveType == null) return this.config.Ts.Keyword.Any;
380
284
 
381
- const isRequired = _.isBoolean(property.required)
382
- ? !!property.required
383
- : _.isArray(requiredProperties)
384
- ? requiredProperties.includes(name)
385
- : !!requiredProperties;
285
+ let resultType;
386
286
 
387
- if (this.config.convertedFromSwagger2) {
388
- return typeof property.nullable === this.config.Ts.Keyword.Undefined ? isRequired : !property.nullable;
287
+ const typeAlias =
288
+ _.get(this.config.primitiveTypes, [primitiveType, schema.format]) ||
289
+ _.get(this.config.primitiveTypes, [primitiveType, "$default"]) ||
290
+ this.config.primitiveTypes[primitiveType];
291
+
292
+ if (_.isFunction(typeAlias)) {
293
+ resultType = typeAlias(schema, this);
294
+ } else {
295
+ resultType = typeAlias || primitiveType;
389
296
  }
390
- return isRequired;
297
+
298
+ if (!resultType) return this.config.Ts.Keyword.Any;
299
+
300
+ return this.schemaUtils.checkAndAddRequiredKeys(schema, this.schemaUtils.safeAddNullToType(schema, resultType));
391
301
  };
392
302
 
393
303
  getObjectSchemaContent = (schema) => {
394
- const { properties, additionalProperties, required: requiredProperties } = schema || {};
304
+ const { properties, additionalProperties } = schema || {};
395
305
 
396
306
  const propertiesContent = _.map(properties, (property, name) => {
397
- const required = this.isRequired(property, name, requiredProperties);
398
- const rawTypeData = _.get(this.getRefType(property), "rawTypeData", {});
307
+ this.$processingSchemaPath.push(name);
308
+ const required = this.schemaUtils.isPropertyRequired(name, property, schema);
309
+ const rawTypeData = _.get(this.schemaUtils.getSchemaRefType(property), "rawTypeData", {});
399
310
  const nullable = !!(rawTypeData.nullable || property.nullable);
400
311
  const fieldName = this.typeName.isValidName(name) ? name : this.config.Ts.StringValue(name);
401
312
  const fieldValue = this.getInlineParseContent(property);
402
313
  const readOnly = property.readOnly;
403
314
 
315
+ this.$processingSchemaPath.pop();
316
+
404
317
  return {
405
318
  ...property,
406
319
  $$raw: property,
@@ -453,7 +366,7 @@ class SchemaParser {
453
366
  * @param formatter {"inline" | "base"}
454
367
  * @return {Record<string, any>}
455
368
  */
456
- parseSchema = (schema, typeName, formatter) => {
369
+ parseSchema = (schema, typeName = null) => {
457
370
  if (!schema) return this.baseSchemaParsers[SCHEMA_TYPES.PRIMITIVE](null, typeName);
458
371
 
459
372
  let schemaType = null;
@@ -463,33 +376,47 @@ class SchemaParser {
463
376
  return schema;
464
377
  }
465
378
 
466
- if (schema.$parsed) {
467
- schemaType = schema.$parsed.schemaType;
468
- parsedSchema = schema.$parsed;
469
- } else {
470
- if (!typeName && this.isRef(schema)) {
471
- typeName = this.getType(schema);
379
+ if (!schema.$parsed) {
380
+ if (!typeName && this.schemaUtils.isRefSchema(schema)) {
381
+ typeName = this.getSchemaType(schema);
472
382
  }
473
383
 
474
- if (schema.items && !schema.type) {
384
+ if (schema.items && !Array.isArray(schema.items) && !schema.type) {
475
385
  schema.type = SCHEMA_TYPES.ARRAY;
476
386
  }
477
-
478
387
  schemaType = this.getInternalSchemaType(schema);
388
+
389
+ this.$processingSchemaPath.push(typeName);
390
+
391
+ _.merge(schema, this.config.hooks.onPreParseSchema(schema, typeName, schemaType));
479
392
  parsedSchema = this.baseSchemaParsers[schemaType](schema, typeName);
393
+ schema.$parsed = this.config.hooks.onParseSchema(schema, parsedSchema) || parsedSchema;
480
394
  }
481
395
 
482
- const formatterFn =
483
- formatter in this.schemaFormatters &&
484
- this.schemaFormatters[formatter] &&
485
- this.schemaFormatters[formatter][schemaType];
396
+ this.$processingSchemaPath.pop();
486
397
 
487
- return (formatterFn && formatterFn(parsedSchema)) || parsedSchema;
398
+ return schema.$parsed;
488
399
  };
489
400
 
490
- getInlineParseContent = (rawTypeData, typeName = null) => this.parseSchema(rawTypeData, typeName, "inline").content;
401
+ getInlineParseContent = (rawTypeData, typeName) => {
402
+ const parsedSchema = this.parseSchema(rawTypeData, typeName);
403
+ const formattedSchema = this.schemaFormatters.formatSchema(parsedSchema, "inline");
404
+ return formattedSchema.content;
405
+ };
491
406
 
492
- getParseContent = (rawTypeData, typeName = null) => this.parseSchema(rawTypeData, typeName).content;
407
+ getParseContent = (rawTypeData, typeName) => {
408
+ const parsedSchema = this.parseSchema(rawTypeData, typeName);
409
+ const formattedSchema = this.schemaFormatters.formatSchema(parsedSchema, "base");
410
+ return formattedSchema.content;
411
+ };
412
+
413
+ buildTypeNameFromPath = () => {
414
+ const schemaPath = _.uniq(_.compact(this.$processingSchemaPath));
415
+
416
+ if (!schemaPath || !schemaPath[0]) return null;
417
+
418
+ return internalCase(camelCase(`${schemaPath[0]}_${schemaPath[schemaPath.length - 1]}`));
419
+ };
493
420
  }
494
421
 
495
422
  module.exports = {