diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/ace.js b/ace.js old mode 100644 new mode 100755 diff --git a/adonisrc.ts b/adonisrc.ts old mode 100644 new mode 100755 index 09ae21e..c5cad75 --- a/adonisrc.ts +++ b/adonisrc.ts @@ -32,7 +32,8 @@ export default defineConfig({ () => import('@adonisjs/cors/cors_provider'), () => import('@adonisjs/lucid/database_provider'), () => import('@adonisjs/auth/auth_provider'), - () => import('@adonisjs/limiter/limiter_provider') + () => import('@adonisjs/limiter/limiter_provider'), + () => import('@adonisjs/ally/ally_provider'), ], /* diff --git a/app/controllers/auth_controller.ts b/app/controllers/auth_controller.ts old mode 100644 new mode 100755 index 3dc2454..8ba509a --- a/app/controllers/auth_controller.ts +++ b/app/controllers/auth_controller.ts @@ -4,13 +4,12 @@ import User from '#models/user' import logger from '@adonisjs/core/services/logger' export default class AuthController { - /** * Registers a user using the provided email, password, and full name. - * - * @bodyParam *email* - string | The email of the user. - * @bodyParam *password* - string | The password of the user. - * @bodyParam *fullName* - string | The full name of the user. + * + * @bodyParam *email* - string | The email of the user. + * @bodyParam *password* - string | The password of the user. + * @bodyParam *fullName* - string | The full name of the user. * @returns The user access token. */ async register({ request }: HttpContext) { @@ -19,16 +18,15 @@ export default class AuthController { const user = await User.create(data) logger.info('User registered: %s, %s, %s', user.fullName, user.email, request.ip()) return User.accessTokens.create(user) - } - catch(error) { - logger.error('Registration failed: %s',error) - throw(error) + } catch (error) { + logger.error('Registration failed: %s', error) + throw error } } /** * Log in a user using the provided email and password. - * + * * @bodyParam *email* - string | The email of the user. * @bodyParam *password* - string | The password of the user. * @returns The access token of the user. @@ -39,17 +37,12 @@ export default class AuthController { const user = await User.verifyCredentials(email, password) logger.info('User logged in: %s', email) return User.accessTokens.create(user) - } - catch(error) { - logger.error('Login failed: %s',error) + } catch (error) { + logger.error('Login failed: %s', error) throw error } } - - - - /** * Deletes the user's access token and logs them out. If the user is not * authenticated, returns an unauthorized message. @@ -60,10 +53,9 @@ export default class AuthController { try { await User.accessTokens.delete(user, user.currentAccessToken.identifier) return { message: 'User logged out' } - } - catch(error){ - logger.error('Logout failed: %s',error) - throw(error) + } catch (error) { + logger.error('Logout failed: %s', error) + throw error } } diff --git a/app/controllers/restaurant_menu_items_controller.ts b/app/controllers/restaurant_menu_items_controller.ts old mode 100644 new mode 100755 index 28308eb..4bb7233 --- a/app/controllers/restaurant_menu_items_controller.ts +++ b/app/controllers/restaurant_menu_items_controller.ts @@ -1,120 +1,132 @@ import type { HttpContext } from '@adonisjs/core/http' import RestaurantMenuItem from '#models/restaurant_menu_item' +import RestaurantMenu from '#models/restaurant_menu' import logger from '@adonisjs/core/services/logger' import { menuItemValidator } from '#validators/menu' export default class RestaurantMenuItemsController { + /** + * Retrieve all restaurant menu items. + * + * @returns An array of all restaurant menu items. + */ + async getAll() { + const items = await RestaurantMenuItem.query().preload('category').preload('menus') + return items + } - /** - * Retrieve all restaurant menu items. - * - * @returns An array of all restaurant menu items. - */ - async getAll() { - const items = await RestaurantMenuItem.all() - return items + /** + * Retrieve a single restaurant menu item. + * + * @param request - The HTTP context containing the request data. + * @returns The restaurant menu item with the specified id. + */ + + async getOne({ request }: HttpContext) { + try { + const id = request.body().id + const item = await RestaurantMenuItem.query() + .where('id', id) + .preload('category') + .preload('menus') + .first() + return item + } catch (error) { + logger.error('Menu item retrieval failed: %s', error) } + } - /** - * Retrieve a single restaurant menu item. - * - * @param request - The HTTP context containing the request data. - * @returns The restaurant menu item with the specified id. - */ + // The following methods require authentication. Log user activity. - async getOne({request}: HttpContext) { - try { - const id = request.body().id - const item = await RestaurantMenuItem.find(id) - return item - } - catch (error) { - logger.error('Menu item retrieval failed: %s',error) - } + /** + * Create a restaurant menu item. + * + * @bodyParam *name* - string | The name of the menu item. + * @bodyParam *priceSmall* - number | The price of the small serving of the menu item. + * @bodyParam *priceLarge* - number | The price of the large serving of the menu item. + * @bodyParam *description* - string | The description of the menu item. + * @bodyParam *menu_id* - number | The menu id of the menu item. + * @returns The created menu item. + */ + async create({ request, auth }: HttpContext) { + const data = await request.validateUsing(menuItemValidator) + try { + const item = await RestaurantMenuItem.create(data) + logger.info('Menu item created: %s by %s', item.name, auth.getUserOrFail().email) + return item + } catch (error) { + logger.error('Menu item creation failed: %s', error) } + } - // The following methods require authentication. Log user activity. - - /** - * Create a restaurant menu item. - * - * @bodyParam *name* - string | The name of the menu item. - * @bodyParam *priceSmall* - number | The price of the small serving of the menu item. - * @bodyParam *priceLarge* - number | The price of the large serving of the menu item. - * @bodyParam *description* - string | The description of the menu item. - * @bodyParam *menu_id* - number | The menu id of the menu item. - * @returns The created menu item. - */ - async create({request, auth}: HttpContext) { - const data = await request.validateUsing(menuItemValidator) - try { - const item = await RestaurantMenuItem.create(data) - logger.info('Menu item created: %s by %s', item.name, auth.getUserOrFail().email) - return item - } - catch(error) { - logger.error('Menu item creation failed: %s',error) - } + /** + * Update a restaurant menu item. + * + * @bodyParam *id* - number | The id of the menu item to update. + * @bodyParam *name* - string | The new name of the menu item. + * @bodyParam *priceSmall* - number | The new price of the small size of the menu item. + * @bodyParam *priceLarge* - number | The new price of the large size of the menu item. + * @bodyParam *description* - string | The new description of the menu item. + * @bodyParam *menu_id* - number | The new menu id of the menu item. + */ + async update({ request, auth }: HttpContext) { + const data = request.body() + try { + const item = await RestaurantMenuItem.find(data.id) + item?.merge(data) + await item?.save() + logger.info('Menu item updated: %s by %s', item?.name, auth.getUserOrFail().email) + } catch (error) { + logger.error('Menu item update failed: %s', error) } + } - /** - * Update a restaurant menu item. - * - * @bodyParam *id* - number | The id of the menu item to update. - * @bodyParam *name* - string | The new name of the menu item. - * @bodyParam *priceSmall* - number | The new price of the small size of the menu item. - * @bodyParam *priceLarge* - number | The new price of the large size of the menu item. - * @bodyParam *description* - string | The new description of the menu item. - * @bodyParam *menu_id* - number | The new menu id of the menu item. - */ - async update({request, auth}: HttpContext) { - const data = request.body() - try { - const item = await RestaurantMenuItem.find(data.id) - item?.merge(data) - await item?.save() - logger.info('Menu item updated: %s by %s', item?.name, auth.getUserOrFail().email) - } - catch(error) { - logger.error('Menu item update failed: %s',error) - } + /** + * Delete a restaurant menu item. + * + * @bodyParam *id* - number | The id of the menu item to delete. + */ + async delete({ request, auth, response }: HttpContext) { + const id = request.body().id + try { + const item = await RestaurantMenuItem.find(id) + if (!item) { + return response.notFound({ message: 'Menu item not found' }) + } + // Detach from all menus first + await item.related('menus').detach() + await item.delete() + logger.info('Menu item deleted: %s by %s', item.name, auth.getUserOrFail().email) + return response.ok({ message: 'Menu item deleted' }) + } catch (error) { + logger.error('Menu item deletion failed: %s', error) + return response.internalServerError({ message: 'Menu item deletion failed' }) } + } - /** - * Delete a restaurant menu item. - * - * @bodyParam *id* - number | The id of the menu item to delete. - */ - async delete({request, auth}: HttpContext) { - const id = request.body().id - try { - const item = await RestaurantMenuItem.find(id) - await item?.delete() - logger.info('Menu item deleted: %s by %s', item?.name, auth.getUserOrFail().email) - } - catch(error) { - logger.error('Menu item deletion failed: %s',error) - } - } + // This method connects the menu item to a menu. - // This method connects the menu item to a menu. - - /** - * Connect a restaurant menu item to a restaurant menu. - * - * @bodyParam *item_id* - number | The id of the menu item to connect. - * @bodyParam *menu_id* - number | The id of the menu to connect the menu item to. - */ - async connectToMenu({request}: HttpContext) { - const data = request.body() - try { - const item = await RestaurantMenuItem.find(data.item_id) - const menu = await data.menu_id - item?.merge({menu_id: menu}) - await item?.save() - } - catch(error) { - logger.error('Menu item connection failed: %s',error) - } + /** + * Connect a restaurant menu item to a restaurant menu. + * + * @bodyParam *item_id* - number | The id of the menu item to connect. + * @bodyParam *menu_id* - number | The id of the menu to connect the menu item to. + */ + async connectToMenu({ request, response }: HttpContext) { + const data = request.body() + try { + const item = await RestaurantMenuItem.find(data.item_id) + const menu = await RestaurantMenu.find(data.menu_id) + + if (!item || !menu) { + return response.notFound({ message: 'Menu or Item not found' }) + } + + await item.related('menus').attach([menu.id]) + return response.ok({ message: 'Menu item connected to menu' }) + } catch (error) { + logger.error('Menu item connection failed: %s', error) + return response.internalServerError({ message: 'Menu item connection failed' }) } -} \ No newline at end of file + } +} diff --git a/app/controllers/restaurant_menus_controller.ts b/app/controllers/restaurant_menus_controller.ts old mode 100644 new mode 100755 index 891657c..93a3a75 --- a/app/controllers/restaurant_menus_controller.ts +++ b/app/controllers/restaurant_menus_controller.ts @@ -1,90 +1,99 @@ // import type { HttpContext } from '@adonisjs/core/http' -import RestaurantMenu from "#models/restaurant_menu" -import { HttpContext } from "@adonisjs/core/http" -import logger from "@adonisjs/core/services/logger" +import RestaurantMenu from '#models/restaurant_menu' +import { HttpContext } from '@adonisjs/core/http' +import logger from '@adonisjs/core/services/logger' export default class RestaurantMenusController { - - /** - * Retrieve all restaurant menus. - * - * @returns An array of all restaurant menus. - */ - async getAll() { - const menus = await RestaurantMenu.all() - return menus - } - /** - * Retrieve a restaurant menu. - * - * @bodyParam id number The id of the menu to retrieve. - * @returns The retrieved menu. - */ - async getOne({ request }: HttpContext) { - const id = request.body().id - try { - const menu = await RestaurantMenu.find(id) - return menu - } - catch (error) { - logger.error('Menu retrieval failed: %s', error) - } + /** + * Retrieve all restaurant menus. + * + * @returns An array of all restaurant menus. + */ + async getAll() { + const menus = await RestaurantMenu.query().preload('items', (itemsQuery) => { + itemsQuery.preload('category') + }) + return menus + } + /** + * Retrieve a restaurant menu. + * + * @bodyParam id number The id of the menu to retrieve. + * @returns The retrieved menu. + */ + async getOne({ request }: HttpContext) { + const id = request.body().id + try { + const menu = await RestaurantMenu.query() + .where('id', id) + .preload('items', (itemsQuery) => { + itemsQuery.preload('category') + }) + .first() + return menu + } catch (error) { + logger.error('Menu retrieval failed: %s', error) } + } - /** - * Create a restaurant menu. - * - * @bodyParam name string The name of the menu. - * @bodyParam description string The description of the menu. - * @returns The created menu. - */ - async create({ request, auth }: HttpContext) { - const data = request.body() - try { - const menu = await RestaurantMenu.create(data) - logger.info('Menu created: %s by %s', menu.name, auth.getUserOrFail().email) - return menu - } - catch (error) { - logger.error('Menu creation failed: %s', error) - } + /** + * Create a restaurant menu. + * + * @bodyParam name string The name of the menu. + * @bodyParam description string The description of the menu. + * @returns The created menu. + */ + async create({ request, auth }: HttpContext) { + const data = request.body() + try { + const menu = await RestaurantMenu.create(data) + logger.info('Menu created: %s by %s', menu.name, auth.getUserOrFail().email) + return menu + } catch (error) { + logger.error('Menu creation failed: %s', error) } + } - /** - * Update a restaurant menu. - * - * @bodyParam id number The id of the menu to update. - * @bodyParam name string The new name of the menu. - */ - async update({ request, auth }: HttpContext) { - const data = request.body() - try { - const menu = await RestaurantMenu.find(data.id) - menu?.merge(data) - await menu?.save() - logger.info('Menu updated: %s by %s', menu?.name, auth.getUserOrFail().email) - } - catch (error) { - logger.error('Menu update failed: %s', error) - } + /** + * Update a restaurant menu. + * + * @bodyParam id number. The id of the menu to update. + * @bodyParam name string. The new name of the menu. + */ + async update({ request, auth }: HttpContext) { + const data = request.body() + try { + const menu = await RestaurantMenu.find(data.id) + menu?.merge(data) + await menu?.save() + logger.info('Menu updated: %s by %s', menu?.name, auth.getUserOrFail().email) + } catch (error) { + logger.error('Menu update failed: %s', error) } + } + /** + * Delete a restaurant menu. + * + * @bodyParam id number. The id of the menu to delete. + */ + async delete({ request, auth, response }: HttpContext) { + const id = request.body().id + try { + const menu = await RestaurantMenu.find(id) + if (!menu) { + return response.notFound({ message: 'Menu not found' }) + } - /** - * Delete a restaurant menu. - * - * @bodyParam id number The id of the menu to delete. - */ - async delete({ request, auth }: HttpContext) { - const id = request.body().id - try { - const menu = await RestaurantMenu.find(id) - await menu?.delete() - logger.info('Menu deleted: %s by %s', menu?.name, auth.getUserOrFail().email) - } - catch (error) { - logger.error('Menu deletion failed: %s', error) - } + // Detach all menu items before deleting the menu + await menu.related('items').detach() + await menu.delete() + logger.info('Menu deleted: %s by %s', menu.name, auth.getUserOrFail().email) + return response.ok({ message: 'Menu deleted' }) + } catch (error) { + logger.error('Menu deletion failed: %s', error) + return response.internalServerError({ message: 'Menu deletion failed' }) } -} \ No newline at end of file + } +} diff --git a/app/exceptions/handler.ts b/app/exceptions/handler.ts old mode 100644 new mode 100755 diff --git a/app/middleware/auth_middleware.ts b/app/middleware/auth_middleware.ts old mode 100644 new mode 100755 diff --git a/app/middleware/container_bindings_middleware.ts b/app/middleware/container_bindings_middleware.ts old mode 100644 new mode 100755 diff --git a/app/middleware/force_json_response_middleware.ts b/app/middleware/force_json_response_middleware.ts old mode 100644 new mode 100755 diff --git a/app/models/restaurant_menu.ts b/app/models/restaurant_menu.ts old mode 100644 new mode 100755 index bb5ea54..5a7dc9e --- a/app/models/restaurant_menu.ts +++ b/app/models/restaurant_menu.ts @@ -1,6 +1,6 @@ import { DateTime } from 'luxon' -import { BaseModel, column, hasMany } from '@adonisjs/lucid/orm' -import type { HasMany } from '@adonisjs/lucid/types/relations' +import { BaseModel, column, manyToMany } from '@adonisjs/lucid/orm' +import type { ManyToMany } from '@adonisjs/lucid/types/relations' import RestaurantMenuItem from './restaurant_menu_item.js' export default class RestaurantMenu extends BaseModel { @@ -16,6 +16,14 @@ export default class RestaurantMenu extends BaseModel { @column() declare name: string - @hasMany(() => RestaurantMenuItem) - declare items: HasMany -} \ No newline at end of file + @column({ columnName: 'name_hu' }) + declare nameHu: string | null + + @column({ columnName: 'name_en' }) + declare nameEn: string | null + + @manyToMany(() => RestaurantMenuItem, { + pivotTable: 'menu_item_menus', + }) + declare items: ManyToMany +} diff --git a/app/models/restaurant_menu_item.ts b/app/models/restaurant_menu_item.ts old mode 100644 new mode 100755 index 7b882d2..1ef7739 --- a/app/models/restaurant_menu_item.ts +++ b/app/models/restaurant_menu_item.ts @@ -1,5 +1,8 @@ import { DateTime } from 'luxon' -import { BaseModel, column } from '@adonisjs/lucid/orm' +import { BaseModel, column, belongsTo, manyToMany } from '@adonisjs/lucid/orm' +import type { BelongsTo, ManyToMany } from '@adonisjs/lucid/types/relations' +import Category from '#models/category' +import RestaurantMenu from '#models/restaurant_menu' export default class RestaurantMenuItem extends BaseModel { @column({ isPrimary: true }) @@ -14,6 +17,12 @@ export default class RestaurantMenuItem extends BaseModel { @column() declare name: string + @column({ columnName: 'name_hu' }) + declare nameHu: string | null + + @column({ columnName: 'name_en' }) + declare nameEn: string | null + @column() declare priceSmall: number @@ -23,9 +32,20 @@ export default class RestaurantMenuItem extends BaseModel { @column() declare description: string | null - //connet to restaurant_menu - @column() - declare menu_id: number | null + @column({ columnName: 'description_hu' }) + declare descriptionHu: string | null + @column({ columnName: 'description_en' }) + declare descriptionEn: string | null -} \ No newline at end of file + @column({ columnName: 'category_id' }) + declare categoryId: number | null + + @belongsTo(() => Category) + declare category: BelongsTo + + @manyToMany(() => RestaurantMenu, { + pivotTable: 'menu_item_menus', + }) + declare menus: ManyToMany +} diff --git a/app/models/user.ts b/app/models/user.ts old mode 100644 new mode 100755 index bcae077..1354000 --- a/app/models/user.ts +++ b/app/models/user.ts @@ -20,6 +20,9 @@ export default class User extends compose(BaseModel, AuthFinder) { @column() declare email: string + @column() + declare role: string + @column({ serializeAs: null }) declare password: string diff --git a/app/validators/auth.ts b/app/validators/auth.ts old mode 100644 new mode 100755 index 311fda1..db3d9df --- a/app/validators/auth.ts +++ b/app/validators/auth.ts @@ -13,7 +13,8 @@ export const registerValidator = vine.compile( return !match }), password, - fullName: vine.string() + fullName: vine.string(), + role: vine.string().optional(), }) ) export const loginValidator = vine.compile( diff --git a/app/validators/menu.ts b/app/validators/menu.ts old mode 100644 new mode 100755 index 2032418..1466e2d --- a/app/validators/menu.ts +++ b/app/validators/menu.ts @@ -1,10 +1,14 @@ -import vine from "@vinejs/vine"; +import vine from '@vinejs/vine' export const menuItemValidator = vine.compile( - vine.object({ - name: vine.string(), - priceSmall: vine.number(), - priceLarge: vine.number(), - description: vine.string(), - }) -); \ No newline at end of file + vine.object({ + name: vine.string(), + nameHu: vine.string(), + nameEn: vine.string(), + priceSmall: vine.number(), + priceLarge: vine.number(), + description: vine.string().optional(), + descriptionHu: vine.string().optional(), + descriptionEn: vine.string().optional(), + }) +) diff --git a/bin/console.ts b/bin/console.ts old mode 100644 new mode 100755 diff --git a/bin/server.ts b/bin/server.ts old mode 100644 new mode 100755 diff --git a/compose.yaml b/compose.yaml old mode 100644 new mode 100755 index 1a70ce3..65227ca --- a/compose.yaml +++ b/compose.yaml @@ -1,5 +1,4 @@ services: - db: image: postgres ports: @@ -17,8 +16,4 @@ services: POSTGRES_PASSWORD: Paprika_2025 POSTGRES_USER: paprika POSTGRES_DB: paprika - adminer: - image: adminer - restart: always - ports: - - 8080:8080 + diff --git a/config/app.ts b/config/app.ts old mode 100644 new mode 100755 diff --git a/config/auth.ts b/config/auth.ts old mode 100644 new mode 100755 diff --git a/config/bodyparser.ts b/config/bodyparser.ts old mode 100644 new mode 100755 diff --git a/config/cors.ts b/config/cors.ts old mode 100644 new mode 100755 diff --git a/config/database.ts b/config/database.ts old mode 100644 new mode 100755 index cdd2d3d..a97bc71 --- a/config/database.ts +++ b/config/database.ts @@ -21,4 +21,4 @@ const dbConfig = defineConfig({ }, }) -export default dbConfig \ No newline at end of file +export default dbConfig diff --git a/config/hash.ts b/config/hash.ts old mode 100644 new mode 100755 diff --git a/config/limiter.ts b/config/limiter.ts old mode 100644 new mode 100755 index e2595cc..106d417 --- a/config/limiter.ts +++ b/config/limiter.ts @@ -7,19 +7,18 @@ const limiterConfig = defineConfig({ /** * Database store to save rate limiting data inside a * MYSQL or PostgreSQL database. - */ - database: stores.database({ - connectionName: 'postgres', - dbName: env.get('DB_DATABASE'), - tableName: 'rate_limits', - clearExpiredByTimeout: false + */ + database: stores.database({ + connectionName: 'postgres', + dbName: env.get('DB_DATABASE'), + tableName: 'rate_limits', + clearExpiredByTimeout: false, }), - /** * Memory store could be used during * testing - */ - memory: stores.memory({}), + */ + memory: stores.memory({}), }, }) @@ -28,4 +27,3 @@ export default limiterConfig declare module '@adonisjs/limiter/types' { export interface LimitersList extends InferLimiters {} } - diff --git a/config/logger.ts b/config/logger.ts old mode 100644 new mode 100755 index b961300..c866906 --- a/config/logger.ts +++ b/config/logger.ts @@ -17,7 +17,7 @@ const loggerConfig = defineConfig({ transport: { targets: targets() .pushIf(!app.inProduction, targets.pretty()) - .pushIf(app.inProduction, targets.file({ destination: 1 })) + .pushIf(app.inProduction, targets.file({ destination: './logs/app.log' })) .toArray(), }, }, diff --git a/database/migrations/1744568171094_create_users_table.ts b/database/migrations/1744568171094_create_users_table.ts deleted file mode 100644 index d6a6798..0000000 --- a/database/migrations/1744568171094_create_users_table.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { BaseSchema } from '@adonisjs/lucid/schema' - -export default class extends BaseSchema { - protected tableName = 'users' - - async up() { - this.schema.createTable(this.tableName, (table) => { - table.increments('id').notNullable() - table.string('full_name').nullable() - table.string('email', 254).notNullable().unique() - table.string('password').notNullable() - - table.timestamp('created_at').notNullable() - table.timestamp('updated_at').nullable() - }) - } - - async down() { - this.schema.dropTable(this.tableName) - } -} \ No newline at end of file diff --git a/database/migrations/1744568171095_create_access_tokens_table.ts b/database/migrations/1744568171095_create_access_tokens_table.ts deleted file mode 100644 index a3ce197..0000000 --- a/database/migrations/1744568171095_create_access_tokens_table.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { BaseSchema } from '@adonisjs/lucid/schema' - -export default class extends BaseSchema { - protected tableName = 'auth_access_tokens' - - async up() { - this.schema.createTable(this.tableName, (table) => { - table.increments('id') - table - .integer('tokenable_id') - .notNullable() - .unsigned() - .references('id') - .inTable('users') - .onDelete('CASCADE') - - table.string('type').notNullable() - table.string('name').nullable() - table.string('hash').notNullable() - table.text('abilities').notNullable() - table.timestamp('created_at') - table.timestamp('updated_at') - table.timestamp('last_used_at').nullable() - table.timestamp('expires_at').nullable() - }) - } - - async down() { - this.schema.dropTable(this.tableName) - } -} diff --git a/database/migrations/1748532404153_create_dbs_table.ts b/database/migrations/1748532404153_create_dbs_table.ts deleted file mode 100644 index feb16fb..0000000 --- a/database/migrations/1748532404153_create_dbs_table.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { BaseSchema } from '@adonisjs/lucid/schema' - -export default class extends BaseSchema { - protected tableName = 'dbs' - - async up() { - this.schema.createTable(this.tableName, (table) => { - table.increments('id') - - table.timestamp('created_at') - table.timestamp('updated_at') - }) - } - - async down() { - this.schema.dropTable(this.tableName) - } -} \ No newline at end of file diff --git a/database/migrations/1748802217892_create_rate_limits_table.ts b/database/migrations/1748802217892_create_rate_limits_table.ts deleted file mode 100644 index 6d46ced..0000000 --- a/database/migrations/1748802217892_create_rate_limits_table.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { BaseSchema } from '@adonisjs/lucid/schema' - -export default class extends BaseSchema { - protected tableName = 'rate_limits' - - async up() { - this.schema.createTable(this.tableName, (table) => { - table.string('key', 255).notNullable().primary() - table.integer('points', 9).notNullable().defaultTo(0) - table.bigint('expire').unsigned() - }) - } - - async down() { - this.schema.dropTable(this.tableName) - } -} \ No newline at end of file diff --git a/database/migrations/1753030795466_create_restaurant_menus_table.ts b/database/migrations/1753030795466_create_restaurant_menus_table.ts deleted file mode 100644 index 465d52d..0000000 --- a/database/migrations/1753030795466_create_restaurant_menus_table.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { BaseSchema } from '@adonisjs/lucid/schema' - -export default class extends BaseSchema { - protected tableName = 'restaurant_menus' - - async up() { - this.schema.createTable(this.tableName, (table) => { - table.increments('id').primary() - - table.string('name').notNullable() - - table.timestamp('created_at') - table.timestamp('updated_at') - }) - } - - async down() { - this.schema.dropTable(this.tableName) - } -} \ No newline at end of file diff --git a/database/migrations/1753031513937_create_restaurant_menu_items_table.ts b/database/migrations/1753031513937_create_restaurant_menu_items_table.ts deleted file mode 100644 index 86bd56f..0000000 --- a/database/migrations/1753031513937_create_restaurant_menu_items_table.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { BaseSchema } from '@adonisjs/lucid/schema' - -export default class extends BaseSchema { - protected tableName = 'restaurant_menu_items' - - async up() { - this.schema.createTable(this.tableName, (table) => { - table.increments('id').primary() - table.integer('restaurant_menu_id').unsigned().references('restaurant_menus.id') - table.string('name').notNullable() - table.integer('price_small').notNullable() - table.integer('price_large').notNullable() - table.string('description').nullable() - - table.timestamp('created_at') - table.timestamp('updated_at') - }) - } - - async down() { - this.schema.dropTable(this.tableName) - } -} \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js old mode 100644 new mode 100755 diff --git a/package-lock.json b/package-lock.json old mode 100644 new mode 100755 index 2091962..9d16287 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "license": "UNLICENSED", "dependencies": { + "@adonisjs/ally": "^5.0.0", "@adonisjs/auth": "^9.3.1", "@adonisjs/core": "^6.17.2", "@adonisjs/cors": "^2.2.1", @@ -61,6 +62,22 @@ "node": ">=18.16.0" } }, + "node_modules/@adonisjs/ally": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@adonisjs/ally/-/ally-5.1.1.tgz", + "integrity": "sha512-Uu+g5y7jnmMP0iXhPYTx9caJnovp+CTqxDN6XpyuLQGVZjNr9fqbPeaBVs1/jTAVSAtpv4UrHsb+827XXd24Jw==", + "license": "MIT", + "dependencies": { + "@poppinss/oauth-client": "^7.0.1", + "@poppinss/utils": "^6.10.1" + }, + "engines": { + "node": ">=20.6.0" + }, + "peerDependencies": { + "@adonisjs/core": "^6.2.0" + } + }, "node_modules/@adonisjs/application": { "version": "8.3.1", "resolved": "https://registry.npmjs.org/@adonisjs/application/-/application-8.3.1.tgz", @@ -152,22 +169,22 @@ } }, "node_modules/@adonisjs/bodyparser": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@adonisjs/bodyparser/-/bodyparser-10.0.3.tgz", - "integrity": "sha512-rgnAE+w7/+8tlCG+GxT8/99TLyccMFHtUyIP99K4YbSg0af6kTHrbXOJkKE8YHKU8cFwECybu3uZOoIoHOYLyQ==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@adonisjs/bodyparser/-/bodyparser-10.1.2.tgz", + "integrity": "sha512-Lp419XmpMOq878Ee9V1Iqu2vGHEFBMUrUK3A3Fz3/dCP70E40esRf7wzTvRe+YZfXqQLaz1XCE0xfy3lj9wA9Q==", "license": "MIT", "dependencies": { "@paralleldrive/cuid2": "^2.2.2", - "@poppinss/macroable": "^1.0.4", + "@poppinss/macroable": "^1.1.0", "@poppinss/multiparty": "^2.0.1", - "@poppinss/utils": "^6.9.2", - "@types/qs": "^6.9.18", + "@poppinss/utils": "^6.10.1", + "@types/qs": "^6.14.0", "bytes": "^3.1.2", - "file-type": "^20.1.0", + "file-type": "^21.1.1", "inflation": "^2.1.0", "media-typer": "^1.1.0", "qs": "^6.14.0", - "raw-body": "^3.0.0" + "raw-body": "^3.0.1" }, "engines": { "node": ">=18.16.0" @@ -634,6 +651,16 @@ "node": ">=6.9.0" } }, + "node_modules/@borewit/text-codec": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.1.tgz", + "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@chevrotain/cst-dts-gen": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", @@ -1007,7 +1034,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@japa/assert/-/assert-4.0.1.tgz", "integrity": "sha512-n/dA9DVLNvM/Bw8DtN8kBdPjYsSHe3XTRjF5+U8vlzDavpW9skUANl2CHR1K/TBWZxwMfGi15SJIjo6UCs09AA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@poppinss/macroable": "^1.0.4", @@ -1165,15 +1192,6 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@lukeed/ms": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz", - "integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@noble/hashes": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", @@ -1320,13 +1338,10 @@ } }, "node_modules/@poppinss/exception": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.1.tgz", - "integrity": "sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==", - "license": "MIT", - "engines": { - "node": ">=18" - } + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", + "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", + "license": "MIT" }, "node_modules/@poppinss/hooks": { "version": "7.2.5", @@ -1338,13 +1353,10 @@ } }, "node_modules/@poppinss/macroable": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@poppinss/macroable/-/macroable-1.0.4.tgz", - "integrity": "sha512-ct43jurbe7lsUX5eIrj4ijO3j/6zIPp7CDnFWXDs7UPAbw1Pu1iH3oAmFdP4jcskKJBURH5M9oTtyeiUXyHX8Q==", - "license": "MIT", - "engines": { - "node": ">=18.16.0" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@poppinss/macroable/-/macroable-1.1.0.tgz", + "integrity": "sha512-y/YKzZDuG8XrpXpM7Z1RdQpiIc0MAKyva24Ux1PB4aI7RiSI/79K8JVDcdyubriTm7vJ1LhFs8CrZpmPnx/8Pw==", + "license": "MIT" }, "node_modules/@poppinss/matchit": { "version": "3.1.2", @@ -1375,6 +1387,19 @@ "uid-safe": "2.1.5" } }, + "node_modules/@poppinss/oauth-client": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@poppinss/oauth-client/-/oauth-client-7.0.2.tgz", + "integrity": "sha512-7zFnfGtd7oLb9Ox9Kz77QwU8t4IV8PdHIicSkLgXGis1ZfLb/853dm+26xz0dPo0qZCJvbBVelgmDvm+JFMhQw==", + "license": "MIT", + "dependencies": { + "@poppinss/exception": "^1.2.2", + "ky": "^1.14.1" + }, + "engines": { + "node": ">=24.0.0" + } + }, "node_modules/@poppinss/object-builder": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@poppinss/object-builder/-/object-builder-1.1.0.tgz", @@ -1400,36 +1425,29 @@ } }, "node_modules/@poppinss/string": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@poppinss/string/-/string-1.2.0.tgz", - "integrity": "sha512-1z78zjqhfjqsvWr+pQzCpRNcZpIM+5vNY5SFOvz28GrL/LRanwtmOku5tBX7jE8/ng3oXaOVrB59lnnXFtvkug==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@poppinss/string/-/string-1.7.1.tgz", + "integrity": "sha512-OrLzv/nGDU6l6dLXIQHe8nbNSWWfuSbpB/TW5nRpZFf49CLuQlIHlSPN9IdSUv2vG+59yGM6LoibsaHn8B8mDw==", "license": "MIT", "dependencies": { - "@lukeed/ms": "^2.0.2", - "@types/bytes": "^3.1.5", "@types/pluralize": "^0.0.33", - "bytes": "^3.1.2", - "case-anything": "^3.1.0", + "case-anything": "^3.1.2", "pluralize": "^8.0.0", - "slugify": "^1.6.6", - "truncatise": "^0.0.8" - }, - "engines": { - "node": ">=20.6.0" + "slugify": "^1.6.6" } }, "node_modules/@poppinss/utils": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/@poppinss/utils/-/utils-6.9.2.tgz", - "integrity": "sha512-ypVszZxhwiehhklM5so2BI+nClQJwp7mBUSJh/R1GepeUH1vvD5GtxMz8Lp9dO9oAbKyDmq1jc4g/4E0dv8r2g==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@poppinss/utils/-/utils-6.10.1.tgz", + "integrity": "sha512-da+MMyeXhBaKtxQiWPfy7+056wk3lVIhioJnXHXkJ2/OHDaZfFcyKHNl1R06sdYO8lIRXcXdoZ6LO2ARmkAREA==", "license": "MIT", "dependencies": { - "@poppinss/exception": "^1.2.0", + "@poppinss/exception": "^1.2.1", "@poppinss/object-builder": "^1.1.0", - "@poppinss/string": "^1.1.0", + "@poppinss/string": "^1.3.0", "flattie": "^1.1.1", "safe-stable-stringify": "^2.5.0", - "secure-json-parse": "^3.0.1" + "secure-json-parse": "^4.0.0" }, "engines": { "node": ">=18.16.0" @@ -1732,14 +1750,13 @@ } }, "node_modules/@tokenizer/inflate": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", - "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "fflate": "^0.8.2", - "token-types": "^6.0.0" + "debug": "^4.4.3", + "token-types": "^6.1.1" }, "engines": { "node": ">=18" @@ -1796,17 +1813,11 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/bytes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.5.tgz", - "integrity": "sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ==", - "license": "MIT" - }, "node_modules/@types/chai": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.1.tgz", "integrity": "sha512-iu1JLYmGmITRzUgNiLMZD3WCoFzpYtueuyAgHTXqgwSRAMIlFTnZqG6/xenkpUGRJEzSfklUTI4GNSzks/dc0w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/deep-eql": "*" @@ -1823,7 +1834,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/estree": { @@ -1884,9 +1895,9 @@ "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.18", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", - "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "license": "MIT" }, "node_modules/@types/superagent": { @@ -2271,7 +2282,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=12" @@ -2342,9 +2353,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2507,7 +2518,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "assertion-error": "^2.0.1", @@ -2563,7 +2574,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 16" @@ -2955,9 +2966,9 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3000,7 +3011,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -3697,12 +3708,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "license": "MIT" - }, "node_modules/figures": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", @@ -3733,18 +3738,18 @@ } }, "node_modules/file-type": { - "version": "20.4.1", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.4.1.tgz", - "integrity": "sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==", + "version": "21.3.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.0.tgz", + "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", "license": "MIT", "dependencies": { - "@tokenizer/inflate": "^0.2.6", - "strtok3": "^10.2.0", - "token-types": "^6.0.0", + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sindresorhus/file-type?sponsor=1" @@ -4195,19 +4200,23 @@ } }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/human-signals": { @@ -4221,15 +4230,19 @@ } }, "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { @@ -4525,9 +4538,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -4715,6 +4728,18 @@ "node": ">=8" } }, + "node_modules/ky": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.1.tgz", + "integrity": "sha512-hYje4L9JCmpEQBtudo+v52X5X8tgWXUYyPcxKSuxQNboqufecl9VMWjGiucAFH060AwPXHZuH+WB2rrqfkmafw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4865,7 +4890,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/lru-cache": { @@ -5457,25 +5482,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 14.16" } }, - "node_modules/peek-readable": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-7.0.0.tgz", - "integrity": "sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/pg": { "version": "8.14.1", "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.1.tgz", @@ -5974,9 +5986,9 @@ } }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -6047,18 +6059,18 @@ "license": "ISC" }, "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.10" } }, "node_modules/react-is": { @@ -6478,9 +6490,9 @@ "license": "MIT" }, "node_modules/secure-json-parse": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-3.0.2.tgz", - "integrity": "sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", "funding": [ { "type": "github", @@ -6795,9 +6807,9 @@ } }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -6899,13 +6911,12 @@ } }, "node_modules/strtok3": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.2.2.tgz", - "integrity": "sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==", + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", "license": "MIT", "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^7.0.0" + "@tokenizer/token": "^0.3.0" }, "engines": { "node": ">=18" @@ -7079,11 +7090,12 @@ } }, "node_modules/token-types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz", - "integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", "license": "MIT", "dependencies": { + "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" }, @@ -7095,12 +7107,6 @@ "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/truncatise": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/truncatise/-/truncatise-0.0.8.tgz", - "integrity": "sha512-cXzueh9pzBCsLzhToB4X4gZCb3KYkrsAcBAX97JnazE74HOl3cpBJYEV7nabHeG/6/WXCU5Yujlde/WPBUwnsg==", - "license": "MIT" - }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -7287,9 +7293,9 @@ } }, "node_modules/uint8array-extras": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz", - "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", "license": "MIT", "engines": { "node": ">=18" @@ -7387,9 +7393,9 @@ } }, "node_modules/validator": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.0.tgz", - "integrity": "sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==", + "version": "13.15.26", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz", + "integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==", "license": "MIT", "engines": { "node": ">= 0.10" diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 98c110e..893a36c --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "module", "license": "UNLICENSED", "scripts": { - "start": "node bin/server.js", + "start": "node bin/server.ts", "build": "node ace build", "dev": "node ace serve --hmr", "test": "node ace test", @@ -52,6 +52,7 @@ }, "dependencies": { "@adonisjs/auth": "^9.3.1", + "@adonisjs/ally": "^5.0.0", "@adonisjs/core": "^6.17.2", "@adonisjs/cors": "^2.2.1", "@adonisjs/limiter": "^2.4.0", diff --git a/start/env.ts b/start/env.ts old mode 100644 new mode 100755 diff --git a/start/kernel.ts b/start/kernel.ts old mode 100644 new mode 100755 index 2ffd205..5dbfd8e --- a/start/kernel.ts +++ b/start/kernel.ts @@ -32,12 +32,16 @@ server.use([ * The router middleware stack runs middleware on all the HTTP * requests with a registered route. */ -router.use([() => import('@adonisjs/core/bodyparser_middleware'), () => import('@adonisjs/auth/initialize_auth_middleware')]) +router.use([ + () => import('@adonisjs/core/bodyparser_middleware'), + () => import('@adonisjs/auth/initialize_auth_middleware'), +]) /** * Named middleware collection must be explicitly assigned to * the routes or the routes group. */ export const middleware = router.named({ - auth: () => import('#middleware/auth_middleware') + auth: () => import('#middleware/auth_middleware'), + admin: () => import('#middleware/admin_middleware'), }) diff --git a/start/routes.ts b/start/routes.ts old mode 100644 new mode 100755 index 42e1ff1..d649795 --- a/start/routes.ts +++ b/start/routes.ts @@ -14,26 +14,123 @@ import { throttle } from '#start/limiter' const AuthController = () => import('#controllers/auth_controller') const RestaurantMenuItemsController = () => import('#controllers/restaurant_menu_items_controller') const RestaurantMenusController = () => import('#controllers/restaurant_menus_controller') +const CategoriesController = () => import('#controllers/categories_controller') +const UsersController = () => import('#controllers/users_controller') +const ImagesController = () => import('#controllers/images_controller') -//Auth routes -router.post('/register', [AuthController, 'register']).as('auth.register').use(throttle) -router.post('/login', [AuthController, 'login']).as('auth.login').use(throttle) -router.delete('/logout', [AuthController, 'logout']).as('auth.logout').use(middleware.auth()) -router.get('/me', [AuthController, 'me']).as('auth.me').use(middleware.auth()) - - +// Auth routes +router.group(() => { + router.post('/register', [AuthController, 'register']).as('auth.register').use(throttle) + router.post('/login', [AuthController, 'login']).as('auth.login').use(throttle) + router.delete('/logout', [AuthController, 'logout']).as('auth.logout').use(middleware.auth()) + router.get('/me', [AuthController, 'me']).as('auth.me').use(middleware.auth()).use(throttle) +}) // RestaurantMenuItem routes -router.get('/api/menu-items', [RestaurantMenuItemsController, 'getAll']).as('menu-items.getAll') -router.post('/api/menu-items', [RestaurantMenuItemsController, 'getOne']).as('menu-items.getOne') -router.post('/api/menu-items/create', [RestaurantMenuItemsController, 'create']).as('menu-items.create').use(middleware.auth()) -router.put('/api/menu-items', [RestaurantMenuItemsController, 'update']).as('menu-items.update').use(middleware.auth()) -router.delete('/api/menu-items', [RestaurantMenuItemsController, 'delete']).as('menu-items.delete').use(middleware.auth()).use(throttle) +router + .group(() => { + router + .group(() => { + router.get('/', [RestaurantMenuItemsController, 'getAll']).as('menu-items.getAll') + router + .post('/', [RestaurantMenuItemsController, 'getOne']) + .as('menu-items.getOne') + .use([middleware.auth(), middleware.admin()]) + router + .post('/create', [RestaurantMenuItemsController, 'create']) + .as('menu-items.create') + .use([middleware.auth(), middleware.admin()]) + router + .put('/', [RestaurantMenuItemsController, 'update']) + .as('menu-items.update') + .use([middleware.auth(), middleware.admin()]) + router + .delete('/', [RestaurantMenuItemsController, 'delete']) + .as('menu-items.delete') + .use([middleware.auth(), middleware.admin(), throttle]) + router + .post('/attach', [RestaurantMenuItemsController, 'connectToMenu']) + .as('menu-items.attach') + .use([middleware.auth(), middleware.admin()]) + }) + .prefix('/menu-items') + // RestaurantMenu routes + router + .group(() => { + router.get('/', [RestaurantMenusController, 'getAll']).as('menus.getAll') + router + .post('/', [RestaurantMenusController, 'getOne']) + .as('menus.getOne') + .use([middleware.auth(), middleware.admin()]) + router + .post('/create', [RestaurantMenusController, 'create']) + .as('menus.create') + .use([middleware.auth(), middleware.admin()]) + router + .put('/', [RestaurantMenusController, 'update']) + .as('menus.update') + .use([middleware.auth(), middleware.admin()]) + router + .delete('/', [RestaurantMenusController, 'delete']) + .as('menus.delete') + .use([middleware.auth(), middleware.admin(), throttle]) + }) + .prefix('/menus') + // Category routes + router + .group(() => { + router.get('/', [CategoriesController, 'getAll']).as('categories.getAll') + router + .post('/', [CategoriesController, 'getOne']) + .as('categories.getOne') + .use([middleware.auth(), middleware.admin()]) + router + .post('/create', [CategoriesController, 'create']) + .as('categories.create') + .use([middleware.auth(), middleware.admin()]) + router + .put('/', [CategoriesController, 'update']) + .as('categories.update') + .use([middleware.auth(), middleware.admin()]) + router + .delete('/', [CategoriesController, 'delete']) + .as('categories.delete') + .use([middleware.auth(), middleware.admin(), throttle]) + }) + .prefix('/categories') -// RestaurantMenu routes -router.get('/api/menus', [RestaurantMenusController, 'getAll']).as('menus.getAll') -router.post('/api/menus', [RestaurantMenusController, 'getOne']).as('menus.getOne') -router.post('/api/menus/create', [RestaurantMenusController, 'create']).as('menus.create').use(middleware.auth()) -router.put('/api/menus', [RestaurantMenusController, 'update']).as('menus.update').use(middleware.auth()) -router.delete('/api/menus', [RestaurantMenusController, 'delete']).as('menus.delete').use(middleware.auth()).use(throttle) + // User routes + router + .group(() => { + router.get('/', [UsersController, 'getAll']).as('users.getAll').use(middleware.auth()) + router + .post('/', [UsersController, 'create']) + .as('users.create') + .use([middleware.auth(), middleware.admin()]) + router + .post('/get-one', [UsersController, 'getOne']) + .as('users.getOne') + .use([middleware.auth(), middleware.admin()]) + router + .put('/', [UsersController, 'update']) + .as('users.update') + .use([middleware.auth(), middleware.admin()]) + router + .delete('/', [UsersController, 'delete']) + .as('users.delete') + .use([middleware.auth(), middleware.admin()]) + }) + .prefix('/users') + // Image routes + router + .group(() => { + router + .post('/upload', [ImagesController, 'upload']) + .as('images.upload') + .use([middleware.auth(), middleware.admin()]) + router.get('/:filename', [ImagesController, 'show']).as('images.show') + }) + .prefix('/images') + }) + .prefix('/api') diff --git a/tests/bootstrap.ts b/tests/bootstrap.ts old mode 100644 new mode 100755 index 09b0cfc..be26211 --- a/tests/bootstrap.ts +++ b/tests/bootstrap.ts @@ -5,7 +5,6 @@ import type { Config } from '@japa/runner/types' import { pluginAdonisJS } from '@japa/plugin-adonisjs' import testUtils from '@adonisjs/core/services/test_utils' - /** * This file is imported by the "bin/test.ts" entrypoint file */ @@ -19,7 +18,8 @@ export const plugins: Config['plugins'] = [ apiClient({ baseURL: 'http://localhost:3333', }), - pluginAdonisJS(app)] + pluginAdonisJS(app), +] /** * Configure lifecycle function to run before and after all the diff --git a/tests/unit/restaurant_menu_items/create.spec.ts b/tests/unit/restaurant_menu_items/create.spec.ts old mode 100644 new mode 100755 index 3872e81..c3af5ce --- a/tests/unit/restaurant_menu_items/create.spec.ts +++ b/tests/unit/restaurant_menu_items/create.spec.ts @@ -1,21 +1,9 @@ import { test } from '@japa/runner' test.group('Restaurant menu items', () => { - test('create', async ({ assert, client }) => { - const item = { - name: 'test', - priceSmall: 10, - priceLarge: 20, - description: 'test' - } - const response = await client.post('/api/menu-items/create').json(item) - assert.equal(response.body().name, item.name) - assert.equal(response.body().priceSmall, item.priceSmall) - assert.equal(response.body().priceLarge, item.priceLarge) - assert.equal(response.body().description, item.description) - }), test('get all', async ({ assert, client }) => { const response = await client.get('/api/menu-items') + assert.equal(response.status(), 200) assert.isArray(response.body()) }) -}) \ No newline at end of file +}) diff --git a/tsconfig.json b/tsconfig.json old mode 100644 new mode 100755