From 7584d2d7a7110aef0331ebfa178b2295842c59fa Mon Sep 17 00:00:00 2001 From: MCMXC <16797721+mcmxcdev@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:19:14 -0700 Subject: refactor: project maintenance - work in progress --- app/Controllers/Http/ServiceController.ts | 204 ++++++++++++++---------------- 1 file changed, 92 insertions(+), 112 deletions(-) (limited to 'app/Controllers/Http/ServiceController.ts') diff --git a/app/Controllers/Http/ServiceController.ts b/app/Controllers/Http/ServiceController.ts index 76e72e4..9988244 100644 --- a/app/Controllers/Http/ServiceController.ts +++ b/app/Controllers/Http/ServiceController.ts @@ -1,49 +1,49 @@ -import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; -import { schema } from '@ioc:Adonis/Core/Validator'; -import Service from 'App/Models/Service'; -import { url } from 'Config/app'; -import { v4 as uuid } from 'uuid'; -import * as fs from 'fs-extra'; -import path from 'node:path'; -import Application from '@ioc:Adonis/Core/Application'; -import sanitize from 'sanitize-filename'; +import type { HttpContext } from '@adonisjs/core/http' +import { schema } from '@adonisjs/validator' +import Service from '#app/Models/Service' +import { url } from '#config/app' +import { v4 as uuid } from 'uuid' +import * as fs from 'fs-extra' +import path from 'node:path' +import { app } from '@adonisjs/core/services/app' +import sanitize from 'sanitize-filename' const createSchema = schema.create({ name: schema.string(), recipeId: schema.string(), -}); +}) export default class ServiceController { // Create a new service for user - public async create({ request, response, auth }: HttpContextContract) { + public async create({ request, response, auth }: HttpContext) { // @ts-expect-error Property 'user' does not exist on type 'HttpContextContract'. - const user = auth.user ?? request.user; + const user = auth.user ?? request.user if (!user) { - return response.unauthorized('Missing or invalid api token'); + return response.unauthorized('Missing or invalid api token') } // Validate user input - const data = request.all(); + const data = request.all() try { - await request.validate({ schema: createSchema }); + await request.validate({ schema: createSchema }) } catch (error) { return response.status(401).send({ message: 'Invalid POST arguments', messages: error.messages, status: 401, - }); + }) } // Get new, unused uuid - let serviceId; + let serviceId do { - serviceId = uuid(); + serviceId = uuid() } while ( // eslint-disable-next-line no-await-in-loop, unicorn/no-await-expression-member (await Service.query().where('serviceId', serviceId)).length > 0 - ); + ) await Service.create({ userId: user.id, @@ -51,7 +51,7 @@ export default class ServiceController { name: data.name, recipeId: data.recipeId, settings: JSON.stringify(data), - }); + }) return response.send({ data: { @@ -72,28 +72,26 @@ export default class ServiceController { ...data, }, status: ['created'], - }); + }) } // List all services a user has created - public async list({ request, response, auth }: HttpContextContract) { + public async list({ request, response, auth }: HttpContext) { // @ts-expect-error Property 'user' does not exist on type 'HttpContextContract'. - const user = auth.user ?? request.user; + const user = auth.user ?? request.user if (!user) { - return response.unauthorized('Missing or invalid api token'); + return response.unauthorized('Missing or invalid api token') } - const { id } = user; - const services = await user.related('services').query(); + const { id } = user + const services = await user.related('services').query() // Convert to array with all data Franz wants // eslint-disable-next-line @typescript-eslint/no-explicit-any const servicesArray = services.map((service: any) => { const settings = - typeof service.settings === 'string' - ? JSON.parse(service.settings) - : service.settings; + typeof service.settings === 'string' ? JSON.parse(service.settings) : service.settings return { customRecipe: false, @@ -110,99 +108,87 @@ export default class ServiceController { iconUrl: settings.iconId ? `${url}/v1/icon/${settings.iconId}` : // eslint-disable-next-line unicorn/no-null - null, + null, id: service.serviceId, name: service.name, recipeId: service.recipeId, userId: id, - }; - }); + } + }) - return response.send(servicesArray); + return response.send(servicesArray) } - public async delete({ - request, - params, - auth, - response, - }: HttpContextContract) { + public async delete({ request, params, auth, response }: HttpContext) { // @ts-expect-error Property 'user' does not exist on type 'HttpContextContract'. - const user = auth.user ?? request.user; + const user = auth.user ?? request.user if (!user) { - return response.unauthorized('Missing or invalid api token'); + return response.unauthorized('Missing or invalid api token') } // Update data in database - await Service.query() - .where('serviceId', params.id) - .where('userId', user.id) - .delete(); + await Service.query().where('serviceId', params.id).where('userId', user.id).delete() return response.send({ message: 'Sucessfully deleted service', status: 200, - }); + }) } // TODO: Test if icon upload works - public async edit({ request, response, auth, params }: HttpContextContract) { + public async edit({ request, response, auth, params }: HttpContext) { // @ts-expect-error Property 'user' does not exist on type 'HttpContextContract'. - const user = auth.user ?? request.user; + const user = auth.user ?? request.user if (!user) { - return response.unauthorized('Missing or invalid api token'); + return response.unauthorized('Missing or invalid api token') } - const { id } = params; + const { id } = params const service = await Service.query() .where('serviceId', id) .where('userId', user.id) - .firstOrFail(); + .firstOrFail() if (request.file('icon')) { // Upload custom service icon const icon = request.file('icon', { extnames: ['png', 'jpg', 'jpeg', 'svg'], size: '2mb', - }); + }) if (icon === null) { - return response.badRequest('Icon not uploaded.'); + return response.badRequest('Icon not uploaded.') } const settings = - typeof service.settings === 'string' - ? JSON.parse(service.settings) - : service.settings; + typeof service.settings === 'string' ? JSON.parse(service.settings) : service.settings - let iconId; + let iconId do { - iconId = uuid() + uuid(); + iconId = uuid() + uuid() } while ( // eslint-disable-next-line no-await-in-loop - await fs.exists(path.join(Application.tmpPath('uploads'), iconId)) - ); - iconId = `${iconId}.${icon.extname}`; + await fs.exists(path.join(app.tmpPath('uploads'), iconId)) + ) + iconId = `${iconId}.${icon.extname}` - await icon.move(Application.tmpPath('uploads'), { + await icon.move(app.tmpPath('uploads'), { name: iconId, overwrite: true, - }); + }) if (icon.state !== 'moved') { - return response.status(500).send(icon.errors); + return response.status(500).send(icon.errors) } const newSettings = { ...settings, iconId, - customIconVersion: settings?.customIconVersion - ? settings.customIconVersion + 1 - : 1, - }; + customIconVersion: settings?.customIconVersion ? settings.customIconVersion + 1 : 1, + } // Update data in database await Service.query() @@ -211,7 +197,7 @@ export default class ServiceController { .update({ name: service.name, settings: JSON.stringify(newSettings), - }); + }) return response.send({ data: { @@ -222,28 +208,24 @@ export default class ServiceController { userId: user.id, }, status: ['updated'], - }); + }) } // Update service info - const data = request.all(); + const data = request.all() const settings = { - ...(typeof service.settings === 'string' - ? JSON.parse(service.settings) - : service.settings), + ...(typeof service.settings === 'string' ? JSON.parse(service.settings) : service.settings), ...data, - }; + } if (settings.customIcon === 'delete') { - fs.remove( - path.join(Application.tmpPath('uploads'), settings.iconId), - ).catch(error => { - console.error(error); - }); - - settings.iconId = undefined; - settings.customIconVersion = undefined; - settings.customIcon = ''; + fs.remove(path.join(app.tmpPath('uploads'), settings.iconId)).catch((error) => { + console.error(error) + }) + + settings.iconId = undefined + settings.customIconVersion = undefined + settings.customIcon = '' } // Update data in database @@ -253,13 +235,13 @@ export default class ServiceController { .update({ name: data.name, settings: JSON.stringify(settings), - }); + }) // Get updated row const serviceUpdated = await Service.query() .where('serviceId', id) .where('userId', user.id) - .firstOrFail(); + .firstOrFail() return response.send({ data: { @@ -270,19 +252,19 @@ export default class ServiceController { userId: user.id, }, status: ['updated'], - }); + }) } // TODO: Test if this works - public async reorder({ request, response, auth }: HttpContextContract) { + public async reorder({ request, response, auth }: HttpContext) { // @ts-expect-error Property 'user' does not exist on type 'HttpContextContract'. - const user = auth.user ?? request.user; + const user = auth.user ?? request.user if (!user) { - return response.unauthorized('Missing or invalid api token'); + return response.unauthorized('Missing or invalid api token') } - const data = request.all(); + const data = request.all() for (const service of Object.keys(data)) { // Get current settings from db @@ -290,14 +272,14 @@ export default class ServiceController { .where('serviceId', service) .where('userId', user.id) - .firstOrFail(); + .firstOrFail() const settings = { ...(typeof serviceData.settings === 'string' ? JSON.parse(serviceData.settings) : serviceData.settings), order: data[service], - }; + } // Update data in database await Service.query() // eslint-disable-line no-await-in-loop @@ -305,18 +287,16 @@ export default class ServiceController { .where('userId', user.id) .update({ settings: JSON.stringify(settings), - }); + }) } // Get new services - const services = await user.related('services').query(); + const services = await user.related('services').query() // Convert to array with all data Franz wants // eslint-disable-next-line @typescript-eslint/no-explicit-any const servicesArray = services.map((service: any) => { const settings = - typeof service.settings === 'string' - ? JSON.parse(service.settings) - : service.settings; + typeof service.settings === 'string' ? JSON.parse(service.settings) : service.settings return { customRecipe: false, @@ -333,39 +313,39 @@ export default class ServiceController { iconUrl: settings.iconId ? `${url}/v1/icon/${settings.iconId}` : // eslint-disable-next-line unicorn/no-null - null, + null, id: service.serviceId, name: service.name, recipeId: service.recipeId, userId: user.id, - }; - }); + } + }) - return response.send(servicesArray); + return response.send(servicesArray) } // TODO: Test if this works - public async icon({ params, response }: HttpContextContract) { - let { id } = params; + public async icon({ params, response }: HttpContext) { + let { id } = params - id = sanitize(id); + id = sanitize(id) if (id === '') { return response.status(404).send({ - status: 'Icon doesn\'t exist', - }); + status: "Icon doesn't exist", + }) } - const iconPath = path.join(Application.tmpPath('uploads'), id); + const iconPath = path.join(app.tmpPath('uploads'), id) try { - await fs.access(iconPath); + await fs.access(iconPath) } catch { // File not available. return response.status(404).send({ - status: 'Icon doesn\'t exist', - }); + status: "Icon doesn't exist", + }) } - return response.download(iconPath); + return response.download(iconPath) } } -- cgit v1.2.3-70-g09d2