@credibledata/cred-cli 0.1.3 → 0.1.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 (172) hide show
  1. package/.prettierignore +2 -1
  2. package/README.md +0 -2
  3. package/bun.lock +182 -283
  4. package/dist/client/api.js +804 -111
  5. package/dist/client/api.js.map +1 -1
  6. package/dist/clientconfiguration.js +55 -13
  7. package/dist/clientconfiguration.js.map +1 -1
  8. package/dist/clientconfiguration.spec.js +305 -16
  9. package/dist/clientconfiguration.spec.js.map +1 -1
  10. package/dist/commands/add.js +6 -3
  11. package/dist/commands/add.js.map +1 -1
  12. package/dist/commands/connection/createconnections.js +18 -3
  13. package/dist/commands/connection/createconnections.js.map +1 -1
  14. package/dist/commands/connection/createconnections.spec.js +219 -0
  15. package/dist/commands/connection/createconnections.spec.js.map +1 -0
  16. package/dist/commands/connection/deleteconnection.spec.js +130 -0
  17. package/dist/commands/connection/deleteconnection.spec.js.map +1 -0
  18. package/dist/commands/connection/listconnections.js +9 -3
  19. package/dist/commands/connection/listconnections.js.map +1 -1
  20. package/dist/commands/connection/listconnections.spec.js +117 -0
  21. package/dist/commands/connection/listconnections.spec.js.map +1 -0
  22. package/dist/commands/group/addmember.js +2 -0
  23. package/dist/commands/group/addmember.js.map +1 -1
  24. package/dist/commands/group/addmember.spec.js +148 -0
  25. package/dist/commands/group/addmember.spec.js.map +1 -0
  26. package/dist/commands/group/creategroup.spec.js +122 -0
  27. package/dist/commands/group/creategroup.spec.js.map +1 -0
  28. package/dist/commands/group/deletegroup.spec.js +104 -0
  29. package/dist/commands/group/deletegroup.spec.js.map +1 -0
  30. package/dist/commands/group/getgroup.spec.js +111 -0
  31. package/dist/commands/group/getgroup.spec.js.map +1 -0
  32. package/dist/commands/group/listgroups.spec.js +118 -0
  33. package/dist/commands/group/listgroups.spec.js.map +1 -0
  34. package/dist/commands/group/removemember.js +1 -0
  35. package/dist/commands/group/removemember.js.map +1 -1
  36. package/dist/commands/group/removemember.spec.js +138 -0
  37. package/dist/commands/group/removemember.spec.js.map +1 -0
  38. package/dist/commands/groupaccesstoken/createToken.js +6 -2
  39. package/dist/commands/groupaccesstoken/createToken.js.map +1 -1
  40. package/dist/commands/groupaccesstoken/createToken.spec.js +127 -0
  41. package/dist/commands/groupaccesstoken/createToken.spec.js.map +1 -0
  42. package/dist/commands/groupaccesstoken/deleteToken.js.map +1 -1
  43. package/dist/commands/groupaccesstoken/deleteToken.spec.js +103 -0
  44. package/dist/commands/groupaccesstoken/deleteToken.spec.js.map +1 -0
  45. package/dist/commands/groupaccesstoken/groupContainer.js.map +1 -1
  46. package/dist/commands/groupaccesstoken/listTokens.js.map +1 -1
  47. package/dist/commands/groupaccesstoken/listTokens.spec.js +115 -0
  48. package/dist/commands/groupaccesstoken/listTokens.spec.js.map +1 -0
  49. package/dist/commands/list.js +10 -3
  50. package/dist/commands/list.js.map +1 -1
  51. package/dist/commands/misc/login.js +146 -22
  52. package/dist/commands/misc/login.js.map +1 -1
  53. package/dist/commands/misc/login.spec.js +111 -6
  54. package/dist/commands/misc/login.spec.js.map +1 -1
  55. package/dist/commands/misc/logout.spec.js +30 -0
  56. package/dist/commands/misc/logout.spec.js.map +1 -0
  57. package/dist/commands/misc/loopbackOAuth.js +110 -0
  58. package/dist/commands/misc/loopbackOAuth.js.map +1 -0
  59. package/dist/commands/misc/set-access-token.js.map +1 -1
  60. package/dist/commands/misc/set-access-token.spec.js +65 -0
  61. package/dist/commands/misc/set-access-token.spec.js.map +1 -0
  62. package/dist/commands/package/deletepackage.spec.js +136 -0
  63. package/dist/commands/package/deletepackage.spec.js.map +1 -0
  64. package/dist/commands/package/listpackages.js +10 -5
  65. package/dist/commands/package/listpackages.js.map +1 -1
  66. package/dist/commands/package/listpackages.spec.js +129 -0
  67. package/dist/commands/package/listpackages.spec.js.map +1 -0
  68. package/dist/commands/package/publish.js +23 -0
  69. package/dist/commands/package/publish.js.map +1 -1
  70. package/dist/commands/package/publish.spec.js +511 -0
  71. package/dist/commands/package/publish.spec.js.map +1 -0
  72. package/dist/commands/package/updatepackage.spec.js +50 -0
  73. package/dist/commands/package/updatepackage.spec.js.map +1 -1
  74. package/dist/commands/project/createproject.js +11 -1
  75. package/dist/commands/project/createproject.js.map +1 -1
  76. package/dist/commands/project/createproject.spec.js +154 -0
  77. package/dist/commands/project/createproject.spec.js.map +1 -0
  78. package/dist/commands/project/deleteproject.spec.js +106 -0
  79. package/dist/commands/project/deleteproject.spec.js.map +1 -0
  80. package/dist/commands/project/getproject.spec.js +99 -0
  81. package/dist/commands/project/getproject.spec.js.map +1 -0
  82. package/dist/commands/project/listprojects.js +13 -7
  83. package/dist/commands/project/listprojects.js.map +1 -1
  84. package/dist/commands/project/listprojects.spec.js +111 -0
  85. package/dist/commands/project/listprojects.spec.js.map +1 -0
  86. package/dist/commands/project/setproject.spec.js +58 -0
  87. package/dist/commands/project/setproject.spec.js.map +1 -0
  88. package/dist/commands/project/updateproject.js +68 -0
  89. package/dist/commands/project/updateproject.js.map +1 -0
  90. package/dist/commands/project/updateproject.spec.js +129 -0
  91. package/dist/commands/project/updateproject.spec.js.map +1 -0
  92. package/dist/commands/rm.js.map +1 -1
  93. package/dist/commands/update.js +13 -0
  94. package/dist/commands/update.js.map +1 -1
  95. package/dist/commands/version/listversions.spec.js +121 -0
  96. package/dist/commands/version/listversions.spec.js.map +1 -0
  97. package/dist/common/UserGroupId.spec.js +92 -0
  98. package/dist/common/UserGroupId.spec.js.map +1 -0
  99. package/dist/constants.js +49 -13
  100. package/dist/constants.js.map +1 -1
  101. package/dist/index.js +40 -18
  102. package/dist/index.js.map +1 -1
  103. package/dist/logger.spec.js +125 -0
  104. package/dist/logger.spec.js.map +1 -0
  105. package/dist/polyfills/file.polyfill.js.map +1 -1
  106. package/dist/utils.js +59 -0
  107. package/dist/utils.js.map +1 -1
  108. package/dist/utils.spec.js +158 -0
  109. package/dist/utils.spec.js.map +1 -0
  110. package/docker/Dockerfile.ci +11 -3
  111. package/eslint.config.mjs +45 -0
  112. package/generate-client.sh +5 -0
  113. package/package.json +24 -16
  114. package/src/client/.openapi-generator/FILES +1 -0
  115. package/src/client/api.ts +1999 -696
  116. package/src/clientconfiguration.spec.ts +394 -20
  117. package/src/clientconfiguration.ts +74 -15
  118. package/src/commands/add.ts +15 -6
  119. package/src/commands/connection/createconnections.spec.ts +403 -0
  120. package/src/commands/connection/createconnections.ts +30 -5
  121. package/src/commands/connection/deleteconnection.spec.ts +189 -0
  122. package/src/commands/connection/listconnections.spec.ts +132 -0
  123. package/src/commands/connection/listconnections.ts +22 -3
  124. package/src/commands/group/addmember.spec.ts +257 -0
  125. package/src/commands/group/addmember.ts +2 -0
  126. package/src/commands/group/creategroup.spec.ts +146 -0
  127. package/src/commands/group/deletegroup.spec.ts +120 -0
  128. package/src/commands/group/getgroup.spec.ts +129 -0
  129. package/src/commands/group/listgroups.spec.ts +137 -0
  130. package/src/commands/group/removemember.spec.ts +224 -0
  131. package/src/commands/group/removemember.ts +1 -0
  132. package/src/commands/groupaccesstoken/createToken.spec.ts +211 -0
  133. package/src/commands/groupaccesstoken/createToken.ts +55 -51
  134. package/src/commands/groupaccesstoken/deleteToken.spec.ts +147 -0
  135. package/src/commands/groupaccesstoken/deleteToken.ts +16 -11
  136. package/src/commands/groupaccesstoken/groupContainer.ts +51 -51
  137. package/src/commands/groupaccesstoken/listTokens.spec.ts +147 -0
  138. package/src/commands/groupaccesstoken/listTokens.ts +16 -11
  139. package/src/commands/list.ts +50 -9
  140. package/src/commands/misc/login.spec.ts +91 -6
  141. package/src/commands/misc/login.ts +208 -25
  142. package/src/commands/misc/logout.spec.ts +32 -0
  143. package/src/commands/misc/loopbackOAuth.ts +127 -0
  144. package/src/commands/misc/set-access-token.spec.ts +95 -0
  145. package/src/commands/misc/set-access-token.ts +16 -16
  146. package/src/commands/package/deletepackage.spec.ts +164 -0
  147. package/src/commands/package/listpackages.spec.ts +147 -0
  148. package/src/commands/package/listpackages.ts +28 -5
  149. package/src/commands/package/publish.spec.ts +597 -0
  150. package/src/commands/package/publish.ts +32 -0
  151. package/src/commands/package/updatepackage.spec.ts +98 -0
  152. package/src/commands/project/createproject.spec.ts +247 -0
  153. package/src/commands/project/createproject.ts +12 -1
  154. package/src/commands/project/deleteproject.spec.ts +123 -0
  155. package/src/commands/project/getproject.spec.ts +109 -0
  156. package/src/commands/project/listprojects.spec.ts +121 -0
  157. package/src/commands/project/listprojects.ts +33 -7
  158. package/src/commands/project/setproject.spec.ts +63 -0
  159. package/src/commands/project/updateproject.spec.ts +217 -0
  160. package/src/commands/project/updateproject.ts +82 -0
  161. package/src/commands/rm.ts +1 -6
  162. package/src/commands/update.ts +24 -1
  163. package/src/commands/version/listversions.spec.ts +138 -0
  164. package/src/common/UserGroupId.spec.ts +117 -0
  165. package/src/constants.ts +59 -13
  166. package/src/index.ts +46 -20
  167. package/src/logger.spec.ts +158 -0
  168. package/src/polyfills/file.polyfill.ts +1 -0
  169. package/src/utils.spec.ts +135 -0
  170. package/src/utils.ts +81 -0
  171. package/tsconfig.json +15 -18
  172. package/.eslintrc +0 -33
