declarapi
Version:
Declarative API generation
131 lines • 5.3 kB
JavaScript
import { map } from 'microtil';
import { validate, isValidationError } from './jsonSchema.js';
import { loadJSON, baseSchemaLocation } from '../util.js';
const contractOptions = (input) => {
if (Array.isArray(input)) {
if (input.some(x => x === '?')) {
return input;
}
return input.concat(['?']);
}
return [input, '?'];
};
const searchToType = (idType, dataType, search) => {
if (search === 'idOnly') {
return { id: [idType, { $array: idType }, '?'] };
}
else if (search === 'textSearch') {
return { search: ['string', '?'], id: [idType, { $array: idType }, '?'] };
}
else if (search === 'full') {
return map(dataType, value => contractOptions(value));
}
else if (!search) {
return {};
}
return search;
};
const checkIdField = (contract) => {
if (contract.dataType.id === undefined) {
return {
type: 'error',
errors: 'id field does not exist in the data declaration'
};
}
const idType = contract.dataType.id;
if (!(idType === 'string' || idType.$string)) {
return {
type: 'error',
errors: 'Type of id field must be string'
};
}
return false;
};
const checkManageFields = (contract) => {
for (const [key, value] of Object.entries(contract.manageFields || {})) {
if (value) {
const fieldType = contract.dataType[key];
if (fieldType === undefined) {
return {
type: 'error',
errors: `managed field "${key}" is not present on data type`
};
}
if (!(fieldType === 'string' || fieldType.$string)) {
return {
type: 'error',
errors: `managed field "${key}" must be a string, current type :${fieldType}`
};
}
}
}
return false;
};
const removeManaged = (args, manageFields) => {
const result = { ...args };
for (const [key, value] of Object.entries(manageFields || {})) {
if (value) {
delete result[key];
}
}
return result;
};
const isCrudAuth = (tbd) => tbd.post !== undefined;
const isCrudAuthSome = (tbd) => tbd.modify !== undefined;
const transformForPost = (tbd) => Array.isArray(tbd) && tbd.find(x => x.createdBy) ? true : tbd;
export const transform = async (data) => {
var _a, _b, _c, _d, _e;
const valid = await validate(await loadJSON(`${await baseSchemaLocation()}crudContractSchema.json`), data);
if (isValidationError(valid))
return valid;
const contractData = data;
const au = contractData.authentication;
const auth = {
GET: isCrudAuth(au) ? au.get : (isCrudAuthSome(au) ? au.get : au),
POST: isCrudAuth(au) ? au.post : transformForPost((isCrudAuthSome(au) ? au.modify : au)),
PUT: isCrudAuth(au) ? au.put : (isCrudAuthSome(au) ? au.modify : au),
PATCH: isCrudAuth(au) ? au.put : (isCrudAuthSome(au) ? au.modify : au),
DELETE: isCrudAuth(au) ? au.delete : (isCrudAuthSome(au) ? au.delete || au.modify : au)
};
const createOutput = (method, args, returns = contractData.dataType) => ({
method,
name: contractData.name,
authentication: auth[method],
manageFields: contractData.manageFields || {},
search: contractData.search,
preferredImplementation: contractData.preferredImplementation,
arguments: args,
returns
});
const returnArray = { $array: contractData.dataType };
const output = [];
const errorWithId = checkIdField(contractData);
if (errorWithId)
return errorWithId;
const errorWithManageFields = checkManageFields(contractData);
if (errorWithManageFields)
return errorWithManageFields;
const idType = contractData.dataType.id;
if (((_a = contractData.methods) === null || _a === void 0 ? void 0 : _a.get) !== false) {
const search = contractData.search;
output.push(createOutput('GET', searchToType(idType, contractData.dataType, search), returnArray));
}
if (((_b = contractData.methods) === null || _b === void 0 ? void 0 : _b.post) !== false) {
const post = { ...contractData.dataType, id: [idType, '?'] };
output.push(createOutput('POST', removeManaged(post, contractData.manageFields)));
}
if (((_c = contractData.methods) === null || _c === void 0 ? void 0 : _c.put) !== false) {
output.push(createOutput('PUT', removeManaged(contractData.dataType, contractData.manageFields)));
}
if (((_d = contractData.methods) === null || _d === void 0 ? void 0 : _d.patch) !== false) {
const patch = { ...map(contractData.dataType, contractOptions), id: idType };
output.push(createOutput('PATCH', removeManaged(patch, contractData.manageFields)));
}
if (((_e = contractData.methods) === null || _e === void 0 ? void 0 : _e.delete) !== false) {
const deleteIds = { id: [idType, { $array: idType }] };
output.push(createOutput('DELETE', deleteIds, returnArray));
}
return { type: 'result', key: contractData.name, results: output };
};
export default transform;
//# sourceMappingURL=crud.js.map