@rockcarver/frodo-lib 0.11.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/.eslintrc +32 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +30 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/README.md +121 -0
- package/.github/workflows/pipeline.yml +287 -0
- package/.prettierrc +6 -0
- package/CHANGELOG.md +512 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/LICENSE +21 -0
- package/README.md +8 -0
- package/docs/CONTRIBUTE.md +96 -0
- package/docs/PIPELINE.md +169 -0
- package/docs/images/npm_versioning_guidelines.png +0 -0
- package/docs/images/release_pipeline.png +0 -0
- package/jsconfig.json +6 -0
- package/package.json +95 -0
- package/resources/sampleEntitiesFile.json +8 -0
- package/resources/sampleEnvFile.env +2 -0
- package/src/api/AuthenticateApi.js +33 -0
- package/src/api/BaseApi.js +242 -0
- package/src/api/CirclesOfTrustApi.js +87 -0
- package/src/api/EmailTemplateApi.js +37 -0
- package/src/api/IdmConfigApi.js +88 -0
- package/src/api/LogApi.js +45 -0
- package/src/api/ManagedObjectApi.js +62 -0
- package/src/api/OAuth2ClientApi.js +69 -0
- package/src/api/OAuth2OIDCApi.js +73 -0
- package/src/api/OAuth2ProviderApi.js +32 -0
- package/src/api/RealmApi.js +99 -0
- package/src/api/Saml2Api.js +176 -0
- package/src/api/ScriptApi.js +84 -0
- package/src/api/SecretsApi.js +151 -0
- package/src/api/ServerInfoApi.js +41 -0
- package/src/api/SocialIdentityProvidersApi.js +114 -0
- package/src/api/StartupApi.js +45 -0
- package/src/api/ThemeApi.js +181 -0
- package/src/api/TreeApi.js +207 -0
- package/src/api/VariablesApi.js +104 -0
- package/src/api/utils/ApiUtils.js +77 -0
- package/src/api/utils/ApiUtils.test.js +96 -0
- package/src/api/utils/Base64.js +62 -0
- package/src/index.js +32 -0
- package/src/index.test.js +13 -0
- package/src/ops/AdminOps.js +901 -0
- package/src/ops/AuthenticateOps.js +342 -0
- package/src/ops/CirclesOfTrustOps.js +350 -0
- package/src/ops/ConnectionProfileOps.js +254 -0
- package/src/ops/EmailTemplateOps.js +326 -0
- package/src/ops/IdmOps.js +227 -0
- package/src/ops/IdpOps.js +342 -0
- package/src/ops/JourneyOps.js +2026 -0
- package/src/ops/LogOps.js +357 -0
- package/src/ops/ManagedObjectOps.js +34 -0
- package/src/ops/OAuth2ClientOps.js +151 -0
- package/src/ops/OrganizationOps.js +85 -0
- package/src/ops/RealmOps.js +139 -0
- package/src/ops/SamlOps.js +541 -0
- package/src/ops/ScriptOps.js +211 -0
- package/src/ops/SecretsOps.js +288 -0
- package/src/ops/StartupOps.js +114 -0
- package/src/ops/ThemeOps.js +379 -0
- package/src/ops/VariablesOps.js +185 -0
- package/src/ops/templates/OAuth2ClientTemplate.json +270 -0
- package/src/ops/templates/OrgModelUserAttributesTemplate.json +149 -0
- package/src/ops/templates/cloud/GenericExtensionAttributesTemplate.json +392 -0
- package/src/ops/templates/cloud/managed.json +4119 -0
- package/src/ops/utils/Console.js +434 -0
- package/src/ops/utils/DataProtection.js +92 -0
- package/src/ops/utils/DataProtection.test.js +28 -0
- package/src/ops/utils/ExportImportUtils.js +146 -0
- package/src/ops/utils/ExportImportUtils.test.js +119 -0
- package/src/ops/utils/OpsUtils.js +76 -0
- package/src/ops/utils/Wordwrap.js +11 -0
- package/src/storage/SessionStorage.js +45 -0
- package/src/storage/StaticStorage.js +15 -0
- package/test/e2e/journey/baseline/ForgottenUsername.journey.json +216 -0
- package/test/e2e/journey/baseline/Login.journey.json +205 -0
- package/test/e2e/journey/baseline/PasswordGrant.journey.json +139 -0
- package/test/e2e/journey/baseline/ProgressiveProfile.journey.json +198 -0
- package/test/e2e/journey/baseline/Registration.journey.json +249 -0
- package/test/e2e/journey/baseline/ResetPassword.journey.json +268 -0
- package/test/e2e/journey/baseline/UpdatePassword.journey.json +323 -0
- package/test/e2e/journey/baseline/allAlphaJourneys.journeys.json +1520 -0
- package/test/e2e/journey/delete/ForgottenUsername.journey.json +216 -0
- package/test/e2e/journey/delete/Login.journey.json +205 -0
- package/test/e2e/journey/delete/PasswordGrant.journey.json +139 -0
- package/test/e2e/journey/delete/ProgressiveProfile.journey.json +198 -0
- package/test/e2e/journey/delete/Registration.journey.json +249 -0
- package/test/e2e/journey/delete/ResetPassword.journey.json +268 -0
- package/test/e2e/journey/delete/UpdatePassword.journey.json +323 -0
- package/test/e2e/journey/delete/deleteMe.journey.json +230 -0
- package/test/e2e/journey/list/Disabled.journey.json +43 -0
- package/test/e2e/journey/list/ForgottenUsername.journey.json +216 -0
- package/test/e2e/journey/list/Login.journey.json +205 -0
- package/test/e2e/journey/list/PasswordGrant.journey.json +139 -0
- package/test/e2e/journey/list/ProgressiveProfile.journey.json +198 -0
- package/test/e2e/journey/list/Registration.journey.json +249 -0
- package/test/e2e/journey/list/ResetPassword.journey.json +268 -0
- package/test/e2e/journey/list/UpdatePassword.journey.json +323 -0
- package/test/e2e/setup.js +107 -0
- package/test/e2e/theme/baseline/Contrast.theme.json +95 -0
- package/test/e2e/theme/baseline/Highlander.theme.json +95 -0
- package/test/e2e/theme/baseline/Robroy.theme.json +95 -0
- package/test/e2e/theme/baseline/Starter-Theme.theme.json +94 -0
- package/test/e2e/theme/baseline/Zardoz.theme.json +95 -0
- package/test/e2e/theme/import/Contrast.theme.json +95 -0
- package/test/e2e/theme/import/Highlander.theme.json +95 -0
- package/test/e2e/theme/import/Robroy.theme.json +95 -0
- package/test/e2e/theme/import/Starter-Theme.theme.json +94 -0
- package/test/e2e/theme/import/Zardoz.default.theme.json +95 -0
- package/test/fs_tmp/.gitkeep +2 -0
- package/test/global/setup.js +65 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import {
|
|
3
|
+
deleteTheme,
|
|
4
|
+
deleteThemeByName,
|
|
5
|
+
deleteThemes,
|
|
6
|
+
getTheme,
|
|
7
|
+
getThemeByName,
|
|
8
|
+
getThemes,
|
|
9
|
+
putTheme,
|
|
10
|
+
putThemeByName,
|
|
11
|
+
putThemes,
|
|
12
|
+
} from '../api/ThemeApi.js';
|
|
13
|
+
import {
|
|
14
|
+
createProgressBar,
|
|
15
|
+
createTable,
|
|
16
|
+
failSpinner,
|
|
17
|
+
printMessage,
|
|
18
|
+
showSpinner,
|
|
19
|
+
stopProgressBar,
|
|
20
|
+
succeedSpinner,
|
|
21
|
+
updateProgressBar,
|
|
22
|
+
} from './utils/Console.js';
|
|
23
|
+
import {
|
|
24
|
+
getRealmString,
|
|
25
|
+
getTypedFilename,
|
|
26
|
+
saveToFile,
|
|
27
|
+
validateImport,
|
|
28
|
+
} from './utils/ExportImportUtils.js';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* List all the themes
|
|
32
|
+
* @param {boolean} long Long version, more fields
|
|
33
|
+
*/
|
|
34
|
+
export async function listThemes(long = false) {
|
|
35
|
+
const themeList = await getThemes();
|
|
36
|
+
themeList.sort((a, b) => a.name.localeCompare(b.name));
|
|
37
|
+
if (!long) {
|
|
38
|
+
themeList.forEach((theme) => {
|
|
39
|
+
printMessage(
|
|
40
|
+
`${theme.isDefault ? theme.name.brightCyan : theme.name}`,
|
|
41
|
+
'data'
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
const table = createTable([
|
|
46
|
+
'Name'.brightCyan,
|
|
47
|
+
'Id'.brightCyan,
|
|
48
|
+
'Default'.brightCyan,
|
|
49
|
+
]);
|
|
50
|
+
themeList.forEach((theme) => {
|
|
51
|
+
table.push([
|
|
52
|
+
`${theme.name}`,
|
|
53
|
+
`${theme._id}`,
|
|
54
|
+
`${theme.isDefault ? 'Yes'.brightGreen : ''}`,
|
|
55
|
+
]);
|
|
56
|
+
});
|
|
57
|
+
printMessage(table.toString(), 'data');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Export theme by name to file
|
|
63
|
+
* @param {String} name theme name
|
|
64
|
+
* @param {String} file optional export file name
|
|
65
|
+
*/
|
|
66
|
+
export async function exportThemeByName(name, file) {
|
|
67
|
+
let fileName = getTypedFilename(name, 'theme');
|
|
68
|
+
if (file) {
|
|
69
|
+
fileName = file;
|
|
70
|
+
}
|
|
71
|
+
createProgressBar(1, `Exporting ${name}`);
|
|
72
|
+
const themeData = await getThemeByName(name);
|
|
73
|
+
if (themeData.length === 0) {
|
|
74
|
+
stopProgressBar(`Theme ${name} not found!`);
|
|
75
|
+
printMessage(`Theme ${name} not found!`, 'error');
|
|
76
|
+
} else {
|
|
77
|
+
updateProgressBar(`Writing file ${fileName}`);
|
|
78
|
+
saveToFile('theme', themeData, '_id', fileName);
|
|
79
|
+
stopProgressBar(`Successfully exported theme ${name}.`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Export theme by uuid to file
|
|
85
|
+
* @param {String} id theme uuid
|
|
86
|
+
* @param {String} file optional export file name
|
|
87
|
+
*/
|
|
88
|
+
export async function exportThemeById(id, file) {
|
|
89
|
+
let fileName = getTypedFilename(id, 'theme');
|
|
90
|
+
if (file) {
|
|
91
|
+
fileName = file;
|
|
92
|
+
}
|
|
93
|
+
createProgressBar(1, `Exporting ${id}`);
|
|
94
|
+
const themeData = await getTheme(id);
|
|
95
|
+
if (themeData.length === 0) {
|
|
96
|
+
stopProgressBar(`Theme ${id} not found!`);
|
|
97
|
+
printMessage(`Theme ${id} not found!`, 'error');
|
|
98
|
+
} else {
|
|
99
|
+
updateProgressBar(`Writing file ${fileName}`);
|
|
100
|
+
saveToFile('theme', themeData, '_id', fileName);
|
|
101
|
+
stopProgressBar(`Successfully exported theme ${id}.`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Export all themes to file
|
|
107
|
+
* @param {String} file optional export file name
|
|
108
|
+
*/
|
|
109
|
+
export async function exportThemesToFile(file) {
|
|
110
|
+
let fileName = getTypedFilename(`all${getRealmString()}Themes`, 'theme');
|
|
111
|
+
if (file) {
|
|
112
|
+
fileName = file;
|
|
113
|
+
}
|
|
114
|
+
const allThemesData = await getThemes();
|
|
115
|
+
createProgressBar(allThemesData.length, 'Exporting themes');
|
|
116
|
+
for (const themeData of allThemesData) {
|
|
117
|
+
updateProgressBar(`Exporting theme ${themeData.name}`);
|
|
118
|
+
}
|
|
119
|
+
saveToFile('theme', allThemesData, '_id', fileName);
|
|
120
|
+
stopProgressBar(`${allThemesData.length} themes exported to ${fileName}.`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Export all themes to separate files
|
|
125
|
+
*/
|
|
126
|
+
export async function exportThemesToFiles() {
|
|
127
|
+
const allThemesData = await getThemes();
|
|
128
|
+
createProgressBar(allThemesData.length, 'Exporting themes');
|
|
129
|
+
for (const themeData of allThemesData) {
|
|
130
|
+
updateProgressBar(`Writing theme ${themeData.name}`);
|
|
131
|
+
const fileName = getTypedFilename(themeData.name, 'theme');
|
|
132
|
+
saveToFile('theme', themeData, '_id', fileName);
|
|
133
|
+
}
|
|
134
|
+
stopProgressBar(`${allThemesData.length} themes exported.`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Import theme by name from file
|
|
139
|
+
* @param {String} name theme name
|
|
140
|
+
* @param {String} file import file name
|
|
141
|
+
*/
|
|
142
|
+
export async function importThemeByName(name, file) {
|
|
143
|
+
fs.readFile(file, 'utf8', (err, data) => {
|
|
144
|
+
if (err) throw err;
|
|
145
|
+
const themeData = JSON.parse(data);
|
|
146
|
+
if (validateImport(themeData.meta)) {
|
|
147
|
+
createProgressBar(1, 'Importing theme...');
|
|
148
|
+
let found = false;
|
|
149
|
+
for (const id in themeData.theme) {
|
|
150
|
+
if ({}.hasOwnProperty.call(themeData.theme, id)) {
|
|
151
|
+
if (themeData.theme[id].name === name) {
|
|
152
|
+
found = true;
|
|
153
|
+
updateProgressBar(`Importing ${themeData.theme[id].name}`);
|
|
154
|
+
putThemeByName(name, themeData.theme[id]).then((result) => {
|
|
155
|
+
if (result == null) {
|
|
156
|
+
stopProgressBar(
|
|
157
|
+
`Error importing theme ${themeData.theme[id].name}`
|
|
158
|
+
);
|
|
159
|
+
printMessage(
|
|
160
|
+
`Error importing theme ${themeData.theme[id].name}`,
|
|
161
|
+
'error'
|
|
162
|
+
);
|
|
163
|
+
} else {
|
|
164
|
+
stopProgressBar(`Successfully imported theme ${name}.`);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (!found) {
|
|
172
|
+
stopProgressBar(`Theme ${name} not found!`);
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
printMessage('Import validation failed...', 'error');
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Import theme by uuid from file
|
|
182
|
+
* @param {String} id theme uuid
|
|
183
|
+
* @param {String} file import file name
|
|
184
|
+
*/
|
|
185
|
+
export async function importThemeById(id, file) {
|
|
186
|
+
fs.readFile(file, 'utf8', (err, data) => {
|
|
187
|
+
if (err) throw err;
|
|
188
|
+
const themeData = JSON.parse(data);
|
|
189
|
+
if (validateImport(themeData.meta)) {
|
|
190
|
+
createProgressBar(1, 'Importing theme...');
|
|
191
|
+
let found = false;
|
|
192
|
+
for (const themeId in themeData.theme) {
|
|
193
|
+
if ({}.hasOwnProperty.call(themeData.theme, themeId)) {
|
|
194
|
+
if (themeId === id) {
|
|
195
|
+
found = true;
|
|
196
|
+
updateProgressBar(`Importing ${themeData.theme[themeId]._id}`);
|
|
197
|
+
putTheme(themeId, themeData.theme[themeId]).then((result) => {
|
|
198
|
+
if (result == null) {
|
|
199
|
+
stopProgressBar(
|
|
200
|
+
`Error importing theme ${themeData.theme[themeId]._id}`
|
|
201
|
+
);
|
|
202
|
+
printMessage(
|
|
203
|
+
`Error importing theme ${themeData.theme[themeId]._id}`,
|
|
204
|
+
'error'
|
|
205
|
+
);
|
|
206
|
+
} else {
|
|
207
|
+
stopProgressBar(`Successfully imported theme ${id}.`);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (!found) {
|
|
215
|
+
stopProgressBar(`Theme ${id} not found!`);
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
printMessage('Import validation failed...', 'error');
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Import all themes from single file
|
|
225
|
+
* @param {String} file import file name
|
|
226
|
+
*/
|
|
227
|
+
export async function importThemesFromFile(file) {
|
|
228
|
+
fs.readFile(file, 'utf8', (err, data) => {
|
|
229
|
+
if (err) throw err;
|
|
230
|
+
const fileData = JSON.parse(data);
|
|
231
|
+
if (validateImport(fileData.meta)) {
|
|
232
|
+
createProgressBar(
|
|
233
|
+
Object.keys(fileData.theme).length,
|
|
234
|
+
'Importing themes...'
|
|
235
|
+
);
|
|
236
|
+
for (const id in fileData.theme) {
|
|
237
|
+
if ({}.hasOwnProperty.call(fileData.theme, id)) {
|
|
238
|
+
updateProgressBar(`Importing ${fileData.theme[id].name}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
putThemes(fileData.theme).then((result) => {
|
|
242
|
+
if (result == null) {
|
|
243
|
+
stopProgressBar(
|
|
244
|
+
`Error importing ${Object.keys(fileData.theme).length} themes!`
|
|
245
|
+
);
|
|
246
|
+
printMessage(
|
|
247
|
+
`Error importing ${
|
|
248
|
+
Object.keys(fileData.theme).length
|
|
249
|
+
} themes from ${file}`,
|
|
250
|
+
'error'
|
|
251
|
+
);
|
|
252
|
+
} else {
|
|
253
|
+
stopProgressBar(
|
|
254
|
+
`Successfully imported ${
|
|
255
|
+
Object.keys(fileData.theme).length
|
|
256
|
+
} themes.`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
} else {
|
|
261
|
+
printMessage('Import validation failed...', 'error');
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Import themes from separate files
|
|
268
|
+
*/
|
|
269
|
+
export async function importThemesFromFiles() {
|
|
270
|
+
const names = fs.readdirSync('.');
|
|
271
|
+
const jsonFiles = names.filter((name) =>
|
|
272
|
+
name.toLowerCase().endsWith('.theme.json')
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
createProgressBar(jsonFiles.length, 'Importing themes...');
|
|
276
|
+
let fileData = null;
|
|
277
|
+
let count = 0;
|
|
278
|
+
let total = 0;
|
|
279
|
+
let files = 0;
|
|
280
|
+
for (const file of jsonFiles) {
|
|
281
|
+
const data = fs.readFileSync(file, 'utf8');
|
|
282
|
+
fileData = JSON.parse(data);
|
|
283
|
+
if (validateImport(fileData.meta)) {
|
|
284
|
+
count = Object.keys(fileData.theme).length;
|
|
285
|
+
// eslint-disable-next-line no-await-in-loop
|
|
286
|
+
const result = await putThemes(fileData.theme);
|
|
287
|
+
if (result == null) {
|
|
288
|
+
printMessage(`Error importing ${count} themes from ${file}`, 'error');
|
|
289
|
+
} else {
|
|
290
|
+
files += 1;
|
|
291
|
+
total += count;
|
|
292
|
+
updateProgressBar(`Imported ${count} theme(s) from ${file}`);
|
|
293
|
+
}
|
|
294
|
+
} else {
|
|
295
|
+
printMessage(`Validation of ${file} failed!`, 'error');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
stopProgressBar(
|
|
299
|
+
`Finished importing ${total} theme(s) from ${files} file(s).`
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Import first theme from file
|
|
305
|
+
* @param {String} file import file name
|
|
306
|
+
*/
|
|
307
|
+
export async function importFirstThemeFromFile(file) {
|
|
308
|
+
fs.readFile(file, 'utf8', (err, data) => {
|
|
309
|
+
if (err) throw err;
|
|
310
|
+
const themeData = JSON.parse(data);
|
|
311
|
+
if (validateImport(themeData.meta)) {
|
|
312
|
+
createProgressBar(1, 'Importing theme...');
|
|
313
|
+
for (const id in themeData.theme) {
|
|
314
|
+
if ({}.hasOwnProperty.call(themeData.theme, id)) {
|
|
315
|
+
updateProgressBar(`Importing ${themeData.theme[id].name}`);
|
|
316
|
+
putTheme(id, themeData.theme[id]).then((result) => {
|
|
317
|
+
if (result == null) {
|
|
318
|
+
stopProgressBar(
|
|
319
|
+
`Error importing theme ${themeData.theme[id].name}`
|
|
320
|
+
);
|
|
321
|
+
printMessage(
|
|
322
|
+
`Error importing theme ${themeData.theme[id].name}`,
|
|
323
|
+
'error'
|
|
324
|
+
);
|
|
325
|
+
} else {
|
|
326
|
+
stopProgressBar(
|
|
327
|
+
`Successfully imported theme ${themeData.theme[id].name}`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
} else {
|
|
335
|
+
printMessage('Import validation failed...', 'error');
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Delete theme by id
|
|
342
|
+
* @param {String} id theme id
|
|
343
|
+
*/
|
|
344
|
+
export async function deleteThemeCmd(id) {
|
|
345
|
+
showSpinner(`Deleting ${id}...`);
|
|
346
|
+
try {
|
|
347
|
+
await deleteTheme(id);
|
|
348
|
+
succeedSpinner(`Deleted ${id}.`);
|
|
349
|
+
} catch (error) {
|
|
350
|
+
failSpinner(`Error: ${error.message}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Delete theme by name
|
|
356
|
+
* @param {String} name theme name
|
|
357
|
+
*/
|
|
358
|
+
export async function deleteThemeByNameCmd(name) {
|
|
359
|
+
showSpinner(`Deleting ${name}...`);
|
|
360
|
+
try {
|
|
361
|
+
await deleteThemeByName(name);
|
|
362
|
+
succeedSpinner(`Deleted ${name}.`);
|
|
363
|
+
} catch (error) {
|
|
364
|
+
failSpinner(`Error: ${error.message}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Delete all themes
|
|
370
|
+
*/
|
|
371
|
+
export async function deleteThemesCmd() {
|
|
372
|
+
showSpinner(`Deleting all realm themes...`);
|
|
373
|
+
try {
|
|
374
|
+
await deleteThemes();
|
|
375
|
+
succeedSpinner(`Deleted all realm themes.`);
|
|
376
|
+
} catch (error) {
|
|
377
|
+
failSpinner(`Error: ${error.message}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createKeyValueTable,
|
|
3
|
+
createProgressBar,
|
|
4
|
+
createTable,
|
|
5
|
+
failSpinner,
|
|
6
|
+
printMessage,
|
|
7
|
+
showSpinner,
|
|
8
|
+
stopProgressBar,
|
|
9
|
+
succeedSpinner,
|
|
10
|
+
updateProgressBar,
|
|
11
|
+
} from './utils/Console.js';
|
|
12
|
+
import {
|
|
13
|
+
deleteVariable,
|
|
14
|
+
getVariable,
|
|
15
|
+
getVariables,
|
|
16
|
+
putVariable,
|
|
17
|
+
setVariableDescription,
|
|
18
|
+
} from '../api/VariablesApi.js';
|
|
19
|
+
import wordwrap from './utils/Wordwrap.js';
|
|
20
|
+
import { resolveUserName } from './ManagedObjectOps.js';
|
|
21
|
+
import { decode } from '../api/utils/Base64.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* List variables
|
|
25
|
+
* @param {boolean} long Long version, all the fields
|
|
26
|
+
*/
|
|
27
|
+
export async function listVariables(long) {
|
|
28
|
+
let variables = [];
|
|
29
|
+
try {
|
|
30
|
+
variables = (await getVariables()).data.result;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
printMessage(`${error.message}`, 'error');
|
|
33
|
+
printMessage(error.response.data, 'error');
|
|
34
|
+
}
|
|
35
|
+
if (long) {
|
|
36
|
+
const table = createTable([
|
|
37
|
+
'Id'.brightCyan,
|
|
38
|
+
'Value'.brightCyan,
|
|
39
|
+
'Status'.brightCyan,
|
|
40
|
+
'Description'.brightCyan,
|
|
41
|
+
'Modifier'.brightCyan,
|
|
42
|
+
'Modified'.brightCyan,
|
|
43
|
+
]);
|
|
44
|
+
variables.sort((a, b) => a._id.localeCompare(b._id));
|
|
45
|
+
for (const variable of variables) {
|
|
46
|
+
table.push([
|
|
47
|
+
variable._id,
|
|
48
|
+
wordwrap(decode(variable.valueBase64), 40),
|
|
49
|
+
variable.loaded ? 'loaded'.brightGreen : 'unloaded'.brightRed,
|
|
50
|
+
wordwrap(variable.description, 40),
|
|
51
|
+
// eslint-disable-next-line no-await-in-loop
|
|
52
|
+
await resolveUserName('teammember', variable.lastChangedBy),
|
|
53
|
+
new Date(variable.lastChangeDate).toLocaleString(),
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
printMessage(table.toString());
|
|
57
|
+
} else {
|
|
58
|
+
variables.forEach((secret) => {
|
|
59
|
+
printMessage(secret._id);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Create variable
|
|
66
|
+
* @param {String} variableId variable id
|
|
67
|
+
* @param {String} value variable value
|
|
68
|
+
* @param {String} description variable description
|
|
69
|
+
*/
|
|
70
|
+
export async function createVariable(variableId, value, description) {
|
|
71
|
+
showSpinner(`Creating variable ${variableId}...`);
|
|
72
|
+
try {
|
|
73
|
+
await putVariable(variableId, value, description);
|
|
74
|
+
succeedSpinner(`Created variable ${variableId}`);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
failSpinner(
|
|
77
|
+
`Error: ${error.response.data.code} - ${error.response.data.message}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Update variable
|
|
84
|
+
* @param {String} variableId variable id
|
|
85
|
+
* @param {String} value variable value
|
|
86
|
+
* @param {String} description variable description
|
|
87
|
+
*/
|
|
88
|
+
export async function updateVariable(variableId, value, description) {
|
|
89
|
+
showSpinner(`Updating variable ${variableId}...`);
|
|
90
|
+
try {
|
|
91
|
+
await putVariable(variableId, value, description);
|
|
92
|
+
succeedSpinner(`Updated variable ${variableId}`);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
failSpinner(
|
|
95
|
+
`Error: ${error.response.data.code} - ${error.response.data.message}`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Set description of variable
|
|
102
|
+
* @param {String} variableId variable id
|
|
103
|
+
* @param {String} description variable description
|
|
104
|
+
*/
|
|
105
|
+
export async function setDescriptionOfVariable(variableId, description) {
|
|
106
|
+
showSpinner(`Setting description of variable ${variableId}...`);
|
|
107
|
+
try {
|
|
108
|
+
await setVariableDescription(variableId, description);
|
|
109
|
+
succeedSpinner(`Set description of variable ${variableId}`);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
failSpinner(
|
|
112
|
+
`Error: ${error.response.data.code} - ${error.response.data.message}`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Delete a variable
|
|
119
|
+
* @param {String} variableId variable id
|
|
120
|
+
*/
|
|
121
|
+
export async function deleteVariableCmd(variableId) {
|
|
122
|
+
showSpinner(`Deleting variable ${variableId}...`);
|
|
123
|
+
try {
|
|
124
|
+
await deleteVariable(variableId);
|
|
125
|
+
succeedSpinner(`Deleted variable ${variableId}`);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
failSpinner(
|
|
128
|
+
`Error: ${error.response.data.code} - ${error.response.data.message}`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Delete all variables
|
|
135
|
+
*/
|
|
136
|
+
export async function deleteVariablesCmd() {
|
|
137
|
+
try {
|
|
138
|
+
const variables = (await getVariables()).data.result;
|
|
139
|
+
createProgressBar(variables.length, `Deleting variable...`);
|
|
140
|
+
for (const variable of variables) {
|
|
141
|
+
try {
|
|
142
|
+
// eslint-disable-next-line no-await-in-loop
|
|
143
|
+
await deleteVariable(variable._id);
|
|
144
|
+
updateProgressBar(`Deleted variable ${variable._id}`);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
printMessage(
|
|
147
|
+
`Error: ${error.response.data.code} - ${error.response.data.message}`,
|
|
148
|
+
'error'
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
stopProgressBar(`Variables deleted.`);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
printMessage(
|
|
155
|
+
`Error: ${error.response.data.code} - ${error.response.data.message}`,
|
|
156
|
+
'error'
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Describe a variable
|
|
163
|
+
* @param {String} variableId variable id
|
|
164
|
+
*/
|
|
165
|
+
export async function describeVariable(variableId) {
|
|
166
|
+
const variable = (await getVariable(variableId)).data;
|
|
167
|
+
const table = createKeyValueTable();
|
|
168
|
+
table.push(['Name'.brightCyan, variable._id]);
|
|
169
|
+
table.push(['Value'.brightCyan, wordwrap(decode(variable.valueBase64), 40)]);
|
|
170
|
+
table.push([
|
|
171
|
+
'Status'.brightCyan,
|
|
172
|
+
variable.loaded ? 'loaded'.brightGreen : 'unloaded'.brightRed,
|
|
173
|
+
]);
|
|
174
|
+
table.push(['Description'.brightCyan, wordwrap(variable.description, 60)]);
|
|
175
|
+
table.push([
|
|
176
|
+
'Modified'.brightCyan,
|
|
177
|
+
new Date(variable.lastChangeDate).toLocaleString(),
|
|
178
|
+
]);
|
|
179
|
+
table.push([
|
|
180
|
+
'Modifier'.brightCyan,
|
|
181
|
+
await resolveUserName('teammember', variable.lastChangedBy),
|
|
182
|
+
]);
|
|
183
|
+
table.push(['Modifier UUID'.brightCyan, variable.lastChangedBy]);
|
|
184
|
+
printMessage(table.toString());
|
|
185
|
+
}
|