forked from airbytehq/airbyte-platform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
orval.config.ts
106 lines (98 loc) · 4.01 KB
/
orval.config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import fs from "node:fs";
import path from "node:path";
import { defineConfig, Options } from "orval";
import * as apis from "./src/core/api/apis";
type ApiFn = keyof typeof apis;
/**
* A method returning a post processing hook that will generate the files that will reexport all types
* into src/core/api/types.
*/
const createTypeReexportFile = (name: string) => {
return () => {
console.log(`Write type re-export file for ${name}...`);
fs.writeFileSync(`./src/core/api/types/${name}.ts`, `export * from "../generated/${name}.schemas";\n`);
};
};
/**
* A post processing hook that will do all required transformation on the generated files.
*/
const postProcessFileContent = (files: string[]) => {
console.log(`Post process generated content in ${path.basename(files[0])}...`);
const newContent = fs
.readFileSync(files[0], { encoding: "utf-8" })
// Make the options parameter mandatory, so it can't be forgetten to be passed in
.replace(/options\?: SecondParameter/g, "options: SecondParameter")
// Turn optional parameters (e.g. GET with non required parameters) into a `| undefined` type instead
// so they can be before the now mandatory options parameters.
.replace(/\?: ([^,]+),((?:[\s\S][^)])*options: SecondParameter)/g, ": $1 | undefined,$2");
fs.writeFileSync(files[0], newContent);
};
/**
* Helper function to create an new auto generated API.
*
* @param inputSpecFile The path (relative to airbyte-webapp) to the OpenAPI spec from which to generate an API.
* @param name The name of the output file for this API.
* @param apiFn The API function in src/core/api/apis.ts to call for this API. This function must be specific
* for this API and use the base api path that this API is reachable under. You don't need to pass this
* for type only APIs (i.e. if you don't want to use the generated fetching functions).
* @param excludedPaths A list of API pathes to filter out, i.e. code won't be generated for pathes in this array.
*/
const createApi = (inputSpecFile: string, name: string, apiFn?: ApiFn, excludedPaths?: string[]): Options => {
return {
input: {
target: inputSpecFile,
override: {
transformer: (spec) => {
if (!excludedPaths) {
// If no API filter has been specified return the spec as it is.
return spec;
}
return {
...spec,
paths: Object.fromEntries(Object.entries(spec.paths).filter(([path]) => !excludedPaths.includes(path))),
};
},
},
},
output: {
mode: "split",
target: `./src/core/api/generated/${name}.ts`,
prettier: true,
override: {
header: (info) => [
`eslint-disable`,
`Generated by orval 🍺`,
`Do not edit manually. Run "pnpm run generate-client" instead.`,
...(info.title ? [info.title] : []),
...(info.description ? [info.description] : []),
...(info.version ? [`OpenAPI spec version: ${info.version}`] : []),
],
// Do only use the mutator if an `apiFn` to call has been specified.
...(apiFn
? {
mutator: {
path: "./src/core/api/apis.ts",
name: apiFn,
},
}
: {}),
},
},
hooks: {
afterAllFilesWrite: [postProcessFileContent, createTypeReexportFile(name)],
},
};
};
export default defineConfig({
api: createApi("../airbyte-api/src/main/openapi/config.yaml", "AirbyteClient", "apiCall", [
// Required to exclude, due to us not being able to convert JSON parameters
"/public/v1/oauth/callback",
]),
cloudApi: createApi("../airbyte-api/src/main/openapi/cloud-config.yaml", "CloudApi", "cloudApiCall"),
connectorBuilder: createApi(
"../airbyte-connector-builder-server/src/main/openapi/openapi.yaml",
"ConnectorBuilderClient",
"connectorBuilderApiCall"
),
connectorManifest: createApi("./src/services/connectorBuilder/connector_manifest_openapi.yaml", "ConnectorManifest"),
});