157 lines
4.5 KiB
TypeScript
157 lines
4.5 KiB
TypeScript
import { DesugaringStep } from "./Conversion"
|
|
import { Utils } from "../../../Utils"
|
|
import Translations from "../../../UI/i18n/Translations"
|
|
|
|
export class AddContextToTranslations<T> extends DesugaringStep<T> {
|
|
private readonly _prefix: string
|
|
|
|
constructor(prefix = "") {
|
|
super(
|
|
"Adds a '_context' to every object that is probably a translation",
|
|
["_context"],
|
|
"AddContextToTranslation"
|
|
)
|
|
this._prefix = prefix
|
|
}
|
|
|
|
/**
|
|
* const theme = {
|
|
* layers: [
|
|
* {
|
|
* builtin: ["abc"],
|
|
* override: {
|
|
* title:{
|
|
* en: "Some title"
|
|
* }
|
|
* }
|
|
* }
|
|
* ]
|
|
* }
|
|
* const rewritten = new AddContextToTranslations<any>("prefix:").convert(theme, "context").result
|
|
* const expected = {
|
|
* layers: [
|
|
* {
|
|
* builtin: ["abc"],
|
|
* override: {
|
|
* title:{
|
|
* _context: "prefix:context.layers.0.override.title"
|
|
* en: "Some title"
|
|
* }
|
|
* }
|
|
* }
|
|
* ]
|
|
* }
|
|
* rewritten // => expected
|
|
*
|
|
* // should use the ID if one is present instead of the index
|
|
* const theme = {
|
|
* layers: [
|
|
* {
|
|
* tagRenderings:[
|
|
* {id: "some-tr",
|
|
* question:{
|
|
* en:"Question?"
|
|
* }
|
|
* }
|
|
* ]
|
|
* }
|
|
* ]
|
|
* }
|
|
* const rewritten = new AddContextToTranslations<any>("prefix:").convert(theme, "context").result
|
|
* const expected = {
|
|
* layers: [
|
|
* {
|
|
* tagRenderings:[
|
|
* {id: "some-tr",
|
|
* question:{
|
|
* _context: "prefix:context.layers.0.tagRenderings.some-tr.question"
|
|
* en:"Question?"
|
|
* }
|
|
* }
|
|
* ]
|
|
* }
|
|
* ]
|
|
* }
|
|
* rewritten // => expected
|
|
*
|
|
* // should preserve nulls
|
|
* const theme = {
|
|
* layers: [
|
|
* {
|
|
* builtin: ["abc"],
|
|
* override: {
|
|
* name:null
|
|
* }
|
|
* }
|
|
* ]
|
|
* }
|
|
* const rewritten = new AddContextToTranslations<any>("prefix:").convert(theme, "context").result
|
|
* const expected = {
|
|
* layers: [
|
|
* {
|
|
* builtin: ["abc"],
|
|
* override: {
|
|
* name: null
|
|
* }
|
|
* }
|
|
* ]
|
|
* }
|
|
* rewritten // => expected
|
|
*
|
|
*
|
|
* // Should ignore all if '#dont-translate' is set
|
|
* const theme = {
|
|
* "#dont-translate": "*",
|
|
* layers: [
|
|
* {
|
|
* builtin: ["abc"],
|
|
* override: {
|
|
* title:{
|
|
* en: "Some title"
|
|
* }
|
|
* }
|
|
* }
|
|
* ]
|
|
* }
|
|
* const rewritten = new AddContextToTranslations<any>("prefix:").convert(theme, "context").result
|
|
* rewritten // => theme
|
|
*
|
|
*/
|
|
convert(
|
|
json: T,
|
|
context: string
|
|
): { result: T; errors?: string[]; warnings?: string[]; information?: string[] } {
|
|
if (json["#dont-translate"] === "*") {
|
|
return { result: json }
|
|
}
|
|
|
|
const result = Utils.WalkJson(
|
|
json,
|
|
(leaf, path) => {
|
|
if (leaf === undefined || leaf === null) {
|
|
return leaf
|
|
}
|
|
if (typeof leaf === "object") {
|
|
// follow the path. If we encounter a number, check that there is no ID we can use instead
|
|
let breadcrumb = json
|
|
for (let i = 0; i < path.length; i++) {
|
|
const pointer = path[i]
|
|
breadcrumb = breadcrumb[pointer]
|
|
if (pointer.match("[0-9]+") && breadcrumb["id"] !== undefined) {
|
|
path[i] = breadcrumb["id"]
|
|
}
|
|
}
|
|
|
|
return { ...leaf, _context: this._prefix + context + "." + path.join(".") }
|
|
} else {
|
|
return leaf
|
|
}
|
|
},
|
|
(obj) => obj === undefined || obj === null || Translations.isProbablyATranslation(obj)
|
|
)
|
|
|
|
return {
|
|
result,
|
|
}
|
|
}
|
|
}
|