@f3liz/rescript-autogen-openapi 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,15 +32,62 @@ function escapeString(str) {
32
32
  }
33
33
 
34
34
  function escapeRegexPattern(str) {
35
- return escapeString((function(s) {
36
- return s.replace(/(\\*)(\/)/g, function(match, backslashes, slash) {
37
- if (backslashes.length % 2 === 0) {
38
- return backslashes + '\\\\' + slash;
39
- } else {
40
- return match;
35
+ return (function(s) {
36
+ return s.replace(/\[([^\]]+)\]/g, function(match) {
37
+ let content = match.slice(1, -1);
38
+ let chars = [];
39
+ let hyphenCount = 0;
40
+ let i = 0;
41
+
42
+ while (i < content.length) {
43
+ if (content[i] === '\\\\' && i + 1 < content.length) {
44
+ if (content[i + 1] === '-') {
45
+ // Escaped hyphen - count it and skip
46
+ hyphenCount++;
47
+ i += 2;
48
+ } else {
49
+ // Other escaped char - keep as is
50
+ chars.push(content[i]);
51
+ chars.push(content[i + 1]);
52
+ i += 2;
53
+ }
54
+ } else if (content[i] === '-' && i > 0 && i < content.length - 1) {
55
+ // Check if this hyphen is part of a valid range
56
+ let prevChar = chars[chars.length - 1];
57
+ let nextChar = content[i + 1];
58
+ // If previous char is a backslash, this can't be a range
59
+ if (chars.length >= 2 && chars[chars.length - 2] === '\\\\') {
60
+ // Previous was escaped, so this hyphen is literal
61
+ hyphenCount++;
62
+ i++;
63
+ } else if (nextChar === '\\\\') {
64
+ // Next is escape sequence, hyphen is literal
65
+ hyphenCount++;
66
+ i++;
67
+ } else if (prevChar && nextChar && prevChar.charCodeAt(0) < nextChar.charCodeAt(0)) {
68
+ // Valid range (e.g., a-z), keep the hyphen
69
+ chars.push('-');
70
+ i++;
71
+ } else {
72
+ // Invalid or ambiguous, move to end
73
+ hyphenCount++;
74
+ i++;
75
+ }
76
+ } else {
77
+ // Regular character or hyphen at start/end
78
+ chars.push(content[i]);
79
+ i++;
80
+ }
81
+ }
82
+
83
+ // Add collected hyphens at the end
84
+ let result = chars.join('');
85
+ if (hyphenCount > 0) {
86
+ result += '-'.repeat(hyphenCount);
41
87
  }
88
+ return '[' + result + ']';
42
89
  });
43
- })(str));
90
+ })(str);
44
91
  }
45
92
 
46
93
  function generateFileHeader(description) {
@@ -48,6 +95,7 @@ function generateFileHeader(description) {
48
95
  // Generated by @f3liz/rescript-autogen-openapi
49
96
  // DO NOT EDIT - This file is auto-generated
50
97
 
98
+ S.enableJson()
51
99
  `;
52
100
  }
53
101
 
@@ -50,7 +50,7 @@ function generateSchemaWithContext(ctx, depthOpt, extractedTypeMap, irType) {
50
50
  let s = applyConstraints("S.string", c.minLength, c.maxLength, v => v.toString());
51
51
  let p = c.pattern;
52
52
  if (p !== undefined) {
53
- return s + `->S.pattern(%re("/` + CodegenUtils.escapeRegexPattern(p) + `/"))`;
53
+ return s + `->S.pattern(/` + CodegenUtils.escapeRegexPattern(p) + `/)`;
54
54
  } else {
55
55
  return s;
56
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@f3liz/rescript-autogen-openapi",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Generate ReScript code with Sury schemas from OpenAPI 3.1 specs. Supports multiple forks with diff/merge capabilities.",
5
5
  "keywords": [
6
6
  "rescript",
@@ -48,21 +48,69 @@ let escapeString = (str: string): string =>
48
48
  ->String.replaceAll("\n", "\\n")->String.replaceAll("\r", "\\r")
49
49
  ->String.replaceAll("\t", "\\t")
50
50
 
51
- // Escape Regex Pattern (escape unescaped slashes, then escape string)
51
+ // Escape Regex Pattern for ReScript 12 regex literals
52
+ // With /.../ syntax, forward slashes don't need escaping inside character classes
53
+ // Only fix hyphen placement in character classes for clarity
52
54
  let escapeRegexPattern = (str: string): string => {
53
- let withEscapedSlashes = %raw(`
55
+ // Move escaped hyphens (\-) to the end of character classes for clarity
56
+ %raw(`
54
57
  function(s) {
55
- return s.replace(/(\\*)(\/)/g, function(match, backslashes, slash) {
56
- if (backslashes.length % 2 === 0) {
57
- return backslashes + '\\\\' + slash;
58
- } else {
59
- return match;
58
+ return s.replace(/\[([^\]]+)\]/g, function(match) {
59
+ let content = match.slice(1, -1);
60
+ let chars = [];
61
+ let hyphenCount = 0;
62
+ let i = 0;
63
+
64
+ while (i < content.length) {
65
+ if (content[i] === '\\\\' && i + 1 < content.length) {
66
+ if (content[i + 1] === '-') {
67
+ // Escaped hyphen - count it and skip
68
+ hyphenCount++;
69
+ i += 2;
70
+ } else {
71
+ // Other escaped char - keep as is
72
+ chars.push(content[i]);
73
+ chars.push(content[i + 1]);
74
+ i += 2;
75
+ }
76
+ } else if (content[i] === '-' && i > 0 && i < content.length - 1) {
77
+ // Check if this hyphen is part of a valid range
78
+ let prevChar = chars[chars.length - 1];
79
+ let nextChar = content[i + 1];
80
+ // If previous char is a backslash, this can't be a range
81
+ if (chars.length >= 2 && chars[chars.length - 2] === '\\\\') {
82
+ // Previous was escaped, so this hyphen is literal
83
+ hyphenCount++;
84
+ i++;
85
+ } else if (nextChar === '\\\\') {
86
+ // Next is escape sequence, hyphen is literal
87
+ hyphenCount++;
88
+ i++;
89
+ } else if (prevChar && nextChar && prevChar.charCodeAt(0) < nextChar.charCodeAt(0)) {
90
+ // Valid range (e.g., a-z), keep the hyphen
91
+ chars.push('-');
92
+ i++;
93
+ } else {
94
+ // Invalid or ambiguous, move to end
95
+ hyphenCount++;
96
+ i++;
97
+ }
98
+ } else {
99
+ // Regular character or hyphen at start/end
100
+ chars.push(content[i]);
101
+ i++;
102
+ }
60
103
  }
104
+
105
+ // Add collected hyphens at the end
106
+ let result = chars.join('');
107
+ if (hyphenCount > 0) {
108
+ result += '-'.repeat(hyphenCount);
109
+ }
110
+ return '[' + result + ']';
61
111
  });
62
112
  }
63
113
  `)(str)
64
-
65
- escapeString(withEscapedSlashes)
66
114
  }
67
115
 
68
116
  // Generate file header
@@ -71,6 +119,7 @@ let generateFileHeader = (~description: string): string =>
71
119
  // Generated by @f3liz/rescript-autogen-openapi
72
120
  // DO NOT EDIT - This file is auto-generated
73
121
 
122
+ S.enableJson()
74
123
  `
75
124
 
76
125
  // Indent code
@@ -42,7 +42,7 @@ let rec generateSchemaWithContext = (~ctx: GenerationContext.t, ~depth=0, ~extra
42
42
  | String({constraints: c}) =>
43
43
  let s = applyConstraints("S.string", c.minLength, c.maxLength, v => Int.toString(v))
44
44
  switch c.pattern {
45
- | Some(p) => `${s}->S.pattern(%re("/${CodegenUtils.escapeRegexPattern(p)}/"))`
45
+ | Some(p) => `${s}->S.pattern(/${CodegenUtils.escapeRegexPattern(p)}/)`
46
46
  | None => s
47
47
  }
48
48
  | Number({constraints: c}) =>