Skip to content

Commit

Permalink
Format file correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
ZiomaleQ committed Sep 3, 2023
1 parent ba5457b commit afaad10
Showing 1 changed file with 78 additions and 66 deletions.
144 changes: 78 additions & 66 deletions scripts/endpoint_typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,124 +2,136 @@ const $ = async (...cmd: string[]) => {
const proc = new Deno.Command(cmd.join(" "), {
stdout: "piped",
stderr: "piped",
})
const childProc = proc.spawn()
const status = await childProc.status
return status.code
}
});
const childProc = proc.spawn();
const status = await childProc.status;
return status.code;
};

const API_DOCS_URL = "https://raw.githubusercontent.com/discord/discord-api-spec/main/specs/openapi.json"
const API_DOCS_URL =
"https://raw.githubusercontent.com/discord/discord-api-spec/main/specs/openapi.json";

interface Endpoint {
title: string
name: string
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
url: string
params: string[]
title: string;
name: string;
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
url: string;
params: string[];
}

const endpoints: Endpoint[] = []
const endpoints: Endpoint[] = [];

const jsonDocs = await fetch(API_DOCS_URL).then((e) => e.json())
const jsonDocs = await fetch(API_DOCS_URL).then((e) => e.json());

type ApiParam = {
name: string,
in: "query" | "path",
name: string;
in: "query" | "path";
schema: {
type: string[],
format: string
}
}
type: string[];
format: string;
};
};

type OpenApiInfo = {
operationId: string
responses: Record<string, { description: string, content: string }>
security: Record<string, never>[]
parameters?: ApiParam[]
}
operationId: string;
responses: Record<string, { description: string; content: string }>;
security: Record<string, never>[];
parameters?: ApiParam[];
};

for (const [path, data] of Object.entries(jsonDocs.paths)) {
const preParams: ApiParam[] = [];

Object.entries(data as Record<string, OpenApiInfo | ApiParam[]>).find(
([method, info]) => {
if (method === "parameters") {
preParams.push(...info as ApiParam[]);
}
},
);

for (
const [method, info] of Object.entries(data as Record<string, OpenApiInfo>)
) {
if (method === "parameters") continue;

const preParams: ApiParam[] = []

Object.entries(data as Record<string, OpenApiInfo | ApiParam[]>).find(([method, info]) => {
if (method === 'parameters') {
preParams.push(...info as ApiParam[])
}
})

for (const [method, info] of Object.entries(data as Record<string, OpenApiInfo>)) {
if (method === 'parameters') continue

const splitName = info.operationId.split('_').map(e => e[0].toUpperCase() + e.slice(1))
const splitName = info.operationId.split("_").map((e) =>
e[0].toUpperCase() + e.slice(1)
);

const params = [...preParams, ...(info?.parameters ?? [])].filter(e => e.in === 'path')
const params = [...preParams, ...(info?.parameters ?? [])].filter((e) =>
e.in === "path"
);

let url = path
let url = path;

for (const param of params) {
param.name = param.name.split('_').map(e => e[0].toUpperCase() + e.slice(1)).join('')
param.name = param.name.replace('Id', 'ID')
url = url.replace(`{${param.name}}`, '${' + param.name + '}')
param.name = param.name.split("_").map((e) =>
e[0].toUpperCase() + e.slice(1)
).join("");
param.name = param.name.replace("Id", "ID");
url = url.replace(`{${param.name}}`, "${" + param.name + "}");
}

endpoints.push({
title: splitName.join(' '),
name: splitName.join(''),
title: splitName.join(" "),
name: splitName.join(""),
method: method.toUpperCase() as Endpoint["method"],
url: path,
params: params.map(e => e.name),
})
params: params.map((e) => e.name),
});
}
}

let types =
`// NOTE: This file is auto-generated by scripts/endpoint_typegen.ts\n\nimport { snowflake } from "./common.ts";\n\n`
`// NOTE: This file is auto-generated by scripts/endpoint_typegen.ts\n\nimport { snowflake } from "./common.ts";\n\n`;

function getParamType(name: string): string {
if (name.endsWith("ID")) {
return "snowflake"
return "snowflake";
} else if (
name.endsWith("Token") || name.endsWith("Emoji") || name.endsWith("Code") || name === 'EmojiName'
name.endsWith("Token") || name.endsWith("Emoji") || name.endsWith("Code") ||
name === "EmojiName"
) {
return "string"
} else throw new Error(`Unable to infer Param Type: ${name}`)
return "string";
} else throw new Error(`Unable to infer Param Type: ${name}`);
}

for (const endpoint of endpoints) {
types += `/**\n * ${endpoint.title}\n * @method ${endpoint.method}\n */\n`
types += `export type ${endpoint.name}Endpoint`
types += `/**\n * ${endpoint.title}\n * @method ${endpoint.method}\n */\n`;
types += `export type ${endpoint.name}Endpoint`;
if (endpoint.params.length) {
types += `<\n`
types += `<\n`;
for (const param of endpoint.params) {
const type = getParamType(param)
types += ` ${param} extends ${type} = ${type},\n`
const type = getParamType(param);
types += ` ${param} extends ${type} = ${type},\n`;
}
types += `>`
types += `>`;
}
types += ` = \`${endpoint.url}\`;\n\n`
types += ` = \`${endpoint.url}\`;\n\n`;
}

types += `export type Endpoint =\n`
types += `export type Endpoint =\n`;
for (const _ in endpoints) {
const i = Number(_)
const endpoint = endpoints[i]
types += ` | ${endpoint.name}Endpoint${i === endpoints.length - 1 ? ";" : ""
}\n`
const i = Number(_);
const endpoint = endpoints[i];
types += ` | ${endpoint.name}Endpoint${
i === endpoints.length - 1 ? ";" : ""
}\n`;
}

const TYPES_FILE = new URL("../types/src/endpoints.ts", import.meta.url)
const TYPES_FILE = new URL("../types/src/endpoints.ts", import.meta.url);
await Deno.writeTextFile(
TYPES_FILE,
types,
)
);

await $(
"deno",
"fmt",
"-c",
new URL("../deno.json", import.meta.url).pathname,
TYPES_FILE.pathname,
)
);

console.log("Generated Endpoint Types!")
console.log("Generated Endpoint Types!");

0 comments on commit afaad10

Please sign in to comment.