mirror of
https://github.com/stoatchat/javascript-client-api.git
synced 2026-07-16 05:31:52 -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"
|
||||
};`
|
||||
);
|
||||
});
|
||||
+4
-2
@@ -16,7 +16,6 @@
|
||||
"prepublish": "in-publish && pnpm build || echo Skipping build."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@insertish/oapi": "0.2.6",
|
||||
"in-publish": "^2.0.1",
|
||||
"openapi-typescript": "^5.4.2",
|
||||
"typescript": "^5.8.3"
|
||||
@@ -28,5 +27,8 @@
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39"
|
||||
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39",
|
||||
"dependencies": {
|
||||
"json-with-bigint": "^3.4.4"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+9
-20
@@ -7,10 +7,11 @@ settings:
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
json-with-bigint:
|
||||
specifier: ^3.4.4
|
||||
version: 3.4.4
|
||||
devDependencies:
|
||||
'@insertish/oapi':
|
||||
specifier: 0.2.6
|
||||
version: 0.2.6
|
||||
in-publish:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1
|
||||
@@ -27,10 +28,6 @@ packages:
|
||||
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@insertish/oapi@0.2.6':
|
||||
resolution: {integrity: sha512-6IWpLFhygWu+hN8+bNXH3pK0hypxoS522Vn6AOhphzXrWQlDo6IhEWRWXV/XlyYQIPiugkDcqtD2p0dtB9Wftg==}
|
||||
hasBin: true
|
||||
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
@@ -48,6 +45,9 @@ packages:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
|
||||
json-with-bigint@3.4.4:
|
||||
resolution: {integrity: sha512-AhpYAAaZsPjU7smaBomDt1SOQshi9rEm6BlTbfVwsG1vNmeHKtEedJi62sHZzJTyKNtwzmNnrsd55kjwJ7054A==}
|
||||
|
||||
mime@3.0.0:
|
||||
resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
@@ -66,11 +66,6 @@ packages:
|
||||
tiny-glob@0.2.9:
|
||||
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
|
||||
|
||||
typescript@4.9.5:
|
||||
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
|
||||
typescript@5.8.3:
|
||||
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
|
||||
engines: {node: '>=14.17'}
|
||||
@@ -88,12 +83,6 @@ snapshots:
|
||||
|
||||
'@fastify/busboy@2.1.1': {}
|
||||
|
||||
'@insertish/oapi@0.2.6':
|
||||
dependencies:
|
||||
typescript: 4.9.5
|
||||
optionalDependencies:
|
||||
openapi-typescript: 5.4.2
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
globalyzer@0.1.0: {}
|
||||
@@ -106,6 +95,8 @@ snapshots:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
json-with-bigint@3.4.4: {}
|
||||
|
||||
mime@3.0.0: {}
|
||||
|
||||
openapi-typescript@5.4.2:
|
||||
@@ -124,8 +115,6 @@ snapshots:
|
||||
globalyzer: 0.1.0
|
||||
globrex: 0.1.2
|
||||
|
||||
typescript@4.9.5: {}
|
||||
|
||||
typescript@5.8.3: {}
|
||||
|
||||
undici@5.29.0:
|
||||
|
||||
+7
-3
@@ -1,11 +1,14 @@
|
||||
// This file was auto-generated by @insertish/oapi!
|
||||
import type { APIRoutes } from "./routes.js";
|
||||
export type { APIRoutes } from "./routes.js";
|
||||
|
||||
export * from "./types.js";
|
||||
|
||||
import { defaultBaseURL } from "./baseURL.js";
|
||||
import { pathResolve, queryParams } from "./params.js";
|
||||
|
||||
import { JSONParse, JSONStringify } from 'json-with-bigint';
|
||||
|
||||
type Methods = APIRoutes["method"];
|
||||
type PickRoutes<Method extends Methods> = APIRoutes & { method: Method };
|
||||
|
||||
@@ -189,7 +192,7 @@ export class API {
|
||||
}
|
||||
const passbody = ["head", "get"].includes(method)
|
||||
? undefined
|
||||
: JSON.stringify(body);
|
||||
: JSONStringify(body);
|
||||
|
||||
let fetchpath = `${path}?${query.toString()}`;
|
||||
if (fetchpath.startsWith("/")) {
|
||||
@@ -205,13 +208,14 @@ export class API {
|
||||
body: passbody,
|
||||
});
|
||||
|
||||
const respType = config?.responseType || "json";
|
||||
const data =
|
||||
fetchdata.status === 204
|
||||
? null
|
||||
: await fetchdata[config?.responseType || "json"]();
|
||||
: await fetchdata[respType === 'json' ? 'text' : respType]();
|
||||
|
||||
if (fetchdata.ok) {
|
||||
return data;
|
||||
return respType === 'json' ? JSONParse(data as string) : data as never;
|
||||
} else {
|
||||
throw data;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES6",
|
||||
"moduleResolution": "node",
|
||||
"module": "es6",
|
||||
"moduleResolution": "bundler",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
|
||||
Reference in New Issue
Block a user