contensis-cli 1.0.0-beta.87 → 1.0.0-beta.89
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/dist/commands/dev.js +8 -1
- package/dist/commands/dev.js.map +2 -2
- package/dist/localisation/en-GB.js +1 -0
- package/dist/localisation/en-GB.js.map +2 -2
- package/dist/models/CliService.d.js +17 -0
- package/dist/models/CliService.d.js.map +7 -0
- package/dist/services/ContensisCliService.js +41 -20
- package/dist/services/ContensisCliService.js.map +3 -3
- package/dist/services/ContensisDevService.js +132 -19
- package/dist/services/ContensisDevService.js.map +3 -3
- package/dist/services/ContensisRoleService.js +92 -0
- package/dist/services/ContensisRoleService.js.map +7 -0
- package/dist/util/find.js +31 -0
- package/dist/util/find.js.map +7 -0
- package/dist/util/logger.js +20 -0
- package/dist/util/logger.js.map +2 -2
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -1
- package/src/commands/dev.ts +10 -1
- package/src/localisation/en-GB.ts +3 -1
- package/src/models/CliService.d.ts +36 -0
- package/src/services/ContensisCliService.ts +55 -65
- package/src/services/ContensisDevService.ts +141 -21
- package/src/services/ContensisRoleService.ts +84 -0
- package/src/util/find.ts +8 -0
- package/src/util/logger.ts +28 -0
- package/src/version.ts +1 -1
|
@@ -221,6 +221,8 @@ export const LogMessages = {
|
|
|
221
221
|
`Assign your new key to a role with "set role assignments", or create a new role with "create role"`,
|
|
222
222
|
failedCreate: (env: string, name: string) =>
|
|
223
223
|
`[${env}] Unable to create API key ${Logger.highlightText(name)}`,
|
|
224
|
+
failedUpdate: (env: string, name: string) =>
|
|
225
|
+
`[${env}] Unable to update API key ${Logger.highlightText(name)}`,
|
|
224
226
|
removed: (env: string, id: string) =>
|
|
225
227
|
`[${env}] Deleted API key ${Logger.highlightText(id)}`,
|
|
226
228
|
failedRemove: (env: string, id: string) =>
|
|
@@ -479,7 +481,7 @@ You could visit ${git.secretsUri} to check that you can see repository settings`
|
|
|
479
481
|
)}`,
|
|
480
482
|
addGitSecretsIntro: () =>
|
|
481
483
|
`We have ceated an API key that allows you to deploy your app image to a Contensis Block but we need you to add these details to your GitLab repository.`,
|
|
482
|
-
addGitSecretsHelp: (git: GitHelper, id
|
|
484
|
+
addGitSecretsHelp: (git: GitHelper, id?: string, secret?: string) =>
|
|
483
485
|
`Add secrets or variables in your repository's settings page\n\nGo to ${Logger.highlightText(
|
|
484
486
|
git.secretsUri
|
|
485
487
|
)}\n\n${
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
export type OutputFormat = 'json' | 'csv' | 'xml';
|
|
3
|
+
|
|
4
|
+
export type OutputOptions = {
|
|
5
|
+
format?: OutputFormat;
|
|
6
|
+
output?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export interface IConnectOptions extends IAuthOptions {
|
|
10
|
+
alias?: string;
|
|
11
|
+
projectId?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IAuthOptions {
|
|
15
|
+
user?: string;
|
|
16
|
+
password?: string;
|
|
17
|
+
clientId?: string;
|
|
18
|
+
sharedSecret?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IImportOptions {
|
|
22
|
+
sourceAlias?: string;
|
|
23
|
+
sourceProjectId?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type OutputOptionsConstructorArg = OutputOptions &
|
|
27
|
+
IConnectOptions &
|
|
28
|
+
IImportOptions;
|
|
29
|
+
|
|
30
|
+
export interface ContensisCliConstructor {
|
|
31
|
+
new (
|
|
32
|
+
args: string[],
|
|
33
|
+
outputOpts?: OutputOptionsConstructorArg,
|
|
34
|
+
contensisOpts?: Partial<MigrateRequest>
|
|
35
|
+
): ContensisCli;
|
|
36
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import fetch from 'node-fetch';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
1
|
import to from 'await-to-js';
|
|
6
2
|
import chalk from 'chalk';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import fetch from 'node-fetch';
|
|
6
|
+
import path from 'path';
|
|
7
7
|
|
|
8
8
|
import { Component, ContentType, Project } from 'contensis-core-api';
|
|
9
|
+
import { Node } from 'contensis-delivery-api/lib/models';
|
|
9
10
|
import { Entry, Role } from 'contensis-management-api/lib/models';
|
|
10
11
|
import {
|
|
11
12
|
ContensisMigrationService,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
import ContensisAuthService from './ContensisAuthService';
|
|
23
24
|
|
|
24
25
|
import { LogMessages } from '~/localisation/en-GB';
|
|
26
|
+
import { OutputFormat, OutputOptionsConstructorArg } from '~/models/CliService';
|
|
25
27
|
|
|
26
28
|
import { readJsonFile } from '~/providers/file-provider';
|
|
27
29
|
import SessionCacheProvider from '../providers/SessionCacheProvider';
|
|
@@ -47,42 +49,8 @@ import { jsonFormatter } from '~/util/json.formatter';
|
|
|
47
49
|
import { diffLogStrings } from '~/util/diff';
|
|
48
50
|
import { logError, Logger } from '~/util/logger';
|
|
49
51
|
import { promiseDelay } from '~/util/timers';
|
|
52
|
+
import { findByIdOrName } from '~/util/find';
|
|
50
53
|
|
|
51
|
-
type OutputFormat = 'json' | 'csv' | 'xml';
|
|
52
|
-
|
|
53
|
-
type OutputOptions = {
|
|
54
|
-
format?: OutputFormat;
|
|
55
|
-
output?: string;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
interface IConnectOptions extends IAuthOptions {
|
|
59
|
-
alias?: string;
|
|
60
|
-
projectId?: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
interface IAuthOptions {
|
|
64
|
-
user?: string;
|
|
65
|
-
password?: string;
|
|
66
|
-
clientId?: string;
|
|
67
|
-
sharedSecret?: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
interface IImportOptions {
|
|
71
|
-
sourceAlias?: string;
|
|
72
|
-
sourceProjectId?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export type OutputOptionsConstructorArg = OutputOptions &
|
|
76
|
-
IConnectOptions &
|
|
77
|
-
IImportOptions;
|
|
78
|
-
|
|
79
|
-
export interface ContensisCliConstructor {
|
|
80
|
-
new (
|
|
81
|
-
args: string[],
|
|
82
|
-
outputOpts?: OutputOptionsConstructorArg,
|
|
83
|
-
contensisOpts?: Partial<MigrateRequest>
|
|
84
|
-
): ContensisCli;
|
|
85
|
-
}
|
|
86
54
|
let insecurePasswordWarningShown = false;
|
|
87
55
|
|
|
88
56
|
class ContensisCli {
|
|
@@ -937,15 +905,7 @@ class ContensisCli {
|
|
|
937
905
|
if (Array.isArray(roles)) {
|
|
938
906
|
log.success(messages.roles.list(currentEnv));
|
|
939
907
|
|
|
940
|
-
const role =
|
|
941
|
-
roles.find(
|
|
942
|
-
r =>
|
|
943
|
-
r.id === roleNameOrId ||
|
|
944
|
-
r.name.toLowerCase() === roleNameOrId.toLowerCase()
|
|
945
|
-
) ||
|
|
946
|
-
roles.find(r =>
|
|
947
|
-
r.name.toLowerCase().includes(roleNameOrId.toLowerCase())
|
|
948
|
-
);
|
|
908
|
+
const role = findByIdOrName(roles, roleNameOrId);
|
|
949
909
|
|
|
950
910
|
if (role) this.HandleFormattingAndOutput(role, log.object);
|
|
951
911
|
else log.error(messages.roles.failedGet(currentEnv, roleNameOrId));
|
|
@@ -996,11 +956,7 @@ class ContensisCli {
|
|
|
996
956
|
if (Array.isArray(roles)) {
|
|
997
957
|
log.success(messages.roles.list(currentEnv));
|
|
998
958
|
|
|
999
|
-
const existingRole = roles
|
|
1000
|
-
r =>
|
|
1001
|
-
r.id === roleNameOrId ||
|
|
1002
|
-
r.name.toLowerCase() === roleNameOrId.toLowerCase()
|
|
1003
|
-
);
|
|
959
|
+
const existingRole = findByIdOrName(roles, roleNameOrId, true);
|
|
1004
960
|
if (existingRole) {
|
|
1005
961
|
log.info(messages.roles.setPayload());
|
|
1006
962
|
log.object(role);
|
|
@@ -1040,11 +996,8 @@ class ContensisCli {
|
|
|
1040
996
|
if (Array.isArray(roles)) {
|
|
1041
997
|
log.success(messages.roles.list(currentEnv));
|
|
1042
998
|
|
|
1043
|
-
const existingRole = roles
|
|
1044
|
-
|
|
1045
|
-
r.id === roleNameOrId ||
|
|
1046
|
-
r.name.toLowerCase() === roleNameOrId.toLowerCase()
|
|
1047
|
-
);
|
|
999
|
+
const existingRole = findByIdOrName(roles, roleNameOrId, true);
|
|
1000
|
+
|
|
1048
1001
|
if (existingRole) {
|
|
1049
1002
|
const [deleteErr] = await contensis.roles.RemoveRole(existingRole.id);
|
|
1050
1003
|
|
|
@@ -1737,12 +1690,45 @@ class ContensisCli {
|
|
|
1737
1690
|
log.error(messages.nodes.failedGet(currentProject), err);
|
|
1738
1691
|
return;
|
|
1739
1692
|
}
|
|
1740
|
-
const
|
|
1693
|
+
const root = contensis.content.sourceRepo.nodes.tree;
|
|
1741
1694
|
|
|
1742
1695
|
log.success(messages.nodes.get(currentProject, rootPath, depth));
|
|
1743
|
-
|
|
1696
|
+
|
|
1697
|
+
const outputNode = (node: Node | any, spaces: string) =>
|
|
1698
|
+
`${node.entry ? log.highlightText('e') : log.infoText('-')}${
|
|
1699
|
+
node.isCanonical ? log.highlightText('c') : log.infoText('-')
|
|
1700
|
+
}${
|
|
1701
|
+
node.includeInMenu ? log.highlightText('m') : log.infoText('-')
|
|
1702
|
+
}${spaces}${
|
|
1703
|
+
node.isCanonical ? log.boldText(`/${node.slug}`) : `/${node.slug}`
|
|
1704
|
+
}${node.entry ? ` ${log.helpText(node.entry.sys.contentTypeId)}` : ''}${
|
|
1705
|
+
node.childCount ? ` +${node.childCount}` : ``
|
|
1706
|
+
} ${log.infoText(node.displayName)}`;
|
|
1707
|
+
|
|
1708
|
+
this.HandleFormattingAndOutput(root, () => {
|
|
1744
1709
|
// print the nodes to console
|
|
1745
|
-
log.object(
|
|
1710
|
+
log.object({ ...root, children: undefined });
|
|
1711
|
+
log.raw('');
|
|
1712
|
+
log.info(
|
|
1713
|
+
`${log.highlightText('e')} = has entry; ${log.highlightText(
|
|
1714
|
+
'c'
|
|
1715
|
+
)} = canonical; ${log.highlightText('m')} = include in menu`
|
|
1716
|
+
);
|
|
1717
|
+
log.line();
|
|
1718
|
+
const outputChildren = (root: Node | undefined, depth = 2) => {
|
|
1719
|
+
let str = '';
|
|
1720
|
+
for (const node of (root as any)?.children as Node[]) {
|
|
1721
|
+
str += `${outputNode(node, Array(depth + 1).join(' '))}\n`;
|
|
1722
|
+
if ('children' in node) str += outputChildren(node, depth + 1);
|
|
1723
|
+
}
|
|
1724
|
+
return str;
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1727
|
+
const children = outputChildren(root);
|
|
1728
|
+
log.limits(
|
|
1729
|
+
`${outputNode(root, ' ')}${children ? `\n${children}` : ''}`,
|
|
1730
|
+
100
|
|
1731
|
+
);
|
|
1746
1732
|
});
|
|
1747
1733
|
} else {
|
|
1748
1734
|
log.warning(messages.models.noList(currentProject));
|
|
@@ -2218,7 +2204,9 @@ class ContensisCli {
|
|
|
2218
2204
|
const contensis = await this.ConnectContensis();
|
|
2219
2205
|
if (contensis) {
|
|
2220
2206
|
// Retrieve proxies list for env
|
|
2221
|
-
const [err, proxies] = await contensis.proxies.GetProxies(
|
|
2207
|
+
const [err, proxies] = await (contensis.proxies.GetProxies as any)(
|
|
2208
|
+
proxyId
|
|
2209
|
+
); // TODO: resolve any cast;
|
|
2222
2210
|
|
|
2223
2211
|
if (Array.isArray(proxies)) {
|
|
2224
2212
|
this.HandleFormattingAndOutput(proxies, () => {
|
|
@@ -2230,7 +2218,9 @@ class ContensisCli {
|
|
|
2230
2218
|
version.versionNo
|
|
2231
2219
|
}] ${id} ${log.infoText`${description}`}`
|
|
2232
2220
|
);
|
|
2233
|
-
for (const [language, endpoint] of Object.entries(
|
|
2221
|
+
for (const [language, endpoint] of Object.entries(
|
|
2222
|
+
endpoints as { [k: string]: any }
|
|
2223
|
+
)) // TODO: resolve any cast
|
|
2234
2224
|
console.log(
|
|
2235
2225
|
` - ${log.infoText`language: ${language}
|
|
2236
2226
|
server: ${endpoint.server}
|
|
@@ -2253,9 +2243,9 @@ class ContensisCli {
|
|
|
2253
2243
|
const contensis = await this.ConnectContensis();
|
|
2254
2244
|
if (contensis) {
|
|
2255
2245
|
// Retrieve renderers list for env
|
|
2256
|
-
const [err, renderers] = await contensis.renderers.GetRenderers(
|
|
2246
|
+
const [err, renderers] = await (contensis.renderers.GetRenderers as any)(
|
|
2257
2247
|
rendererId
|
|
2258
|
-
);
|
|
2248
|
+
); // TODO: resolve any cast
|
|
2259
2249
|
|
|
2260
2250
|
if (Array.isArray(renderers)) {
|
|
2261
2251
|
this.HandleFormattingAndOutput(renderers, () => {
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
+
import to from 'await-to-js';
|
|
1
2
|
import { execFile, spawn } from 'child_process';
|
|
2
3
|
import inquirer from 'inquirer';
|
|
3
4
|
import path from 'path';
|
|
5
|
+
import { Entry, Role } from 'contensis-management-api/lib/models';
|
|
4
6
|
|
|
5
7
|
import { MigrateRequest } from 'migratortron';
|
|
6
8
|
import { stringify } from 'yaml';
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
} from './ContensisCliService';
|
|
9
|
+
import ContensisCli from './ContensisCliService';
|
|
10
|
+
import ContensisRole from './ContensisRoleService';
|
|
11
|
+
import { OutputOptionsConstructorArg } from '~/models/CliService';
|
|
11
12
|
import { mapSiteConfigYaml } from '~/mappers/ContensisCliService-to-RequestHanderSiteConfigYaml';
|
|
12
|
-
import { appRootDir, writeFile } from '~/providers/file-provider';
|
|
13
|
+
import { appRootDir, readFile, writeFile } from '~/providers/file-provider';
|
|
13
14
|
import { jsonFormatter } from '~/util/json.formatter';
|
|
14
15
|
import { GitHelper } from '~/util/git';
|
|
16
|
+
import { findByIdOrName } from '~/util/find';
|
|
15
17
|
|
|
16
|
-
class ContensisDev extends
|
|
18
|
+
class ContensisDev extends ContensisRole {
|
|
17
19
|
constructor(
|
|
18
20
|
args: string[],
|
|
19
21
|
outputOpts?: OutputOptionsConstructorArg,
|
|
@@ -23,6 +25,7 @@ class ContensisDev extends ContensisCli {
|
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
DevelopmentInit = async (projectHome: string, opts: any) => {
|
|
28
|
+
const { dryRun = false } = opts || {};
|
|
26
29
|
const { currentEnv, currentProject, log, messages } = this;
|
|
27
30
|
const contensis = await this.ConnectContensis();
|
|
28
31
|
|
|
@@ -45,12 +48,23 @@ class ContensisDev extends ContensisCli {
|
|
|
45
48
|
// Retrieve ci workflow info
|
|
46
49
|
const workflowFiles = git.workflows;
|
|
47
50
|
|
|
48
|
-
// Set variables for logging etc.
|
|
51
|
+
// Set variables for performing operations and logging etc.
|
|
49
52
|
let ciFileName = git.ciFileName;
|
|
50
53
|
|
|
51
|
-
const
|
|
52
|
-
const
|
|
54
|
+
const devKeyName = `${git.name} development`;
|
|
55
|
+
const devKeyDescription = `${git.name} [contensis-cli]`;
|
|
56
|
+
const devKeyPermissions = { blocks: [] } as Partial<Role['permissions']>;
|
|
57
|
+
let existingDevKey = apiKeyExists(devKeyName);
|
|
58
|
+
|
|
59
|
+
const deployKeyName = `${git.name} deployment`;
|
|
60
|
+
const deployKeyDescription = `${git.name} deploy [contensis-cli]`;
|
|
61
|
+
const deployKeyPermissions = { blocks: ['push', 'release'] } as Partial<
|
|
62
|
+
Role['permissions']
|
|
63
|
+
>;
|
|
64
|
+
let existingDeployKey = apiKeyExists(deployKeyName);
|
|
65
|
+
|
|
53
66
|
const blockId = git.name;
|
|
67
|
+
const errors = [] as AppError[];
|
|
54
68
|
|
|
55
69
|
// Start render console output
|
|
56
70
|
log.raw('');
|
|
@@ -68,12 +82,12 @@ class ContensisDev extends ContensisCli {
|
|
|
68
82
|
);
|
|
69
83
|
log.raw(
|
|
70
84
|
log.infoText(
|
|
71
|
-
messages.devinit.developmentKey(
|
|
85
|
+
messages.devinit.developmentKey(devKeyName, !!existingDevKey)
|
|
72
86
|
)
|
|
73
87
|
);
|
|
74
88
|
log.raw(
|
|
75
89
|
log.infoText(
|
|
76
|
-
messages.devinit.deploymentKey(
|
|
90
|
+
messages.devinit.deploymentKey(deployKeyName, !!existingDeployKey)
|
|
77
91
|
)
|
|
78
92
|
);
|
|
79
93
|
log.raw('');
|
|
@@ -95,7 +109,7 @@ class ContensisDev extends ContensisCli {
|
|
|
95
109
|
}
|
|
96
110
|
|
|
97
111
|
log.raw(log.infoText(messages.devinit.ciDetails(ciFileName)));
|
|
98
|
-
|
|
112
|
+
ylog.help(messages.devinit.ciIntro(git));
|
|
99
113
|
|
|
100
114
|
// Confirm prompt
|
|
101
115
|
const { confirm } = await inquirer.prompt([
|
|
@@ -120,25 +134,131 @@ class ContensisDev extends ContensisCli {
|
|
|
120
134
|
log.raw('');
|
|
121
135
|
|
|
122
136
|
// Magic happens...
|
|
137
|
+
const checkpoint = (op: string) => {
|
|
138
|
+
if (errors.length) throw errors[0];
|
|
139
|
+
else log.debug(`${op} completed ok`);
|
|
140
|
+
return true;
|
|
141
|
+
};
|
|
123
142
|
|
|
124
143
|
// Arrange API keys for development and deployment
|
|
125
|
-
|
|
126
|
-
|
|
144
|
+
const [getRolesErr, roles] = await to(contensis.roles.GetRoles());
|
|
145
|
+
if (!roles && getRolesErr) errors.push(getRolesErr);
|
|
146
|
+
checkpoint(`fetched ${roles?.length} roles`);
|
|
147
|
+
if (dryRun) {
|
|
148
|
+
checkpoint(`skip api key creation (dry-run)`);
|
|
149
|
+
} else {
|
|
150
|
+
existingDevKey = await this.CreateOrUpdateApiKey(
|
|
151
|
+
existingDevKey,
|
|
152
|
+
devKeyName,
|
|
153
|
+
devKeyDescription
|
|
154
|
+
);
|
|
155
|
+
checkpoint('dev key created');
|
|
156
|
+
|
|
157
|
+
existingDeployKey = await this.CreateOrUpdateApiKey(
|
|
158
|
+
existingDeployKey,
|
|
159
|
+
deployKeyName,
|
|
160
|
+
deployKeyDescription
|
|
161
|
+
);
|
|
162
|
+
checkpoint('deploy key created');
|
|
163
|
+
|
|
164
|
+
// Ensure dev API key is assigned to a role
|
|
165
|
+
let existingDevRole = findByIdOrName(roles || [], devKeyName, true) as
|
|
166
|
+
| Role
|
|
167
|
+
| undefined;
|
|
168
|
+
existingDevRole = await this.CreateOrUpdateRole(
|
|
169
|
+
existingDevRole,
|
|
170
|
+
devKeyName,
|
|
171
|
+
devKeyDescription,
|
|
172
|
+
{ apiKeys: [devKeyName] },
|
|
173
|
+
devKeyPermissions
|
|
174
|
+
);
|
|
175
|
+
checkpoint('dev key role assigned');
|
|
176
|
+
log.success(messages.devinit.createDevKey(devKeyName, true));
|
|
177
|
+
|
|
178
|
+
// Ensure deploy API key is assigned to a role with the right permissions
|
|
179
|
+
let existingDeployRole = findByIdOrName(
|
|
180
|
+
roles || [],
|
|
181
|
+
deployKeyName,
|
|
182
|
+
true
|
|
183
|
+
) as Role | undefined;
|
|
184
|
+
existingDeployRole = await this.CreateOrUpdateRole(
|
|
185
|
+
existingDeployRole,
|
|
186
|
+
deployKeyName,
|
|
187
|
+
deployKeyDescription,
|
|
188
|
+
{ apiKeys: [deployKeyName] },
|
|
189
|
+
deployKeyPermissions
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
checkpoint('deploy key role assigned');
|
|
193
|
+
log.success(messages.devinit.createDeployKey(deployKeyName, true));
|
|
194
|
+
checkpoint('api keys done');
|
|
195
|
+
}
|
|
127
196
|
|
|
128
197
|
// Update or create a file called .env in project home
|
|
129
|
-
|
|
130
|
-
|
|
198
|
+
const envContents = {
|
|
199
|
+
ALIAS: currentEnv,
|
|
200
|
+
PROJECT: currentProject,
|
|
201
|
+
ACCESS_TOKEN: accessToken,
|
|
202
|
+
};
|
|
203
|
+
const envFilePath = `${projectHome}/.env`;
|
|
204
|
+
const existingEnvFile = readFile(envFilePath);
|
|
205
|
+
const existingFileLines = (existingEnvFile || '').split('\n');
|
|
206
|
+
const envFileLines: string[] = [];
|
|
207
|
+
|
|
208
|
+
const updatedEnvKeys: string[] = [];
|
|
209
|
+
for (const ln of existingFileLines) {
|
|
210
|
+
let newline = '';
|
|
211
|
+
for (const [k, v] of Object.entries(envContents))
|
|
212
|
+
if (ln.startsWith(`${k}=`)) {
|
|
213
|
+
newline = `${k}=${v}`;
|
|
214
|
+
updatedEnvKeys.push(k);
|
|
215
|
+
}
|
|
216
|
+
envFileLines.push(newline || ln);
|
|
217
|
+
}
|
|
218
|
+
for (const addKey of existingFileLines
|
|
219
|
+
.filter(
|
|
220
|
+
efl =>
|
|
221
|
+
!updatedEnvKeys.find(uek =>
|
|
222
|
+
uek.startsWith(`${efl.split('=')?.[0]}=`)
|
|
223
|
+
) && Object.keys(envContents).find(ck => ck === efl.split('=')?.[0])
|
|
224
|
+
)
|
|
225
|
+
.map(fl => fl.split('=')?.[0]) as (keyof typeof envContents)[]) {
|
|
226
|
+
envFileLines.push(`${addKey}=${envContents[addKey]}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (dryRun) {
|
|
230
|
+
checkpoint('skip .env file update (dry-run)');
|
|
231
|
+
log.info(`.env file`);
|
|
232
|
+
log.object(envFileLines);
|
|
233
|
+
} else {
|
|
234
|
+
writeFile(envFilePath, envFileLines.join('\n'));
|
|
235
|
+
checkpoint('.env file updated');
|
|
236
|
+
log.success(messages.devinit.writeEnvFile());
|
|
237
|
+
// log.help(messages.devinit.useEnvFileTip());
|
|
238
|
+
}
|
|
131
239
|
|
|
132
240
|
// Update CI file -- different for GH/GL -- create a sample one with build?
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
241
|
+
if (dryRun) {
|
|
242
|
+
checkpoint('skip CI file update (dry-run)');
|
|
243
|
+
log.info(`${ciFileName} file`);
|
|
244
|
+
// TODO: log what we might add to the file
|
|
245
|
+
//log.object(envFileLines);
|
|
246
|
+
} else {
|
|
247
|
+
log.success(messages.devinit.writeCiFile(`./${ciFileName}`));
|
|
248
|
+
log.info(
|
|
249
|
+
messages.devinit.ciBlockTip(blockId, currentEnv, currentProject)
|
|
250
|
+
);
|
|
251
|
+
checkpoint('CI file updated');
|
|
252
|
+
}
|
|
137
253
|
|
|
138
254
|
// Echo Deployment API key to console, ask user to add secrets to repo
|
|
139
255
|
log.warning(messages.devinit.addGitSecretsIntro());
|
|
140
256
|
log.help(
|
|
141
|
-
messages.devinit.addGitSecretsHelp(
|
|
257
|
+
messages.devinit.addGitSecretsHelp(
|
|
258
|
+
git,
|
|
259
|
+
existingDeployKey?.id,
|
|
260
|
+
existingDeployKey?.sharedSecret
|
|
261
|
+
)
|
|
142
262
|
);
|
|
143
263
|
|
|
144
264
|
log.success(messages.devinit.success());
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Role } from 'contensis-management-api/lib/models';
|
|
2
|
+
import { ApiKey, MigrateRequest } from 'migratortron';
|
|
3
|
+
|
|
4
|
+
import ContensisCli from './ContensisCliService';
|
|
5
|
+
import { OutputOptionsConstructorArg } from '~/models/CliService';
|
|
6
|
+
|
|
7
|
+
class ContensisRole extends ContensisCli {
|
|
8
|
+
constructor(
|
|
9
|
+
args: string[],
|
|
10
|
+
outputOpts?: OutputOptionsConstructorArg,
|
|
11
|
+
contensisOpts: Partial<MigrateRequest> = {}
|
|
12
|
+
) {
|
|
13
|
+
super(args, outputOpts, contensisOpts);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
CreateOrUpdateApiKey = async (
|
|
17
|
+
existingKey: ApiKey | undefined,
|
|
18
|
+
name: string,
|
|
19
|
+
description: string
|
|
20
|
+
) => {
|
|
21
|
+
const { contensis, currentEnv, messages } = this;
|
|
22
|
+
if (!contensis) throw new Error('shouldnt be here');
|
|
23
|
+
if (existingKey) {
|
|
24
|
+
const [err, key] = await contensis.apiKeys.UpdateKey(existingKey.id, {
|
|
25
|
+
name,
|
|
26
|
+
description,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (err)
|
|
30
|
+
throw new Error(messages.keys.failedUpdate(currentEnv, name), {
|
|
31
|
+
cause: err,
|
|
32
|
+
});
|
|
33
|
+
return key;
|
|
34
|
+
} else {
|
|
35
|
+
const [err, key] = await contensis.apiKeys.CreateKey(name, description);
|
|
36
|
+
if (err)
|
|
37
|
+
throw new Error(messages.keys.failedCreate(currentEnv, name), {
|
|
38
|
+
cause: err,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return key;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
CreateOrUpdateRole = async (
|
|
46
|
+
existingRole: Role | undefined,
|
|
47
|
+
name: string,
|
|
48
|
+
description: string,
|
|
49
|
+
assignments: Role['assignments'],
|
|
50
|
+
permissions: Role['permissions']
|
|
51
|
+
) => {
|
|
52
|
+
const { contensis, currentEnv, messages } = this;
|
|
53
|
+
if (!contensis) throw new Error('shouldnt be here');
|
|
54
|
+
|
|
55
|
+
if (existingRole) {
|
|
56
|
+
// TODO: check is update needed?
|
|
57
|
+
const [err, updated] = await contensis.roles.UpdateRole(existingRole.id, {
|
|
58
|
+
...existingRole,
|
|
59
|
+
assignments,
|
|
60
|
+
permissions,
|
|
61
|
+
});
|
|
62
|
+
if (err)
|
|
63
|
+
throw new Error(messages.roles.failedSet(currentEnv, name), {
|
|
64
|
+
cause: err,
|
|
65
|
+
});
|
|
66
|
+
return updated;
|
|
67
|
+
} else {
|
|
68
|
+
const [err, created] = await contensis.roles.CreateRole({
|
|
69
|
+
name,
|
|
70
|
+
description,
|
|
71
|
+
enabled: true,
|
|
72
|
+
assignments,
|
|
73
|
+
permissions,
|
|
74
|
+
} as Role);
|
|
75
|
+
if (err)
|
|
76
|
+
throw new Error(messages.roles.failedCreate(currentEnv, name), {
|
|
77
|
+
cause: err,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return created;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export default ContensisRole;
|
package/src/util/find.ts
ADDED
package/src/util/logger.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import dateFormat from 'dateformat';
|
|
4
4
|
import deepCleaner from 'deep-cleaner';
|
|
5
|
+
import { ansiEscapeCodes, first, strlen } from 'printable-characters';
|
|
5
6
|
// import ProgressBar from 'progress';
|
|
6
7
|
import { isSysError, tryStringify } from '.';
|
|
7
8
|
|
|
@@ -88,6 +89,13 @@ export class Logger {
|
|
|
88
89
|
else console.log(message);
|
|
89
90
|
progress.current.interrupt(message);
|
|
90
91
|
};
|
|
92
|
+
static debug: LogMethod = content => {
|
|
93
|
+
const message = `${Logger.getPrefix()} ${
|
|
94
|
+
Logger.isUserTerminal ? chalk.bgGrey(' ⚙ ') : '[DEBUG]'
|
|
95
|
+
} ${Logger.infoText(content)}`;
|
|
96
|
+
if (progress.active) progress.current.interrupt(message);
|
|
97
|
+
else console.log(message);
|
|
98
|
+
};
|
|
91
99
|
static json: LogJsonDepthMethod = (content, depth = 9) =>
|
|
92
100
|
console.dir(deepCleaner(content), { colors: true, depth });
|
|
93
101
|
static mixed: LogArrayMethod = contentArray =>
|
|
@@ -214,6 +222,26 @@ export class Logger {
|
|
|
214
222
|
if (progress.active) progress.current.interrupt(content);
|
|
215
223
|
else console.log(content);
|
|
216
224
|
};
|
|
225
|
+
|
|
226
|
+
static limits = (content: string, displayLength = 30) => {
|
|
227
|
+
const consoleWidth = process.stdout.columns;
|
|
228
|
+
console.info(
|
|
229
|
+
consoleWidth
|
|
230
|
+
? content
|
|
231
|
+
.split('\n')
|
|
232
|
+
.slice(0, consoleWidth ? displayLength : undefined)
|
|
233
|
+
.map((line: string) =>
|
|
234
|
+
consoleWidth && strlen(line) > consoleWidth
|
|
235
|
+
? first(line, consoleWidth)
|
|
236
|
+
: line
|
|
237
|
+
)
|
|
238
|
+
.join('\n')
|
|
239
|
+
: content.replace(ansiEscapeCodes, '')
|
|
240
|
+
);
|
|
241
|
+
const tableArray = content.split('\n');
|
|
242
|
+
if (consoleWidth && tableArray.length > displayLength)
|
|
243
|
+
console.info(`\n`, `- and ${tableArray.length - displayLength} more...`);
|
|
244
|
+
};
|
|
217
245
|
}
|
|
218
246
|
|
|
219
247
|
export const logError: LogErrorFunc = (
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const LIB_VERSION = "1.0.0-beta.
|
|
1
|
+
export const LIB_VERSION = "1.0.0-beta.89";
|