locize-cli 11.0.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/LICENSE +1 -1
- package/README.md +1 -0
- package/dist/cjs/add.js +90 -0
- package/{bin/locize → dist/cjs/cli.js} +390 -670
- package/dist/cjs/combineSubkeyPreprocessor.js +155 -0
- package/dist/cjs/convertToDesiredFormat.js +205 -0
- package/dist/cjs/convertToFlatFormat.js +231 -0
- package/dist/cjs/copyVersion.js +60 -0
- package/dist/cjs/createBranch.js +59 -0
- package/dist/cjs/deleteBranch.js +89 -0
- package/dist/cjs/deleteNamespace.js +37 -0
- package/dist/cjs/download.js +376 -0
- package/dist/cjs/filterNamespaces.js +13 -0
- package/dist/cjs/format.js +156 -0
- package/dist/cjs/formats.js +33 -0
- package/dist/cjs/get.js +66 -0
- package/dist/cjs/getBranches.js +37 -0
- package/dist/cjs/getJob.js +37 -0
- package/dist/cjs/getProjectStats.js +37 -0
- package/dist/cjs/getRemoteLanguages.js +38 -0
- package/dist/cjs/getRemoteNamespace.js +125 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/isValidUuid.js +6 -0
- package/dist/cjs/lngs.js +215 -0
- package/dist/cjs/mapLimit.js +22 -0
- package/dist/cjs/mergeBranch.js +80 -0
- package/dist/cjs/migrate.js +239 -0
- package/dist/cjs/missing.js +162 -0
- package/dist/cjs/package.json +5 -0
- package/{parseLocalLanguage.js → dist/cjs/parseLocalLanguage.js} +135 -142
- package/dist/cjs/parseLocalLanguages.js +18 -0
- package/dist/cjs/parseLocalReference.js +11 -0
- package/dist/cjs/publishVersion.js +42 -0
- package/dist/cjs/removeUndefinedFromArrays.js +19 -0
- package/dist/cjs/removeVersion.js +42 -0
- package/dist/cjs/request.js +66 -0
- package/dist/cjs/shouldUnflatten.js +21 -0
- package/dist/cjs/sortFlatResources.js +13 -0
- package/dist/cjs/sync.js +772 -0
- package/dist/cjs/unflatten.js +81 -0
- package/dist/esm/add.js +88 -0
- package/dist/esm/cli.js +1020 -0
- package/{combineSubkeyPreprocessor.js → dist/esm/combineSubkeyPreprocessor.js} +70 -73
- package/dist/esm/convertToDesiredFormat.js +203 -0
- package/dist/esm/convertToFlatFormat.js +229 -0
- package/dist/esm/copyVersion.js +58 -0
- package/dist/esm/createBranch.js +57 -0
- package/dist/esm/deleteBranch.js +87 -0
- package/dist/esm/deleteNamespace.js +35 -0
- package/dist/esm/download.js +374 -0
- package/{filterNamespaces.js → dist/esm/filterNamespaces.js} +4 -4
- package/dist/esm/format.js +154 -0
- package/{formats.js → dist/esm/formats.js} +7 -11
- package/dist/esm/get.js +64 -0
- package/dist/esm/getBranches.js +35 -0
- package/dist/esm/getJob.js +35 -0
- package/dist/esm/getProjectStats.js +35 -0
- package/dist/esm/getRemoteLanguages.js +36 -0
- package/dist/esm/getRemoteNamespace.js +123 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/isValidUuid.js +4 -0
- package/dist/esm/lngs.js +213 -0
- package/dist/esm/mapLimit.js +20 -0
- package/dist/esm/mergeBranch.js +78 -0
- package/dist/esm/migrate.js +237 -0
- package/dist/esm/missing.js +160 -0
- package/dist/esm/parseLocalLanguage.js +194 -0
- package/dist/esm/parseLocalLanguages.js +16 -0
- package/dist/esm/parseLocalReference.js +9 -0
- package/dist/esm/publishVersion.js +40 -0
- package/{removeUndefinedFromArrays.js → dist/esm/removeUndefinedFromArrays.js} +5 -5
- package/dist/esm/removeVersion.js +40 -0
- package/dist/esm/request.js +64 -0
- package/{shouldUnflatten.js → dist/esm/shouldUnflatten.js} +7 -7
- package/dist/esm/sortFlatResources.js +11 -0
- package/dist/esm/sync.js +770 -0
- package/{unflatten.js → dist/esm/unflatten.js} +36 -34
- package/package.json +39 -18
- package/rollup.config.js +57 -0
- package/add.js +0 -105
- package/convertToDesiredFormat.js +0 -268
- package/convertToFlatFormat.js +0 -322
- package/copyVersion.js +0 -69
- package/createBranch.js +0 -61
- package/deleteBranch.js +0 -97
- package/deleteNamespace.js +0 -39
- package/download.js +0 -516
- package/format.js +0 -206
- package/get.js +0 -81
- package/getBranches.js +0 -40
- package/getJob.js +0 -40
- package/getProjectStats.js +0 -40
- package/getRemoteLanguages.js +0 -40
- package/getRemoteNamespace.js +0 -122
- package/index.js +0 -9
- package/isValidUuid.js +0 -2
- package/lngs.json +0 -211
- package/mergeBranch.js +0 -102
- package/migrate.js +0 -314
- package/missing.js +0 -169
- package/parseLocalLanguages.js +0 -22
- package/parseLocalReference.js +0 -10
- package/publishVersion.js +0 -64
- package/removeVersion.js +0 -64
- package/request.js +0 -64
- package/sortFlatResources.js +0 -9
- package/sync.js +0 -786
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { mkdirp } from 'mkdirp';
|
|
4
|
+
import convertToFlatFormat from './convertToFlatFormat.js';
|
|
5
|
+
import { fileExtensionsMap as fileExtensionsMap$1, acceptedFileExtensions as acceptedFileExtensions$1 } from './formats.js';
|
|
6
|
+
import xcstrings2locize from 'locize-xcstrings/cjs/xcstrings2locize';
|
|
7
|
+
|
|
8
|
+
const fileExtensionsMap = fileExtensionsMap$1;
|
|
9
|
+
const acceptedFileExtensions = acceptedFileExtensions$1;
|
|
10
|
+
|
|
11
|
+
const getFiles = (srcpath) => {
|
|
12
|
+
return fs.readdirSync(srcpath).filter((file) => {
|
|
13
|
+
return !fs.statSync(path.join(srcpath, file)).isDirectory()
|
|
14
|
+
}).filter((file) => acceptedFileExtensions.indexOf(path.extname(file)) > -1)
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const getDirectories = (srcpath) => {
|
|
18
|
+
return fs.readdirSync(srcpath).filter((file) => {
|
|
19
|
+
return fs.statSync(path.join(srcpath, file)).isDirectory()
|
|
20
|
+
})
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const parseLocalLanguage = async (opt, lng) => {
|
|
24
|
+
const hasNamespaceInPath = opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) > -1;
|
|
25
|
+
const filledLngMask = opt.pathMask.replace(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`, opt.format === 'xcstrings' ? '' : lng);
|
|
26
|
+
let firstPartLngMask, lastPartLngMask;
|
|
27
|
+
if (opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`) > opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`)) {
|
|
28
|
+
const secondPartMask = opt.pathMask.substring(opt.pathMask.lastIndexOf(path.sep) + 1);
|
|
29
|
+
firstPartLngMask = secondPartMask.substring(0, secondPartMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`));
|
|
30
|
+
lastPartLngMask = secondPartMask.substring(secondPartMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`) + `${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`.length);
|
|
31
|
+
}
|
|
32
|
+
let lngPath;
|
|
33
|
+
if (filledLngMask.lastIndexOf(path.sep) > 0) {
|
|
34
|
+
lngPath = filledLngMask.substring(0, filledLngMask.lastIndexOf(path.sep));
|
|
35
|
+
}
|
|
36
|
+
if (!opt.dry && lngPath && lngPath.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) < 0) mkdirp.sync(path.join(opt.path, lngPath));
|
|
37
|
+
|
|
38
|
+
let files = [];
|
|
39
|
+
try {
|
|
40
|
+
if (lngPath) {
|
|
41
|
+
if (lngPath.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) > -1) {
|
|
42
|
+
const firstPart = lngPath.substring(0, lngPath.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`));
|
|
43
|
+
const lastPart = lngPath.substring(lngPath.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) + `${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`.length);
|
|
44
|
+
let additionalSubDirsLeft = '';
|
|
45
|
+
let additionalSubDirs = '';
|
|
46
|
+
const splittedP = lngPath.split(path.sep);
|
|
47
|
+
const foundSplitted = splittedP.find((s) => s.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) > -1);
|
|
48
|
+
const foundSplittedIndex = splittedP.indexOf(foundSplitted);
|
|
49
|
+
if (splittedP.length > 2) {
|
|
50
|
+
additionalSubDirsLeft = splittedP.slice(0, foundSplittedIndex).join(path.sep);
|
|
51
|
+
additionalSubDirs = splittedP.slice(foundSplittedIndex + 1).join(path.sep);
|
|
52
|
+
}
|
|
53
|
+
let dirs = getDirectories(path.join(opt.path, additionalSubDirsLeft));
|
|
54
|
+
if (additionalSubDirs === '') {
|
|
55
|
+
dirs = dirs.filter((d) => d.startsWith(firstPart) && d.endsWith(lastPart));
|
|
56
|
+
}
|
|
57
|
+
dirs.forEach((d) => {
|
|
58
|
+
if (additionalSubDirs && fs.statSync(path.join(opt.path, additionalSubDirsLeft, d)).isDirectory()) {
|
|
59
|
+
let directoryExists = false;
|
|
60
|
+
try {
|
|
61
|
+
directoryExists = fs.statSync(path.join(opt.path, additionalSubDirsLeft, d, additionalSubDirs)).isDirectory();
|
|
62
|
+
} catch (e) {}
|
|
63
|
+
if (directoryExists) {
|
|
64
|
+
let subFls = getFiles(path.join(opt.path, additionalSubDirsLeft, d, additionalSubDirs));
|
|
65
|
+
if (firstPartLngMask || lastPartLngMask) subFls = subFls.filter((f) => path.basename(f, path.extname(f)) === `${firstPartLngMask}${lng}${lastPartLngMask}`);
|
|
66
|
+
|
|
67
|
+
subFls = subFls.filter((f) => {
|
|
68
|
+
const a = path.join(additionalSubDirsLeft, d, additionalSubDirs, path.basename(f, path.extname(f)));
|
|
69
|
+
const startIndexOfNs = filledLngMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`);
|
|
70
|
+
if (startIndexOfNs === -1) return true
|
|
71
|
+
const afterNs = filledLngMask.substring(startIndexOfNs + `${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`.length);
|
|
72
|
+
const nsName = a.substring(startIndexOfNs, a.indexOf(afterNs));
|
|
73
|
+
const b = filledLngMask.replace(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`, nsName);
|
|
74
|
+
return a === b
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
files = files.concat(subFls.map((f) => `${additionalSubDirsLeft ? additionalSubDirsLeft + path.sep : ''}${d}${path.sep}${additionalSubDirs}${path.sep}${f}`));
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
const fls = getFiles(path.join(opt.path, additionalSubDirsLeft, d)).filter((f) => path.basename(f, path.extname(f)) === `${firstPartLngMask}${lng}${lastPartLngMask}`);
|
|
81
|
+
files = files.concat(fls.map((f) => `${additionalSubDirsLeft ? additionalSubDirsLeft + path.sep : ''}${d}${path.sep}${f}`));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
files = getFiles(path.join(opt.path, lngPath));
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
files = getFiles(opt.path);
|
|
89
|
+
// filter lng files...
|
|
90
|
+
const lngIndex = filledLngMask.indexOf(lng);
|
|
91
|
+
const lngLeftLength = filledLngMask.length - lngIndex;
|
|
92
|
+
files = files.filter((f) => { // {{language}} can be left or right of {{namespace}}
|
|
93
|
+
if (opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}language${opt.pathMaskInterpolationSuffix}`) < opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`)) {
|
|
94
|
+
return f.indexOf(lng) === lngIndex
|
|
95
|
+
}
|
|
96
|
+
return (path.basename(f, path.extname(f)).length - f.indexOf(lng)) === lngLeftLength
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
} catch (err) {}
|
|
100
|
+
|
|
101
|
+
// Async map logic using Promise.all
|
|
102
|
+
const results = await Promise.all(files.map(async (fileOrig) => {
|
|
103
|
+
let file = fileOrig;
|
|
104
|
+
let dirPath;
|
|
105
|
+
if (file.lastIndexOf(path.sep) > 0) {
|
|
106
|
+
dirPath = file.substring(0, file.lastIndexOf(path.sep));
|
|
107
|
+
file = file.substring(file.lastIndexOf(path.sep) + 1);
|
|
108
|
+
}
|
|
109
|
+
const fExt = path.extname(file);
|
|
110
|
+
let namespace = path.basename(file, fExt);
|
|
111
|
+
const nsMask = `${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`;
|
|
112
|
+
const filledNsMask = lngPath && lngPath.indexOf(nsMask) > -1 ? filledLngMask : filledLngMask.substring(filledLngMask.lastIndexOf(path.sep) + 1);
|
|
113
|
+
const startNsIndex = filledNsMask.indexOf(nsMask);
|
|
114
|
+
let restNsMask = filledNsMask.substring((startNsIndex || 0) + nsMask.length);
|
|
115
|
+
namespace = namespace.substring(startNsIndex || 0, namespace.lastIndexOf(restNsMask));
|
|
116
|
+
if (lngPath && lngPath.indexOf(nsMask) > -1) {
|
|
117
|
+
restNsMask = restNsMask.substring(0, restNsMask.lastIndexOf(path.sep));
|
|
118
|
+
if (dirPath.indexOf(restNsMask) > 0) {
|
|
119
|
+
namespace = dirPath.substring(filledNsMask.indexOf(nsMask), dirPath.indexOf(restNsMask));
|
|
120
|
+
} else {
|
|
121
|
+
namespace = dirPath.substring(filledNsMask.indexOf(nsMask));
|
|
122
|
+
}
|
|
123
|
+
} else if (!hasNamespaceInPath && startNsIndex < 0) {
|
|
124
|
+
namespace = opt.namespace;
|
|
125
|
+
}
|
|
126
|
+
let fPath = path.join(opt.path, lngPath || '', file);
|
|
127
|
+
if (dirPath && lngPath.indexOf(nsMask) > -1) {
|
|
128
|
+
fPath = path.join(opt.path, dirPath.replace(nsMask, namespace), file);
|
|
129
|
+
}
|
|
130
|
+
if (!namespace) throw new Error(`namespace could not be found in ${fPath}`)
|
|
131
|
+
if (opt.namespaces && opt.namespaces.indexOf(namespace) < 0) return undefined
|
|
132
|
+
if (opt.namespace && opt.namespace !== namespace) return undefined
|
|
133
|
+
const data = await fs.promises.readFile(fPath);
|
|
134
|
+
if (fileExtensionsMap[fExt].indexOf(opt.format) < 0) {
|
|
135
|
+
throw new Error(`Format mismatch! Found ${fileExtensionsMap[fExt][0]} but requested ${opt.format}!`)
|
|
136
|
+
}
|
|
137
|
+
if (opt.namespace) {
|
|
138
|
+
let hasNamespaceInPathPask = !opt.pathMask || !opt.pathMaskInterpolationPrefix || !opt.pathMaskInterpolationSuffix;
|
|
139
|
+
hasNamespaceInPathPask = !hasNamespaceInPathPask && opt.pathMask.indexOf(`${opt.pathMaskInterpolationPrefix}namespace${opt.pathMaskInterpolationSuffix}`) > -1;
|
|
140
|
+
if (!hasNamespaceInPathPask && namespace === lng) {
|
|
141
|
+
namespace = opt.namespace;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (opt.format === 'xcstrings') {
|
|
145
|
+
try {
|
|
146
|
+
const content = xcstrings2locize(data);
|
|
147
|
+
const stat = await fs.promises.stat(fPath);
|
|
148
|
+
return Object.keys(content.resources).map((l) => ({
|
|
149
|
+
namespace,
|
|
150
|
+
path: fPath,
|
|
151
|
+
extension: fExt,
|
|
152
|
+
content: content.resources[l],
|
|
153
|
+
language: l,
|
|
154
|
+
mtime: stat.mtime
|
|
155
|
+
}))
|
|
156
|
+
} catch (err) {
|
|
157
|
+
err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '');
|
|
158
|
+
err.message += '\n' + fPath;
|
|
159
|
+
throw err
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
let content;
|
|
163
|
+
try {
|
|
164
|
+
content = await convertToFlatFormat(opt, data, lng);
|
|
165
|
+
} catch (err) {
|
|
166
|
+
err.message = 'Invalid content for "' + opt.format + '" format!\n' + (err.message || '');
|
|
167
|
+
err.message += '\n' + fPath;
|
|
168
|
+
throw err
|
|
169
|
+
}
|
|
170
|
+
const stat = await fs.promises.stat(fPath);
|
|
171
|
+
return {
|
|
172
|
+
namespace,
|
|
173
|
+
path: fPath,
|
|
174
|
+
extension: fExt,
|
|
175
|
+
content,
|
|
176
|
+
language: lng,
|
|
177
|
+
mtime: stat.mtime
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}));
|
|
181
|
+
|
|
182
|
+
// xcstrings, returns array in array
|
|
183
|
+
const r = results.filter((r) => r !== undefined).reduce((prev, cur) => {
|
|
184
|
+
if (Array.isArray(cur)) {
|
|
185
|
+
prev = prev.concat(cur);
|
|
186
|
+
} else {
|
|
187
|
+
prev.push(cur);
|
|
188
|
+
}
|
|
189
|
+
return prev
|
|
190
|
+
}, []);
|
|
191
|
+
return r
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export { parseLocalLanguage as default };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import parseLocalLanguage from './parseLocalLanguage.js';
|
|
2
|
+
import filterNamespaces from './filterNamespaces.js';
|
|
3
|
+
|
|
4
|
+
const parseLocalLanguages = async (opt, lngs) => {
|
|
5
|
+
let res = [];
|
|
6
|
+
for (const lng of lngs) {
|
|
7
|
+
if (opt.language && (lng !== opt.language && lng !== opt.referenceLanguage)) {
|
|
8
|
+
continue
|
|
9
|
+
}
|
|
10
|
+
const nss = await parseLocalLanguage(opt, lng);
|
|
11
|
+
res = res.concat(filterNamespaces(opt, nss));
|
|
12
|
+
}
|
|
13
|
+
return res
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { parseLocalLanguages as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import parseLocalLanguage from './parseLocalLanguage.js';
|
|
2
|
+
import filterNamespaces from './filterNamespaces.js';
|
|
3
|
+
|
|
4
|
+
const parseLocalReference = async (opt) => {
|
|
5
|
+
const nss = await parseLocalLanguage(opt, opt.referenceLanguage);
|
|
6
|
+
return filterNamespaces(opt, nss).filter((n) => n.language === opt.referenceLanguage)
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export { parseLocalReference as default };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import colors from 'colors';
|
|
2
|
+
import request from './request.js';
|
|
3
|
+
import getJob from './getJob.js';
|
|
4
|
+
|
|
5
|
+
const publishVersion = async (opt) => {
|
|
6
|
+
const { res, obj } = await request(opt.apiEndpoint + '/publish/' + opt.projectId + '/' + opt.version + (opt.tenants ? '?tenants=true' : ''), {
|
|
7
|
+
method: 'post',
|
|
8
|
+
headers: {
|
|
9
|
+
Authorization: opt.apiKey
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
if (obj && (obj.errorMessage || obj.message)) {
|
|
13
|
+
console.log(colors.red(`publishing failed for ${opt.version}...`));
|
|
14
|
+
throw new Error(obj.errorMessage || obj.message)
|
|
15
|
+
}
|
|
16
|
+
if (res.status >= 300) {
|
|
17
|
+
console.error(colors.red(res.statusText + ' (' + res.status + ')'));
|
|
18
|
+
throw new Error(res.statusText + ' (' + res.status + ')')
|
|
19
|
+
}
|
|
20
|
+
if (!obj || !obj.jobId) {
|
|
21
|
+
console.error(colors.red('No jobId! Something went wrong!'));
|
|
22
|
+
throw new Error('No jobId! Something went wrong!')
|
|
23
|
+
}
|
|
24
|
+
// Poll for job completion
|
|
25
|
+
while (true) {
|
|
26
|
+
const job = await getJob(opt, obj.jobId);
|
|
27
|
+
if (job && !job.timeouted) {
|
|
28
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
29
|
+
continue
|
|
30
|
+
}
|
|
31
|
+
if (job && job.timeouted) {
|
|
32
|
+
console.error(colors.red('Job timeouted!'));
|
|
33
|
+
throw new Error('Job timeouted!')
|
|
34
|
+
}
|
|
35
|
+
break
|
|
36
|
+
}
|
|
37
|
+
console.log(colors.green(`publishing for ${opt.version} succesfully requested`));
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { publishVersion as default };
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
function removeUndefinedFromArrays (obj) {
|
|
3
3
|
if (!obj) return obj
|
|
4
4
|
|
|
5
|
-
const propNames = Object.keys(obj)
|
|
5
|
+
const propNames = Object.keys(obj);
|
|
6
6
|
propNames.forEach((propName) => {
|
|
7
7
|
if (Array.isArray(obj[propName]) && obj[propName][0] === undefined) {
|
|
8
|
-
obj[propName].shift()
|
|
8
|
+
obj[propName].shift();
|
|
9
9
|
} else if (typeof obj[propName] === 'object') {
|
|
10
|
-
removeUndefinedFromArrays(obj[propName])
|
|
10
|
+
removeUndefinedFromArrays(obj[propName]);
|
|
11
11
|
}
|
|
12
|
-
})
|
|
12
|
+
});
|
|
13
13
|
|
|
14
14
|
return obj
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
export { removeUndefinedFromArrays as default };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import colors from 'colors';
|
|
2
|
+
import request from './request.js';
|
|
3
|
+
import getJob from './getJob.js';
|
|
4
|
+
|
|
5
|
+
const removeVersion = async (opt) => {
|
|
6
|
+
const { res, obj } = await request(opt.apiEndpoint + '/version/' + opt.projectId + '/' + opt.version, {
|
|
7
|
+
method: 'delete',
|
|
8
|
+
headers: {
|
|
9
|
+
Authorization: opt.apiKey
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
if (obj && (obj.errorMessage || obj.message)) {
|
|
13
|
+
console.log(colors.red(`remove failed for version ${opt.version}...`));
|
|
14
|
+
throw new Error(obj.errorMessage || obj.message)
|
|
15
|
+
}
|
|
16
|
+
if (res.status >= 300) {
|
|
17
|
+
console.error(colors.red(res.statusText + ' (' + res.status + ')'));
|
|
18
|
+
throw new Error(res.statusText + ' (' + res.status + ')')
|
|
19
|
+
}
|
|
20
|
+
if (!obj || !obj.jobId) {
|
|
21
|
+
console.error(colors.red('No jobId! Something went wrong!'));
|
|
22
|
+
throw new Error('No jobId! Something went wrong!')
|
|
23
|
+
}
|
|
24
|
+
// Poll for job completion
|
|
25
|
+
while (true) {
|
|
26
|
+
const job = await getJob(opt, obj.jobId);
|
|
27
|
+
if (job && !job.timeouted) {
|
|
28
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
29
|
+
continue
|
|
30
|
+
}
|
|
31
|
+
if (job && job.timeouted) {
|
|
32
|
+
console.error(colors.red('Job timeouted!'));
|
|
33
|
+
throw new Error('Job timeouted!')
|
|
34
|
+
}
|
|
35
|
+
break
|
|
36
|
+
}
|
|
37
|
+
console.log(colors.green(`remove version ${opt.version} succesfully requested`));
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { removeVersion as default };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
2
|
+
import https from 'https';
|
|
3
|
+
import CacheableLookup from 'cacheable-lookup';
|
|
4
|
+
|
|
5
|
+
const cacheable = new CacheableLookup();
|
|
6
|
+
cacheable.install(https.globalAgent);
|
|
7
|
+
|
|
8
|
+
const httpProxy = process.env.http_proxy || process.env.HTTP_PROXY || process.env.https_proxy || process.env.HTTPS_PROXY;
|
|
9
|
+
const isRetriableError = (err) => {
|
|
10
|
+
return err && err.message && (
|
|
11
|
+
err.message.indexOf('ETIMEDOUT') > -1 || // on timeout retry
|
|
12
|
+
err.message.indexOf('FetchError') > -1 ||
|
|
13
|
+
err.code === 'ETIMEDOUT' ||
|
|
14
|
+
// on dns errors
|
|
15
|
+
err.message.indexOf('ENOTFOUND') > -1 ||
|
|
16
|
+
err.message.indexOf('ENODATA') > -1 ||
|
|
17
|
+
err.message.indexOf('ENOENT') > -1 // Windows: name exists, but not this record type
|
|
18
|
+
)
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const isJSONResponse = (res) => res.headers.get('content-type') && res.headers.get('content-type').indexOf('json') > 0;
|
|
22
|
+
|
|
23
|
+
const handleResponse = (res) => {
|
|
24
|
+
if (isJSONResponse(res)) {
|
|
25
|
+
return new Promise((resolve, reject) => res.json().then((obj) => resolve({ res, obj })).catch(reject))
|
|
26
|
+
} else {
|
|
27
|
+
return { res }
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
async function request (url, options) {
|
|
32
|
+
if (httpProxy) {
|
|
33
|
+
const httpsProxyAgent = new HttpsProxyAgent(httpProxy);
|
|
34
|
+
cacheable.install(httpsProxyAgent);
|
|
35
|
+
options.agent = httpsProxyAgent;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
options.headers = options.headers || {};
|
|
39
|
+
options.headers['User-Agent'] = `__packageName__/v__packageVersion__ (node/${process.version}; ${process.platform} ${process.arch})`; // This string is replaced with the actual version at build time by rollup
|
|
40
|
+
options.headers['X-User-Agent'] = options.headers['User-Agent'];
|
|
41
|
+
if (options.body || options.method !== 'get') options.headers['Content-Type'] = 'application/json';
|
|
42
|
+
if (options.body) {
|
|
43
|
+
if (typeof options.body !== 'string') {
|
|
44
|
+
options.body = JSON.stringify(options.body);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (options.headers['Authorization'] === undefined) delete options.headers['Authorization'];
|
|
48
|
+
|
|
49
|
+
async function retriableFetch (maxRetries) {
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(url, options);
|
|
52
|
+
const result = await handleResponse(response);
|
|
53
|
+
return result
|
|
54
|
+
} catch (err) {
|
|
55
|
+
if (maxRetries < 1) throw err
|
|
56
|
+
if (!isRetriableError(err)) throw err
|
|
57
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
58
|
+
return retriableFetch(--maxRetries)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return retriableFetch(3)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { request as default };
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
const shouldUnflatten = (json) => {
|
|
2
|
-
const keys = Object.keys(json)
|
|
3
|
-
let shouldUnflatten = true
|
|
2
|
+
const keys = Object.keys(json);
|
|
3
|
+
let shouldUnflatten = true;
|
|
4
4
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
5
|
-
const key = keys[i]
|
|
5
|
+
const key = keys[i];
|
|
6
6
|
|
|
7
7
|
if (shouldUnflatten && /( |,|\?)/.test(key)) {
|
|
8
|
-
shouldUnflatten = false
|
|
8
|
+
shouldUnflatten = false;
|
|
9
9
|
return shouldUnflatten
|
|
10
10
|
} else if (shouldUnflatten && key.indexOf('.') > -1 && keys.indexOf(key.substring(0, key.lastIndexOf('.'))) > -1) {
|
|
11
|
-
shouldUnflatten = false
|
|
11
|
+
shouldUnflatten = false;
|
|
12
12
|
return shouldUnflatten
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
return shouldUnflatten
|
|
17
|
-
}
|
|
17
|
+
};
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
export { shouldUnflatten as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const sortFlatResources = (resources) => {
|
|
2
|
+
const keys = Object.keys(resources).sort();
|
|
3
|
+
const cleaned = {};
|
|
4
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
5
|
+
const key = keys[i];
|
|
6
|
+
cleaned[key] = resources[key];
|
|
7
|
+
}
|
|
8
|
+
return cleaned
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { sortFlatResources as default };
|