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.
Files changed (95) hide show
  1. package/.vscode/launch.json +15 -0
  2. package/README.md +631 -0
  3. package/cli.js +7 -0
  4. package/dist/commands/connect.js +44 -0
  5. package/dist/commands/connect.js.map +7 -0
  6. package/dist/commands/create.js +55 -0
  7. package/dist/commands/create.js.map +7 -0
  8. package/dist/commands/get.js +121 -0
  9. package/dist/commands/get.js.map +7 -0
  10. package/dist/commands/globalOptions.js +139 -0
  11. package/dist/commands/globalOptions.js.map +7 -0
  12. package/dist/commands/import.js +95 -0
  13. package/dist/commands/import.js.map +7 -0
  14. package/dist/commands/index.js +81 -0
  15. package/dist/commands/index.js.map +7 -0
  16. package/dist/commands/list.js +88 -0
  17. package/dist/commands/list.js.map +7 -0
  18. package/dist/commands/login.js +56 -0
  19. package/dist/commands/login.js.map +7 -0
  20. package/dist/commands/push.js +133 -0
  21. package/dist/commands/push.js.map +7 -0
  22. package/dist/commands/remove.js +77 -0
  23. package/dist/commands/remove.js.map +7 -0
  24. package/dist/commands/set.js +55 -0
  25. package/dist/commands/set.js.map +7 -0
  26. package/dist/index.js +32 -0
  27. package/dist/index.js.map +7 -0
  28. package/dist/localisation/en-GB.js +203 -0
  29. package/dist/localisation/en-GB.js.map +7 -0
  30. package/dist/models/AppError.d.js +2 -0
  31. package/dist/models/AppError.d.js.map +7 -0
  32. package/dist/models/Cache.d.js +2 -0
  33. package/dist/models/Cache.d.js.map +7 -0
  34. package/dist/models/JsModules.d.js +2 -0
  35. package/dist/models/JsModules.d.js.map +7 -0
  36. package/dist/providers/CredentialProvider.js +87 -0
  37. package/dist/providers/CredentialProvider.js.map +7 -0
  38. package/dist/providers/SessionCacheProvider.js +91 -0
  39. package/dist/providers/SessionCacheProvider.js.map +7 -0
  40. package/dist/providers/file-provider.js +113 -0
  41. package/dist/providers/file-provider.js.map +7 -0
  42. package/dist/services/ContensisAuthService.js +75 -0
  43. package/dist/services/ContensisAuthService.js.map +7 -0
  44. package/dist/services/ContensisCliService.js +1110 -0
  45. package/dist/services/ContensisCliService.js.map +7 -0
  46. package/dist/shell.js +261 -0
  47. package/dist/shell.js.map +7 -0
  48. package/dist/util/console.printer.js +194 -0
  49. package/dist/util/console.printer.js.map +7 -0
  50. package/dist/util/csv.formatter.js +50 -0
  51. package/dist/util/csv.formatter.js.map +7 -0
  52. package/dist/util/index.js +94 -0
  53. package/dist/util/index.js.map +7 -0
  54. package/dist/util/json.formatter.js +29 -0
  55. package/dist/util/json.formatter.js.map +7 -0
  56. package/dist/util/logger.js +184 -0
  57. package/dist/util/logger.js.map +7 -0
  58. package/dist/util/xml.formatter.js +51 -0
  59. package/dist/util/xml.formatter.js.map +7 -0
  60. package/dist/version.js +29 -0
  61. package/dist/version.js.map +7 -0
  62. package/esbuild.config.js +49 -0
  63. package/headless-setup.sh +7 -0
  64. package/package.json +59 -0
  65. package/patches/inquirer-command-prompt+0.1.0.patch +27 -0
  66. package/src/commands/connect.ts +23 -0
  67. package/src/commands/create.ts +41 -0
  68. package/src/commands/get.ts +139 -0
  69. package/src/commands/globalOptions.ts +126 -0
  70. package/src/commands/import.ts +89 -0
  71. package/src/commands/index.ts +72 -0
  72. package/src/commands/list.ts +90 -0
  73. package/src/commands/login.ts +33 -0
  74. package/src/commands/push.ts +120 -0
  75. package/src/commands/remove.ts +77 -0
  76. package/src/commands/set.ts +40 -0
  77. package/src/index.ts +19 -0
  78. package/src/localisation/en-GB.ts +211 -0
  79. package/src/models/AppError.d.ts +40 -0
  80. package/src/models/Cache.d.ts +25 -0
  81. package/src/models/JsModules.d.ts +1 -0
  82. package/src/providers/CredentialProvider.ts +88 -0
  83. package/src/providers/SessionCacheProvider.ts +74 -0
  84. package/src/providers/file-provider.ts +72 -0
  85. package/src/services/ContensisAuthService.ts +70 -0
  86. package/src/services/ContensisCliService.ts +1390 -0
  87. package/src/shell.ts +250 -0
  88. package/src/util/console.printer.ts +203 -0
  89. package/src/util/csv.formatter.ts +21 -0
  90. package/src/util/index.ts +67 -0
  91. package/src/util/json.formatter.ts +1 -0
  92. package/src/util/logger.ts +165 -0
  93. package/src/util/xml.formatter.ts +20 -0
  94. package/src/version.ts +1 -0
  95. package/tsconfig.json +22 -0
