Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/api/mustache/generator/NameGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Field, Identifier, NestedType, TypeSchema } from "@typeschema/types";
import type { Field, NestedTypeSchema, TypeIdentifier, TypeSchema } from "@typeschema/types";

export type NameTransformation = {
pattern: RegExp | string;
Expand Down Expand Up @@ -65,7 +65,7 @@ export class NameGenerator {
return this._generateTypeName(name);
}

private _generateTypeFromTypeRef(typeRef: Identifier): string {
private _generateTypeFromTypeRef(typeRef: TypeIdentifier): string {
if (typeRef.kind === "primitive-type") {
return this._generateTypeName(typeRef.name);
}
Expand All @@ -86,7 +86,7 @@ export class NameGenerator {
return this._generateTypeFromTypeRef((schema as any).type);
}

public generateType(schemaOrRefOrString: TypeSchema | NestedType | Identifier | string): string {
public generateType(schemaOrRefOrString: TypeSchema | NestedTypeSchema | TypeIdentifier | string): string {
if (typeof schemaOrRefOrString === "string") {
return this._generateTypeName(schemaOrRefOrString);
}
Expand Down
55 changes: 31 additions & 24 deletions src/api/mustache/generator/ViewModelFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import type { IsPrefixed } from "@root/utils/types";
import {
type ChoiceFieldInstance,
type Field,
type Identifier,
isComplexTypeIdentifier,
isNotChoiceDeclarationField,
isResourceIdentifier,
type NestedType,
type NestedTypeSchema,
type RegularField,
type TypeIdentifier,
type TypeSchema,
} from "@typeschema/types";

Expand All @@ -35,15 +35,15 @@ export class ViewModelFactory {
constructor(
private readonly tsIndex: TypeSchemaIndex,
private readonly nameGenerator: NameGenerator,
private readonly filterPred: (id: Identifier) => boolean,
private readonly filterPred: (id: TypeIdentifier) => boolean,
) {}

public createUtility(): RootViewModel<ViewModel> {
return this._createForRoot();
}

public createComplexType(
typeRef: Identifier,
typeRef: TypeIdentifier,
cache: ViewModelCache = { resourcesByUri: {}, complexTypesByUri: {} },
): RootViewModel<ResolvedTypeViewModel> {
const base = this._createForComplexType(typeRef, cache);
Expand All @@ -64,7 +64,7 @@ export class ViewModelFactory {
});
}
public createResource(
typeRef: Identifier,
typeRef: TypeIdentifier,
cache: ViewModelCache = { resourcesByUri: {}, complexTypesByUri: {} },
): RootViewModel<ResolvedTypeViewModel> {
const base = this._createForResource(typeRef, cache);
Expand All @@ -85,7 +85,7 @@ export class ViewModelFactory {
});
}

private _createFor(typeRef: Identifier, cache: ViewModelCache, nestedIn?: TypeSchema): TypeViewModel {
private _createFor(typeRef: TypeIdentifier, cache: ViewModelCache, nestedIn?: TypeSchema): TypeViewModel {
if (typeRef.kind === "complex-type") {
return this._createForComplexType(typeRef, cache, nestedIn);
}
Expand All @@ -95,7 +95,11 @@ export class ViewModelFactory {
throw new Error(`Unknown type ${typeRef.kind}`);
}

private _createForComplexType(typeRef: Identifier, cache: ViewModelCache, nestedIn?: TypeSchema): TypeViewModel {
private _createForComplexType(
typeRef: TypeIdentifier,
cache: ViewModelCache,
nestedIn?: TypeSchema,
): TypeViewModel {
const type = this.tsIndex.resolve(typeRef);
if (!type) {
throw new Error(`ComplexType ${typeRef.name} not found`);
Expand All @@ -108,7 +112,7 @@ export class ViewModelFactory {
return res;
}

private _createForResource(typeRef: Identifier, cache: ViewModelCache, nestedIn?: TypeSchema): TypeViewModel {
private _createForResource(typeRef: TypeIdentifier, cache: ViewModelCache, nestedIn?: TypeSchema): TypeViewModel {
const type = this.tsIndex.resolve(typeRef);
if (!type) {
throw new Error(`Resource ${typeRef.name} not found`);
Expand All @@ -121,25 +125,25 @@ export class ViewModelFactory {
return res;
}

private _createChildrenFor(typeRef: Identifier, cache: ViewModelCache, nestedIn?: TypeSchema): TypeViewModel[] {
private _createChildrenFor(typeRef: TypeIdentifier, cache: ViewModelCache, nestedIn?: TypeSchema): TypeViewModel[] {
const schema = this.tsIndex.resolve(typeRef);
if (!schema || !("typeFamily" in schema)) return [];
if (isComplexTypeIdentifier(typeRef)) {
return (schema.typeFamily?.complexTypes ?? [])
.filter(this.filterPred)
.map((childRef: Identifier) => this._createFor(childRef, cache, nestedIn));
.map((childRef: TypeIdentifier) => this._createFor(childRef, cache, nestedIn));
}
if (isResourceIdentifier(typeRef)) {
return (schema.typeFamily?.resources ?? [])
.filter(this.filterPred)
.map((childRef: Identifier) => this._createFor(childRef, cache, nestedIn));
.map((childRef: TypeIdentifier) => this._createFor(childRef, cache, nestedIn));
}
return [];
}

private _createParentsFor(base: TypeSchema | NestedType, cache: ViewModelCache) {
private _createParentsFor(base: TypeSchema | NestedTypeSchema, cache: ViewModelCache) {
const parents: TypeViewModel[] = [];
let parentRef: Identifier | undefined = "base" in base ? base.base : undefined;
let parentRef: TypeIdentifier | undefined = "base" in base ? base.base : undefined;
while (parentRef) {
parents.push(this._createFor(parentRef, cache, undefined));
const parent = this.tsIndex.resolve(parentRef);
Expand All @@ -149,7 +153,7 @@ export class ViewModelFactory {
}

private _createForNestedType(
nested: NestedType,
nested: NestedTypeSchema,
cache: ViewModelCache,
nestedIn?: TypeSchema,
): ResolvedTypeViewModel {
Expand All @@ -171,7 +175,7 @@ export class ViewModelFactory {
}

private _createTypeViewModel(
schema: TypeSchema | NestedType,
schema: TypeSchema | NestedTypeSchema,
cache: ViewModelCache,
nestedIn?: TypeSchema,
): TypeViewModel {
Expand Down Expand Up @@ -229,7 +233,7 @@ export class ViewModelFactory {
};
}

private _collectDependencies(schema: TypeSchema | NestedType): TypeViewModel["dependencies"] {
private _collectDependencies(schema: TypeSchema | NestedTypeSchema): TypeViewModel["dependencies"] {
const dependencies: TypeViewModel["dependencies"] = {
resources: [],
complexTypes: [],
Expand Down Expand Up @@ -273,35 +277,35 @@ export class ViewModelFactory {
return dependencies;
}

private _createIsResource(typeRef: Identifier): Record<IsPrefixed<string>, boolean> | false {
private _createIsResource(typeRef: TypeIdentifier): Record<IsPrefixed<string>, boolean> | false {
if (typeRef.kind !== "resource") {
return false;
}
return Object.fromEntries(
this.tsIndex
.collectResources()
.map((e) => e.identifier)
.map((resourceRef: Identifier) => [
.map((resourceRef: TypeIdentifier) => [
`is${resourceRef.name.charAt(0).toUpperCase() + resourceRef.name.slice(1)}`,
resourceRef.url === typeRef.url,
]),
) as Record<IsPrefixed<string>, boolean>;
}
private _createIsComplexType(typeRef: Identifier): Record<IsPrefixed<string>, boolean> | false {
private _createIsComplexType(typeRef: TypeIdentifier): Record<IsPrefixed<string>, boolean> | false {
if (typeRef.kind !== "complex-type" && typeRef.kind !== "nested") {
return false;
}
return Object.fromEntries(
this.tsIndex
.collectComplexTypes()
.map((e) => e.identifier)
.map((complexTypeRef: Identifier) => [
.map((complexTypeRef: TypeIdentifier) => [
`is${complexTypeRef.name.charAt(0).toUpperCase() + complexTypeRef.name.slice(1)}`,
complexTypeRef.url === typeRef.url,
]),
) as Record<IsPrefixed<string>, boolean>;
}
private _createIsPrimitiveType(typeRef: Identifier): Record<IsPrefixed<string>, boolean> | false {
private _createIsPrimitiveType(typeRef: TypeIdentifier): Record<IsPrefixed<string>, boolean> | false {
if (typeRef.kind !== "primitive-type") {
return false;
}
Expand All @@ -310,7 +314,10 @@ export class ViewModelFactory {
) as FieldViewModel["isPrimitive"];
}

private _collectNestedComplex(schema: TypeSchema | NestedType, cache: ViewModelCache): ResolvedTypeViewModel[] {
private _collectNestedComplex(
schema: TypeSchema | NestedTypeSchema,
cache: ViewModelCache,
): ResolvedTypeViewModel[] {
const nested: ResolvedTypeViewModel[] = [];
if ("nested" in schema && schema.nested) {
schema.nested
Expand Down Expand Up @@ -347,14 +354,14 @@ export class ViewModelFactory {
complexTypes: this.tsIndex
.collectComplexTypes()
.map((e) => e.identifier)
.map((typeRef: Identifier) => ({
.map((typeRef: TypeIdentifier) => ({
name: typeRef.name,
saveName: this.nameGenerator.generateType(typeRef),
})),
resources: this.tsIndex
.collectResources()
.map((e) => e.identifier)
.map((typeRef: Identifier) => ({
.map((typeRef: TypeIdentifier) => ({
name: typeRef.name,
saveName: this.nameGenerator.generateType(typeRef),
})),
Expand Down
4 changes: 2 additions & 2 deletions src/api/mustache/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IsPrefixed } from "@root/utils/types";
import type { Field, NestedType, TypeSchema } from "@typeschema/types";
import type { Field, NestedTypeSchema, TypeSchema } from "@typeschema/types";

export type DebugMixin = {
debug: string;
Expand Down Expand Up @@ -131,7 +131,7 @@ export type RootViewModel<T> = T & {
};

export type TypeViewModel = NamedViewModel & {
schema: TypeSchema | NestedType;
schema: TypeSchema | NestedTypeSchema;
fields: FieldViewModel[];

dependencies: {
Expand Down
4 changes: 2 additions & 2 deletions src/api/writer-generator/csharp/csharp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
import { pascalCase, uppercaseFirstLetter, uppercaseFirstLetterOfEach } from "@root/api/writer-generator/utils.ts";
import { Writer, type WriterOptions } from "@root/api/writer-generator/writer.ts";
import type { PartialBy } from "@root/utils/types.ts";
import type { Field, Identifier, RegularField } from "@typeschema/types";
import type { Field, RegularField, TypeIdentifier } from "@typeschema/types";
import {
type ChoiceFieldInstance,
isChoiceDeclarationField,
Expand Down Expand Up @@ -74,7 +74,7 @@ const canonicalToName = (canonical: string | undefined, dropFragment = true): st
return formatName(localName);
};

const getResourceName = (id: Identifier): string => {
const getResourceName = (id: TypeIdentifier): string => {
if (id.kind === "nested") {
const url = id.url;
const path = canonicalToName(url, false);
Expand Down
16 changes: 8 additions & 8 deletions src/api/writer-generator/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { fileURLToPath } from "node:url";
import { camelCase, pascalCase, snakeCase, uppercaseFirstLetterOfEach } from "@root/api/writer-generator/utils";
import { Writer, type WriterOptions } from "@root/api/writer-generator/writer.ts";
import { groupByPackages, sortAsDeclarationSequence, type TypeSchemaIndex } from "@root/typeschema/utils";
import type { EnumDefinition, Field, Identifier, SpecializationTypeSchema } from "@typeschema/types.ts";
import type { EnumDefinition, Field, SpecializationTypeSchema, TypeIdentifier } from "@typeschema/types.ts";

const PRIMITIVE_TYPE_MAP: Record<string, string> = {
boolean: "bool",
Expand Down Expand Up @@ -125,7 +125,7 @@ const canonicalToName = (canonical: string | undefined, dropFragment = true) =>
return snakeCase(localName);
};

const deriveResourceName = (id: Identifier): string => {
const deriveResourceName = (id: TypeIdentifier): string => {
if (id.kind === "nested") {
const url = id.url;
const path = canonicalToName(url, false);
Expand Down Expand Up @@ -585,7 +585,7 @@ export class Python extends Writer<PythonGeneratorOptions> {
this.importResourceDependencies(schema.dependencies);
}

private importComplexTypeDependencies(dependencies: Identifier[]): void {
private importComplexTypeDependencies(dependencies: TypeIdentifier[]): void {
const complexTypeDeps = dependencies.filter((dep) => dep.kind === "complex-type");
const depsByPackage = this.groupDependenciesByPackage(complexTypeDeps);

Expand All @@ -594,7 +594,7 @@ export class Python extends Writer<PythonGeneratorOptions> {
}
}

private importResourceDependencies(dependencies: Identifier[]): void {
private importResourceDependencies(dependencies: TypeIdentifier[]): void {
const resourceDeps = dependencies.filter((dep) => dep.kind === "resource");

for (const dep of resourceDeps) {
Expand All @@ -606,7 +606,7 @@ export class Python extends Writer<PythonGeneratorOptions> {
}
}

private groupDependenciesByPackage(dependencies: Identifier[]): ImportGroup {
private groupDependenciesByPackage(dependencies: TypeIdentifier[]): ImportGroup {
const grouped: ImportGroup = {};

for (const dep of dependencies) {
Expand Down Expand Up @@ -646,7 +646,7 @@ export class Python extends Writer<PythonGeneratorOptions> {
this.line(")");
}

private pyImportType(identifier: Identifier): void {
private pyImportType(identifier: TypeIdentifier): void {
this.pyImportFrom(this.pyPackage(identifier), pascalCase(identifier.name));
}

Expand Down Expand Up @@ -727,15 +727,15 @@ export class Python extends Writer<PythonGeneratorOptions> {
return parts.join(".");
}

private pyFhirPackage(identifier: Identifier): string {
private pyFhirPackage(identifier: TypeIdentifier): string {
return this.pyFhirPackageByName(identifier.package);
}

private pyFhirPackageByName(name: string): string {
return [this.opts.rootPackageName, this.buildPyPackageName(name)].join(".");
}

private pyPackage(identifier: Identifier): string {
private pyPackage(identifier: TypeIdentifier): string {
if (identifier.kind === "complex-type") {
return `${this.pyFhirPackage(identifier)}.base`;
}
Expand Down
12 changes: 6 additions & 6 deletions src/api/writer-generator/typescript/name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
import {
type CanonicalUrl,
extractNameFromCanonical,
type Identifier,
type ProfileTypeSchema,
type TypeIdentifier,
} from "@root/typeschema/types";
import type { TypeSchemaIndex } from "@root/typeschema/utils";

Expand All @@ -31,7 +31,7 @@ export const tsPackageDir = (name: string): string => {
return kebabCase(name);
};

export const tsModuleName = (id: Identifier): string => {
export const tsModuleName = (id: TypeIdentifier): string => {
// NOTE: Why not pascal case?
// In hl7-fhir-uv-xver-r5-r4 we have:
// - http://hl7.org/fhir/5.0/StructureDefinition/extension-Subscription.topic (subscription_topic)
Expand All @@ -40,11 +40,11 @@ export const tsModuleName = (id: Identifier): string => {
return uppercaseFirstLetter(tsResourceName(id));
};

export const tsModuleFileName = (id: Identifier): string => {
export const tsModuleFileName = (id: TypeIdentifier): string => {
return `${tsModuleName(id)}.ts`;
};

export const tsModulePath = (id: Identifier): string => {
export const tsModulePath = (id: TypeIdentifier): string => {
return `${tsPackageDir(id.package)}/${tsModuleName(id)}`;
};

Expand All @@ -55,7 +55,7 @@ export const tsNameFromCanonical = (canonical: string | undefined, dropFragment
return normalizeTsName(localName);
};

export const tsResourceName = (id: Identifier): string => {
export const tsResourceName = (id: TypeIdentifier): string => {
if (id.kind === "nested") {
const url = id.url;
// Extract name from URL without normalizing dots (needed for fragment splitting)
Expand Down Expand Up @@ -137,4 +137,4 @@ export const tsResolvedSliceBaseName = (
sliceName: string,
): string => sliceBaseNames[`${fieldName}:${sliceName}`] ?? sliceName;

export const tsValueFieldName = (id: Identifier): string => `value${uppercaseFirstLetter(id.name)}`;
export const tsValueFieldName = (id: TypeIdentifier): string => `value${uppercaseFirstLetter(id.name)}`;
Loading
Loading