Skip to content

Commit

Permalink
api.js make generation dynamic. messages.js add schemas from separate…
Browse files Browse the repository at this point in the history
… file. messages-schemas.js used for messages endpoint schemas
  • Loading branch information
NickOvt committed Oct 3, 2023
1 parent a69c6ad commit e7a3c72
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 151 deletions.
176 changes: 91 additions & 85 deletions api.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,8 +578,6 @@ module.exports = done => {
tools.responseWrapper(async (req, res) => {
res.charSet('utf-8');

const testRoute = server.router.getRoutes().postusersusermailboxesmailboxmessages;

// console.log(testRoute.spec.pathParams);
// console.log(testRoute.spec.requestBody.bimi);
// console.log(testRoute.spec.queryParams);
Expand Down Expand Up @@ -622,6 +620,22 @@ module.exports = done => {
// - name: TwoFactorAuth
// - name: Users
// - name: Webhooks`;

// securitySchemes:
// AccessTokenAuth:
// name: X-Access-Token
// type: apiKey
// in: header
// description: |-
// If authentication is enabled in the WildDuck configuration, you will need to supply an access token in the `X-Access-Token` header.

// ```json
// {
// "X-Access-Token": "59fc66a03e54454869460e45"
// }
// ```
// security:
// - AccessTokenAuth: []
// console.log(docs);

// console.info(testRoute.spec.pathParams.user._flags, testRoute.spec.pathParams.user._singleRules);
Expand Down Expand Up @@ -685,94 +699,82 @@ module.exports = done => {

const mapPathToMethods = {}; // map -> {post, put, delete, get}

const { spec } = testRoute;
// const testRoute = server.router.getRoutes().postusersusermailboxesmailboxmessages;

if (!mapPathToMethods[spec.path]) {
mapPathToMethods[spec.path] = {};
}
const routes = server.router.getRoutes();
for (const routePath in routes) {
const route = routes[routePath];
const { spec } = route;

mapPathToMethods[spec.path][spec.method.toLowerCase()] = {};
const methodObj = mapPathToMethods[spec.path][spec.method.toLowerCase()];
// 1) add tags
methodObj.tags = spec.tags;

// 2) add summary
methodObj.summary = spec.summary || '';
if (!mapPathToMethods[spec.path]) {
mapPathToMethods[spec.path] = {};
}

// 3) add description
methodObj.description = spec.description || '';
mapPathToMethods[spec.path][spec.method.toLowerCase()] = {};
const methodObj = mapPathToMethods[spec.path][spec.method.toLowerCase()];
// 1) add tags
methodObj.tags = spec.tags;

// 2) add summary
methodObj.summary = spec.summary || '';

// 3) add description
methodObj.description = spec.description || '';

// 4) add operationId
methodObj.operationId = spec.name || route.name;

// 5) add requestBody, if object use recursion
// if object then fields are in _ids._byKey.get(<key>)
methodObj.requestBody = {
content: {
'application/json': {
schema: {
type: 'object',
properties: {}
}
}
},
required: true
};
for (const reqBodyKey in spec.requestBody) {
const reqBodyKeyData = spec.requestBody[reqBodyKey];

// 4) add operationId
methodObj.operationId = spec.name || testRoute.name;
parseJoiObject(reqBodyKey, reqBodyKeyData, methodObj.requestBody.content['application/json'].schema.properties);
}

// 5) add requestBody, if object use recursion
// if object then fields are in _ids._byKey.get(<key>)
methodObj.requestBody = {
content: {
'application/json': {
schema: {
type: 'object',
properties: {}
}
}
},
required: true
};
for (const reqBodyKey in spec.requestBody) {
const reqBodyKeyData = spec.requestBody[reqBodyKey];

// if (reqBodyKey === 'reference') {
// console.log(reqBodyKeyData._ids._byKey.get('attachments').schema.$_terms.matches[0].schema);
// }
// if (reqBodyKeyData.type === 'array') {
// console.log(reqBodyKeyData.$_terms.items[0]._ids);
// break;
// }

parseJoiObject(reqBodyKey, reqBodyKeyData, methodObj.requestBody.content['application/json'].schema.properties);
}
console.log(methodObj.requestBody.content['application/json'].schema /*.properties.reference*/);

console.log(methodObj.requestBody.content['application/json'].schema.properties.reference);
// 6) add parameters (queryParams + pathParams).
// TODO: ADD FORMAT key in schema BASED ON FIELD ADDITIONAL RULES IN JOI
methodObj.parameters = {};
for (const paramKey in spec.pathParams) {
const paramKeyData = spec.pathParams[paramKey];

// 6) add parameters (queryParams + pathParams). TODO: ADD FORMAT key in schema BASED ON FIELD ADDITIONAL RULES IN JOI
methodObj.parameters = {};
for (const paramKey in spec.pathParams) {
const paramKeyData = spec.pathParams[paramKey];
methodObj.parameters[paramKey] = {};
const obj = methodObj.parameters[paramKey];
obj.in = 'path';
obj.description = paramKeyData._flags.description || '';
obj.required = paramKeyData._flags.presence === 'required';
obj.schema = { type: paramKeyData.type };

methodObj.parameters[paramKey] = {};
const obj = methodObj.parameters[paramKey];
obj.in = 'path';
obj.description = paramKeyData._flags.description || '';
obj.required = paramKeyData._flags.presence === 'required';
obj.schema = { type: paramKeyData.type };
// console.log(paramKeyData);
}

// console.log(paramKeyData);
}
for (const paramKey in spec.queryParams) {
const paramKeyData = spec.queryParams[paramKey];

for (const paramKey in spec.queryParams) {
const paramKeyData = spec.pathParams[paramKey];
methodObj.parameters[paramKey] = {};
const obj = methodObj.parameters[paramKey];
obj.in = 'query';
obj.description = paramKeyData._flags.description || '';
obj.required = paramKeyData._flags.presence === 'required';
obj.schema = { type: paramKeyData.type };
}

methodObj.parameters[paramKey] = {};
const obj = methodObj.parameters[paramKey];
obj.in = 'query';
obj.description = paramKeyData._flags.description || '';
obj.required = paramKeyData._flags.presence === 'required';
obj.schema = { type: paramKeyData.type };
// 7) add responses
methodObj.responses = {};
}

// 7) add responses
methodObj.responses = {};

// console.log(mapPathToMethods['/users/:user/mailboxes/:mailbox/messages'].post.parameters);
// console.log(
// isRequired,
// description,
// originalType,
// testRoute.spec.description,
// testRoute.spec.method.toLowerCase(),
// testRoute.spec.path,
// testRoute.spec.tags
// );
})
);

Expand All @@ -795,7 +797,7 @@ module.exports = done => {

const data = {
type: joiObject.type,
descrption: joiObject._flags.description || 'OBJECT DESCRIPTION',
descrption: joiObject._flags.description || '',
properties: {},
required: []
};
Expand All @@ -805,7 +807,6 @@ module.exports = done => {
requestBodyProperties.push(data);
}
for (const [key, value] of fieldsMap) {
// console.log(key, value);
if (value.schema._flags.presence === 'required') {
data.required.push(key);
}
Expand All @@ -816,7 +817,7 @@ module.exports = done => {

const data = {
oneOf: [],
description: joiObject._flags.description || 'ALTERNATIVES DESCRIPTION'
description: joiObject._flags.description || ''
};

if (path) {
Expand All @@ -836,7 +837,7 @@ module.exports = done => {
const data = {
type: 'array',
items: [],
description: joiObject._flags.description || 'ARRAY DESCRIPTION'
description: joiObject._flags.description || ''
};

if (path) {
Expand All @@ -862,16 +863,21 @@ module.exports = done => {
}
// TODO: if type before and after is string, add additional checks

const data = { type: openApiType, description, format, required: isRequired };
if (openApiType === 'string') {
console.log(joiObject._rules);
}

const data = { type: openApiType, description, required: isRequired };
if (format) {
data.format = format;
}
if (path) {
requestBodyProperties[path] = data;
} else {
// no path given, expect requestBodyProperties to be an array to append to
requestBodyProperties.push(data);
}

// console.log(openApiType, isRequired, description, format);

// all other types
// 1) get type
// 2) get if required
Expand Down
77 changes: 11 additions & 66 deletions lib/api/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const { getMongoDBQuery /*, getElasticSearchQuery*/ } = require('../search-query
//const { getClient } = require('../elasticsearch');

const BimiHandler = require('../bimi-handler');
const { Address, AddressOptionalName, Header, Attachment, ReferenceWithAttachments, Bimi } = require('../schemas/request/messages-schemas');

module.exports = (db, server, messageHandler, userHandler, storageHandler, settingsHandler) => {
let maildrop = new Maildropper({
Expand Down Expand Up @@ -1546,45 +1547,17 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti

raw: Joi.binary().max(consts.MAX_ALLOWED_MESSAGE_SIZE).empty(''),

from: Joi.object().keys({
name: Joi.string().empty('').max(255),
address: Joi.string().email({ tlds: false }).required()
}),
from: Address,

replyTo: Joi.object().keys({
name: Joi.string().empty('').max(255),
address: Joi.string().email({ tlds: false }).required()
}),
replyTo: Address,

to: Joi.array().items(
Joi.object().keys({
name: Joi.string().empty('').max(255),
address: Joi.string().email({ tlds: false }).required()
})
),
to: AddressOptionalName,

cc: Joi.array().items(
Joi.object().keys({
name: Joi.string().empty('').max(255),
address: Joi.string().email({ tlds: false }).required()
})
),
cc: AddressOptionalName,

bcc: Joi.array().items(
Joi.object().keys({
name: Joi.string().empty('').max(255),
address: Joi.string().email({ tlds: false }).required()
})
),

headers: Joi.array().items(
Joi.object().keys({
key: Joi.string().empty('').max(255),
value: Joi.string()
.empty('')
.max(100 * 1024)
})
),
bcc: AddressOptionalName,

headers: Joi.array().items(Header),

subject: Joi.string()
.empty('')
Expand All @@ -1598,46 +1571,18 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti

files: Joi.array().items(Joi.string().hex().lowercase().length(24)),

attachments: Joi.array().items(
Joi.object().keys({
filename: Joi.string().empty('').max(255),
contentType: Joi.string().empty('').max(255),
encoding: Joi.string().empty('').default('base64'),
contentTransferEncoding: Joi.string().empty(''),
content: Joi.string().required(),
cid: Joi.string().empty('').max(255)
})
),
attachments: Joi.array().items(Attachment),

metaData: metaDataSchema.label('metaData'),

reference: Joi.object().keys({
mailbox: Joi.string().hex().lowercase().length(24).required(),
id: Joi.number().required(),
action: Joi.string().valid('reply', 'replyAll', 'forward').required(),
attachments: Joi.alternatives().try(
booleanSchema,
Joi.array().items(
Joi.string()
.regex(/^ATT\d+$/i)
.uppercase()
)
)
}),
reference: ReferenceWithAttachments,

replacePrevious: Joi.object({
mailbox: Joi.string().hex().lowercase().length(24),
id: Joi.number().required()
}),

bimi: Joi.object().keys({
domain: Joi.string().domain().required(),
selector: Joi.string().empty('').max(255),
bimi: Joi.object().keys({
domain: Joi.string().domain().required(),
selector: Joi.string().empty('').max(255)
})
}),
bimi: Bimi,

sess: sessSchema,
ip: sessIPSchema
Expand Down
Loading

0 comments on commit e7a3c72

Please sign in to comment.