Skip to content

Commit

Permalink
feat(templates): support printing Date instead of string for date-tim…
Browse files Browse the repository at this point in the history
…e formats in models
  • Loading branch information
mrlubos committed Mar 1, 2024
1 parent a3fa57f commit 66f6e7e
Show file tree
Hide file tree
Showing 17 changed files with 331 additions and 178 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ $ openapi --help
--postfixServices Service name postfix (default: "Service")
--postfixModels Model name postfix
--request <value> Path to custom request file
--useDateType <value> Output Date instead of string for the format "date-time" in the models (default: false)
--useOperationId <value> Use operation id to generate operation names (default: true)
-h, --help display help for command
Examples
Expand Down
2 changes: 2 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const params = program
.option('--exportSchemas <value>', 'Write schemas to disk', false)
.option('--indent <value>', 'Indentation options [4, 2, tab]', '4')
.option('--postfixServices <value>', 'Service name postfix', 'Service')
.option('--useDateType <value>', 'Output Date instead of string for the format "date-time" in the models', false)
.option('--useOperationId <value>', 'Use operation id to generate operation names', true)
.option('--postfixModels <value>', 'Model name postfix')
.option('--request <value>', 'Path to custom request file')
Expand Down Expand Up @@ -54,6 +55,7 @@ if (OpenAPI) {
postfixModels: params.postfixModels,
postfixServices: params.postfixServices,
request: params.request,
useDateType: JSON.parse(params.useDateType) === true,
useOperationId: JSON.parse(params.useOperationId) === true,
useOptions: params.useOptions,
useUnionTypes: params.useUnionTypes,
Expand Down
1 change: 1 addition & 0 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const handlebarsPlugin = () => ({
intersection: true,
notEquals: true,
union: true,
useDateType: true,
},
});
return `export default ${templateSpec};`;
Expand Down
2 changes: 1 addition & 1 deletion samples/spec/v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@
}
},
"X-Expires-After": {
"description": "date in UTC when toekn expires",
"description": "date in UTC when token expires",
"schema": {
"type": "string",
"format": "date-time"
Expand Down
1 change: 1 addition & 0 deletions src/client/interfaces/Options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface Options {
postfixModels?: string;
postfixServices?: string;
request?: string;
useDateType?: boolean;
useOperationId?: boolean;
useOptions?: boolean;
useUnionTypes?: boolean;
Expand Down
54 changes: 28 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export { Indent } from './Indent';
* @param exportServices Generate services
* @param exportModels Generate models
* @param exportSchemas Generate schemas
* @param useDateType Output Date instead of string for the format "date-time" in the models
* @param useOperationId should the operationId be used when generating operation names
* @param indent Indentation options (4, 2 or tab)
* @param postfixServices Service name postfix
Expand All @@ -37,16 +38,17 @@ export { Indent } from './Indent';
*/
export const generate = async (options: Options): Promise<void> => {
const {
httpClient = HttpClient.FETCH,
useOptions = false,
useUnionTypes = false,
exportCore = true,
exportServices = true,
exportModels = true,
exportSchemas = false,
exportServices = true,
httpClient = HttpClient.FETCH,
indent = Indent.SPACE_4,
postfixServices = 'Service',
postfixModels = '',
postfixServices = 'Service',
useDateType = false,
useOptions = false,
useUnionTypes = false,
write = true,
} = options;
const openApi = isString(options.input) ? await getOpenApiSpec(options.input) : options.input;
Expand All @@ -71,27 +73,27 @@ export const generate = async (options: Options): Promise<void> => {
}
}

if (parser) {
const client = parser(openApi, options);
const clientFinal = postProcessClient(client);
if (write) {
await writeClient(
clientFinal,
templates,
options.output,
httpClient,
useOptions,
useUnionTypes,
exportCore,
exportServices,
exportModels,
exportSchemas,
indent,
postfixServices,
postfixModels,
options
);
}
if (!parser) {
return;
}

const client = parser(openApi, options);
const clientFinal = postProcessClient(client);
if (write) {
await writeClient(clientFinal, templates, {
...options,
exportCore,
exportModels,
exportSchemas,
exportServices,
httpClient,
indent,
postfixModels,
postfixServices,
useDateType,
useOptions,
useUnionTypes,
});
}
};

Expand Down
4 changes: 4 additions & 0 deletions src/templates/partials/base.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
{{~#equals @root.httpClient 'angular'}}Blob{{/equals~}}
{{~#equals @root.httpClient 'node'}}Blob{{/equals~}}
{{~else~}}
{{~#useDateType @root.useDateType format~}}
Date
{{~else~}}
{{{base}}}
{{~/useDateType~}}
{{~/equals~}}
1 change: 1 addition & 0 deletions src/utils/registerHandlebarHelpers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ describe('registerHandlebarHelpers', () => {
expect(helpers).toContain('intersection');
expect(helpers).toContain('notEquals');
expect(helpers).toContain('union');
expect(helpers).toContain('useDateType');
});
});
116 changes: 64 additions & 52 deletions src/utils/registerHandlebarHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,63 +28,17 @@ export const registerHandlebarHelpers = (root: {
useOptions: boolean;
useUnionTypes: boolean;
}): void => {
Handlebars.registerHelper('ifdef', function (this: any, ...args): string {
const options = args.pop();
if (!args.every(value => !value)) {
return options.fn(this);
}
return options.inverse(this);
Handlebars.registerHelper('camelCase', function (value: string): string {
return camelCase(value);
});

Handlebars.registerHelper(
'equals',
function (this: any, a: string, b: string, options: Handlebars.HelperOptions): string {
return a === b ? options.fn(this) : options.inverse(this);
}
);

Handlebars.registerHelper(
'notEquals',
function (this: any, a: string, b: string, options: Handlebars.HelperOptions): string {
return a !== b ? options.fn(this) : options.inverse(this);
}
);

Handlebars.registerHelper(
'containsSpaces',
function (this: any, value: string, options: Handlebars.HelperOptions): string {
return /\s+/.test(value) ? options.fn(this) : options.inverse(this);
}
);

Handlebars.registerHelper(
'union',
function (this: any, properties: Model[], parent: string | undefined, options: Handlebars.HelperOptions) {
const type = Handlebars.partials['type'];
const types = properties.map(property => type({ ...root, ...property, parent }));
const uniqueTypes = types.filter(unique);
let uniqueTypesString = uniqueTypes.join(' | ');
if (uniqueTypes.length > 1) {
uniqueTypesString = `(${uniqueTypesString})`;
}
return options.fn(uniqueTypesString);
}
);

Handlebars.registerHelper(
'intersection',
function (this: any, properties: Model[], parent: string | undefined, options: Handlebars.HelperOptions) {
const type = Handlebars.partials['type'];
const types = properties.map(property => type({ ...root, ...property, parent }));
const uniqueTypes = types.filter(unique);
let uniqueTypesString = uniqueTypes.join(' & ');
if (uniqueTypes.length > 1) {
uniqueTypesString = `(${uniqueTypesString})`;
}
return options.fn(uniqueTypesString);
}
);

Handlebars.registerHelper(
'enumerator',
function (
Expand All @@ -106,6 +60,13 @@ export const registerHandlebarHelpers = (root: {
}
);

Handlebars.registerHelper(
'equals',
function (this: any, a: string, b: string, options: Handlebars.HelperOptions): string {
return a === b ? options.fn(this) : options.inverse(this);
}
);

Handlebars.registerHelper('escapeComment', function (value: string): string {
return value
.replace(/\*\//g, '*')
Expand All @@ -121,11 +82,62 @@ export const registerHandlebarHelpers = (root: {
return escapeEnumName(name);
});

Handlebars.registerHelper('camelCase', function (value: string): string {
return camelCase(value);
});

Handlebars.registerHelper('escapeNewline', function (value: string): string {
return value.replace(/\n/g, '\\n');
});

Handlebars.registerHelper('ifdef', function (this: any, ...args): string {
const options = args.pop();
if (!args.every(value => !value)) {
return options.fn(this);
}
return options.inverse(this);
});

Handlebars.registerHelper(
'intersection',
function (this: any, properties: Model[], parent: string | undefined, options: Handlebars.HelperOptions) {
const type = Handlebars.partials['type'];
const types = properties.map(property => type({ ...root, ...property, parent }));
const uniqueTypes = types.filter(unique);
let uniqueTypesString = uniqueTypes.join(' & ');
if (uniqueTypes.length > 1) {
uniqueTypesString = `(${uniqueTypesString})`;
}
return options.fn(uniqueTypesString);
}
);

Handlebars.registerHelper(
'notEquals',
function (this: any, a: string, b: string, options: Handlebars.HelperOptions): string {
return a !== b ? options.fn(this) : options.inverse(this);
}
);

Handlebars.registerHelper(
'union',
function (this: any, properties: Model[], parent: string | undefined, options: Handlebars.HelperOptions) {
const type = Handlebars.partials['type'];
const types = properties.map(property => type({ ...root, ...property, parent }));
const uniqueTypes = types.filter(unique);
let uniqueTypesString = uniqueTypes.join(' | ');
if (uniqueTypes.length > 1) {
uniqueTypesString = `(${uniqueTypesString})`;
}
return options.fn(uniqueTypesString);
}
);

Handlebars.registerHelper(
'useDateType',
function (
this: any,
useDateType: boolean | undefined,
format: string | undefined,
options: Handlebars.HelperOptions
) {
return useDateType && format === 'date-time' ? options.fn(this) : options.inverse(this);
}
);
};
34 changes: 15 additions & 19 deletions src/utils/writeClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,21 @@ describe('writeClient', () => {
},
};

await writeClient(
client,
templates,
'./dist',
HttpClient.FETCH,
false,
false,
true,
true,
true,
true,
Indent.SPACE_4,
'Service',
'AppClient',
{
input: '',
output: '',
}
);
await writeClient(client, templates, {
exportCore: true,
exportModels: true,
exportSchemas: true,
exportServices: true,
indent: Indent.SPACE_4,
input: '',
output: './dist',
httpClient: HttpClient.FETCH,
postfixModels: 'AppClient',
postfixServices: 'Service',
useDateType: false,
useOptions: false,
useUnionTypes: false,
});

expect(rmdir).toBeCalled();
expect(mkdir).toBeCalled();
Expand Down
Loading

0 comments on commit 66f6e7e

Please sign in to comment.