Skip to content

Commit a8f6448

Browse files
authored
Merge pull request #46 from nicolas-chaulet/fix/enum-const
fix(template): support printing exact arrays
2 parents e1d7700 + 62496a5 commit a8f6448

File tree

8 files changed

+250
-37
lines changed

8 files changed

+250
-37
lines changed

rollup.config.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const handlebarsPlugin = () => ({
3737
escapeDescription: true,
3838
escapeEnumName: true,
3939
escapeNewline: true,
40+
exactArray: true,
4041
ifdef: true,
4142
ifOperationDataOptional: true,
4243
intersection: true,

src/openApi/v3/parser/getModel.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,16 @@ export const getModel = (
9292
}
9393
}
9494

95-
const arrayItems = getModel(openApi, definition.items);
95+
/**
96+
* if items are a plain array, infer any-of composition
97+
* {@link} https://github.com/ferdikoomen/openapi-typescript-codegen/issues/2062
98+
*/
99+
const arrayItemsDefinition: OpenApiSchema = Array.isArray(definition.items)
100+
? {
101+
anyOf: definition.items,
102+
}
103+
: definition.items;
104+
const arrayItems = getModel(openApi, arrayItemsDefinition);
96105
model.base = arrayItems.base;
97106
model.export = 'array';
98107
model.imports.push(...arrayItems.imports);

src/templates/partials/typeArray.hbs

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
{{~#exactArray this}}
2+
[{{>type link filterProperties="exact"}}]{{>isNullable}}
3+
{{~else~}}
14
{{~#if link~}}
25
Array<{{>type link}}>{{>isNullable}}
36
{{~else~}}
47
Array<{{>base}}>{{>isNullable}}
58
{{~/if~}}
9+
{{~/exactArray~}}

src/templates/partials/typeUnion.hbs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#union properties parent}}{{this}}{{/union}}{{>isNullable}}
1+
{{#union properties parent filterProperties}}{{this}}{{/union}}{{>isNullable}}

src/utils/registerHandlebarHelpers.spec.ts renamed to src/utils/__tests__/registerHandlebarHelpers.spec.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Handlebars from 'handlebars/runtime';
22

3-
import { HttpClient } from '../HttpClient';
4-
import { registerHandlebarHelpers } from './registerHandlebarHelpers';
3+
import { HttpClient } from '../../HttpClient';
4+
import { registerHandlebarHelpers } from '../registerHandlebarHelpers';
55

66
describe('registerHandlebarHelpers', () => {
77
it('should register the helpers', () => {
@@ -20,6 +20,7 @@ describe('registerHandlebarHelpers', () => {
2020
expect(helpers).toContain('escapeDescription');
2121
expect(helpers).toContain('escapeEnumName');
2222
expect(helpers).toContain('escapeNewline');
23+
expect(helpers).toContain('exactArray');
2324
expect(helpers).toContain('ifdef');
2425
expect(helpers).toContain('ifOperationDataOptional');
2526
expect(helpers).toContain('intersection');

src/utils/registerHandlebarHelpers.ts

+21-7
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ export const registerHandlebarHelpers = (
8585
return value.replace(/\n/g, '\\n');
8686
});
8787

88+
Handlebars.registerHelper('exactArray', function (this: any, model: Model, options: Handlebars.HelperOptions) {
89+
if (model.export === 'array' && model.maxItems && model.minItems && model.maxItems === model.minItems) {
90+
return options.fn(this);
91+
}
92+
return options.inverse(this);
93+
});
94+
8895
Handlebars.registerHelper('ifdef', function (this: any, ...args): string {
8996
const options = args.pop();
9097
if (!args.every(value => !value)) {
@@ -127,15 +134,22 @@ export const registerHandlebarHelpers = (
127134

128135
Handlebars.registerHelper(
129136
'union',
130-
function (this: any, properties: Model[], parent: string | undefined, options: Handlebars.HelperOptions) {
137+
function (
138+
this: any,
139+
properties: Model[],
140+
parent: string | undefined,
141+
filterProperties: 'exact' | undefined,
142+
options: Handlebars.HelperOptions
143+
) {
131144
const type = Handlebars.partials['type'];
132-
const types = properties.map(property => type({ ...root, ...property, parent }));
133-
const uniqueTypes = types.filter(unique);
134-
let uniqueTypesString = uniqueTypes.join(' | ');
135-
if (uniqueTypes.length > 1) {
136-
uniqueTypesString = `(${uniqueTypesString})`;
145+
const types = properties
146+
.map(property => type({ ...root, ...property, parent }))
147+
.filter((...args) => filterProperties === 'exact' || unique(...args));
148+
let output = types.join(' | ');
149+
if (types.length > 1 && types.length !== properties.length) {
150+
output = `(${output})`;
137151
}
138-
return options.fn(uniqueTypesString);
152+
return options.fn(output);
139153
}
140154
);
141155

0 commit comments

Comments
 (0)