Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: get rid of ReadonlyDeep type #3201

Merged
merged 6 commits into from
Feb 4, 2025
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
3 changes: 1 addition & 2 deletions packages/ts/generator-core/src/Generator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import SwaggerParser from '@apidevtools/swagger-parser';
import type LoggerFactory from '@vaadin/hilla-generator-utils/LoggerFactory.js';
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import ts from 'typescript';
import type { PluginConstructor } from './Plugin.js';
import PluginManager from './PluginManager.js';
Expand All @@ -28,7 +27,7 @@

async process(input: string): Promise<readonly File[]> {
this.#logger.global.debug('Processing OpenAPI');
const api = (await this.#parser.bundle(JSON.parse(input))) as ReadonlyDeep<OpenAPIV3.Document>;
const api = (await this.#parser.bundle(JSON.parse(input))) as OpenAPIV3.Document;

Check warning on line 30 in packages/ts/generator-core/src/Generator.ts

View check run for this annotation

Codecov / codecov/patch

packages/ts/generator-core/src/Generator.ts#L30

Added line #L30 was not covered by tests

const storage: SharedStorage = {
api,
Expand Down
3 changes: 1 addition & 2 deletions packages/ts/generator-core/src/ReferenceResolver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type SwaggerParser from '@apidevtools/swagger-parser';
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';

export default class ReferenceResolver {
readonly #parser: SwaggerParser;
Expand All @@ -9,7 +8,7 @@
this.#parser = parser;
}

resolve<T extends ReadonlyDeep<object>>(obj: ReadonlyDeep<OpenAPIV3.ReferenceObject> | T): T {
resolve<T extends object>(obj: OpenAPIV3.ReferenceObject | T): T {

Check warning on line 11 in packages/ts/generator-core/src/ReferenceResolver.ts

View check run for this annotation

Codecov / codecov/patch

packages/ts/generator-core/src/ReferenceResolver.ts#L11

Added line #L11 was not covered by tests
return '$ref' in obj ? this.#parser.$refs.get(obj.$ref) : obj;
}
}
13 changes: 6 additions & 7 deletions packages/ts/generator-core/src/Schema.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep, Simplify } from 'type-fest';

export type Nullified<T, K extends keyof T> = T & Record<K, undefined>;

export type ReferenceSchema = ReadonlyDeep<OpenAPIV3.ReferenceObject>;
export type ArraySchema = ReadonlyDeep<OpenAPIV3.ArraySchemaObject>;
export type NonArraySchema = ReadonlyDeep<OpenAPIV3.NonArraySchemaObject>;
export type ReferenceSchema = OpenAPIV3.ReferenceObject;
export type ArraySchema = OpenAPIV3.ArraySchemaObject;
export type NonArraySchema = OpenAPIV3.NonArraySchemaObject;
export type RegularSchema = ArraySchema | NonArraySchema;

export type NullableSchema = Readonly<Required<Pick<RegularSchema, 'nullable'>>> & RegularSchema;
Expand All @@ -21,7 +20,7 @@
| OneOfRuleComposedSchema;

export type NonComposedRegularSchema = Readonly<Nullified<RegularSchema, 'allOf' | 'anyOf' | 'oneOf'>> & RegularSchema;
export type NonComposedSchema = Simplify<NonComposedRegularSchema | ReferenceSchema>;
export type NonComposedSchema = NonComposedRegularSchema | ReferenceSchema;

export type BooleanSchema = NonComposedRegularSchema & Readonly<{ type: 'boolean' }>;
export type IntegerSchema = NonComposedRegularSchema & Readonly<{ type: 'integer' }>;
Expand All @@ -34,7 +33,7 @@
export type NonEmptyObjectSchema = ObjectSchema & Readonly<Required<Pick<ObjectSchema, 'properties'>>>;
export type MapSchema = EmptyObjectSchema & Readonly<Required<Pick<ObjectSchema, 'additionalProperties'>>>;

export type Schema = ReadonlyDeep<ReferenceSchema | RegularSchema>;
export type Schema = ReferenceSchema | RegularSchema;

export function isReferenceSchema(schema: Schema): schema is ReferenceSchema {
return '$ref' in schema;
Expand Down Expand Up @@ -152,7 +151,7 @@
}

export function resolveReference(
schemas: ReadonlyDeep<OpenAPIV3.ComponentsObject>['schemas'],
schemas: OpenAPIV3.ComponentsObject['schemas'],

Check warning on line 154 in packages/ts/generator-core/src/Schema.ts

View check run for this annotation

Codecov / codecov/patch

packages/ts/generator-core/src/Schema.ts#L154

Added line #L154 was not covered by tests
{ $ref }: ReferenceSchema,
): Schema | undefined {
if (schemas) {
Expand Down
3 changes: 1 addition & 2 deletions packages/ts/generator-core/src/SharedStorage.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import type { $Refs } from '@apidevtools/swagger-parser';
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import type { SourceFile, TypeNode } from 'typescript';

export type TransferTypeMaker = (typeArguments: readonly TypeNode[] | undefined) => TypeNode;

export type TransferTypes = Map<string, TransferTypeMaker>;

export type SharedStorage = Readonly<{
api: ReadonlyDeep<OpenAPIV3.Document>;
api: OpenAPIV3.Document;
apiRefs: $Refs;
outputDir?: string;
pluginStorage: Map<string, unknown>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import ClientPlugin from '@vaadin/hilla-generator-plugin-client';
import type DependencyManager from '@vaadin/hilla-generator-utils/dependencies/DependencyManager.js';
import equal from 'fast-deep-equal';
import { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import ts, { type Expression, type Statement, type TypeNode } from 'typescript';
import EndpointMethodRequestBodyProcessor from './EndpointMethodRequestBodyProcessor.js';
import EndpointMethodResponseProcessor from './EndpointMethodResponseProcessor.js';

export type EndpointMethodOperation = ReadonlyDeep<OpenAPIV3.OperationObject>;
export type EndpointMethodOperation = OpenAPIV3.OperationObject;

export default abstract class EndpointMethodOperationProcessor {
// eslint-disable-next-line @typescript-eslint/max-params
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import {
import type { TransferTypes } from '@vaadin/hilla-generator-core/SharedStorage.js';
import type DependencyManager from '@vaadin/hilla-generator-utils/dependencies/DependencyManager.js';
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import ts, { type Identifier, type ObjectLiteralExpression, type ParameterDeclaration } from 'typescript';
import TypeSchemaProcessor from './TypeSchemaProcessor.js';
import { defaultMediaType } from './utils.js';

export type EndpointMethodRequestBody = ReadonlyDeep<OpenAPIV3.RequestBodyObject>;
export type EndpointMethodRequestBody = OpenAPIV3.RequestBodyObject;

export type EndpointMethodRequestBodyProcessingResult = Readonly<{
parameters: readonly ParameterDeclaration[];
Expand All @@ -32,7 +31,7 @@ export default class EndpointMethodRequestBodyProcessor {
readonly #requestBody?: EndpointMethodRequestBody;

constructor(
requestBody: ReadonlyDeep<OpenAPIV3.ReferenceObject | OpenAPIV3.RequestBodyObject> | undefined,
requestBody: OpenAPIV3.ReferenceObject | OpenAPIV3.RequestBodyObject | undefined,
dependencies: DependencyManager,
transferTypes: TransferTypes,
owner: Plugin,
Expand Down Expand Up @@ -102,7 +101,7 @@ export default class EndpointMethodRequestBodyProcessor {
}

#extractParameterData(
basicSchema?: ReadonlyDeep<OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject>,
basicSchema?: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject,
): Array<readonly [string, Schema]> {
if (!basicSchema) {
return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import type Plugin from '@vaadin/hilla-generator-core/Plugin.js';
import type { TransferTypes } from '@vaadin/hilla-generator-core/SharedStorage.js';
import type DependencyManager from '@vaadin/hilla-generator-utils/dependencies/DependencyManager.js';
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import type { TypeNode } from 'typescript';
import TypeSchemaProcessor from './TypeSchemaProcessor.js';
import { defaultMediaType } from './utils.js';

export type EndpointMethodResponses = ReadonlyDeep<OpenAPIV3.ResponsesObject>;
export type EndpointMethodResponse = ReadonlyDeep<OpenAPIV3.ResponseObject>;
export type EndpointMethodResponses = OpenAPIV3.ResponsesObject;
export type EndpointMethodResponse = OpenAPIV3.ResponseObject;

export default class EndpointMethodResponseProcessor {
readonly #code: string;
Expand Down
12 changes: 4 additions & 8 deletions packages/ts/generator-plugin-backbone/src/EndpointProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import createSourceFile from '@vaadin/hilla-generator-utils/createSourceFile.js'
import DependencyManager from '@vaadin/hilla-generator-utils/dependencies/DependencyManager.js';
import PathManager from '@vaadin/hilla-generator-utils/dependencies/PathManager.js';
import { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import type { SourceFile, Statement } from 'typescript';
import EndpointMethodOperationProcessor from './EndpointMethodOperationProcessor.js';

export default class EndpointProcessor {
static async create(
name: string,
methods: Map<string, ReadonlyDeep<OpenAPIV3.PathItemObject>>,
methods: Map<string, OpenAPIV3.PathItemObject>,
storage: SharedStorage,
owner: Plugin,
): Promise<EndpointProcessor> {
Expand All @@ -26,15 +25,15 @@ export default class EndpointProcessor {

readonly #createdFilePaths = new PathManager({ extension: 'ts' });
readonly #dependencies = new DependencyManager(new PathManager({ extension: '.js' }));
readonly #methods: Map<string, ReadonlyDeep<OpenAPIV3.PathItemObject>>;
readonly #methods: Map<string, OpenAPIV3.PathItemObject>;
readonly #name: string;
readonly #outputDir: string | undefined;
readonly #transferTypes: TransferTypes;
readonly #owner: Plugin;

private constructor(
name: string,
methods: Map<string, ReadonlyDeep<OpenAPIV3.PathItemObject>>,
methods: Map<string, OpenAPIV3.PathItemObject>,
storage: SharedStorage,
owner: Plugin,
) {
Expand All @@ -60,10 +59,7 @@ export default class EndpointProcessor {
);
}

async #processMethod(
method: string,
pathItem: ReadonlyDeep<OpenAPIV3.PathItemObject>,
): Promise<readonly Statement[]> {
async #processMethod(method: string, pathItem: OpenAPIV3.PathItemObject): Promise<readonly Statement[]> {
this.#owner.logger.debug(`Processing endpoint method: ${this.#name}.${method}`);

return (
Expand Down
5 changes: 2 additions & 3 deletions packages/ts/generator-plugin-backbone/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Plugin from '@vaadin/hilla-generator-core/Plugin.js';
import type { SharedStorage } from '@vaadin/hilla-generator-core/SharedStorage.js';
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import type { SourceFile } from 'typescript';
import EndpointProcessor from './EndpointProcessor.js';
import { EntityProcessor } from './EntityProcessor.js';
Expand Down Expand Up @@ -33,14 +32,14 @@ export default class BackbonePlugin extends Plugin {

async #processEndpoints(storage: SharedStorage): Promise<readonly SourceFile[]> {
this.logger.debug('Processing endpoints');
const endpoints = new Map<string, Map<string, ReadonlyDeep<OpenAPIV3.PathItemObject>>>();
const endpoints = new Map<string, Map<string, OpenAPIV3.PathItemObject>>();

Object.entries(storage.api.paths)
.filter(([, pathItem]) => !!pathItem)
.forEach(([path, pathItem]) => {
const [, endpointName, endpointMethodName] = path.split('/');

let methods: Map<string, ReadonlyDeep<OpenAPIV3.PathItemObject>>;
let methods: Map<string, OpenAPIV3.PathItemObject>;

if (endpoints.has(endpointName)) {
methods = endpoints.get(endpointName)!;
Expand Down
3 changes: 1 addition & 2 deletions packages/ts/generator-plugin-model/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Plugin from '@vaadin/hilla-generator-core/Plugin.js';
import type { SharedStorage } from '@vaadin/hilla-generator-core/SharedStorage.js';
import type { OpenAPIV3 } from 'openapi-types';
import type { ReadonlyDeep } from 'type-fest';
import type { SourceFile } from 'typescript';
import { EntityModelProcessor } from './EntityModelProcessor.js';
import type { Context } from './utils.js';
Expand All @@ -27,7 +26,7 @@ export default class ModelPlugin extends Plugin {
storage.pluginStorage.set(this.constructor.MODEL_PLUGIN_FILE_TAGS, this.#tags);
}

#processEntities(schemas: ReadonlyDeep<OpenAPIV3.ComponentsObject>['schemas'] | undefined): readonly SourceFile[] {
#processEntities(schemas: OpenAPIV3.ComponentsObject['schemas'] | undefined): readonly SourceFile[] {
this.logger.debug('Processing entities');

if (!schemas) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import ts, { type SourceFile } from 'typescript';
export class SubTypesProcessor {
readonly #typeName: string;
readonly #source: SourceFile;
readonly #oneOf: ReferenceSchema[];
readonly #dependencies;
readonly #oneOf: readonly ReferenceSchema[];
readonly #dependencies: DependencyManager;

constructor(typeName: string, source: SourceFile, oneOf: ReferenceSchema[]) {
constructor(typeName: string, source: SourceFile, oneOf: readonly ReferenceSchema[]) {
this.#typeName = typeName;
this.#source = source;
this.#oneOf = oneOf;
Expand Down
17 changes: 8 additions & 9 deletions packages/ts/generator-plugin-subtypes/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Plugin from '@vaadin/hilla-generator-core/Plugin.js';
import { convertFullyQualifiedNameToRelativePath } from '@vaadin/hilla-generator-core/Schema.js';
import { isReferenceSchema, convertFullyQualifiedNameToRelativePath } from '@vaadin/hilla-generator-core/Schema.js';
import type { SharedStorage } from '@vaadin/hilla-generator-core/SharedStorage.js';
import type { OpenAPIV3 } from 'openapi-types';
import { ModelFixProcessor } from './ModelFixProcessor.js';
import { SubTypesProcessor } from './SubTypesProcessor.js';
import { TypeFixProcessor } from './TypeFixProcessor.js';
Expand All @@ -25,19 +24,19 @@ export default class SubTypesPlugin extends Plugin {

Object.entries(components).forEach(([baseKey, baseComponent]) => {
// search for components with oneOf: those are union types
if ('oneOf' in baseComponent && Array.isArray(baseComponent.oneOf)) {
if (
'oneOf' in baseComponent &&
Array.isArray(baseComponent.oneOf) &&
baseComponent.oneOf.every((schema) => isReferenceSchema(schema))
) {
const fn = `${convertFullyQualifiedNameToRelativePath(baseKey)}.ts`;
const source = sources.find(({ fileName }) => fileName === fn)!;
// replace the (empty) source with a newly-generated one
const newSource = new SubTypesProcessor(
baseKey,
source,
baseComponent.oneOf as OpenAPIV3.ReferenceObject[],
).process();
const newSource = new SubTypesProcessor(baseKey, source, baseComponent.oneOf).process();
sources.splice(sources.indexOf(source), 1, newSource);

// mentioned types in the oneOf need to be fixed as well
(baseComponent.oneOf as OpenAPIV3.ReferenceObject[]).forEach((schema) => {
baseComponent.oneOf.forEach((schema) => {
if ('$ref' in schema) {
const path = schema.$ref;
Object.entries(components).forEach(([subKey, subComponent]) => {
Expand Down