contensis-cli 1.0.0-beta.10 → 1.0.0-beta.100

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.
Files changed (125) hide show
  1. package/README.md +1146 -78
  2. package/cli.js +3 -0
  3. package/dist/commands/connect.js +3 -3
  4. package/dist/commands/connect.js.map +2 -2
  5. package/dist/commands/create.js +45 -10
  6. package/dist/commands/create.js.map +2 -2
  7. package/dist/commands/dev.js +71 -0
  8. package/dist/commands/dev.js.map +7 -0
  9. package/dist/commands/diff.js +57 -0
  10. package/dist/commands/diff.js.map +7 -0
  11. package/dist/commands/execute.js +103 -0
  12. package/dist/commands/execute.js.map +7 -0
  13. package/dist/commands/get.js +169 -32
  14. package/dist/commands/get.js.map +3 -3
  15. package/dist/commands/globalOptions.js +37 -12
  16. package/dist/commands/globalOptions.js.map +2 -2
  17. package/dist/commands/import.js +65 -12
  18. package/dist/commands/import.js.map +2 -2
  19. package/dist/commands/index.js +22 -2
  20. package/dist/commands/index.js.map +2 -2
  21. package/dist/commands/list.js +53 -10
  22. package/dist/commands/list.js.map +2 -2
  23. package/dist/commands/login.js +2 -2
  24. package/dist/commands/login.js.map +2 -2
  25. package/dist/commands/push.js +17 -13
  26. package/dist/commands/push.js.map +2 -2
  27. package/dist/commands/remove.js +51 -8
  28. package/dist/commands/remove.js.map +2 -2
  29. package/dist/commands/set.js +139 -12
  30. package/dist/commands/set.js.map +2 -2
  31. package/dist/index.js +1 -1
  32. package/dist/index.js.map +2 -2
  33. package/dist/localisation/en-GB.js +297 -49
  34. package/dist/localisation/en-GB.js.map +2 -2
  35. package/dist/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml.js +56 -0
  36. package/dist/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml.js.map +7 -0
  37. package/dist/mappers/DevInit-to-CIWorkflow.js +374 -0
  38. package/dist/mappers/DevInit-to-CIWorkflow.js.map +7 -0
  39. package/dist/mappers/DevInit-to-RolePermissions.js +56 -0
  40. package/dist/mappers/DevInit-to-RolePermissions.js.map +7 -0
  41. package/dist/mappers/DevRequests-to-RequestHanderSiteConfigYaml.js +56 -0
  42. package/dist/mappers/DevRequests-to-RequestHanderSiteConfigYaml.js.map +7 -0
  43. package/dist/models/CliService.d.js +17 -0
  44. package/dist/models/CliService.d.js.map +7 -0
  45. package/dist/models/DevService.d.js +17 -0
  46. package/dist/models/DevService.d.js.map +7 -0
  47. package/dist/providers/CredentialProvider.js +46 -14
  48. package/dist/providers/CredentialProvider.js.map +3 -3
  49. package/dist/providers/SessionCacheProvider.js +21 -1
  50. package/dist/providers/SessionCacheProvider.js.map +2 -2
  51. package/dist/providers/file-provider.js +12 -6
  52. package/dist/providers/file-provider.js.map +3 -3
  53. package/dist/services/ContensisCliService.js +1211 -420
  54. package/dist/services/ContensisCliService.js.map +3 -3
  55. package/dist/services/ContensisDevService.js +368 -0
  56. package/dist/services/ContensisDevService.js.map +7 -0
  57. package/dist/services/ContensisRoleService.js +114 -0
  58. package/dist/services/ContensisRoleService.js.map +7 -0
  59. package/dist/shell.js +58 -18
  60. package/dist/shell.js.map +3 -3
  61. package/dist/util/console.printer.js +171 -55
  62. package/dist/util/console.printer.js.map +2 -2
  63. package/dist/util/diff.js +116 -0
  64. package/dist/util/diff.js.map +7 -0
  65. package/dist/util/dotenv.js +57 -0
  66. package/dist/util/dotenv.js.map +7 -0
  67. package/dist/util/find.js +31 -0
  68. package/dist/util/find.js.map +7 -0
  69. package/dist/util/git.js +128 -0
  70. package/dist/util/git.js.map +7 -0
  71. package/dist/util/index.js +8 -2
  72. package/dist/util/index.js.map +3 -3
  73. package/dist/util/logger.js +90 -29
  74. package/dist/util/logger.js.map +3 -3
  75. package/dist/util/os.js +42 -0
  76. package/dist/util/os.js.map +7 -0
  77. package/dist/util/timers.js +49 -0
  78. package/dist/util/timers.js.map +7 -0
  79. package/dist/util/yaml.js +45 -0
  80. package/dist/util/yaml.js.map +7 -0
  81. package/dist/version.js +1 -1
  82. package/dist/version.js.map +1 -1
  83. package/esbuild.config.js +3 -1
  84. package/package.json +14 -3
  85. package/src/commands/connect.ts +3 -2
  86. package/src/commands/create.ts +61 -8
  87. package/src/commands/dev.ts +69 -0
  88. package/src/commands/diff.ts +41 -0
  89. package/src/commands/execute.ts +117 -0
  90. package/src/commands/get.ts +242 -28
  91. package/src/commands/globalOptions.ts +42 -12
  92. package/src/commands/import.ts +83 -8
  93. package/src/commands/index.ts +22 -1
  94. package/src/commands/list.ts +85 -11
  95. package/src/commands/login.ts +2 -1
  96. package/src/commands/push.ts +18 -11
  97. package/src/commands/remove.ts +66 -4
  98. package/src/commands/set.ts +189 -9
  99. package/src/index.ts +1 -4
  100. package/src/localisation/en-GB.ts +428 -66
  101. package/src/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml.ts +44 -0
  102. package/src/mappers/DevInit-to-CIWorkflow.ts +526 -0
  103. package/src/mappers/DevInit-to-RolePermissions.ts +32 -0
  104. package/src/mappers/DevRequests-to-RequestHanderSiteConfigYaml.ts +44 -0
  105. package/src/models/CliService.d.ts +36 -0
  106. package/src/models/DevService.d.ts +40 -0
  107. package/src/models/JsModules.d.ts +2 -0
  108. package/src/providers/CredentialProvider.ts +51 -18
  109. package/src/providers/SessionCacheProvider.ts +29 -2
  110. package/src/providers/file-provider.ts +17 -6
  111. package/src/services/ContensisCliService.ts +1532 -508
  112. package/src/services/ContensisDevService.ts +434 -0
  113. package/src/services/ContensisRoleService.ts +108 -0
  114. package/src/shell.ts +68 -18
  115. package/src/util/console.printer.ts +240 -78
  116. package/src/util/diff.ts +124 -0
  117. package/src/util/dotenv.ts +37 -0
  118. package/src/util/find.ts +8 -0
  119. package/src/util/git.ts +131 -0
  120. package/src/util/index.ts +16 -7
  121. package/src/util/logger.ts +145 -31
  122. package/src/util/os.ts +12 -0
  123. package/src/util/timers.ts +24 -0
  124. package/src/util/yaml.ts +13 -0
  125. package/src/version.ts +1 -1
