Skip to content

Commit

Permalink
feat: render patternProperties for TS class and interface (#270)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni authored Jun 28, 2021
1 parent dc6971d commit bc5c24b
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 8 deletions.
9 changes: 9 additions & 0 deletions src/generators/typescript/TypeScriptRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ ${lines.map(line => ` * ${line}`).join('\n')}
content.push(additionalProperty);
}

if (this.model.patternProperties !== undefined) {
for (const [pattern, patternModel] of Object.entries(this.model.patternProperties)) {
const propertyName = getUniquePropertyName(this.model, `${pattern}${DefaultPropertyNames.patternProperties}`);
const renderedPatternProperty = await this.runPropertyPreset(propertyName, patternModel, PropertyType.patternProperties);
content.push(renderedPatternProperty);
}
}

return this.renderBlock(content);
}

Expand All @@ -118,6 +126,7 @@ ${lines.map(line => ` * ${line}`).join('\n')}
signature = this.renderTypeSignature(property, { isRequired: this.model.isRequired(propertyName) });
return `${name}${signature};`;
case PropertyType.additionalProperty:
case PropertyType.patternProperties:
signature = this.renderType(property);
return `${name}?: Map<String, ${signature}>;`;
default:
Expand Down
21 changes: 15 additions & 6 deletions src/generators/typescript/renderers/ClassRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ ${this.indent(this.renderBlock(content, 2))}
content.push(this.renderBlock([getter, setter]));
}

if (this.model.patternProperties !== undefined) {
for (const [pattern, patternModel] of Object.entries(this.model.patternProperties)) {
const propertyName = getUniquePropertyName(this.model, `${pattern}${DefaultPropertyNames.patternProperties}`);
const getter = await this.runGetterPreset(propertyName, patternModel, PropertyType.patternProperties);
const setter = await this.runSetterPreset(propertyName, patternModel, PropertyType.patternProperties);
content.push(this.renderBlock([getter, setter]));
}
}

return this.renderBlock(content, 2);
}

Expand Down Expand Up @@ -86,9 +95,9 @@ ${renderer.indent(renderer.renderBlock(assignments))}
let signature = '';
if (type === PropertyType.property) {
signature = renderer.renderTypeSignature(property, { orUndefined: !isRequired });
} else if (type === PropertyType.additionalProperty) {
const additionalPropertyType = renderer.renderType(property);
signature = `: Map<String, ${additionalPropertyType}> | undefined`;
} else if (type === PropertyType.additionalProperty || type === PropertyType.patternProperties) {
const mapType = renderer.renderType(property);
signature = `: Map<String, ${mapType}> | undefined`;
}
return `get ${propertyName}()${signature} { return this._${propertyName}; }`;
},
Expand All @@ -98,9 +107,9 @@ ${renderer.indent(renderer.renderBlock(assignments))}
let signature = '';
if (type === PropertyType.property) {
signature = renderer.renderTypeSignature(property, { orUndefined: !isRequired });
} else if (type === PropertyType.additionalProperty) {
const additionalPropertyType = renderer.renderType(property);
signature = `: Map<String, ${additionalPropertyType}> | undefined`;
} else if (type === PropertyType.additionalProperty || type === PropertyType.patternProperties) {
const mapType = renderer.renderType(property);
signature = `: Map<String, ${mapType}> | undefined`;
}
return `set ${propertyName}(${propertyName}${signature}) { this._${propertyName} = ${propertyName}; }`;
},
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/NameHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { CommonModel } from 'models';
* Default property names for different aspects of the common model
*/
export enum DefaultPropertyNames {
additionalProperties = 'additionalProperties'
additionalProperties = 'additionalProperties',
patternProperties = 'PatternProperties'
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/models/Preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export interface CommonPreset<R extends AbstractRenderer, O extends object = any

export enum PropertyType {
property,
additionalProperty
additionalProperty,
patternProperties
}
export interface PropertyArgs {
propertyName: string;
Expand Down
5 changes: 5 additions & 0 deletions test/blackbox/docs/dummy.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
"$ref": "#/definitions/dummyObject"
}
},
"patternProperties": {
"^S(.?*)pattern&": {
"type": "string"
}
},
"definitions": {
"dummyInfo": {
"type": "object",
Expand Down
15 changes: 15 additions & 0 deletions test/generators/typescript/TypeScriptGenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ describe('TypeScriptGenerator', () => {
tuple_type_with_additional_items: { type: 'array', items: [{ type: 'string' }, { type: 'number' }], additionalItems: true },
array_type: { type: 'array', items: { type: 'string' } },
},
patternProperties: {
'^S(.?*)test&': {
type: 'string'
}
},
required: ['street_name', 'city', 'state', 'house_number', 'array_type'],
};
const expected = `export class Address {
Expand All @@ -33,6 +38,7 @@ describe('TypeScriptGenerator', () => {
private _tupleTypeWithAdditionalItems?: [string, number, ...(object | string | number | Array<unknown> | boolean | null | number)[]];
private _arrayType: Array<string>;
private _additionalProperties?: Map<String, object | string | number | Array<unknown> | boolean | null | number>;
private _sTestPatternProperties?: Map<String, string>;
constructor(input: {
streetName: string,
Expand Down Expand Up @@ -85,6 +91,9 @@ describe('TypeScriptGenerator', () => {
get additionalProperties(): Map<String, object | string | number | Array<unknown> | boolean | null | number> | undefined { return this._additionalProperties; }
set additionalProperties(additionalProperties: Map<String, object | string | number | Array<unknown> | boolean | null | number> | undefined) { this._additionalProperties = additionalProperties; }
get sTestPatternProperties(): Map<String, string> | undefined { return this._sTestPatternProperties; }
set sTestPatternProperties(sTestPatternProperties: Map<String, string> | undefined) { this._sTestPatternProperties = sTestPatternProperties; }
}`;

const inputModel = await generator.process(doc);
Expand Down Expand Up @@ -160,6 +169,11 @@ ${content}`;
tuple_type_with_additional_items: { type: 'array', items: [{ type: 'string' }, { type: 'number' }], additionalItems: true },
array_type: { type: 'array', items: { type: 'string' } },
},
patternProperties: {
'^S(.?*)test&': {
type: 'string'
}
},
required: ['street_name', 'city', 'state', 'house_number', 'array_type'],
};
const expected = `export interface Address {
Expand All @@ -173,6 +187,7 @@ ${content}`;
tupleTypeWithAdditionalItems?: [string, number, ...(object | string | number | Array<unknown> | boolean | null | number)[]];
arrayType: Array<string>;
additionalProperties?: Map<String, object | string | number | Array<unknown> | boolean | null | number>;
sTestPatternProperties?: Map<String, string>;
}`;

const interfaceGenerator = new TypeScriptGenerator({modelType: 'interface'});
Expand Down

0 comments on commit bc5c24b

Please sign in to comment.