@rockcarver/frodo-cli 0.13.3 → 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.
- package/CHANGELOG.md +21 -1
- package/babel.config.esm.json +6 -0
- package/package.json +14 -7
- package/src/{app.js → app.ts} +14 -14
- package/src/cli/_template/{cmd-delete.js → cmd-delete.ts} +0 -0
- package/src/cli/_template/{cmd-describe.js → cmd-describe.ts} +0 -0
- package/src/cli/_template/{cmd-export.js → cmd-export.ts} +0 -0
- package/src/cli/_template/{cmd-import.js → cmd-import.ts} +0 -0
- package/src/cli/_template/{cmd-list.js → cmd-list.ts} +0 -0
- package/src/cli/_template/{cmd-sub1-delete.js → cmd-sub1-delete.ts} +0 -0
- package/src/cli/_template/{cmd-sub1-describe.js → cmd-sub1-describe.ts} +0 -0
- package/src/cli/_template/{cmd-sub1-export.js → cmd-sub1-export.ts} +0 -0
- package/src/cli/_template/{cmd-sub1-import.js → cmd-sub1-import.ts} +0 -0
- package/src/cli/_template/{cmd-sub1-list.js → cmd-sub1-list.ts} +0 -0
- package/src/cli/_template/{cmd-sub1.js → cmd-sub1.ts} +0 -0
- package/src/cli/_template/{cmd-sub2-delete.js → cmd-sub2-delete.ts} +0 -0
- package/src/cli/_template/{cmd-sub2-describe.js → cmd-sub2-describe.ts} +0 -0
- package/src/cli/_template/{cmd-sub2-export.js → cmd-sub2-export.ts} +0 -0
- package/src/cli/_template/{cmd-sub2-import.js → cmd-sub2-import.ts} +0 -0
- package/src/cli/_template/{cmd-sub2-list.js → cmd-sub2-list.ts} +0 -0
- package/src/cli/_template/{cmd-sub2.js → cmd-sub2.ts} +0 -0
- package/src/cli/_template/{cmd.js → cmd.ts} +0 -0
- package/src/cli/admin/{admin-add-autoid-static-user-mapping.js → admin-add-autoid-static-user-mapping.ts} +0 -0
- package/src/cli/admin/{admin-create-oauth2-client-with-admin-privileges.js → admin-create-oauth2-client-with-admin-privileges.ts} +0 -0
- package/src/cli/admin/{admin-get-access-token.js → admin-get-access-token.ts} +0 -0
- package/src/cli/admin/{admin-grant-oauth2-client-admin-privileges.js → admin-grant-oauth2-client-admin-privileges.ts} +0 -0
- package/src/cli/admin/{admin-hide-generic-extension-attributes.js → admin-hide-generic-extension-attributes.ts} +0 -0
- package/src/cli/admin/{admin-list-oauth2-clients-with-admin-privileges.js → admin-list-oauth2-clients-with-admin-privileges.ts} +0 -0
- package/src/cli/admin/{admin-list-oauth2-clients-with-custom-privileges.js → admin-list-oauth2-clients-with-custom-privileges.ts} +0 -0
- package/src/cli/admin/{admin-list-static-user-mappings.js → admin-list-static-user-mappings.ts} +0 -0
- package/src/cli/admin/{admin-remove-static-user-mapping.js → admin-remove-static-user-mapping.ts} +0 -0
- package/src/cli/admin/{admin-repair-org-model.js → admin-repair-org-model.ts} +7 -1
- package/src/cli/admin/{admin-revoke-oauth2-client-admin-privileges.js → admin-revoke-oauth2-client-admin-privileges.ts} +0 -0
- package/src/cli/admin/{admin-show-generic-extension-attributes.js → admin-show-generic-extension-attributes.ts} +0 -0
- package/src/cli/admin/{admin.js → admin.ts} +0 -0
- package/src/cli/app/{app-delete.js → app-delete.ts} +0 -0
- package/src/cli/app/{app-describe.js → app-describe.ts} +0 -0
- package/src/cli/app/{app-export.js → app-export.ts} +0 -0
- package/src/cli/app/{app-import.js → app-import.ts} +0 -0
- package/src/cli/app/{app-list.js → app-list.ts} +0 -0
- package/src/cli/app/{app.js → app.ts} +0 -0
- package/src/cli/{cmd_common.js → cmd_common.ts} +0 -0
- package/src/cli/conn/{conn-add.js → conn-add.ts} +0 -0
- package/src/cli/conn/{conn-delete.js → conn-delete.ts} +0 -0
- package/src/cli/conn/{conn-describe.js → conn-describe.ts} +0 -0
- package/src/cli/conn/{conn-list.js → conn-list.ts} +0 -0
- package/src/cli/conn/{conn.js → conn.ts} +0 -0
- package/src/cli/email/{email-template-export.js → email-template-export.ts} +0 -0
- package/src/cli/email/{email-template-import.js → email-template-import.ts} +0 -0
- package/src/cli/email/{email-template-list.js → email-template-list.ts} +0 -0
- package/src/cli/email/{email-template.js → email-template.ts} +0 -0
- package/src/cli/email/{email.js → email.ts} +0 -0
- package/src/cli/esv/{esv-apply.js → esv-apply.ts} +0 -0
- package/src/cli/esv/{esv-secret-create.js → esv-secret-create.ts} +0 -0
- package/src/cli/esv/{esv-secret-delete.js → esv-secret-delete.ts} +0 -0
- package/src/cli/esv/{esv-secret-describe.js → esv-secret-describe.ts} +0 -0
- package/src/cli/esv/{esv-secret-export.js → esv-secret-export.ts} +0 -0
- package/src/cli/esv/{esv-secret-import.js → esv-secret-import.ts} +0 -0
- package/src/cli/esv/{esv-secret-list.js → esv-secret-list.ts} +0 -0
- package/src/cli/esv/{esv-secret-set.js → esv-secret-set.ts} +0 -0
- package/src/cli/esv/{esv-secret-version-activate.js → esv-secret-version-activate.ts} +0 -0
- package/src/cli/esv/{esv-secret-version-create.js → esv-secret-version-create.ts} +0 -0
- package/src/cli/esv/{esv-secret-version-deactivate.js → esv-secret-version-deactivate.ts} +0 -0
- package/src/cli/esv/{esv-secret-version-delete.js → esv-secret-version-delete.ts} +0 -0
- package/src/cli/esv/{esv-secret-version-list.js → esv-secret-version-list.ts} +0 -0
- package/src/cli/esv/{esv-secret-version.js → esv-secret-version.ts} +0 -0
- package/src/cli/esv/{esv-secret.js → esv-secret.ts} +0 -0
- package/src/cli/esv/{esv-variable-create.js → esv-variable-create.ts} +0 -0
- package/src/cli/esv/{esv-variable-delete.js → esv-variable-delete.ts} +0 -0
- package/src/cli/esv/{esv-variable-describe.js → esv-variable-describe.ts} +0 -0
- package/src/cli/esv/{esv-variable-export.js → esv-variable-export.ts} +0 -0
- package/src/cli/esv/{esv-variable-import.js → esv-variable-import.ts} +0 -0
- package/src/cli/esv/{esv-variable-list.js → esv-variable-list.ts} +0 -0
- package/src/cli/esv/{esv-variable-set.js → esv-variable-set.ts} +0 -0
- package/src/cli/esv/{esv-variable.js → esv-variable.ts} +0 -0
- package/src/cli/esv/{esv.js → esv.ts} +0 -0
- package/src/cli/idm/{idm-count.js → idm-count.ts} +0 -0
- package/src/cli/idm/{idm-export.js → idm-export.ts} +0 -0
- package/src/cli/idm/{idm-list.js → idm-list.ts} +0 -0
- package/src/cli/idm/{idm.js → idm.ts} +0 -0
- package/src/cli/idp/{idp-export.js → idp-export.ts} +0 -0
- package/src/cli/idp/{idp-import.js → idp-import.ts} +0 -0
- package/src/cli/idp/{idp-list.js → idp-list.ts} +0 -0
- package/src/cli/idp/{idp.js → idp.ts} +0 -0
- package/src/cli/info/{info.js → info.ts} +1 -1
- package/src/cli/journey/journey-delete.e2e.test_.ts +380 -0
- package/src/cli/journey/{journey-delete.js → journey-delete.ts} +0 -0
- package/src/cli/journey/{journey-describe.js → journey-describe.ts} +19 -14
- package/src/cli/journey/{journey-export.js → journey-export.ts} +0 -0
- package/src/cli/journey/{journey-import.js → journey-import.ts} +0 -0
- package/src/cli/journey/journey-list.e2e.test_.ts +142 -0
- package/src/cli/journey/{journey-list.js → journey-list.ts} +0 -0
- package/src/cli/journey/{journey-prune.js → journey-prune.ts} +0 -0
- package/src/cli/journey/{journey.js → journey.ts} +0 -0
- package/src/cli/logging/{logs-list.js → logs-list.ts} +0 -0
- package/src/cli/logging/{logs-tail.js → logs-tail.ts} +0 -0
- package/src/cli/logging/{logs.js → logs.ts} +0 -0
- package/src/cli/realm/{realm-add-custom-domain.js → realm-add-custom-domain.ts} +0 -0
- package/src/cli/realm/{realm-describe.js → realm-describe.ts} +0 -0
- package/src/cli/realm/{realm-list.js → realm-list.ts} +0 -0
- package/src/cli/realm/{realm-remove-custom-domain.js → realm-remove-custom-domain.ts} +0 -0
- package/src/cli/realm/{realm.js → realm.ts} +0 -0
- package/src/cli/saml/{saml-cot-export.js → saml-cot-export.ts} +0 -0
- package/src/cli/saml/{saml-cot-import.js → saml-cot-import.ts} +0 -0
- package/src/cli/saml/{saml-cot-list.js → saml-cot-list.ts} +0 -0
- package/src/cli/saml/{saml-cot.js → saml-cot.ts} +0 -0
- package/src/cli/saml/{saml-describe.js → saml-describe.ts} +0 -0
- package/src/cli/saml/{saml-export.js → saml-export.ts} +0 -0
- package/src/cli/saml/{saml-import.js → saml-import.ts} +0 -0
- package/src/cli/saml/{saml-list.js → saml-list.ts} +0 -0
- package/src/cli/saml/{saml-metadata-export.js → saml-metadata-export.ts} +0 -0
- package/src/cli/saml/{saml-metadata.js → saml-metadata.ts} +0 -0
- package/src/cli/saml/{saml.js → saml.ts} +0 -0
- package/src/cli/script/{script-delete.js → script-delete.ts} +0 -0
- package/src/cli/script/{script-describe.js → script-describe.ts} +0 -0
- package/src/cli/script/{script-export.js → script-export.ts} +0 -0
- package/src/cli/script/{script-import.js → script-import.ts} +0 -0
- package/src/cli/script/{script-list.js → script-list.ts} +0 -0
- package/src/cli/script/{script.js → script.ts} +0 -0
- package/src/cli/theme/theme-delete.e2e.test_.ts +178 -0
- package/src/cli/theme/{theme-delete.js → theme-delete.ts} +0 -0
- package/src/cli/theme/{theme-export.js → theme-export.ts} +0 -0
- package/src/cli/theme/{theme-import.js → theme-import.ts} +0 -0
- package/src/cli/theme/theme-list.e2e.test_.ts +119 -0
- package/src/cli/theme/{theme-list.js → theme-list.ts} +0 -0
- package/src/cli/theme/{theme.js → theme.ts} +0 -0
- package/src/ops/CirclesOfTrustOps.ts +12 -0
- package/src/ops/EmailTemplateOps.ts +19 -0
- package/src/ops/IdpOps.ts +11 -0
- package/src/ops/JourneyOps.ts +278 -0
- package/src/ops/NodeOps.ts +47 -0
- package/src/ops/Saml2Ops.ts +24 -0
- package/src/ops/ScriptOps.ts +11 -0
- package/src/ops/ThemeOps.ts +17 -0
- package/src/ops/utils/Wordwrap.ts +11 -0
- package/src/storage/{StaticStorage.js → StaticStorage.ts} +0 -0
- package/src/utils/{Console.js → Console.ts} +3 -2
- package/tsconfig.json +6 -6
|
@@ -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
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
InnerNodeRefSkeletonInterface,
|
|
3
|
+
NodeRefSkeletonInterface,
|
|
4
|
+
NodeSkeleton,
|
|
5
|
+
} from '@rockcarver/frodo-lib/types/api/ApiTypes';
|
|
6
|
+
import { Node, Types } from '@rockcarver/frodo-lib';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get node classification
|
|
10
|
+
* @param {string} nodeType node type
|
|
11
|
+
* @returns {stringp[]} Colored string array of classifications
|
|
12
|
+
*/
|
|
13
|
+
export function getNodeClassification(nodeType: string): string[] {
|
|
14
|
+
return Node.getNodeClassification(nodeType).map((it) => {
|
|
15
|
+
switch (it) {
|
|
16
|
+
case Types.NodeClassification.STANDARD:
|
|
17
|
+
return it.toString()['brightGreen'];
|
|
18
|
+
|
|
19
|
+
case Types.NodeClassification.CLOUD:
|
|
20
|
+
return it.toString()['brightMagenta'];
|
|
21
|
+
|
|
22
|
+
case Types.NodeClassification.CUSTOM:
|
|
23
|
+
return it.toString()['brightRed'];
|
|
24
|
+
|
|
25
|
+
case Types.NodeClassification.PREMIUM:
|
|
26
|
+
return it.toString()['brightYellow'];
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get a one-line description of the node
|
|
33
|
+
* @param {NodeSkeleton} nodeObj node object to describe
|
|
34
|
+
* @param {NodeRefSkeletonInterface | InnerNodeRefSkeletonInterface} nodeRef node reference object
|
|
35
|
+
* @returns {string} a one-line description
|
|
36
|
+
*/
|
|
37
|
+
export function getOneLineDescription(
|
|
38
|
+
nodeObj: NodeSkeleton,
|
|
39
|
+
nodeRef?: NodeRefSkeletonInterface | InnerNodeRefSkeletonInterface
|
|
40
|
+
): string {
|
|
41
|
+
const description = `[${nodeObj._id['brightCyan']}] (${getNodeClassification(
|
|
42
|
+
nodeObj._type._id
|
|
43
|
+
).join(', ')}) ${nodeObj._type._id}${
|
|
44
|
+
nodeRef ? ' - ' + nodeRef?.displayName : ''
|
|
45
|
+
}`;
|
|
46
|
+
return description;
|
|
47
|
+
}
|