mirror of
https://github.com/stoatchat/javascript-client-api.git
synced 2026-07-20 01:25:03 -04:00
chore: use bigint parse/stringify
chore: move cli generator into this repo
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env bash
|
||||
":"; //# comment; exec /usr/bin/env node --input-type=module - "$@" < "$0"
|
||||
|
||||
import { readFile, writeFile } from "fs/promises";
|
||||
import openapi from "openapi-typescript";
|
||||
// import { resolve } from "path";
|
||||
// import { cwd } from "process";
|
||||
|
||||
const NOTICE = `// This file was auto-generated by @insertish/oapi!\n`;
|
||||
|
||||
readFile("OpenAPI.json").then((data) => {
|
||||
// Load and patch anything we need to
|
||||
let source = data.toString();
|
||||
|
||||
if (process.env.REWRITE_ANYOF) {
|
||||
source = source.replace(/"anyOf"/g, '"oneOf"');
|
||||
}
|
||||
|
||||
// Parse spec
|
||||
const spec = JSON.parse(source);
|
||||
|
||||
// Copy index.ts
|
||||
// readFile(
|
||||
// resolve(cwd(), "node_modules", "@insertish", "oapi", "src", "index.ts")
|
||||
// ).then((data) => writeFile("src/index.ts", data));
|
||||
|
||||
// Generate Schema
|
||||
openapi(spec).then((data) => writeFile("src/schema.ts", data));
|
||||
|
||||
// Route Types + Data
|
||||
{
|
||||
const entries = [
|
||||
"import { paths } from './schema';",
|
||||
"export type APIRoutes =",
|
||||
];
|
||||
const paths = Object.keys(spec.paths);
|
||||
const queryData = {};
|
||||
|
||||
for (const path of paths) {
|
||||
const data = spec.paths[path];
|
||||
const methods = Object.keys(data);
|
||||
|
||||
let template = path.replace(/\{\w+\}/g, "${string}");
|
||||
|
||||
for (const method of methods) {
|
||||
const OPERATION = `paths['${path}']['${method}']`;
|
||||
|
||||
const route = data[method];
|
||||
const response =
|
||||
Object.keys(route["responses"]).find((x) => x !== "default") ||
|
||||
"default";
|
||||
const contentType = Object.keys(
|
||||
route["responses"][response]["content"] || {}
|
||||
)[0];
|
||||
const RESPONSE =
|
||||
response === "204" || !contentType
|
||||
? "undefined"
|
||||
: `${OPERATION}['responses']['${response}']['content']['${contentType}']`;
|
||||
|
||||
let queryParams = [];
|
||||
let hasBody = false;
|
||||
|
||||
if (route["parameters"]) {
|
||||
for (const parameter of route["parameters"]) {
|
||||
if (parameter.in === "query") {
|
||||
queryParams.push(parameter.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (route["requestBody"]?.["content"]?.["application/json"]) {
|
||||
hasBody = true;
|
||||
}
|
||||
|
||||
let params = "undefined";
|
||||
if (hasBody || queryParams.length > 0) {
|
||||
let entries = [];
|
||||
|
||||
if (queryParams.length > 0) {
|
||||
entries.push(`${OPERATION}['parameters']['query']`);
|
||||
}
|
||||
|
||||
if (hasBody) {
|
||||
entries.push(
|
||||
`${OPERATION}['requestBody']['content']['application/json']`
|
||||
);
|
||||
}
|
||||
|
||||
params = entries.join("|");
|
||||
}
|
||||
|
||||
const parts = path.split("").filter((x) => x === "/").length;
|
||||
entries.push(
|
||||
`| { method: '${method}', path: \`${template}\`, parts: ${parts}, params: ${params}, response: ${RESPONSE} }`
|
||||
);
|
||||
|
||||
if (/\{\w+\}/.test(path)) {
|
||||
entries.push(
|
||||
`| { method: '${method}', path: '-${path}', parts: ${parts}, params: ${params}, response: ${RESPONSE} }`
|
||||
);
|
||||
}
|
||||
|
||||
queryData[path] = {
|
||||
...queryData[path],
|
||||
[method]: queryParams,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const pathResolve = {};
|
||||
for (const path of paths) {
|
||||
const segments = path.split("/");
|
||||
segments.shift();
|
||||
pathResolve[segments.length] = [
|
||||
...(pathResolve[segments.length] || []),
|
||||
segments.map((key) => (/\{.*\}/.test(key) ? [key] : key)),
|
||||
];
|
||||
}
|
||||
|
||||
writeFile("src/routes.ts", NOTICE + entries.join("\n") + ";");
|
||||
writeFile(
|
||||
"src/params.ts",
|
||||
NOTICE +
|
||||
"export const pathResolve = " +
|
||||
JSON.stringify(pathResolve) +
|
||||
";\n" +
|
||||
"export const queryParams = " +
|
||||
JSON.stringify(queryData) +
|
||||
";"
|
||||
);
|
||||
}
|
||||
|
||||
// Type Exports
|
||||
{
|
||||
const entries = ["import { components } from './schema';"];
|
||||
const schemas = spec.components.schemas;
|
||||
|
||||
for (const schema of Object.keys(schemas)) {
|
||||
entries.push(
|
||||
`export type ${schema.replace(
|
||||
/\s/g,
|
||||
"_"
|
||||
)} = components['schemas']['${schema}'];`
|
||||
);
|
||||
}
|
||||
|
||||
writeFile("src/types.ts", NOTICE + entries.join("\n") + ";");
|
||||
}
|
||||
|
||||
// Default Base URL
|
||||
const baseURL = spec["servers"]?.[0]?.["url"];
|
||||
writeFile(
|
||||
"src/baseURL.ts",
|
||||
NOTICE +
|
||||
`export const defaultBaseURL = ${
|
||||
baseURL ? '"' + baseURL + '"' : "undefined"
|
||||
};`
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user