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.
- package/CHANGELOG.md +38 -0
- package/dist/localisation/en-GB.js +5 -3
- package/dist/localisation/en-GB.js.map +2 -2
- package/dist/mappers/DevInit-to-CIWorkflow.js +6 -8
- package/dist/mappers/DevInit-to-CIWorkflow.js.map +2 -2
- package/dist/mappers/DevInit-to-RolePermissions.js +4 -4
- package/dist/mappers/DevInit-to-RolePermissions.js.map +2 -2
- package/dist/services/ContensisAuthService.js.map +2 -2
- package/dist/services/ContensisCliService.js +24 -18
- package/dist/services/ContensisCliService.js.map +2 -2
- package/dist/services/ContensisDevService.js +51 -56
- package/dist/services/ContensisDevService.js.map +3 -3
- package/dist/shell.js +2 -0
- package/dist/shell.js.map +2 -2
- package/dist/util/csv.formatter.js +3 -11
- package/dist/util/csv.formatter.js.map +3 -3
- package/dist/util/diff.js +1 -1
- package/dist/util/diff.js.map +2 -2
- package/dist/util/git.js +1 -0
- package/dist/util/git.js.map +2 -2
- package/dist/util/json.formatter.js +35 -3
- package/dist/util/json.formatter.js.map +3 -3
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/src/localisation/en-GB.ts +6 -3
- package/src/mappers/DevInit-to-CIWorkflow.ts +8 -8
- package/src/mappers/DevInit-to-RolePermissions.ts +5 -2
- package/src/models/Cache.d.ts +2 -1
- package/src/services/ContensisAuthService.ts +1 -1
- package/src/services/ContensisCliService.ts +26 -28
- package/src/services/ContensisDevService.ts +76 -70
- package/src/shell.ts +4 -0
- package/src/util/csv.formatter.ts +1 -4
- package/src/util/diff.ts +1 -1
- package/src/util/git.ts +2 -1
- package/src/util/json.formatter.ts +32 -1
- 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
|
-
|
|
27
|
+
flattenObject: () => flattenObject,
|
|
28
|
+
jsonFormatter: () => jsonFormatter,
|
|
29
|
+
limitFields: () => limitFields
|
|
22
30
|
});
|
|
23
31
|
module.exports = __toCommonJS(json_formatter_exports);
|
|
24
|
-
|
|
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
|
-
|
|
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": ["
|
|
5
|
-
"mappings": "
|
|
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.
|
|
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
|
package/dist/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["export const LIB_VERSION = \"1.
|
|
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.
|
|
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(
|
|
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: () =>
|
|
554
|
+
accessTokenFetch: () =>
|
|
555
|
+
`Please wait, fetching Delivery API access token ⏳`,
|
|
555
556
|
accessTokenSuccess: (token: string) =>
|
|
556
|
-
`Successfully fetched Delivery API 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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
301
|
+
cli.deployCredentials.clientId
|
|
302
302
|
);
|
|
303
303
|
setWorkflowElement(
|
|
304
304
|
workflowDoc,
|
|
305
305
|
'env.CONTENSIS_SHARED_SECRET',
|
|
306
|
-
cli.
|
|
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:
|
|
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:
|
|
28
|
+
name: roleName,
|
|
26
29
|
description,
|
|
27
30
|
assignments: {
|
|
28
31
|
apiKeys: [keyName],
|
package/src/models/Cache.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
2515
|
+
writeString = csvFormatter(limitFields(obj, fields));
|
|
2519
2516
|
} else if (format === 'xml') {
|
|
2520
|
-
writeString = xmlFormatter(obj
|
|
2521
|
-
} else
|
|
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(
|
|
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'] =
|
|
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(`
|
|
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
|
-
|
|
351
|
-
|
|
352
|
-
|
|
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
|
-
|
|
407
|
+
`${this.urls?.cms}${
|
|
402
408
|
classicToken ? `?SecurityToken=${classicToken}` : ''
|
|
403
409
|
}`
|
|
404
410
|
)
|