@@ -0,0 +1,33 @@
1
+ import { Command } from 'commander';
2
+ import { cliCommand } from '~/services/ContensisCliService';
3
+ import { shell } from '~/shell';
4
+
5
+ export const makeLoginCommand = () => {
6
+ const login = new Command()
7
+ .command('login')
8
+ .argument('<user/clientId>', 'the username to login with')
9
+ .argument(
10
+ '[password]',
11
+ 'the password to use to login with (optional/insecure)'
12
+ )
13
+ .option(
14
+ '-s --shared-secret <sharedSecret>',
15
+ 'the shared secret to use when logging in with a client id'
16
+ )
17
+ .usage('<user/clientId> [password] [-s <sharedSecret>]')
18
+ .addHelpText(
19
+ 'after',
20
+ `
21
+ Example call:
22
+ > login myuserid\n -- or --\n > login {clientId} -s {sharedSecret}
23
+ `
24
+ )
25
+ .action(async (user, password, opts) => {
26
+ const token = await cliCommand(['login', user]).Login(user, {
27
+ password,
28
+ sharedSecret: opts.sharedSecret,
29
+ });
30
+ if (token) await shell().start();
31
+ });
32
+ return login;
33
+ };
@@ -0,0 +1,120 @@
1
+ import { Command } from 'commander';
2
+ import mapJson from 'jsonpath-mapper';
3
+ import { PushBlockParams } from 'migratortron';
4
+ import { cliCommand } from '~/services/ContensisCliService';
5
+
6
+ export const makePushCommand = () => {
7
+ const push = new Command()
8
+ .command('push')
9
+ .showHelpAfterError(true)
10
+ .exitOverride();
11
+
12
+ push
13
+ .command('block')
14
+ .argument('<block-id>', 'the name of the block to push to')
15
+ .argument(
16
+ '<image uri:tag>',
17
+ 'the uri and tag of the container image to push as a block (tag default: latest)'
18
+ )
19
+ .argument('[branch]', 'the branch we are pushing to')
20
+ .option(
21
+ '-r, --release',
22
+ 'whether to release the pushed block version',
23
+ false
24
+ )
25
+ .option(
26
+ '-cid, --commit-id <commitId>',
27
+ 'the id of the source git commit for the supplied image uri'
28
+ )
29
+ .option(
30
+ '-cmsg, --commit-message <commitMessage>',
31
+ 'the git commit message for the supplied commit id'
32
+ )
33
+ .option(
34
+ '-cdt, --commit-datetime <commitDateTime>',
35
+ 'the timestamp of the source git commit for the supplied image uri'
36
+ )
37
+ .option(
38
+ '-author, --author-email <authorEmail>',
39
+ 'the git email address of the author of the source git commit'
40
+ )
41
+ .option(
42
+ '-committer, --committer-email <committerEmail>',
43
+ 'the git email address of the commiter of the source git commit'
44
+ )
45
+ .option(
46
+ '-repo, --repository-url <repositoryUrl>',
47
+ 'the url of the source repository for the supplied image uri'
48
+ )
49
+ .option(
50
+ '-pr, --provider <sourceProvider>',
51
+ 'the url of the source repository for the supplied image uri'
52
+ )
53
+ .usage('<block-id> <image uri> [branch] [options]')
54
+ .addHelpText(
55
+ 'after',
56
+ `
57
+ Example call:
58
+ > push block contensis-app ghcr.io/contensis/contensis-app/build-4359 master --release\n`
59
+ )
60
+ .action(async (blockId: string, imageUri: string, branch: string, opts) => {
61
+ const cli = cliCommand(['push', 'block', blockId], opts);
62
+ const mapSourceVars = {
63
+ blockId,
64
+ imageUri,
65
+ branch,
66
+ ...opts,
67
+ ...process.env,
68
+ };
69
+
70
+ const blockRequest = mapJson(mapSourceVars, {
71
+ autoRelease: { $path: 'release', $default: () => false },
72
+ id: ['blockId'],
73
+ image: () => {
74
+ const lastIndexOfColon = imageUri.lastIndexOf(':');
75
+ return {
76
+ uri: imageUri.slice(0, lastIndexOfColon),
77
+ tag: imageUri.slice(lastIndexOfColon + 1) || 'latest',
78
+ };
79
+ },
80
+ projectId: () => cli.env.currentProject || '',
81
+ source: {
82
+ provider: {
83
+ $path: ['provider'],
84
+ $return: (provider: string, { GITHUB_ACTIONS, GITLAB_CI }) => {
85
+ if (provider) return provider;
86
+ if (GITHUB_ACTIONS) return 'Github';
87
+ else if (GITLAB_CI) return 'GitlabSelfHosted';
88
+ },
89
+ },
90
+ repositoryUrl: {
91
+ $path: ['repositoryUrl', 'CI_PROJECT_URL', 'GITHUB_REPOSITORY'],
92
+ $formatting: (url: string, { GITHUB_ACTIONS }) => {
93
+ if (GITHUB_ACTIONS) url = `https://github.com/${url}`;
94
+
95
+ if (url && !url.endsWith('.git')) return `${url}.git`;
96
+ return url;
97
+ },
98
+ },
99
+ branch: ['branch', 'CI_COMMIT_REF_NAME', 'GITHUB_REF_NAME'],
100
+ commit: {
101
+ id: ['commitId', 'CI_COMMIT_SHORT_SHA', 'GITHUB_SHA'],
102
+ message: ['commitMessage', 'CI_COMMIT_MESSAGE'], // ${{ github.event.head_commit.message }}
103
+ dateTime: ['commitDatetime', 'CI_COMMIT_TIMESTAMP'], // ${{ github.event.head_commit.timestamp }}
104
+ authorEmail: ['authorEmail', 'GITLAB_USER_EMAIL', 'GITHUB_ACTOR'], // ${{ github.event.head_commit.author.email }}
105
+ committerEmail: [
106
+ 'committerEmail',
107
+ 'GITLAB_USER_EMAIL',
108
+ 'GITHUB_TRIGGERING_ACTOR',
109
+ ], // ${{ github.event.head_commit.committer.email }}
110
+ },
111
+ },
112
+ }) as PushBlockParams;
113
+
114
+ await cli.PushBlock(blockRequest);
115
+
116
+ // console.log(process.env);
117
+ });
118
+
119
+ return push;
120
+ };
@@ -0,0 +1,77 @@
1
+ import { Command } from 'commander';
2
+ import { cliCommand } from '~/services/ContensisCliService';
3
+ import { shell } from '~/shell';
4
+ import { commit, mapContensisOpts } from './globalOptions';
5
+
6
+ export const makeRemoveCommand = () => {
7
+ const remove = new Command()
8
+ .command('remove')
9
+ .showHelpAfterError(true)
10
+ .exitOverride();
11
+
12
+ remove
13
+ .command('project')
14
+ .argument('<projectId>', 'the project id to delete')
15
+ .usage('<projectId>')
16
+ .action(async (projectId, opts) => {
17
+ const project = await cliCommand(
18
+ ['remove', 'project', projectId],
19
+ opts
20
+ ).SetProject(projectId);
21
+ if (project) await shell().start();
22
+ });
23
+ remove
24
+ .command('key')
25
+ .argument('<id>', 'the id of the API key to delete')
26
+ .usage('<id>')
27
+ .addHelpText(
28
+ 'after',
29
+ `
30
+ Example call:
31
+ > remove key 4ceb9575-28d3-4d5b-a77b-5e5221e603dd
32
+ `
33
+ )
34
+ .action(async (id, opts) => {
35
+ await cliCommand(['remove', 'key', id], opts).RemoveApiKey(id);
36
+ });
37
+
38
+ remove
39
+ .command('components')
40
+ .argument('<id...>', 'the id(s) of the components to delete')
41
+ .addOption(commit)
42
+ .usage('<id> [--commit]')
43
+ .addHelpText(
44
+ 'after',
45
+ `
46
+ Example call:
47
+ > remove components addressComponent
48
+ `
49
+ )
50
+ .action(async (id: string[], opts) => {
51
+ await cliCommand(
52
+ ['remove', 'components', id.join(', ')],
53
+ opts
54
+ ).RemoveComponents(id, opts.commit);
55
+ });
56
+
57
+ remove
58
+ .command('contenttypes')
59
+ .argument('<id...>', 'the id(s) of the content types to delete')
60
+ .addOption(commit)
61
+ .usage('<id> [--commit]')
62
+ .addHelpText(
63
+ 'after',
64
+ `
65
+ Example call:
66
+ > remove contenttypes blogPost
67
+ `
68
+ )
69
+ .action(async (id: string[], opts) => {
70
+ await cliCommand(
71
+ ['remove', 'contenttypes', id.join(', ')],
72
+ opts
73
+ ).RemoveContentTypes(id, opts.commit);
74
+ });
75
+
76
+ return remove;
77
+ };
@@ -0,0 +1,40 @@
1
+ import { Argument, Command } from 'commander';
2
+ import { cliCommand } from '~/services/ContensisCliService';
3
+ import { shell } from '~/shell';
4
+
5
+ export const makeSetCommand = () => {
6
+ const set = new Command()
7
+ .command('set')
8
+ .showHelpAfterError(true)
9
+ .exitOverride();
10
+ set
11
+ .command('project')
12
+ .argument('<projectId>', 'the project id to work with')
13
+ .usage('<projectId>')
14
+ .action(async projectId => {
15
+ const project = await cliCommand([
16
+ 'set',
17
+ 'project',
18
+ projectId,
19
+ ]).SetProject(projectId);
20
+ if (project) await shell().start();
21
+ });
22
+ set
23
+ .command('version')
24
+ .addArgument(
25
+ new Argument('<versionStatus>', 'content version status')
26
+ .choices(['latest', 'published'])
27
+ .default('latest')
28
+ )
29
+ .usage('<latest/published>')
30
+ .action(async versionStatus => {
31
+ const success = await cliCommand([
32
+ 'set',
33
+ 'version',
34
+ versionStatus,
35
+ ]).SetVersion(versionStatus);
36
+ if (success) await shell().start();
37
+ });
38
+
39
+ return set;
40
+ };
package/src/index.ts ADDED
@@ -0,0 +1,19 @@
1
+ import commands from './commands';
2
+ import { logError } from './util/logger';
3
+ import ContensisCli from './services/ContensisCliService';
4
+ import { jsonFormatter } from './util/json.formatter';
5
+ // new ContensisCli(process.argv).DoCommandTasksAsync();
6
+
7
+ // This is the CLI part of the app
8
+ const program = commands();
9
+ program
10
+ .parseAsync(process.argv)
11
+ .then(() => {
12
+ ContensisCli.quit();
13
+ })
14
+ .catch((err: any) => {
15
+ if (!err.name?.includes('CommanderError'))
16
+ logError(err, `CLI ${err.toString()}`);
17
+ ContensisCli.quit(err);
18
+ });
19
+ //.exitOverride(() => console.log('exit override!!!'));
@@ -0,0 +1,211 @@
1
+ import { BlockRunningStatus, MigrateStatus } from 'migratortron';
2
+ import { Logger } from '~/util/logger';
3
+
4
+ export const LogMessages = {
5
+ app: {
6
+ contensis: () => 'Contensis',
7
+ quit: () => `Goodbye 👋\n`,
8
+ startup: () =>
9
+ `© 2001-${new Date().getFullYear()} Zengenti 🇬🇧. \n - Creators of Contensis and purveyors of other fine software\n\n👋 Welcome to the contensis-cli\n`,
10
+ help: () =>
11
+ 'Press [CTRL]+[C] or type "quit" to return to your system shell\nPress [TAB] for suggestions\n',
12
+ suggestions: () =>
13
+ `\n${Logger.errorText('>>')} Press [TAB] for suggestions\n`,
14
+ autocomplete: () => `\n${Logger.errorText('>>')} Available commands:`,
15
+ unknownError: () => `Something went wrong...`,
16
+ fileOutput: (format = 'json', path?: string) =>
17
+ `Output ${format} file: ${Logger.infoText(path)}\n`,
18
+ noFileOutput: () => `No output written\n`,
19
+ },
20
+ command: {
21
+ notKnown: (command: string) => `${command} is not known`,
22
+ },
23
+ envs: {
24
+ found: (num: number) =>
25
+ `environments store found containing ${num} environment${
26
+ num === 1 ? '' : 's'
27
+ }`,
28
+ tip: () =>
29
+ `Connect to a Contensis cloud instance using "contensis connect {cms alias}"`,
30
+ },
31
+ connect: {
32
+ command: {
33
+ name: () => 'connect',
34
+ example: () => `Example call:\n > connect example-dev`,
35
+ },
36
+ args: {
37
+ alias: {
38
+ name: () => '<alias>',
39
+ description: () => 'the Contensis Cloud alias to connect with',
40
+ },
41
+ },
42
+ noEnv: () => `Cannot connect - no environment alias specified`,
43
+ unreachable: (url: string, status: number) =>
44
+ `Cannot reach ${url}${status ? ` - status ${status}` : ''}`,
45
+ connected: (env: string) => `Current environment set to "${env}"`,
46
+ help: () =>
47
+ `Connect to a Contensis cloud instance using "contensis connect {cms alias}"`,
48
+ projects: () => `Available projects:`,
49
+ noProjects: () => `Cannot retrieve projects list`,
50
+ tip: () =>
51
+ `Introduce yourself with "login {username}" or "login {clientId} -s {secret}" or by passing credentials as options with your command`,
52
+ },
53
+ login: {
54
+ command: {
55
+ name: () => 'login',
56
+ usage: () => `<user/clientId> [password] [-s <sharedSecret>]`,
57
+ example: () =>
58
+ `Example call:\n > login myuserid\n -- or --\n > login {clientId} -s {sharedSecret}`,
59
+ },
60
+ args: {
61
+ user: {
62
+ name: () => '<user/clientId>',
63
+ description: () => 'the username to login with',
64
+ },
65
+ password: {
66
+ name: () => '[password]',
67
+ description: () =>
68
+ 'the password to use to login with (optional/insecure)',
69
+ },
70
+ secret: {
71
+ name: () => '-s --sharedSecret <sharedSecret>',
72
+ description: () =>
73
+ 'the shared secret to use when logging in with a client id',
74
+ },
75
+ },
76
+ passwordPrompt: (env: string, userId: string) =>
77
+ `Enter password for ${userId}@${env}:`,
78
+ failed: (env: string, userId: string) =>
79
+ `Unable to login to ${env} as ${userId}`,
80
+ success: (env: string, userId: string) =>
81
+ `User ${userId} connected to ${env} successfully\n`,
82
+ insecurePassword: () =>
83
+ `Could not connect to local keystore - your password could be stored unencrypted!`,
84
+ noEnv: () => `No environment set, use "contensis connect {alias}" first`,
85
+ noUserId: () => `No user id specified`,
86
+ },
87
+ projects: {
88
+ list: () => `Available projects:`,
89
+ noList: () => `Cannot retrieve projects list`,
90
+ set: (projectId: string) => `Current project is set to "${projectId}"`,
91
+ failedSet: (projectId: string) => `Project "${projectId}" not found`,
92
+ },
93
+ contenttypes: {
94
+ list: (projectId: string) => `Content types in "${projectId}":`,
95
+ noList: (projectId: string) =>
96
+ `[${projectId}] Cannot retrieve content types list`,
97
+ get: (projectId: string, contentTypeId: string) =>
98
+ `[${projectId}] Content type "${contentTypeId}"`,
99
+ failedGet: (projectId: string, contentTypeId: string) =>
100
+ `[${projectId}] Unable to get content type "${contentTypeId}"`,
101
+ created: (projectId: string, componentId: string, status?: string) =>
102
+ `[${projectId}] Content type ${status}d "${componentId}"`,
103
+ removed: (env: string, id: string, commit: boolean) =>
104
+ `[${env}] ${commit ? `Deleted` : `Will delete`} content type "${id}"`,
105
+ failedRemove: (env: string, id: string) =>
106
+ `[${env}] Unable to delete content type "${id}"`,
107
+ },
108
+ components: {
109
+ list: (projectId: string) => `Components in "${projectId}":`,
110
+ noList: (projectId: string) =>
111
+ `[${projectId}] Cannot retrieve components list`,
112
+ get: (projectId: string, componentId: string) =>
113
+ `[${projectId}] Component "${componentId}"`,
114
+ failedGet: (projectId: string, componentId: string) =>
115
+ `[${projectId}] Unable to get component "${componentId}"`,
116
+ created: (projectId: string, componentId: string, status?: string) =>
117
+ `[${projectId}] Component ${status}d "${componentId}"`,
118
+ removed: (env: string, id: string, commit: boolean) =>
119
+ `[${env}] ${commit ? `Deleted` : `Will delete`} component "${id}"`,
120
+ failedRemove: (env: string, id: string) =>
121
+ `[${env}] Unable to delete component "${id}"`,
122
+ },
123
+ version: {
124
+ set: (env: string, versionStatus: string) =>
125
+ `[${env}] Content version status set to "${versionStatus}"`,
126
+ invalid: (versionStatus: string) =>
127
+ `Content version status "${versionStatus}" is not valid, allowed values are "published" or "latest".`,
128
+ noEnv: () =>
129
+ `No Contensis environment set, connect to your Contensis cloud instance using "contensis connect {cms alias}"`,
130
+ },
131
+ entries: {
132
+ migrateStatus: (status: MigrateStatus) => {
133
+ switch (status) {
134
+ case 'no change':
135
+ return Logger.successText;
136
+ case 'create':
137
+ case 'two-pass':
138
+ case 'update':
139
+ case 'delete':
140
+ return Logger.warningText;
141
+ case 'error':
142
+ case 'not found':
143
+ return Logger.errorText;
144
+ default:
145
+ return Logger.infoText;
146
+ }
147
+ },
148
+ removed: (env: string, id: string, commit: boolean) =>
149
+ `[${env}] ${commit ? `Deleted` : `Will delete`} entry "${id}"`,
150
+ failedRemove: (env: string, id: string) =>
151
+ `[${env}] Unable to delete entry "${id}"`,
152
+ notFound: (id: string) => `Entry "${id}" not found`,
153
+ commitTip: () => ` Add --commit flag to commit the previewed changes`,
154
+ },
155
+ keys: {
156
+ list: (env: string) => `[${env}] API keys:`,
157
+ noList: (env: string) => `[${env}] Cannot retrieve API`,
158
+ created: (env: string, name: string) =>
159
+ `[${env}] Created API key "${name}"`,
160
+ failedCreate: (env: string, name: string) =>
161
+ `[${env}] Unable to create API key "${name}"`,
162
+ removed: (env: string, id: string) => `[${env}] Deleted API key "${id}"`,
163
+ failedRemove: (env: string, id: string) =>
164
+ `[${env}] Unable to delete API key "${id}"`,
165
+ },
166
+ blocks: {
167
+ runningStatus: (status: BlockRunningStatus | 'broken') => {
168
+ switch (status) {
169
+ case 'available':
170
+ return Logger.successText(status);
171
+ case 'pending':
172
+ case 'starting':
173
+ case 'stopped':
174
+ return Logger.warningText(status);
175
+ case 'degraded':
176
+ case 'faulted':
177
+ case 'broken':
178
+ return Logger.errorText(status);
179
+ default:
180
+ return Logger.infoText(status);
181
+ }
182
+ },
183
+ get: (env: string) => `[${env}] Block versions:`,
184
+ list: (env: string, projectId?: string) =>
185
+ `[${env}] Blocks in project ${projectId}:`,
186
+ noList: (env: string, projectId?: string) =>
187
+ `[${env}] Cannot retrieve blocks in project ${projectId}`,
188
+ tryPush: (id: string, branch: string, env: string, projectId?: string) =>
189
+ `[${env}] Request to push block "${id}" in branch ${branch} in project ${projectId}`,
190
+ pushed: (id: string, branch: string, env: string, projectId?: string) =>
191
+ `[${env}] Pushed block "${id}" in branch ${branch} in project ${projectId}`,
192
+ failedPush: (id: string, env: string, projectId?: string) =>
193
+ `[${env}] Unable to push block "${id}" in project ${projectId}`,
194
+ deleted: (id: string, env: string, projectId?: string) =>
195
+ `[${env}] Deleted block "${id}" in project ${projectId}`,
196
+ failedDelete: (id: string, env: string, projectId?: string) =>
197
+ `[${env}] Unable to delete block "${id}" in project ${projectId}`,
198
+ },
199
+ webhooks: {
200
+ list: (env: string) => `[${env}] Webhook subscriptions:`,
201
+ noList: (env: string) => `[${env}] Cannot retrieve webhook subscriptions`,
202
+ created: (env: string, name: string) =>
203
+ `[${env}] Created Webhook subscription "${name}"`,
204
+ failedCreate: (env: string, name: string) =>
205
+ `[${env}] Unable to create Webhook subscription "${name}"`,
206
+ deleted: (env: string, id: string) =>
207
+ `[${env}] Deleted Webhook subscription "${id}"`,
208
+ failedDelete: (env: string, id: string) =>
209
+ `[${env}] Unable to delete Webhook subscription "${id}"`,
210
+ },
211
+ };
@@ -0,0 +1,40 @@
1
+ type AppError = (Error & ApiErrorResponse) | ApiErrorResponse;
2
+
3
+ type InnerDataArray = [
4
+ {
5
+ field: string;
6
+ message: string;
7
+ }
8
+ ];
9
+
10
+ type ApiErrorResponse = {
11
+ name?: string;
12
+ error?: { code: string; message: string };
13
+ code?: string;
14
+ type?: string;
15
+ timeout?: number;
16
+ status?: number;
17
+ statusText?: string;
18
+ url?: string;
19
+ data?:
20
+ | {
21
+ logId: string;
22
+ message: string;
23
+ data: InnerDataArray;
24
+ type: string;
25
+ }
26
+ | any;
27
+ };
28
+
29
+ type MappedError = {
30
+ status: number;
31
+ statusText?: string;
32
+ url?: string;
33
+ message: string;
34
+ name?: string;
35
+ code?: string;
36
+ type?: string;
37
+ logId?: string;
38
+ data?: InnerDataArray | any;
39
+ stack?: string;
40
+ };
@@ -0,0 +1,25 @@
1
+ type SessionCache = {
2
+ currentEnvironment?: string;
3
+ currentTimestamp: string;
4
+ environments: {
5
+ [alias: string]: EnvironmentCache;
6
+ };
7
+ history: string[];
8
+ };
9
+
10
+ type EnvironmentCache = {
11
+ lastUserId: string;
12
+ passwordFallback?: string;
13
+ authToken?: string;
14
+ currentProject?: string;
15
+ projects: string[];
16
+ history: CliCommand[];
17
+ versionStatus: 'latest' | 'published';
18
+ };
19
+
20
+ type CliCommand = {
21
+ createdDate: string;
22
+ createdUserId: string;
23
+ commandText: string;
24
+ result?: any;
25
+ };
@@ -0,0 +1 @@
1
+ declare module 'inquirer-command-prompt';
@@ -0,0 +1,88 @@
1
+ import keytar from 'keytar';
2
+ import to from 'await-to-js';
3
+ import { Logger } from '~/util/logger';
4
+
5
+ const SERVICE_NAME = 'contensis-cli';
6
+
7
+ interface Remarks {
8
+ secure: boolean;
9
+ }
10
+
11
+ class CredentialProvider {
12
+ private serviceId: string;
13
+ private userId: string = '';
14
+ private passwordFallback?: string;
15
+
16
+ current: {
17
+ account: string;
18
+ password: string;
19
+ } | null = null;
20
+ remarks: Remarks = { secure: false };
21
+
22
+ constructor(
23
+ { userId, alias }: { userId: string; alias?: string },
24
+ passwordFallback?: string
25
+ ) {
26
+ this.serviceId =
27
+ typeof alias !== 'undefined' ? `${SERVICE_NAME}_${alias}` : SERVICE_NAME;
28
+ this.userId = userId;
29
+ this.passwordFallback = passwordFallback;
30
+ }
31
+
32
+ Init = async (): Promise<[Error, CredentialProvider]> => {
33
+ const [err, stored] = (await to(
34
+ keytar.findCredentials(this.serviceId)
35
+ )) as [
36
+ Error,
37
+ {
38
+ account: string;
39
+ password: string;
40
+ }[]
41
+ ];
42
+ if (err && this.passwordFallback) {
43
+ this.current = { account: this.userId, password: this.passwordFallback };
44
+ // this.remarks = { secure: false };
45
+ }
46
+ if (!err) {
47
+ this.remarks = { secure: true };
48
+ this.current =
49
+ stored?.find(
50
+ u => u?.account?.toLowerCase() === this.userId.toLowerCase()
51
+ ) || null;
52
+ }
53
+ return [err, this];
54
+ };
55
+
56
+ Save = async (password: string) => {
57
+ const [err] = await to(
58
+ keytar.setPassword(this.serviceId, this.userId, password)
59
+ );
60
+
61
+ if (!err) Logger.info(`${this.serviceId} - credentials saved`);
62
+ return err && !this.passwordFallback ? err : true;
63
+ };
64
+
65
+ Delete = async () => {
66
+ if (this.passwordFallback) {
67
+ this.passwordFallback = undefined;
68
+ return true;
69
+ } else {
70
+ const [err] = await to(
71
+ keytar.deletePassword(this.serviceId, this.userId)
72
+ );
73
+
74
+ Logger.warning(`${this.serviceId} - invalid credentials removed`);
75
+ return err || true;
76
+ }
77
+ };
78
+
79
+ // GetPassword = async () => {
80
+ // const [err, password] = await to(
81
+ // keytar.getPassword(this.serviceId, this.userId)
82
+ // );
83
+
84
+ // return err || password;
85
+ // };
86
+ }
87
+
88
+ export default CredentialProvider;