|
|
|
@ -1,5 +1,11 @@ |
|
|
|
import { VOLO_NAME_VALUE, VOLO_REGEX } from '../constants'; |
|
|
|
import { VOLO_REGEX } from '../constants'; |
|
|
|
import { Interface, Model, Property, PropertyDef, Type, TypeWithEnum } from '../models'; |
|
|
|
import { |
|
|
|
extractGenerics, |
|
|
|
generateRefWithPlaceholders, |
|
|
|
GenericsCollector, |
|
|
|
replacePlaceholdersWithGenerics, |
|
|
|
} from './generics'; |
|
|
|
import { parseNamespace } from './namespace'; |
|
|
|
import { relativePathToModel } from './path'; |
|
|
|
import { camel } from './text'; |
|
|
|
@ -8,6 +14,7 @@ import { |
|
|
|
createTypeParser, |
|
|
|
createTypeSimplifier, |
|
|
|
createTypesToImportsReducer, |
|
|
|
extendsSelf, |
|
|
|
removeTypeModifiers, |
|
|
|
} from './type'; |
|
|
|
|
|
|
|
@ -27,6 +34,7 @@ export function createImportRefsToModelReducer(params: ModelGeneratorParams) { |
|
|
|
return (models: Model[], importRefs: string[]) => { |
|
|
|
const enums: string[] = []; |
|
|
|
const interfaces = importRefs.reduce(reduceImportRefsToInterfaces, []); |
|
|
|
|
|
|
|
sortInterfaces(interfaces); |
|
|
|
|
|
|
|
interfaces.forEach(_interface => { |
|
|
|
@ -40,12 +48,9 @@ export function createImportRefsToModelReducer(params: ModelGeneratorParams) { |
|
|
|
const index = models.findIndex(m => m.namespace === _interface.namespace); |
|
|
|
if (index > -1) { |
|
|
|
if (models[index].interfaces.some(i => i.identifier === _interface.identifier)) return; |
|
|
|
if (_interface.ref.startsWith(VOLO_NAME_VALUE.ref)) return; |
|
|
|
|
|
|
|
models[index].interfaces.push(_interface); |
|
|
|
} else { |
|
|
|
if (_interface.ref.startsWith(VOLO_NAME_VALUE.ref)) _interface = VOLO_NAME_VALUE; |
|
|
|
|
|
|
|
const { namespace } = _interface; |
|
|
|
|
|
|
|
models.push( |
|
|
|
@ -70,7 +75,7 @@ export function createImportRefsToModelReducer(params: ModelGeneratorParams) { |
|
|
|
isEnum: false, |
|
|
|
}); |
|
|
|
|
|
|
|
_interface.properties.forEach(prop => { |
|
|
|
[..._interface.properties, ..._interface.generics].forEach(prop => { |
|
|
|
prop.refs.forEach(ref => { |
|
|
|
const propType = types[ref]; |
|
|
|
if (!propType) return; |
|
|
|
@ -100,38 +105,50 @@ export function createImportRefToInterfaceReducerCreator(params: ModelGeneratorP |
|
|
|
const parseType = createTypeParser(removeTypeModifiers); |
|
|
|
const simplifyType = createTypeSimplifier(); |
|
|
|
const getIdentifier = (type: string) => removeTypeModifiers(simplifyType(type)); |
|
|
|
const genericsCollector = new GenericsCollector(getIdentifier); |
|
|
|
|
|
|
|
return reduceRefsToInterfaces; |
|
|
|
|
|
|
|
function reduceRefsToInterfaces(interfaces: Interface[], ref: string) { |
|
|
|
function reduceRefsToInterfaces(interfaces: Interface[], ref: string): Interface[] { |
|
|
|
const typeDef = types[ref]; |
|
|
|
if (!typeDef) return interfaces; |
|
|
|
|
|
|
|
const namespace = parseNamespace(solution, ref); |
|
|
|
|
|
|
|
const identifier = (typeDef.genericArguments ?? []).reduce( |
|
|
|
(acc, t, i) => acc.replace(`T${i}`, t), |
|
|
|
getIdentifier(ref), |
|
|
|
); |
|
|
|
let { baseType: base, genericArguments } = typeDef; |
|
|
|
genericArguments = genericArguments || []; |
|
|
|
let identifier = getIdentifier(ref); |
|
|
|
identifier = replacePlaceholdersWithGenerics(identifier, genericArguments, genericsCollector); |
|
|
|
|
|
|
|
if (base) { |
|
|
|
if (extendsSelf(ref, base)) { |
|
|
|
genericsCollector.collect(extractGenerics(base).generics, genericArguments); |
|
|
|
return reduceRefsToInterfaces(interfaces, generateRefWithPlaceholders(base)); |
|
|
|
} else { |
|
|
|
base = getIdentifier(base); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const base = typeDef.baseType ? getIdentifier(typeDef.baseType) : null; |
|
|
|
const _interface = new Interface({ identifier, base, namespace, ref }); |
|
|
|
const { generics } = genericsCollector; |
|
|
|
const _interface = new Interface({ identifier, base, namespace, ref, generics }); |
|
|
|
genericsCollector.reset(); |
|
|
|
|
|
|
|
typeDef.properties?.forEach(prop => { |
|
|
|
const name = camel(prop.name); |
|
|
|
const optional = isOptionalProperty(prop) ? '?' : ''; |
|
|
|
const type = simplifyType(prop.typeSimple); |
|
|
|
const refs = parseType(prop.type).reduce( |
|
|
|
(acc: string[], r) => acc.concat(parseGenerics(r).toGenerics()), |
|
|
|
[], |
|
|
|
); |
|
|
|
const property = new Property({ name, type, refs }); |
|
|
|
property.setOptional(isOptionalProperty(prop)); |
|
|
|
|
|
|
|
_interface.properties.push(new Property({ name, optional, type, refs })); |
|
|
|
_interface.properties.push(property); |
|
|
|
}); |
|
|
|
|
|
|
|
interfaces.push(_interface); |
|
|
|
|
|
|
|
return _interface.properties |
|
|
|
return [..._interface.properties, ..._interface.generics] |
|
|
|
.reduce<string[]>((refs, prop) => { |
|
|
|
prop.refs.forEach(type => { |
|
|
|
if (types[type]?.isEnum) return; |
|
|
|
@ -142,7 +159,7 @@ export function createImportRefToInterfaceReducerCreator(params: ModelGeneratorP |
|
|
|
return refs; |
|
|
|
}, []) |
|
|
|
.concat(base ? parseGenerics(typeDef.baseType!).toGenerics() : []) |
|
|
|
.reduce<Interface[]>(reduceRefsToInterfaces, interfaces); |
|
|
|
.reduce(reduceRefsToInterfaces, interfaces); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|