contensis-cli 1.0.0-beta.5
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/.vscode/launch.json +15 -0
- package/README.md +631 -0
- package/cli.js +7 -0
- package/dist/commands/connect.js +44 -0
- package/dist/commands/connect.js.map +7 -0
- package/dist/commands/create.js +55 -0
- package/dist/commands/create.js.map +7 -0
- package/dist/commands/get.js +121 -0
- package/dist/commands/get.js.map +7 -0
- package/dist/commands/globalOptions.js +139 -0
- package/dist/commands/globalOptions.js.map +7 -0
- package/dist/commands/import.js +95 -0
- package/dist/commands/import.js.map +7 -0
- package/dist/commands/index.js +81 -0
- package/dist/commands/index.js.map +7 -0
- package/dist/commands/list.js +88 -0
- package/dist/commands/list.js.map +7 -0
- package/dist/commands/login.js +56 -0
- package/dist/commands/login.js.map +7 -0
- package/dist/commands/push.js +133 -0
- package/dist/commands/push.js.map +7 -0
- package/dist/commands/remove.js +77 -0
- package/dist/commands/remove.js.map +7 -0
- package/dist/commands/set.js +55 -0
- package/dist/commands/set.js.map +7 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +7 -0
- package/dist/localisation/en-GB.js +203 -0
- package/dist/localisation/en-GB.js.map +7 -0
- package/dist/models/AppError.d.js +2 -0
- package/dist/models/AppError.d.js.map +7 -0
- package/dist/models/Cache.d.js +2 -0
- package/dist/models/Cache.d.js.map +7 -0
- package/dist/models/JsModules.d.js +2 -0
- package/dist/models/JsModules.d.js.map +7 -0
- package/dist/providers/CredentialProvider.js +87 -0
- package/dist/providers/CredentialProvider.js.map +7 -0
- package/dist/providers/SessionCacheProvider.js +91 -0
- package/dist/providers/SessionCacheProvider.js.map +7 -0
- package/dist/providers/file-provider.js +113 -0
- package/dist/providers/file-provider.js.map +7 -0
- package/dist/services/ContensisAuthService.js +75 -0
- package/dist/services/ContensisAuthService.js.map +7 -0
- package/dist/services/ContensisCliService.js +1110 -0
- package/dist/services/ContensisCliService.js.map +7 -0
- package/dist/shell.js +261 -0
- package/dist/shell.js.map +7 -0
- package/dist/util/console.printer.js +194 -0
- package/dist/util/console.printer.js.map +7 -0
- package/dist/util/csv.formatter.js +50 -0
- package/dist/util/csv.formatter.js.map +7 -0
- package/dist/util/index.js +94 -0
- package/dist/util/index.js.map +7 -0
- package/dist/util/json.formatter.js +29 -0
- package/dist/util/json.formatter.js.map +7 -0
- package/dist/util/logger.js +184 -0
- package/dist/util/logger.js.map +7 -0
- package/dist/util/xml.formatter.js +51 -0
- package/dist/util/xml.formatter.js.map +7 -0
- package/dist/version.js +29 -0
- package/dist/version.js.map +7 -0
- package/esbuild.config.js +49 -0
- package/headless-setup.sh +7 -0
- package/package.json +59 -0
- package/patches/inquirer-command-prompt+0.1.0.patch +27 -0
- package/src/commands/connect.ts +23 -0
- package/src/commands/create.ts +41 -0
- package/src/commands/get.ts +139 -0
- package/src/commands/globalOptions.ts +126 -0
- package/src/commands/import.ts +89 -0
- package/src/commands/index.ts +72 -0
- package/src/commands/list.ts +90 -0
- package/src/commands/login.ts +33 -0
- package/src/commands/push.ts +120 -0
- package/src/commands/remove.ts +77 -0
- package/src/commands/set.ts +40 -0
- package/src/index.ts +19 -0
- package/src/localisation/en-GB.ts +211 -0
- package/src/models/AppError.d.ts +40 -0
- package/src/models/Cache.d.ts +25 -0
- package/src/models/JsModules.d.ts +1 -0
- package/src/providers/CredentialProvider.ts +88 -0
- package/src/providers/SessionCacheProvider.ts +74 -0
- package/src/providers/file-provider.ts +72 -0
- package/src/services/ContensisAuthService.ts +70 -0
- package/src/services/ContensisCliService.ts +1390 -0
- package/src/shell.ts +250 -0
- package/src/util/console.printer.ts +203 -0
- package/src/util/csv.formatter.ts +21 -0
- package/src/util/index.ts +67 -0
- package/src/util/json.formatter.ts +1 -0
- package/src/util/logger.ts +165 -0
- package/src/util/xml.formatter.ts +20 -0
- package/src/version.ts +1 -0
- package/tsconfig.json +22 -0
package/src/shell.ts
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import figlet from 'figlet';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import inquirerPrompt from 'inquirer-command-prompt';
|
|
5
|
+
import commands from './commands';
|
|
6
|
+
import { LogMessages } from './localisation/en-GB';
|
|
7
|
+
import { logError, Logger } from './util/logger';
|
|
8
|
+
import CredentialProvider from './providers/CredentialProvider';
|
|
9
|
+
import ContensisCli, { cliCommand } from './services/ContensisCliService';
|
|
10
|
+
import { Logging } from './util';
|
|
11
|
+
|
|
12
|
+
class ContensisShell {
|
|
13
|
+
private currentEnvironment!: string;
|
|
14
|
+
private emptyInputCounter: number = 0;
|
|
15
|
+
private env!: EnvironmentCache;
|
|
16
|
+
private firstStart = true;
|
|
17
|
+
private userId: string = '';
|
|
18
|
+
private log = Logger;
|
|
19
|
+
private messages = LogMessages;
|
|
20
|
+
|
|
21
|
+
private refreshEnvironment = () => {
|
|
22
|
+
// Reload any persisted changes from the disk cache
|
|
23
|
+
const {
|
|
24
|
+
cache: { currentEnvironment = '', environments = {} },
|
|
25
|
+
} = new ContensisCli([]);
|
|
26
|
+
// console.log(`refreshing env w/${currentEnvironment}`);
|
|
27
|
+
this.currentEnvironment = currentEnvironment;
|
|
28
|
+
this.env = environments[currentEnvironment];
|
|
29
|
+
|
|
30
|
+
// Reload logging here to support changing language
|
|
31
|
+
Logging('en-GB').then(({ messages, Log }) => {
|
|
32
|
+
this.log = Log;
|
|
33
|
+
this.messages = messages;
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
constructor() {
|
|
38
|
+
this.refreshEnvironment();
|
|
39
|
+
inquirerPrompt.setConfig({
|
|
40
|
+
history: {
|
|
41
|
+
save: true,
|
|
42
|
+
folder: path.join(__dirname, '../'),
|
|
43
|
+
limit: 100,
|
|
44
|
+
blacklist: ['quit'],
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
// inquirer.registerPrompt('command', inquirerPrompt);
|
|
48
|
+
|
|
49
|
+
const { log, messages } = this;
|
|
50
|
+
|
|
51
|
+
figlet.text(
|
|
52
|
+
messages.app.contensis(),
|
|
53
|
+
{
|
|
54
|
+
font: 'Block',
|
|
55
|
+
horizontalLayout: 'default',
|
|
56
|
+
verticalLayout: 'default',
|
|
57
|
+
width: process.stdout.columns,
|
|
58
|
+
whitespaceBreak: true,
|
|
59
|
+
},
|
|
60
|
+
(err, data) => {
|
|
61
|
+
if (err) {
|
|
62
|
+
log.error(messages.app.unknownError());
|
|
63
|
+
console.dir(err);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log(log.successText(data));
|
|
67
|
+
console.log(log.infoText(messages.app.startup()));
|
|
68
|
+
console.log(log.helpText(messages.app.help()));
|
|
69
|
+
|
|
70
|
+
this.start().catch(ex => log.error(ex));
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
start = async () => {
|
|
76
|
+
this.log.line();
|
|
77
|
+
this.refreshEnvironment();
|
|
78
|
+
this.userId = '';
|
|
79
|
+
const { currentEnvironment, env, log, messages } = this;
|
|
80
|
+
|
|
81
|
+
if (env?.lastUserId) {
|
|
82
|
+
const [credsErr, credentials] = await new CredentialProvider(
|
|
83
|
+
{
|
|
84
|
+
userId: env.lastUserId,
|
|
85
|
+
alias: currentEnvironment,
|
|
86
|
+
},
|
|
87
|
+
env.passwordFallback
|
|
88
|
+
).Init();
|
|
89
|
+
if (credsErr && !credentials.current) {
|
|
90
|
+
log.error(credsErr.message);
|
|
91
|
+
}
|
|
92
|
+
if (credentials.current) {
|
|
93
|
+
if (this.firstStart) {
|
|
94
|
+
const token = await cliCommand(['login', env.lastUserId]).Login(
|
|
95
|
+
env.lastUserId,
|
|
96
|
+
{
|
|
97
|
+
promptPassword: false,
|
|
98
|
+
silent: true,
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
if (token) this.userId = env.lastUserId;
|
|
102
|
+
this.firstStart = false;
|
|
103
|
+
this.refreshEnvironment();
|
|
104
|
+
} else {
|
|
105
|
+
this.userId = env.lastUserId;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
await this.contensisPrompt();
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
contensisPrompt = async (): Promise<any> => {
|
|
113
|
+
const { currentEnvironment, env, log, messages, userId } = this;
|
|
114
|
+
|
|
115
|
+
const availableCommands = [
|
|
116
|
+
{
|
|
117
|
+
filter: (str: string) => {
|
|
118
|
+
return str.replace(/ \[.*$/, '');
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
'connect',
|
|
122
|
+
'list envs',
|
|
123
|
+
'quit',
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
if (currentEnvironment)
|
|
127
|
+
availableCommands.push('login', 'list projects', 'set project');
|
|
128
|
+
if (userId)
|
|
129
|
+
availableCommands.push(
|
|
130
|
+
'get block',
|
|
131
|
+
'get block logs',
|
|
132
|
+
'get contenttype',
|
|
133
|
+
'get component',
|
|
134
|
+
'get entries',
|
|
135
|
+
'import contenttypes',
|
|
136
|
+
'import components',
|
|
137
|
+
'import entries',
|
|
138
|
+
'list blocks',
|
|
139
|
+
'list contenttypes',
|
|
140
|
+
'list components',
|
|
141
|
+
'list models',
|
|
142
|
+
'list keys',
|
|
143
|
+
'list webhooks',
|
|
144
|
+
'create key',
|
|
145
|
+
'push block',
|
|
146
|
+
'remove key',
|
|
147
|
+
'remove entry',
|
|
148
|
+
'remove contenttypes',
|
|
149
|
+
'remove components'
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const prompt = inquirer.createPromptModule();
|
|
153
|
+
prompt.registerPrompt('command', inquirerPrompt);
|
|
154
|
+
return prompt([
|
|
155
|
+
{
|
|
156
|
+
type: 'command',
|
|
157
|
+
name: 'cmd',
|
|
158
|
+
autoCompletion: availableCommands,
|
|
159
|
+
autocompletePrompt: log.infoText(messages.app.autocomplete()),
|
|
160
|
+
message: `${userId ? `${userId}@` : ''}${currentEnvironment || ''}>`,
|
|
161
|
+
context: 0,
|
|
162
|
+
validate: (val: string) => {
|
|
163
|
+
if (!val) this.emptyInputCounter++;
|
|
164
|
+
if (this.emptyInputCounter > 1)
|
|
165
|
+
console.log(this.log.infoText(this.messages.app.suggestions()));
|
|
166
|
+
if (val) {
|
|
167
|
+
this.emptyInputCounter = 0;
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
prefix: `${env?.currentProject || 'contensis'}`,
|
|
172
|
+
short: true,
|
|
173
|
+
},
|
|
174
|
+
])
|
|
175
|
+
.then(async (answers: { cmd: string }) => {
|
|
176
|
+
if (answers.cmd === 'quit') {
|
|
177
|
+
this.quit();
|
|
178
|
+
} else {
|
|
179
|
+
try {
|
|
180
|
+
if (answers.cmd) {
|
|
181
|
+
const program = commands();
|
|
182
|
+
await program.parseAsync(
|
|
183
|
+
answers.cmd
|
|
184
|
+
.match(/"[^"]+"|[^\s]+/g)
|
|
185
|
+
?.map(e => e.replace(/"(.+)"/, '$1')),
|
|
186
|
+
{
|
|
187
|
+
from: 'user',
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
} catch (ex: any) {
|
|
192
|
+
const str = ex.toString();
|
|
193
|
+
if (!str.includes('CommanderError'))
|
|
194
|
+
logError(ex, `Shell ${ex.toString()}`);
|
|
195
|
+
} finally {
|
|
196
|
+
return this.contensisPrompt();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
.catch((err: Error) => {
|
|
201
|
+
log.error(err.message);
|
|
202
|
+
this.quit();
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
quit = (error?: Error) => {
|
|
207
|
+
const { log, messages } = this;
|
|
208
|
+
process.removeAllListeners('exit');
|
|
209
|
+
|
|
210
|
+
if (error) {
|
|
211
|
+
log.error(error.message);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
} else {
|
|
214
|
+
log.success(messages.app.quit());
|
|
215
|
+
process.exitCode = 0;
|
|
216
|
+
process.exit(0);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
let globalShell: ContensisShell;
|
|
222
|
+
|
|
223
|
+
export const shell = () => {
|
|
224
|
+
if (typeof process.argv?.[2] !== 'undefined') return { start() {} } as any;
|
|
225
|
+
if (!globalShell) globalShell = new ContensisShell();
|
|
226
|
+
return globalShell;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
process.on('uncaughtException', function (err) {
|
|
230
|
+
// Handle the error safely
|
|
231
|
+
console.log(err);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
process.on('SIGINT', () => {
|
|
235
|
+
console.log('catching SIGINT');
|
|
236
|
+
shell().quit();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
process.on('SIGTERM', () => {
|
|
240
|
+
console.log('catching SIGTERM');
|
|
241
|
+
shell().quit();
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
process.stdin.on('data', key => {
|
|
245
|
+
if ((key as any) == '\u0003') {
|
|
246
|
+
console.log('');
|
|
247
|
+
Logger.info(`[CTRL]+[C] detected, exiting shell...`);
|
|
248
|
+
shell().quit();
|
|
249
|
+
}
|
|
250
|
+
});
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import { BlockVersion, MigrateStatus } from 'migratortron';
|
|
3
|
+
import ContensisCli from '~/services/ContensisCliService';
|
|
4
|
+
|
|
5
|
+
const formatDate = (date: Date | string, format = 'DD/MM/YYYY HH:mm') =>
|
|
6
|
+
dayjs(date).format(format);
|
|
7
|
+
|
|
8
|
+
export const printBlockVersion = (
|
|
9
|
+
{ log, messages }: ContensisCli,
|
|
10
|
+
block: BlockVersion,
|
|
11
|
+
printOptions = {
|
|
12
|
+
showSource: true,
|
|
13
|
+
showStatus: true,
|
|
14
|
+
showStaticPaths: true,
|
|
15
|
+
showImage: true,
|
|
16
|
+
}
|
|
17
|
+
) => {
|
|
18
|
+
console.log(
|
|
19
|
+
` ${log.standardText(`v${block.version.versionNo}`)} ${block.id}`
|
|
20
|
+
);
|
|
21
|
+
console.log(
|
|
22
|
+
` state: ${messages.blocks.runningStatus(
|
|
23
|
+
block.status.broken ? 'broken' : block.status.running.global
|
|
24
|
+
)}`
|
|
25
|
+
);
|
|
26
|
+
console.log(
|
|
27
|
+
` released: ${log.infoText(
|
|
28
|
+
block.version.released
|
|
29
|
+
? `[${formatDate(block.version.released)}] ${block.version.releasedBy}`
|
|
30
|
+
: 'no'
|
|
31
|
+
)}`
|
|
32
|
+
);
|
|
33
|
+
if (block.version.madeLive)
|
|
34
|
+
console.log(
|
|
35
|
+
` live: ${log.infoText(
|
|
36
|
+
`[${formatDate(block.version.madeLive)}] ${block.version.madeLiveBy}`
|
|
37
|
+
)}`
|
|
38
|
+
);
|
|
39
|
+
if (printOptions.showStatus) {
|
|
40
|
+
console.log(` status:`);
|
|
41
|
+
console.log(` deployment: ${log.infoText(block.status.deployment)}`);
|
|
42
|
+
console.log(` workflow: ${log.infoText(block.status.workflow)}`);
|
|
43
|
+
console.log(
|
|
44
|
+
` running status: ${messages.blocks.runningStatus(
|
|
45
|
+
block.status.running.global
|
|
46
|
+
)}`
|
|
47
|
+
);
|
|
48
|
+
console.log(` datacentres:`);
|
|
49
|
+
console.log(
|
|
50
|
+
` hq: ${messages.blocks.runningStatus(
|
|
51
|
+
block.status.running.dataCenters.hq
|
|
52
|
+
)}`
|
|
53
|
+
);
|
|
54
|
+
console.log(
|
|
55
|
+
` london: ${messages.blocks.runningStatus(
|
|
56
|
+
block.status.running.dataCenters.london
|
|
57
|
+
)}`
|
|
58
|
+
);
|
|
59
|
+
console.log(
|
|
60
|
+
` manchester: ${messages.blocks.runningStatus(
|
|
61
|
+
block.status.running.dataCenters.manchester
|
|
62
|
+
)}`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (printOptions.showSource) {
|
|
66
|
+
console.log(` source:`);
|
|
67
|
+
console.log(` commit: ${log.helpText(block.source.commit.id)}`);
|
|
68
|
+
console.log(
|
|
69
|
+
` message: ${log.infoText(
|
|
70
|
+
block.source.commit.message
|
|
71
|
+
?.replaceAll('\n', '\\n')
|
|
72
|
+
.replaceAll('\\n\\n', '\\n')
|
|
73
|
+
.replaceAll('\\n', '; ')
|
|
74
|
+
)}`
|
|
75
|
+
);
|
|
76
|
+
console.log(
|
|
77
|
+
` committed: ${log.infoText(
|
|
78
|
+
`[${formatDate(block.source.commit.dateTime)}] ${
|
|
79
|
+
block.source.commit.authorEmail
|
|
80
|
+
}`
|
|
81
|
+
)}`
|
|
82
|
+
);
|
|
83
|
+
console.log(
|
|
84
|
+
` pushed: ${log.infoText(
|
|
85
|
+
`[${formatDate(block.version.pushed)}] ${block.version.pushedBy}`
|
|
86
|
+
)}`
|
|
87
|
+
);
|
|
88
|
+
console.log(` ${log.infoText(block.source.commit.commitUrl)}`);
|
|
89
|
+
}
|
|
90
|
+
if (printOptions.showImage) {
|
|
91
|
+
console.log(` image:`);
|
|
92
|
+
console.log(` uri: ${log.infoText(block.image.uri)}`);
|
|
93
|
+
console.log(` tag: ${log.helpText(block.image.tag)}`);
|
|
94
|
+
}
|
|
95
|
+
if (printOptions.showStaticPaths) {
|
|
96
|
+
if (block.staticPaths?.length) {
|
|
97
|
+
console.log(` static paths:`);
|
|
98
|
+
for (const path of block.staticPaths) console.log(` - ${path}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (block.stagingUrl)
|
|
102
|
+
console.log(` staging url: ${log.infoText(block.stagingUrl)}`);
|
|
103
|
+
console.log('');
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const printMigrateResult = (
|
|
107
|
+
{ log, messages, contensis, currentProject }: ContensisCli,
|
|
108
|
+
migrateResult: any,
|
|
109
|
+
{ action = 'import' }: { action?: 'import' | 'delete' } = {}
|
|
110
|
+
) => {
|
|
111
|
+
console.log(``);
|
|
112
|
+
|
|
113
|
+
if (action === 'import') {
|
|
114
|
+
for (const [projectId, contentTypeCounts] of Object.entries(
|
|
115
|
+
migrateResult.entries || {}
|
|
116
|
+
) as [string, any][]) {
|
|
117
|
+
console.log(
|
|
118
|
+
`import from project ${log.highlightText(projectId)} to ${log.boldText(
|
|
119
|
+
log.successText(currentProject)
|
|
120
|
+
)}`
|
|
121
|
+
);
|
|
122
|
+
for (const [contentTypeId, count] of Object.entries(
|
|
123
|
+
contentTypeCounts
|
|
124
|
+
) as [string, number][]) {
|
|
125
|
+
const entriesToMigrate =
|
|
126
|
+
migrateResult.entriesToMigrate?.[projectId]?.[contentTypeId];
|
|
127
|
+
|
|
128
|
+
console.log(
|
|
129
|
+
` - ${
|
|
130
|
+
contentTypeId === 'totalCount'
|
|
131
|
+
? log.warningText(`${contentTypeId}: ${count}`)
|
|
132
|
+
: log.helpText(`${contentTypeId}: ${count}`)
|
|
133
|
+
} ${log.infoText`[existing: ${(
|
|
134
|
+
((migrateResult.existing?.[projectId]?.[contentTypeId] || 0) /
|
|
135
|
+
count) *
|
|
136
|
+
100
|
|
137
|
+
).toFixed(0)}%]`} [${
|
|
138
|
+
typeof entriesToMigrate !== 'number' ? `unchanged` : `to update`
|
|
139
|
+
}: ${(
|
|
140
|
+
((typeof entriesToMigrate !== 'number'
|
|
141
|
+
? entriesToMigrate?.['no change'] || 0
|
|
142
|
+
: entriesToMigrate) /
|
|
143
|
+
count) *
|
|
144
|
+
100
|
|
145
|
+
).toFixed(0)}%]`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
console.log(``);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (
|
|
152
|
+
contensis?.isPreview &&
|
|
153
|
+
migrateResult.entriesToMigrate?.[currentProject]?.totalCount > 0 &&
|
|
154
|
+
!migrateResult.errors
|
|
155
|
+
) {
|
|
156
|
+
log.help(messages.entries.commitTip());
|
|
157
|
+
}
|
|
158
|
+
for (const [contentTypeId, entryRes] of Object.entries(
|
|
159
|
+
migrateResult.entriesToMigrate.entryIds
|
|
160
|
+
) as [string, any]) {
|
|
161
|
+
for (const [originalId, entryStatus] of Object.entries(entryRes) as [
|
|
162
|
+
string,
|
|
163
|
+
any
|
|
164
|
+
][]) {
|
|
165
|
+
console.log(
|
|
166
|
+
log.infoText(
|
|
167
|
+
`${originalId} [${Object.entries(entryStatus || {})
|
|
168
|
+
.filter(x => x[0] !== 'entryTitle')
|
|
169
|
+
.map(([projectId, projectStatus]) => {
|
|
170
|
+
const [targetGuid, { status }] = (Object.entries(
|
|
171
|
+
projectStatus || {}
|
|
172
|
+
)?.[0] as [string, { status: MigrateStatus }]) || [
|
|
173
|
+
'',
|
|
174
|
+
{ x: { status: undefined } },
|
|
175
|
+
];
|
|
176
|
+
return `${messages.entries.migrateStatus(status)(
|
|
177
|
+
`${projectId}: ${status}`
|
|
178
|
+
)}${targetGuid !== originalId ? `-> ${targetGuid}` : ''}`;
|
|
179
|
+
})}]`
|
|
180
|
+
)
|
|
181
|
+
);
|
|
182
|
+
console.log(` ${log.helpText(contentTypeId)} ${entryStatus.entryTitle}`);
|
|
183
|
+
|
|
184
|
+
for (const [projectId, projectStatus] of Object.entries(
|
|
185
|
+
entryStatus
|
|
186
|
+
).filter(([key]) => key !== 'entryTitle') as [string, any][]) {
|
|
187
|
+
const [targetGuid, { error, diff, status }] = Object.entries(
|
|
188
|
+
projectStatus
|
|
189
|
+
)[0] as [string, any];
|
|
190
|
+
if (error) log.error(error);
|
|
191
|
+
if (diff) {
|
|
192
|
+
console.log(
|
|
193
|
+
` ${messages.entries.migrateStatus(status)(status)} ${log.infoText(
|
|
194
|
+
targetGuid
|
|
195
|
+
)} ${log.infoText(contentTypeId)} ${log.infoText(projectId)}`
|
|
196
|
+
);
|
|
197
|
+
console.log(``);
|
|
198
|
+
console.log(log.highlightText(diff));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { flatten } from 'flat';
|
|
2
|
+
import { Parser } from 'json2csv';
|
|
3
|
+
import cleaner from 'deep-cleaner';
|
|
4
|
+
|
|
5
|
+
const flattenObject = (obj: any) => flatten(cleaner(obj, ['workflow']));
|
|
6
|
+
|
|
7
|
+
export const csvFormatter = <T>(entries: T | T[]) => {
|
|
8
|
+
// Flatten the passed in object
|
|
9
|
+
const flatEntries = [];
|
|
10
|
+
if (Array.isArray(entries))
|
|
11
|
+
for (const entry of entries) {
|
|
12
|
+
flatEntries.push(flattenObject(entry));
|
|
13
|
+
}
|
|
14
|
+
else flatEntries.push(flattenObject(entries));
|
|
15
|
+
|
|
16
|
+
// Parse the flattened object to csv
|
|
17
|
+
const json2csvParser = new Parser();
|
|
18
|
+
const csv = json2csvParser.parse(flatEntries);
|
|
19
|
+
|
|
20
|
+
return csv;
|
|
21
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import mergeWith from 'lodash/mergeWith';
|
|
2
|
+
import { Logger } from './logger';
|
|
3
|
+
|
|
4
|
+
export const isSharedSecret = (str = '') =>
|
|
5
|
+
str.length > 80 && str.split('-').length === 3 ? str : undefined;
|
|
6
|
+
|
|
7
|
+
export const isPassword = (str = '') =>
|
|
8
|
+
!isSharedSecret(str) ? str : undefined;
|
|
9
|
+
|
|
10
|
+
export const tryParse = (str: string) => {
|
|
11
|
+
try {
|
|
12
|
+
return typeof str === 'object' ? str : JSON.parse(str);
|
|
13
|
+
} catch (e) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const isJson = (str: string) =>
|
|
19
|
+
typeof str === 'object' || !!tryParse(str);
|
|
20
|
+
|
|
21
|
+
export const tryStringify = (obj: any) => {
|
|
22
|
+
try {
|
|
23
|
+
return typeof obj === 'object' ? JSON.stringify(obj) : obj;
|
|
24
|
+
} catch (e) {
|
|
25
|
+
return obj;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const isUuid = (str: string) => {
|
|
30
|
+
// Regular expression to check if string is a valid UUID
|
|
31
|
+
const regexExp =
|
|
32
|
+
/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/gi;
|
|
33
|
+
|
|
34
|
+
return regexExp.test(str);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const url = (alias: string, project: string) => {
|
|
38
|
+
const projectAndAlias =
|
|
39
|
+
project && project.toLowerCase() !== 'website'
|
|
40
|
+
? `${project.toLowerCase()}-${alias}`
|
|
41
|
+
: alias;
|
|
42
|
+
return {
|
|
43
|
+
api: `https://api-${alias}.cloud.contensis.com`,
|
|
44
|
+
cms: `https://cms-${alias}.cloud.contensis.com`,
|
|
45
|
+
liveWeb: `https://live-${projectAndAlias}.cloud.contensis.com`,
|
|
46
|
+
previewWeb: `https://preview-${projectAndAlias}.cloud.contensis.com`,
|
|
47
|
+
iisWeb: `https://iis-live-${projectAndAlias}.cloud.contensis.com`,
|
|
48
|
+
iisPreviewWeb: `https://iis-preview-${projectAndAlias}.cloud.contensis.com`,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const Logging = async (language = 'en-GB') => {
|
|
53
|
+
const { LogMessages: defaultMessages } = await import(
|
|
54
|
+
`../localisation/en-GB.js`
|
|
55
|
+
);
|
|
56
|
+
const { LogMessages: localisedMessages } = await import(
|
|
57
|
+
`../localisation/${language}.js`
|
|
58
|
+
);
|
|
59
|
+
return {
|
|
60
|
+
messages: mergeWith(
|
|
61
|
+
localisedMessages,
|
|
62
|
+
defaultMessages,
|
|
63
|
+
(v, s) => v || s
|
|
64
|
+
) as typeof defaultMessages,
|
|
65
|
+
Log: Logger,
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const jsonFormatter = <T>(obj: T) => JSON.stringify(obj, null, 2);
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import dateFormat from 'dateformat';
|
|
4
|
+
import deepCleaner from 'deep-cleaner';
|
|
5
|
+
import ProgressBar from 'progress';
|
|
6
|
+
import { tryStringify } from '.';
|
|
7
|
+
|
|
8
|
+
type LogMethod = (content: string) => void;
|
|
9
|
+
type LogErrorMethod = (content: string, err?: any) => void;
|
|
10
|
+
type LogJsonMethod = (content: any) => void;
|
|
11
|
+
type LogArrayMethod = (contentArray: string[]) => void;
|
|
12
|
+
type LogErrorFunc = (
|
|
13
|
+
err: any,
|
|
14
|
+
msg?: string,
|
|
15
|
+
level?: 'error' | 'critical'
|
|
16
|
+
) => void;
|
|
17
|
+
|
|
18
|
+
export class Logger {
|
|
19
|
+
static isUserTerminal = !!process.stdout.columns;
|
|
20
|
+
static getPrefix = () => {
|
|
21
|
+
return Logger.isUserTerminal
|
|
22
|
+
? Logger.infoText(`[cli]`)
|
|
23
|
+
: `[${dateFormat(new Date(), 'dd/mm HH:MM:ss')}]`;
|
|
24
|
+
};
|
|
25
|
+
static errorText = chalk.bold.red;
|
|
26
|
+
static warningText = chalk.keyword('orange');
|
|
27
|
+
static successText = chalk.keyword('green');
|
|
28
|
+
static helpText = chalk.blue;
|
|
29
|
+
static highlightText = chalk.yellow;
|
|
30
|
+
static infoText = chalk.keyword('grey');
|
|
31
|
+
static standardText = chalk.keyword('white');
|
|
32
|
+
static boldText = chalk.bold;
|
|
33
|
+
static critical: LogMethod = content => {
|
|
34
|
+
const message = `${Logger.getPrefix()} ${Logger.errorText(
|
|
35
|
+
'[CRITICAL]'
|
|
36
|
+
)} ${content}`;
|
|
37
|
+
console.log(message);
|
|
38
|
+
};
|
|
39
|
+
static error: LogErrorMethod = (content, err) => {
|
|
40
|
+
const message = `${Logger.getPrefix()} ${Logger.errorText(
|
|
41
|
+
`${Logger.isUserTerminal ? '❌' : '[ERROR]'} ${content}${
|
|
42
|
+
err ? `\n\n${JSON.stringify(err, null, 2)}` : ''
|
|
43
|
+
}`
|
|
44
|
+
)}\n`;
|
|
45
|
+
if (progress.active) progress.current.interrupt(message);
|
|
46
|
+
else console.log(message);
|
|
47
|
+
};
|
|
48
|
+
static warning: LogMethod = content => {
|
|
49
|
+
// if (process.env.DEBUG === 'true') {
|
|
50
|
+
const message = `${Logger.getPrefix()} ${Logger.warningText(
|
|
51
|
+
`${Logger.isUserTerminal ? '⚠️ ' : '[WARN]'} ${content}`
|
|
52
|
+
)}\n`;
|
|
53
|
+
if (progress.active) progress.current.interrupt(message);
|
|
54
|
+
else console.log(message);
|
|
55
|
+
// }
|
|
56
|
+
};
|
|
57
|
+
static success: LogMethod = content => {
|
|
58
|
+
const message = `${Logger.getPrefix()} ${Logger.successText(
|
|
59
|
+
`${Logger.isUserTerminal ? '✅' : '[OK]'} ${content}`
|
|
60
|
+
)}`;
|
|
61
|
+
if (progress.active) progress.current.interrupt(message);
|
|
62
|
+
else console.log(message);
|
|
63
|
+
};
|
|
64
|
+
static info: LogMethod = content => {
|
|
65
|
+
const message = `${Logger.getPrefix()} ${
|
|
66
|
+
Logger.isUserTerminal ? chalk.bgCyan(' ℹ ') : '[INFO]'
|
|
67
|
+
} ${Logger.infoText(content)}`;
|
|
68
|
+
if (progress.active) progress.current.interrupt(message);
|
|
69
|
+
else console.log(message);
|
|
70
|
+
};
|
|
71
|
+
static help: LogMethod = content => {
|
|
72
|
+
const message = `${Logger.getPrefix()} ${chalk.blue(
|
|
73
|
+
`${Logger.isUserTerminal ? '⏩' : '[HELP]'} ${content}`
|
|
74
|
+
)}\n`;
|
|
75
|
+
if (progress.active) progress.current.interrupt(message);
|
|
76
|
+
else console.log(message);
|
|
77
|
+
};
|
|
78
|
+
static standard: LogMethod = content => {
|
|
79
|
+
const message = `${Logger.getPrefix()} ${
|
|
80
|
+
Logger.isUserTerminal ? '◻️' : '[STD]'
|
|
81
|
+
} \n${Logger.standardText(content)}`;
|
|
82
|
+
if (progress.active) progress.current.interrupt(message);
|
|
83
|
+
else console.log(message);
|
|
84
|
+
progress.current.interrupt(message);
|
|
85
|
+
};
|
|
86
|
+
static json: LogJsonMethod = (content, depth = 9) =>
|
|
87
|
+
console.dir(deepCleaner(content), { colors: true, depth });
|
|
88
|
+
static mixed: LogArrayMethod = contentArray =>
|
|
89
|
+
console.log(`${Logger.getPrefix()} ${contentArray.join(' ')}`);
|
|
90
|
+
static line = () =>
|
|
91
|
+
Logger.raw(` ${Logger.infoText(`-------------------------------------`)}`);
|
|
92
|
+
|
|
93
|
+
static object: LogJsonMethod = content => {
|
|
94
|
+
for (const [key, value] of Object.entries(content)) {
|
|
95
|
+
if (value && typeof value === 'object') {
|
|
96
|
+
Logger.raw(` ${chalk.bold.grey(key)}:`);
|
|
97
|
+
if (key === 'fields' && Array.isArray(value)) {
|
|
98
|
+
for (const field of value || []) {
|
|
99
|
+
Logger.raw(
|
|
100
|
+
` ${chalk.bold(field.id)}: ${chalk.grey(field.dataType)}`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
} else if (key === 'groups' && Array.isArray(value)) {
|
|
104
|
+
for (const group of value || []) {
|
|
105
|
+
const description =
|
|
106
|
+
Object.keys(group.description).length &&
|
|
107
|
+
Object.values(group.description)?.[0];
|
|
108
|
+
Logger.raw(
|
|
109
|
+
` ${chalk.bold(group.id)}${
|
|
110
|
+
description
|
|
111
|
+
? `: ${chalk.grey(Object.values(group.description)?.[0])}`
|
|
112
|
+
: ''
|
|
113
|
+
}`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
for (const [innerkey, innervalue] of Object.entries(value)) {
|
|
118
|
+
if (innervalue && typeof innervalue === 'object') {
|
|
119
|
+
Logger.raw(` ${chalk.bold.grey(innerkey)}:`);
|
|
120
|
+
console.table(innervalue);
|
|
121
|
+
} else if (
|
|
122
|
+
typeof innervalue !== 'undefined' ||
|
|
123
|
+
innervalue !== null
|
|
124
|
+
) {
|
|
125
|
+
Logger.raw(` ${chalk.bold.grey(innerkey)}: ${innervalue}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
} else if (typeof value !== 'undefined' || value !== null) {
|
|
130
|
+
Logger.raw(` ${chalk.bold.grey(key)}: ${value}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
static raw: LogMethod = (content: string) => {
|
|
135
|
+
if (progress.active) progress.current.interrupt(content);
|
|
136
|
+
else console.log(content);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export const logError: LogErrorFunc = (
|
|
141
|
+
err = new Error('Undefined error'),
|
|
142
|
+
msg,
|
|
143
|
+
level = 'error'
|
|
144
|
+
) => {
|
|
145
|
+
Logger[level](msg || err.message || err?.data?.message || err.Message);
|
|
146
|
+
(Array.isArray(err) ? err : [err]).map((error: AppError) => {
|
|
147
|
+
if ('stack' in error) Logger.raw(` ${Logger.infoText(error.stack)}`);
|
|
148
|
+
if ('data' in error)
|
|
149
|
+
Logger.raw(` ${Logger.infoText(tryStringify(error.data))}`);
|
|
150
|
+
});
|
|
151
|
+
//Logger.line();
|
|
152
|
+
return null;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export const progress = {
|
|
156
|
+
active: false,
|
|
157
|
+
done: () => new ProgressBar('', 0),
|
|
158
|
+
colours: { green: '\u001b[42m \u001b[0m', red: '\u001b[41m \u001b[0m' },
|
|
159
|
+
current: new ProgressBar(`:bar`, {
|
|
160
|
+
complete: '=',
|
|
161
|
+
incomplete: ' ',
|
|
162
|
+
width: 20,
|
|
163
|
+
total: 100,
|
|
164
|
+
}),
|
|
165
|
+
};
|