-
Notifications
You must be signed in to change notification settings - Fork 94
/
helper.ts
98 lines (90 loc) · 2.41 KB
/
helper.ts
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
import {
LanguageTag,
MessageBundle,
MessageBundleWithSlots,
Message,
MessageSlot,
Text,
} from "./types.js"
/**
* create v2 MessageBundle
* @example createMessageBundle({
* id: "greeting",
* messages: [
* createMessage({locale: "en", text: "Hello world!"})
* createMessage({locale: "de", text: "Hallo Welt!"})
* ]
* })
*/
export function createMessageBundle(args: {
id: string
messages: Message[]
alias?: MessageBundle["alias"]
}): MessageBundle {
return {
id: args.id,
alias: args.alias ?? {},
messages: args.messages,
}
}
/**
* create v2 Messsage AST with text-only pattern
* @example createMessage({locale: "en", text: "Hello world"})
*/
export function createMessage(args: {
locale: LanguageTag
text: string
match?: Array<string>
}): Message {
return {
locale: args.locale,
declarations: [],
selectors: [],
variants: [{ match: args.match ? args.match : [], pattern: [toTextElement(args.text ?? "")] }],
}
}
export function toTextElement(text: string): Text {
return {
type: "text",
value: text,
}
}
// ****************************
// WIP experimental persistence
// ****************************
/**
* create MessageSlot for a locale (only used for persistence)
*/
export function createMessageSlot(locale: LanguageTag): MessageSlot {
return {
locale,
slot: true,
}
}
/**
* return structuredClone with message slots for all locales not yet present
*/
export function addSlots(messageBundle: MessageBundle, locales: string[]): MessageBundleWithSlots {
const bundle = structuredClone(messageBundle) as MessageBundleWithSlots
bundle.messages = locales.map((locale) => {
return bundle.messages.find((message) => message.locale === locale) ?? createMessageSlot(locale)
})
return bundle
}
/**
* remove empty message slots without first creating a structured clone
*/
export function removeSlots(messageBundle: MessageBundleWithSlots) {
messageBundle.messages = messageBundle.messages.filter((message) => !("slot" in message))
return messageBundle as MessageBundle
}
/**
* Add newlines between bundles and messages to avoid merge conflicts
*/
export function injectJSONNewlines(json: string): string {
return json
.replace(/\{"id":"/g, '\n\n\n\n{"id":"')
.replace(/"messages":\[\{"locale":"/g, '"messages":[\n\n\n\n{"locale":"')
.replace(/\}\]\}\]\},\{"locale":"/g, '}]}]},\n\n\n\n{"locale":"')
.replace(/"slot":true\},\{"locale":/g, '"slot":true},\n\n\n\n{"locale":')
}