@@ -0,0 +1,211 @@
1
+ import { expect } from "chai";
2
+ import sinon from "sinon";
3
+ import { GroupsApi } from "../../client/api";
4
+ import { ClientConfiguration } from "../../clientconfiguration";
5
+ import { logger } from "../../logger";
6
+ import { createGroupAccessToken } from "./createToken";
7
+
8
+ describe("create-group-access-token", () => {
9
+ let sandbox: sinon.SinonSandbox;
10
+ let createGroupAccessTokenStub: sinon.SinonStub;
11
+ let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
12
+ let consoleLogStub: sinon.SinonStub;
13
+ let processExitStub: sinon.SinonStub;
14
+
15
+ beforeEach(() => {
16
+ sandbox = sinon.createSandbox();
17
+ createGroupAccessTokenStub = sandbox.stub();
18
+ loggerStub = sandbox.stub(logger);
19
+ consoleLogStub = sandbox.stub(console, "log");
20
+ processExitStub = sandbox.stub(process, "exit");
21
+
22
+ sandbox
23
+ .stub(ClientConfiguration.prototype, "getOrganization")
24
+ .returns("test-org");
25
+ sandbox
26
+ .stub(ClientConfiguration.prototype, "doesConfigExists")
27
+ .returns(true);
28
+ sandbox
29
+ .stub(ClientConfiguration.prototype, "getAuthenticationHeader")
30
+ .returns("Bearer test-token");
31
+
32
+ sandbox
33
+ .stub(GroupsApi.prototype, "createGroupAccessToken")
34
+ .callsFake(createGroupAccessTokenStub);
35
+ });
36
+
37
+ afterEach(() => {
38
+ sandbox.restore();
39
+ });
40
+
41
+ it("should create group access token successfully", async () => {
42
+ const mockResponse = {
43
+ data: { tokenName: "test-token", secret: "secret-value" },
44
+ };
45
+ createGroupAccessTokenStub.resolves(mockResponse);
46
+
47
+ const result = await createGroupAccessToken(
48
+ "http://test-server",
49
+ "test-group",
50
+ "test-token",
51
+ undefined,
52
+ false,
53
+ false,
54
+ );
55
+
56
+ expect(createGroupAccessTokenStub.calledOnce).to.be.true;
57
+ expect(createGroupAccessTokenStub.firstCall.args[0]).to.equal("test-org");
58
+ expect(createGroupAccessTokenStub.firstCall.args[1]).to.equal(
59
+ "test-group",
60
+ );
61
+ expect(createGroupAccessTokenStub.firstCall.args[2]).to.equal(
62
+ "test-token",
63
+ );
64
+ expect(createGroupAccessTokenStub.firstCall.args[3]).to.be.undefined;
65
+ expect(consoleLogStub.called).to.be.true;
66
+ expect(
67
+ loggerStub.info.calledWith(
68
+ sinon.match("Group access token created successfully"),
69
+ ),
70
+ ).to.be.true;
71
+ expect(result).to.deep.equal(mockResponse.data);
72
+ });
73
+
74
+ it("should create token with expiration date", async () => {
75
+ const futureDate = new Date();
76
+ futureDate.setFullYear(futureDate.getFullYear() + 1);
77
+ const expiresAt = futureDate.toISOString();
78
+ const mockResponse = {
79
+ data: { tokenName: "test-token" },
80
+ };
81
+ createGroupAccessTokenStub.resolves(mockResponse);
82
+
83
+ await createGroupAccessToken(
84
+ "http://test-server",
85
+ "test-group",
86
+ "test-token",
87
+ expiresAt,
88
+ false,
89
+ false,
90
+ );
91
+
92
+ expect(createGroupAccessTokenStub.firstCall.args[3]).to.equal(expiresAt);
93
+ });
94
+
95
+ it("should reject invalid expiration date format", async () => {
96
+ await createGroupAccessToken(
97
+ "http://test-server",
98
+ "test-group",
99
+ "test-token",
100
+ "invalid-date",
101
+ false,
102
+ false,
103
+ );
104
+
105
+ expect(createGroupAccessTokenStub.called).to.be.false;
106
+ expect(
107
+ loggerStub.error.calledWith(
108
+ sinon.match(/Invalid expiration date format/),
109
+ ),
110
+ ).to.be.true;
111
+ expect(processExitStub.calledWith(1)).to.be.true;
112
+ });
113
+
114
+ it("should reject expiration date in the past", async () => {
115
+ const pastDate = new Date();
116
+ pastDate.setFullYear(pastDate.getFullYear() - 1);
117
+ const expiresAt = pastDate.toISOString();
118
+
119
+ await createGroupAccessToken(
120
+ "http://test-server",
121
+ "test-group",
122
+ "test-token",
123
+ expiresAt,
124
+ false,
125
+ false,
126
+ );
127
+
128
+ expect(createGroupAccessTokenStub.called).to.be.false;
129
+ expect(
130
+ loggerStub.error.calledWith(
131
+ sinon.match("Expiration date must be in the future"),
132
+ ),
133
+ ).to.be.true;
134
+ expect(processExitStub.calledWith(1)).to.be.true;
135
+ });
136
+
137
+ it("should return JSON output when jsonOutput is true", async () => {
138
+ const mockResponse = {
139
+ data: { tokenName: "test-token", secret: "secret-value" },
140
+ };
141
+ createGroupAccessTokenStub.resolves(mockResponse);
142
+
143
+ const result = await createGroupAccessToken(
144
+ "http://test-server",
145
+ "test-group",
146
+ "test-token",
147
+ undefined,
148
+ true,
149
+ false,
150
+ );
151
+
152
+ expect(result).to.deep.equal(mockResponse.data);
153
+ expect(
154
+ loggerStub.info.calledWith(
155
+ sinon.match("Group access token created successfully"),
156
+ ),
157
+ ).to.be.false;
158
+ });
159
+
160
+ it("should handle missing config", async () => {
161
+ sandbox.restore();
162
+ sandbox = sinon.createSandbox();
163
+ createGroupAccessTokenStub = sandbox.stub();
164
+ loggerStub = sandbox.stub(logger);
165
+ consoleLogStub = sandbox.stub(console, "log");
166
+ processExitStub = sandbox.stub(process, "exit");
167
+
168
+ sandbox
169
+ .stub(ClientConfiguration.prototype, "doesConfigExists")
170
+ .returns(false);
171
+ sandbox
172
+ .stub(GroupsApi.prototype, "createGroupAccessToken")
173
+ .callsFake(createGroupAccessTokenStub);
174
+
175
+ const result = await createGroupAccessToken(
176
+ "http://test-server",
177
+ "test-group",
178
+ "test-token",
179
+ undefined,
180
+ false,
181
+ false,
182
+ );
183
+
184
+ expect(createGroupAccessTokenStub.called).to.be.false;
185
+ expect(result).to.be.undefined;
186
+ expect(
187
+ loggerStub.error.calledWith(
188
+ sinon.match("Please, make sure that you are logged in"),
189
+ ),
190
+ ).to.be.true;
191
+ });
192
+
193
+ it("should handle API errors", async () => {
194
+ const mockError = new Error("API Error");
195
+ createGroupAccessTokenStub.rejects(mockError);
196
+
197
+ await createGroupAccessToken(
198
+ "http://test-server",
199
+ "test-group",
200
+ "test-token",
201
+ undefined,
202
+ false,
203
+ true,
204
+ );
205
+
206
+ expect(createGroupAccessTokenStub.calledOnce).to.be.true;
207
+ expect(loggerStub.error.calledWith(sinon.match("Operation failed"))).to.be
208
+ .true;
209
+ expect(processExitStub.calledWith(1)).to.be.true;
210
+ });
211
+ });
@@ -3,66 +3,70 @@ import { logger } from "../../logger";
3
3
  import { withGroupContext } from "./groupContainer";
