0

Download a locale

by
Published Oct 17, 2025

Download a locale in a specific file format.

Script phrase Verified

The script

Submitted by hugo697 Bun
Verified 235 days ago
1
//native
2
type Phrase = {
3
	token: string
4
	baseUrl: string
5
}
6
/**
7
 * Download a locale
8
 * Download a locale in a specific file format.
9
 */
10
export async function main(
11
	auth: Phrase,
12
	project_id: string,
13
	id: string,
14
	branch: string | undefined,
15
	file_format: string | undefined,
16
	tags: string | undefined,
17
	tag: string | undefined,
18
	include_empty_translations: string | undefined,
19
	exclude_empty_zero_forms: string | undefined,
20
	include_translated_keys: string | undefined,
21
	keep_notranslate_tags: string | undefined,
22
	convert_emoji: string | undefined,
23
	format_options: any,
24
	encoding: string | undefined,
25
	skip_unverified_translations: string | undefined,
26
	include_unverified_translations: string | undefined,
27
	use_last_reviewed_version: string | undefined,
28
	fallback_locale_id: string | undefined,
29
	source_locale_id: string | undefined,
30
	translation_key_prefix: string | undefined,
31
	filter_by_prefix: string | undefined,
32
	custom_metadata_filters: any,
33
	If_Modified_Since: string,
34
	If_None_Match: string
35
) {
36
	const url = new URL(`${auth.baseUrl}/projects/${project_id}/locales/${id}/download`)
37
	for (const [k, v] of [
38
		['branch', branch],
39
		['file_format', file_format],
40
		['tags', tags],
41
		['tag', tag],
42
		['include_empty_translations', include_empty_translations],
43
		['exclude_empty_zero_forms', exclude_empty_zero_forms],
44
		['include_translated_keys', include_translated_keys],
45
		['keep_notranslate_tags', keep_notranslate_tags],
46
		['convert_emoji', convert_emoji],
47
		['encoding', encoding],
48
		['skip_unverified_translations', skip_unverified_translations],
49
		['include_unverified_translations', include_unverified_translations],
50
		['use_last_reviewed_version', use_last_reviewed_version],
51
		['fallback_locale_id', fallback_locale_id],
52
		['source_locale_id', source_locale_id],
53
		['translation_key_prefix', translation_key_prefix],
54
		['filter_by_prefix', filter_by_prefix]
55
	]) {
56
		if (v !== undefined && v !== '' && k !== undefined) {
57
			url.searchParams.append(k, v)
58
		}
59
	}
60
	encodeParams({ format_options, custom_metadata_filters }).forEach((v, k) => {
61
		if (v !== undefined && v !== '') {
62
			url.searchParams.append(k, v)
63
		}
64
	})
65
	const response = await fetch(url, {
66
		method: 'GET',
67
		headers: {
68
			'If-Modified-Since': If_Modified_Since,
69
			'If-None-Match': If_None_Match,
70
			Authorization: 'ApiToken ' + auth.token
71
		},
72
		body: undefined
73
	})
74
	if (!response.ok) {
75
		const text = await response.text()
76
		throw new Error(`${response.status} ${text}`)
77
	}
78
	return await response.text()
79
}
80

81
function encodeParams(o: any) {
82
	function iter(o: any, path: string) {
83
		if (Array.isArray(o)) {
84
			o.forEach(function (a) {
85
				iter(a, path + '[]')
86
			})
87
			return
88
		}
89
		if (o !== null && typeof o === 'object') {
90
			Object.keys(o).forEach(function (k) {
91
				iter(o[k], path + '[' + k + ']')
92
			})
93
			return
94
		}
95
		data.push(path + '=' + o)
96
	}
97
	const data: string[] = []
98
	Object.keys(o).forEach(function (k) {
99
		if (o[k] !== undefined) {
100
			iter(o[k], k)
101
		}
102
	})
103
	return new URLSearchParams(data.join('&'))
104
}
105