This repository has been archived by the owner on Apr 17, 2019. It is now read-only.
/
serialize.js
118 lines (93 loc) · 2.79 KB
/
serialize.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { L10nError } from '../../../lib/errors';
export function serializeLegacyContext(ctx) {
const lang = ctx.langs[0];
const cache = ctx.env.resCache;
return ctx.resIds.reduce(([errorsSeq, entriesSeq], cur) => {
const sourceRes = cache.get(cur + 'en-USapp');
const langRes = cache.get(cur + lang.code + lang.src);
const [errors, entries] = serializeEntries(
lang,
langRes instanceof L10nError ? {} : langRes,
sourceRes instanceof L10nError ? {} : sourceRes);
return [errorsSeq.concat(errors), entriesSeq.concat(entries)];
}, [[], []]);
}
function serializeEntries(lang, langEntries, sourceEntries) {
const errors = [];
const entries = Object.keys(sourceEntries).map(id => {
const sourceEntry = sourceEntries[id];
const langEntry = langEntries[id];
if (!langEntry) {
errors.push(new L10nError(
'"' + id + '" not found in ' + lang.code, id, lang));
return serializeEntry(sourceEntry, id);
}
if (!areEntityStructsEqual(sourceEntry, langEntry)) {
errors.push(new L10nError(
'"' + id + '" is malformed in ' + lang.code, id, lang));
return serializeEntry(sourceEntry, id);
}
return serializeEntry(langEntry, id);
});
return [errors, entries];
}
function serializeEntry(entry, id) {
if (typeof entry === 'string') {
return { $i: id, $v: entry };
}
const node = {
$i: id,
};
if (entry.value !== null) {
node.$v = entry.value;
}
if (entry.index !== null) {
node.$x = entry.index;
}
for (const key in entry.attrs) {
node[key] = serializeAttribute(entry.attrs[key]);
}
return node;
}
function serializeAttribute(attr) {
if (typeof attr === 'string') {
return attr;
}
const node = {};
if (attr.value !== null) {
node.$v = attr.value;
}
if (attr.index !== null) {
node.$x = attr.index;
}
return node;
}
function resolvesToString(entity) {
return typeof entity === 'string' || // a simple string
typeof entity.value === 'string' || // a simple string, entity with attrs
Array.isArray(entity.value) || // a complex string
typeof entity.value === 'object' && // a dict with an index
entity.index !== null;
}
function areAttrsEqual(attrs1, attrs2) {
const keys1 = Object.keys(attrs1 || Object.create(null));
const keys2 = Object.keys(attrs2 || Object.create(null));
if (keys1.length !== keys2.length) {
return false;
}
for (let i = 0; i < keys1.length; i++) {
if (keys2.indexOf(keys1[i]) === -1) {
return false;
}
}
return true;
}
function areEntityStructsEqual(source, translation) {
if (resolvesToString(source) && !resolvesToString(translation)) {
return false;
}
if (source.attrs || translation.attrs) {
return areAttrsEqual(source.attrs, translation.attrs);
}
return true;
}