Merge pull request #3 from ArthurDanjou/dev

Merge dev into Master
This commit is contained in:
2021-11-10 12:07:36 +01:00
committed by GitHub
167 changed files with 9541 additions and 5914 deletions

10
.adonisrc.json Normal file → Executable file
View File

@@ -5,7 +5,8 @@
"@adonisjs/core/build/commands",
"@adonisjs/repl/build/commands",
"@adonisjs/lucid/build/commands",
"@adonisjs/mail/build/commands"
"@adonisjs/mail/build/commands",
"@adonisjs/bouncer/build/commands"
],
"exceptionHandlerNamespace": "App/Exceptions/Handler",
"aliases": {
@@ -16,18 +17,19 @@
},
"preloads": [
"./start/routes",
"./start/kernel"
"./start/kernel",
"./start/bouncer"
],
"providers": [
"./providers/AppProvider",
"@adonisjs/core",
"@adonisjs/redis",
"@adonisjs/session",
"@adonisjs/auth",
"@adonisjs/lucid",
"@adonisjs/mail",
"@adonisjs/view",
"@adonisjs/ally"
"@adonisjs/bouncer",
"@adonisjs/redis"
],
"aceProviders": [
"@adonisjs/repl"

1
.dockerignore Normal file → Executable file
View File

@@ -1 +1,2 @@
node_modules
.env

0
.editorconfig Normal file → Executable file
View File

28
.env.example Normal file → Executable file
View File

@@ -3,6 +3,12 @@ HOST=
NODE_ENV=
APP_KEY=
APP_NAME=
BASE_URL=
API_VERSION=
GITHUB_TOKEN=
GITHUB_SOURCE=
DISCORD_ID=
DB_CONNECTION=
@@ -20,21 +26,13 @@ REDIS_DB=
REDIS_HOST=
REDIS_PASSWORD=
GITHUB_TOKEN=
GITHUB_SOURCE=
BASE_URL=
API_VERSION=
CACHE_VIEWS=
MAILGUN_API_KEY=
MAILGUN_URL=
SMTP_HOST=
SMTP_PORT=
SMTP_USERNAME=
SMTP_PASSWORD=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
TWITTER_CLIENT_ID=
TWITTER_CLIENT_SECRET=
WAKATIME_USER=
WAKATIME_KEY=
WAKATIME_ID=

3
.eslintignore Normal file
View File

@@ -0,0 +1,3 @@
nodes_modules
.env
build

3
.eslintrc Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": "@antfu"
}

115
.gitignore vendored Normal file → Executable file
View File

@@ -1,10 +1,111 @@
node_modules
build
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
.vscode
.DS_STORE
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
tmp
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Jetbrains
.idea
# AdonisJS
database/seeders
.idea/
/database/seeders/
build

5
.idea/.gitignore generated vendored
View File

@@ -1,5 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

12
.idea/artapi.iml generated
View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/artapi.iml" filepath="$PROJECT_DIR$/.idea/artapi.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

14
Dockerfile Normal file → Executable file
View File

@@ -1,20 +1,16 @@
FROM node:15.8.0-alpine3.10
FROM node:16-alpine3.11
RUN mkdir -p /usr/src/artapi
WORKDIR /usr/src/artapi
RUN mkdir -p /usr/src/athena
COPY . /usr/src/artapi
WORKDIR /usr/src/athena
RUN apk update && \
apk add git
COPY . /usr/src/athena
RUN yarn install
RUN yarn build
RUN cp .env build
WORKDIR /usr/src/artapi/build
WORKDIR /usr/src/athena/build
RUN yarn install --production

0
LICENSE Normal file → Executable file
View File

6
README.md Normal file → Executable file
View File

