fork of hey-api/openapi-ts because I need some additional things

Merge pull request #2692 from hey-api/copilot/fix-4811abf9-2ebf-43bc-b1cd-2fde0f579207

authored by

Lubos and committed by
GitHub
bee26fe5 c8124d9f

+91 -2
+5
.changeset/lazy-ties-cross.md
··· 1 + --- 2 + "@hey-api/openapi-ts": patch 3 + --- 4 + 5 + fix(validators): escaping slashes in regular expressions
+76
packages/openapi-ts/src/tsc/__tests__/types.test.ts
··· 1 + import { describe, expect, it } from 'vitest'; 2 + 3 + import { createRegularExpressionLiteral } from '../types'; 4 + 5 + describe('createRegularExpressionLiteral', () => { 6 + it('should escape forward slashes in regex patterns', () => { 7 + const result = createRegularExpressionLiteral({ 8 + text: '^data:image/svg\\+xml;base64,[A-Za-z0-9+/]+=*$', 9 + }); 10 + 11 + expect(result.text).toBe( 12 + '/^data:image\\/svg\\+xml;base64,[A-Za-z0-9+\\/]+=*$/', 13 + ); 14 + }); 15 + 16 + it('should handle patterns without forward slashes', () => { 17 + const result = createRegularExpressionLiteral({ 18 + text: '^[a-zA-Z0-9_]*$', 19 + }); 20 + 21 + expect(result.text).toBe('/^[a-zA-Z0-9_]*$/'); 22 + }); 23 + 24 + it('should handle patterns that already have slashes at start and end', () => { 25 + const result = createRegularExpressionLiteral({ 26 + text: '/^[a-zA-Z0-9_]*$/', 27 + }); 28 + 29 + expect(result.text).toBe('/^[a-zA-Z0-9_]*$/'); 30 + }); 31 + 32 + it('should handle patterns with slashes at start/end and internal slashes', () => { 33 + const result = createRegularExpressionLiteral({ 34 + text: '/^data:image/svg\\+xml;base64,[A-Za-z0-9+/]+=*$/', 35 + }); 36 + 37 + expect(result.text).toBe( 38 + '/^data:image\\/svg\\+xml;base64,[A-Za-z0-9+\\/]+=*$/', 39 + ); 40 + }); 41 + 42 + it('should preserve flags', () => { 43 + const result = createRegularExpressionLiteral({ 44 + flags: ['g', 'i'], 45 + text: '^[a-zA-Z]*$', 46 + }); 47 + 48 + expect(result.text).toBe('/^[a-zA-Z]*$/gi'); 49 + }); 50 + 51 + it('should handle patterns with multiple forward slashes', () => { 52 + const result = createRegularExpressionLiteral({ 53 + text: '^path/to/file/name$', 54 + }); 55 + 56 + expect(result.text).toBe('/^path\\/to\\/file\\/name$/'); 57 + }); 58 + 59 + it('should handle empty pattern', () => { 60 + const result = createRegularExpressionLiteral({ 61 + text: '', 62 + }); 63 + 64 + expect(result.text).toBe('//'); 65 + }); 66 + 67 + it('should handle patterns with already correctly escaped slashes', () => { 68 + const result = createRegularExpressionLiteral({ 69 + text: '^data:image\\/svg\\+xml;base64,[A-Za-z0-9+\\/]+=*$', 70 + }); 71 + 72 + expect(result.text).toBe( 73 + '/^data:image\\/svg\\+xml;base64,[A-Za-z0-9+\\/]+=*$/', 74 + ); 75 + }); 76 + });
+10 -2
packages/openapi-ts/src/tsc/types.ts
··· 1080 1080 flags?: ReadonlyArray<'g' | 'i' | 'm' | 's' | 'u' | 'y'>; 1081 1081 text: string; 1082 1082 }) => { 1083 - const textWithSlashes = 1084 - text.startsWith('/') && text.endsWith('/') ? text : `/${text}/`; 1083 + // Extract pattern content, removing outer slashes if present 1084 + const patternContent = 1085 + text.startsWith('/') && text.endsWith('/') ? text.slice(1, -1) : text; 1086 + 1087 + // Escape forward slashes in the pattern content, but only if they're not already escaped 1088 + const escapedPattern = patternContent.replace(/(?<!\\)\//g, '\\/'); 1089 + 1090 + // Wrap with forward slashes 1091 + const textWithSlashes = `/${escapedPattern}/`; 1092 + 1085 1093 return ts.factory.createRegularExpressionLiteral( 1086 1094 `${textWithSlashes}${flags.join('')}`, 1087 1095 );