mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
Escaping regexp pattern properly
This commit is contained in:
parent
97f8204028
commit
be5161a7c5
@ -7,6 +7,7 @@ import { getComment } from './getComment';
|
||||
import { getEnum } from './getEnum';
|
||||
import { getEnumFromDescription } from './getEnumFromDescription';
|
||||
import { getModelProperties } from './getModelProperties';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefinition: boolean = false, name: string = ''): Model {
|
||||
@ -30,12 +31,12 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
|
||||
multipleOf: definition.multipleOf,
|
||||
maxLength: definition.maxLength,
|
||||
minLength: definition.minLength,
|
||||
pattern: definition.pattern,
|
||||
maxItems: definition.maxItems,
|
||||
minItems: definition.minItems,
|
||||
uniqueItems: definition.uniqueItems,
|
||||
maxProperties: definition.maxProperties,
|
||||
minProperties: definition.minProperties,
|
||||
pattern: getPattern(definition.pattern),
|
||||
imports: [],
|
||||
extends: [],
|
||||
enum: [],
|
||||
|
||||
@ -3,6 +3,7 @@ import type { OpenApi } from '../interfaces/OpenApi';
|
||||
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
import { escapeName } from './escapeName';
|
||||
import { getComment } from './getComment';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
// Fix for circular dependency between getModel and getModelProperties
|
||||
@ -36,12 +37,12 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
|
||||
multipleOf: property.multipleOf,
|
||||
maxLength: property.maxLength,
|
||||
minLength: property.minLength,
|
||||
pattern: property.pattern,
|
||||
maxItems: property.maxItems,
|
||||
minItems: property.minItems,
|
||||
uniqueItems: property.uniqueItems,
|
||||
maxProperties: property.maxProperties,
|
||||
minProperties: property.minProperties,
|
||||
pattern: getPattern(property.pattern),
|
||||
imports: model.imports,
|
||||
extends: [],
|
||||
enum: [],
|
||||
@ -70,12 +71,12 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
|
||||
multipleOf: property.multipleOf,
|
||||
maxLength: property.maxLength,
|
||||
minLength: property.minLength,
|
||||
pattern: property.pattern,
|
||||
maxItems: property.maxItems,
|
||||
minItems: property.minItems,
|
||||
uniqueItems: property.uniqueItems,
|
||||
maxProperties: property.maxProperties,
|
||||
minProperties: property.minProperties,
|
||||
pattern: getPattern(property.pattern),
|
||||
imports: model.imports,
|
||||
extends: model.extends,
|
||||
enum: model.enum,
|
||||
|
||||
@ -9,6 +9,7 @@ import { getEnumFromDescription } from './getEnumFromDescription';
|
||||
import { getModel } from './getModel';
|
||||
import { getOperationParameterDefault } from './getOperationParameterDefault';
|
||||
import { getOperationParameterName } from './getOperationParameterName';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParameter): OperationParameter {
|
||||
@ -34,10 +35,10 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
|
||||
multipleOf: parameter.multipleOf,
|
||||
maxLength: parameter.maxLength,
|
||||
minLength: parameter.minLength,
|
||||
pattern: parameter.pattern,
|
||||
maxItems: parameter.maxItems,
|
||||
minItems: parameter.minItems,
|
||||
uniqueItems: parameter.uniqueItems,
|
||||
pattern: getPattern(parameter.pattern),
|
||||
imports: [],
|
||||
extends: [],
|
||||
enum: [],
|
||||
|
||||
@ -4,6 +4,7 @@ import type { OpenApiResponse } from '../interfaces/OpenApiResponse';
|
||||
import { PrimaryType } from './constants';
|
||||
import { getComment } from './getComment';
|
||||
import { getModel } from './getModel';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse, responseCode: number): OperationResponse {
|
||||
@ -73,12 +74,12 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
|
||||
operationResponse.multipleOf = model.multipleOf;
|
||||
operationResponse.maxLength = model.maxLength;
|
||||
operationResponse.minLength = model.minLength;
|
||||
operationResponse.pattern = model.pattern;
|
||||
operationResponse.maxItems = model.maxItems;
|
||||
operationResponse.minItems = model.minItems;
|
||||
operationResponse.uniqueItems = model.uniqueItems;
|
||||
operationResponse.maxProperties = model.maxProperties;
|
||||
operationResponse.minProperties = model.minProperties;
|
||||
operationResponse.pattern = getPattern(model.pattern);
|
||||
operationResponse.imports.push(...model.imports);
|
||||
operationResponse.extends.push(...model.extends);
|
||||
operationResponse.enum.push(...model.enum);
|
||||
|
||||
14
src/openApi/v2/parser/getPattern.spec.ts
Normal file
14
src/openApi/v2/parser/getPattern.spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { getPattern } from './getPattern';
|
||||
|
||||
describe('getPattern', () => {
|
||||
it('should produce correct result', () => {
|
||||
expect(getPattern()).toEqual(undefined);
|
||||
expect(getPattern('')).toEqual('');
|
||||
expect(getPattern('^[a-zA-Z]')).toEqual('^[a-zA-Z]');
|
||||
expect(getPattern('^\\w+$')).toEqual('^\\\\w+$');
|
||||
expect(getPattern('^\\d{3}-\\d{2}-\\d{4}$')).toEqual('^\\\\d{3}-\\\\d{2}-\\\\d{4}$');
|
||||
expect(getPattern('\\')).toEqual('\\\\');
|
||||
expect(getPattern('\\/')).toEqual('\\\\/');
|
||||
expect(getPattern('\\/\\/')).toEqual('\\\\/\\\\/');
|
||||
});
|
||||
});
|
||||
10
src/openApi/v2/parser/getPattern.ts
Normal file
10
src/openApi/v2/parser/getPattern.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* The spec generates a pattern like this '^\d{3}-\d{2}-\d{4}$'
|
||||
* However, to use it in HTML or inside new RegExp() we need to
|
||||
* escape the pattern to become: '^\\d{3}-\\d{2}-\\d{4}$' in order
|
||||
* to make it a valid regexp string.
|
||||
* @param pattern
|
||||
*/
|
||||
export function getPattern(pattern?: string): string | undefined {
|
||||
return pattern?.replace(/\\/g, '\\\\');
|
||||
}
|
||||
@ -8,6 +8,7 @@ import { getEnum } from './getEnum';
|
||||
import { getEnumFromDescription } from './getEnumFromDescription';
|
||||
import { getModelDefault } from './getModelDefault';
|
||||
import { getModelProperties } from './getModelProperties';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefinition: boolean = false, name: string = ''): Model {
|
||||
@ -31,12 +32,12 @@ export function getModel(openApi: OpenApi, definition: OpenApiSchema, isDefiniti
|
||||
multipleOf: definition.multipleOf,
|
||||
maxLength: definition.maxLength,
|
||||
minLength: definition.minLength,
|
||||
pattern: definition.pattern,
|
||||
maxItems: definition.maxItems,
|
||||
minItems: definition.minItems,
|
||||
uniqueItems: definition.uniqueItems,
|
||||
maxProperties: definition.maxProperties,
|
||||
minProperties: definition.minProperties,
|
||||
pattern: getPattern(definition.pattern),
|
||||
imports: [],
|
||||
extends: [],
|
||||
enum: [],
|
||||
|
||||
@ -3,6 +3,7 @@ import type { OpenApi } from '../interfaces/OpenApi';
|
||||
import type { OpenApiSchema } from '../interfaces/OpenApiSchema';
|
||||
import { escapeName } from './escapeName';
|
||||
import { getComment } from './getComment';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
// Fix for circular dependency between getModel and getModelProperties
|
||||
@ -36,12 +37,12 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
|
||||
multipleOf: property.multipleOf,
|
||||
maxLength: property.maxLength,
|
||||
minLength: property.minLength,
|
||||
pattern: property.pattern,
|
||||
maxItems: property.maxItems,
|
||||
minItems: property.minItems,
|
||||
uniqueItems: property.uniqueItems,
|
||||
maxProperties: property.maxProperties,
|
||||
minProperties: property.minProperties,
|
||||
pattern: getPattern(property.pattern),
|
||||
imports: model.imports,
|
||||
extends: [],
|
||||
enum: [],
|
||||
@ -70,12 +71,12 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
|
||||
multipleOf: property.multipleOf,
|
||||
maxLength: property.maxLength,
|
||||
minLength: property.minLength,
|
||||
pattern: property.pattern,
|
||||
maxItems: property.maxItems,
|
||||
minItems: property.minItems,
|
||||
uniqueItems: property.uniqueItems,
|
||||
maxProperties: property.maxProperties,
|
||||
minProperties: property.minProperties,
|
||||
pattern: getPattern(property.pattern),
|
||||
imports: model.imports,
|
||||
extends: model.extends,
|
||||
enum: model.enum,
|
||||
|
||||
@ -6,6 +6,7 @@ import { getComment } from './getComment';
|
||||
import { getModel } from './getModel';
|
||||
import { getModelDefault } from './getModelDefault';
|
||||
import { getOperationParameterName } from './getOperationParameterName';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParameter): OperationParameter {
|
||||
@ -68,12 +69,12 @@ export function getOperationParameter(openApi: OpenApi, parameter: OpenApiParame
|
||||
operationParameter.multipleOf = model.multipleOf;
|
||||
operationParameter.maxLength = model.maxLength;
|
||||
operationParameter.minLength = model.minLength;
|
||||
operationParameter.pattern = model.pattern;
|
||||
operationParameter.maxItems = model.maxItems;
|
||||
operationParameter.minItems = model.minItems;
|
||||
operationParameter.uniqueItems = model.uniqueItems;
|
||||
operationParameter.maxProperties = model.maxProperties;
|
||||
operationParameter.minProperties = model.minProperties;
|
||||
operationParameter.pattern = getPattern(model.pattern);
|
||||
operationParameter.default = model.default;
|
||||
operationParameter.imports.push(...model.imports);
|
||||
operationParameter.extends.push(...model.extends);
|
||||
|
||||
@ -5,6 +5,7 @@ import { PrimaryType } from './constants';
|
||||
import { getComment } from './getComment';
|
||||
import { getContent } from './getContent';
|
||||
import { getModel } from './getModel';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationRequestBody(openApi: OpenApi, parameter: OpenApiRequestBody): OperationParameter {
|
||||
@ -59,12 +60,12 @@ export function getOperationRequestBody(openApi: OpenApi, parameter: OpenApiRequ
|
||||
requestBody.multipleOf = model.multipleOf;
|
||||
requestBody.maxLength = model.maxLength;
|
||||
requestBody.minLength = model.minLength;
|
||||
requestBody.pattern = model.pattern;
|
||||
requestBody.maxItems = model.maxItems;
|
||||
requestBody.minItems = model.minItems;
|
||||
requestBody.uniqueItems = model.uniqueItems;
|
||||
requestBody.maxProperties = model.maxProperties;
|
||||
requestBody.minProperties = model.minProperties;
|
||||
requestBody.pattern = getPattern(model.pattern);
|
||||
requestBody.imports.push(...model.imports);
|
||||
requestBody.extends.push(...model.extends);
|
||||
requestBody.enum.push(...model.enum);
|
||||
|
||||
@ -5,6 +5,7 @@ import { PrimaryType } from './constants';
|
||||
import { getComment } from './getComment';
|
||||
import { getContent } from './getContent';
|
||||
import { getModel } from './getModel';
|
||||
import { getPattern } from './getPattern';
|
||||
import { getType } from './getType';
|
||||
|
||||
export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse, responseCode: number): OperationResponse {
|
||||
@ -72,12 +73,12 @@ export function getOperationResponse(openApi: OpenApi, response: OpenApiResponse
|
||||
operationResponse.multipleOf = model.multipleOf;
|
||||
operationResponse.maxLength = model.maxLength;
|
||||
operationResponse.minLength = model.minLength;
|
||||
operationResponse.pattern = model.pattern;
|
||||
operationResponse.maxItems = model.maxItems;
|
||||
operationResponse.minItems = model.minItems;
|
||||
operationResponse.uniqueItems = model.uniqueItems;
|
||||
operationResponse.maxProperties = model.maxProperties;
|
||||
operationResponse.minProperties = model.minProperties;
|
||||
operationResponse.pattern = getPattern(model.pattern);
|
||||
operationResponse.imports.push(...model.imports);
|
||||
operationResponse.extends.push(...model.extends);
|
||||
operationResponse.enum.push(...model.enum);
|
||||
|
||||
14
src/openApi/v3/parser/getPattern.spec.ts
Normal file
14
src/openApi/v3/parser/getPattern.spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { getPattern } from './getPattern';
|
||||
|
||||
describe('getPattern', () => {
|
||||
it('should produce correct result', () => {
|
||||
expect(getPattern()).toEqual(undefined);
|
||||
expect(getPattern('')).toEqual('');
|
||||
expect(getPattern('^[a-zA-Z]')).toEqual('^[a-zA-Z]');
|
||||
expect(getPattern('^\\w+$')).toEqual('^\\\\w+$');
|
||||
expect(getPattern('^\\d{3}-\\d{2}-\\d{4}$')).toEqual('^\\\\d{3}-\\\\d{2}-\\\\d{4}$');
|
||||
expect(getPattern('\\')).toEqual('\\\\');
|
||||
expect(getPattern('\\/')).toEqual('\\\\/');
|
||||
expect(getPattern('\\/\\/')).toEqual('\\\\/\\\\/');
|
||||
});
|
||||
});
|
||||
10
src/openApi/v3/parser/getPattern.ts
Normal file
10
src/openApi/v3/parser/getPattern.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* The spec generates a pattern like this '^\d{3}-\d{2}-\d{4}$'
|
||||
* However, to use it in HTML or inside new RegExp() we need to
|
||||
* escape the pattern to become: '^\\d{3}-\\d{2}-\\d{4}$' in order
|
||||
* to make it a valid regexp string.
|
||||
* @param pattern
|
||||
*/
|
||||
export function getPattern(pattern?: string): string | undefined {
|
||||
return pattern?.replace(/\\/g, '\\\\');
|
||||
}
|
||||
@ -36,7 +36,7 @@
|
||||
minLength: {{{minLength}}},
|
||||
{{/if}}
|
||||
{{#if pattern}}
|
||||
pattern: /{{{pattern}}}/,
|
||||
pattern: '{{{pattern}}}',
|
||||
{{/if}}
|
||||
{{#if maxItems}}
|
||||
maxItems: {{{maxItems}}},
|
||||
|
||||
@ -883,6 +883,8 @@ export interface ModelWithPattern {
|
||||
name: string;
|
||||
readonly enabled?: boolean;
|
||||
readonly modified?: string;
|
||||
id?: string;
|
||||
text?: string;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -1525,7 +1527,7 @@ export const $ModelWithPattern = {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
maxLength: 64,
|
||||
pattern: /^[a-zA-Z0-9_]*$/,
|
||||
pattern: '^[a-zA-Z0-9_]*$',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
@ -1541,6 +1543,14 @@ export const $ModelWithPattern = {
|
||||
isReadOnly: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
pattern: '^\\\\\\\\d{2}-\\\\\\\\d{3}-\\\\\\\\d{4}$',
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
pattern: '^\\\\\\\\w+$',
|
||||
},
|
||||
},
|
||||
};"
|
||||
`;
|
||||
@ -1671,7 +1681,7 @@ exports[`v2 should generate: ./test/generated/v2/schemas/$SimpleStringWithPatter
|
||||
export const $SimpleStringWithPattern = {
|
||||
type: 'string',
|
||||
maxLength: 64,
|
||||
pattern: /^[a-zA-Z0-9_]*$/,
|
||||
pattern: '^[a-zA-Z0-9_]*$',
|
||||
};"
|
||||
`;
|
||||
|
||||
@ -3105,6 +3115,8 @@ export interface ModelWithPattern {
|
||||
name: string;
|
||||
readonly enabled?: boolean;
|
||||
readonly modified?: string;
|
||||
id?: string;
|
||||
text?: string;
|
||||
}
|
||||
"
|
||||
`;
|
||||
@ -3758,7 +3770,7 @@ export const $ModelWithPattern = {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
maxLength: 64,
|
||||
pattern: /^[a-zA-Z0-9_]*$/,
|
||||
pattern: '^[a-zA-Z0-9_]*$',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
@ -3774,6 +3786,14 @@ export const $ModelWithPattern = {
|
||||
isReadOnly: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
pattern: '^\\\\\\\\d{2}-\\\\\\\\d{3}-\\\\\\\\d{4}$',
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
pattern: '^\\\\\\\\w+$',
|
||||
},
|
||||
},
|
||||
};"
|
||||
`;
|
||||
@ -3910,7 +3930,7 @@ export const $SimpleStringWithPattern = {
|
||||
type: 'string',
|
||||
isNullable: true,
|
||||
maxLength: 64,
|
||||
pattern: /^[a-zA-Z0-9_]*$/,
|
||||
pattern: '^[a-zA-Z0-9_]*$',
|
||||
};"
|
||||
`;
|
||||
|
||||
|
||||
@ -1234,6 +1234,14 @@
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"readOnly": true
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^\\d{2}-\\d{3}-\\d{4}$"
|
||||
},
|
||||
"text": {
|
||||
"type": "string",
|
||||
"pattern": "^\\w+$"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1751,6 +1751,14 @@
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"readOnly": true
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^\\d{2}-\\d{3}-\\d{4}$"
|
||||
},
|
||||
"text": {
|
||||
"type": "string",
|
||||
"pattern": "^\\w+$"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user