Merge branch 'release/1.3.2'

This commit is contained in:
Sergey Yarkov 2022-06-07 00:13:54 +03:00
commit 2ebb21cdc1
37 changed files with 13682 additions and 2891 deletions

View File

@ -15,7 +15,7 @@
"project": "./tsconfig.json",
"include": ["src/**/*.ts", "src/**/*.js", "test/**/*.ts"]
},
"plugins": ["@typescript-eslint"],
"plugins": ["@typescript-eslint", "import"],
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error"]

View File

@ -1,5 +1,19 @@
# Changelog
## [1.3.2] - 2022-06-06
## Added
- Updated npm dependencies
- [Added](https://github.com/sergeyyarkov/educt-server/commit/294a4f584dd39d295372802305004365fb01fdb2) `MAILER` env variable
## Fix
- Fixed schema validator on saving lesson order
- Fixed lesson [duration updating](https://github.com/sergeyyarkov/educt-server/commit/ffdebc4f927abe3b63c62c84268f40f9e6663895#diff-86d18314585862595621b4e90f675b79ac74e7a0a47b2797556902eeff75e14a)
- Updated cors config
- Deleted `api` from path url
## [1.3.1] - 2022-04-10
## Added

View File

@ -11,19 +11,66 @@
},
"list:routes": {
"settings": {
"loadApp": true
"loadApp": true,
"stayAlive": true
},
"commandPath": "@adonisjs/core/build/commands/ListRoutes",
"commandPath": "@adonisjs/core/build/commands/ListRoutes/index",
"commandName": "list:routes",
"description": "List application routes",
"args": [],
"aliases": [],
"flags": [
{
"name": "verbose",
"propertyName": "verbose",
"type": "boolean",
"description": "Display more information"
},
{
"name": "reverse",
"propertyName": "reverse",
"type": "boolean",
"alias": "r",
"description": "Reverse routes display"
},
{
"name": "methods",
"propertyName": "methodsFilter",
"type": "array",
"alias": "m",
"description": "Filter routes by method"
},
{
"name": "patterns",
"propertyName": "patternsFilter",
"type": "array",
"alias": "p",
"description": "Filter routes by the route pattern"
},
{
"name": "names",
"propertyName": "namesFilter",
"type": "array",
"alias": "n",
"description": "Filter routes by route name"
},
{
"name": "json",
"propertyName": "json",
"type": "boolean",
"description": "Output as JSON"
},
{
"name": "table",
"propertyName": "table",
"type": "boolean",
"description": "Output as Table"
},
{
"name": "max-width",
"propertyName": "maxWidth",
"type": "number",
"description": "Specify maximum rendering width. Ignored for JSON Output"
}
]
},
@ -55,7 +102,7 @@
},
"commandPath": "@adonisjs/lucid/build/commands/DbSeed",
"commandName": "db:seed",
"description": "Execute database seeder files",
"description": "Execute database seeders",
"args": [],
"aliases": [],
"flags": [
@ -79,6 +126,12 @@
"type": "array",
"description": "Define a custom set of seeders files names to run",
"alias": "f"
},
{
"name": "compact-output",
"propertyName": "compactOutput",
"type": "boolean",
"description": "A compact single-line output"
}
]
},
@ -113,6 +166,13 @@
"type": "boolean",
"alias": "c",
"description": "Generate the controller for the model"
},
{
"name": "factory",
"propertyName": "factory",
"type": "boolean",
"alias": "f",
"description": "Generate a factory for the model"
}
]
},
@ -177,13 +237,81 @@
"aliases": [],
"flags": []
},
"make:factory": {
"settings": {},
"commandPath": "@adonisjs/lucid/build/commands/MakeFactory",
"commandName": "make:factory",
"description": "Make a new factory",
"args": [
{
"type": "string",
"propertyName": "model",
"name": "model",
"required": true,
"description": "The name of the model"
}
],
"aliases": [],
"flags": [
{
"name": "model-path",
"propertyName": "modelPath",
"type": "string",
"description": "The path to the model"
},
{
"name": "exact",
"propertyName": "exact",
"type": "boolean",
"description": "Create the factory with the exact name as provided",
"alias": "e"
}
]
},
"db:wipe": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/DbWipe",
"commandName": "db:wipe",
"description": "Drop all tables, views and types in database",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection",
"alias": "c"
},
{
"name": "drop-views",
"propertyName": "dropViews",
"type": "boolean",
"description": "Drop all views"
},
{
"name": "drop-types",
"propertyName": "dropTypes",
"type": "boolean",
"description": "Drop all custom types (Postgres only)"
},
{
"name": "force",
"propertyName": "force",
"type": "boolean",
"description": "Explicitly force command to run in production"
}
]
},
"migration:run": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Run",
"commandName": "migration:run",
"description": "Run pending migrations",
"description": "Migrate database by running pending migrations",
"args": [],
"aliases": [],
"flags": [
@ -204,7 +332,13 @@
"name": "dry-run",
"propertyName": "dryRun",
"type": "boolean",
"description": "Print SQL queries, instead of running the migrations"
"description": "Do not run actual queries. Instead view the SQL output"
},
{
"name": "compact-output",
"propertyName": "compactOutput",
"type": "boolean",
"description": "A compact single-line output"
}
]
},
@ -214,7 +348,7 @@
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Rollback",
"commandName": "migration:rollback",
"description": "Rollback migrations to a given batch number",
"description": "Rollback migrations to a specific batch number",
"args": [],
"aliases": [],
"flags": [
@ -235,13 +369,19 @@
"name": "dry-run",
"propertyName": "dryRun",
"type": "boolean",
"description": "Print SQL queries, instead of running the migrations"
"description": "Do not run actual queries. Instead view the SQL output"
},
{
"name": "batch",
"propertyName": "batch",
"type": "number",
"description": "Define custom batch number for rollback. Use 0 to rollback to initial state"
},
{
"name": "compact-output",
"propertyName": "compactOutput",
"type": "boolean",
"description": "A compact single-line output"
}
]
},
@ -251,7 +391,7 @@
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Status",
"commandName": "migration:status",
"description": "Check migrations current status.",
"description": "View migrations status",
"args": [],
"aliases": [],
"flags": [
@ -264,6 +404,117 @@
}
]
},
"migration:reset": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Reset",
"commandName": "migration:reset",
"description": "Rollback all migrations",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection",
"alias": "c"
},
{
"name": "force",
"propertyName": "force",
"type": "boolean",
"description": "Explicitly force command to run in production"
},
{
"name": "dry-run",
"propertyName": "dryRun",
"type": "boolean",
"description": "Do not run actual queries. Instead view the SQL output"
}
]
},
"migration:refresh": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Refresh",
"commandName": "migration:refresh",
"description": "Rollback and migrate database",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection",
"alias": "c"
},
{
"name": "force",
"propertyName": "force",
"type": "boolean",
"description": "Explicitly force command to run in production"
},
{
"name": "dry-run",
"propertyName": "dryRun",
"type": "boolean",
"description": "Do not run actual queries. Instead view the SQL output"
},
{
"name": "seed",
"propertyName": "seed",
"type": "boolean",
"description": "Run seeders"
}
]
},
"migration:fresh": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Fresh",
"commandName": "migration:fresh",
"description": "Drop all tables and re-migrate the database",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection",
"alias": "c"
},
{
"name": "force",
"propertyName": "force",
"type": "boolean",
"description": "Explicitly force command to run in production"
},
{
"name": "seed",
"propertyName": "seed",
"type": "boolean",
"description": "Run seeders"
},
{
"name": "drop-views",
"propertyName": "dropViews",
"type": "boolean",
"description": "Drop all views"
},
{
"name": "drop-types",
"propertyName": "dropTypes",
"type": "boolean",
"description": "Drop all custom types (Postgres only)"
}
]
},
"make:mailer": {
"settings": {},
"commandPath": "@adonisjs/mail/build/commands/MakeMailer",

View File

@ -1,6 +1,6 @@
import { Exception, inject, Ioc } from '@adonisjs/core/build/standalone';
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import { schema } from '@ioc:Adonis/Core/Validator';
import { schema, rules } from '@ioc:Adonis/Core/Validator';
/**
* Services
@ -141,7 +141,7 @@ export default class LessonsController extends BaseController {
// eslint-disable-next-line class-methods-use-this
public async saveOrder(ctx: HttpContextContract) {
const saveOrderSchema = schema.create({
ids: schema.array().members(schema.string()),
ids: schema.array([rules.minLength(1)]).members(schema.string()),
});
const payload = await ctx.request.validate({ schema: saveOrderSchema });
const { data, message, status, success, error } = await this.lessonService.updateOrder(payload.ids);

View File

@ -237,6 +237,7 @@ export default class CourseRepository {
public async delete(id: string | number): Promise<Course | null> {
const course = await this.Course.query()
.preload('category')
.preload('lessons', q => q.preload('video').preload('materials'))
.withCount('students')
.withCount('likes')
.withCount('lessons')

View File

@ -144,12 +144,13 @@ export default class LessonRepository {
if (lesson) {
/**
* Update files
* Update fields
*/
lesson.merge({
title: data.title,
description: data.description,
course_id: data.course_id,
...(data.duration && { duration: data.duration.toFormat('HH:mm:ss') }),
});
/**

View File

@ -72,7 +72,7 @@ export default class AuthService {
});
/**
* Set cookie toke to response
* Set cookie token to response
*/
ctx.response.cookie('token', token.token);

View File

@ -25,6 +25,7 @@ import CreateCourseValidator from 'App/Validators/Course/CreateCourseValidator';
import UpdateCourseValidator from 'App/Validators/Course/UpdateCourseValidator';
import FetchCoursesValidator from 'App/Validators/Course/FetchCoursesValidator';
import Course from 'App/Models/Course';
import Drive from '@ioc:Adonis/Core/Drive';
@inject()
export default class CourseService {
@ -310,6 +311,24 @@ export default class CourseService {
};
}
/**
* Collect all file names from lessons in course and delete files
*/
const videos: string[] = course.lessons.map(lesson => lesson.video.name);
const materials: string[] = course.lessons.map(lesson => lesson.materials.map(m => m.name)).flat();
await Promise.all(
videos.map(async name => {
await Drive.delete(`videos/${name}`);
})
);
await Promise.all(
materials.map(async name => {
await Drive.delete(`materials/${name}`);
})
);
return {
success: true,
status: HttpStatusEnum.OK,

View File

@ -56,7 +56,6 @@ class RedisSessionStore {
public async getSessions(): Promise<Array<SessionDataType | undefined>> {
const keys = await this.scanSessionKeys();
const commands = Array.from(keys).map(key => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [, ...id] = key.split('-');
return ['hmget', id.join('-'), 'userId', 'userName', 'connected'];
});
@ -64,7 +63,10 @@ class RedisSessionStore {
return this.redisClient
.multi(commands)
.exec()
.then(results => results.map(([err, session]) => (err ? undefined : this.transform(session))));
.then(results => {
if (results === null) return [];
return results.map(([err, session]: [Error, (string | null)[]]) => (err ? undefined : this.transform(session)));
});
}
/**

View File

@ -7,7 +7,7 @@ export default class CreateContactsValidator {
public schema = schema.create({
phone_number: schema.string.nullableAndOptional({}, [
rules.mobile({
locales: ['ru-RU', 'en-US'],
locale: ['ru-RU', 'en-US'],
strict: true,
}),
]),

View File

@ -7,7 +7,7 @@ export default class UpdateContactsValidator {
public schema = schema.create({
phone_number: schema.string.nullableAndOptional({}, [
rules.mobile({
locales: ['ru-RU', 'en-US'],
locale: ['ru-RU', 'en-US'],
strict: true,
}),
rules.unique({ table: 'contacts', column: 'phone_number' }),

View File

@ -11,7 +11,7 @@ export default class CreateCourseValidator {
education_description: schema.string.nullable(),
image: schema.file.optional({
size: '10mb',
extnames: ['jpg', 'jpeg', 'png'],
extnames: ['jpg', 'jpeg', 'png', 'webp'],
}),
teacher_id: schema.string({}, [rules.exists({ table: 'users', column: 'id' })]),
category_id: schema.string({}, [rules.exists({ table: 'categories', column: 'id' })]),

View File

@ -10,7 +10,7 @@ export default class UpdateCourseValidator {
education_description: schema.string.nullable(),
image: schema.file.optional({
size: '10mb',
extnames: ['jpg', 'jpeg', 'png'],
extnames: ['jpg', 'jpeg', 'png', 'webp'],
}),
teacher_id: schema.string.optional({}, [rules.exists({ table: 'users', column: 'id' })]),
category_id: schema.string.optional({}, [rules.exists({ table: 'categories', column: 'id' })]),

View File

@ -7,7 +7,7 @@ export default class UpdateUserInfoValidator {
public schema = schema.create({
about: schema.string.nullableAndOptional(),
phone_number: schema.string.nullableAndOptional({}, [
rules.mobile({ locales: ['ru-RU', 'en-US'], strict: true }),
rules.mobile({ locale: ['ru-RU', 'en-US'], strict: true }),
rules.unique({ table: 'contacts', column: 'phone_number' }),
]),
vk_id: schema.string.nullableAndOptional({}, [

View File

@ -106,8 +106,8 @@ export const http: ServerConfig = {
path: '/',
maxAge: '1d',
httpOnly: true,
secure: false,
sameSite: false,
secure: true,
sameSite: 'none',
},
/*

View File

@ -6,7 +6,7 @@
*/
import Env from '@ioc:Adonis/Core/Env';
import { DriveConfig } from '@ioc:Adonis/Core/Drive';
import { driveConfig } from '@adonisjs/core/build/config';
import Application from '@ioc:Adonis/Core/Application';
/*
@ -18,7 +18,7 @@ import Application from '@ioc:Adonis/Core/Application';
| defined inside the `contracts` directory.
|
*/
const driveConfig: DriveConfig = {
export default driveConfig({
/*
|--------------------------------------------------------------------------
| Default disk
@ -143,6 +143,4 @@ const driveConfig: DriveConfig = {
// usingUniformAcl: false
// },
},
};
export default driveConfig;
});

View File

@ -6,7 +6,7 @@
*/
import Env from '@ioc:Adonis/Core/Env';
import { HashConfig } from '@ioc:Adonis/Core/Hash';
import { hashConfig } from '@adonisjs/core/build/config';
/*
|--------------------------------------------------------------------------
@ -17,7 +17,7 @@ import { HashConfig } from '@ioc:Adonis/Core/Hash';
| defined inside `contracts` directory.
|
*/
const hashConfig: HashConfig = {
export default hashConfig({
/*
|--------------------------------------------------------------------------
| Default hasher
@ -70,6 +70,4 @@ const hashConfig: HashConfig = {
rounds: 10,
},
},
};
export default hashConfig;
});

View File

@ -6,9 +6,9 @@
*/
import Env from '@ioc:Adonis/Core/Env';
import { MailConfig } from '@ioc:Adonis/Addons/Mail';
import { mailConfig } from '@adonisjs/mail/build/config';
const mailConfig: MailConfig = {
export default mailConfig({
/*
|--------------------------------------------------------------------------
| Default mailer
@ -18,7 +18,7 @@ const mailConfig: MailConfig = {
| a mailer
|
*/
mailer: 'mailgun',
mailer: Env.get('MAILER'),
/*
|--------------------------------------------------------------------------
@ -71,6 +71,4 @@ const mailConfig: MailConfig = {
domain: Env.get('MAILGUN_DOMAIN'),
},
},
};
export default mailConfig;
});

View File

@ -1,16 +1,6 @@
import { InferDisksFromConfig } from '@adonisjs/core/build/config';
import driveConfig from '../config/drive';
declare module '@ioc:Adonis/Core/Drive' {
interface DisksList {
local: {
config: LocalDriverConfig;
implementation: LocalDriverContract;
};
s3: {
config: S3DriverConfig;
implementation: S3DriverContract;
};
// gcs: {
// config: GcsDriverConfig
// implementation: GcsDriverContract
// }
}
interface DisksList extends InferDisksFromConfig<typeof driveConfig> {}
}

View File

@ -1,19 +1,6 @@
/**
* Contract source: https://git.io/Jfefs
*
* Feel free to let us know via PR, if you find something broken in this contract
* file.
*/
import { InferListFromConfig } from '@adonisjs/core/build/config';
import hashConfig from '../config/hash';
declare module '@ioc:Adonis/Core/Hash' {
interface HashersList {
bcrypt: {
config: BcryptConfig;
implementation: BcryptContract;
};
argon: {
config: ArgonConfig;
implementation: ArgonContract;
};
}
interface HashersList extends InferListFromConfig<typeof hashConfig> {}
}

View File

@ -1,15 +1,6 @@
/**
* Contract source: https://git.io/JvgAT
*
* Feel free to let us know via PR, if you find something broken in this contract
* file.
*/
import { InferMailersFromConfig } from '@adonisjs/mail/build/config';
import mailConfig from '../config/mail';
declare module '@ioc:Adonis/Addons/Mail' {
import { MailDrivers } from '@ioc:Adonis/Addons/Mail';
interface MailersList {
smtp: MailDrivers['smtp'];
mailgun: MailDrivers['mailgun'];
}
interface MailersList extends InferMailersFromConfig<typeof mailConfig> {}
}

View File

@ -1,4 +1,4 @@
import Factory from '@ioc:Adonis/Lucid/Factory';
import Factory, { FactoryContextContract } from '@ioc:Adonis/Lucid/Factory';
import { string } from '@ioc:Adonis/Core/Helpers';
/**
@ -18,7 +18,7 @@ import Role from 'App/Models/Role';
import User from 'App/Models/User';
import { DateTime } from 'luxon';
const makeFakeUser = (faker: Faker.FakerStatic, loginPrefix?: string) => {
const makeFakeUser = (faker: FactoryContextContract['faker'], loginPrefix?: string) => {
return {
first_name: faker.name.firstName(),
last_name: faker.name.lastName(),

3
env.ts
View File

@ -19,7 +19,7 @@ export default Env.rules({
PORT: Env.schema.number(),
APP_KEY: Env.schema.string(),
APP_NAME: Env.schema.string(),
NODE_ENV: Env.schema.enum(['development', 'production', 'testing'] as const),
NODE_ENV: Env.schema.enum(['development', 'production', 'test'] as const),
DRIVE_DISK: Env.schema.enum(['local', 's3'] as const),
PG_HOST: Env.schema.string({ format: 'host' }),
PG_PORT: Env.schema.number(),
@ -30,6 +30,7 @@ export default Env.rules({
REDIS_HOST: Env.schema.string({ format: 'host' }),
REDIS_PORT: Env.schema.number(),
REDIS_PASSWORD: Env.schema.string.optional(),
MAILER: Env.schema.enum(['mailgun', 'smtp'] as const),
SMTP_HOST: Env.schema.string({ format: 'host' }),
SMTP_PORT: Env.schema.number(),
SMTP_USERNAME: Env.schema.string(),

16045
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "server",
"version": "1.3.1",
"version": "1.3.2",
"private": true,
"scripts": {
"build": "node ace build --production",
@ -15,44 +15,44 @@
"db:seed:force": "node ace seed --force"
},
"devDependencies": {
"@adonisjs/assembler": "^5.3.7",
"@typescript-eslint/eslint-plugin": "^4.30.0",
"@typescript-eslint/parser": "^4.30.0",
"@adonisjs/assembler": "^5.7.0",
"@typescript-eslint/eslint-plugin": "^5.27.0",
"@typescript-eslint/parser": "^5.27.0",
"adonis-preset-ts": "^2.1.0",
"eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-airbnb-typescript": "^12.3.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-prettier": "^3.4.1",
"pino-pretty": "^5.1.3",
"prettier": "^2.3.2",
"typescript": "^4.4.2",
"youch": "^2.2.2",
"youch-terminal": "^1.1.1"
"eslint": "^8.17.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.0.0",
"pino-pretty": "^8.0.0",
"prettier": "^2.6.2",
"typescript": "^4.7.3",
"youch": "^3.2.0",
"youch-terminal": "^2.1.4"
},
"dependencies": {
"@adonisjs/application": "^5.2.0",
"@adonisjs/attachment-lite": "^1.0.1",
"@adonisjs/auth": "^8.0.10",
"@adonisjs/bouncer": "^2.2.5",
"@adonisjs/core": "^5.4.2",
"@adonisjs/drive": "^2.0.7",
"@adonisjs/drive-s3": "^1.0.5",
"@adonisjs/lucid": "^16.3.2",
"@adonisjs/mail": "^7.2.4",
"@adonisjs/redis": "^7.1.0",
"@adonisjs/repl": "^3.1.7",
"@adonisjs/view": "^6.1.1",
"@adonisjs/application": "^5.2.5",
"@adonisjs/attachment-lite": "^1.0.7",
"@adonisjs/auth": "^8.2.1",
"@adonisjs/bouncer": "^2.3.0",
"@adonisjs/core": "^5.8.3",
"@adonisjs/drive": "^2.2.0",
"@adonisjs/drive-s3": "^1.3.1",
"@adonisjs/lucid": "^18.0.1",
"@adonisjs/mail": "^8.1.2",
"@adonisjs/redis": "^7.3.0",
"@adonisjs/repl": "^3.1.11",
"@adonisjs/view": "^6.1.5",
"@types/socket.io": "^3.0.2",
"cloudinary": "^1.26.3",
"luxon": "^1.28.0",
"nanoid": "^3.1.25",
"pg": "^8.7.1",
"luxon": "^2.4.0",
"nanoid": "^3.3.4",
"pg": "^8.7.3",
"phc-bcrypt": "^1.0.7",
"proxy-addr": "^2.0.7",
"reflect-metadata": "^0.1.13",
"socket.io": "^4.4.1",
"source-map-support": "^0.5.19"
"socket.io": "^4.5.1",
"source-map-support": "^0.5.21"
}
}

View File

@ -21,5 +21,3 @@ const server = new Ignitor(__dirname).httpServer();
server.start().catch(error => {
throw new Error(error);
});
process.on('SIGINT', () => server.kill(10));

View File

@ -3,4 +3,4 @@ import Route from '@ioc:Adonis/Core/Route';
Route.group(() => {
Route.post('login', 'Api/v1/AuthController.login').as('auth.login');
Route.post('logout', 'Api/v1/AuthController.logout').middleware('auth').as('auth.logout');
}).prefix('api/v1/auth');
}).prefix('v1/auth');

View File

@ -7,5 +7,5 @@ Route.group(() => {
Route.delete('/:id', 'Api/v1/CategoriesController.delete').middleware('role:admin,teacher').as('categories.delete');
Route.patch('/:id', 'Api/v1/CategoriesController.update').middleware('role:admin,teacher').as('categories.update');
})
.prefix('api/v1/categories')
.prefix('v1/categories')
.middleware('auth');

View File

@ -5,5 +5,5 @@ Route.group(() => {
.middleware('role:admin,teacher,student')
.as('chat.get-conversations');
})
.prefix('api/v1/chat')
.prefix('v1/chat')
.middleware('auth');

View File

@ -62,5 +62,5 @@ Route.group(() => {
.middleware('role:admin,teacher,student')
.as('courses.get-lessons-progress');
})
.prefix('api/v1/courses')
.prefix('v1/courses')
.middleware('auth');

View File

@ -9,5 +9,5 @@ Route.group(() => {
return report.healthy ? ctx.response.ok(report) : ctx.response.badRequest(report);
}).as('health');
})
.prefix('api/v1/health')
.prefix('v1/health')
.middleware('auth');

View File

@ -6,5 +6,5 @@ Route.group(() => {
Route.get('/', 'Api/v1/ImagesController.list').as('images.list');
Route.get('/:id', 'Api/v1/ImagesController.show').as('images.show');
})
.prefix('api/v1/images')
.prefix('v1/images')
.middleware('auth');

View File

@ -19,5 +19,5 @@ Route.group(() => {
.middleware('role:admin,teacher,student')
.as('lessons.get-video-progress');
})
.prefix('api/v1/lessons')
.prefix('v1/lessons')
.middleware('auth');

View File

@ -19,5 +19,5 @@ Route.group(() => {
.middleware('role:admin,teacher,student')
.as('me.update-contacts');
})
.prefix('api/v1/me')
.prefix('v1/me')
.middleware('auth');

View File

@ -3,5 +3,5 @@ import Route from '@ioc:Adonis/Core/Route';
Route.group(() => {
Route.get('/', 'Api/v1/StatController.index').middleware('role:admin,teacher,student').as('stat.index');
})
.prefix('api/v1/stat')
.prefix('v1/stat')
.middleware('auth');

View File

@ -13,5 +13,5 @@ Route.group(() => {
.middleware('role:admin')
.as('users.detach-role');
})
.prefix('api/v1/users')
.prefix('v1/users')
.middleware('auth');

View File

@ -1,30 +1,17 @@
{
"extends": "./node_modules/adonis-preset-ts/tsconfig",
"include": [
"**/*"
],
"exclude": [
"node_modules",
"build"
],
"include": ["**/*"],
"exclude": ["node_modules", "build"],
"compilerOptions": {
"outDir": "build",
"rootDir": "./",
"sourceMap": true,
"useDefineForClassFields": true,
"paths": {
"App/*": [
"./app/*"
],
"Config/*": [
"./config/*"
],
"Contracts/*": [
"./contracts/*"
],
"Database/*": [
"./database/*"
]
"App/*": ["./app/*"],
"Config/*": ["./config/*"],
"Contracts/*": ["./contracts/*"],
"Database/*": ["./database/*"]
},
"types": [
"@adonisjs/core",