4
4
 
5
5
  export async function createGroupAccessToken(
6
- controlPlane: string,
7
- groupName: string,
8
- tokenName: string,
9
- expiresAt: string | undefined,
10
- debug: boolean,
6
+ controlPlane: string,
7
+ groupName: string,
8
+ tokenName: string,
9
+ expiresAt: string | undefined,
10
+ jsonOutput: boolean,
11
+ debug: boolean,
11
12
  ) {
12
- // Validate expiresAt format if provided
13
- if (expiresAt) {
14
- const expiresAtDate = new Date(expiresAt);
15
- if (isNaN(expiresAtDate.getTime())) {
16
- logger.error(
17
- `Invalid expiration date format: ${expiresAt}. Please use ISO 8601 format (e.g., 2025-12-31T23:59:59Z)`,
18
- );
19
- process.exit(1);
20
- }
21
- if (expiresAtDate <= new Date()) {
22
- logger.error(
23
- "Expiration date must be in the future",
24
- );
25
- process.exit(1);
26
- }
27
- }
13
+ // Validate expiresAt format if provided
14
+ if (expiresAt) {
15
+ const expiresAtDate = new Date(expiresAt);
16
+ if (isNaN(expiresAtDate.getTime())) {
17
+ logger.error(
18
+ `Invalid expiration date format: ${expiresAt}. Please use ISO 8601 format (e.g., 2025-12-31T23:59:59Z)`,
19
+ );
20
+ process.exit(1);
21
+ return;
22
+ }
23
+ if (expiresAtDate <= new Date()) {
24
+ logger.error("Expiration date must be in the future");
25
+ process.exit(1);
26
+ return;
27
+ }
28
+ }
28
29
 
29
- const result = await withGroupContext(controlPlane, async (context) => {
30
- const { organizationName, groupsApi, options } = context;
30
+ const result = await withGroupContext(
31
+ controlPlane,
32
+ async (context) => {
33
+ const { organizationName, groupsApi, options } = context;
31
34
 
32
- logger.info(
33
- `Creating access token ${tokenName} for group ${groupName} in organization ${organizationName}${expiresAt ? ` (expires: ${expiresAt})` : ""}`,
34
- );
35
-
36
- const response = await groupsApi.createGroupAccessToken(
35
+ const response = await groupsApi.createGroupAccessToken(
37
36
  organizationName,
38
37
  groupName,
39
38
  tokenName,
40
39
  expiresAt,
41
40
  options,
42
- );
41
+ );
42
+
43
+ return response.data;
44
+ },
45
+ undefined,
46
+ debug,
47
+ );
43
48
 
44
- return response.data;
45
- }, undefined, debug);
49
+ if (jsonOutput) {
50
+ return result;
51
+ }
46
52
 
47
- // Display security warning after the response is printed
48
- console.log("\n" + kleur.yellow().bold("⚠️ IMPORTANT SECURITY NOTICE ⚠️"));
49
- console.log(
50
- kleur.yellow(
51
- "The token secret shown above will NOT be displayed again.",
52
- ),
53
- );
54
- console.log(
55
- kleur.yellow(
56
- "Please store it securely in a password manager or secure vault.",
57
- ),
58
- );
59
- console.log(
60
- kleur.yellow(
61
- "If you lose this token, you will need to create a new one.",
62
- ),
63
- );
64
- console.log("");
65
- logger.info("Group access token created successfully");
53
+ // Display security warning after the response is printed
54
+ console.log("\n" + kleur.yellow().bold("⚠️ IMPORTANT SECURITY NOTICE ⚠️"));
55
+ console.log(
56
+ kleur.yellow("The token secret shown above will NOT be displayed again."),
57
+ );
58
+ console.log(
59
+ kleur.yellow(
60
+ "Please store it securely in a password manager or secure vault.",
61
+ ),
62
+ );
63
+ console.log(
64
+ kleur.yellow(
65
+ "If you lose this token, you will need to create a new one.",
66
+ ),
67
+ );
68
+ console.log("");
69
+ logger.info("Group access token created successfully");
66
70
 
67
- return result;
71
+ return result;
68
72
  }
