contensis-cli 1.0.12-beta.8 → 1.1.1-beta.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/localisation/en-GB.js +5 -3
  3. package/dist/localisation/en-GB.js.map +2 -2
  4. package/dist/mappers/DevInit-to-CIWorkflow.js +6 -8
  5. package/dist/mappers/DevInit-to-CIWorkflow.js.map +2 -2
  6. package/dist/mappers/DevInit-to-RolePermissions.js +4 -4
  7. package/dist/mappers/DevInit-to-RolePermissions.js.map +2 -2
  8. package/dist/services/ContensisAuthService.js.map +2 -2
  9. package/dist/services/ContensisCliService.js +24 -18
  10. package/dist/services/ContensisCliService.js.map +2 -2
  11. package/dist/services/ContensisDevService.js +51 -56
  12. package/dist/services/ContensisDevService.js.map +3 -3
  13. package/dist/shell.js +2 -0
  14. package/dist/shell.js.map +2 -2
  15. package/dist/util/csv.formatter.js +3 -11
  16. package/dist/util/csv.formatter.js.map +3 -3
  17. package/dist/util/diff.js +1 -1
  18. package/dist/util/diff.js.map +2 -2
  19. package/dist/util/git.js +1 -0
  20. package/dist/util/git.js.map +2 -2
  21. package/dist/util/json.formatter.js +35 -3
  22. package/dist/util/json.formatter.js.map +3 -3
  23. package/dist/version.js +1 -1
  24. package/dist/version.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/localisation/en-GB.ts +6 -3
  27. package/src/mappers/DevInit-to-CIWorkflow.ts +8 -8
  28. package/src/mappers/DevInit-to-RolePermissions.ts +5 -2
  29. package/src/models/Cache.d.ts +2 -1
  30. package/src/services/ContensisAuthService.ts +1 -1
  31. package/src/services/ContensisCliService.ts +26 -28
  32. package/src/services/ContensisDevService.ts +76 -70
  33. package/src/shell.ts +4 -0
  34. package/src/util/csv.formatter.ts +1 -4
  35. package/src/util/diff.ts +1 -1
  36. package/src/util/git.ts +2 -1
  37. package/src/util/json.formatter.ts +32 -1
  38. package/src/version.ts +1 -1
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,15 +17,45 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
18
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
25
  var json_formatter_exports = {};
20
26
  __export(json_formatter_exports, {
21
- jsonFormatter: () => jsonFormatter
27
+ flattenObject: () => flattenObject,
28
+ jsonFormatter: () => jsonFormatter,
29
+ limitFields: () => limitFields
22
30
  });
23
31
  module.exports = __toCommonJS(json_formatter_exports);
24
- const jsonFormatter = (obj) => JSON.stringify(obj, null, 2);
32
+ var import_flat = require("flat");
33
+ var import_deep_cleaner = __toESM(require("deep-cleaner"));
34
+ const jsonFormatter = (obj, fields) => JSON.stringify(limitFields(obj, fields), null, 2);
35
+ const flattenObject = (obj) => (0, import_flat.flatten)((0, import_deep_cleaner.default)(obj, ["workflow"]));
36
+ const limitFields = (obj, fields) => {
37
+ if (!fields)
38
+ return obj;
39
+ if (obj && Array.isArray(obj)) {
40
+ const arr = [];
41
+ for (const child of obj)
42
+ arr.push(limitFields(child, fields));
43
+ return arr;
44
+ }
45
+ if (obj && typeof obj === "object") {
46
+ const flattenedObj = (0, import_flat.flatten)(obj);
47
+ const sortedObj = {};
48
+ for (const field of fields) {
49
+ sortedObj[field] = flattenedObj[field];
50
+ }
51
+ return (0, import_flat.unflatten)(sortedObj);
52
+ }
53
+ return obj;
54
+ };
25
55
  // Annotate the CommonJS export names for ESM import in node:
26
56
  0 && (module.exports = {
27
- jsonFormatter
57
+ flattenObject,
58
+ jsonFormatter,
59
+ limitFields
28
60
  });
29
61
  //# sourceMappingURL=json.formatter.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/util/json.formatter.ts"],
