@rockcarver/frodo-cli 0.13.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/babel.config.esm.json +6 -0
  3. package/package.json +14 -7
  4. package/src/{app.js → app.ts} +14 -14
  5. package/src/cli/_template/{cmd-delete.js → cmd-delete.ts} +0 -0
  6. package/src/cli/_template/{cmd-describe.js → cmd-describe.ts} +0 -0
  7. package/src/cli/_template/{cmd-export.js → cmd-export.ts} +0 -0
  8. package/src/cli/_template/{cmd-import.js → cmd-import.ts} +0 -0
  9. package/src/cli/_template/{cmd-list.js → cmd-list.ts} +0 -0
  10. package/src/cli/_template/{cmd-sub1-delete.js → cmd-sub1-delete.ts} +0 -0
  11. package/src/cli/_template/{cmd-sub1-describe.js → cmd-sub1-describe.ts} +0 -0
  12. package/src/cli/_template/{cmd-sub1-export.js → cmd-sub1-export.ts} +0 -0
  13. package/src/cli/_template/{cmd-sub1-import.js → cmd-sub1-import.ts} +0 -0
  14. package/src/cli/_template/{cmd-sub1-list.js → cmd-sub1-list.ts} +0 -0
  15. package/src/cli/_template/{cmd-sub1.js → cmd-sub1.ts} +0 -0
  16. package/src/cli/_template/{cmd-sub2-delete.js → cmd-sub2-delete.ts} +0 -0
  17. package/src/cli/_template/{cmd-sub2-describe.js → cmd-sub2-describe.ts} +0 -0
  18. package/src/cli/_template/{cmd-sub2-export.js → cmd-sub2-export.ts} +0 -0
  19. package/src/cli/_template/{cmd-sub2-import.js → cmd-sub2-import.ts} +0 -0
  20. package/src/cli/_template/{cmd-sub2-list.js → cmd-sub2-list.ts} +0 -0
  21. package/src/cli/_template/{cmd-sub2.js → cmd-sub2.ts} +0 -0
  22. package/src/cli/_template/{cmd.js → cmd.ts} +0 -0
  23. package/src/cli/admin/{admin-add-autoid-static-user-mapping.js → admin-add-autoid-static-user-mapping.ts} +0 -0
  24. package/src/cli/admin/{admin-create-oauth2-client-with-admin-privileges.js → admin-create-oauth2-client-with-admin-privileges.ts} +0 -0
  25. package/src/cli/admin/{admin-get-access-token.js → admin-get-access-token.ts} +0 -0
  26. package/src/cli/admin/{admin-grant-oauth2-client-admin-privileges.js → admin-grant-oauth2-client-admin-privileges.ts} +0 -0
  27. package/src/cli/admin/{admin-hide-generic-extension-attributes.js → admin-hide-generic-extension-attributes.ts} +0 -0
  28. package/src/cli/admin/{admin-list-oauth2-clients-with-admin-privileges.js → admin-list-oauth2-clients-with-admin-privileges.ts} +0 -0
  29. package/src/cli/admin/{admin-list-oauth2-clients-with-custom-privileges.js → admin-list-oauth2-clients-with-custom-privileges.ts} +0 -0
  30. package/src/cli/admin/{admin-list-static-user-mappings.js → admin-list-static-user-mappings.ts} +0 -0
  31. package/src/cli/admin/{admin-remove-static-user-mapping.js → admin-remove-static-user-mapping.ts} +0 -0
  32. package/src/cli/admin/{admin-repair-org-model.js → admin-repair-org-model.ts} +7 -1
  33. package/src/cli/admin/{admin-revoke-oauth2-client-admin-privileges.js → admin-revoke-oauth2-client-admin-privileges.ts} +0 -0
  34. package/src/cli/admin/{admin-show-generic-extension-attributes.js → admin-show-generic-extension-attributes.ts} +0 -0
  35. package/src/cli/admin/{admin.js → admin.ts} +0 -0
  36. package/src/cli/app/{app-delete.js → app-delete.ts} +0 -0
  37. package/src/cli/app/{app-describe.js → app-describe.ts} +0 -0
  38. package/src/cli/app/{app-export.js → app-export.ts} +0 -0
  39. package/src/cli/app/{app-import.js → app-import.ts} +0 -0
  40. package/src/cli/app/{app-list.js → app-list.ts} +0 -0
  41. package/src/cli/app/{app.js → app.ts} +0 -0
  42. package/src/cli/{cmd_common.js → cmd_common.ts} +0 -0
  43. package/src/cli/conn/{conn-add.js → conn-add.ts} +0 -0
  44. package/src/cli/conn/{conn-delete.js → conn-delete.ts} +0 -0
  45. package/src/cli/conn/{conn-describe.js → conn-describe.ts} +0 -0
  46. package/src/cli/conn/{conn-list.js → conn-list.ts} +0 -0
  47. package/src/cli/conn/{conn.js → conn.ts} +0 -0
  48. package/src/cli/email/{email-template-export.js → email-template-export.ts} +0 -0
  49. package/src/cli/email/{email-template-import.js → email-template-import.ts} +0 -0
  50. package/src/cli/email/{email-template-list.js → email-template-list.ts} +0 -0
  51. package/src/cli/email/{email-template.js → email-template.ts} +0 -0
  52. package/src/cli/email/{email.js → email.ts} +0 -0
  53. package/src/cli/esv/{esv-apply.js → esv-apply.ts} +0 -0
  54. package/src/cli/esv/{esv-secret-create.js → esv-secret-create.ts} +0 -0
  55. package/src/cli/esv/{esv-secret-delete.js → esv-secret-delete.ts} +0 -0
  56. package/src/cli/esv/{esv-secret-describe.js → esv-secret-describe.ts} +0 -0
  57. package/src/cli/esv/{esv-secret-export.js → esv-secret-export.ts} +0 -0
  58. package/src/cli/esv/{esv-secret-import.js → esv-secret-import.ts} +0 -0
  59. package/src/cli/esv/{esv-secret-list.js → esv-secret-list.ts} +0 -0
  60. package/src/cli/esv/{esv-secret-set.js → esv-secret-set.ts} +0 -0
  61. package/src/cli/esv/{esv-secret-version-activate.js → esv-secret-version-activate.ts} +0 -0
  62. package/src/cli/esv/{esv-secret-version-create.js → esv-secret-version-create.ts} +0 -0
  63. package/src/cli/esv/{esv-secret-version-deactivate.js → esv-secret-version-deactivate.ts} +0 -0
  64. package/src/cli/esv/{esv-secret-version-delete.js → esv-secret-version-delete.ts} +0 -0
  65. package/src/cli/esv/{esv-secret-version-list.js → esv-secret-version-list.ts} +0 -0
  66. package/src/cli/esv/{esv-secret-version.js → esv-secret-version.ts} +0 -0
  67. package/src/cli/esv/{esv-secret.js → esv-secret.ts} +0 -0
  68. package/src/cli/esv/{esv-variable-create.js → esv-variable-create.ts} +0 -0
  69. package/src/cli/esv/{esv-variable-delete.js → esv-variable-delete.ts} +0 -0
  70. package/src/cli/esv/{esv-variable-describe.js → esv-variable-describe.ts} +0 -0
  71. package/src/cli/esv/{esv-variable-export.js → esv-variable-export.ts} +0 -0
  72. package/src/cli/esv/{esv-variable-import.js → esv-variable-import.ts} +0 -0
  73. package/src/cli/esv/{esv-variable-list.js → esv-variable-list.ts} +0 -0
  74. package/src/cli/esv/{esv-variable-set.js → esv-variable-set.ts} +0 -0
  75. package/src/cli/esv/{esv-variable.js → esv-variable.ts} +0 -0
  76. package/src/cli/esv/{esv.js → esv.ts} +0 -0
  77. package/src/cli/idm/{idm-count.js → idm-count.ts} +0 -0
  78. package/src/cli/idm/{idm-export.js → idm-export.ts} +0 -0
  79. package/src/cli/idm/{idm-list.js → idm-list.ts} +0 -0
  80. package/src/cli/idm/{idm.js → idm.ts} +0 -0
  81. package/src/cli/idp/{idp-export.js → idp-export.ts} +0 -0
  82. package/src/cli/idp/{idp-import.js → idp-import.ts} +0 -0
  83. package/src/cli/idp/{idp-list.js → idp-list.ts} +0 -0
  84. package/src/cli/idp/{idp.js → idp.ts} +0 -0
  85. package/src/cli/info/{info.js → info.ts} +1 -1
  86. package/src/cli/journey/journey-delete.e2e.test_.ts +380 -0
  87. package/src/cli/journey/{journey-delete.js → journey-delete.ts} +0 -0
  88. package/src/cli/journey/{journey-describe.js → journey-describe.ts} +60 -12
  89. package/src/cli/journey/{journey-export.js → journey-export.ts} +0 -0
  90. package/src/cli/journey/{journey-import.js → journey-import.ts} +0 -0
  91. package/src/cli/journey/journey-list.e2e.test_.ts +142 -0
  92. package/src/cli/journey/{journey-list.js → journey-list.ts} +0 -0
  93. package/src/cli/journey/{journey-prune.js → journey-prune.ts} +0 -0
  94. package/src/cli/journey/{journey.js → journey.ts} +0 -0
  95. package/src/cli/logging/{logs-list.js → logs-list.ts} +0 -0
  96. package/src/cli/logging/{logs-tail.js → logs-tail.ts} +0 -0
  97. package/src/cli/logging/{logs.js → logs.ts} +0 -0
  98. package/src/cli/realm/{realm-add-custom-domain.js → realm-add-custom-domain.ts} +0 -0
  99. package/src/cli/realm/{realm-describe.js → realm-describe.ts} +0 -0
  100. package/src/cli/realm/{realm-list.js → realm-list.ts} +0 -0
  101. package/src/cli/realm/{realm-remove-custom-domain.js → realm-remove-custom-domain.ts} +0 -0
  102. package/src/cli/realm/{realm.js → realm.ts} +0 -0
  103. package/src/cli/saml/{saml-cot-export.js → saml-cot-export.ts} +0 -0
  104. package/src/cli/saml/{saml-cot-import.js → saml-cot-import.ts} +0 -0
  105. package/src/cli/saml/{saml-cot-list.js → saml-cot-list.ts} +0 -0
  106. package/src/cli/saml/{saml-cot.js → saml-cot.ts} +0 -0
  107. package/src/cli/saml/{saml-describe.js → saml-describe.ts} +0 -0
  108. package/src/cli/saml/{saml-export.js → saml-export.ts} +0 -0
  109. package/src/cli/saml/{saml-import.js → saml-import.ts} +0 -0
  110. package/src/cli/saml/{saml-list.js → saml-list.ts} +0 -0
  111. package/src/cli/saml/{saml-metadata-export.js → saml-metadata-export.ts} +0 -0
  112. package/src/cli/saml/{saml-metadata.js → saml-metadata.ts} +0 -0
  113. package/src/cli/saml/{saml.js → saml.ts} +0 -0
  114. package/src/cli/script/{script-delete.js → script-delete.ts} +0 -0
  115. package/src/cli/script/{script-describe.js → script-describe.ts} +0 -0
  116. package/src/cli/script/{script-export.js → script-export.ts} +0 -0
  117. package/src/cli/script/{script-import.js → script-import.ts} +0 -0
  118. package/src/cli/script/{script-list.js → script-list.ts} +0 -0
  119. package/src/cli/script/{script.js → script.ts} +0 -0
  120. package/src/cli/theme/theme-delete.e2e.test_.ts +178 -0
  121. package/src/cli/theme/{theme-delete.js → theme-delete.ts} +0 -0
  122. package/src/cli/theme/{theme-export.js → theme-export.ts} +0 -0
  123. package/src/cli/theme/{theme-import.js → theme-import.ts} +0 -0
  124. package/src/cli/theme/theme-list.e2e.test_.ts +119 -0
  125. package/src/cli/theme/{theme-list.js → theme-list.ts} +0 -0
  126. package/src/cli/theme/{theme.js → theme.ts} +0 -0
  127. package/src/ops/CirclesOfTrustOps.ts +12 -0
  128. package/src/ops/EmailTemplateOps.ts +19 -0
  129. package/src/ops/IdpOps.ts +11 -0
  130. package/src/ops/JourneyOps.ts +278 -0
  131. package/src/ops/NodeOps.ts +47 -0
  132. package/src/ops/Saml2Ops.ts +24 -0
  133. package/src/ops/ScriptOps.ts +11 -0
  134. package/src/ops/ThemeOps.ts +17 -0
  135. package/src/ops/utils/Wordwrap.ts +11 -0
  136. package/src/storage/{StaticStorage.js → StaticStorage.ts} +0 -0
  137. package/src/utils/{Console.js → Console.ts} +3 -2
  138. package/tsconfig.json +6 -6
