forked from sheepzh/time-tracker-4-browser
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync-source.ts
More file actions
104 lines (98 loc) · 3.59 KB
/
sync-source.ts
File metadata and controls
104 lines (98 loc) · 3.59 KB
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
import { type SourceFilesModel, type SourceStringsModel } from "@crowdin/crowdin-api-client"
import { toMap } from "@util/array"
import { type CrowdinClient, getClientFromEnv, type NameKey } from "./client"
import {
ALL_DIRS,
Dir,
isIgnored,
ItemSet,
readAllMessages,
SOURCE_LOCALE,
transMsg
} from "./common"
async function initBranch(client: CrowdinClient): Promise<SourceFilesModel.Branch> {
const branch = await client.getOrCreateMainBranch()
if (!branch) {
console.error("Failed to create main branch")
process.exit(1)
}
return branch
}
/**
* Process strings
*
* @param client client
* @param existFile exist crowdin file
* @param fileContent strings
*/
async function processStrings(
client: CrowdinClient,
existFile: SourceFilesModel.File,
fileContent: ItemSet,
) {
const existStrings = await client.listStringsByFile(existFile.id)
const existStringsKeyMap = toMap(existStrings, s => s.identifier)
const strings2Delete: SourceStringsModel.String[] = []
const strings2Create: ItemSet = {}
const strings2Update: ItemSet = {}
Object.entries(fileContent).forEach(([path, text]) => {
if (!text) {
// maybe blank or undefined sometimes
return
}
const existString = existStringsKeyMap[path]
if (existString) {
strings2Update[path] = text
} else {
strings2Create[path] = text
}
})
Object.entries(existStringsKeyMap).forEach(([path, string]) => !fileContent[path] && strings2Delete.push(string))
await client.batchCreateString(existFile.id, strings2Create)
await client.batchUpdateIfNecessary(strings2Update, existStringsKeyMap)
await client.batchDeleteString(strings2Delete.map(s => s.id))
}
async function processByDir(client: CrowdinClient, dir: Dir, branch: SourceFilesModel.Branch): Promise<void> {
// 1. init directory
const dirKey: NameKey = { name: dir, branchId: branch.id }
let directory = await client.getDirByName(dirKey)
if (!directory) {
directory = await client.createDirectory(dirKey)
}
console.log('Directory: ' + JSON.stringify(directory))
// 2. iterate all messages
const messages = await readAllMessages(dir)
console.log(`Found ${Object.keys(messages).length} message(s)`)
// 3. list all files in directory
const existFiles = await client.listFilesByDirectory(directory.id)
console.log("Exists file count: " + existFiles.length)
const existFileNameMap = toMap(existFiles, f => f.name)
// 4. create new files
for (const [fileName, msg] of Object.entries(messages)) {
if (isIgnored(dir, fileName)) {
console.log(`Ignored file: ${dir}/${fileName}`)
continue
}
const crowdinFilename = fileName + '.json'
const fileContent = transMsg(msg[SOURCE_LOCALE])
let existFile = existFileNameMap[crowdinFilename]
if (!existFile) {
// Create with empty file
const storage = await client.createStorage(crowdinFilename, fileContent)
existFile = await client.createFile(directory.id, storage, crowdinFilename)
console.log(`Created new file: dir=${dir}, fileName=${crowdinFilename}, id=${existFile.id}`)
}
// Process by strings
await processStrings(client, existFile, fileContent)
}
}
async function main() {
const client = getClientFromEnv()
// Init main branch
const branch = await initBranch(client)
// Process by dir
for (const dir of ALL_DIRS) {
await processByDir(client, dir, branch)
}
}
main()