Skip to content

Commit

Permalink
chore: Adjust openapi generator for azure spec (#4953)
Browse files Browse the repository at this point in the history
* add schema prefix option

* Changes from lint:fix

* parse properties + required

* Changes from lint:fix

* fix test

* fix

* Changes from lint:fix

* array has type obj with allOf only

* Changes from lint:fix

* fixes

* lint fix + log

* fix message

* empty string for prefix

* clean up

* refactor + tests

* Changes from lint:fix

* Update packages/openapi-generator/src/generator.ts

* regenerate with different name

* review remarks

* add comments

* additionalprop

* Changes from lint:fix

---------

Co-authored-by: cloud-sdk-js <[email protected]>
Co-authored-by: Marika Marszalkowski <[email protected]>
  • Loading branch information
3 people authored Sep 16, 2024
1 parent fd0ff0a commit 37b0397
Show file tree
Hide file tree
Showing 24 changed files with 303 additions and 11 deletions.
4 changes: 3 additions & 1 deletion packages/openapi-generator/src/file-serializer/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export function serializeSchema(schema: OpenApiSchema): string {
const type = serializeSchema(schema.items);
return schema.uniqueItems
? `Set<${type}>`
: 'properties' in schema.items
: ['properties', 'allOf', 'oneOf', 'anyOf'].some(
prop => prop in schema.items
)
? `(${type})[]`
: `${type}[]`;
}
Expand Down
104 changes: 104 additions & 0 deletions packages/openapi-generator/src/parser/schema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,110 @@ describe('parseSchema', () => {
);
});

it('parses xOf schema ignoring type:object at same level', async () => {
const schema: OpenAPIV3.SchemaObject = {
type: 'object',
oneOf: [
{ type: 'object' },
{
anyOf: [
{ type: 'object' },
{ allOf: [{ type: 'object' }, { type: 'string' }] }
]
}
]
};
expect(parseSchema(schema, await createTestRefs(), defaultOptions)).toEqual(
{
oneOf: [
emptyObjectSchema,
{
anyOf: [
emptyObjectSchema,
{ allOf: [emptyObjectSchema, { type: 'string' }] }
]
}
]
}
);
});

it('normalizes xOf schemas with properties at same level', async () => {
const schema: OpenAPIV3.SchemaObject = {
type: 'object',
properties: { prop1: { type: 'string' } },
oneOf: [
{ type: 'object' },
{
allOf: [{ type: 'object' }, { type: 'string' }]
}
]
};
expect(parseSchema(schema, await createTestRefs(), defaultOptions)).toEqual(
{
oneOf: [
emptyObjectSchema,
{ allOf: [emptyObjectSchema, { type: 'string' }] },
{
additionalProperties: { type: 'any' },
properties: [
{
name: 'prop1',
description: undefined,
required: false,
schema: {
type: 'string'
},
schemaProperties: {}
}
]
}
]
}
);
});

it('parses xOf schemas with required', async () => {
const schema: OpenAPIV3.SchemaObject = {
oneOf: [
{ type: 'object' },
{
allOf: [
{ type: 'object', properties: { prop1: { type: 'string' } } },
{ type: 'string' }
],
required: ['prop1']
}
]
};
expect(parseSchema(schema, await createTestRefs(), defaultOptions)).toEqual(
{
oneOf: [
emptyObjectSchema,
{
allOf: [
{
additionalProperties: { type: 'any' },
properties: [
{
name: 'prop1',
description: undefined,
required: true,
schema: {
type: 'string'
},
schemaProperties: {}
}
]
},
{ type: 'string' }
]
}
]
}
);
});

