mirror of
https://github.com/discordeno/discordeno.git
synced 2026-05-21 02:40:08 +00:00
I prefer semicolors, they also help avoiding certain pitfalls in JavaScript/TypeScript, such as the following code sample: ```js const xyz = "test" (something.else as string) = "another" ``` This results in a TypeError: "test" is not a function, this is because js thinks we are trying to call the string "test" as a function. To fix this it requires a `;` somewhere before the `(`, such as `;(something ... ` which in my opinion is ugly and less clean overall.
127 lines
4.0 KiB
JavaScript
127 lines
4.0 KiB
JavaScript
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
|
|
import fs from 'fs';
|
|
|
|
// TODO: replace with fetch of live spec
|
|
const DISCORD_SPEC = {};
|
|
|
|
function schemaRefToName(ref) {
|
|
if (!ref) return '';
|
|
return `Discord${ref?.substring(ref.lastIndexOf('/') + 1)}`;
|
|
}
|
|
|
|
function snakeToPascalCase(str) {
|
|
if (!str.includes('_')) return str;
|
|
|
|
let result = '';
|
|
for (let i = 0, len = str.length; i < len; ++i) {
|
|
if (str[i] === '_') {
|
|
result += str[++i].toUpperCase();
|
|
|
|
continue;
|
|
}
|
|
|
|
result += str[i];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function generateFromSpec() {
|
|
const finalTypings = [];
|
|
|
|
for (const [key, schema] of Object.entries(DISCORD_SPEC.components.schemas)) {
|
|
const interfacey = [`export interface Discord${key} {`];
|
|
|
|
if (schema.properties) {
|
|
for (const [name, property] of Object.entries(schema.properties)) {
|
|
const type = Array.isArray(property.type) ? property.type : property.type ? [property.type] : undefined;
|
|
let ref = property.$ref && schemaRefToName(property.$ref);
|
|
let allOf = property.allOf?.find((a) => a.$ref);
|
|
if (allOf) {
|
|
allOf = schemaRefToName(allOf.$ref);
|
|
}
|
|
|
|
const isArray = property.type === 'array';
|
|
if (isArray) {
|
|
if (property.items.$ref) ref = schemaRefToName(property.items.$ref);
|
|
else if (Array.isArray(property.oneOf)) {
|
|
ref = property.oneOf.map((o) => schemaRefToName(o.$ref)).join(' | ');
|
|
}
|
|
}
|
|
|
|
if (property.description) {
|
|
interfacey.push(` /** ${property.description} */`);
|
|
}
|
|
|
|
let cleanType =
|
|
ref ??
|
|
allOf ??
|
|
type
|
|
?.map((type) =>
|
|
type === 'integer'
|
|
? 'number'
|
|
: type === 'array'
|
|
? property.items.$ref
|
|
? `${schemaRefToName(property.items.$ref)}[]`
|
|
: Array.isArray(property.items.oneOf)
|
|
? `${property.items.oneOf.map((o) => `${schemaRefToName(o.$ref)}[]`).join(' | ')}`
|
|
: `unknown[]`
|
|
: type,
|
|
)
|
|
.join(' | ') ??
|
|
property.oneOf
|
|
?.map(
|
|
(o) =>
|
|
(o.type
|
|
? o.type === 'integer'
|
|
? o.enum
|
|
? o.allOf.map((a) => schemaRefToName(a.$ref)).join(' | ')
|
|
: 'number'
|
|
: o.type
|
|
: undefined) ?? schemaRefToName(o.$ref),
|
|
)
|
|
.join(' | ') ??
|
|
'unknown';
|
|
|
|
if (cleanType.startsWith('null | ')) cleanType = cleanType.substring(cleanType.indexOf('|') + 2) + ' | null';
|
|
interfacey.push(` ${name}${schema.required?.includes(name) ? ':' : '?:'} ${cleanType}`);
|
|
}
|
|
} else {
|
|
// No properties so is enum
|
|
if (['integer', 'string'].includes(schema.type) && Array.isArray(schema.oneOf)) {
|
|
const enumm = [`export enum Discord${key} {`];
|
|
for (const possible of schema.oneOf) {
|
|
if (possible.description) enumm.push(` /** ${possible.description} */`);
|
|
// TODO: camel case the title
|
|
enumm.push(
|
|
` ${possible.title.includes('-') ? '"' : ''}${snakeToPascalCase(
|
|
`${possible.title[0].toUpperCase()}${possible.title.substring(1).toLowerCase()}`,
|
|
)}${possible.title.includes('-') ? '"' : ''} = ${schema.type === 'string' ? '"' : ''}${possible.const}${
|
|
schema.type === 'string' ? '"' : ''
|
|
},`,
|
|
);
|
|
}
|
|
enumm.push('}');
|
|
|
|
finalTypings.push(enumm.join('\n'));
|
|
continue;
|
|
}
|
|
|
|
console.log('NO PROPERTIES', key, schema);
|
|
continue;
|
|
}
|
|
|
|
interfacey.push('}');
|
|
|
|
finalTypings.push(interfacey.join('\n'));
|
|
}
|
|
|
|
fs.writeFileSync('./packages/types/src/discord.ts', finalTypings.join('\n\n'), function (err, _result) {
|
|
if (err) throw err;
|
|
});
|
|
}
|
|
|
|
generateFromSpec();
|