@f3liz/rescript-autogen-openapi 0.1.0
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.
- package/LICENSE +339 -0
- package/README.md +98 -0
- package/lib/es6/src/Codegen.mjs +423 -0
- package/lib/es6/src/Types.mjs +20 -0
- package/lib/es6/src/core/CodegenUtils.mjs +186 -0
- package/lib/es6/src/core/DocOverride.mjs +399 -0
- package/lib/es6/src/core/FileSystem.mjs +78 -0
- package/lib/es6/src/core/IRBuilder.mjs +201 -0
- package/lib/es6/src/core/OpenAPIParser.mjs +168 -0
- package/lib/es6/src/core/Pipeline.mjs +150 -0
- package/lib/es6/src/core/ReferenceResolver.mjs +41 -0
- package/lib/es6/src/core/Result.mjs +378 -0
- package/lib/es6/src/core/SchemaIR.mjs +355 -0
- package/lib/es6/src/core/SchemaIRParser.mjs +490 -0
- package/lib/es6/src/core/SchemaRefResolver.mjs +146 -0
- package/lib/es6/src/core/SchemaRegistry.mjs +92 -0
- package/lib/es6/src/core/SpecDiffer.mjs +251 -0
- package/lib/es6/src/core/SpecMerger.mjs +237 -0
- package/lib/es6/src/generators/ComponentSchemaGenerator.mjs +125 -0
- package/lib/es6/src/generators/DiffReportGenerator.mjs +155 -0
- package/lib/es6/src/generators/EndpointGenerator.mjs +172 -0
- package/lib/es6/src/generators/IRToSuryGenerator.mjs +233 -0
- package/lib/es6/src/generators/IRToTypeGenerator.mjs +241 -0
- package/lib/es6/src/generators/IRToTypeScriptGenerator.mjs +143 -0
- package/lib/es6/src/generators/ModuleGenerator.mjs +285 -0
- package/lib/es6/src/generators/SchemaCodeGenerator.mjs +77 -0
- package/lib/es6/src/generators/ThinWrapperGenerator.mjs +97 -0
- package/lib/es6/src/generators/TypeScriptDtsGenerator.mjs +172 -0
- package/lib/es6/src/generators/TypeScriptWrapperGenerator.mjs +145 -0
- package/lib/es6/src/types/CodegenError.mjs +79 -0
- package/lib/es6/src/types/Config.mjs +42 -0
- package/lib/es6/src/types/GenerationContext.mjs +24 -0
- package/package.json +44 -0
- package/rescript.json +20 -0
- package/src/Codegen.res +222 -0
- package/src/Types.res +195 -0
- package/src/core/CodegenUtils.res +130 -0
- package/src/core/DocOverride.res +504 -0
- package/src/core/FileSystem.res +62 -0
- package/src/core/IRBuilder.res +66 -0
- package/src/core/OpenAPIParser.res +144 -0
- package/src/core/Pipeline.res +51 -0
- package/src/core/ReferenceResolver.res +41 -0
- package/src/core/Result.res +187 -0
- package/src/core/SchemaIR.res +258 -0
- package/src/core/SchemaIRParser.res +360 -0
- package/src/core/SchemaRefResolver.res +143 -0
- package/src/core/SchemaRegistry.res +107 -0
- package/src/core/SpecDiffer.res +270 -0
- package/src/core/SpecMerger.res +245 -0
- package/src/generators/ComponentSchemaGenerator.res +127 -0
- package/src/generators/DiffReportGenerator.res +152 -0
- package/src/generators/EndpointGenerator.res +172 -0
- package/src/generators/IRToSuryGenerator.res +199 -0
- package/src/generators/IRToTypeGenerator.res +199 -0
- package/src/generators/IRToTypeScriptGenerator.res +72 -0
- package/src/generators/ModuleGenerator.res +362 -0
- package/src/generators/SchemaCodeGenerator.res +83 -0
- package/src/generators/ThinWrapperGenerator.res +124 -0
- package/src/generators/TypeScriptDtsGenerator.res +193 -0
- package/src/generators/TypeScriptWrapperGenerator.res +166 -0
- package/src/types/CodegenError.res +82 -0
- package/src/types/Config.res +89 -0
- package/src/types/GenerationContext.res +23 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Fs from "fs";
|
|
4
|
+
import * as Text from "@std/text";
|
|
5
|
+
import * as Js_string from "@rescript/runtime/lib/es6/Js_string.js";
|
|
6
|
+
import * as FileSystem from "./FileSystem.mjs";
|
|
7
|
+
import * as CodegenUtils from "./CodegenUtils.mjs";
|
|
8
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
9
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
10
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
11
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
12
|
+
|
|
13
|
+
function generateEndpointHash(endpoint) {
|
|
14
|
+
let parts = [
|
|
15
|
+
endpoint.path,
|
|
16
|
+
endpoint.method,
|
|
17
|
+
Stdlib_Option.getOr(endpoint.operationId, ""),
|
|
18
|
+
Stdlib_Option.getOr(endpoint.summary, ""),
|
|
19
|
+
Stdlib_Option.getOr(endpoint.description, "")
|
|
20
|
+
];
|
|
21
|
+
let combined = parts.join("|");
|
|
22
|
+
return Stdlib_Array.reduce(combined.split(""), 0, (acc, char) => {
|
|
23
|
+
let code = Js_string.charCodeAt(0, char) | 0;
|
|
24
|
+
return (((acc << 5) - acc | 0) + code | 0) % 2147483647;
|
|
25
|
+
}).toString(16);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function extractCodeBlock(markdown) {
|
|
29
|
+
let parts = markdown.split("```");
|
|
30
|
+
if (parts.length < 3) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let content = parts[1];
|
|
34
|
+
if (content === undefined) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
let trimmed = content.trim();
|
|
38
|
+
if (trimmed === "" || trimmed === "<!-- Empty - no override -->") {
|
|
39
|
+
return;
|
|
40
|
+
} else {
|
|
41
|
+
return trimmed;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function parseOverrideMarkdown(content) {
|
|
46
|
+
let parts = content.split("---");
|
|
47
|
+
if (parts.length < 3) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let frontmatter = Stdlib_Option.getOr(parts[1], "");
|
|
51
|
+
let body = parts.slice(2, parts.length).join("---").trim();
|
|
52
|
+
let lines = frontmatter.split("\n").map(prim => prim.trim());
|
|
53
|
+
let metadata_endpoint = Stdlib_Option.getOr(Stdlib_Option.map(lines.find(l => l.startsWith("endpoint:")), l => {
|
|
54
|
+
let parts = l.split(":");
|
|
55
|
+
return parts.slice(1, parts.length).join(":").trim();
|
|
56
|
+
}), "");
|
|
57
|
+
let metadata_method = Stdlib_Option.getOr(Stdlib_Option.map(lines.find(l => l.startsWith("method:")), l => Stdlib_Option.getOr(l.split(":")[1], "").trim()), "");
|
|
58
|
+
let metadata_hash = Stdlib_Option.getOr(Stdlib_Option.map(lines.find(l => l.startsWith("hash:")), l => Stdlib_Option.getOr(l.split(":")[1], "").trim()), "");
|
|
59
|
+
let metadata_host = Stdlib_Option.flatMap(lines.find(l => l.startsWith("host:")), l => {
|
|
60
|
+
let parts = l.split(":");
|
|
61
|
+
return parts.slice(1, parts.length).join(":").trim();
|
|
62
|
+
});
|
|
63
|
+
let metadata_version = Stdlib_Option.flatMap(lines.find(l => l.startsWith("version:")), l => Stdlib_Option.map(l.split(":")[1], prim => prim.trim()));
|
|
64
|
+
let metadata_operationId = Stdlib_Option.flatMap(lines.find(l => l.startsWith("operationId:")), l => Stdlib_Option.map(l.split(":")[1], prim => prim.trim()));
|
|
65
|
+
let metadata = {
|
|
66
|
+
endpoint: metadata_endpoint,
|
|
67
|
+
method: metadata_method,
|
|
68
|
+
hash: metadata_hash,
|
|
69
|
+
host: metadata_host,
|
|
70
|
+
version: metadata_version,
|
|
71
|
+
operationId: metadata_operationId
|
|
72
|
+
};
|
|
73
|
+
let parts$1 = Stdlib_Option.getOr(body.split("## Override")[0], "").split("## Default Description");
|
|
74
|
+
let defaultDescSection = parts$1.slice(1, parts$1.length).join("## Default Description").trim();
|
|
75
|
+
let parts$2 = body.split("## Override");
|
|
76
|
+
let overrideSection = parts$2.slice(1, parts$2.length).join("## Override");
|
|
77
|
+
let overrideDesc = extractCodeBlock(overrideSection);
|
|
78
|
+
let hasOverride = Stdlib_Option.isSome(overrideDesc);
|
|
79
|
+
return {
|
|
80
|
+
metadata: metadata,
|
|
81
|
+
defaultDescription: defaultDescSection,
|
|
82
|
+
overrideDescription: overrideDesc,
|
|
83
|
+
hasOverride: hasOverride
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function generateOverrideMarkdown(endpoint, host, version, param) {
|
|
88
|
+
let hash = generateEndpointHash(endpoint);
|
|
89
|
+
let operationName = CodegenUtils.generateOperationName(endpoint.operationId, endpoint.path, endpoint.method);
|
|
90
|
+
let match = endpoint.summary;
|
|
91
|
+
let match$1 = endpoint.description;
|
|
92
|
+
let defaultDesc = match !== undefined ? (
|
|
93
|
+
match$1 !== undefined && match !== match$1 ? match + "\n\n" + match$1 : match
|
|
94
|
+
) : (
|
|
95
|
+
match$1 !== undefined ? match$1 : "No description provided."
|
|
96
|
+
);
|
|
97
|
+
let metadata = [
|
|
98
|
+
"---",
|
|
99
|
+
`endpoint: ` + endpoint.path,
|
|
100
|
+
`method: ` + endpoint.method.toUpperCase(),
|
|
101
|
+
`hash: ` + hash
|
|
102
|
+
].concat(Stdlib_Array.filterMap([
|
|
103
|
+
Stdlib_Option.map(host, h => `host: ` + h),
|
|
104
|
+
Stdlib_Option.map(version, v => `version: ` + v),
|
|
105
|
+
Stdlib_Option.map(endpoint.operationId, id => `operationId: ` + id),
|
|
106
|
+
"---"
|
|
107
|
+
], x => x));
|
|
108
|
+
let content = `
|
|
109
|
+
|` + metadata.join("\n") + `
|
|
110
|
+
|
|
|
111
|
+
|# ` + Stdlib_Option.getOr(endpoint.summary, endpoint.path) + `
|
|
112
|
+
|
|
|
113
|
+
|**Path**: \`` + endpoint.path + `\`
|
|
114
|
+
|**Method**: \`` + endpoint.method.toUpperCase() + `\`
|
|
115
|
+
|**Operation**: \`` + operationName + `\`
|
|
116
|
+
|
|
|
117
|
+
|## Default Description
|
|
118
|
+
|
|
|
119
|
+
|` + defaultDesc + `
|
|
120
|
+
|
|
|
121
|
+
|## Override
|
|
122
|
+
|
|
|
123
|
+
|Add your custom documentation here. If this code block is empty, the default description will be used.
|
|
124
|
+
|
|
|
125
|
+
|\`\`\`
|
|
126
|
+
|<!-- Empty - no override -->
|
|
127
|
+
|\`\`\`
|
|
128
|
+
|`;
|
|
129
|
+
return CodegenUtils.trimMargin(content, undefined);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function validateOverride(override, currentHash) {
|
|
133
|
+
if (override.metadata.hash === currentHash) {
|
|
134
|
+
return "Valid";
|
|
135
|
+
} else {
|
|
136
|
+
return {
|
|
137
|
+
TAG: "HashMismatch",
|
|
138
|
+
expected: currentHash,
|
|
139
|
+
found: override.metadata.hash
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function readOverrideWithValidation(overrideDir, moduleName, functionName, currentHash) {
|
|
145
|
+
let filePath = FileSystem.makePath(FileSystem.makePath(overrideDir, moduleName), functionName + ".md");
|
|
146
|
+
if (!Fs.existsSync(filePath)) {
|
|
147
|
+
return "NoOverride";
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
let content = Fs.readFileSync(filePath, {
|
|
151
|
+
encoding: "utf8"
|
|
152
|
+
});
|
|
153
|
+
let parsed = parseOverrideMarkdown(content);
|
|
154
|
+
if (parsed === undefined) {
|
|
155
|
+
return {
|
|
156
|
+
TAG: "FileError",
|
|
157
|
+
_0: "Failed to parse markdown file"
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (!parsed.hasOverride) {
|
|
161
|
+
return "NoOverride";
|
|
162
|
+
}
|
|
163
|
+
let msg = validateOverride(parsed, currentHash);
|
|
164
|
+
if (typeof msg !== "object") {
|
|
165
|
+
if (msg !== "Valid") {
|
|
166
|
+
return {
|
|
167
|
+
TAG: "FileError",
|
|
168
|
+
_0: "Override file missing"
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
let desc = parsed.overrideDescription;
|
|
172
|
+
if (desc !== undefined) {
|
|
173
|
+
return {
|
|
174
|
+
TAG: "ValidOverride",
|
|
175
|
+
_0: desc
|
|
176
|
+
};
|
|
177
|
+
} else {
|
|
178
|
+
return "NoOverride";
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
if (msg.TAG !== "HashMismatch") {
|
|
182
|
+
return {
|
|
183
|
+
TAG: "FileError",
|
|
184
|
+
_0: msg._0
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
let desc$1 = parsed.overrideDescription;
|
|
188
|
+
if (desc$1 !== undefined) {
|
|
189
|
+
return {
|
|
190
|
+
TAG: "InvalidHash",
|
|
191
|
+
override: desc$1,
|
|
192
|
+
expected: msg.expected,
|
|
193
|
+
found: msg.found
|
|
194
|
+
};
|
|
195
|
+
} else {
|
|
196
|
+
return "NoOverride";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
} catch (raw_err) {
|
|
200
|
+
let err = Primitive_exceptions.internalToException(raw_err);
|
|
201
|
+
if (err.RE_EXN_ID === "JsExn") {
|
|
202
|
+
return {
|
|
203
|
+
TAG: "FileError",
|
|
204
|
+
_0: Stdlib_Option.getOr(Stdlib_JsExn.message(err._1), "Unknown error")
|
|
205
|
+
};
|
|
206
|
+
} else {
|
|
207
|
+
return {
|
|
208
|
+
TAG: "FileError",
|
|
209
|
+
_0: "Unknown error reading file"
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function readOverride(overrideDir, moduleName, functionName) {
|
|
216
|
+
let filePath = FileSystem.makePath(FileSystem.makePath(overrideDir, moduleName), functionName + ".md");
|
|
217
|
+
if (!Fs.existsSync(filePath)) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
let content = Fs.readFileSync(filePath, {
|
|
222
|
+
encoding: "utf8"
|
|
223
|
+
});
|
|
224
|
+
let parsed = parseOverrideMarkdown(content);
|
|
225
|
+
if (parsed !== undefined) {
|
|
226
|
+
return parsed.overrideDescription;
|
|
227
|
+
} else {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
} catch (exn) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function isFileCustomized(filePath) {
|
|
236
|
+
if (!Fs.existsSync(filePath)) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
let content = Fs.readFileSync(filePath, {
|
|
241
|
+
encoding: "utf8"
|
|
242
|
+
});
|
|
243
|
+
let parsed = parseOverrideMarkdown(content);
|
|
244
|
+
if (parsed !== undefined) {
|
|
245
|
+
return parsed.hasOverride;
|
|
246
|
+
} else {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
} catch (exn) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function generateOverrideFiles(spec, endpoints, outputDir, host, groupByTagOpt, param) {
|
|
255
|
+
let groupByTag = groupByTagOpt !== undefined ? groupByTagOpt : true;
|
|
256
|
+
let version = spec.info.version;
|
|
257
|
+
let hostUrl = host !== undefined ? host : spec.info.description;
|
|
258
|
+
return Stdlib_Array.keepSome(endpoints.map(endpoint => {
|
|
259
|
+
let moduleName;
|
|
260
|
+
if (groupByTag) {
|
|
261
|
+
let tags = endpoint.tags;
|
|
262
|
+
moduleName = tags !== undefined ? Stdlib_Option.getOr(tags[0], "Default") : "Default";
|
|
263
|
+
} else {
|
|
264
|
+
moduleName = "API";
|
|
265
|
+
}
|
|
266
|
+
let functionName = CodegenUtils.generateOperationName(endpoint.operationId, endpoint.path, endpoint.method);
|
|
267
|
+
let modulePath = FileSystem.makePath(outputDir, Text.toPascalCase(moduleName));
|
|
268
|
+
let filePath = FileSystem.makePath(modulePath, functionName + ".md");
|
|
269
|
+
if (isFileCustomized(filePath)) {
|
|
270
|
+
console.log(`ℹ️ Skipping ` + moduleName + `/` + functionName + ` - file already customized`);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
let content = generateOverrideMarkdown(endpoint, hostUrl, version, undefined);
|
|
274
|
+
return {
|
|
275
|
+
path: filePath,
|
|
276
|
+
content: content
|
|
277
|
+
};
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function generateOverrideReadme(host, version, param) {
|
|
282
|
+
let hostInfo = Stdlib_Option.getOr(host, "Not specified");
|
|
283
|
+
let versionInfo = Stdlib_Option.getOr(version, "Not specified");
|
|
284
|
+
return CodegenUtils.trimMargin(`
|
|
285
|
+
|# API Documentation Overrides
|
|
286
|
+
|
|
|
287
|
+
|This directory contains markdown files that allow you to override the auto-generated documentation.
|
|
288
|
+
|
|
|
289
|
+
|## Global Information
|
|
290
|
+
|
|
|
291
|
+
|- **Host**: ` + hostInfo + `
|
|
292
|
+
|- **Version**: ` + versionInfo + `
|
|
293
|
+
|
|
|
294
|
+
|## Structure
|
|
295
|
+
|
|
|
296
|
+
|Each module has its own directory, and each endpoint has its own markdown file:
|
|
297
|
+
|
|
|
298
|
+
|\`\`\`
|
|
299
|
+
|docs/
|
|
300
|
+
|├── README.md (this file)
|
|
301
|
+
|├── Account/
|
|
302
|
+
|│ ├── postBlockingCreate.md
|
|
303
|
+
|│ ├── postBlockingDelete.md
|
|
304
|
+
|│ └── ...
|
|
305
|
+
|├── Notes/
|
|
306
|
+
|│ ├── postNotesCreate.md
|
|
307
|
+
|│ └── ...
|
|
308
|
+
|└── ...
|
|
309
|
+
|\`\`\`
|
|
310
|
+
|
|
|
311
|
+
|## How to Override
|
|
312
|
+
|
|
|
313
|
+
|1. Find the endpoint you want to document in its module directory
|
|
314
|
+
|2. Open the markdown file
|
|
315
|
+
|3. Edit the code block under the "## Override" section
|
|
316
|
+
|4. Add your custom documentation (supports markdown)
|
|
317
|
+
|5. Regenerate the code - your custom documentation will be used instead of the default
|
|
318
|
+
|
|
|
319
|
+
|## File Format
|
|
320
|
+
|
|
|
321
|
+
|Each file contains:
|
|
322
|
+
|
|
|
323
|
+
|### Frontmatter
|
|
324
|
+
|- \`endpoint\`: The API endpoint path
|
|
325
|
+
|- \`method\`: HTTP method (GET, POST, etc.)
|
|
326
|
+
|- \`hash\`: Hash of the endpoint for change detection
|
|
327
|
+
|- \`host\`: API host URL
|
|
328
|
+
|- \`version\`: API version
|
|
329
|
+
|- \`operationId\`: OpenAPI operation ID
|
|
330
|
+
|
|
|
331
|
+
|### Default Description
|
|
332
|
+
|The original description from the OpenAPI spec.
|
|
333
|
+
|
|
|
334
|
+
|### Override Section
|
|
335
|
+
|A code block where you can add your custom documentation. If empty, the default description is used.
|
|
336
|
+
|
|
|
337
|
+
|## Example
|
|
338
|
+
|
|
|
339
|
+
|\`\`\`markdown
|
|
340
|
+
|---
|
|
341
|
+
|endpoint: /blocking/create
|
|
342
|
+
|method: POST
|
|
343
|
+
|hash: abc123
|
|
344
|
+
|host: https://misskey.io
|
|
345
|
+
|version: 1.0.0
|
|
346
|
+
|---
|
|
347
|
+
|
|
|
348
|
+
|# blocking/create
|
|
349
|
+
|
|
|
350
|
+
|**Path**: \`/blocking/create\`
|
|
351
|
+
|**Method**: \`POST\`
|
|
352
|
+
|
|
|
353
|
+
|## Default Description
|
|
354
|
+
|
|
|
355
|
+
|No description provided.
|
|
356
|
+
|
|
|
357
|
+
|**Credential required**: *Yes* / **Permission**: *write:blocks*
|
|
358
|
+
|
|
|
359
|
+
|## Override
|
|
360
|
+
|
|
|
361
|
+
|\`\`\`
|
|
362
|
+
|Create a blocking relationship with another user.
|
|
363
|
+
|
|
|
364
|
+
|This endpoint allows you to block a user by their user ID. Once blocked:
|
|
365
|
+
|- The user will not be able to see your posts
|
|
366
|
+
|- You will not see their posts in your timeline
|
|
367
|
+
|- They cannot follow you
|
|
368
|
+
|
|
|
369
|
+
|**Parameters:**
|
|
370
|
+
|- \`userId\`: The ID of the user to block
|
|
371
|
+
|
|
|
372
|
+
|**Example:**
|
|
373
|
+
|\`\`\`typescript
|
|
374
|
+
|await client.blocking.create({ userId: "user123" })
|
|
375
|
+
|\`\`\`
|
|
376
|
+
|\`\`\`
|
|
377
|
+
|\`\`\`
|
|
378
|
+
|
|
|
379
|
+
|## Notes
|
|
380
|
+
|
|
|
381
|
+
|- The hash is used to detect if the endpoint has changed in the OpenAPI spec
|
|
382
|
+
|- If the endpoint changes, you may need to update your override
|
|
383
|
+
|- Empty override blocks (with just \`<!-- Empty - no override -->\`) are ignored
|
|
384
|
+
|`, undefined);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export {
|
|
388
|
+
generateEndpointHash,
|
|
389
|
+
extractCodeBlock,
|
|
390
|
+
parseOverrideMarkdown,
|
|
391
|
+
generateOverrideMarkdown,
|
|
392
|
+
validateOverride,
|
|
393
|
+
readOverrideWithValidation,
|
|
394
|
+
readOverride,
|
|
395
|
+
isFileCustomized,
|
|
396
|
+
generateOverrideFiles,
|
|
397
|
+
generateOverrideReadme,
|
|
398
|
+
}
|
|
399
|
+
/* fs Not a pure module */
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Fs from "fs";
|
|
4
|
+
import * as Path from "@std/path";
|
|
5
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
6
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
8
|
+
|
|
9
|
+
function ensureDir(path) {
|
|
10
|
+
try {
|
|
11
|
+
Fs.mkdirSync(Path.dirname(path), {
|
|
12
|
+
recursive: true
|
|
13
|
+
});
|
|
14
|
+
return;
|
|
15
|
+
} catch (exn) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function writeFile(file) {
|
|
21
|
+
try {
|
|
22
|
+
ensureDir(file.path);
|
|
23
|
+
Fs.writeFileSync(file.path, file.content, "utf8");
|
|
24
|
+
return {
|
|
25
|
+
TAG: "Ok",
|
|
26
|
+
_0: undefined
|
|
27
|
+
};
|
|
28
|
+
} catch (raw_exn) {
|
|
29
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
30
|
+
if (exn.RE_EXN_ID !== "JsExn") {
|
|
31
|
+
return {
|
|
32
|
+
TAG: "Error",
|
|
33
|
+
_0: `Failed to write file ` + file.path + `: Unknown error`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let message = Stdlib_Option.getOr(Stdlib_JsExn.message(exn._1), "Unknown error");
|
|
37
|
+
return {
|
|
38
|
+
TAG: "Error",
|
|
39
|
+
_0: `Failed to write file ` + file.path + `: ` + message
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function writeFiles(files) {
|
|
45
|
+
let successes = [];
|
|
46
|
+
let errors = [];
|
|
47
|
+
files.forEach(file => {
|
|
48
|
+
let err = writeFile(file);
|
|
49
|
+
if (err.TAG === "Ok") {
|
|
50
|
+
successes.push(file.path);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
errors.push(err._0);
|
|
54
|
+
});
|
|
55
|
+
if (errors.length !== 0) {
|
|
56
|
+
return {
|
|
57
|
+
TAG: "Error",
|
|
58
|
+
_0: errors
|
|
59
|
+
};
|
|
60
|
+
} else {
|
|
61
|
+
return {
|
|
62
|
+
TAG: "Ok",
|
|
63
|
+
_0: successes
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function makePath(baseDir, filename) {
|
|
69
|
+
return Path.join(baseDir, filename);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
ensureDir,
|
|
74
|
+
writeFile,
|
|
75
|
+
writeFiles,
|
|
76
|
+
makePath,
|
|
77
|
+
}
|
|
78
|
+
/* fs Not a pure module */
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function string(min, max, pattern, param) {
|
|
5
|
+
return {
|
|
6
|
+
minLength: min,
|
|
7
|
+
maxLength: max,
|
|
8
|
+
pattern: pattern
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function number(min, max, multipleOf, param) {
|
|
13
|
+
return {
|
|
14
|
+
minimum: min,
|
|
15
|
+
maximum: max,
|
|
16
|
+
multipleOf: multipleOf
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function array(min, max, uniqueOpt, param) {
|
|
21
|
+
let unique = uniqueOpt !== undefined ? uniqueOpt : false;
|
|
22
|
+
return {
|
|
23
|
+
minItems: min,
|
|
24
|
+
maxItems: max,
|
|
25
|
+
uniqueItems: unique
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let Constraints = {
|
|
30
|
+
string: string,
|
|
31
|
+
number: number,
|
|
32
|
+
array: array
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function string$1(min, max, pattern, param) {
|
|
36
|
+
return {
|
|
37
|
+
TAG: "String",
|
|
38
|
+
constraints: {
|
|
39
|
+
minLength: min,
|
|
40
|
+
maxLength: max,
|
|
41
|
+
pattern: pattern
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function number$1(min, max, multipleOf, param) {
|
|
47
|
+
return {
|
|
48
|
+
TAG: "Number",
|
|
49
|
+
constraints: {
|
|
50
|
+
minimum: min,
|
|
51
|
+
maximum: max,
|
|
52
|
+
multipleOf: multipleOf
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function int(min, max, multipleOf, param) {
|
|
58
|
+
return {
|
|
59
|
+
TAG: "Integer",
|
|
60
|
+
constraints: {
|
|
61
|
+
minimum: min,
|
|
62
|
+
maximum: max,
|
|
63
|
+
multipleOf: multipleOf
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function array$1(items, min, max, uniqueOpt, param) {
|
|
69
|
+
let unique = uniqueOpt !== undefined ? uniqueOpt : false;
|
|
70
|
+
return {
|
|
71
|
+
TAG: "Array",
|
|
72
|
+
items: items,
|
|
73
|
+
constraints: array(min, max, unique, undefined)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function object_(props, additional, param) {
|
|
78
|
+
return {
|
|
79
|
+
TAG: "Object",
|
|
80
|
+
properties: props,
|
|
81
|
+
additionalProperties: additional
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function union(types) {
|
|
86
|
+
return {
|
|
87
|
+
TAG: "Union",
|
|
88
|
+
_0: types
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function intersection(types) {
|
|
93
|
+
return {
|
|
94
|
+
TAG: "Intersection",
|
|
95
|
+
_0: types
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function ref(refPath) {
|
|
100
|
+
return {
|
|
101
|
+
TAG: "Reference",
|
|
102
|
+
_0: refPath
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function option(type_) {
|
|
107
|
+
return {
|
|
108
|
+
TAG: "Option",
|
|
109
|
+
_0: type_
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function stringLit(s) {
|
|
114
|
+
return {
|
|
115
|
+
TAG: "Literal",
|
|
116
|
+
_0: {
|
|
117
|
+
TAG: "StringLiteral",
|
|
118
|
+
_0: s
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function numberLit(n) {
|
|
124
|
+
return {
|
|
125
|
+
TAG: "Literal",
|
|
126
|
+
_0: {
|
|
127
|
+
TAG: "NumberLiteral",
|
|
128
|
+
_0: n
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function boolLit(b) {
|
|
134
|
+
return {
|
|
135
|
+
TAG: "Literal",
|
|
136
|
+
_0: {
|
|
137
|
+
TAG: "BooleanLiteral",
|
|
138
|
+
_0: b
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function prop(name, type_, requiredOpt, param) {
|
|
144
|
+
let required = requiredOpt !== undefined ? requiredOpt : true;
|
|
145
|
+
return [
|
|
146
|
+
name,
|
|
147
|
+
type_,
|
|
148
|
+
required
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function optProp(name, type_) {
|
|
153
|
+
return [
|
|
154
|
+
name,
|
|
155
|
+
type_,
|
|
156
|
+
false
|
|
157
|
+
];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function named(name, description, type_) {
|
|
161
|
+
return {
|
|
162
|
+
name: name,
|
|
163
|
+
description: description,
|
|
164
|
+
type_: type_
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let bool = "Boolean";
|
|
169
|
+
|
|
170
|
+
let $$null = "Null";
|
|
171
|
+
|
|
172
|
+
let unknown = "Unknown";
|
|
173
|
+
|
|
174
|
+
let nullLit = {
|
|
175
|
+
TAG: "Literal",
|
|
176
|
+
_0: "NullLiteral"
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export {
|
|
180
|
+
Constraints,
|
|
181
|
+
string$1 as string,
|
|
182
|
+
number$1 as number,
|
|
183
|
+
int,
|
|
184
|
+
bool,
|
|
185
|
+
$$null,
|
|
186
|
+
unknown,
|
|
187
|
+
array$1 as array,
|
|
188
|
+
object_,
|
|
189
|
+
union,
|
|
190
|
+
intersection,
|
|
191
|
+
ref,
|
|
192
|
+
option,
|
|
193
|
+
stringLit,
|
|
194
|
+
numberLit,
|
|
195
|
+
boolLit,
|
|
196
|
+
nullLit,
|
|
197
|
+
prop,
|
|
198
|
+
optProp,
|
|
199
|
+
named,
|
|
200
|
+
}
|
|
201
|
+
/* No side effect */
|