4
- "sourcesContent": ["export const jsonFormatter = <T>(obj: T) => JSON.stringify(obj, null, 2);\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,gBAAgB,CAAI,QAAW,KAAK,UAAU,KAAK,MAAM,CAAC;",
6
- "names": []
4
+ "sourcesContent": ["import { flatten, unflatten } from 'flat';\nimport cleaner from 'deep-cleaner';\n\n// Format a JSON object for a nice output\nexport const jsonFormatter = <T>(obj: T, fields?: string[]) =>\n JSON.stringify(limitFields(obj, fields), null, 2);\n\n// Flatten a JSON object such as an entry so there are no\n// nested object and the keys are presented like \"sys.version.versionNo\": \"1.0\"\nexport const flattenObject = (obj: any) => flatten(cleaner(obj, ['workflow']));\n\n// Will limit and sort an object's keys by an array of supplied fields\nexport const limitFields = (obj: any, fields?: string[]): any => {\n if (!fields) return obj;\n if (obj && Array.isArray(obj)) {\n const arr = [];\n for (const child of obj) arr.push(limitFields(child, fields));\n return arr;\n }\n\n if (obj && typeof obj === 'object') {\n const flattenedObj = flatten(obj) as any;\n const sortedObj = {} as any;\n for (const field of fields) {\n sortedObj[field] = flattenedObj[field];\n }\n\n return unflatten(sortedObj);\n }\n\n return obj;\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAmC;AACnC,0BAAoB;AAGb,MAAM,gBAAgB,CAAI,KAAQ,WACvC,KAAK,UAAU,YAAY,KAAK,MAAM,GAAG,MAAM,CAAC;AAI3C,MAAM,gBAAgB,CAAC,YAAa,yBAAQ,oBAAAA,SAAQ,KAAK,CAAC,UAAU,CAAC,CAAC;AAGtE,MAAM,cAAc,CAAC,KAAU,WAA2B;AAC/D,MAAI,CAAC;AAAQ,WAAO;AACpB,MAAI,OAAO,MAAM,QAAQ,GAAG,GAAG;AAC7B,UAAM,MAAM,CAAC;AACb,eAAW,SAAS;AAAK,UAAI,KAAK,YAAY,OAAO,MAAM,CAAC;AAC5D,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,UAAM,mBAAe,qBAAQ,GAAG;AAChC,UAAM,YAAY,CAAC;AACnB,eAAW,SAAS,QAAQ;AAC1B,gBAAU,SAAS,aAAa;AAAA,IAClC;AAEA,eAAO,uBAAU,SAAS;AAAA,EAC5B;AAEA,SAAO;AACT;",
6
+ "names": ["cleaner"]
7
7
  }
package/dist/version.js CHANGED
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  LIB_VERSION: () => LIB_VERSION
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const LIB_VERSION = "1.0.12-beta.8";
24
+ const LIB_VERSION = "1.1.1-beta.0";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  LIB_VERSION
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["export const LIB_VERSION = \"1.0.12-beta.8\";\n"],
4
+ "sourcesContent": ["export const LIB_VERSION = \"1.1.1-beta.0\";\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contensis-cli",
3
- "version": "1.0.12-beta.8",
3
+ "version": "1.1.1-beta.0",
4
4
  "description": "A fully featured Contensis command line interface with a shell UI provides simple and intuitive ways to manage or profile your content in any NodeJS terminal.",
5
5
  "repository": "https://github.com/contensis/cli",
6
6
  "homepage": "https://github.com/contensis/cli/tree/main/packages/contensis-cli#readme",
@@ -451,7 +451,7 @@ export const LogMessages = {
451
451
  ) =>
452
452
  `
453
453
  Project: ${Logger.standardText(name)}
454
- - Home: ${Logger.standardText(process.cwd())}
454
+ - Home: ${Logger.standardText(git.gitcwd())}
455
455
  - Repository: ${Logger.standardText(git.home)}
456
456
  - Block id: ${Logger.highlightText(blockId)}
457
457
 
@@ -551,9 +551,10 @@ export const LogMessages = {
551
551
  } ${Logger.highlightText(`CONTENSIS_SHARED_SECRET`)}\n ${
552
552
  git.type === 'github' ? `Secret:` : `Value:`
553
553
  } ${Logger.standardText(secret)}`,
554
- accessTokenFetch: () => `Please wait, fecthing Delivery API token ⏳`,
554
+ accessTokenFetch: () =>
555
+ `Please wait, fetching Delivery API access token ⏳`,
555
556
  accessTokenSuccess: (token: string) =>
556
- `Successfully fetched Delivery API token 👉 ${Logger.infoText(token)}`,
557
+ `Successfully fetched Delivery API token\n ${Logger.infoText(token)}`,
557
558
  accessTokenFailed: () =>
558
559
  `Something went wrong! If the problem persists, please contact our support team 🛟`,
559
560
  accessTokenPermission: () =>
@@ -572,6 +573,8 @@ export const LogMessages = {
572
573
  failed: () => `Contensis developer environment initialisation failed`,
573
574
  dryRun: () =>
574
575
  `Contensis developer environment initialisation dry run completed`,
576
+ dryRunKeyMessage: (dryRun: boolean) =>
577
+ dryRun ? '<< not created: dry-run >>' : undefined,
575
578
  noChanges: () =>
576
579
  `No changes were made to your project, run the command again without the ${Logger.highlightText(
577
580
  '--dry-run'
@@ -102,12 +102,10 @@ const mapGitLabCIWorkflowContent = async (
102
102
  alias: cli.currentEnv,
103
103
  project_id: cli.currentProject,
104
104
  client_id:
105
- loc === 'env'
106
- ? cli.devinit?.credentials.clientId
107
- : '$CONTENSIS_CLIENT_ID',
105
+ loc === 'env' ? cli.deployCredentials.clientId : '$CONTENSIS_CLIENT_ID',
108
106
  shared_secret:
109
107
  loc === 'env'
110
- ? cli.devinit?.credentials.clientSecret
108
+ ? cli.deployCredentials.clientSecret
111
109
  : '$CONTENSIS_SHARED_SECRET',
112
110
  },
113
111
  };
@@ -120,12 +118,14 @@ const mapGitLabCIWorkflowContent = async (
120
118
  setWorkflowElement(
121
119
  workflowDoc,
122
120
  `variables.CONTENSIS_CLIENT_ID`,
123
- `${cli.devinit.credentials.clientId}`
121
+ cli.deployCredentials.clientId ||
122
+ cli.messages.devinit.dryRunKeyMessage(!!cli.command.options.dryRun)
124
123
  );
125
124
  setWorkflowElement(
126
125
  workflowDoc,
127
126
  `variables.CONTENSIS_CLIENT_SECRET`,
128
- `${cli.devinit.credentials.clientSecret}`
127
+ cli.deployCredentials.clientSecret ||
128
+ cli.messages.devinit.dryRunKeyMessage(!!cli.command.options.dryRun)
129
129
  );
130
130
  }
131
131
 
@@ -298,12 +298,12 @@ const mapGitHubActionCIWorkflowContent = async (
298
298
  setWorkflowElement(
299
299
  workflowDoc,
300
300
  `env.CONTENSIS_CLIENT_ID`,
301
- cli.devinit?.credentials.clientId
301
+ cli.deployCredentials.clientId
302
302
  );
303
303
  setWorkflowElement(
304
304
  workflowDoc,
305
305
  'env.CONTENSIS_SHARED_SECRET',
306
- cli.devinit?.credentials.clientSecret
306
+ cli.deployCredentials.clientSecret
307
307
  );
308
308
  }
309
309
 
@@ -1,15 +1,17 @@
1
1
  import { Role } from 'contensis-management-api/lib/models';
2
2
 
3
3
  export const devKeyPermissions = {} as Partial<Role['permissions']>;
4
+
4
5
  export const deployKeyPermissions = {
5
6
  blocks: { actions: ['push', 'release', 'view'] },
6
7
  } as Role['permissions'];
7
8
 
8
9
  export const devKeyRole = (
9
10
  keyName: string,
11
+ roleName: string,
10
12
  description: string
11
13
  ): Partial<Role> => ({
12
- name: keyName,
14
+ name: roleName,
13
15
  description,
14
16
  assignments: {
15
17
  apiKeys: [keyName],
@@ -20,9 +22,10 @@ export const devKeyRole = (
20
22
 
21
23
  export const deployKeyRole = (
22
24
  keyName: string,
25
+ roleName: string,
23
26
  description: string
24
27
  ): Partial<Role> => ({
25
- name: keyName,
28
+ name: roleName,
26
29
  description,
27
30
  assignments: {
28
31
  apiKeys: [keyName],
@@ -19,7 +19,8 @@ type EnvironmentCache = {
19
19
 
20
20
  type CliCommand = {
21
21
  createdDate: string;
22
- createdUserId: string;
22
+ invokedBy: string;
23
23
  commandText: string;
24
+ options: { [key: string]: string | boolean };
24
25
  result?: any;
25
26
  };
@@ -59,7 +59,7 @@ class ContensisAuthService {
59
59
  });
60
60
  }
61
61
 
62
- ClassicToken = async () => {
62
+ ClassicToken = async (): Promise<string | null | undefined> => {
63
63
  // make sure our token isn't expried.
64
64
  await this.client.ensureBearerToken();
65
65
  return (this.client as any).contensisClassicToken;
@@ -46,7 +46,7 @@ import {
46
46
  } from '~/util/console.printer';
47
47
  import { csvFormatter } from '~/util/csv.formatter';
48
48
  import { xmlFormatter } from '~/util/xml.formatter';
49
- import { jsonFormatter } from '~/util/json.formatter';
49
+ import { jsonFormatter, limitFields } from '~/util/json.formatter';
50
50
  import { diffLogStrings } from '~/util/diff';
51
51
  import { logError, Logger } from '~/util/logger';
52
52
  import { promiseDelay } from '~/util/timers';
@@ -63,23 +63,16 @@ class ContensisCli {
63
63
  process.exit(exitCode);
64
64
  };
65
65
 
66
- private command: CliCommand;
67
66
  private format?: OutputFormat;
68
67
  private output?: string;
69
68
  private session: SessionCacheProvider;
70
69
 
70
+ auth?: ContensisAuthService;
71
+ command: CliCommand;
71
72
  contensis?: ContensisMigrationService;
72
73
  contensisOpts: Partial<MigrateRequest>;
73
74
  currentProject: string;
74
75
 
75
- devinit!: {
76
- invokedBy: string;
77
- credentials: {
78
- clientId: string;
79
- clientSecret: string;
80
- };
81
- };
82
-
83
76
  sourceAlias?: string;
84
77
  targetEnv?: string;
85
78
  urls:
@@ -99,10 +92,6 @@ class ContensisCli {
99
92
  noun: string;
100
93
  thirdArg: string;
101
94
 
102
- get invokedBy() {
103
- return this.command.createdUserId;
104
- }
105
-
106
95
  get cache() {
107
96
  return this.session.Get();
108
97
  }
@@ -159,15 +148,19 @@ class ContensisCli {
159
148
  const environments = this.cache.environments || {};
160
149
  this.currentEnv = currentEnvironment;
161
150
 
151
+ // Set env from command options
162
152
  const env = this.env;
163
-
164
153
  if (outputOpts?.projectId) env.currentProject = outputOpts.projectId;
165
154
  if (outputOpts?.user) env.lastUserId = outputOpts.user;
166
155
  // setting this in env means passwordFallback is written to environments.json
167
156
  if (outputOpts?.password) env.passwordFallback = outputOpts.password;
168
157
  if (outputOpts?.clientId) env.lastUserId = outputOpts.clientId;
169
158
  if (outputOpts?.sharedSecret)
170
- env.passwordFallback = outputOpts.sharedSecret;
159
+ if (outputOpts.sharedSecret.startsWith('-'))
160
+ throw new Error(
161
+ `Shared secret option provided a value of ${outputOpts.sharedSecret}`
162
+ );
163
+ else env.passwordFallback = outputOpts.sharedSecret;
171
164
 
172
165
  this.currentProject = env?.currentProject || 'null';
173
166
  this.sourceAlias = outputOpts?.sourceAlias || currentEnvironment;
@@ -178,8 +171,9 @@ class ContensisCli {
178
171
 
179
172
  this.command = {
180
173
  commandText,
174
+ options: outputOpts as any,
181
175
  createdDate: new Date().toISOString(),
182
- createdUserId: env?.lastUserId,
176
+ invokedBy: env?.lastUserId,
183
177
  };
184
178
 
185
179
  if (currentEnvironment) {
@@ -419,7 +413,10 @@ class ContensisCli {
419
413
 
420
414
  if (credentialError && !credentials.current) {
421
415
  // Log problem with Credential Provider
422
- log.error(credentialError as any);
416
+ log.error(
417
+ `Unable to find credentials for user ${userId} at ${currentEnv}`,
418
+ credentialError as any
419
+ );
423
420
  return;
424
421
  }
425
422
 
@@ -487,7 +484,7 @@ class ContensisCli {
487
484
  }
488
485
 
489
486
  if (inputPassword || cachedPassword || cachedSecret) {
490
- const authService = new ContensisAuthService({
487
+ this.auth = new ContensisAuthService({
491
488
  username: userId,
492
489
  password: inputPassword || cachedPassword,
493
490
  projectId: env?.currentProject || 'website',
@@ -496,9 +493,7 @@ class ContensisCli {
496
493
  clientSecret: sharedSecret || cachedSecret,
497
494
  });
498
495
 
499
- const [authError, bearerToken] = await to(
500
- authService.BearerToken()
501
- );
496
+ const [authError, bearerToken] = await to(this.auth.BearerToken());
502
497
 
503
498
  // Login successful
504
499
  if (bearerToken) {
@@ -2496,18 +2491,20 @@ class ContensisCli {
2496
2491
  };
2497
2492
  HandleFormattingAndOutput = <T>(obj: T, logFn: (obj: T) => void) => {
2498
2493
  const { format, log, messages, output } = this;
2494
+ const fields = this.contensis?.payload.query?.fields;
2495
+
2499
2496
  if (!format) {
2500
2497
  // print the object to console
2501
2498
  logFn(obj);
2502
2499
  } else if (format === 'csv') {
2503
2500
  log.raw('');
2504
- log.raw(log.infoText(csvFormatter(obj)));
2501
+ log.raw(log.infoText(csvFormatter(limitFields(obj, fields))));
2505
2502
  } else if (format === 'xml') {
2506
2503
  log.raw('');
2507
- log.raw(log.infoText(xmlFormatter(obj)));
2504
+ log.raw(log.infoText(xmlFormatter(limitFields(obj, fields))));
2508
2505
  } else if (format === 'json') {
2509
2506
  log.raw('');
2510
- log.raw(log.infoText(jsonFormatter(obj)));
2507
+ log.raw(log.infoText(jsonFormatter(obj, fields)));
2511
2508
  }
2512
2509
  log.raw('');
2513
2510
 
@@ -2515,10 +2512,11 @@ class ContensisCli {
2515
2512
  let writeString = '';
2516
2513
  const isText = !tryParse(obj) && typeof obj === 'string';
2517
2514
  if (format === 'csv') {
2518
- writeString = csvFormatter(obj as any);
2515
+ writeString = csvFormatter(limitFields(obj, fields));
2519
2516
  } else if (format === 'xml') {
2520
- writeString = xmlFormatter(obj as any);
2521
- } else writeString = isText ? (obj as string) : jsonFormatter(obj);
2517
+ writeString = xmlFormatter(limitFields(obj, fields));
2518
+ } else
2519
+ writeString = isText ? (obj as string) : jsonFormatter(obj, fields);
2522
2520
  // write output to file
2523
2521
  if (writeString) {
2524
2522
  fs.writeFileSync(output, writeString);
@@ -1,6 +1,8 @@
1
+ import ansiEscapes from 'ansi-escapes';
1
2
  import to from 'await-to-js';
2
3
  import { spawn } from 'child_process';
3
4
  import inquirer from 'inquirer';
5
+ import { createSpinner } from 'nanospinner';
4
6
  import path from 'path';
5
7
 
6
8
  import { Role } from 'contensis-management-api/lib/models';
@@ -20,15 +22,17 @@ import { GitHelper } from '~/util/git';
20
22
  import { jsonFormatter } from '~/util/json.formatter';
21
23
  import { winSlash } from '~/util/os';
22
24
  import { stringifyYaml } from '~/util/yaml';
23
- import { createSpinner } from 'nanospinner';
24
25
  import { mergeContentsToAddWithGitignore } from '~/util/gitignore';
25
- import ContensisAuthService from './ContensisAuthService';
26
- import ansiEscapes from 'ansi-escapes';
27
26
 
28
27
  class ContensisDev extends ContensisRole {
29
28
  git!: GitHelper;
30
29
  blockId!: string;
31
30
 
31
+ deployCredentials = {
32
+ clientId: '',
33
+ clientSecret: '',
34
+ };
35
+
32
36
  constructor(
33
37
  args: string[],
34
38
  outputOpts?: OutputOptionsConstructorArg,
@@ -49,8 +53,6 @@ class ContensisDev extends ContensisRole {
49
53
  const contensis = await this.ConnectContensis();
50
54
 
51
55
  if (contensis) {
52
- this.devinit = { ...this.devinit, invokedBy: this.invokedBy };
53
-
54
56
  // First we need to get the block id from the user
55
57
  const validateBlockId = (blockId: string) => {
56
58
  const pattern = /^[0-9a-z](-?[0-9a-z])*$/;
@@ -64,6 +66,7 @@ class ContensisDev extends ContensisRole {
64
66
  prefix: '🧱',
65
67
  message: messages.devinit.blockIdQuestion,
66
68
  validate: validateBlockId,
69
+ default: git.name,
67
70
  });
68
71
  // make sure block id is lowercase
69
72
  this.blockId = blockId.toLowerCase();
@@ -93,65 +96,17 @@ class ContensisDev extends ContensisRole {
93
96
  const devKeyDescription = `Created by Contensis to allow API access from the running block`;
94
97
  let existingDevKey = apiKeyExists(devKeyName);
95
98
 
96
- // if dev api key doesn't exisit go and create it (we need this for local development, we will store these details in the .env file).
97
- if (!existingDevKey) {
98
- existingDevKey = await this.CreateOrUpdateApiKey(
99
- existingDevKey,
100
- devKeyName,
101
- devKeyDescription
102
- );
103
- log.success('Successfully created development key');
104
- }
105
-
106
99
  const deployKeyName = `${apiKeyName}-ci`;
107
100
  const deployKeyDescription = `Created by the Contensis CLI for use in continuous integration`;
108
101
 
109
102
  let existingDeployKey = apiKeyExists(deployKeyName);
110
103
 
111
- // if deploy api key doesn't exisit go and create it (we need this for yml file).
112
- if (!existingDeployKey) {
113
- existingDeployKey = await this.CreateOrUpdateApiKey(
114
- existingDeployKey,
115
- deployKeyName,
116
- deployKeyDescription
117
- );
118
- log.success('Successfully created deploy key');
119
- }
120
-
121
- // check we have the deply key so we can assign them to this values
122
- if (existingDeployKey) {
123
- // Add client id and secret to global 'this'
124
- this.devinit = {
125
- ...this.devinit,
126
- credentials: {
127
- clientId: existingDeployKey?.id,
128
- clientSecret: existingDeployKey?.sharedSecret,
129
- },
130
- };
131
- }
132
-
133
- // we need to credentials of the user so that we can create a auth service
134
- const credentials = await this.GetCredentials(this.devinit.invokedBy);
135
-
136
- // create new auth service using creds
137
- let classicToken: string | undefined | null;
138
- const auth = new ContensisAuthService({
139
- username: credentials?.current?.account,
140
- password: credentials?.current?.password,
141
- projectId: currentProject,
142
- rootUrl: `https://cms-${currentEnv}.cloud.contensis.com`,
143
- });
144
-
145
- // once we have auth service, we can go and fetch out classic token
146
- classicToken = await auth.ClassicToken();
147
-
148
104
  // const blockId = git.name;
149
105
  const errors = [] as AppError[];
150
106
 
151
107
  // Start render console output
152
108
  log.raw('');
153
109
  log.success(messages.devinit.intro());
154
- log.raw('');
155
110
  log.raw(
156
111
  log.infoText(
157
112
  messages.devinit.projectDetails(
@@ -193,7 +148,6 @@ class ContensisDev extends ContensisRole {
193
148
 
194
149
  log.raw(log.infoText(messages.devinit.ciDetails(ciFileName)));
195
150
 
196
- let mappedWorkflow;
197
151
  // Location for Client ID / Secret.
198
152
  const { loc } = await inquirer.prompt({
199
153
  name: 'loc',
@@ -213,9 +167,8 @@ class ContensisDev extends ContensisRole {
213
167
  ],
214
168
  });
215
169
 
170
+ log.raw('');
216
171
  log.help(messages.devinit.ciIntro(git, loc));
217
- // Update CI Workflow
218
- mappedWorkflow = await mapCIWorkflowContent(this, loc);
219
172
 
220
173
  if (!dryRun) {
221
174
  // Confirm prompt
@@ -233,7 +186,6 @@ class ContensisDev extends ContensisRole {
233
186
 
234
187
  // Fetching access token
235
188
  let accessToken: string | undefined = undefined;
236
- log.raw('');
237
189
 
238
190
  const spinner = createSpinner(messages.devinit.accessTokenFetch());
239
191
  spinner.start();
@@ -241,9 +193,9 @@ class ContensisDev extends ContensisRole {
241
193
  const token = await this.GetDeliveryApiKey();
242
194
 
243
195
  if (token) {
244
- spinner.success();
245
- this.log.success(messages.devinit.accessTokenSuccess(token));
246
196
  accessToken = token;
197
+ spinner.success({ text: messages.devinit.accessTokenSuccess(token) });
198
+ log.raw('');
247
199
  } else {
248
200
  spinner.error();
249
201
  this.log.error(messages.devinit.accessTokenFailed());
@@ -261,9 +213,48 @@ class ContensisDev extends ContensisRole {
261
213
  const [getRolesErr, roles] = await to(contensis.roles.GetRoles());
262
214
  if (!roles && getRolesErr) errors.push(getRolesErr);
263
215
  checkpoint(`fetched ${roles?.length} roles`);
216
+
264
217
  if (dryRun) {
265
218
  checkpoint(`skip api key creation (dry-run)`);
266
219
  } else {
220
+ // if dev api key doesn't exist go and create it (we need this for local development, we will store these details in the .env file).
221
+ const devKeyExisted = !!existingDevKey;
222
+ if (!existingDevKey) {
223
+ existingDevKey = await this.CreateOrUpdateApiKey(
224
+ existingDevKey,
225
+ devKeyName,
226
+ devKeyDescription
227
+ );
228
+ log.success(messages.devinit.createDevKey(devKeyName, devKeyExisted));
229
+ }
230
+ // NF 24/11/23 Added this commented code back in as we are not assigning the dev key to any role here
231
+ // // Ensure dev API key is assigned to a role
232
+ // let existingDevRole = findByIdOrName(roles || [], devKeyName, true) as
233
+ // | Role
234
+ // | undefined;
235
+ // existingDevRole = await this.CreateOrUpdateRole(
236
+ // existingDevRole,
237
+ // devKeyRole(devKeyName, devKeyDescription)
238
+ // );
239
+ // checkpoint('dev key role assigned');
240
+
241
+ // if deploy api key doesn't exist go and create it (we need this for yml file).
242
+ const deployKeyExisted = !!existingDeployKey;
243
+ if (!existingDeployKey) {
244
+ existingDeployKey = await this.CreateOrUpdateApiKey(
245
+ existingDeployKey,
246
+ deployKeyName,
247
+ deployKeyDescription
248
+ );
249
+ }
250
+
251
+ // check we have the deploy key so we can assign them to this values
252
+ if (existingDeployKey) {
253
+ // Add client id and secret to credentials
254
+ this.deployCredentials.clientId = existingDeployKey?.id;
255
+ this.deployCredentials.clientSecret = existingDeployKey?.sharedSecret;
256
+ }
257
+
267
258
  // Ensure deploy API key is assigned to a role with the right permissions
268
259
  const deployRoleName = `Role for CI push of block '${blockId}'`;
269
260
  const deplyRoleDescription = `Created by the Contensis CLI for use in continuous integration`;
@@ -274,11 +265,13 @@ class ContensisDev extends ContensisRole {
274
265
  ) as Role | undefined;
275
266
  existingDeployRole = await this.CreateOrUpdateRole(
276
267
  existingDeployRole,
277
- deployKeyRole(deployKeyName, deplyRoleDescription)
268
+ deployKeyRole(deployKeyName, deployRoleName, deplyRoleDescription)
278
269
  );
279
270
 
280
271
  checkpoint('deploy key role assigned');
281
- log.success(messages.devinit.createDeployKey(deployRoleName, true));
272
+ log.success(
273
+ messages.devinit.createDeployKey(deployRoleName, deployKeyExisted)
274
+ );
282
275
  checkpoint('api keys done');
283
276
  }
284
277
 
@@ -297,9 +290,11 @@ class ContensisDev extends ContensisRole {
297
290
  if (accessToken) envContentsToAdd['ACCESS_TOKEN'] = accessToken;
298
291
  // add client id and secret to the env file
299
292
  if (loc === 'env') {
300
- envContentsToAdd['CONTENSIS_CLIENT_ID'] = existingDevKey?.id;
293
+ envContentsToAdd['CONTENSIS_CLIENT_ID'] =
294
+ existingDevKey?.id || messages.devinit.dryRunKeyMessage(dryRun);
301
295
  envContentsToAdd['CONTENSIS_CLIENT_SECRET'] =
302
- existingDevKey?.sharedSecret;
296
+ existingDevKey?.sharedSecret ||
297
+ messages.devinit.dryRunKeyMessage(dryRun);
303
298
  }
304
299
 
305
300
  // if we have client id / secret in our env remove it
@@ -339,7 +334,7 @@ class ContensisDev extends ContensisRole {
339
334
  }
340
335
  checkpoint('skip .env file update (dry-run)');
341
336
  } else {
342
- if (envDiff) log.info(`updating .env file ${winSlash(envFilePath)}`);
337
+ if (envDiff) log.info(`Updating .env file ${winSlash(envFilePath)}`);
343
338
  writeFile(envFilePath, envFileLines.join('\n'));
344
339
  checkpoint('.env file updated');
345
340
  log.success(messages.devinit.writeEnvFile());
@@ -347,9 +342,15 @@ class ContensisDev extends ContensisRole {
347
342
  }
348
343
 
349
344
  // Update git ignore
350
- const gitIgnorePath = `${projectHome}/.gitignore`;
351
- const gitIgnoreContentsToAdd = ['.env'];
352
- mergeContentsToAddWithGitignore(gitIgnorePath, gitIgnoreContentsToAdd);
345
+ if (dryRun) {
346
+ checkpoint('skip .gitignore file update (dry-run)');
347
+ } else {
348
+ mergeContentsToAddWithGitignore(`${projectHome}/.gitignore`, ['.env']);
349
+ log.raw('');
350
+ }
351
+
352
+ // Update CI Workflow
353
+ const mappedWorkflow = await mapCIWorkflowContent(this, loc);
353
354
 
354
355
  // Update CI file -- different for GH/GL
355
356
  if (mappedWorkflow?.diff) {
@@ -372,6 +373,7 @@ class ContensisDev extends ContensisRole {
372
373
  } else {
373
374
  log.info(messages.devinit.ciFileNoChanges(`./${ciFileName}`));
374
375
  }
376
+ log.raw('');
375
377
  checkpoint('CI file updated');
376
378
  }
377
379
  }
@@ -382,8 +384,9 @@ class ContensisDev extends ContensisRole {
382
384
  log.help(
383
385
  messages.devinit.addGitSecretsHelp(
384
386
  git,
385
- existingDeployKey?.id,
386
- existingDeployKey?.sharedSecret
387
+ existingDeployKey?.id || messages.devinit.dryRunKeyMessage(dryRun),
388
+ existingDeployKey?.sharedSecret ||
389
+ messages.devinit.dryRunKeyMessage(dryRun)
387
390
  )
388
391
  );
389
392
  }
@@ -395,10 +398,13 @@ class ContensisDev extends ContensisRole {
395
398
  log.success(messages.devinit.success());
396
399
  log.help(messages.devinit.startProjectTip());
397
400
  // open the cms link -- if no classic token just return the cms url
401
+
402
+ // go and fetch the classic token from auth service
403
+ const classicToken = await this.auth?.ClassicToken();
398
404
  log.help(
399
405
  ansiEscapes.link(
400
406
  `Open Contensis`,
401
- `https://cms-${currentEnv}.cloud.contensis.com${
407
+ `${this.urls?.cms}${
402
408
  classicToken ? `?SecurityToken=${classicToken}` : ''
403
409
  }`
404
410
  )