@@ -0,0 +1,147 @@
1
+ import { expect } from "chai";
2
+ import sinon from "sinon";
3
+ import { GroupsApi } from "../../client/api";
4
+ import { ClientConfiguration } from "../../clientconfiguration";
5
+ import { logger } from "../../logger";
6
+ import { deleteGroupAccessToken } from "./deleteToken";
7
+
8
+ describe("delete-group-access-token", () => {
9
+ let sandbox: sinon.SinonSandbox;
10
+ let deleteGroupAccessTokenStub: sinon.SinonStub;
11
+ let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
12
+ let processExitStub: sinon.SinonStub;
13
+
14
+ beforeEach(() => {
15
+ sandbox = sinon.createSandbox();
16
+ deleteGroupAccessTokenStub = sandbox.stub();
17
+ loggerStub = sandbox.stub(logger);
18
+ processExitStub = sandbox.stub(process, "exit");
19
+
20
+ sandbox
21
+ .stub(ClientConfiguration.prototype, "getOrganization")
22
+ .returns("test-org");
23
+ sandbox
24
+ .stub(ClientConfiguration.prototype, "doesConfigExists")
25
+ .returns(true);
26
+ sandbox
27
+ .stub(ClientConfiguration.prototype, "getAuthenticationHeader")
28
+ .returns("Bearer test-token");
29
+
30
+ sandbox
31
+ .stub(GroupsApi.prototype, "deleteGroupAccessToken")
32
+ .callsFake(deleteGroupAccessTokenStub);
33
+ });
34
+
35
+ afterEach(() => {
36
+ sandbox.restore();
37
+ });
38
+
39
+ it("should delete group access token successfully", async () => {
40
+ deleteGroupAccessTokenStub.resolves({ status: 200 });
41
+
42
+ await deleteGroupAccessToken(
43
+ "http://test-server",
44
+ "test-group",
45
+ "test-token",
46
+ false,
47
+ );
48
+
49
+ expect(deleteGroupAccessTokenStub.calledOnce).to.be.true;
50
+ expect(deleteGroupAccessTokenStub.firstCall.args[0]).to.equal("test-org");
51
+ expect(deleteGroupAccessTokenStub.firstCall.args[1]).to.equal(
52
+ "test-group",
53
+ );
54
+ expect(deleteGroupAccessTokenStub.firstCall.args[2]).to.equal(
55
+ "test-token",
56
+ );
57
+ expect(
58
+ loggerStub.info.calledWith(
59
+ sinon.match(
60
+ "Successfully deleted access token test-token. This token has been immediately revoked.",
61
+ ),
62
+ ),
63
+ ).to.be.true;
64
+ });
65
+
66
+ it("should handle missing config", async () => {
67
+ sandbox.restore();
68
+ sandbox = sinon.createSandbox();
69
+ deleteGroupAccessTokenStub = sandbox.stub();
70
+ loggerStub = sandbox.stub(logger);
71
+ processExitStub = sandbox.stub(process, "exit");
72
+
73
+ sandbox
74
+ .stub(ClientConfiguration.prototype, "doesConfigExists")
75
+ .returns(false);
76
+ sandbox
77
+ .stub(GroupsApi.prototype, "deleteGroupAccessToken")
78
+ .callsFake(deleteGroupAccessTokenStub);
79
+
80
+ const result = await deleteGroupAccessToken(
81
+ "http://test-server",
82
+ "test-group",
83
+ "test-token",
84
+ false,
85
+ );
86
+
87
+ expect(deleteGroupAccessTokenStub.called).to.be.false;
88
+ expect(result).to.be.undefined;
89
+ expect(
90
+ loggerStub.error.calledWith(
91
+ sinon.match("Please, make sure that you are logged in"),
92
+ ),
93
+ ).to.be.true;
94
+ });
95
+
96
+ it("should handle missing organization", async () => {
97
+ sandbox.restore();
98
+ sandbox = sinon.createSandbox();
99
+ deleteGroupAccessTokenStub = sandbox.stub();
100
+ loggerStub = sandbox.stub(logger);
101
+ processExitStub = sandbox.stub(process, "exit");
102
+
103
+ sandbox
104
+ .stub(ClientConfiguration.prototype, "doesConfigExists")
105
+ .returns(true);
106
+ sandbox
107
+ .stub(ClientConfiguration.prototype, "getOrganization")
108
+ .returns(undefined);
109
+ sandbox
110
+ .stub(GroupsApi.prototype, "deleteGroupAccessToken")
111
+ .callsFake(deleteGroupAccessTokenStub);
112
+
113
+ const result = await deleteGroupAccessToken(
114
+ "http://test-server",
115
+ "test-group",
116
+ "test-token",
117
+ false,
118
+ );
119
+
120
+ expect(deleteGroupAccessTokenStub.called).to.be.false;
121
+ expect(result).to.be.undefined;
122
+ expect(
123
+ loggerStub.error.calledWith(
124
+ sinon.match(
125
+ "No organization set. Please login or set an organization.",
126
+ ),
127
+ ),
128
+ ).to.be.true;
129
+ });
130
+
131
+ it("should handle API errors", async () => {
132
+ const mockError = new Error("API Error");
133
+ deleteGroupAccessTokenStub.rejects(mockError);
134
+
135
+ await deleteGroupAccessToken(
136
+ "http://test-server",
137
+ "test-group",
138
+ "test-token",
139
+ true,
140
+ );
141
+
142
+ expect(deleteGroupAccessTokenStub.calledOnce).to.be.true;
143
+ expect(loggerStub.error.calledWith(sinon.match("Operation failed"))).to.be
144
+ .true;
145
+ expect(processExitStub.calledWith(1)).to.be.true;
146
+ });
147
+ });
@@ -2,23 +2,28 @@ import { logger } from "../../logger";
2
2
  import { withGroupContext } from "./groupContainer";
