@magda/scripts 4.2.1 → 4.2.2

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.
@@ -1,833 +0,0 @@
1
- import inquirer from "inquirer";
2
- import trim from "lodash/trim.js";
3
- import fs from "fs";
4
- import path from "path";
5
- import moment from "moment";
6
- import chalk from "chalk";
7
- import pwgen from "./pwgen.js";
8
- import partial from "lodash/partial.js";
9
- import stripJsonComments from "strip-json-comments";
10
-
11
- const questions = [
12
- {
13
- type: "list",
14
- dataType: "boolean",
15
- name: "deploy-to-google-cloud",
16
- message:
17
- "Are you creating k8s secrets for google cloud or local testing cluster?",
18
- choices: [
19
- {
20
- name: "Google Cloud Kubernetes Cluster",
21
- value: true
22
- },
23
- {
24
- name: "Local Testing Kubernetes Cluster",
25
- value: false
26
- }
27
- ]
28
- },
29
- {
30
- type: "list",
31
- name: "local-cluster-type",
32
- message:
33
- "Which local k8s cluster environment you are going to connect to?",
34
- choices: ["minikube", "docker", "microk8s"],
35
- when: onlyWhenQuestion("deploy-to-google-cloud", false)
36
- },
37
- {
38
- type: "list",
39
- dataType: "boolean",
40
- name: "use-cloudsql-instance-credentials",
41
- message: "Do you use google cloud SQL service as your database?",
42
- choices: [
43
- {
44
- name: "YES",
45
- value: true
46
- },
47
- {
48
- name: "NO",
49
- value: false
50
- }
51
- ],
52
- when: onlyAvailableForGoogleCloud
53
- },
54
- {
55
- type: "input",
56
- name: "cloudsql-db-credentials",
57
- message: "Please provide default google cloud SQL service DB password:",
58
- when: onlyWhenQuestion("use-cloudsql-instance-credentials", true),
59
- validate: (input) =>
60
- trim(input).length ? true : "Default password cannot be empty!"
61
- },
62
- {
63
- type: "list",
64
- dataType: "boolean",
65
- name: "reselect-cloudsql-instance-credentials",
66
- message:
67
- "Has located saved Google SQL cloud credentials JSON file. Do you want to re-select?",
68
- choices: [
69
- {
70
- name: "NO",
71
- value: false
72
- },
73
- {
74
- name: "YES",
75
- value: true
76
- }
77
- ],
78
- //--- config parameter needs to be prefilled later before run questionnaire
79
- //--- answers will be provided by inquirer lib at runtime
80
- when: function (config, answers) {
81
- if (
82
- answers["deploy-to-google-cloud"] === false ||
83
- answers["use-cloudsql-instance-credentials"] === false
84
- ) {
85
- return false;
86
- }
87
- if (
88
- config["cloudsql-instance-credentials"] &&
89
- config["cloudsql-instance-credentials"]["value"] &&
90
- config["cloudsql-instance-credentials"]["data"]
91
- ) {
92
- return true;
93
- }
94
- return false;
95
- }
96
- },
97
- {
98
- type: "fuzzypath",
99
- dataType: "jsonfile",
100
- name: "cloudsql-instance-credentials",
101
- pathFilter: pathFilterByExt("json"),
102
- suggestOnly: false,
103
- rootPath: path.resolve(),
104
- message:
105
- "Please provide the path to the credentials JSON file for your Google SQL cloud service access:",
106
- //--- config parameter needs to be prefilled later before run questionnaire
107
- //--- answers will be provided by inquirer lib at runtime
108
- when: function (config, answers) {
109
- if (
110
- answers["deploy-to-google-cloud"] === false ||
111
- answers["use-cloudsql-instance-credentials"] === false
112
- ) {
113
- return false;
114
- }
115
- if (
116
- !config["cloudsql-instance-credentials"] ||
117
- !config["cloudsql-instance-credentials"]["value"] ||
118
- !config["cloudsql-instance-credentials"]["data"]
119
- ) {
120
- return true;
121
- }
122
- if (answers["reselect-cloudsql-instance-credentials"] === false) {
123
- return false;
124
- }
125
- return true;
126
- },
127
- validate: validJsonFileExist,
128
- filter: getJsonFileContent
129
- },
130
- {
131
- type: "list",
132
- dataType: "boolean",
133
- name: "use-storage-account-credentials",
134
- message: "Do you use google storage service?",
135
- choices: [
136
- {
137
- name: "YES",
138
- value: true
139
- },
140
- {
141
- name: "NO",
142
- value: false
143
- }
144
- ],
145
- when: onlyAvailableForGoogleCloud
146
- },
147
- {
148
- type: "list",
149
- dataType: "boolean",
150
- name: "reselect-storage-account-credentials",
151
- message:
152
- "Has located saved Google storage private key JSON file. Do you want to re-select?",
153
- choices: [
154
- {
155
- name: "NO",
156
- value: false
157
- },
158
- {
159
- name: "YES",
160
- value: true
161
- }
162
- ],
163
- //--- config needs to prefill later before run questionnaire
164
- //--- answers will be provided by inquirer lib at runtime
165
- when: function (config, answers) {
166
- if (
167
- answers["deploy-to-google-cloud"] === false ||
168
- answers["use-storage-account-credentials"] === false
169
- ) {
170
- return false;
171
- }
172
- if (
173
- config["storage-account-credentials"] &&
174
- config["storage-account-credentials"]["value"] &&
175
- config["storage-account-credentials"]["data"]
176
- ) {
177
- return true;
178
- }
179
- return false;
180
- }
181
- },
182
- {
183
- type: "fuzzypath",
184
- dataType: "jsonfile",
185
- name: "storage-account-credentials",
186
- pathFilter: pathFilterByExt("json"),
187
- suggestOnly: false,
188
- rootPath: path.resolve(),
189
- message:
190
- "Please provide the path to the private key JSON file for your Google storage service access:",
191
- //--- config needs to prefill later before run questionnaire
192
- //--- answers will be provided by inquirer lib at runtime
193
- when: function (config, answers) {
194
- if (
195
- answers["deploy-to-google-cloud"] === false ||
196
- answers["use-storage-account-credentials"] === false
197
- ) {
198
- return false;
199
- }
200
- if (
201
- !config["storage-account-credentials"] ||
202
- !config["storage-account-credentials"]["value"] ||
203
- !config["storage-account-credentials"]["data"]
204
- ) {
205
- return true;
206
- }
207
- if (answers["reselect-storage-account-credentials"] === false) {
208
- return false;
209
- }
210
- return true;
211
- },
212
- validate: validJsonFileExist,
213
- filter: getJsonFileContent
214
- },
215
- {
216
- type: "list",
217
- dataType: "boolean",
218
- name: "use-smtp-secret",
219
- message:
220
- "Do you need to access SMTP service for sending data request email?",
221
- choices: [
222
- {
223
- name: "YES",
224
- value: true
225
- },
226
- {
227
- name: "NO",
228
- value: false
229
- }
230
- ]
231
- },
232
- {
233
- type: "input",
234
- name: "smtp-secret-username",
235
- message: "Please provide SMTP service username:",
236
- when: onlyWhenQuestion("use-smtp-secret", true),
237
- validate: (input) =>
238
- trim(input).length ? true : "username cannot be empty!"
239
- },
240
- {
241
- type: "input",
242
- name: "smtp-secret-password",
243
- message: "Please provide SMTP service password:",
244
- when: onlyWhenQuestion("use-smtp-secret", true),
245
- validate: (input) =>
246
- trim(input).length ? true : "password cannot be empty!"
247
- },
248
- {
249
- type: "list",
250
- dataType: "boolean",
251
- name: "use-regcred",
252
- message:
253
- "Do you use Gitlab as your CI system and need the access to Gitlab docker registry?",
254
- choices: [
255
- {
256
- name: "YES",
257
- value: true
258
- },
259
- {
260
- name: "NO",
261
- value: false
262
- }
263
- ],
264
- when: onlyAvailableForGoogleCloud
265
- },
266
- {
267
- type: "list",
268
- dataType: "boolean",
269
- name: "use-regcred-password-from-env",
270
- message:
271
- "Do you want to get gitlab docker registry password from environment variable ($CI_JOB_TOKEN) or input manually now?",
272
- choices: [
273
- {
274
- name: "YES (Get from $CI_JOB_TOKEN)",
275
- value: true
276
- },
277
- {
278
- name: "NO (input manually)",
279
- value: false
280
- }
281
- ],
282
- when: onlyWhenQuestion("use-regcred", true)
283
- },
284
- {
285
- type: "input",
286
- name: "regcred-email",
287
- message:
288
- "Please provide the email address that you want to use for Gitlab docker registry:",
289
- when: onlyWhenQuestion("use-regcred", true),
290
- validate: (input) =>
291
- trim(input).length ? true : "email cannot be empty!"
292
- },
293
- {
294
- type: "input",
295
- name: "regcred-password",
296
- message: "Please provide password for Gitlab docker registry:",
297
- when: onlyWhenQuestion("use-regcred-password-from-env", false),
298
- validate: (input) =>
299
- trim(input).length ? true : "password cannot be empty!"
300
- },
301
- {
302
- type: "list",
303
- dataType: "boolean",
304
- name: "use-oauth-secrets-google",
305
- message: "Do you want to create google-client-secret for oAuth SSO?",
306
- choices: [
307
- {
308
- name: "YES",
309
- value: true
310
- },
311
- {
312
- name: "NO",
313
- value: false
314
- }
315
- ]
316
- },
317
- {
318
- type: "input",
319
- name: "oauth-secrets-google",
320
- message: "Please provide google api access key for oAuth SSO:",
321
- when: onlyWhenQuestion("use-oauth-secrets-google", true),
322
- validate: (input) =>
323
- trim(input).length ? true : "secret cannot be empty!"
324
- },
325
- {
326
- type: "list",
327
- dataType: "boolean",
328
- name: "use-oauth-secrets-facebook",
329
- message: "Do you want to create facebook-client-secret for oAuth SSO?",
330
- choices: [
331
- {
332
- name: "YES",
333
- value: true
334
- },
335
- {
336
- name: "NO",
337
- value: false
338
- }
339
- ]
340
- },
341
- {
342
- type: "input",
343
- name: "oauth-secrets-facebook",
344
- message: "Please provide facebook api access key for oAuth SSO:",
345
- when: onlyWhenQuestion("use-oauth-secrets-facebook", true),
346
- validate: (input) =>
347
- trim(input).length ? true : "secret cannot be empty!"
348
- },
349
- {
350
- type: "list",
351
- dataType: "boolean",
352
- name: "use-oauth-secrets-arcgis",
353
- message: "Do you want to create arcgis-client-secret for oAuth SSO?",
354
- choices: [
355
- {
356
- name: "YES",
357
- value: true
358
- },
359
- {
360
- name: "NO",
361
- value: false
362
- }
363
- ]
364
- },
365
- {
366
- type: "input",
367
- name: "oauth-secrets-arcgis",
368
- message: "Please provide arcgis api access key for oAuth SSO:",
369
- when: onlyWhenQuestion("use-oauth-secrets-arcgis", true),
370
- validate: (input) =>
371
- trim(input).length ? true : "secret cannot be empty!"
372
- },
373
- {
374
- type: "list",
375
- dataType: "boolean",
376
- name: "use-oauth-secrets-aaf",
377
- message:
378
- "Do you want to create aaf-client-secret for AAF Rapid Connect SSO?",
379
- choices: [
380
- {
381
- name: "YES",
382
- value: true
383
- },
384
- {
385
- name: "NO",
386
- value: false
387
- }
388
- ]
389
- },
390
- {
391
- type: "input",
392
- name: "oauth-secrets-aaf",
393
- message: "Please provide AAF secret for AAF Rapid Connect SSO:",
394
- when: onlyWhenQuestion("use-oauth-secrets-aaf", true),
395
- validate: (input) =>
396
- trim(input).length ? true : "secret cannot be empty!"
397
- },
398
- {
399
- type: "list",
400
- dataType: "boolean",
401
- name: "use-web-access-secret",
402
- message: "Do you want to setup HTTP Basic authentication?",
403
- choices: [
404
- {
405
- name: "YES",
406
- value: true
407
- },
408
- {
409
- name: "NO",
410
- value: false
411
- }
412
- ]
413
- },
414
- {
415
- type: "input",
416
- name: "web-access-username",
417
- message:
418
- "Please provide the username for HTTP Basic authentication setup:",
419
- when: (answers) => answers["use-web-access-secret"] === true,
420
- validate: (input) => {
421
- const r = trim(input);
422
- if (!r.length) {
423
- return "username cannot be empty!";
424
- }
425
- if (r.indexOf(":") !== -1) {
426
- return "username cannot contains `:`!";
427
- }
428
- return true;
429
- }
430
- },
431
- {
432
- type: "transformer-list",
433
- dataType: "boolean",
434
- name: "manual-web-access-password",
435
- message:
436
- "Do you want to manually input the password for HTTP Basic authentication setup?",
437
- choices: [
438
- {
439
- name: "NO (A random password will be generated for you now)",
440
- value: false
441
- },
442
- {
443
- name: "YES",
444
- value: true
445
- }
446
- ],
447
- when: (answers) => answers["use-web-access-secret"] === true,
448
- filter: function (input) {
449
- const r = {
450
- answer: input
451
- };
452
- if (input === false) {
453
- r["password"] = pwgen();
454
- }
455
- return r;
456
- },
457
- transformer: function (value, answers) {
458
- if (value.answer === true) {
459
- return chalk.yellow("Chose to manually input password");
460
- } else {
461
- return chalk.yellow(
462
- "Generated password: " +
463
- chalk.green.underline(value["password"])
464
- );
465
- }
466
- }
467
- },
468
- {
469
- type: "input",
470
- name: "web-access-password",
471
- message:
472
- "Please provide the password for HTTP Basic authentication setup:",
473
- when: (answers) =>
474
- answers["use-web-access-secret"] === true &&
475
- answers["manual-web-access-password"]["answer"] === true,
476
- validate: (input) =>
477
- trim(input).length ? true : "password cannot be empty!"
478
- },
479
- {
480
- type: "transformer-list",
481
- dataType: "boolean",
482
- name: "manual-db-passwords",
483
- message:
484
- "Do you want to manually input the password used for databases?",
485
- choices: [
486
- {
487
- name: "NO (A random password will be generated for you now)",
488
- value: false
489
- },
490
- {
491
- name: "YES",
492
- value: true
493
- }
494
- ],
495
- filter: function (input) {
496
- const r = {
497
- answer: input
498
- };
499
- if (input === false) {
500
- r["password"] = pwgen();
501
- }
502
- return r;
503
- },
504
- transformer: function (value, answers) {
505
- if (value.answer === true) {
506
- return chalk.yellow("Chose to manually input password");
507
- } else {
508
- return chalk.yellow(
509
- "Generated password: " +
510
- chalk.green.underline(value["password"])
511
- );
512
- }
513
- }
514
- },
515
- {
516
- type: "input",
517
- name: "db-passwords",
518
- message: "Please provide the password used for databases:",
519
- when: (answers) => answers["manual-db-passwords"]["answer"] === true,
520
- validate: (input) =>
521
- trim(input).length ? true : "password cannot be empty!"
522
- },
523
- {
524
- type: "input",
525
- name: "accesskey",
526
- message: "Please enter an access key for your MinIO server:",
527
- validate: (input) => {
528
- const trimmedInput = trim(input);
529
- return trimmedInput.length && trimmedInput.length >= 5
530
- ? true
531
- : "MinIO access keys need to be at least 5 characters.";
532
- }
533
- },
534
- {
535
- type: "input",
536
- name: "secretkey",
537
- message: "Please enter a secret key for your MinIO server::",
538
- validate: (input) => {
539
- const trimmedInput = trim(input);
540
- return trimmedInput.length && trimmedInput.length >= 8
541
- ? true
542
- : "MinIO secret keys need to be at least 8 characters.";
543
- }
544
- },
545
- {
546
- type: "list",
547
- dataType: "boolean",
548
- name: "get-namespace-from-env",
549
- message:
550
- "Specify a namespace or leave blank and override by env variable later?",
551
- choices: [
552
- {
553
- name: "YES (Specify a namespace)",
554
- value: false
555
- },
556
- {
557
- name: "NO (leave blank and override by env variable later)",
558
- value: true
559
- }
560
- ]
561
- },
562
- {
563
- type: "input",
564
- name: "cluster-namespace",
565
- message:
566
- "What's the namespace you want to create secrets into (input `default` if you want to use the `default` namespace)?",
567
- when: onlyWhenQuestion("get-namespace-from-env", false),
568
- validate: (input) =>
569
- trim(input).length ? true : "Cluster namespace cannot be empty!"
570
- },
571
- {
572
- type: "list",
573
- dataType: "boolean",
574
- name: "allow-env-override-settings",
575
- message:
576
- "Do you want to allow environment variables (see --help for full list) to override current settings at runtime?",
577
- choices: [
578
- {
579
- name: "YES (Any environment variable can overide my settings)",
580
- value: true
581
- },
582
- {
583
- name: "NO (No settings will be override)",
584
- value: false
585
- }
586
- ]
587
- }
588
- ];
589
-
590
- function onlyAvailableForGoogleCloud(answers) {
591
- return answers["deploy-to-google-cloud"];
592
- }
593
-
594
- function onlyWhenQuestion(name, value) {
595
- return (answers) => {
596
- return answers[name] === value;
597
- };
598
- }
599
-
600
- function validJsonFileExist(choice) {
601
- try {
602
- const filePath = trim(choice.value);
603
- if (!fs.existsSync(filePath)) {
604
- return "The file doe not exist or cannot read. Please re-select.";
605
- }
606
- const content = fs.readFileSync(filePath, {
607
- encoding: "utf-8"
608
- });
609
- try {
610
- const data = JSON.parse(stripJsonComments(content));
611
- return true;
612
- } catch (e) {
613
- return `The file content is not in valid JSON format: ${e}`;
614
- }
615
- } catch (e) {
616
- return String(e);
617
- }
618
- }
619
-
620
- function pathFilterByExt(ext) {
621
- return (isDirectory, nodePath) => {
622
- if (isDirectory) return false;
623
- const idx = nodePath.lastIndexOf(".");
624
- let fileExt;
625
- if (idx === -1 || idx === nodePath.length - 1) {
626
- fileExt = "";
627
- } else {
628
- fileExt = nodePath.substring(idx + 1).toLowerCase();
629
- }
630
- return fileExt === ext.toLowerCase();
631
- };
632
- }
633
-
634
- function getJsonFileContent(filePath) {
635
- try {
636
- filePath = trim(filePath);
637
- const content = fs.readFileSync(filePath, {
638
- encoding: "utf-8"
639
- });
640
- return {
641
- value: filePath,
642
- data: JSON.parse(stripJsonComments(content))
643
- };
644
- } catch (e) {
645
- console.log(chalk.red(`Failed to process data: ${e}`));
646
- process.exit(1);
647
- }
648
- }
649
-
650
- function prefillQuestions(questions, config) {
651
- const questionNamesRequireBindWhen = [
652
- "reselect-cloudsql-instance-credentials",
653
- "cloudsql-instance-credentials",
654
- "reselect-storage-account-credentials",
655
- "storage-account-credentials"
656
- ];
657
- return questions
658
- .map((question) => {
659
- let configValue = config.get(question.name);
660
- const type = typeof configValue;
661
- if (type === "undefined") return question;
662
- if (type === "object") {
663
- if (typeof configValue.value === "undefined") return question;
664
- else configValue = configValue.value;
665
- }
666
-
667
- return Object.assign({}, question, {
668
- default: configValue
669
- });
670
- })
671
- .map((question) => {
672
- if (questionNamesRequireBindWhen.indexOf(question["name"]) === -1) {
673
- return question;
674
- }
675
- return Object.assign({}, question, {
676
- when: partial(question.when, config.all)
677
- });
678
- });
679
- }
680
-
681
- const inquirerFuzzyPath = require("./prompts/inquirer-fuzzy-path");
682
- const inquirerListWithTransformer = require("./prompts/list-with-transformer");
683
- inquirer.registerPrompt("fuzzypath", inquirerFuzzyPath);
684
- inquirer.registerPrompt("transformer-list", inquirerListWithTransformer);
685
- function askSettingQuestions(config) {
686
- return inquirer
687
- .prompt(prefillQuestions(questions, config))
688
- .then(function (answers) {
689
- const configData = config.all;
690
- //--- if user didn't re-select credentials files,
691
- //--- we needs to save to answers before clear the config
692
- if (
693
- answers["use-cloudsql-instance-credentials"] === true &&
694
- configData["cloudsql-instance-credentials"] &&
695
- configData["cloudsql-instance-credentials"]["value"] &&
696
- configData["cloudsql-instance-credentials"]["data"] &&
697
- answers["reselect-cloudsql-instance-credentials"] === false
698
- ) {
699
- answers["cloudsql-instance-credentials"] = {};
700
- answers["cloudsql-instance-credentials"]["value"] =
701
- configData["cloudsql-instance-credentials"]["value"];
702
- answers["cloudsql-instance-credentials"]["data"] =
703
- configData["cloudsql-instance-credentials"]["data"];
704
- }
705
- if (
706
- answers["use-storage-account-credentials"] === true &&
707
- configData["storage-account-credentials"] &&
708
- configData["storage-account-credentials"]["value"] &&
709
- configData["storage-account-credentials"]["data"] &&
710
- answers["reselect-storage-account-credentials"] === false
711
- ) {
712
- answers["storage-account-credentials"] = {};
713
- answers["storage-account-credentials"]["value"] =
714
- configData["storage-account-credentials"]["value"];
715
- answers["storage-account-credentials"]["data"] =
716
- configData["storage-account-credentials"]["data"];
717
- }
718
- config.clear();
719
- config.set(answers);
720
- config.set("creation-time", new Date().toISOString());
721
- });
722
- }
723
- function askClosingQuestions(config) {
724
- return inquirer
725
- .prompt([
726
- {
727
- type: "list",
728
- name: "deploy-now",
729
- message:
730
- "Do you want to connect to kubernetes cluster to create secrets now?",
731
- choices: [
732
- {
733
- name: "YES (Create Secrets in Cluster now)",
734
- value: true
735
- },
736
- {
737
- name: "NO (Exit but all settings have been saved)",
738
- value: false
739
- }
740
- ]
741
- }
742
- ])
743
- .then((answers) => answers["deploy-now"]);
744
- }
745
- function askStartSecretsCreationWithoutQuestions(config) {
746
- const creationTime = new Date(config.get("creation-time"));
747
- console.log(
748
- chalk.yellow(
749
- `Found previous saved config (${moment(creationTime).format(
750
- "MMMM Do YYYY, h:mm:ss a"
751
- )}).`
752
- )
753
- );
754
- return inquirer
755
- .prompt([
756
- {
757
- type: "list",
758
- name: "deploy-now",
759
- message:
760
- "Do you want to connect to kubernetes cluster to create secrets without going through any questions?",
761
- choices: [
762
- {
763
- name: "NO (Going through all questions)",
764
- value: false
765
- },
766
- {
767
- name:
768
- "YES (Create Secrets in Cluster using existing config now)",
769
- value: true
770
- }
771
- ]
772
- }
773
- ])
774
- .then((answers) => answers["deploy-now"]);
775
- }
776
-
777
- export function askIfCreateNamespace(namespace) {
778
- return inquirer
779
- .prompt([
780
- {
781
- type: "list",
782
- name: "if-create-namespace",
783
- message: `Do you want to create namespace \`${namespace}\` now?`,
784
- choices: [
785
- {
786
- name: "YES",
787
- value: true
788
- },
789
- {
790
- name: "NO",
791
- value: false
792
- }
793
- ]
794
- }
795
- ])
796
- .then((answers) => answers["if-create-namespace"]);
797
- }
798
-
799
- export function askQuestions(config) {
800
- return new Promise(function (resolve, reject) {
801
- const creationTime = config.get("creation-time");
802
- let p;
803
- if (typeof creationTime !== "undefined") {
804
- p = askStartSecretsCreationWithoutQuestions(config);
805
- } else {
806
- p = Promise.resolve(false);
807
- }
808
- p.then((ifGoCreatioin) => {
809
- if (ifGoCreatioin) {
810
- return true;
811
- } else {
812
- return askSettingQuestions(config).then(
813
- askClosingQuestions.bind(null, config)
814
- );
815
- }
816
- }).then((answer) => resolve(answer));
817
- });
818
- }
819
-
820
- export function getEnvVarInfo() {
821
- return questions.map((item) => ({
822
- name: settingNameToEnvVarName(item.name),
823
- dataType: item.dataType ? item.dataType : "string",
824
- settingName: item.name,
825
- description: item.message
826
- }));
827
- }
828
-
829
- export function settingNameToEnvVarName(settingName) {
830
- return settingName.replace(/\-/g, "_").toUpperCase();
831
- }
832
-
833
- export default askQuestions;