* 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
155 lines
4.3 KiB
JavaScript
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 })
|
|
}
|
|
}
|