it('parses not schema', async () => {
const schema: OpenAPIV3.SchemaObject = {
not: { type: 'object' }
Expand Down
51 changes: 42 additions & 9 deletions packages/openapi-generator/src/parser/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,6 @@ export function parseSchema(
return parseArraySchema(schema, refs, options);
}

if (
schema.type === 'object' ||
schema.properties ||
'additionalProperties' in schema
) {
return parseObjectSchema(schema, refs, options);
}

if (schema.enum?.length) {
return parseEnumSchema(schema, options);
}
Expand All @@ -66,6 +58,16 @@ export function parseSchema(
return parseXOfSchema(schema, refs, 'anyOf', options);
}

// An object schema should be parsed after allOf, anyOf, oneOf.
// When object.properties are at the same level with anyOf, oneOf, allOf, they should be treated as part of allOf, etc.
if (
schema.type === 'object' ||
schema.properties ||
schema.additionalProperties
) {
return parseObjectSchema(schema, refs, options);
}

if (schema.not) {
return {
not: parseSchema(schema.not, refs, options)
Expand Down Expand Up @@ -223,11 +225,42 @@ function parseXOfSchema(
xOf: 'oneOf' | 'allOf' | 'anyOf',
options: ParserOptions
): any {
const normalizedSchema = normalizeSchema(schema, xOf);

return {
[xOf]: (schema[xOf] || []).map(entry => parseSchema(entry, refs, options))
[xOf]: (normalizedSchema[xOf] || []).map(entry =>
parseSchema(
{
...entry,
required: [
// Add required properties from the entry.
...('required' in entry && entry.required ? entry.required : []),
// Add required properties from the top level schema (xOf).
...(normalizedSchema.required || [])
]
},
refs,
options
)
)
};
}

function normalizeSchema(
schema: OpenAPIV3.NonArraySchemaObject,
xOf: 'oneOf' | 'allOf' | 'anyOf'
): OpenAPIV3.NonArraySchemaObject {
if (schema.properties || schema.additionalProperties) {
logger.info(
`Detected schema with ${xOf} and properties in the same level. This was refactored to a schema with ${xOf} only, containing all the properties from the top level.`
);

const { [xOf]: xOfSchema = [], ...objectSchema } = schema;
return { [xOf]: [...xOfSchema, objectSchema] };
}
return schema;
}

/**
* Parse schema properties e.g. 'maxLength', 'minimum', etc.
* @param schema - Original schema representing a ref or schema object.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Composition of extended properties (inheritance) and schema-specific properties together with required attribute.
*/
export type EntityXOfInheritance = TestEntity & {
booleanProperty: boolean;
integerProperty2?: number;
} & Record<string, any>;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Composition of extended properties (inheritance) and schema-specific properties together with required attribute.
*/
export type EntityXOfInheritance = TestEntity & {
booleanProperty: boolean;
integerProperty2?: number;
} & Record<string, any>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Entity with xOf and schema properties at same level. This is normalized to only xOf with schema properties inside xOf. Also works if only additionalProperties true is used.
*/
export type EntityXOfNormalizedWithObject =
| TestEntity
| ({
booleanProperty: boolean;
} & Record<string, any>);

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Entity with xOf and schema properties at same level. This is normalized to only xOf with schema properties inside xOf. Also works if only additionalProperties true is used.
*/
export type EntityXOfNormalizedWithObject =
| TestEntity
| ({
booleanProperty: boolean;
} & Record<string, any>);
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
export * from './test-entity';
export * from './entity-x-of-inheritance';
export * from './entity-x-of-normalized-with-object';

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
export * from './test-entity';
export * from './entity-x-of-inheritance';
export * from './entity-x-of-normalized-with-object';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Representation of the 'TestEntity2' schema.
*/
export type TestEntity2 = TestEntity & {
booleanProperty: boolean;
integerProperty2?: number;
} & Record<string, any>;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Representation of the 'TestEntity2' schema.
*/
export type TestEntity2 = TestEntity & {
booleanProperty: boolean;
integerProperty2?: number;
} & Record<string, any>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Representation of the 'TestEntity3' schema.
*/
export type TestEntity3 =
| TestEntity
| ({
booleanProperty?: boolean;
} & Record<string, any>);

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved.
*
* This is a generated file powered by the SAP Cloud SDK for JavaScript.
*/
import type { TestEntity } from './test-entity';
/**
* Representation of the 'TestEntity3' schema.
*/
export type TestEntity3 =
| TestEntity
| ({
booleanProperty?: boolean;
} & Record<string, any>);
23 changes: 23 additions & 0 deletions test-resources/openapi-service-specs/swagger-yaml-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,26 @@ definitions:
type: integer
description: An integer property
required: false
EntityXOfInheritance:
type: object
description: Composition of extended properties (inheritance) and schema-specific properties together with required attribute.
allOf:
- $ref: '#/definitions/TestEntity'
- properties:
booleanProperty:
type: boolean
required: false
integerProperty2:
type: integer
required:
- booleanProperty
EntityXOfNormalizedWithObject:
type: object
description: Entity with xOf and schema properties at same level. This is normalized to only xOf with schema properties inside xOf. Also works if only additionalProperties true is used.
anyOf:
- $ref: '#/definitions/TestEntity'
properties:
booleanProperty:
type: boolean
required:
- booleanProperty

0 comments on commit 37b0397

Please sign in to comment.