@@ -1,6 +1,6 @@
# ArtApi 🧠
# Athena 🧠
ArtAPi is my personnal api connected to my instances
Athena is my personal api connected to my instances
## Features ✨
@@ -26,4 +26,4 @@ ArtAPi is my personnal api connected to my instances
## License 📑
Copyright © 2020 - [@ArthurDanj](https://arthurdanjou.fr) \
This project is [MIT](https://github.com/ArthurDanjou/artapi/blob/master/LICENSE) Licensed.
This project is [MIT](https://github.com/ArthurDanjou/athena/blob/master/LICENSE) Licensed.

0
ace Normal file → Executable file
View File

44
ace-manifest.json Normal file → Executable file
View File

@@ -2,7 +2,7 @@
"commands": {
"dump:rcfile": {
"settings": {},
"commandPath": "@adonisjs/core/build/commands/DumpRc",
"commandPath": "@adonisjs/core/commands/DumpRc",
"commandName": "dump:rcfile",
"description": "Dump contents of .adonisrc.json file along with defaults",
"args": [],
@@ -13,7 +13,7 @@
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/core/build/commands/ListRoutes",
"commandPath": "@adonisjs/core/commands/ListRoutes",
"commandName": "list:routes",
"description": "List application routes",
"args": [],
@@ -29,7 +29,7 @@
},
"generate:key": {
"settings": {},
"commandPath": "@adonisjs/core/build/commands/GenerateKey",
"commandPath": "@adonisjs/core/commands/GenerateKey",
"commandName": "generate:key",
"description": "Generate a new APP_KEY secret",
"args": [],
@@ -136,7 +136,7 @@
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection for the migration"
"description": "The connection flag is used to lookup the directory for the migration file"
},
{
"name": "folder",
@@ -278,6 +278,42 @@
],
"aliases": [],
"flags": []
},
"make:policy": {
"settings": {},
"commandPath": "@adonisjs/bouncer/build/commands/MakePolicy",
"commandName": "make:policy",
"description": "Make a new bouncer policy",
"args": [
{
"type": "string",
"propertyName": "name",
"name": "name",
"required": true,
"description": "Name of the policy to create"
}
],
"aliases": [],
"flags": [
{
"name": "resource-model",
"propertyName": "resourceModel",
"type": "string",
"description": "Name of the resource model to authorize"
},
{
"name": "user-model",
"propertyName": "userModel",
"type": "string",
"description": "Name of the user model to be authorized"
},
{
"name": "actions",
"propertyName": "actions",
"type": "array",
"description": "Actions to implement"
}
]
}
},
"aliases": {}

View File

@@ -0,0 +1,36 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Announce from 'App/Models/Announce'
import AnnounceUpdateValidator from 'App/Validators/announce/AnnounceUpdateValidator'
import File from 'App/Models/File'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class AnnouncesController {
public async index({ response }: HttpContextContract) {
const announce = await Announce
.query()
.orderBy('created_at', 'desc')
.preload('message')
.preload('cover')
.first()
return response.status(200).send({
announce,
})
}
public async update({ request, params, response }: HttpContextContract) {
const data = await request.validate(AnnounceUpdateValidator)
const announce = await Announce.findOrFail(params.id)
if (data.code)
await announce.related('message').associate(await getTranslation(data.code))
const cover = await File.findBy('label', data.cover)
if (cover) await announce.related('cover').associate(cover)
await announce.merge(data).save()
return response.status(200).send({
announce,
})
}
}

166
app/Controllers/Http/AuthController.ts Normal file → Executable file
View File

@@ -1,136 +1,52 @@
import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext'
import User from "App/Models/User";
import AuthValidator from "App/Validators/AuthValidator";
import {AllyUserContract} from "@ioc:Adonis/Addons/Ally";
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import AuthValidator from 'App/Validators/AuthValidator'
export default class AuthController {
public async loginWeb ({request, auth}: HttpContextContract) {
const data = await request.validate(AuthValidator)
const {email, password, remember_me } = data
try {
await auth.attempt(email, password, remember_me)
const user = await User.query()
.where('id', auth.user!.id)
.firstOrFail()
if (!remember_me) {
await user.merge({
rememberMeToken: ''
}).save()
}
return { user }
} catch (error) {
if (error.code === 'E_INVALID_AUTH_UID') return { error: "L'utilisateur n'a pas été trouvé" }
if (error.code === 'E_INVALID_AUTH_PASSWORD') return { error: "L'identifiant ou le mot de passe est incorrect" }
}
}
public async loginApi ({request, auth}: HttpContextContract) {
const email = request.input('email')
const password = request.input('password')
public async loginApi({ request, auth, response }: HttpContextContract) {
const { email, password } = await request.validate(AuthValidator)
const token = await auth.use('api').attempt(email, password, {
expiresIn: '2 days'
expiresIn: '2 days',
})
return response.status(200).send({
token: token.toJSON(),
})
return token.toJSON()
}
public async createInfiniteToken ({request, auth}: HttpContextContract) {
const email = request.input('email')
const password = request.input('password')
public async loginWeb({ request, auth, response }: HttpContextContract) {
const { email, password, remember } = await request.validate(AuthValidator)
await auth.use('web').attempt(email, password, remember)
return response.status(200).send({
user: auth.use('web').user,
})
}
public async createInfiniteToken({ request, auth, response }: HttpContextContract) {
const { email, password } = await request.validate(AuthValidator)
const token = await auth.use('api').attempt(email, password)
return token.toJSON()
}
public async logoutWeb ({auth}: HttpContextContract) {
await auth.logout()
return { message: 'Vous avez été déconnecté' }
}
public async logoutApi ({auth}: HttpContextContract) {
await auth.use('api').logout()
return { message: 'Vous avez été déconnecté' }
}
public async user ({auth}: HttpContextContract) {
await auth.authenticate()
return await User.query()
.where('id', auth.user!.id)
.firstOrFail()
}
public async twitter ({ally, auth}: HttpContextContract) {
const twitter = ally.use('twitter')
if (twitter.accessDenied()) {
return 'Access Denied'
}
if (twitter.stateMisMatch()) {
return 'Request expired. Retry again'
}
if (twitter.hasError()) {
return twitter.getError()
}
const twitterUser = await twitter.user()
const user = await this.createUser(twitterUser)
await auth.use('web').login(user)
return user
}
public async github ({ally, auth}: HttpContextContract) {
const github = ally.use('github')
if (github.accessDenied()) {
return 'Access Denied'
}
if (github.stateMisMatch()) {
return 'Request expired. Retry again'
}
if (github.hasError()) {
return github.getError()
}
const githubUser = await github.user()
const user = await this.createUser(githubUser)
await auth.use('web').login(user)
return user
}
public async google ({ally, auth}: HttpContextContract) {
const google = ally.use('google')
if (google.accessDenied()) {
return 'Access Denied'
}
if (google.stateMisMatch()) {
return 'Request expired. Retry again'
}
if (google.hasError()) {
return google.getError()
}
const googleUser = await google.user()
const user = await this.createUser(googleUser)
await auth.use('web').login(user)
return user
}
public async createUser(allyUser: AllyUserContract<any>): Promise<User> {
return await User.firstOrCreate({
email: allyUser.email!,
}, {
email: allyUser.email!,
username: allyUser.name,
isConfirmed: allyUser.emailVerificationState === 'verified'
return response.status(200).send({
token: token.toJSON(),
})
}
public async logoutApi({ auth, response }: HttpContextContract) {
await auth.use('api').revoke()
return response.status(200).send({
message: 'You have been disconnected!',
})
}
public async logoutWeb({ auth, response }: HttpContextContract) {
await auth.use('web').logout()
return response.status(200).send({
message: 'You have been disconnected!',
})
}
public async user({ auth, response }: HttpContextContract) {
const user = await auth.use('web').authenticate() || await auth.use('api').authenticate()
return response.status(200).send({
user,
})
}
}

View File

@@ -0,0 +1,57 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Experience from 'App/Models/Experience'
import ExperienceStoreValidator from 'App/Validators/experience/ExperienceStoreValidator'
import ExperienceUpdateValidator from 'App/Validators/experience/ExperienceUpdateValidator'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class ExperiencesController {
public async index({ response }: HttpContextContract) {
const experiences = await Experience
.query()
.orderBy('begin_date', 'desc')
.preload('title')
return response.status(200).send({
experiences,
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(ExperienceStoreValidator)
const experience = await Experience.create(data)
await experience.related('title').associate(await getTranslation(data.title))
return response.status(200).send({
experience,
})
}
public async show({ params, response }: HttpContextContract) {
const experience = await Experience.findOrFail(params.id)
experience.load('title')
return response.status(200).send({
experience,
})
}
public async update({ request, params, response }: HttpContextContract) {
const data = await request.validate(ExperienceUpdateValidator)
const experience = await Experience.findOrFail(params.id)
if (data.title)
await experience.related('title').associate(await getTranslation(data.title))
await experience.merge(data).save()
return response.status(200).send({
experience,
})
}
public async destroy({ response, params }: HttpContextContract) {
const experience = await Experience.findOrFail(params.id)
await experience.delete()
return response.status(200).send({
message: 'Experience successfully deleted!',
})
}
}

View File

@@ -1,40 +0,0 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Application from "@ioc:Adonis/Core/Application";
import File from "App/Models/File";
export default class FileController {
public async index () {
return File.query()
}
public async store ({request}: HttpContextContract) {
const file = await request.file('file', {
extnames: ['jpg', 'png', 'jpeg']
})
const label = request.input('label')
if (!file) {
return 'Please upload file'
}
if (file.hasErrors) {
return file.errors
}
await file.move(Application.makePath('storage'), {
name: `${label}.${file.extname}`
})
return await File.create({
fileName: `${label}.${file.extname}`,
label: label
})
}
public async destroy({ params }: HttpContextContract) {
const file = await File.findOrFail(params.id)
await file.delete()
return { message: "Le fichier a bien été supprimée" }
}
}

View File

@@ -0,0 +1,46 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Application from '@ioc:Adonis/Core/Application'
import File from 'App/Models/File'
export default class FilesController {
public async index({ response }: HttpContextContract) {
return response.status(200).send({
files: await File.all(),
})
}
public async store({ request, response }: HttpContextContract) {
const file = await request.file('file', {
extnames: ['jpg', 'png', 'jpeg'],
})
const label = request.input('label')
if (!file)
return 'Please upload file!'
if (file.hasErrors)
return file.errors
await file.move(Application.makePath('storage'), {
name: `${label}.${file.extname}`,
overwrite: true,
})
return response.status(200).send({
file: await File.firstOrCreate({
label,
}, {
fileName: `${label}.${file.extname}`,
label,
}),
})
}
public async destroy({ params, response }: HttpContextContract) {
const file = await File.findOrFail(params.id)
await file.delete()
return response.status(200).send({
message: 'File successfully deleted!',
})
}
}

View File

@@ -0,0 +1,64 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import FormationStoreValidator from 'App/Validators/formation/FormationStoreValidator'
import FormationUpdateValidator from 'App/Validators/formation/FormationUpdateValidator'
import Formation from 'App/Models/Formation'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class FormationsController {
public async index({ response }: HttpContextContract) {
const formations = await Formation
.query()
.orderBy('begin_date', 'desc')
.preload('title')
.preload('description')
return response.status(200).send({
formations,
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(FormationStoreValidator)
const formation = await Formation.create(data)
await formation.related('title').associate(await getTranslation(data.title))
await formation.related('description').associate(await getTranslation(data.description))
return response.status(200).send({
formation,
})
}
public async show({ params, response }: HttpContextContract) {
const formation = await Formation.findOrFail(params.id)
formation.load('title')
formation.load('description')
return response.status(200).send({
formation,
})
}
public async update({ request, params, response }: HttpContextContract) {
const data = await request.validate(FormationUpdateValidator)
const formation = await Formation.findOrFail(params.id)
if (data.title)
await formation.related('title').associate(await getTranslation(data.title))
if (data.description)
await formation.related('description').associate(await getTranslation(data.description))
await formation.merge(data).save()
return response.status(200).send({
formation,
})
}
public async destroy({ response, params }: HttpContextContract) {
const formation = await Formation.findOrFail(params.id)
await formation.delete()
return response.status(200).send({
message: 'Formation successfully deleted!',
})
}
}

37
app/Controllers/Http/FormsController.ts Normal file → Executable file
View File

@@ -1,20 +1,33 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import FormValidator from "App/Validators/FormValidator";
import Form from "App/Models/Form";
//import FormConfirmation from "App/Mailers/FormConfirmation";
import FormStoreValidator from 'App/Validators/form/FormStoreValidator'
import Form from 'App/Models/Form'
export default class FormsController {
public async send({ request, response }: HttpContextContract) {
const data = await request.validate(FormValidator)
await Form.create(data)
//await new FormConfirmation(data.name, data.email).sendLater()
//todo send confirmation email + email to me
public async index({ response }: HttpContextContract) {
return response.status(200).send({
status: 200
forms: Form.query().orderBy('created_at', 'asc'),
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(FormStoreValidator)
// todo send confirmation email + email to me with FormConfirmation
return response.status(200).send({
form: await Form.create(data),
})
}
public async show({ params, response }: HttpContextContract) {
return response.status(200).send({
form: await Form.findOrFail(params.id),
})
}
public async destroy({ response, params }: HttpContextContract) {
const form = await Form.findOrFail(params.id)
await form.delete()
return response.status(200).send({
message: 'Form successfully deleted!',
})
}
}

View File

@@ -1,16 +0,0 @@
import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext";
import GuestBookMessage from "../../Models/GuestBookMessage";
import StoreValidator from "../../Validators/guestbook/StoreValidator";
export default class GuestBookController {
public async index () {
return GuestBookMessage.query().orderBy('created_at', 'desc')
}
public async store ({request}: HttpContextContract) {
const data = await request.validate(StoreValidator)
return await GuestBookMessage.create(data)
}
}

View File

@@ -0,0 +1,31 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Information from 'App/Models/Information'
import InformationUpdateValidator from 'App/Validators/information/InformationUpdateValidator'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class InformationsController {
public async index({ response }: HttpContextContract) {
return response.status(200).send({
informations: await Information
.query()
.preload('translation')
.first(),
})
}
public async update({ response, request }: HttpContextContract) {
const information = await Information.firstOrFail()
const data = await request.validate(InformationUpdateValidator)
if (data.code) {
const translation = await getTranslation(data.code)
await information.related('translation').associate(translation)
}
await information.merge(data).save()
return response.status(200).send({
information,
})
}
}

35
app/Controllers/Http/LocationsController.ts Normal file → Executable file
View File

@@ -1,24 +1,31 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Location from "App/Models/Location";
import LocationValidator from "App/Validators/location/LocationValidator";
import Location from 'App/Models/Location'
import LocationValidator from 'App/Validators/location/LocationValidator'
export default class LocationsController {
public async get ({ response }: HttpContextContract) {
const location = await Location.query().orderBy('since', 'desc').firstOrFail()
return response.status(200).send({
place: location.place,
left: location.left,
since: location.since
})
public async index({ response }: HttpContextContract) {
const location = await Location.query().orderBy('since', 'desc').first()
if (location) {
return response.status(200).send({
location: {
place: location.place,
left: location.left,
since: location.since,
},
})
}
else {
return response.status(200).send({
location: 'Location is unknown...',
})
}
}
public async add ({ request, response }: HttpContextContract) {
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(LocationValidator)
await Location.create(data)
const location = await Location.create(data)
return response.status(200).send({
message: 'Location successfully added !'
location,
})
}
}

View File

@@ -0,0 +1,31 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Maintenance from 'App/Models/Maintenance'
import MaintenanceUpdateValidator from 'App/Validators/maintenance/MaintenanceUpdateValidator'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class MaintenancesController {
public async index({ response }: HttpContextContract) {
const maintenance = await Maintenance
.query()
.orderBy('created_at', 'desc')
.preload('reason')
.first()
return response.status(200).send({
maintenance,
})
}
public async update({ request, params, response }: HttpContextContract) {
const data = await request.validate(MaintenanceUpdateValidator)
const maintenance = await Maintenance.findOrFail(params.id)
if (data.reason)
await maintenance.related('reason').associate(await getTranslation(data.reason))
await maintenance.merge(data).save()
return response.status(200).send({
maintenance,
})
}
}

View File

@@ -0,0 +1,44 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import PostColor from 'App/Models/PostColor'
import PostColorStoreValidator from 'App/Validators/postColor/PostColorStoreValidator'
import PostColorUpdateValidator from 'App/Validators/postColor/PostColorUpdateValidator'
export default class PostColorsController {
public async index({ response }: HttpContextContract) {
return response.status(200).send({
post_colors: await PostColor.all(),
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(PostColorStoreValidator)
const postColor = await PostColor.create(data)
return response.status(200).send({
post_color: postColor,
})
}
public async show({ params, response }: HttpContextContract) {
const postColor = await PostColor.findOrFail(params.id)
return response.status(200).send({
post_color: postColor,
})
}
public async update({ request, params, response }: HttpContextContract) {
const data = await request.validate(PostColorUpdateValidator)
const postColor = await PostColor.findOrFail(params.id)
await postColor.merge(data).save()
return response.status(200).send({
post_color: postColor,
})
}
public async destroy({ response, params }: HttpContextContract) {
const postColor = await PostColor.findOrFail(params.id)
await postColor.delete()
return response.status(200).send({
message: 'PostColor successfully deleted!',
})
}
}

165
app/Controllers/Http/PostsController.ts Normal file → Executable file
View File

@@ -1,54 +1,137 @@
import Post from "App/Models/Post";
import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext";
import Post from 'App/Models/Post'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import PostUpdateValidator from 'App/Validators/post/PostUpdateValidator'
import File from 'App/Models/File'
import PostStoreValidator from 'App/Validators/post/PostStoreValidator'
import PostColor from 'App/Models/PostColor'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class PostsController {
public async getLikes ({params}: HttpContextContract) {
let post = await Post.findBy('slug', params.slug)
if (!post) {
post = await Post.create({
slug: params.slug,
likes: 0
})
}
return post.likes
}
public async like ({params, response}: HttpContextContract) {
let post = await Post.findBy('slug', params.slug)
if (!post) {
post = await Post.create({
slug: params.slug,
likes: 0
})
}
const getLikes = post.likes + 1
await post.merge({
likes: getLikes
}).save()
public async index({ response }: HttpContextContract) {
return response.status(200).send({
status: 200,
post
posts: await Post.query()
.orderBy('id', 'desc')
.preload('tags', (tags) => {
tags.preload('label')
})
.preload('cover')
.preload('color')
.preload('content')
.preload('title')
.preload('description'),
})
}
public async unlike ({params, response}: HttpContextContract) {
let post = await Post.findByOrFail('slug', params.slug)
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(PostStoreValidator)
const post = await Post.create(data)
const getLikes = post.likes - 1
const cover = await File.findByOrFail('label', data.cover)
const color = await PostColor.findByOrFail('name', data.color)
await post.related('cover').associate(cover)
await post.related('color').associate(color)
await post.related('description').associate(await getTranslation(data.description))
await post.related('title').associate(await getTranslation(data.title))
await post.related('content').associate(await getTranslation(data.content))
await post.related('tags').sync(data.tags!)
await post.merge({
likes: getLikes
}).save()
return response.status(200).send({
status: 200,
post
post,
})
}
public async show({ params, response }: HttpContextContract) {
const post = await Post.findOrFail(params.id)
await post.load('cover')
await post.load('title')
await post.load('description')
await post.load('content')
await post.load('color')
await post.load('tags', (tags) => {
tags.preload('label')
})
return response.status(200).send({
post,
})
}
public async get({ params, response }: HttpContextContract) {
const post = await Post.firstOrCreate({
slug: params.slug,
}, {
slug: params.slug,
likes: 0,
})
await post.load('tags', (tags) => {
tags.preload('label')
})
await post.load('cover')
await post.load('description')
await post.load('title')
await post.load('content')
await post.load('color')
return response.status(200).send({
post,
})
}
public async update({ request, params, response }: HttpContextContract) {
const post = await Post.findOrFail(params.id)
const data = await request.validate(PostUpdateValidator)
await post.merge(data).save()
await post.related('tags').sync(data.tags!)
await post.related('description').associate(await getTranslation(data.description!))
await post.related('title').associate(await getTranslation(data.title!))
await post.related('content').associate(await getTranslation(data.content!))
const cover = await File.findBy('label', data.cover)
if (cover) await post.related('cover').associate(cover)
const color = await PostColor.findBy('name', data.color)
if (color) await post.related('color').associate(color)
return response.status(200).send({
post,
})
}
public async destroy({ response, params }: HttpContextContract) {
const post = await Post.findOrFail(params.id)
await post.delete()
return response.status(200).send({
message: 'Post successfully deleted!',
})
}
public async like({ params, response }: HttpContextContract) {
const post = await Post.firstOrCreate({
slug: params.slug,
}, {
slug: params.slug,
likes: 0,
})
const getLikes = post.likes
await post.merge({
likes: getLikes + 1,
}).save()
return response.status(200).send({
post,
})
}
public async unlike({ params, response }: HttpContextContract) {
const post = await Post.findByOrFail('slug', params.slug)
const getLikes = post.likes
await post.merge({
likes: getLikes - 1,
}).save()
return response.status(200).send({
post,
})
}
}

62
app/Controllers/Http/ProfileController.ts Normal file → Executable file
View File

@@ -1,46 +1,46 @@
import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext";
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ProfileController {
public me ({ response }: HttpContextContract) {
public me({ response }: HttpContextContract) {
return response.status(200).send({
pronouns: "Arthur",
home: ["Paris", "France"],
pronouns: 'Arthur',
home: ['Paris', 'France'],
passions: [
"Dev",
"DevOps",
"New technologies",
"Gaming"
'Dev',
'DevOps',
'New technologies',
'Gaming',
'Cloud',
],
code: [
"Javascript",
"Typescript",
"HTML",
"CSS",
"GoLang",
"Java"
'Javascript',
'Typescript',
'HTML',
'CSS',
'GoLang',
'Java',
],
ask_me_about: [
"Web dev",
"Tech",
"Consulting",
"Cloud computing",
"DevOps",
"Software dev"
'Web dev',
'Tech',
'Consulting',
'Cloud computing',
'DevOps',
'Software dev',
],
technologies: {
web_app: ["VueJs", "NuxtJs", "Sass", "Tailwind"],
desktop_app: ["ElectronJs"],
mobile_app: ["React Native"],
web_app: ['VueJs', 'NuxtJs', 'Sass', 'TailwindCss', 'WindiCss'],
desktop_app: ['ElectronJs'],
mobile_app: ['React Native', 'Vue Native'],
back_end: {
typescript: ["AdonisJs"],
java: ["Spring"]
typescript: ['AdonisJs'],
java: ['Spring'],
},
databases: ["MongoDB", "MariaDB", "Redis"],
messaging: ["RabbitMq"],
other: ["Docker", "Git"],
architecture: ["microservices", "event-driven", "design system pattern"],
operating_systems: ['Windows', 'Linux']
databases: ['MongoDB', 'MariaDB', 'Redis'],
messaging: ['RabbitMQ'],
other: ['Docker', 'Git'],
architecture: ['microservices', 'event-driven', 'design system pattern'],
operating_systems: ['MacOS', 'Linux'],
},
})
}

67
app/Controllers/Http/ProjectsController.ts Normal file → Executable file
View File

@@ -1,22 +1,69 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Project from "App/Models/Project";
import ProjectValidator from "App/Validators/project/ProjectValidator";
import Project from 'App/Models/Project'
import ProjectStoreValidator from 'App/Validators/project/ProjectStoreValidator'
import ProjectUpdateValidator from 'App/Validators/project/ProjectUpdateValidator'
import File from 'App/Models/File'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class ProjectsController {
public async get ({ response }: HttpContextContract) {
const projects = await Project.query().orderBy('id', 'asc')
public async index({ response }: HttpContextContract) {
return response.status(200).send({
projects
projects: await Project.query()
.orderBy('id', 'asc')
.preload('cover')
.preload('description')
.preload('tags', (tags) => {
tags.preload('label')
}),
})
}
public async add ({ request, response}: HttpContextContract) {
const data = await request.validate(ProjectValidator)
await Project.create(data)
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(ProjectStoreValidator)
const project = await Project.create(data)
const cover = await File.findByOrFail('label', data.cover)
await project.related('cover').associate(cover)
await project.related('description').associate(await getTranslation(data.description))
await project.related('tags').sync(data.tags!)
return response.status(200).send({
message: 'Project successfully created'
project,
})
}
public async show({ params, response }: HttpContextContract) {
const project = await Project.findOrFail(params.id)
await project.load('cover')
await project.load('description')
await project.load('tags', (tags) => {
tags.preload('label')
})
return response.status(200).send({
project,
})
}
public async update({ request, params, response }: HttpContextContract) {
const project = await Project.findOrFail(params.id)
const data = await request.validate(ProjectUpdateValidator)
const cover = await File.findBy('label', data.cover)
await project.merge(data).save()
if (cover) await project.related('cover').associate(cover)
if (data.description) await project.related('description').associate(await getTranslation(data.description))
await project.related('tags').sync(data.tags!)
return response.status(200).send({
project,
})
}
public async destroy({ response, params }: HttpContextContract) {
const project = await Project.findOrFail(params.id)
await project.delete()
return response.status(200).send({
message: 'Project successfully deleted!',
})
}
}

View File

@@ -0,0 +1,57 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import File from 'App/Models/File'
import Skill from 'App/Models/Skill'
import SkillStoreValidator from 'App/Validators/skill/SkillStoreValidator'
import SkillUpdateValidator from 'App/Validators/skill/SkillUpdateValidator'
export default class SkillsController {
public async index({ response }: HttpContextContract) {
const skills = await Skill
.query()
.preload('file')
return response.status(200).send({
skills,
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(SkillStoreValidator)
const skill = await Skill.create(data)
const cover = await File.findBy('label', data.cover)
if (cover) await skill.related('file').associate(cover)
return response.status(200).send({
skill,
})
}
public async show({ params, response }: HttpContextContract) {
const skill = await Skill.findOrFail(params.id)
skill.load('file')
return response.status(200).send({
skill,
})
}
public async update({ request, params, response }: HttpContextContract) {
const data = await request.validate(SkillUpdateValidator)
const skill = await Skill.findOrFail(params.id)
const cover = await File.findBy('label', data.cover)
if (cover) await skill.related('file').associate(cover)
await skill.merge(data).save()
return response.status(200).send({
skill,
})
}
public async destroy({ response, params }: HttpContextContract) {
const skill = await Skill.findOrFail(params.id)
await skill.delete()
return response.status(200).send({
message: 'Skill successfully deleted!',
})
}
}

View File

@@ -1,63 +1,31 @@
import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext";
import Redis from "@ioc:Adonis/Addons/Redis";
import {UpdateGitHubReadme} from "App/tasks/UpdateGithubReadme";
import Logger from "@ioc:Adonis/Core/Logger";
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Redis from '@ioc:Adonis/Addons/Redis'
import StateSleepingValidator from 'App/Validators/states/StateSleepingValidator'
export default class StatesController {
// Listening Music
public async get ({response}: HttpContextContract) {
const is_sleeping = await Redis.get('states:sleeping')
const is_listening_music = await Redis.get('states:listening')
const is_developing = await Redis.get('states:developing')
const is_learning = await Redis.get('states:learning')
public async index({ response }: HttpContextContract) {
const sleeping = this.formatValue(await Redis.get('states:sleeping'))
const developing = this.formatValue(await Redis.get('states:developing'))
return response.status(200).send({
is_learning: this.getStatus(is_learning),
is_sleeping: this.getStatus(is_sleeping),
is_developing: this.getStatus(is_developing),
is_listening_music: this.getStatus(is_listening_music)
sleeping,
developing,
listening_music: 'Soon',
})
}
public async set ({request, response, params}: HttpContextContract) {
const state = params.state
const value = await request.input('value')
if (state && value) {
await Redis.set(`states:${state}`, value)
if (value === 'true') {
switch (state) {
case 'learning':
await Redis.set(`states:developing`, 'false')
await Redis.set(`states:sleeping`, 'false')
break
case 'developing':
await Redis.set(`states:learning`, 'false')
await Redis.set(`states:sleeping`, 'false')
break
case 'listening':
await Redis.set(`states:sleeping`, 'false')
break
case 'sleeping':
await Redis.set(`states:developing`, 'false')
await Redis.set(`states:listening`, 'false')
await Redis.set(`states:learning`, 'false')
break
}
}
await UpdateGitHubReadme()
return response.status(200).send({
message: 'State successfully updated !'
})
}
Logger.info("Finish")
public async setSleeping({ request, response }: HttpContextContract) {
const { value } = await request.validate(StateSleepingValidator)
await Redis.set('states:sleeping', String(value))
await Redis.set('states:developing', String(!value))
return response.status(200).send({
message: 'State was successfully set!',
value: this.formatValue(String(value)),
})
}
public getStatus(state: string | null): string {
if (state === null) return "No"
return state === 'true' ? "Yes" : "No"
public formatValue(value: string | null): string {
return value === 'true' ? 'Yes' : 'No'
}
}

View File

@@ -0,0 +1,68 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import CommandsRun from 'App/Models/CommandsRun'
import BuildsRun from 'App/Models/BuildsRun'
import {
fetchDailyStatistics,
fetchMonthlyStatistics,
fetchStatistics,
fetchWeeklyStatistics,
NOW,
} from 'App/Utils/StatsUtils'
export default class StatsController {
public async index({ response }: HttpContextContract) {
const daily = await fetchDailyStatistics()
const weekly = await fetchWeeklyStatistics()
const monthly = await fetchMonthlyStatistics()
const total = await fetchStatistics()
return response.status(200).send({
daily,
weekly,
monthly,
total: {
development_time: total.development_time,
commands_run: total.commands_ran,
builds_run: total.builds_ran,
},
})
}
public async incrementCommandCount({ response }: HttpContextContract) {
const current_commands = await CommandsRun.firstOrCreate(
{
date: NOW,
},
{
date: NOW,
commands: 0,
},
)
current_commands.commands++
await current_commands.save()
return response.status(200).send({
message: 'Commands Count successfully incremented!',
})
}
public async incrementBuildCount({ response }: HttpContextContract) {
const current_builds = await BuildsRun.firstOrCreate(
{
date: NOW,
},
{
date: NOW,
builds: 0,
},
)
current_builds.builds++
await current_builds.save()
return response.status(200).send({
message: 'Builds Count successfully incremented!',
})
}
}

View File

@@ -0,0 +1,28 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Subscriber from 'App/Models/Subscriber'
import SubscriberStoreValidator from 'App/Validators/subscriber/SubscriberStoreValidator'
export default class SubscribersController {
public async index({ response }: HttpContextContract) {
const subscribers = await Subscriber.query()
return response.status(200).send({
count: subscribers.length,
subscribers,
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(SubscriberStoreValidator)
return response.status(200).send({
subscriber: await Subscriber.create(data),
})
}
public async destroy({ params, response }: HttpContextContract) {
const subscriber = await Subscriber.findOrFail(params.id)
await subscriber.delete()
return response.status(200).send({
message: 'Subscriber successfully deleted!',
})
}
}

View File

@@ -0,0 +1,55 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import TagStoreValidator from 'App/Validators/tag/TagStoreValidator'
import TagUpdateValidator from 'App/Validators/tag/TagUpdateValidator'
import Tag from 'App/Models/Tag'
import { getTranslation } from 'App/Utils/TranslationsUtils'
export default class TagsController {
public async index({ response }: HttpContextContract) {
const tags = await Tag
.query()
.preload('label')
return response.status(200).send({
tags,
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(TagStoreValidator)
const tag = await Tag.create({})
await tag.related('label').associate(await getTranslation(data.label))
return response.status(200).send({
tag,
})
}
public async show({ params, response }: HttpContextContract) {
const tag = await Tag.findOrFail(params.id)
tag.load('label')
return response.status(200).send({
tag,
})
}
public async update({ request, params, response }: HttpContextContract) {
const data = await request.validate(TagUpdateValidator)
const tag = await Tag.findOrFail(params.id)
if (data.label)
await tag.related('label').associate(await getTranslation(data.label))
return response.status(200).send({
tag,
})
}
public async destroy({ response, params }: HttpContextContract) {
const tag = await Tag.findOrFail(params.id)
await tag.delete()
return response.status(200).send({
message: 'Tag successfully deleted!',
})
}
}

View File

@@ -0,0 +1,43 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Translation from 'App/Models/Translation'
import TranslationStoreValidator from 'App/Validators/translation/TranslationStoreValidator'
import TranslationUpdateValidator from 'App/Validators/translation/TranslationUpdateValidator'
export default class TranslationsController {
public async index({ response }: HttpContextContract) {
return response.status(200).send({
translations: await Translation.query().orderBy('id', 'asc'),
})
}
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(TranslationStoreValidator)
return response.status(200).send({
translation: await Translation.create(data),
})
}
public async show({ params, response }: HttpContextContract) {
return response.status(200).send({
translation: await Translation.findOrFail(params.id),
})
}
public async update({ request, params, response }: HttpContextContract) {
const translation = await Translation.findOrFail(params.id)
const data = await request.validate(TranslationUpdateValidator)
await translation.merge(data).save()
return response.status(200).send({
translation,
})
}
public async destroy({ response, params }: HttpContextContract) {
const translation = await Translation.findOrFail(params.id)
await translation.delete()
return response.status(200).send({
message: 'Translation successfully deleted!',
})
}
}

52
app/Controllers/Http/UsersController.ts Normal file → Executable file
View File

@@ -1,50 +1,48 @@
import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext'
import User from "App/Models/User";
import StoreValidator from "App/Validators/users/StoreValidator";
import UpdateValidator from "App/Validators/users/UpdateValidator";
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
import UserStoreValidator from 'App/Validators/user/UserStoreValidator'
import UserUpdateValidator from 'App/Validators/user/UserUpdateValidator'
export default class UsersController {
public async index () {
return User.query()
public async index({ response }: HttpContextContract) {
return response.status(200).send({
users: await User.all(),
})
}
public async store ({request}: HttpContextContract) {
const data = await request.validate(StoreValidator)
return await User.create(data)
public async store({ request, response }: HttpContextContract) {
const data = await request.validate(UserStoreValidator)
return response.status(200).send({
user: await User.create(data),
})
}
public async show ({params}: HttpContextContract) {
return await User.findOrFail(params.id)
public async show({ params, response }: HttpContextContract) {
return response.status(200).send({
user: await User.findOrFail(params.id),
})
}
public async update({ request, params, response }: HttpContextContract) {
const user = await User.findOrFail(params.id)
const data = await request.validate(UpdateValidator)
const { email } = data
const user2 = await User.findBy('email', email)
if (user2 !== null && user.email !== email) {
return response.abort({
message: 'L\' adresse mail n\'est pas unique !'
})
}
const data = await request.validate(UserUpdateValidator)
await user.merge(data).save()
return { message: 'Le compte a été mis à jour' }
return response.status(200).send({
user,
})
}
public async destroy({ response, params, auth }: HttpContextContract) {
const user = await User.findOrFail(params.id)
const admin = await User.findBy('email', 'arthurdanjou@outlook.fr')
if (auth.user?.id != admin?.id) {
if (auth.user?.id !== admin?.id)
return response.unauthorized()
}
await user.delete()
return { message: "L'utilisateur a bien été supprimé" }
return response.status(200).send({
message: 'User successfully deleted!',
})
}
}

2
app/Exceptions/Handler.ts Normal file → Executable file
View File

@@ -17,7 +17,7 @@ import Logger from '@ioc:Adonis/Core/Logger'
import HttpExceptionHandler from '@ioc:Adonis/Core/HttpExceptionHandler'
export default class ExceptionHandler extends HttpExceptionHandler {
constructor () {
constructor() {
super(Logger)
}
}

19
app/Mailers/FormConfirmation.ts Normal file → Executable file
View File

@@ -1,22 +1,23 @@
import mjml from 'mjml'
import { BaseMailer, MessageContract } from '@ioc:Adonis/Addons/Mail'
import View from "@ioc:Adonis/Core/View";
export default class FormConfirmation extends BaseMailer {
constructor (private name: string, private email: string) {
constructor(private name: string, private email: string) {
super()
}
public html = mjml(View.render('emails/confirmation_form', {
/* public html = mjml(View.render('emails/confirmation_form', {
name: this.name
})).html
})).html */
public prepare(message: MessageContract) {
message
.from('contact@arthurdanjou.fr')
.from('no-reply@arthurdanjou.fr')
.replyTo('contact@arthurdanjou.fr')
.to(this.email)
.subject('Confirmation Form')
.html(this.html)
.subject('Thank you for contacting !')
.htmlView('emails/confirmation_form', {
name: this.name,
url: 'https://arthurdanjou.fr',
})
}
}

31
app/Middleware/Auth.ts Normal file → Executable file
View File

@@ -22,24 +22,23 @@ export default class AuthMiddleware {
* of the mentioned guards and that guard will be used by the rest of the code
* during the current request.
*/
protected async authenticate (auth: HttpContextContract['auth'], guards: any[]) {
/**
* Hold reference to the guard last attempted within the for loop. We pass
* the reference of the guard to the "AuthenticationException", so that
* it can decide the correct response behavior based upon the guard
* driver
*/
let guardLastAttempted: string | undefined
for (let guard of guards) {
guardLastAttempted = guard
protected async authenticate(auth: HttpContextContract['auth'], guards: any[]) {
/**
* Hold reference to the guard last attempted within the for loop. We pass
* the reference of the guard to the "AuthenticationException", so that
* it can decide the correct response behavior based upon the guard
* driver
*/
let guardLastAttempted: string | undefined
for (const guard of guards) {
guardLastAttempted = guard
if (await auth.use(guard).check()) {
/**
* Instruct auth to use the given guard as the default guard for
* the rest of the request, since the user authenticated
* succeeded here
*/
* Instruct auth to use the given guard as the default guard for
* the rest of the request, since the user authenticated
* succeeded here
*/
auth.defaultGuard = guard
return true
}
@@ -59,7 +58,7 @@ export default class AuthMiddleware {
/**
* Handle request
*/
public async handle ({ auth }: HttpContextContract, next: () => Promise<void>, customGuards: string[]) {
public async handle({ auth }: HttpContextContract, next: () => Promise<void>, customGuards: string[]) {
/**
* Uses the user defined guards or the default guard mentioned in
* the config file

5
app/Middleware/SilentAuth.ts Normal file → Executable file
View File

@@ -10,12 +10,13 @@ export default class SilentAuthMiddleware {
/**
* Handle request
*/
public async handle ({ auth }: HttpContextContract, next: () => Promise<void>) {
public async handle({ auth }: HttpContextContract, next: () => Promise<void>) {
/**
* Check if user is logged-in or not. If yes, then `ctx.auth.user` will be
* set to the instance of the currently logged in user.
*/
await auth.check()
await auth.use('api').check()
await auth.use('web').check()
await next()
}
}

37
app/Models/Announce.ts Normal file
View File

@@ -0,0 +1,37 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import File from 'App/Models/File'
import Translation from 'App/Models/Translation'
export default class Announce extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public color: string
@column()
public hoverColor: string
@belongsTo(() => Translation, {
foreignKey: 'messageId',
})
public message: BelongsTo<typeof Translation>
@column()
public messageId: number
@belongsTo(() => File, {
foreignKey: 'coverId',
})
public cover: BelongsTo<typeof File>
@column()
public coverId: number
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

12
app/Models/BuildsRun.ts Normal file
View File

@@ -0,0 +1,12 @@
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class BuildsRun extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public builds: number
@column()
public date: string
}

12
app/Models/CommandsRun.ts Normal file
View File

@@ -0,0 +1,12 @@
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class CommandsRun extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public commands: number
@column()
public date: string
}

View File

@@ -0,0 +1,12 @@
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class DevelopmentHour extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public seconds: number
@column()
public date: string
}

34
app/Models/Experience.ts Normal file
View File

@@ -0,0 +1,34 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import Translation from 'App/Models/Translation'
export default class Experience extends BaseModel {
@column({ isPrimary: true })
public id: number
@belongsTo(() => Translation, {
foreignKey: 'titleId',
})
public title: BelongsTo<typeof Translation>
@column()
public titleId: number
@column()
public company: string
@column()
public location: string
@column()
public beginDate: string
@column()
public endDate: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

2
app/Models/File.ts Normal file → Executable file
View File

@@ -1,5 +1,5 @@
import { DateTime } from 'luxon'
import {BaseModel, column} from '@ioc:Adonis/Lucid/Orm'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class File extends BaseModel {
@column({ isPrimary: true })

0
app/Models/Form.ts Normal file → Executable file
View File

39
app/Models/Formation.ts Normal file
View File

@@ -0,0 +1,39 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import Translation from 'App/Models/Translation'
export default class Formation extends BaseModel {
@column({ isPrimary: true })
public id: number
@belongsTo(() => Translation, {
foreignKey: 'titleId',
})
public title: BelongsTo<typeof Translation>
@column()
public titleId: number
@belongsTo(() => Translation, {
foreignKey: 'descriptionId',
})
public description: BelongsTo<typeof Translation>
@column()
public descriptionId: number
@column()
public location: string
@column()
public beginDate: string
@column()
public endDate: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

View File

@@ -1,23 +0,0 @@
import { DateTime } from 'luxon'
import {BaseModel, BelongsTo, belongsTo, column} from '@ioc:Adonis/Lucid/Orm'
import User from "./User";
export default class GuestBookMessage extends BaseModel {
@column({ isPrimary: true })
public id: number
@belongsTo(() => User)
public user: BelongsTo<typeof User>
@column()
public userId: number
@column()
public message: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

23
app/Models/Information.ts Normal file
View File

@@ -0,0 +1,23 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import Translation from 'App/Models/Translation'
export default class Information extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public age: number
@belongsTo(() => Translation)
public translation: BelongsTo<typeof Translation>
@column()
public translationId: number
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

0
app/Models/Location.ts Normal file → Executable file
View File

25
app/Models/Maintenance.ts Normal file
View File

@@ -0,0 +1,25 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import Translation from 'App/Models/Translation'
export default class Maintenance extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public active: boolean
@belongsTo(() => Translation, {
foreignKey: 'reasonId',
})
public reason: BelongsTo<typeof Translation>
@column()
public reasonId: number
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

55
app/Models/Post.ts Normal file → Executable file
View File

@@ -1,16 +1,69 @@
import { DateTime } from 'luxon'
import {BaseModel, column} from '@ioc:Adonis/Lucid/Orm'
import { BaseModel, BelongsTo, belongsTo, column, manyToMany, ManyToMany } from '@ioc:Adonis/Lucid/Orm'
import Tag from 'App/Models/Tag'
import Translation from 'App/Models/Translation'
import File from 'App/Models/File'
import PostColor from 'App/Models/PostColor'
export default class Post extends BaseModel {
@column({ isPrimary: true })
public id: number
@manyToMany(() => Tag)
public tags: ManyToMany<typeof Tag>
@column()
public slug: string
@column()
public likes: number
@belongsTo(() => Translation, {
foreignKey: 'titleId',
})
public title: BelongsTo<typeof Translation>
@column()
public titleId: number
@belongsTo(() => Translation, {
foreignKey: 'descriptionId',
})
public description: BelongsTo<typeof Translation>
@column()
public descriptionId: number
@belongsTo(() => File, {
foreignKey: 'coverId',
})
public cover: BelongsTo<typeof File>
@column()
public coverId: number
@belongsTo(() => Translation, {
foreignKey: 'contentId',
})
public content: BelongsTo<typeof Translation>
@column()
public contentId: number
@belongsTo(() => PostColor, {
foreignKey: 'colorId',
})
public color: BelongsTo<typeof PostColor>
@column()
public colorId: number
@column()
public readingTime: number
@column()
public date: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime

16
app/Models/PostColor.ts Normal file
View File

@@ -0,0 +1,16 @@
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class PostColor extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public name: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

24
app/Models/Project.ts Normal file → Executable file
View File

@@ -1,5 +1,8 @@
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
import { BaseModel, BelongsTo, belongsTo, column, ManyToMany, manyToMany } from '@ioc:Adonis/Lucid/Orm'
import File from 'App/Models/File'
import Tag from 'App/Models/Tag'
import Translation from 'App/Models/Translation'
export default class Project extends BaseModel {
@column({ isPrimary: true })
@@ -8,15 +11,28 @@ export default class Project extends BaseModel {
@column()
public name: string
@column()
public description: string
@belongsTo(() => Translation, {
foreignKey: 'descriptionId',
})
public description: BelongsTo<typeof Translation>
@column()
public progress: number
public descriptionId: number
@column()
public url: string
@belongsTo(() => File, {
foreignKey: 'coverId',
})
public cover: BelongsTo<typeof File>
@column()
public coverId: number
@manyToMany(() => Tag)
public tags: ManyToMany<typeof Tag>
@column.dateTime({ autoCreate: true })
public createdAt: DateTime

26
app/Models/Skill.ts Normal file
View File

@@ -0,0 +1,26 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import File from 'App/Models/File'
export default class Skill extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public name: string
@belongsTo(() => File)
public file: BelongsTo<typeof File>
@column()
public fileId: number
@column()
public color: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

16
app/Models/Subscriber.ts Executable file
View File

@@ -0,0 +1,16 @@
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class Subscriber extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public email: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

22
app/Models/Tag.ts Normal file
View File

@@ -0,0 +1,22 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import Translation from 'App/Models/Translation'
export default class Tag extends BaseModel {
@column({ isPrimary: true })
public id: number
@belongsTo(() => Translation, {
foreignKey: 'labelId',
})
public label: BelongsTo<typeof Translation>
@column()
public labelId: number
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

View File

@@ -1,30 +1,18 @@
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class Song extends BaseModel {
export default class Translation extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public author: string
public code: string
@column()
public album: string
public french: string
@column()
public title: string
@column()
public type: string
@column()
public device: string
@column()
public duration: number
@column.date()
public releaseDate: DateTime
public english: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime

11
app/Models/User.ts Normal file → Executable file
View File

@@ -1,10 +1,6 @@
import { DateTime } from 'luxon'
import Hash from '@ioc:Adonis/Core/Hash'
import {
column,
beforeSave,
BaseModel,
} from '@ioc:Adonis/Lucid/Orm'
import { BaseModel, beforeSave, column } from '@ioc:Adonis/Lucid/Orm'
export default class User extends BaseModel {
@column({ isPrimary: true })
@@ -35,9 +31,8 @@ export default class User extends BaseModel {
public updatedAt: DateTime
@beforeSave()
public static async hashPassword (user: User) {
if (user.$dirty.password) {
public static async hashPassword(user: User) {
if (user.$dirty.password)
user.password = await Hash.make(user.password)
}
}
}

13
app/Tasks/SongsTask.ts Normal file
View File

@@ -0,0 +1,13 @@
import Logger from '@ioc:Adonis/Core/Logger'
const MS = 1000
export async function getCurrentPlayingMusic(): Promise<void> {
// Fetch from deezer
}
export async function Activate(): Promise<void> {
Logger.info(`Starting task runner for watching deezer current playing [${MS} ms]`)
await getCurrentPlayingMusic()
setInterval(getCurrentPlayingMusic, MS)
}

49
app/Tasks/StatesTask.ts Normal file
View File

@@ -0,0 +1,49 @@
import { btoa } from 'buffer'
import axios from 'axios'
import Env from '@ioc:Adonis/Core/Env'
import Logger from '@ioc:Adonis/Core/Logger'
import Redis from '@ioc:Adonis/Addons/Redis'
const MS = 1000 * 2 * 60 // 2 min
let taskId
interface StatesResponse {
time: number
}
async function getCurrentTime(): Promise<void> {
const response = await axios.get<{ data: StatesResponse[]}>(`https://wakatime.com/api/v1/users/${Env.get('WAKATIME_USER')}/heartbeats`, {
headers: {
Authorization: `Basic ${btoa(Env.get('WAKATIME_KEY'))}`,
},
params: {
date: new Date(),
},
})
if (response.status === 200) {
const heartbeat = response.data.data[response.data.data.length - 1]
const current_time = new Date(Date.now()).getTime() / 1000
if (heartbeat.time) {
const active = current_time - heartbeat.time <= 60 * 5 // Less than 5 min.
const redis_state = await Redis.get('states:developing') === 'true'
if (redis_state !== active) {
await Redis.set('states:developing', String(active))
if (redis_state) await Redis.set('states:sleeping', 'false')
}
}
}
}
export async function Activate(): Promise<void> {
Logger.info(`Starting task runner for getting current developing state [every ${MS} ms]`)
await getCurrentTime()
taskId = setInterval(getCurrentTime, MS)
}
export function ShutDown(): void {
clearInterval(taskId)
Logger.info('Shutdown task runner for getting current developing state')
}

47
app/Tasks/StatsTask.ts Normal file
View File

@@ -0,0 +1,47 @@
import Logger from '@ioc:Adonis/Core/Logger'
import Env from '@ioc:Adonis/Core/Env'
import axios from 'axios'
import DevelopmentHour from 'App/Models/DevelopmentHour'
const MS = 1000 * 5 * 60 // 5 min
let taskId
interface StatsResponse {
grand_total: {
total_seconds: number
}
range: {
date: string
}
}
async function getDevelopmentHours(): Promise<void> {
const response = await axios.get<{ data: StatsResponse[]}>(`https://wakatime.com/share/@${Env.get('WAKATIME_USER')}/${Env.get('WAKATIME_ID')}.json`)
if (response.status === 200) {
const mapped_stats = response.data.data.map((item: StatsResponse) => {
return {
seconds: item.grand_total.total_seconds, date: item.range.date,
}
})
for (const data of mapped_stats) {
await DevelopmentHour.updateOrCreate({
date: data.date.split('T')[0],
}, {
date: data.date.split('T')[0],
seconds: data.seconds,
})
}
}
}
export async function Activate(): Promise<void> {
Logger.info(`Starting task runner for getting development hours [every ${MS} ms]`)
await getDevelopmentHours()
taskId = setInterval(getDevelopmentHours, MS)
}
export function ShutDown(): void {
clearInterval(taskId)
Logger.info('Shutdown task runner for getting development hours')
}

11
app/Utils/SongUtils.ts Normal file
View File

@@ -0,0 +1,11 @@
export async function getHistory(range: 'day' | 'week' | 'month') {
return range
}
export async function getTopTrack() {
return 0
}
export async function GetCurrentPlaying() {
return null
}

153
app/Utils/StatsUtils.ts Normal file
View File

@@ -0,0 +1,153 @@
import DevelopmentHour from 'App/Models/DevelopmentHour'
import CommandsRun from 'App/Models/CommandsRun'
import BuildsRun from 'App/Models/BuildsRun'
interface Time {
total_hours: number
total_minutes: number
total_seconds: number
}
interface Stats {
range: {
start: string
end: string
}
development_time: Time
commands_ran: number
builds_ran: number
}
function formatDate(date: Date): string {
return date.toISOString().split('T')[0]
}
export const NOW = formatDate(new Date())
export async function getDevelopmentHours(start: string, end: string): Promise<Time> {
const development_time = await DevelopmentHour
.query()
.where('date', '>=', start)
.where('date', '<=', end)
.orderBy('date', 'desc')
if (!development_time) {
return {
total_hours: 0,
total_minutes: 0,
total_seconds: 0,
}
}
let total = 0
development_time.forEach(item => total += item.seconds)
return {
total_hours: Math.floor(total / 3600),
total_minutes: Math.floor(total / 60),
total_seconds: Math.floor(total),
}
}
export async function getCommandsRan(start: string, end: string): Promise<number> {
const commands_run = await CommandsRun
.query()
.where('date', '>=', start)
.where('date', '<=', end)
.orderBy('date', 'desc')
if (!commands_run)
return 0
let commands = 0
commands_run.forEach(item => commands += item.commands)
return commands
}
export async function getBuildsRan(start: string, end: string): Promise<number> {
const builds_run = await BuildsRun
.query()
.where('date', '>=', start)
.where('date', '<=', end)
.orderBy('date', 'desc')
if (!builds_run)
return 0
let builds = 0
builds_run.forEach(item => builds += item.builds)
return builds
}
export async function fetchStatistics(): Promise<Stats> {
const start = formatDate(new Date('2020-10-13'))
const development_time = await getDevelopmentHours(start, NOW)
const commands_ran = await getCommandsRan(start, NOW)
const builds_ran = await getBuildsRan(start, NOW)
return {
range: {
start,
end: NOW,
},
development_time,
commands_ran,
builds_ran,
}
}
export async function fetchMonthlyStatistics(): Promise<Stats> {
const start = formatDate(new Date(new Date().setMonth(new Date().getMonth() - 1)))
const development_time = await getDevelopmentHours(start, NOW)
const commands_ran = await getCommandsRan(start, NOW)
const builds_ran = await getBuildsRan(start, NOW)
return {
range: {
start,
end: NOW,
},
development_time,
commands_ran,
builds_ran,
}
}
export async function fetchWeeklyStatistics(): Promise<Stats> {
const start = formatDate(new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000))
const development_time = await getDevelopmentHours(start, NOW)
const commands_ran = await getCommandsRan(start, NOW)
const builds_ran = await getBuildsRan(start, NOW)
return {
range: {
start,
end: NOW,
},
development_time,
commands_ran,
builds_ran,
}
}
export async function fetchDailyStatistics(): Promise<Stats> {
const development_time = await getDevelopmentHours(NOW, NOW)
const commands_ran = await getCommandsRan(NOW, NOW)
const builds_ran = await getBuildsRan(NOW, NOW)
return {
range: {
start: NOW,
end: NOW,
},
development_time,
commands_ran,
builds_ran,
}
}

View File

@@ -0,0 +1,5 @@
import Translation from 'App/Models/Translation'
export async function getTranslation(code: string): Promise<Translation> {
return await Translation.firstOrNew({ code }, { code })
}

18
app/Validators/AuthValidator.ts Normal file → Executable file
View File

@@ -1,26 +1,22 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {rules, schema} from '@ioc:Adonis/Core/Validator'
import { rules, schema } from '@ioc:Adonis/Core/Validator'
export default class AuthValidator {
constructor (private ctx: HttpContextContract) {
public messages = {
required: 'The field {{field}} is required',
}
public schema = schema.create({
email: schema.string({ trim: true }, [
rules.email(),
rules.required()
rules.required(),
]),
password: schema.string({ trim: true }, [
rules.required()
rules.required(),
]),
remember_me: schema.boolean()
remember: schema.boolean.optional(),
})
public cacheKey = this.ctx.routeKey
public messages = {
'email.email': 'L\'adresse mail n\'est pas valide !',
'email.required': 'Veuillez renseigner une adresse mail !',
'password.required': 'Veuillez renseigner un mot de passe !',
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -0,0 +1,18 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class AnnounceUpdateValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
code: schema.string.optional(),
cover: schema.string.optional(),
color: schema.string.optional(),
hoverColor: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,19 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ExperienceStoreValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
title: schema.string(),
company: schema.string(),
location: schema.string(),
beginDate: schema.string(),
endDate: schema.string(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,19 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ExperienceUpdateValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
title: schema.string.optional(),
company: schema.string.optional(),
location: schema.string.optional(),
beginDate: schema.string.optional(),
endDate: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -1,16 +1,18 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class FormValidator {
constructor (protected ctx: HttpContextContract) {
export default class FormStoreValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
name: schema.string(),
email: schema.string(),
subject: schema.string(),
content: schema.string()
content: schema.string(),
})
public messages = {}
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,19 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class FormationStoreValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
title: schema.string(),
description: schema.string(),
location: schema.string(),
beginDate: schema.string(),
endDate: schema.string(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,19 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class FormationUpdateValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
title: schema.string.optional(),
description: schema.string.optional(),
location: schema.string.optional(),
beginDate: schema.string.optional(),
endDate: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -1,24 +0,0 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {rules, schema} from '@ioc:Adonis/Core/Validator'
export default class StoreValidator {
constructor (private ctx: HttpContextContract) {
}
public schema = schema.create({
user_id: schema.number( [
rules.required(),
rules.unique({table: 'golden_messages', column: 'user_id'}),
rules.exists({ table: 'users', column: 'id'})
]),
message: schema.string({}, [
rules.required()
])
})
public cacheKey = this.ctx.routeKey
public messages = {
required: 'Le champ {{field}} doit être valide !',
}
}

View File

@@ -0,0 +1,16 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class InformationUpdateValidator {
public schema = schema.create({
age: schema.number.optional(),
code: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
constructor(protected ctx: HttpContextContract) {
}
}

6
app/Validators/location/LocationValidator.ts Normal file → Executable file
View File

@@ -1,8 +1,8 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {schema} from '@ioc:Adonis/Core/Validator'
import { schema } from '@ioc:Adonis/Core/Validator'
export default class LocationValidator {
constructor (private ctx: HttpContextContract) {
constructor(private ctx: HttpContextContract) {
}
public schema = schema.create({
@@ -14,6 +14,6 @@ export default class LocationValidator {
public cacheKey = this.ctx.routeKey
public messages = {
required: 'Le champ {{field}} doit être valide !',
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,16 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class MaintenanceUpdateValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
reason: schema.string.optional(),
active: schema.boolean.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,24 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class PostStoreValidator {
public schema = schema.create({
slug: schema.string(),
likes: schema.number(),
tags: schema.array().members(schema.string()),
title: schema.string(),
description: schema.string(),
cover: schema.string(),
readingTime: schema.number(),
date: schema.string(),
color: schema.string(),
content: schema.string(),
})
public messages = {
required: 'The field {{field}} is required',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -0,0 +1,24 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class PostUpdateValidator {
public schema = schema.create({
slug: schema.string.optional(),
likes: schema.number.optional(),
tags: schema.array.optional().members(schema.string()),
title: schema.string.optional(),
description: schema.string.optional(),
cover: schema.string.optional(),
readingTime: schema.number.optional(),
date: schema.string.optional(),
color: schema.string.optional(),
content: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -0,0 +1,15 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class PostColorStoreValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
name: schema.string(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,15 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class PostColorUpdateValidator {
public schema = schema.create({
name: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -0,0 +1,19 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ProjectStoreValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
name: schema.string(),
description: schema.string(),
url: schema.string(),
cover: schema.string(),
tags: schema.array.optional().members(schema.string()),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,19 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ProjectUpdateValidator {
public schema = schema.create({
name: schema.string.optional(),
description: schema.string.optional(),
url: schema.string.optional(),
cover: schema.string.optional(),
tags: schema.array.optional().members(schema.string()),
})
public messages = {
required: 'The field {{field}} is required',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -1,19 +0,0 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ProjectValidator {
constructor (protected ctx: HttpContextContract) {
}
public schema = schema.create({
name: schema.string(),
description: schema.string(),
progress: schema.number(),
url: schema.string()
})
public messages = {
required: 'Le champ {{field}} doit être valide !',
}
}

View File

@@ -0,0 +1,17 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class SkillStoreValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
name: schema.string(),
cover: schema.string(),
color: schema.string(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,17 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class SkillUpdateValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
name: schema.string.optional(),
cover: schema.string.optional(),
color: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,15 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class StateSleepingValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
value: schema.boolean(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -1,21 +0,0 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {rules, schema} from '@ioc:Adonis/Core/Validator'
export default class StoreValidator {
constructor (private ctx: HttpContextContract) {
}
public schema = schema.create({
email: schema.string({ trim: true }, [
rules.email(),
rules.unique({table: 'subscribers', column: 'email'})
]),
name: schema.string()
})
public cacheKey = this.ctx.routeKey
public messages = {
required: 'Le champ {{field}} doit être valide !',
}
}

View File

@@ -0,0 +1,21 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { rules, schema } from '@ioc:Adonis/Core/Validator'
export default class SubscriberStoreValidator {
public schema = schema.create({
email: schema.string({ trim: true }, [
rules.email(),
rules.unique({
table: 'subscribers',
column: 'email',
}),
]),
})
public messages = {
required: 'The field {{field}} is required',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -1,21 +0,0 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {rules, schema} from '@ioc:Adonis/Core/Validator'
export default class UpdateValidator {
constructor (private ctx: HttpContextContract) {
}
public schema = schema.create({
email: schema.string({ trim: true }, [
rules.email(),
rules.unique({table: 'subscribers', column: 'email'})
]),
name: schema.string.optional()
})
public cacheKey = this.ctx.routeKey
public messages = {
required: 'Le champ {{field}} doit être valide !'
}
}

View File

@@ -0,0 +1,15 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class TagStoreValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
label: schema.string(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,15 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class TagUpdateValidator {
constructor(protected ctx: HttpContextContract) {
}
public schema = schema.create({
label: schema.string.optional(),
})
public messages = {
required: 'The field {{field}} is required',
}
}

View File

@@ -0,0 +1,23 @@
import { rules, schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class TranslationStoreValidator {
public schema = schema.create({
code: schema.string({}, [
rules.unique({
table: 'translations',
column: 'code',
}),
]),
english: schema.string.optional(),
french: schema.string.optional(),
})
public messages = {
'required': 'The field {{field}} is required',
'code.unique': 'The translation code is not unique !',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -0,0 +1,23 @@
import { rules, schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class TranslationUpdateValidator {
public schema = schema.create({
code: schema.string({}, [
rules.unique({
table: 'translations',
column: 'code',
}),
]),
english: schema.string.optional(),
french: schema.string.optional(),
})
public messages = {
'required': 'The field {{field}} is required',
'code.unique': 'The translation code is not unique !',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -0,0 +1,24 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { rules, schema } from '@ioc:Adonis/Core/Validator'
export default class UserStoreValidator {
public schema = schema.create({
email: schema.string({ trim: true, escape: true }, [
rules.email(),
rules.required(),
rules.unique({
table: 'users',
column: 'email',
}),
]),
})
public messages = {
'required': 'The field {{field}} is required',
'email.email': 'The email must be valid',
'email.unique': 'The email is not unique',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -0,0 +1,34 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { rules, schema } from '@ioc:Adonis/Core/Validator'
export default class UserUpdateValidator {
public schema = schema.create({
email: schema.string.optional({ trim: true, escape: true },
[
rules.email(),
rules.unique(
{
table: 'users',
column: 'email',
}),
],
),
password: schema.string.optional({ trim: true, escape: true },
[
rules.confirmed(),
],
),
is_confirmed: schema.boolean.optional(),
confirmation_token: schema.string.optional({ trim: true, escape: true }),
remember_me: schema.string.optional({ trim: true, escape: true }),
})
public messages = {
'required': 'The field {{field}} is required',
'email.email': 'The email must be valid',
'password.confirmation': 'Passwords are not the same',
}
constructor(protected ctx: HttpContextContract) {
}
}

View File

@@ -1,22 +0,0 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {rules, schema} from '@ioc:Adonis/Core/Validator'
export default class StoreValidator {
constructor (private ctx: HttpContextContract) {
}
public schema = schema.create({
email: schema.string({ trim: true, escape: true }, [
rules.email(),
rules.required(),
rules.unique({table: 'users', column: 'email'})
])
})
public cacheKey = this.ctx.routeKey
public messages = {
required: 'Le champ {{field}} doit être valide !',
'email.email': 'L\'adresse mail doit être valide !',
}
}

Some files were not shown because too many files have changed in this diff Show More