File without changes
File without changes
File without changes
@@ -0,0 +1,178 @@
1
+ // import { jest } from '@jest/globals';
2
+ import { spawn, spawnSync } from 'child_process';
3
+
4
+ const ansiEscapeCodes =
5
+ // eslint-disable-next-line no-control-regex
6
+ /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
7
+
8
+ /**
9
+ * Run once before running the suites in this file
10
+ */
11
+ beforeAll(async () => {});
12
+
13
+ /**
14
+ * Run before every test in every suite in this file
15
+ */
16
+ beforeEach(async () => {
17
+ // delete all themes
18
+ const deleteThemesCmd = spawnSync('frodo', [
19
+ 'theme',
20
+ 'delete',
21
+ '--all',
22
+ 'frodo-dev',
23
+ ]);
24
+ if (deleteThemesCmd.status > 0) {
25
+ console.error(deleteThemesCmd.stderr.toString());
26
+ console.log(deleteThemesCmd.stdout.toString());
27
+ }
28
+
29
+ // import test themes
30
+ const importTestThemesCmd = spawnSync(
31
+ 'frodo',
32
+ ['theme', 'import', '--all-separate', 'frodo-dev'],
33
+ {
34
+ cwd: `test/e2e/theme/baseline`,
35
+ }
36
+ );
37
+ if (importTestThemesCmd.status > 0) {
38
+ console.error(importTestThemesCmd.stderr.toString());
39
+ console.log(importTestThemesCmd.stdout.toString());
40
+ }
41
+ });
42
+
43
+ describe('frodo theme delete', () => {
44
+ it('"frodo theme delete -n Zardoz": should delete the Zardoz theme', (done) => {
45
+ const deleteThemeCmd = spawn('frodo', [
46
+ 'theme',
47
+ 'delete',
48
+ '-n',
49
+ 'Zardoz',
50
+ 'frodo-dev',
51
+ ]);
52
+ const expected = ['✔ Deleted Zardoz.', ''].join('\n');
53
+ const chunks = [];
54
+ deleteThemeCmd.stderr.on('data', (chunk) => {
55
+ chunks.push(chunk);
56
+ });
57
+ deleteThemeCmd.stderr.on('end', () => {
58
+ const output = Buffer.concat(chunks)
59
+ .toString()
60
+ .replace(ansiEscapeCodes, '');
61
+ try {
62
+ expect(output).toContain(expected);
63
+ done();
64
+ } catch (error) {
65
+ done(error);
66
+ }
67
+ });
68
+ });
69
+
70
+ it('"frodo theme delete -n DoesNotExist": should report an error that the theme does not exist', (done) => {
71
+ const deleteThemeCmd = spawn('frodo', [
72
+ 'theme',
73
+ 'delete',
74
+ '-n',
75
+ 'DoesNotExist',
76
+ 'frodo-dev',
77
+ ]);
78
+ const expected = ['✖ Error: DoesNotExist not found', ''].join('\n');
79
+ const chunks = [];
80
+ deleteThemeCmd.stderr.on('data', (chunk) => {
81
+ chunks.push(chunk);
82
+ });
83
+ deleteThemeCmd.stderr.on('end', () => {
84
+ const output = Buffer.concat(chunks)
85
+ .toString()
86
+ .replace(ansiEscapeCodes, '');
87
+ try {
88
+ expect(output).toContain(expected);
89
+ done();
90
+ } catch (error) {
91
+ done(error);
92
+ }
93
+ });
94
+ });
95
+
96
+ it('"frodo theme delete -i 4ded6d91-ceea-400a-ae3f-42209f1b0e06": should delete the 4ded6d91-ceea-400a-ae3f-42209f1b0e06 (Zardoz) theme', (done) => {
97
+ const deleteThemeCmd = spawn('frodo', [
98
+ 'theme',
99
+ 'delete',
100
+ '-i',
101
+ '4ded6d91-ceea-400a-ae3f-42209f1b0e06',
102
+ 'frodo-dev',
103
+ ]);
104
+ const expected = [
105
+ '✔ Deleted 4ded6d91-ceea-400a-ae3f-42209f1b0e06.',
106
+ '',
107
+ ].join('\n');
108
+ const chunks = [];
109
+ deleteThemeCmd.stderr.on('data', (chunk) => {
110
+ chunks.push(chunk);
111
+ });
112
+ deleteThemeCmd.stderr.on('end', () => {
113
+ const output = Buffer.concat(chunks)
114
+ .toString()
115
+ .replace(ansiEscapeCodes, '');
116
+ try {
117
+ expect(output).toContain(expected);
118
+ done();
119
+ } catch (error) {
120
+ done(error);
121
+ }
122
+ });
123
+ });
124
+
125
+ it('"frodo theme delete -i 4ded6d91-ceea-400a-ae3f-42209f1b0e07": should report an error that the theme does not exist', (done) => {
126
+ const deleteThemeCmd = spawn('frodo', [
127
+ 'theme',
128
+ 'delete',
129
+ '-i',
130
+ '4ded6d91-ceea-400a-ae3f-42209f1b0e07',
131
+ 'frodo-dev',
132
+ ]);
133
+ const expected = [
134
+ '✖ Error: 4ded6d91-ceea-400a-ae3f-42209f1b0e07 not found',
135
+ '',
136
+ ].join('\n');
137
+ const chunks = [];
138
+ deleteThemeCmd.stderr.on('data', (chunk) => {
139
+ chunks.push(chunk);
140
+ });
141
+ deleteThemeCmd.stderr.on('end', () => {
142
+ const output = Buffer.concat(chunks)
143
+ .toString()
144
+ .replace(ansiEscapeCodes, '');
145
+ try {
146
+ expect(output).toContain(expected);
147
+ done();
148
+ } catch (error) {
149
+ done(error);
150
+ }
151
+ });
152
+ });
153
+
154
+ it('"frodo theme delete -a": should delete all themes', (done) => {
155
+ const deleteThemeCmd = spawn('frodo', [
156
+ 'theme',
157
+ 'delete',
158
+ '-a',
159
+ 'frodo-dev',
160
+ ]);
161
+ const expected = ['✔ Deleted all realm themes.', ''].join('\n');
162
+ const chunks = [];
163
+ deleteThemeCmd.stderr.on('data', (chunk) => {
164
+ chunks.push(chunk);
165
+ });
166
+ deleteThemeCmd.stderr.on('end', () => {
167
+ const output = Buffer.concat(chunks)
168
+ .toString()
169
+ .replace(ansiEscapeCodes, '');
170
+ try {
171
+ expect(output).toContain(expected);
172
+ done();
173
+ } catch (error) {
174
+ done(error);
175
+ }
176
+ });
177
+ });
178
+ });
@@ -0,0 +1,119 @@
1
+ // import { jest } from '@jest/globals';
2
+ import { spawn, spawnSync } from 'child_process';
3
+
4
+ const ansiEscapeCodes =
5
+ // eslint-disable-next-line no-control-regex
6
+ /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
7
+
8
+ /**
9
+ * delete all themes and import baseline and additional test themes
10
+ */
11
+ beforeAll(async () => {
12
+ // delete all themes
13
+ const deleteThemesCmd = spawnSync('frodo', [
14
+ 'theme',
15
+ 'delete',
16
+ '--all',
17
+ 'frodo-dev',
18
+ ]);
19
+ if (deleteThemesCmd.status > 0) {
20
+ console.error(deleteThemesCmd.stderr.toString());
21
+ console.log(deleteThemesCmd.stdout.toString());
22
+ }
23
+
24
+ // import baseline themes
25
+ const importBaselineThemesCmd = spawnSync(
26
+ 'frodo',
27
+ ['theme', 'import', '--all-separate', 'frodo-dev'],
28
+ {
29
+ cwd: `test/e2e/theme/baseline`,
30
+ }
31
+ );
32
+ if (importBaselineThemesCmd.status > 0) {
33
+ console.error(importBaselineThemesCmd.stderr.toString());
34
+ console.log(importBaselineThemesCmd.stdout.toString());
35
+ }
36
+ });
37
+
38
+ describe('frodo theme list', () => {
39
+ it('"frodo theme list": should list the names of the default themes', (done) => {
40
+ const themeList = spawn('frodo', ['theme', 'list', 'frodo-dev']);
41
+ const expected = [
42
+ 'Contrast',
43
+ 'Highlander',
44
+ 'Robroy',
45
+ 'Starter Theme',
46
+ 'Zardoz',
47
+ '',
48
+ ].join('\n');
49
+
50
+ const chunks = [];
51
+ themeList.stdout.on('data', (chunk) => {
52
+ chunks.push(chunk);
53
+ });
54
+
55
+ themeList.stdout.on('end', () => {
56
+ const output = Buffer.concat(chunks)
57
+ .toString()
58
+ .replace(ansiEscapeCodes, '');
59
+ try {
60
+ expect(output).toBe(expected);
61
+ done();
62
+ } catch (error) {
63
+ done(error);
64
+ }
65
+ });
66
+ });
67
+
68
+ const expectedLong = [
69
+ 'Name │Id │Default',
70
+ 'Contrast │cd6c93e2-52e2-4340-9770-66a588343841│ ',
71
+ 'Highlander │00203891-dde0-4114-b27a-219ae0b43a61│ ',
72
+ 'Robroy │b82755e8-fe9a-4d27-b66b-45e37ae12345│ ',
73
+ 'Starter Theme│86ce2f64-586d-44fe-8593-b12a85aac68d│Yes ',
74
+ 'Zardoz │4ded6d91-ceea-400a-ae3f-42209f1b0e06│ ',
75
+ '',
76
+ ].join('\n');
77
+
78
+ it('"frodo theme list -l": should list the names, ids, and default flag of the baseline themes', (done) => {
79
+ const themeList = spawn('frodo', ['theme', 'list', '-l', 'frodo-dev']);
80
+
81
+ const chunks = [];
82
+ themeList.stdout.on('data', (chunk) => {
83
+ chunks.push(chunk);
84
+ });
85
+
86
+ themeList.stdout.on('end', () => {
87
+ const output = Buffer.concat(chunks)
88
+ .toString()
89
+ .replace(ansiEscapeCodes, '');
90
+ try {
91
+ expect(output).toBe(expectedLong);
92
+ done();
93
+ } catch (error) {
94
+ done(error);
95
+ }
96
+ });
97
+ });
98
+
99
+ it('"frodo theme list --long": should list the names, status, and default flag of the baseline themes', (done) => {
100
+ const themeList = spawn('frodo', ['theme', 'list', '--long', 'frodo-dev']);
101
+
102
+ const chunks = [];
103
+ themeList.stdout.on('data', (chunk) => {
104
+ chunks.push(chunk);
105
+ });
106
+
107
+ themeList.stdout.on('end', () => {
108
+ const output = Buffer.concat(chunks)
109
+ .toString()
110
+ .replace(ansiEscapeCodes, '');
111
+ try {
112
+ expect(output).toBe(expectedLong);
113
+ done();
114
+ } catch (error) {
115
+ done(error);
116
+ }
117
+ });
118
+ });
119
+ });
File without changes
File without changes
@@ -0,0 +1,12 @@
1
+ // import { CircleOfTrustSkeleton } from "@rockcarver/frodo-lib/types/api/ApiTypes";
2
+ import { TypesRaw } from '@rockcarver/frodo-lib';
3
+
4
+ /**
5
+ * Get a one-line description of the circle of trust object
6
+ * @param {CircleOfTrustSkeleton} cotObj circle of trust object to describe
7
+ * @returns {string} a one-line description
8
+ */
9
+ export function getOneLineDescription(cotObj: TypesRaw.CircleOfTrustSkeleton): string {
10
+ const description = `[${cotObj._id['brightCyan']}]`;
11
+ return description;
12
+ }
@@ -0,0 +1,19 @@
1
+ import { EmailTemplateSkeleton } from '@rockcarver/frodo-lib/types/api/ApiTypes';
2
+
3
+ /**
4
+ * Get a one-line description of the email template
5
+ * @param {EmailTemplateSkeleton} templateObj email template object to describe
6
+ * @returns {string} a one-line description
7
+ */
8
+ export function getOneLineDescription(
9
+ templateObj: EmailTemplateSkeleton
10
+ ): string {
11
+ const description = `[${templateObj._id.split('/')[1]['brightCyan']}] ${
12
+ templateObj.displayName ? templateObj.displayName : ''
13
+ } - ${
14
+ templateObj.defaultLocale
15
+ ? templateObj.subject[templateObj.defaultLocale]
16
+ : Object.values(templateObj.subject)[0]
17
+ }`;
18
+ return description;
19
+ }
@@ -0,0 +1,11 @@
1
+ import { SocialIdpSkeleton } from "@rockcarver/frodo-lib/types/api/ApiTypes";
2
+
3
+ /**
4
+ * Get a one-line description of the social idp object
5
+ * @param {SocialIdpSkeleton} socialIdpObj social idp object to describe
6
+ * @returns {string} a one-line description
7
+ */
8
+ export function getOneLineDescription(socialIdpObj: SocialIdpSkeleton): string {
9
+ const description = `[${socialIdpObj._id['brightCyan']}] ${socialIdpObj._type._id}`;
10
+ return description;
11
+ }
@@ -0,0 +1,278 @@
1
+ import {
2
+ NodeSkeleton,
3
+ TreeSkeleton,
4
+ } from '@rockcarver/frodo-lib/types/api/ApiTypes';
5
+ import {
6
+ SingleTreeExportInterface,
7
+ TreeDependencyMapInterface,
8
+ TreeExportResolverInterface,
9
+ } from '@rockcarver/frodo-lib/types/ops/OpsTypes';
10
+ import { printMessage } from '../utils/Console';
11
+ import { Journey, Types, state } from '@rockcarver/frodo-lib';
12
+ import * as CirclesOfTrust from './CirclesOfTrustOps';
13
+ import * as EmailTemplate from './EmailTemplateOps';
14
+ import * as Idp from './IdpOps';
15
+ import * as Node from './NodeOps';
16
+ import * as Saml2 from './Saml2Ops';
17
+ import * as Script from './ScriptOps';
18
+ import * as Theme from './ThemeOps';
19
+
20
+ const {
21
+ onlineTreeExportResolver,
22
+ getTreeDescendents,
23
+ getNodeRef,
24
+ } = Journey;
25
+
26
+ /**
27
+ * Get journey classification
28
+ * @param {SingleTreeExportInterface} journey journey export
29
+ * @returns {stringp[]} Colored string array of classifications
30
+ */
31
+ export function getJourneyClassification(journey: SingleTreeExportInterface): string[] {
32
+ return Journey.getJourneyClassification(journey).map((it) => {
33
+ switch (it) {
34
+ case Types.JourneyClassification.STANDARD:
35
+ return it.toString()['brightGreen'];
36
+
37
+ case Types.JourneyClassification.CLOUD:
38
+ return it.toString()['brightMagenta'];
39
+
40
+ case Types.JourneyClassification.CUSTOM:
41
+ return it.toString()['brightRed'];
42
+
43
+ case Types.JourneyClassification.PREMIUM:
44
+ return it.toString()['brightYellow'];
45
+ }
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Get a one-line description of the tree object
51
+ * @param {TreeSkeleton} treeObj circle of trust object to describe
52
+ * @returns {string} a one-line description
53
+ */
54
+ export function getOneLineDescription(treeObj: TreeSkeleton): string {
55
+ const description = `[${treeObj._id['brightCyan']}]`;
56
+ return description;
57
+ }
58
+
59
+ /**
60
+ * Helper function to render a nested list of dependent trees
61
+ * @param {TreeDependencyMapInterface} descendents tree dependency map
62
+ * @param {number} depth level of nesting
63
+ */
64
+ function describeTreeDescendents(
65
+ descendents: TreeDependencyMapInterface,
66
+ depth = 0
67
+ ) {
68
+ if (depth || Object.values(descendents)[0].length) {
69
+ // heading
70
+ if (depth === 0) {
71
+ printMessage(
72
+ `\nInner Tree Dependencies (${Object.values(descendents)[0].length}):`,
73
+ 'data'
74
+ );
75
+ }
76
+ const indent = Array(depth * 2)
77
+ .fill(' ')
78
+ .join('');
79
+ const [tree] = Object.keys(descendents);
80
+ printMessage(`${indent}- ${tree['brightCyan']}`, 'data');
81
+ for (const descendent of descendents[tree]) {
82
+ describeTreeDescendents(descendent, depth + 1);
83
+ }
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Describe a journey:
89
+ * - Properties, tags, description, name, metadata
90
+ * - Inner tree dependency tree
91
+ * - Node type summary
92
+ * - Nodes
93
+ * - Themes
94
+ * - Scripts
95
+ * - Email templates
96
+ * - Social identity providers
97
+ * - SAML2 entity providers
98
+ * - SAML2 circles of trust
99
+ * @param {SingleTreeExportInterface} journeyData journey export object
100
+ * @param {TreeExportResolverInterface} resolveTreeExport tree export resolver callback function
101
+ */
102
+ export async function describeJourney(
103
+ journeyData: SingleTreeExportInterface,
104
+ resolveTreeExport: TreeExportResolverInterface = onlineTreeExportResolver
105
+ ): Promise<void> {
106
+ const allNodes = {
107
+ ...journeyData.nodes,
108
+ ...journeyData.innerNodes,
109
+ };
110
+ const nodeTypeMap = {};
111
+
112
+ for (const nodeData of Object.values(allNodes)) {
113
+ if (nodeTypeMap[nodeData._type._id]) {
114
+ nodeTypeMap[nodeData._type._id] += 1;
115
+ } else {
116
+ nodeTypeMap[nodeData._type._id] = 1;
117
+ }
118
+ }
119
+
120
+ // Journey Name
121
+ printMessage(`${getOneLineDescription(journeyData.tree)}`, 'data');
122
+ printMessage(Array(`[${journeyData.tree._id}]`['length']).fill('=').join(''));
123
+
124
+ // Description
125
+ if (journeyData.tree.description) {
126
+ printMessage(`\n${journeyData.tree.description}`, 'data');
127
+ }
128
+
129
+ // Status
130
+ printMessage(
131
+ `\nStatus\n${
132
+ journeyData.tree.enabled === false
133
+ ? 'disabled'['brightRed']
134
+ : 'enabled'['brightGreen']
135
+ }`
136
+ );
137
+
138
+ // Classification
139
+ if (
140
+ !state.default.session.getAmVersion() &&
141
+ journeyData.meta?.originAmVersion
142
+ ) {
143
+ state.default.session.setAmVersion(journeyData.meta.originAmVersion);
144
+ }
145
+ if (state.default.session.getAmVersion()) {
146
+ printMessage(
147
+ `\nClassification\n${getJourneyClassification(journeyData).join(', ')}`,
148
+ 'data'
149
+ );
150
+ }
151
+
152
+ // Categories/Tags
153
+ if (journeyData.tree.uiConfig?.categories && journeyData.tree.uiConfig.categories != '[]') {
154
+ printMessage('\nCategories/Tags', 'data');
155
+ printMessage(
156
+ `${
157
+ JSON.parse(journeyData.tree.uiConfig.categories).join(', ')
158
+ }`,
159
+ 'data'
160
+ );
161
+ }
162
+
163
+ // Dependency Tree
164
+ const descendents = await getTreeDescendents(journeyData, resolveTreeExport);
165
+ describeTreeDescendents(descendents);
166
+
167
+ // Node Types
168
+ if (Object.entries(nodeTypeMap).length) {
169
+ printMessage(
170
+ `\nNode Types (${Object.entries(nodeTypeMap).length}):`,
171
+ 'data'
172
+ );
173
+ for (const [nodeType, count] of Object.entries(nodeTypeMap)) {
174
+ printMessage(
175
+ `- ${String(count)} [${
176
+ nodeType['brightCyan']
177
+ }] (${Node.getNodeClassification(nodeType).join(', ')})`,
178
+ 'data'
179
+ );
180
+ }
181
+ }
182
+
183
+ // Nodes
184
+ if (Object.entries(allNodes).length) {
185
+ printMessage(`\nNodes (${Object.entries(allNodes).length}):`, 'data');
186
+ for (const nodeObj of Object.values<NodeSkeleton>(allNodes)) {
187
+ printMessage(
188
+ `- ${Node.getOneLineDescription(
189
+ nodeObj,
190
+ getNodeRef(nodeObj, journeyData)
191
+ )}`,
192
+ 'data'
193
+ );
194
+ }
195
+ }
196
+
197
+ // Themes
198
+ if (journeyData.themes?.length) {
199
+ printMessage(`\nThemes (${journeyData.themes.length}):`, 'data');
200
+ for (const themeData of journeyData.themes) {
201
+ printMessage(`- ${Theme.getOneLineDescription(themeData)}`, 'data');
202
+ }
203
+ }
204
+
205
+ // Scripts
206
+ if (Object.entries(journeyData.scripts).length) {
207
+ printMessage(
208
+ `\nScripts (${Object.entries(journeyData.scripts).length}):`,
209
+ 'data'
210
+ );
211
+ for (const scriptData of Object.values(journeyData.scripts)) {
212
+ printMessage(`- ${Script.getOneLineDescription(scriptData)}`, 'data');
213
+ }
214
+ }
215
+
216
+ // Email Templates
217
+ if (Object.entries(journeyData.emailTemplates).length) {
218
+ printMessage(
219
+ `\nEmail Templates (${
220
+ Object.entries(journeyData.emailTemplates).length
221
+ }):`,
222
+ 'data'
223
+ );
224
+ for (const templateData of Object.values(journeyData.emailTemplates)) {
225
+ printMessage(
226
+ `- ${EmailTemplate.getOneLineDescription(templateData)}`,
227
+ 'data'
228
+ );
229
+ }
230
+ }
231
+
232
+ // Social Identity Providers
233
+ if (Object.entries(journeyData.socialIdentityProviders).length) {
234
+ printMessage(
235
+ `\nSocial Identity Providers (${
236
+ Object.entries(journeyData.socialIdentityProviders).length
237
+ }):`,
238
+ 'data'
239
+ );
240
+ for (const socialIdpData of Object.values(
241
+ journeyData.socialIdentityProviders
242
+ )) {
243
+ printMessage(`- ${Idp.getOneLineDescription(socialIdpData)}`, 'data');
244
+ }
245
+ }
246
+
247
+ // SAML2 Entity Providers
248
+ if (Object.entries(journeyData.saml2Entities).length) {
249
+ printMessage(
250
+ `\nSAML2 Entity Providers (${
251
+ Object.entries(journeyData.saml2Entities).length
252
+ }):`,
253
+ 'data'
254
+ );
255
+ for (const entityProviderData of Object.values(journeyData.saml2Entities)) {
256
+ printMessage(
257
+ `- ${Saml2.getOneLineDescription(entityProviderData)}`,
258
+ 'data'
259
+ );
260
+ }
261
+ }
262
+
263
+ // SAML2 Circles Of Trust
264
+ if (Object.entries(journeyData.circlesOfTrust).length) {
265
+ printMessage(
266
+ `\nSAML2 Circles Of Trust (${
267
+ Object.entries(journeyData.circlesOfTrust).length
268
+ }):`,
269
+ 'data'
270
+ );
271
+ for (const cotData of Object.values(journeyData.circlesOfTrust)) {
272
+ printMessage(
273
+ `- ${CirclesOfTrust.getOneLineDescription(cotData)}`,
274
+ 'data'
275
+ );
276
+ }
277
+ }
278
+ }