Files
shields/services/localizely/localizely.service.js
chris48s bd3a11b4b6 upgrade to docusaurus 3 (#9820)
* update packages

* add plugin to strip autolinks in code blocks

* fix all the documentation for MDXv3

* remove check-docusaurus-versions

in docusaurus 3 this is now a hard error, not just a warning

* port upstream change to Curl component

fixes performing the 'execute' action when pressing enter
2024-03-23 19:54:57 +00:00

155 lines
4.3 KiB
JavaScript

import Joi from 'joi'
import {
BaseJsonService,
InvalidResponse,
queryParam,
pathParam,
} from '../index.js'
import { coveragePercentage } from '../color-formatters.js'
const description = `
<a href="https://localizely.com/" target="_blank">Localizely</a> is a management system for translation, localization, and internationalization of your projects.
The <b>read-only</b> API token from the Localizely account is required to fetch necessary data.
<b>
Note: Do not use the default API token as it grants full read-write permissions to your projects. You will expose your project and allow malicious users to modify the translations at will.
Instead, create a new one with only read permission.
</b>
You can find more details regarding API tokens under <a href="https://app.localizely.com/account" target="_blank">My profile</a> page.
`
const schema = Joi.object({
strings: Joi.number().required(),
reviewedProgress: Joi.number().required(),
languages: Joi.array()
.items(
Joi.object({
langCode: Joi.string().required(),
langName: Joi.string().required(),
strings: Joi.number().required(),
reviewed: Joi.number().required(),
reviewedProgress: Joi.number().required(),
}),
)
.required(),
}).required()
const queryParamSchema = Joi.object({
token: Joi.string().required(),
languageCode: Joi.string().regex(/^[a-z]{2}(-[A-Z][a-z]{3})?(-[A-Z]{2})?$/),
}).required()
export default class Localizely extends BaseJsonService {
static category = 'other'
static route = {
base: 'localizely/progress',
pattern: ':projectId/:branch*',
queryParamSchema,
}
static openApi = {
'/localizely/progress/{projectId}': {
get: {
summary: 'Localizely progress',
description,
parameters: [
pathParam({
name: 'projectId',
example: '5cc34208-0418-40b1-8353-acc70c95f802',
}),
queryParam({
name: 'token',
example:
'0f4d5e31a44f48dcbab966c52cfb0a67c5f1982186c14b85ab389a031dbc225a',
required: true,
}),
queryParam({
name: 'languageCode',
example: 'en-US',
required: false,
}),
],
},
},
'/localizely/progress/{projectId}/{branch}': {
get: {
summary: 'Localizely progress (branch)',
description,
parameters: [
pathParam({
name: 'projectId',
example: '5cc34208-0418-40b1-8353-acc70c95f802',
}),
pathParam({
name: 'branch',
example: 'main',
}),
queryParam({
name: 'token',
example:
'0f4d5e31a44f48dcbab966c52cfb0a67c5f1982186c14b85ab389a031dbc225a',
required: true,
}),
queryParam({
name: 'languageCode',
example: 'en-US',
required: false,
}),
],
},
},
}
static defaultBadgeData = { label: 'localized' }
static render({ langName, reviewedProgress }) {
return {
label: langName || 'localized',
message: `${reviewedProgress}%`,
color: coveragePercentage(reviewedProgress),
}
}
async fetch({ projectId, branch, apiToken }) {
return this._requestJson({
schema,
url: `https://api.localizely.com/v1/projects/${projectId}/status`,
options: {
searchParams: { branch },
headers: { 'X-Api-Token': apiToken },
},
httpErrors: {
403: 'not authorized for project',
},
})
}
static transform(json, languageCode) {
if (!languageCode) {
return { reviewedProgress: json.reviewedProgress }
}
const language = json.languages.find(lang => lang.langCode === languageCode)
if (!language) {
throw new InvalidResponse({ prettyMessage: 'Unsupported language' })
}
const { langName, reviewedProgress } = language
return { langName, reviewedProgress }
}
async handle({ projectId, branch }, { token: apiToken, languageCode }) {
const json = await this.fetch({ projectId, branch, apiToken })
const { langName, reviewedProgress } = this.constructor.transform(
json,
languageCode,
)
return this.constructor.render({ langName, reviewedProgress })
}
}