3
3
 
4
4
  export async function deleteGroupAccessToken(
5
- controlPlane: string,
6
- groupName: string,
7
- tokenName: string,
8
- debug: boolean,
5
+ controlPlane: string,
6
+ groupName: string,
7
+ tokenName: string,
8
+ debug: boolean,
9
9
  ) {
10
- return withGroupContext(controlPlane, async (context) => {
11
- const { organizationName, groupsApi, options } = context;
10
+ return withGroupContext(
11
+ controlPlane,
12
+ async (context) => {
13
+ const { organizationName, groupsApi, options } = context;
12
14
 
13
- logger.info(
15
+ logger.info(
14
16
  `Deleting access token ${tokenName} from group ${groupName} in organization ${organizationName}`,
15
- );
17
+ );
16
18
 
17
- await groupsApi.deleteGroupAccessToken(
19
+ await groupsApi.deleteGroupAccessToken(
18
20
  organizationName,
19
21
  groupName,
20
22
  tokenName,
21
23
  options,
22
- );
23
- }, `Successfully deleted access token ${tokenName}. This token has been immediately revoked.`, debug);
24
+ );
25
+ },
26
+ `Successfully deleted access token ${tokenName}. This token has been immediately revoked.`,
27
+ debug,
28
+ );
24
29
  }
