mirror of
https://github.com/ArthurDanjou/artdanj-shortener.git
synced 2026-01-14 13:54:03 +01:00
Add I18n
This commit is contained in:
@@ -23,9 +23,13 @@
|
||||
"@adonisjs/auth",
|
||||
"@adonisjs/redis",
|
||||
"@adonisjs/lucid",
|
||||
"@adonisjs/session"
|
||||
"@adonisjs/session",
|
||||
"@adonisjs/i18n"
|
||||
],
|
||||
"aceProviders": [
|
||||
"@adonisjs/repl"
|
||||
],
|
||||
"metaFiles": [
|
||||
"resources/lang/**/*.(json|yaml)"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -5,7 +5,7 @@ import Link from "App/Models/Link";
|
||||
|
||||
export default class LinksController {
|
||||
|
||||
public async getLink ({params, response}: HttpContextContract) {
|
||||
public async getLink ({params, response, i18n}: HttpContextContract) {
|
||||
const code = params.id
|
||||
const link = await Link.findByOrFail('code', code)
|
||||
|
||||
@@ -14,40 +14,44 @@ export default class LinksController {
|
||||
await link.merge({
|
||||
visitCount: visitCount
|
||||
}).save()
|
||||
return response.redirect(link.target)
|
||||
return response.status(200).redirect(link.target)
|
||||
}
|
||||
return response.badRequest(`Code does not exist ! (/${code})`)
|
||||
return response.status(404).send({
|
||||
message: i18n.formatMessage('messages.no_exists', { code: code })
|
||||
})
|
||||
}
|
||||
|
||||
public async getAllLinks ({response}: HttpContextContract) {
|
||||
const links = await Link.query().orderBy('id', 'asc')
|
||||
return response.ok(links);
|
||||
return response.status(200).send({
|
||||
links
|
||||
})
|
||||
}
|
||||
|
||||
public async getVisitCount ({params}: HttpContextContract) {
|
||||
public async getVisitCount ({params, response, i18n}: HttpContextContract) {
|
||||
const code = params.id
|
||||
const link = await Link.findByOrFail('code', code)
|
||||
|
||||
//Check if code exists
|
||||
if (link.code === code) {
|
||||
return {
|
||||
return response.status(200).send({
|
||||
count: link.visitCount
|
||||
}
|
||||
}
|
||||
return {
|
||||
message: `Code does not exist ! (${code}`
|
||||
})
|
||||
}
|
||||
return response.status(404).send({
|
||||
message: i18n.formatMessage('messages.no_exists', { code: code })
|
||||
})
|
||||
}
|
||||
|
||||
public async createLink ({request, auth}: HttpContextContract) {
|
||||
public async createLink ({response, request, auth, i18n}: HttpContextContract) {
|
||||
await auth.authenticate()
|
||||
const link = await Link.create(await request.validate(StoreValidator))
|
||||
return {
|
||||
message: `Link successfully created : ${link.code} + ${link.target}`
|
||||
}
|
||||
return response.status(200).send({
|
||||
message: i18n.formatMessage('messages.created', { link: link.code, target: link.target })
|
||||
})
|
||||
}
|
||||
|
||||
public async updateLink ({request, auth}: HttpContextContract) {
|
||||
public async updateLink ({response, request, auth}: HttpContextContract) {
|
||||
await auth.authenticate()
|
||||
const link = await Link.findByOrFail('code', request.input('code'))
|
||||
const data = await request.validate(UpdateValidator)
|
||||
@@ -55,14 +59,19 @@ export default class LinksController {
|
||||
target: data.target,
|
||||
visitCount: 0
|
||||
}).save()
|
||||
return link
|
||||
return response.status(200).send({
|
||||
link
|
||||
})
|
||||
}
|
||||
|
||||
public async deleteLink ({request, auth}: HttpContextContract) {
|
||||
public async deleteLink ({i18n, response, request, auth}: HttpContextContract) {
|
||||
await auth.authenticate()
|
||||
const code = request.input('code')
|
||||
const link = await Link.findByOrFail('code', code)
|
||||
await link.delete()
|
||||
return response.status(200).send({
|
||||
message: i18n.formatMessage('messages.deleted', { link: link.code })
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,31 +2,39 @@ import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
||||
|
||||
export default class UsersController {
|
||||
|
||||
public async login ({request, auth}: HttpContextContract) {
|
||||
public async login ({request, auth, response}: HttpContextContract) {
|
||||
const email = request.input('email')
|
||||
const password = request.input('password')
|
||||
|
||||
const token = await auth.use('api').attempt(email, password, {
|
||||
expiresIn: '2 days'
|
||||
})
|
||||
return token.toJSON()
|
||||
return response.status(200).send({
|
||||
token: token.toJSON()
|
||||
})
|
||||
}
|
||||
|
||||
public async createInfiniteToken ({request, auth}: HttpContextContract) {
|
||||
public async createInfiniteToken ({response, request, auth}: HttpContextContract) {
|
||||
const email = request.input('email')
|
||||
const password = request.input('password')
|
||||
const token = await auth.use('api').attempt(email, password)
|
||||
return token.toJSON()
|
||||
return response.status(200).send({
|
||||
token: token.toJSON()
|
||||
})
|
||||
}
|
||||
|
||||
public async logout ({auth}: HttpContextContract) {
|
||||
public async logout ({response, auth, i18n}: HttpContextContract) {
|
||||
await auth.use('api').revoke()
|
||||
return { message: 'Vous avez été déconnecté' }
|
||||
return response.status(200).send({
|
||||
message: i18n.formatMessage('messages.logout')
|
||||
})
|
||||
}
|
||||
|
||||
public async me ({auth}: HttpContextContract) {
|
||||
public async me ({response, auth}: HttpContextContract) {
|
||||
await auth.authenticate()
|
||||
return auth.user
|
||||
return response.status(200).send({
|
||||
user: auth.user
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
45
app/Middleware/DetectUserLocale.ts
Normal file
45
app/Middleware/DetectUserLocale.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import I18n from '@ioc:Adonis/Addons/I18n'
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
|
||||
|
||||
/**
|
||||
* The middleware detects the user language using the "Accept-language" HTTP header
|
||||
* or the "lang" query string parameter.
|
||||
*
|
||||
* Feel free to change the middleware implementation to what suits your needs. Just
|
||||
* make sure
|
||||
*
|
||||
* - You always ensure the user selected language is supported by your app.
|
||||
* - Only call "switchLocale" when the detected language is valid string value and
|
||||
* not "null" or "undefined"
|
||||
*/
|
||||
export default class DetectUserLocale {
|
||||
/**
|
||||
* Detect user language using "Accept-language" header or
|
||||
* the "lang" query string parameter.
|
||||
*
|
||||
* The user language must be part of the "supportedLocales", otherwise
|
||||
* this method should return null.
|
||||
*/
|
||||
protected getUserLanguage(ctx: HttpContextContract) {
|
||||
const availableLocales = I18n.supportedLocales()
|
||||
return ctx.request.language(availableLocales) || ctx.request.input('lang')
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle method is called by AdonisJS automatically on every middleware
|
||||
* class.
|
||||
*/
|
||||
public async handle(ctx: HttpContextContract, next: () => Promise<void>) {
|
||||
const language = this.getUserLanguage(ctx)
|
||||
|
||||
/**
|
||||
* Switch locale when we are able to detect the user language and it
|
||||
* is supported by the application
|
||||
*/
|
||||
if (language) {
|
||||
ctx.i18n.switchLocale(language)
|
||||
}
|
||||
|
||||
await next()
|
||||
}
|
||||
}
|
||||
104
config/i18n.ts
Normal file
104
config/i18n.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Config source: https://git.io/Jw53K
|
||||
*
|
||||
* Feel free to let us know via PR, if you find something broken in this config
|
||||
* file.
|
||||
*/
|
||||
|
||||
import Application from '@ioc:Adonis/Core/Application'
|
||||
import { I18nConfig } from '@ioc:Adonis/Addons/I18n'
|
||||
|
||||
const i18nConfig: I18nConfig = {
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Translations format
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The format in which the translation are written. By default only the
|
||||
| ICU message syntax is supported. However, you can register custom
|
||||
| formatters too and please reference the documentation for that.
|
||||
|
|
||||
*/
|
||||
translationsFormat: 'icu',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default locale
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default locale represents the language for which all the translations
|
||||
| are always available.
|
||||
|
|
||||
| Having a default locale allows you to incrementally add translations for
|
||||
| other languages. If a specific language does not have a translation,
|
||||
| then the default locale translation will be used.
|
||||
|
|
||||
| Also, we switch to default locale for HTTP requests where the user language
|
||||
| is not supported by the your app
|
||||
|
|
||||
*/
|
||||
defaultLocale: 'en',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Supported locales
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Optionally define an array of locales that your application supports. If
|
||||
| not defined, we will derive this value from the translations stored
|
||||
| inside the `resources/lang` directory.
|
||||
|
|
||||
*/
|
||||
supportedLocales: [
|
||||
'fr',
|
||||
'en'
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Fallback locales
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you can configure per language fallbacks. For example, you can set
|
||||
| "es" as the fallback locale for the Catalan language.
|
||||
|
|
||||
| If not configured, all languages will fallback to the defaultLocale
|
||||
|
|
||||
*/
|
||||
// fallbackLocales: {},
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Provide validator messages
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Set the following option to "true" if you want to use "i18n" for defining
|
||||
| the validation messages.
|
||||
|
|
||||
| The validation messages will be loaded from the "validator.shared" prefix.
|
||||
|
|
||||
*/
|
||||
provideValidatorMessages: true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Loaders
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Loaders from which to load the translations. You can configure multiple
|
||||
| loaders as well and AdonisJS will merge the translations from all the
|
||||
| loaders to have a unified collection of messages.
|
||||
|
|
||||
| By default, only the "fs" loader is supported. However, you can add custom
|
||||
| loaders too and please reference the documentation for that.
|
||||
|
|
||||
*/
|
||||
loaders: {
|
||||
fs: {
|
||||
enabled: true,
|
||||
location: Application.resourcesPath('lang'),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default i18nConfig
|
||||
25
package.json
25
package.json
@@ -21,24 +21,25 @@
|
||||
"devDependencies": {
|
||||
"@adonisjs/assembler": "^5.3.2",
|
||||
"adonis-preset-ts": "^2.1.0",
|
||||
"pino-pretty": "^5.0.2",
|
||||
"typescript": "^4.3.4",
|
||||
"pino-pretty": "^7.1.0",
|
||||
"typescript": "^4.4.4",
|
||||
"youch": "^2.2.2",
|
||||
"youch-terminal": "^1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@adonisjs/auth": "^8.0.6",
|
||||
"@adonisjs/core": "^5.1.8",
|
||||
"@adonisjs/lucid": "^15.0.1",
|
||||
"@adonisjs/redis": "^7.0.6",
|
||||
"@adonisjs/repl": "^3.1.4",
|
||||
"@adonisjs/session": "^6.0.6",
|
||||
"luxon": "^1.27.0",
|
||||
"@adonisjs/auth": "^8.0.10",
|
||||
"@adonisjs/core": "^5.4.0",
|
||||
"@adonisjs/i18n": "^1.5.2",
|
||||
"@adonisjs/lucid": "^16.2.1",
|
||||
"@adonisjs/redis": "^7.0.9",
|
||||
"@adonisjs/repl": "^3.1.7",
|
||||
"@adonisjs/session": "^6.1.2",
|
||||
"luxon": "^2.0.2",
|
||||
"mysql": "^2.18.1",
|
||||
"phc-argon2": "^1.1.1",
|
||||
"phc-argon2": "^1.1.2",
|
||||
"proxy-addr": "^2.0.7",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"source-map-support": "^0.5.19",
|
||||
"tslib": "^2.3.0"
|
||||
"source-map-support": "^0.5.20",
|
||||
"tslib": "^2.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
6
resources/lang/en/messages.json
Normal file
6
resources/lang/en/messages.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"no_exists": "The code '{code}' does not exist!",
|
||||
"created": "The link '{link}' with target '{target}' was successfully created!",
|
||||
"deleted": "The link '{link}' was successfully deleted!",
|
||||
"logout": "You have been disconnected!"
|
||||
}
|
||||
6
resources/lang/fr/messages.json
Normal file
6
resources/lang/fr/messages.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"no_exists": "Le code '{code}' n'existe pas!",
|
||||
"created": "Le lien '{link}' avec pour direction '{target}' a bien été créé!",
|
||||
"deleted": "Le lien '{link}' a bien été supprimé!",
|
||||
"logout": "Vous avez été déconnecté !"
|
||||
}
|
||||
@@ -22,7 +22,8 @@ import Server from '@ioc:Adonis/Core/Server'
|
||||
*/
|
||||
Server.middleware.register([
|
||||
() => import('@ioc:Adonis/Core/BodyParser'),
|
||||
() => import('App/Middleware/SilentAuth')
|
||||
() => import('App/Middleware/SilentAuth'),
|
||||
() => import('App/Middleware/DetectUserLocale')
|
||||
])
|
||||
|
||||
/*
|
||||
|
||||
@@ -23,7 +23,7 @@ Route.get('/source', async ({response}: HttpContextContract) => {
|
||||
Route.get('health', async ({response}: HttpContextContract) => {
|
||||
const report = await HealthCheck.getReport()
|
||||
const isLive = await HealthCheck.isLive()
|
||||
const isReady = await HealthCheck.isReady()
|
||||
const isReady = HealthCheck.isReady()
|
||||
return report.healthy ? response.ok({ isLive, isReady, report: report.report }) : response.badRequest({ isLive, isReady, report: report.report })
|
||||
})
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
"@adonisjs/auth",
|
||||
"@adonisjs/redis",
|
||||
"@adonisjs/lucid",
|
||||
"@adonisjs/session"
|
||||
"@adonisjs/session",
|
||||
"@adonisjs/i18n"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user