@@ -0,0 +1,434 @@
1
+ import to from 'await-to-js';
2
+ import { spawn } from 'child_process';
3
+ import inquirer from 'inquirer';
4
+ import path from 'path';
5
+
6
+ import { Role } from 'contensis-management-api/lib/models';
7
+ import { MigrateRequest } from 'migratortron';
8
+
9
+ import ContensisRole from './ContensisRoleService';
10
+ import { OutputOptionsConstructorArg } from '~/models/CliService';
11
+ import { EnvContentsToAdd } from '~/models/DevService';
12
+ import { mapSiteConfigYaml } from '~/mappers/DevRequests-to-RequestHanderSiteConfigYaml';
13
+ import { mapCIWorkflowContent } from '~/mappers/DevInit-to-CIWorkflow';
14
+ import {
15
+ deployKeyRole,
16
+ devKeyRole,
17
+ } from '~/mappers/DevInit-to-RolePermissions';
18
+ import { appRootDir, readFile, writeFile } from '~/providers/file-provider';
19
+ import { diffFileContent } from '~/util/diff';
20
+ import { mergeDotEnvFileContents } from '~/util/dotenv';
21
+ import { findByIdOrName } from '~/util/find';
22
+ import { GitHelper } from '~/util/git';
23
+ import { jsonFormatter } from '~/util/json.formatter';
24
+ import { winSlash } from '~/util/os';
25
+ import { stringifyYaml } from '~/util/yaml';
26
+ import { createSpinner } from 'nanospinner';
27
+
28
+ class ContensisDev extends ContensisRole {
29
+ git!: GitHelper;
30
+
31
+ constructor(
32
+ args: string[],
33
+ outputOpts?: OutputOptionsConstructorArg,
34
+ contensisOpts: Partial<MigrateRequest> = {}
35
+ ) {
36
+ super(args, outputOpts, contensisOpts);
37
+ }
38
+
39
+ DevelopmentInit = async (projectHome: string, opts: any) => {
40
+ const { dryRun = false } = opts || {};
41
+ const { currentEnv, currentProject, log, messages } = this;
42
+ const contensis = await this.ConnectContensis();
43
+
44
+ if (contensis) {
45
+ // Retrieve keys list for env
46
+ const [keysErr, apiKeys] = await contensis.apiKeys.GetKeys();
47
+ if (keysErr) {
48
+ log.error(messages.keys.noList(currentEnv));
49
+ log.error(jsonFormatter(keysErr));
50
+ return;
51
+ }
52
+ const apiKeyExists = (findKey: string) =>
53
+ apiKeys?.find(
54
+ k => k.name.trim().toLowerCase() === findKey?.trim().toLowerCase()
55
+ );
56
+
57
+ // Retrieve git info
58
+ const git = (this.git = new GitHelper(projectHome));
59
+
60
+ // Retrieve ci workflow info
61
+ const workflowFiles = git.workflows;
62
+
63
+ // Set variables for performing operations and logging etc.
64
+ let ciFileName = git.ciFileName;
65
+
66
+ const devKeyName = `${git.name} development`;
67
+ const devKeyDescription = `${git.name} [contensis-cli]`;
68
+ let existingDevKey = apiKeyExists(devKeyName);
69
+
70
+ const deployKeyName = `${git.name} deployment`;
71
+ const deployKeyDescription = `${git.name} deploy [contensis-cli]`;
72
+
73
+ let existingDeployKey = apiKeyExists(deployKeyName);
74
+
75
+ const blockId = git.name;
76
+ const errors = [] as AppError[];
77
+
78
+ // Start render console output
79
+ log.raw('');
80
+ log.success(messages.devinit.intro());
81
+ log.raw('');
82
+ log.raw(
83
+ log.infoText(
84
+ messages.devinit.projectDetails(
85
+ git.name,
86
+ currentEnv,
87
+ currentProject,
88
+ git
89
+ )
90
+ )
91
+ );
92
+ log.raw(
93
+ log.infoText(
94
+ messages.devinit.developmentKey(devKeyName, !!existingDevKey)
95
+ )
96
+ );
97
+ log.raw(
98
+ log.infoText(
99
+ messages.devinit.deploymentKey(deployKeyName, !!existingDeployKey)
100
+ )
101
+ );
102
+ log.raw('');
103
+
104
+ if (Array.isArray(workflowFiles) && workflowFiles.length > 1) {
105
+ // Choose GitHub workflow file (if multiple)
106
+ ({ ciFileName } = await inquirer.prompt([
107
+ {
108
+ type: 'list',
109
+ prefix: '⧰',
110
+ message: messages.devinit.ciMultipleChoices(),
111
+ name: 'ciFileName',
112
+ choices: workflowFiles,
113
+ default: workflowFiles.find(f => f.includes('docker')),
114
+ },
115
+ ]));
116
+ log.raw('');
117
+ git.ciFileName = ciFileName;
118
+ }
119
+
120
+ log.raw(log.infoText(messages.devinit.ciDetails(ciFileName)));
121
+
122
+ let mappedWorkflow;
123
+ // Location for Client ID / Secret.
124
+ const { clientDetailsOption } = await inquirer.prompt({
125
+ name: 'clientDetailsOption',
126
+ type: 'list',
127
+ prefix: '🔑',
128
+ // Where would you like to store your Client ID/Secret?
129
+ message: messages.devinit.clientDetailsLocation(),
130
+ choices: [
131
+ messages.devinit.clientDetailsInGit(git),
132
+ messages.devinit.clientDetailsInEnv(),
133
+ ],
134
+ });
135
+
136
+ // global 'clientDetailsLocation' variable stores users input on where client id / secert are stored
137
+ if (clientDetailsOption === messages.devinit.clientDetailsInEnv()) {
138
+ this.clientDetailsLocation = 'env';
139
+ } else {
140
+ this.clientDetailsLocation = 'git';
141
+ }
142
+
143
+ if (this.clientDetailsLocation === 'env') {
144
+ // Update CI Workflow to pull from ENV variables
145
+ mappedWorkflow = await mapCIWorkflowContent(this);
146
+ // Add client id and secret to global 'this'
147
+ this.clientId = existingDeployKey?.id;
148
+ this.clientSecret = existingDeployKey?.sharedSecret;
149
+ log.help(messages.devinit.ciIntro(git, this.clientDetailsLocation));
150
+ } else {
151
+ // Look at the workflow file content and make updates
152
+ mappedWorkflow = await mapCIWorkflowContent(this);
153
+ log.help(messages.devinit.ciIntro(git, this.clientDetailsLocation));
154
+ }
155
+
156
+ if (!dryRun) {
157
+ // Confirm prompt
158
+ const { confirm } = await inquirer.prompt([
159
+ {
160
+ type: 'confirm',
161
+ message: messages.devinit.confirm(),
162
+ name: 'confirm',
163
+ default: false,
164
+ },
165
+ ]);
166
+ log.raw('');
167
+ if (!confirm) return;
168
+ }
169
+
170
+ // Access token prompt
171
+ let accessToken: string | undefined = undefined;
172
+ const { canContinue } = await inquirer.prompt([
173
+ {
174
+ type: 'confirm',
175
+ prefix: '🛡️',
176
+ // We're all set to grab your access token. Can we proceed? (⏎ continue)
177
+ message: messages.devinit.accessTokenPrompt(),
178
+ name: 'canContinue',
179
+ },
180
+ ]);
181
+ log.raw('');
182
+
183
+ if (!canContinue) return;
184
+ if (canContinue) {
185
+ const spinner = createSpinner(messages.devinit.accessTokenFetch());
186
+ spinner.start();
187
+
188
+ // Fetching access token
189
+ const token = await this.GetDeliveryApiKey();
190
+
191
+ if (token) {
192
+ spinner.success();
193
+ this.log.success(messages.devinit.accessTokenSuccess(token));
194
+ accessToken = token;
195
+ } else {
196
+ spinner.error();
197
+ this.log.error(messages.devinit.accessTokenFailed());
198
+ return;
199
+ }
200
+ }
201
+
202
+ // Magic happens...
203
+ const checkpoint = (op: string) => {
204
+ if (errors.length) throw errors[0];
205
+ else log.debug(`${op} completed ok`);
206
+ return true;
207
+ };
208
+
209
+ // Arrange API keys for development and deployment
210
+ const [getRolesErr, roles] = await to(contensis.roles.GetRoles());
211
+ if (!roles && getRolesErr) errors.push(getRolesErr);
212
+ checkpoint(`fetched ${roles?.length} roles`);
213
+ if (dryRun) {
214
+ checkpoint(`skip api key creation (dry-run)`);
215
+ } else {
216
+ existingDevKey = await this.CreateOrUpdateApiKey(
217
+ existingDevKey,
218
+ devKeyName,
219
+ devKeyDescription
220
+ );
221
+ checkpoint('dev key created');
222
+
223
+ existingDeployKey = await this.CreateOrUpdateApiKey(
224
+ existingDeployKey,
225
+ deployKeyName,
226
+ deployKeyDescription
227
+ );
228
+ checkpoint('deploy key created');
229
+
230
+ // Ensure dev API key is assigned to a role
231
+ let existingDevRole = findByIdOrName(roles || [], devKeyName, true) as
232
+ | Role
233
+ | undefined;
234
+ existingDevRole = await this.CreateOrUpdateRole(
235
+ existingDevRole,
236
+ devKeyRole(devKeyName, devKeyDescription)
237
+ );
238
+ checkpoint('dev key role assigned');
239
+ log.success(messages.devinit.createDevKey(devKeyName, true));
240
+
241
+ // Ensure deploy API key is assigned to a role with the right permissions
242
+ let existingDeployRole = findByIdOrName(
243
+ roles || [],
244
+ deployKeyName,
245
+ true
246
+ ) as Role | undefined;
247
+ existingDeployRole = await this.CreateOrUpdateRole(
248
+ existingDeployRole,
249
+ deployKeyRole(deployKeyName, deployKeyDescription)
250
+ );
251
+
252
+ checkpoint('deploy key role assigned');
253
+ log.success(messages.devinit.createDeployKey(deployKeyName, true));
254
+ checkpoint('api keys done');
255
+ }
256
+
257
+ // Update or create a file called .env in project home
258
+ const envContentsToAdd: EnvContentsToAdd = {
259
+ ALIAS: currentEnv,
260
+ PROJECT: currentProject,
261
+ };
262
+ if (accessToken) envContentsToAdd['ACCESS_TOKEN'] = accessToken;
263
+ if (this.clientDetailsLocation === 'env') {
264
+ if (git.type === 'github') {
265
+ envContentsToAdd['CONTENSIS_CLIENT_ID'] = this.clientId;
266
+ envContentsToAdd['CONTENSIS_CLIENT_SECRET'] = this.clientSecret;
267
+ }
268
+ }
269
+
270
+ const envFilePath = `${projectHome}/.env`;
271
+ const existingEnvFile = readFile(envFilePath);
272
+ const envFileLines = mergeDotEnvFileContents(
273
+ (existingEnvFile || '').split('\n').filter(l => !!l),
274
+ envContentsToAdd
275
+ );
276
+ const newEnvFileContent = envFileLines.join('\n');
277
+ const envDiff = diffFileContent(existingEnvFile || '', newEnvFileContent);
278
+
279
+ if (dryRun) {
280
+ if (envDiff) {
281
+ log.info(`Updating .env file ${winSlash(envFilePath)}:\n${envDiff}`);
282
+ log.raw('');
283
+ }
284
+ checkpoint('skip .env file update (dry-run)');
285
+ } else {
286
+ if (envDiff) log.info(`updating .env file ${winSlash(envFilePath)}`);
287
+ writeFile(envFilePath, envFileLines.join('\n'));
288
+ checkpoint('.env file updated');
289
+ log.success(messages.devinit.writeEnvFile());
290
+ // log.help(messages.devinit.useEnvFileTip());
291
+ }
292
+
293
+ // Update CI file -- different for GH/GL
294
+ if (mappedWorkflow?.diff) {
295
+ log.info(
296
+ `Updating ${winSlash(ciFileName)} file:\n${mappedWorkflow.diff}`
297
+ );
298
+ log.raw('');
299
+ }
300
+ if (dryRun) {
301
+ checkpoint('skip CI file update (dry-run)');
302
+ //log.object(ciFileLines);
303
+ } else {
304
+ if (mappedWorkflow?.newWorkflow) {
305
+ if (mappedWorkflow?.diff) {
306
+ writeFile(git.ciFilePath, mappedWorkflow.newWorkflow);
307
+ log.success(messages.devinit.writeCiFile(`./${ciFileName}`));
308
+ log.info(
309
+ messages.devinit.ciBlockTip(blockId, currentEnv, currentProject)
310
+ );
311
+ } else {
312
+ log.info(messages.devinit.ciFileNoChanges(`./${ciFileName}`));
313
+ }
314
+ checkpoint('CI file updated');
315
+ }
316
+ }
317
+
318
+ if (this.clientDetailsLocation === 'git') {
319
+ // Echo Deployment API key to console, ask user to add secrets to repo
320
+ log.warning(messages.devinit.addGitSecretsIntro());
321
+ log.help(
322
+ messages.devinit.addGitSecretsHelp(
323
+ git,
324
+ existingDeployKey?.id,
325
+ existingDeployKey?.sharedSecret
326
+ )
327
+ );
328
+ }
329
+
330
+ if (dryRun) {
331
+ log.success(messages.devinit.dryRun());
332
+ log.help(messages.devinit.noChanges());
333
+ } else {
334
+ log.success(messages.devinit.success());
335
+ log.help(messages.devinit.startProjectTip());
336
+ }
337
+ }
338
+ };
339
+
340
+ ExecRequestHandler = async (blockIds: string[], overrideArgs?: string[]) => {
341
+ // if no request handler exe
342
+ // download it.
343
+
344
+ // if update arg, redownload it
345
+
346
+ const { log } = this;
347
+ // const getPrefixOld = log.getPrefix;
348
+ const exeHome = path.join(appRootDir, 'reqhan');
349
+ const exe = 'Zengenti.Contensis.RequestHandler.LocalDevelopment';
350
+ const exePath = path.join(exeHome, exe);
351
+ const siteConfigPath = path.join(appRootDir, 'site_config.yaml');
352
+
353
+ const siteConfig = await mapSiteConfigYaml(this);
354
+ writeFile('site_config.yaml', stringifyYaml(siteConfig));
355
+
356
+ const args = overrideArgs
357
+ ? typeof overrideArgs?.[0] === 'string' &&
358
+ overrideArgs[0].includes(' ', 2)
359
+ ? overrideArgs[0].split(' ')
360
+ : overrideArgs
361
+ : []; // args could be [ '-c .\\site_config.yaml' ] or [ '-c', '.\\site_config.yaml' ]
362
+
363
+ // Add required args
364
+ if (!args.find(a => a === '-c')) args.push('-c', siteConfigPath);
365
+
366
+ // const child = execFile(exePath, args);
367
+
368
+ const child = spawn(exePath, args, { stdio: 'inherit' });
369
+
370
+ // log.raw('');
371
+ log.info(`Launching request handler...`);
372
+ if (overrideArgs?.length)
373
+ this.log.warning(
374
+ `Spawning process with supplied args: ${JSON.stringify(
375
+ child.spawnargs,
376
+ null,
377
+ 2
378
+ )}`
379
+ );
380
+
381
+ let isRunning = false;
382
+
383
+ // Log child output through event listeners
384
+ child?.stdout?.on('data', data => {
385
+ isRunning = true;
386
+ log.raw(data);
387
+ });
388
+
389
+ child?.stderr?.on('data', data => {
390
+ log.error(data);
391
+ });
392
+
393
+ child.on('spawn', () => {
394
+ isRunning = true;
395
+ log.help(
396
+ `You may see a firewall popup requesting network access, it is safe to approve`
397
+ );
398
+ // log.getPrefix = () => Logger.infoText(`[rqh]`);
399
+ });
400
+
401
+ child.on('exit', code => {
402
+ isRunning = false;
403
+
404
+ log[code === 0 ? 'success' : 'warning'](
405
+ `Request handler exited with code ${code}\n`
406
+ );
407
+ });
408
+
409
+ child.on('error', error => {
410
+ isRunning = false;
411
+ log.error(`Could not launch request handler due to error \n${error}`);
412
+ });
413
+
414
+ await new Promise(resolve => setTimeout(resolve, 2000));
415
+
416
+ // keep the method running until we can return
417
+ while (true === true) {
418
+ if (!isRunning) {
419
+ // log.getPrefix = getPrefixOld; // restore logger state
420
+ return;
421
+ }
422
+ await new Promise(resolve => setTimeout(resolve, 1000));
423
+ }
424
+ };
425
+ }
426
+ export const devCommand = (
427
+ commandArgs: string[],
428
+ outputOpts: OutputOptionsConstructorArg,
429
+ contensisOpts: Partial<MigrateRequest> = {}
430
+ ) => {
431
+ return new ContensisDev(['', '', ...commandArgs], outputOpts, contensisOpts);
432
+ };
433
+
434
+ export default ContensisDev;
@@ -0,0 +1,108 @@
1
+ import { Role } from 'contensis-management-api/lib/models';
2
+ import { ApiKey, MigrateRequest } from 'migratortron';
3
+ import to from 'await-to-js';
4
+ import ContensisCli from './ContensisCliService';
5
+ import { OutputOptionsConstructorArg } from '~/models/CliService';
6
+ import { Logger } from '~/util/logger';
7
+
8
+ class ContensisRole extends ContensisCli {
9
+ constructor(
10
+ args: string[],
11
+ outputOpts?: OutputOptionsConstructorArg,
12
+ contensisOpts: Partial<MigrateRequest> = {}
13
+ ) {
14
+ super(args, outputOpts, contensisOpts);
15
+ }
16
+
17
+ GetDeliveryApiKey = async () => {
18
+ const { contensis, currentEnv } = this;
19
+
20
+ const CMS = `https://cms-${currentEnv}.cloud.contensis.com`;
21
+ const API = 'api/contensis-cli/settings/defaultDeliveryApiAccessToken';
22
+
23
+ if (contensis) {
24
+ const [error, bearerToken] = await to(
25
+ contensis.content.sourceRepo.repo.BearerToken()
26
+ );
27
+ if (error) Logger.error(error.message);
28
+
29
+ const token = fetch(`${CMS}/${API}`, {
30
+ method: 'GET',
31
+ headers: {
32
+ 'Content-Type': 'application/json',
33
+ Authorization: `Bearer ${bearerToken}`,
34
+ },
35
+ })
36
+ .then(repsonse => repsonse.json())
37
+ .then(({ value }) => {
38
+ if (value) return value;
39
+ })
40
+ .catch(error => {
41
+ throw new Error(error);
42
+ });
43
+
44
+ return token;
45
+ }
46
+ };
47
+
48
+ CreateOrUpdateApiKey = async (
49
+ existingKey: ApiKey | undefined,
50
+ name: string,
51
+ description: string
52
+ ) => {
53
+ const { contensis, currentEnv, messages } = this;
54
+ if (!contensis) throw new Error('shouldnt be here');
55
+ if (existingKey) {
56
+ const [err, key] = await contensis.apiKeys.UpdateKey(existingKey.id, {
57
+ name,
58
+ description,
59
+ });
60
+
61
+ if (err)
62
+ throw new Error(messages.keys.failedUpdate(currentEnv, name), {
63
+ cause: err,
64
+ });
65
+ return key;
66
+ } else {
67
+ const [err, key] = await contensis.apiKeys.CreateKey(name, description);
68
+ if (err)
69
+ throw new Error(messages.keys.failedCreate(currentEnv, name), {
70
+ cause: err,
71
+ });
72
+
73
+ return key;
74
+ }
75
+ };
76
+
77
+ CreateOrUpdateRole = async (
78
+ existingRole: Role | undefined,
79
+ role: Partial<Role>
80
+ ) => {
81
+ const { contensis, currentEnv, messages } = this;
82
+ if (!contensis) throw new Error('shouldnt be here');
83
+
84
+ if (existingRole) {
85
+ // TODO: check is update needed?
86
+ const [err, updated] = await contensis.roles.UpdateRole(existingRole.id, {
87
+ ...existingRole,
88
+ ...role,
89
+ });
90
+ if (err)
91
+ throw new Error(messages.roles.failedSet(currentEnv, role.name), {
92
+ cause: err,
93
+ });
94
+ return updated;
95
+ } else {
96
+ const [err, created] = await contensis.roles.CreateRole(
97
+ role as Omit<Role, 'id'>
98
+ );
99
+ if (err)
100
+ throw new Error(messages.roles.failedCreate(currentEnv, role.name), {
101
+ cause: err,
102
+ });
103
+
104
+ return created;
105
+ }
106
+ };
107
+ }
108
+ export default ContensisRole;