declarapi
Version:
Declarative API generation
65 lines (61 loc) • 2.62 kB
JavaScript
import { typeDef, name } from './common.js';
const getTokenDefaultPath = '../getToken';
const containsOptional = (input) => (Array.isArray(input) && input.some(y => y === '?')) ||
input === '?';
const allOptional = (input) => Object.values(input).every(containsOptional);
export const client = (input, getTokenPath) => {
const functions = input.map(x => {
const url = x.method === 'GET' ? `\`/api/${x.name}?\${serialize(input || {})}\`` : `"/api/${x.name}"`;
const fn = `
const valid = validate(contracts.${name(x)}.arguments, input);
if (valid.result === "fail") throw valid;
return fetch(${url}, {
method: "${x.method}",
headers: await defaultHeader(),
body: ${x.method === 'GET' ? 'undefined' : 'JSON.stringify(input)'},
signal
}).then(x=> x.json())
.then(x=> {
if(x.errorType){throw x}
const r = validate(contracts.${name(x)}.returns, x);
if(r.result ==="fail") throw r; return x})\n`;
return `export const ${name(x)} =
async (input: ${name(x)}Argument${allOptional(x.arguments) ? ' = {}' : ''},
signal: AbortSignal | undefined = undefined):
Promise<${name(x)}Returns> => {\n${fn}};\n`;
}).join('\n');
const contractDescription = input.map(x => `${name(x)}: {
name: "${x.name}",
authentication: ${JSON.stringify(x.authentication, undefined, 2)},
type: "${x.method}",
arguments: ${JSON.stringify(x.arguments)},
returns: ${JSON.stringify(x.returns)}}`).join(',');
const fileContent = `/* eslint-disable max-lines */
/**********************************************
DO NOT EDIT THIS FILE, IT WILL BE OVERRIDDEN
***********************************************/
import { validate, Validation } from "yaschva";
import { deepFreeze, serialize } from "microtil";
import getToken from "${getTokenPath !== null && getTokenPath !== void 0 ? getTokenPath : getTokenDefaultPath}"
const defaultHeader = async () => {
const token = await getToken();
const headers = {
'Authorization': \`Bearer \${token}\`,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
if(!token) delete headers.Authorization
return headers;
};
export const contracts: {[key:string]:{
name:string, type:string, authentication:any,
arguments: Validation, returns:Validation}} =
deepFreeze({${contractDescription}});
${typeDef(input)}
${functions}
export const functions = {${input.map(x => `${name(x)}: ${name(x)}`)}}
`;
return fileContent;
};
export default client;
//# sourceMappingURL=client.js.map