@@ -5,23 +5,23 @@ import { logger } from "../../logger";
5
5
  import { printOutError } from "../../utils";
6
6
 
7
7
  export interface ApiOptions {
8
- baseURL: string;
9
- headers: {
10
- Authorization: string;
11
- };
12
- params?: Record<string, unknown>;
8
+ baseURL: string;
9
+ headers: {
10
+ Authorization: string;
11
+ };
12
+ params?: Record<string, unknown>;
13
13
  }
14
14
 
15
15
  export interface GroupContext {
16
- organizationName: string;
17
- groupsApi: GroupsApi;
18
- options: ApiOptions;
16
+ organizationName: string;
17
+ groupsApi: GroupsApi;
18
+ options: ApiOptions;
19
19
  }
20
20
 
21
21
  /**
22
22
  * Container function that handles common ClientConfiguration checks, setup,
23
23
  * error handling, and response printing for group access token operations.
24
- *
24
+ *
25
25
  * @param controlPlane The control plane URL
26
26
  * @param handler The handler function to execute with the configured context
27
27
  * @param successMessage Optional success message to display after the operation
@@ -29,55 +29,55 @@ export interface GroupContext {
29
29
  * @returns The result of the handler function, or void if validation fails
30
30
  */
31
31
  export async function withGroupContext<T>(
32
- controlPlane: string,
33
- handler: (context: GroupContext) => Promise<T>,
34
- successMessage?: string,
35
- debug: boolean = false,
32
+ controlPlane: string,
33
+ handler: (context: GroupContext) => Promise<T>,
34
+ successMessage?: string,
35
+ debug: boolean = false,
36
36
  ): Promise<T | void> {
37
- const clientConfig = new ClientConfiguration();
37
+ const clientConfig = new ClientConfiguration();
38
38
 
39
- if (!clientConfig.doesConfigExists()) {
40
- logger.error("Please, make sure that you are logged in");
41
- return;
42
- }
39
+ if (!clientConfig.doesConfigExists()) {
40
+ logger.error("Please, make sure that you are logged in");
41
+ return;
42
+ }
43
43
 
44
- const organizationName = clientConfig.getOrganization();
45
- if (!organizationName) {
46
- logger.error("No organization set. Please login or set an organization.");
47
- return;
48
- }
44
+ const organizationName = clientConfig.getOrganization();
45
+ if (!organizationName) {
46
+ logger.error("No organization set. Please login or set an organization.");
47
+ return;
48
+ }
49
49
 
50
- const options: ApiOptions = {
51
- baseURL: controlPlane,
52
- headers: {
53
- Authorization: clientConfig.getAuthenticationHeader(),
54
- },
55
- };
50
+ const options: ApiOptions = {
51
+ baseURL: controlPlane,
52
+ headers: {
53
+ Authorization: clientConfig.getAuthenticationHeader(),
54
+ },
55
+ };
56
56
 
57
- const context: GroupContext = {
58
- organizationName,
59
- groupsApi: new GroupsApi(new Configuration()),
60
- options,
61
- };
57
+ const context: GroupContext = {
58
+ organizationName,
59
+ groupsApi: new GroupsApi(new Configuration()),
60
+ options,
61
+ };
62
62
 
63
- try {
64
- const result = await handler(context);
63
+ try {
64
+ const result = await handler(context);
65
65
 
66
- // Print response if it exists
67
- if (result !== undefined && result !== null) {
68
- const jsonString = JSON.stringify(result, null, 2);
69
- console.log(jsonString);
70
- }
66
+ // Print response if it exists
67
+ if (result !== undefined && result !== null) {
68
+ const jsonString = JSON.stringify(result, null, 2);
69
+ console.log(jsonString);
70
+ }
71
71
 
72
- // Print success message if provided
73
- if (successMessage) {
74
- logger.info(successMessage);
75
- }
72
+ // Print success message if provided
73
+ if (successMessage) {
74
+ logger.info(successMessage);
75
+ }
76
76
 
77
- return result;
78
- } catch (error) {
79
- logger.error("Operation failed");
80
- printOutError(error, debug);
81
- process.exit(1);
82
- }
77
+ return result;
78
+ } catch (error) {
79
+ logger.error("Operation failed");
80
+ printOutError(error, debug);
81
+ process.exit(1);
82
+ }
83
83
  }