Skip to content

Commit

Permalink
Fix url replace
Browse files Browse the repository at this point in the history
  • Loading branch information
ZiomaleQ committed Sep 3, 2023
1 parent afaad10 commit c1bb7dd
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 220 deletions.
124 changes: 65 additions & 59 deletions scripts/endpoint_typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,129 +2,135 @@ 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";
"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[] = [];
const preParams: ApiParam[] = []

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

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

const swapped: Record<string, string> = {}

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

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) =>
params.forEach((param) => {
const oldName = param.name
const newName = 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 + "}");
).join("").replace("Id", "ID")

swapped[oldName] = newName
})

for (const [oldName, newName] of Object.entries(swapped)) {
url = url.replace(`{${oldName}}`, "${" + newName + "}")
}

endpoints.push({
title: splitName.join(" "),
name: splitName.join(""),
method: method.toUpperCase() as Endpoint["method"],
url: path,
params: params.map((e) => e.name),
});
url: url,
params: params.map((e) => swapped[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"
) {
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",
Expand All @@ -134,4 +140,4 @@ await $(
TYPES_FILE.pathname,
);

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

0 comments on commit c1bb7dd

Please sign in to comment.