summary refs log tree commit diff
path: root/api/scripts/generate_openapi_schema.ts
blob: c0995b6cf5b5b2719f038583a040f925d297f589 (plain) (blame)
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
// https://mermade.github.io/openapi-gui/#
// https://editor.swagger.io/
import path from "path";
import fs from "fs";
import * as TJS from "typescript-json-schema";
import "missing-native-js-functions";

const settings: TJS.PartialArgs = {
	required: true,
	ignoreErrors: true,
	excludePrivate: true,
	defaultNumberType: "integer",
	noExtraProps: true,
	defaultProps: false
};
const compilerOptions: TJS.CompilerOptions = {
	strictNullChecks: false
};
const openapiPath = path.join(__dirname, "..", "assets", "openapi.json");
var specification = JSON.parse(fs.readFileSync(openapiPath, { encoding: "utf8" }));

async function utilSchemas() {
	const program = TJS.getProgramFromFiles([path.join(__dirname, "..", "..", "util", "src", "index.ts")], compilerOptions);
	const generator = TJS.buildGenerator(program, settings);

	const schemas = ["UserPublic", "UserPrivate", "PublicConnectedAccount"];

	// @ts-ignore
	combineSchemas({ schemas, generator, program });
}

function combineSchemas(opts: { program: TJS.Program; generator: TJS.JsonSchemaGenerator; schemas: string[] }) {
	var definitions: any = {};

	for (const name of opts.schemas) {
		const part = TJS.generateSchema(opts.program, name, settings, [], opts.generator as TJS.JsonSchemaGenerator);
		if (!part) continue;

		definitions = { ...definitions, [name]: { ...part, definitions: undefined, $schema: undefined } };
	}

	for (const key in definitions) {
		specification.components.schemas[key] = definitions[key];
		delete definitions[key].additionalProperties;
		delete definitions[key].$schema;
	}

	return definitions;
}

const ExcludedSchemas = [
	"DefaultSchema",
	"Schema",
	"EntitySchema",
	"ServerResponse",
	"Http2ServerResponse",
	"global.Express.Response",
	"Response",
	"e.Response",
	"request.Response",
	"supertest.Response"
];

function apiSchemas() {
	const program = TJS.getProgramFromFiles([path.join(__dirname, "..", "src", "schema", "index.ts")], compilerOptions);
	const generator = TJS.buildGenerator(program, settings);

	const schemas = generator
		.getUserSymbols()
		.filter((x) => x.endsWith("Response") && !ExcludedSchemas.includes(x))
		.concat(generator.getUserSymbols().filter((x) => x.endsWith("Schema") && !ExcludedSchemas.includes(x)));

	// @ts-ignore
	combineSchemas({ schemas, generator, program });
}

function addDefaultResponses() {
	Object.values(specification.paths).forEach((path: any) => Object.values(path).forEach((request: any) => {}));
}

function main() {
	addDefaultResponses();
	utilSchemas();
	apiSchemas();

	fs.writeFileSync(
		openapiPath,
		JSON.stringify(specification, null, 4).replaceAll("#/definitions", "#/components/schemas").replaceAll("bigint", "number")
	);
}

main();