in scrooge-generator-typescript/src/main/scala/com/gu/scrooge/backend/typescript/TypescriptGenerator.scala [223:279]
def importsForStruct(structSource: StructLike): Seq[TsImport] = {
def namespaceToPackagePath(namespace: String): Path = {
val namespaceElements = packageNameFromNamespace(namespace).split('/').toList
Paths.get(namespaceElements.head, namespaceElements.tail: _*)
}
def listAllNamedTypes(ft: Seq[FieldType]): Seq[FieldType] = ft.flatMap {
case struct: StructType => Seq(struct)
case enum: EnumType => Seq(enum)
case listType: ListType => listAllNamedTypes(Seq(listType.eltType))
case setType: SetType => listAllNamedTypes(Seq(setType.eltType))
case mapType: MapType => listAllNamedTypes(Seq(mapType.keyType, mapType.valueType))
case _ => Nil
}
def importLocation(namedType: NamedType): String = {
val packagePath: Path = namespaceToPackagePath(defaultNamespace)
val structPath: Path = namespaceToPackagePath(namespace.fullName)
val location = for {
prefix <- namedType.scopePrefix
importedDocument <- resolvedDoc.resolver.includeMap.get(prefix.fullName)
namespace <- importedDocument.document.namespace(namespaceLanguage)
namedTypePath = namespaceToPackagePath(namespace.fullName)
} yield {
if (namedTypePath.startsWith(packagePath)) {
val relativePath = structPath.relativize(namedTypePath)
if (relativePath.startsWith(".") || relativePath.startsWith("..")) {
s"${relativePath.resolve(namedType.sid.toCamelCase.name)}"
} else {
s"./${relativePath.resolve(namedType.sid.toCamelCase.name)}"
}
} else {
s"${namedTypePath}/${namedType.sid.toCamelCase.name}"
}
}
location.getOrElse(s"./${namedType.sid.toCamelCase.name}")
}
val listOfAllNamedTypes = listAllNamedTypes(structSource.fields.map(_.fieldType))
// maps the source file to the type to import
val importMappings = listOfAllNamedTypes.foldLeft(Seq.empty[(String, String)]) {
case (agg, struct: StructType) => agg ++ Seq(
importLocation(struct) -> companionName(struct.sid),
importLocation(struct) -> typeName(struct.sid)
)
case (agg, enum: EnumType) => agg ++ Seq(importLocation(enum) -> typeName(enum.sid))
case (agg, _) => agg
}
importMappings
.groupBy(_._1) // group by file
.toSeq
.map { case (file, mapping) => TsImport(mapping.map(_._2).distinct.sorted, file) }
.sortBy(_.file)
}