@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.
- package/.prettierignore +2 -1
- package/README.md +0 -2
- package/bun.lock +182 -283
- package/dist/client/api.js +804 -111
- package/dist/client/api.js.map +1 -1
- package/dist/clientconfiguration.js +55 -13
- package/dist/clientconfiguration.js.map +1 -1
- package/dist/clientconfiguration.spec.js +305 -16
- package/dist/clientconfiguration.spec.js.map +1 -1
- package/dist/commands/add.js +6 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/connection/createconnections.js +18 -3
- package/dist/commands/connection/createconnections.js.map +1 -1
- package/dist/commands/connection/createconnections.spec.js +219 -0
- package/dist/commands/connection/createconnections.spec.js.map +1 -0
- package/dist/commands/connection/deleteconnection.spec.js +130 -0
- package/dist/commands/connection/deleteconnection.spec.js.map +1 -0
- package/dist/commands/connection/listconnections.js +9 -3
- package/dist/commands/connection/listconnections.js.map +1 -1
- package/dist/commands/connection/listconnections.spec.js +117 -0
- package/dist/commands/connection/listconnections.spec.js.map +1 -0
- package/dist/commands/group/addmember.js +2 -0
- package/dist/commands/group/addmember.js.map +1 -1
- package/dist/commands/group/addmember.spec.js +148 -0
- package/dist/commands/group/addmember.spec.js.map +1 -0
- package/dist/commands/group/creategroup.spec.js +122 -0
- package/dist/commands/group/creategroup.spec.js.map +1 -0
- package/dist/commands/group/deletegroup.spec.js +104 -0
- package/dist/commands/group/deletegroup.spec.js.map +1 -0
- package/dist/commands/group/getgroup.spec.js +111 -0
- package/dist/commands/group/getgroup.spec.js.map +1 -0
- package/dist/commands/group/listgroups.spec.js +118 -0
- package/dist/commands/group/listgroups.spec.js.map +1 -0
- package/dist/commands/group/removemember.js +1 -0
- package/dist/commands/group/removemember.js.map +1 -1
- package/dist/commands/group/removemember.spec.js +138 -0
- package/dist/commands/group/removemember.spec.js.map +1 -0
- package/dist/commands/groupaccesstoken/createToken.js +6 -2
- package/dist/commands/groupaccesstoken/createToken.js.map +1 -1
- package/dist/commands/groupaccesstoken/createToken.spec.js +127 -0
- package/dist/commands/groupaccesstoken/createToken.spec.js.map +1 -0
- package/dist/commands/groupaccesstoken/deleteToken.js.map +1 -1
- package/dist/commands/groupaccesstoken/deleteToken.spec.js +103 -0
- package/dist/commands/groupaccesstoken/deleteToken.spec.js.map +1 -0
- package/dist/commands/groupaccesstoken/groupContainer.js.map +1 -1
- package/dist/commands/groupaccesstoken/listTokens.js.map +1 -1
- package/dist/commands/groupaccesstoken/listTokens.spec.js +115 -0
- package/dist/commands/groupaccesstoken/listTokens.spec.js.map +1 -0
- package/dist/commands/list.js +10 -3
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/misc/login.js +146 -22
- package/dist/commands/misc/login.js.map +1 -1
- package/dist/commands/misc/login.spec.js +111 -6
- package/dist/commands/misc/login.spec.js.map +1 -1
- package/dist/commands/misc/logout.spec.js +30 -0
- package/dist/commands/misc/logout.spec.js.map +1 -0
- package/dist/commands/misc/loopbackOAuth.js +110 -0
- package/dist/commands/misc/loopbackOAuth.js.map +1 -0
- package/dist/commands/misc/set-access-token.js.map +1 -1
- package/dist/commands/misc/set-access-token.spec.js +65 -0
- package/dist/commands/misc/set-access-token.spec.js.map +1 -0
- package/dist/commands/package/deletepackage.spec.js +136 -0
- package/dist/commands/package/deletepackage.spec.js.map +1 -0
- package/dist/commands/package/listpackages.js +10 -5
- package/dist/commands/package/listpackages.js.map +1 -1
- package/dist/commands/package/listpackages.spec.js +129 -0
- package/dist/commands/package/listpackages.spec.js.map +1 -0
- package/dist/commands/package/publish.js +23 -0
- package/dist/commands/package/publish.js.map +1 -1
- package/dist/commands/package/publish.spec.js +511 -0
- package/dist/commands/package/publish.spec.js.map +1 -0
- package/dist/commands/package/updatepackage.spec.js +50 -0
- package/dist/commands/package/updatepackage.spec.js.map +1 -1
- package/dist/commands/project/createproject.js +11 -1
- package/dist/commands/project/createproject.js.map +1 -1
- package/dist/commands/project/createproject.spec.js +154 -0
- package/dist/commands/project/createproject.spec.js.map +1 -0
- package/dist/commands/project/deleteproject.spec.js +106 -0
- package/dist/commands/project/deleteproject.spec.js.map +1 -0
- package/dist/commands/project/getproject.spec.js +99 -0
- package/dist/commands/project/getproject.spec.js.map +1 -0
- package/dist/commands/project/listprojects.js +13 -7
- package/dist/commands/project/listprojects.js.map +1 -1
- package/dist/commands/project/listprojects.spec.js +111 -0
- package/dist/commands/project/listprojects.spec.js.map +1 -0
- package/dist/commands/project/setproject.spec.js +58 -0
- package/dist/commands/project/setproject.spec.js.map +1 -0
- package/dist/commands/project/updateproject.js +68 -0
- package/dist/commands/project/updateproject.js.map +1 -0
- package/dist/commands/project/updateproject.spec.js +129 -0
- package/dist/commands/project/updateproject.spec.js.map +1 -0
- package/dist/commands/rm.js.map +1 -1
- package/dist/commands/update.js +13 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/version/listversions.spec.js +121 -0
- package/dist/commands/version/listversions.spec.js.map +1 -0
- package/dist/common/UserGroupId.spec.js +92 -0
- package/dist/common/UserGroupId.spec.js.map +1 -0
- package/dist/constants.js +49 -13
- package/dist/constants.js.map +1 -1
- package/dist/index.js +40 -18
- package/dist/index.js.map +1 -1
- package/dist/logger.spec.js +125 -0
- package/dist/logger.spec.js.map +1 -0
- package/dist/polyfills/file.polyfill.js.map +1 -1
- package/dist/utils.js +59 -0
- package/dist/utils.js.map +1 -1
- package/dist/utils.spec.js +158 -0
- package/dist/utils.spec.js.map +1 -0
- package/docker/Dockerfile.ci +11 -3
- package/eslint.config.mjs +45 -0
- package/generate-client.sh +5 -0
- package/package.json +24 -16
- package/src/client/.openapi-generator/FILES +1 -0
- package/src/client/api.ts +1999 -696
- package/src/clientconfiguration.spec.ts +394 -20
- package/src/clientconfiguration.ts +74 -15
- package/src/commands/add.ts +15 -6
- package/src/commands/connection/createconnections.spec.ts +403 -0
- package/src/commands/connection/createconnections.ts +30 -5
- package/src/commands/connection/deleteconnection.spec.ts +189 -0
- package/src/commands/connection/listconnections.spec.ts +132 -0
- package/src/commands/connection/listconnections.ts +22 -3
- package/src/commands/group/addmember.spec.ts +257 -0
- package/src/commands/group/addmember.ts +2 -0
- package/src/commands/group/creategroup.spec.ts +146 -0
- package/src/commands/group/deletegroup.spec.ts +120 -0
- package/src/commands/group/getgroup.spec.ts +129 -0
- package/src/commands/group/listgroups.spec.ts +137 -0
- package/src/commands/group/removemember.spec.ts +224 -0
- package/src/commands/group/removemember.ts +1 -0
- package/src/commands/groupaccesstoken/createToken.spec.ts +211 -0
- package/src/commands/groupaccesstoken/createToken.ts +55 -51
- package/src/commands/groupaccesstoken/deleteToken.spec.ts +147 -0
- package/src/commands/groupaccesstoken/deleteToken.ts +16 -11
- package/src/commands/groupaccesstoken/groupContainer.ts +51 -51
- package/src/commands/groupaccesstoken/listTokens.spec.ts +147 -0
- package/src/commands/groupaccesstoken/listTokens.ts +16 -11
- package/src/commands/list.ts +50 -9
- package/src/commands/misc/login.spec.ts +91 -6
- package/src/commands/misc/login.ts +208 -25
- package/src/commands/misc/logout.spec.ts +32 -0
- package/src/commands/misc/loopbackOAuth.ts +127 -0
- package/src/commands/misc/set-access-token.spec.ts +95 -0
- package/src/commands/misc/set-access-token.ts +16 -16
- package/src/commands/package/deletepackage.spec.ts +164 -0
- package/src/commands/package/listpackages.spec.ts +147 -0
- package/src/commands/package/listpackages.ts +28 -5
- package/src/commands/package/publish.spec.ts +597 -0
- package/src/commands/package/publish.ts +32 -0
- package/src/commands/package/updatepackage.spec.ts +98 -0
- package/src/commands/project/createproject.spec.ts +247 -0
- package/src/commands/project/createproject.ts +12 -1
- package/src/commands/project/deleteproject.spec.ts +123 -0
- package/src/commands/project/getproject.spec.ts +109 -0
- package/src/commands/project/listprojects.spec.ts +121 -0
- package/src/commands/project/listprojects.ts +33 -7
- package/src/commands/project/setproject.spec.ts +63 -0
- package/src/commands/project/updateproject.spec.ts +217 -0
- package/src/commands/project/updateproject.ts +82 -0
- package/src/commands/rm.ts +1 -6
- package/src/commands/update.ts +24 -1
- package/src/commands/version/listversions.spec.ts +138 -0
- package/src/common/UserGroupId.spec.ts +117 -0
- package/src/constants.ts +59 -13
- package/src/index.ts +46 -20
- package/src/logger.spec.ts +158 -0
- package/src/polyfills/file.polyfill.ts +1 -0
- package/src/utils.spec.ts +135 -0
- package/src/utils.ts +81 -0
- package/tsconfig.json +15 -18
- package/.eslintrc +0 -33
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import sinon from "sinon";
|
|
3
|
+
import { ProjectsApi } from "../../client/api";
|
|
4
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
5
|
+
import { logger } from "../../logger";
|
|
6
|
+
import { prettifyJson } from "../../utils";
|
|
7
|
+
import { listProjects, printOutProjects } from "./listprojects";
|
|
8
|
+
|
|
9
|
+
describe("list-projects", () => {
|
|
10
|
+
let sandbox: sinon.SinonSandbox;
|
|
11
|
+
let listProjectsStub: sinon.SinonStub;
|
|
12
|
+
let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
|
|
13
|
+
let consoleLogStub: sinon.SinonStub;
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
sandbox = sinon.createSandbox();
|
|
17
|
+
listProjectsStub = sandbox.stub();
|
|
18
|
+
loggerStub = sandbox.stub(logger);
|
|
19
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
20
|
+
|
|
21
|
+
sandbox
|
|
22
|
+
.stub(ClientConfiguration.prototype, "getOrganization")
|
|
23
|
+
.returns("test-org");
|
|
24
|
+
sandbox
|
|
25
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
26
|
+
.returns(true);
|
|
27
|
+
sandbox
|
|
28
|
+
.stub(ClientConfiguration.prototype, "getHeaders")
|
|
29
|
+
.returns({ Authorization: "Bearer test-token" });
|
|
30
|
+
|
|
31
|
+
sandbox
|
|
32
|
+
.stub(ProjectsApi.prototype, "listProjects")
|
|
33
|
+
.callsFake(listProjectsStub);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
sandbox.restore();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should list projects successfully", async () => {
|
|
41
|
+
const mockProjects = [
|
|
42
|
+
{ name: "project1", replicationCount: 2 },
|
|
43
|
+
{ name: "project2", replicationCount: 3 },
|
|
44
|
+
];
|
|
45
|
+
const mockResponse = {
|
|
46
|
+
data: mockProjects,
|
|
47
|
+
headers: {},
|
|
48
|
+
};
|
|
49
|
+
listProjectsStub.resolves(mockResponse);
|
|
50
|
+
|
|
51
|
+
const result = await listProjects("http://test-server", false);
|
|
52
|
+
|
|
53
|
+
expect(listProjectsStub.calledOnce).to.be.true;
|
|
54
|
+
expect(listProjectsStub.firstCall.args[0]).to.equal("test-org");
|
|
55
|
+
expect(listProjectsStub.firstCall.args[1]).to.equal(-1); // limit
|
|
56
|
+
expect(listProjectsStub.firstCall.args[2]).to.equal(0); // offset
|
|
57
|
+
expect(listProjectsStub.firstCall.args[3]).to.deep.include({
|
|
58
|
+
baseURL: "http://test-server",
|
|
59
|
+
headers: { Authorization: "Bearer test-token" },
|
|
60
|
+
});
|
|
61
|
+
expect(result).to.deep.equal({
|
|
62
|
+
projects: mockProjects,
|
|
63
|
+
totalCount: undefined,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should return empty array when config doesn't exist", async () => {
|
|
68
|
+
sandbox.restore();
|
|
69
|
+
sandbox = sinon.createSandbox();
|
|
70
|
+
listProjectsStub = sandbox.stub();
|
|
71
|
+
loggerStub = sandbox.stub(logger);
|
|
72
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
73
|
+
|
|
74
|
+
sandbox
|
|
75
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
76
|
+
.returns(false);
|
|
77
|
+
sandbox
|
|
78
|
+
.stub(ProjectsApi.prototype, "listProjects")
|
|
79
|
+
.callsFake(listProjectsStub);
|
|
80
|
+
|
|
81
|
+
const result = await listProjects("http://test-server", false);
|
|
82
|
+
|
|
83
|
+
expect(listProjectsStub.called).to.be.false;
|
|
84
|
+
expect(result).to.be.undefined;
|
|
85
|
+
expect(
|
|
86
|
+
loggerStub.error.calledWith(
|
|
87
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
88
|
+
),
|
|
89
|
+
).to.be.true;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should return empty array on API error", async () => {
|
|
93
|
+
const mockError = new Error("API Error");
|
|
94
|
+
listProjectsStub.rejects(mockError);
|
|
95
|
+
|
|
96
|
+
const result = await listProjects("http://test-server", true);
|
|
97
|
+
|
|
98
|
+
expect(listProjectsStub.calledOnce).to.be.true;
|
|
99
|
+
expect(result).to.be.undefined;
|
|
100
|
+
expect(
|
|
101
|
+
loggerStub.error.calledWith(sinon.match("Failed to list projects")),
|
|
102
|
+
).to.be.true;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("should print projects when using printOutProjects", async () => {
|
|
106
|
+
const mockProjects = [{ name: "project1" }];
|
|
107
|
+
const mockResponse = {
|
|
108
|
+
data: mockProjects,
|
|
109
|
+
headers: {},
|
|
110
|
+
};
|
|
111
|
+
listProjectsStub.resolves(mockResponse);
|
|
112
|
+
|
|
113
|
+
await printOutProjects("http://test-server", false);
|
|
114
|
+
|
|
115
|
+
expect(consoleLogStub.calledOnce).to.be.true;
|
|
116
|
+
const loggedValue = consoleLogStub.firstCall.args[0];
|
|
117
|
+
const parsed = JSON.parse(loggedValue);
|
|
118
|
+
expect(parsed).to.have.property("projects");
|
|
119
|
+
expect(parsed.projects).to.deep.equal(mockProjects);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
@@ -2,35 +2,61 @@ import { ProjectsApi } from "../../client/api";
|
|
|
2
2
|
import { Configuration } from "../../client/configuration";
|
|
3
3
|
import { ClientConfiguration } from "../../clientconfiguration";
|
|
4
4
|
import { logger } from "../../logger";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
prettifyJson,
|
|
7
|
+
printOutError,
|
|
8
|
+
parsePaginationParams,
|
|
9
|
+
extractTotalCount,
|
|
10
|
+
} from "../../utils";
|
|
6
11
|
|
|
7
12
|
const projectsApi = new ProjectsApi(new Configuration());
|
|
8
13
|
|
|
9
|
-
export async function listProjects(
|
|
14
|
+
export async function listProjects(
|
|
15
|
+
controlPlane: string,
|
|
16
|
+
debug: boolean,
|
|
17
|
+
page?: string | number,
|
|
18
|
+
pageSize?: string | number,
|
|
19
|
+
) {
|
|
10
20
|
const clientConfig = new ClientConfiguration();
|
|
11
21
|
|
|
12
22
|
if (!clientConfig.doesConfigExists()) {
|
|
13
23
|
logger.error("Please, make sure that you are logged in");
|
|
14
|
-
return
|
|
24
|
+
return;
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
try {
|
|
28
|
+
const { limit, offset } = parsePaginationParams(page, pageSize);
|
|
29
|
+
|
|
18
30
|
const response = await projectsApi.listProjects(
|
|
19
31
|
clientConfig.getOrganization(),
|
|
32
|
+
limit,
|
|
33
|
+
offset,
|
|
20
34
|
{
|
|
21
35
|
baseURL: controlPlane,
|
|
22
36
|
headers: clientConfig.getHeaders(),
|
|
23
37
|
},
|
|
24
38
|
);
|
|
25
39
|
|
|
26
|
-
|
|
40
|
+
const totalCount = extractTotalCount(response.headers);
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
projects: response.data,
|
|
44
|
+
totalCount,
|
|
45
|
+
};
|
|
27
46
|
} catch (e) {
|
|
28
47
|
logger.error("Failed to list projects");
|
|
29
48
|
printOutError(e, debug);
|
|
30
|
-
return
|
|
49
|
+
return;
|
|
31
50
|
}
|
|
32
51
|
}
|
|
33
52
|
|
|
34
|
-
export async function printOutProjects(
|
|
35
|
-
|
|
53
|
+
export async function printOutProjects(
|
|
54
|
+
controlPlane: string,
|
|
55
|
+
debug: boolean,
|
|
56
|
+
page?: string | number,
|
|
57
|
+
pageSize?: string | number,
|
|
58
|
+
) {
|
|
59
|
+
const projects = await listProjects(controlPlane, debug, page, pageSize);
|
|
60
|
+
|
|
61
|
+
console.log(prettifyJson(projects));
|
|
36
62
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import sinon from "sinon";
|
|
3
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
4
|
+
import { logger } from "../../logger";
|
|
5
|
+
import { setProject } from "./setproject";
|
|
6
|
+
|
|
7
|
+
describe("set-project", () => {
|
|
8
|
+
let sandbox: sinon.SinonSandbox;
|
|
9
|
+
let setProjectStub: sinon.SinonStub;
|
|
10
|
+
let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
|
|
11
|
+
let consoleLogStub: sinon.SinonStub;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
sandbox = sinon.createSandbox();
|
|
15
|
+
loggerStub = sandbox.stub(logger);
|
|
16
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
17
|
+
setProjectStub = sandbox.stub(
|
|
18
|
+
ClientConfiguration.prototype,
|
|
19
|
+
"setProject",
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
sandbox
|
|
23
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
24
|
+
.returns(true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
sandbox.restore();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should set project successfully", async () => {
|
|
32
|
+
await setProject("test-project");
|
|
33
|
+
|
|
34
|
+
expect(setProjectStub.calledOnce).to.be.true;
|
|
35
|
+
expect(setProjectStub.firstCall.args[0]).to.equal("test-project");
|
|
36
|
+
expect(consoleLogStub.calledWith("Setting project test-project")).to.be
|
|
37
|
+
.true;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should handle missing config", async () => {
|
|
41
|
+
sandbox.restore();
|
|
42
|
+
sandbox = sinon.createSandbox();
|
|
43
|
+
loggerStub = sandbox.stub(logger);
|
|
44
|
+
consoleLogStub = sandbox.stub(console, "log");
|
|
45
|
+
setProjectStub = sandbox.stub(
|
|
46
|
+
ClientConfiguration.prototype,
|
|
47
|
+
"setProject",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
sandbox
|
|
51
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
52
|
+
.returns(false);
|
|
53
|
+
|
|
54
|
+
await setProject("test-project");
|
|
55
|
+
|
|
56
|
+
expect(setProjectStub.called).to.be.false;
|
|
57
|
+
expect(
|
|
58
|
+
loggerStub.error.calledWith(
|
|
59
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
60
|
+
),
|
|
61
|
+
).to.be.true;
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import sinon from "sinon";
|
|
3
|
+
import { ProjectsApi } from "../../client/api";
|
|
4
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
5
|
+
import { logger } from "../../logger";
|
|
6
|
+
import { updateProject } from "./updateproject";
|
|
7
|
+
|
|
8
|
+
describe("update-project", () => {
|
|
9
|
+
let sandbox: sinon.SinonSandbox;
|
|
10
|
+
let updateProjectStub: sinon.SinonStub;
|
|
11
|
+
let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
sandbox = sinon.createSandbox();
|
|
15
|
+
updateProjectStub = sandbox.stub();
|
|
16
|
+
loggerStub = sandbox.stub(logger);
|
|
17
|
+
|
|
18
|
+
// Mock ClientConfiguration constructor
|
|
19
|
+
sandbox
|
|
20
|
+
.stub(ClientConfiguration.prototype, "getOrganization")
|
|
21
|
+
.returns("test-org");
|
|
22
|
+
sandbox
|
|
23
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
24
|
+
.returns(true);
|
|
25
|
+
sandbox
|
|
26
|
+
.stub(ClientConfiguration.prototype, "getHeaders")
|
|
27
|
+
.returns({ Authorization: "Bearer test-token" });
|
|
28
|
+
|
|
29
|
+
// Mock ProjectsApi constructor and method
|
|
30
|
+
sandbox
|
|
31
|
+
.stub(ProjectsApi.prototype, "updateProject")
|
|
32
|
+
.callsFake(updateProjectStub);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
sandbox.restore();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("updateProject", () => {
|
|
40
|
+
it("should update project successfully", async () => {
|
|
41
|
+
const mockResponse = { status: 200 };
|
|
42
|
+
updateProjectStub.resolves(mockResponse);
|
|
43
|
+
|
|
44
|
+
await updateProject(
|
|
45
|
+
"http://test-server",
|
|
46
|
+
"test-project",
|
|
47
|
+
{ replicationCount: 3 },
|
|
48
|
+
false,
|
|
49
|
+
true,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(updateProjectStub.calledOnce).to.be.true;
|
|
53
|
+
expect(updateProjectStub.firstCall.args[0]).to.equal("test-org");
|
|
54
|
+
expect(updateProjectStub.firstCall.args[1]).to.equal("test-project");
|
|
55
|
+
expect(updateProjectStub.firstCall.args[2]).to.include({
|
|
56
|
+
replicationCount: 3,
|
|
57
|
+
});
|
|
58
|
+
expect(updateProjectStub.firstCall.args[3]).to.deep.include({
|
|
59
|
+
baseURL: "http://test-server",
|
|
60
|
+
headers: { Authorization: "Bearer test-token" },
|
|
61
|
+
});
|
|
62
|
+
expect(
|
|
63
|
+
loggerStub.info.calledWith(
|
|
64
|
+
sinon.match("Successfully updated project test-project"),
|
|
65
|
+
),
|
|
66
|
+
).to.be.true;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should handle missing project name", async () => {
|
|
70
|
+
await updateProject(
|
|
71
|
+
"http://test-server",
|
|
72
|
+
"",
|
|
73
|
+
{ replicationCount: 3 },
|
|
74
|
+
false,
|
|
75
|
+
true,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(updateProjectStub.called).to.be.false;
|
|
79
|
+
expect(
|
|
80
|
+
loggerStub.error.calledWith(
|
|
81
|
+
sinon.match("Please provide a project name"),
|
|
82
|
+
),
|
|
83
|
+
).to.be.true;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should handle API errors", async () => {
|
|
87
|
+
const mockError = new Error("API Error");
|
|
88
|
+
updateProjectStub.rejects(mockError);
|
|
89
|
+
|
|
90
|
+
await updateProject(
|
|
91
|
+
"http://test-server",
|
|
92
|
+
"test-project",
|
|
93
|
+
{ replicationCount: 3 },
|
|
94
|
+
true,
|
|
95
|
+
true,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
expect(updateProjectStub.calledOnce).to.be.true;
|
|
99
|
+
expect(
|
|
100
|
+
loggerStub.error.calledWith(
|
|
101
|
+
sinon.match("Failed to update project test-project"),
|
|
102
|
+
),
|
|
103
|
+
).to.be.true;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("should handle non-200 response status", async () => {
|
|
107
|
+
const mockResponse = { status: 400 };
|
|
108
|
+
updateProjectStub.resolves(mockResponse);
|
|
109
|
+
|
|
110
|
+
await updateProject(
|
|
111
|
+
"http://test-server",
|
|
112
|
+
"test-project",
|
|
113
|
+
{ replicationCount: 3 },
|
|
114
|
+
false,
|
|
115
|
+
true,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
expect(updateProjectStub.calledOnce).to.be.true;
|
|
119
|
+
expect(
|
|
120
|
+
loggerStub.error.calledWith(
|
|
121
|
+
sinon.match("Failed to update project. Status: 400"),
|
|
122
|
+
),
|
|
123
|
+
).to.be.true;
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe("validators", () => {
|
|
128
|
+
describe("authentication validation", () => {
|
|
129
|
+
it("should fail when user is not logged in", async () => {
|
|
130
|
+
sandbox.restore();
|
|
131
|
+
sandbox = sinon.createSandbox();
|
|
132
|
+
updateProjectStub = sandbox.stub();
|
|
133
|
+
loggerStub = sandbox.stub(logger);
|
|
134
|
+
|
|
135
|
+
sandbox
|
|
136
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
137
|
+
.returns(false);
|
|
138
|
+
sandbox
|
|
139
|
+
.stub(ProjectsApi.prototype, "updateProject")
|
|
140
|
+
.callsFake(updateProjectStub);
|
|
141
|
+
|
|
142
|
+
await updateProject(
|
|
143
|
+
"http://test-server",
|
|
144
|
+
"test-project",
|
|
145
|
+
{ replicationCount: 3 },
|
|
146
|
+
false,
|
|
147
|
+
true,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
expect(updateProjectStub.called).to.be.false;
|
|
151
|
+
expect(
|
|
152
|
+
loggerStub.error.calledWith(
|
|
153
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
154
|
+
),
|
|
155
|
+
).to.be.true;
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe("replication count validation", () => {
|
|
160
|
+
it("should accept valid replication counts", async () => {
|
|
161
|
+
const mockResponse = { status: 200 };
|
|
162
|
+
updateProjectStub.resolves(mockResponse);
|
|
163
|
+
|
|
164
|
+
const validCounts = [1, 2, 5, 10, 100];
|
|
165
|
+
|
|
166
|
+
for (const count of validCounts) {
|
|
167
|
+
await updateProject(
|
|
168
|
+
"http://test-server",
|
|
169
|
+
"test-project",
|
|
170
|
+
{ replicationCount: count },
|
|
171
|
+
false,
|
|
172
|
+
true,
|
|
173
|
+
);
|
|
174
|
+
expect(updateProjectStub.called).to.be.true;
|
|
175
|
+
expect(updateProjectStub.firstCall.args[2]).to.include({
|
|
176
|
+
replicationCount: count,
|
|
177
|
+
});
|
|
178
|
+
updateProjectStub.reset();
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("should reject replication count less than 1", async () => {
|
|
183
|
+
await updateProject(
|
|
184
|
+
"http://test-server",
|
|
185
|
+
"test-project",
|
|
186
|
+
{ replicationCount: 0 },
|
|
187
|
+
false,
|
|
188
|
+
true,
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
expect(updateProjectStub.called).to.be.false;
|
|
192
|
+
expect(
|
|
193
|
+
loggerStub.error.calledWith(
|
|
194
|
+
sinon.match("Replication count must be at least 1"),
|
|
195
|
+
),
|
|
196
|
+
).to.be.true;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("should reject negative replication count", async () => {
|
|
200
|
+
await updateProject(
|
|
201
|
+
"http://test-server",
|
|
202
|
+
"test-project",
|
|
203
|
+
{ replicationCount: -1 },
|
|
204
|
+
false,
|
|
205
|
+
true,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
expect(updateProjectStub.called).to.be.false;
|
|
209
|
+
expect(
|
|
210
|
+
loggerStub.error.calledWith(
|
|
211
|
+
sinon.match("Replication count must be at least 1"),
|
|
212
|
+
),
|
|
213
|
+
).to.be.true;
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Project, ProjectsApi } from "../../client/api";
|
|
2
|
+
import { Configuration } from "../../client/configuration";
|
|
3
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
4
|
+
import { logger } from "../../logger";
|
|
5
|
+
import { getConfirmation, printOutError } from "../../utils";
|
|
6
|
+
|
|
7
|
+
const projectsApi = new ProjectsApi(new Configuration());
|
|
8
|
+
|
|
9
|
+
type UpdateProjectProperties = {
|
|
10
|
+
replicationCount?: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export async function updateProject(
|
|
14
|
+
controlPlane: string,
|
|
15
|
+
projectName: string,
|
|
16
|
+
properties: UpdateProjectProperties,
|
|
17
|
+
debug?: boolean,
|
|
18
|
+
skipConfirmation?: boolean,
|
|
19
|
+
) {
|
|
20
|
+
const clientConfig = new ClientConfiguration();
|
|
21
|
+
if (!clientConfig.doesConfigExists()) {
|
|
22
|
+
logger.error("Please, make sure that you are logged in");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!projectName) {
|
|
27
|
+
logger.error("Please provide a project name");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const organizationName = clientConfig.getOrganization();
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
properties.replicationCount !== undefined &&
|
|
35
|
+
properties.replicationCount < 1
|
|
36
|
+
) {
|
|
37
|
+
logger.error("Replication count must be at least 1");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
if (!skipConfirmation) {
|
|
43
|
+
const confirmation = await getConfirmation(
|
|
44
|
+
`Are you sure you want to update project ${projectName}?`,
|
|
45
|
+
);
|
|
46
|
+
if (!confirmation) {
|
|
47
|
+
logger.info("Operation cancelled.");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const projectUpdate: Project = {};
|
|
53
|
+
|
|
54
|
+
if (properties.replicationCount !== undefined) {
|
|
55
|
+
projectUpdate.replicationCount = properties.replicationCount;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const response = await projectsApi.updateProject(
|
|
59
|
+
organizationName,
|
|
60
|
+
projectName,
|
|
61
|
+
projectUpdate,
|
|
62
|
+
{
|
|
63
|
+
baseURL: controlPlane,
|
|
64
|
+
headers: clientConfig.getHeaders(),
|
|
65
|
+
},
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (response.status === 200) {
|
|
69
|
+
logger.info(`Successfully updated project ${projectName}`);
|
|
70
|
+
if (properties.replicationCount !== undefined) {
|
|
71
|
+
logger.info(
|
|
72
|
+
`Replication count set to ${properties.replicationCount}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
logger.error(`Failed to update project. Status: ${response.status}`);
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
logger.error(`Failed to update project ${projectName}`);
|
|
80
|
+
printOutError(e, debug);
|
|
81
|
+
}
|
|
82
|
+
}
|
package/src/commands/rm.ts
CHANGED
|
@@ -84,13 +84,9 @@ export const registerRmCommands = (cli: Command, environment: Environment) => {
|
|
|
84
84
|
);
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
|
|
88
87
|
rm.command("group-access-token")
|
|
89
88
|
.description("Delete an access token from a group.")
|
|
90
|
-
.argument(
|
|
91
|
-
"<groupName>",
|
|
92
|
-
"The name of the group",
|
|
93
|
-
)
|
|
89
|
+
.argument("<groupName>", "The name of the group")
|
|
94
90
|
.argument("<tokenName>", "The name of the token to delete")
|
|
95
91
|
.option("--debug")
|
|
96
92
|
.option("-y, --yes", "Skip confirmation.")
|
|
@@ -102,5 +98,4 @@ export const registerRmCommands = (cli: Command, environment: Environment) => {
|
|
|
102
98
|
options.debug || false,
|
|
103
99
|
);
|
|
104
100
|
});
|
|
105
|
-
|
|
106
101
|
};
|
package/src/commands/update.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { controlPlanesByEnv, Environment } from "../constants";
|
|
3
3
|
import { updatePackage } from "./package/updatepackage";
|
|
4
|
+
import { updateProject } from "./project/updateproject";
|
|
4
5
|
|
|
5
6
|
export const registerUpdateCommands = (
|
|
6
7
|
cli: Command,
|
|
@@ -11,6 +12,29 @@ export const registerUpdateCommands = (
|
|
|
11
12
|
.description("Update a resource")
|
|
12
13
|
.argument("<resource>", "The resource to update");
|
|
13
14
|
|
|
15
|
+
update
|
|
16
|
+
.command("project")
|
|
17
|
+
.description("Update a project.")
|
|
18
|
+
.argument("<projectName>", "The name of the project to update.")
|
|
19
|
+
.option(
|
|
20
|
+
"--replication <replicationCount>",
|
|
21
|
+
"The new replication count (must be at least 1).",
|
|
22
|
+
parseInt,
|
|
23
|
+
)
|
|
24
|
+
.option("--debug")
|
|
25
|
+
.option("-y, --yes", "Skip confirmation.")
|
|
26
|
+
.action((projectName, options) => {
|
|
27
|
+
updateProject(
|
|
28
|
+
controlPlanesByEnv[environment],
|
|
29
|
+
projectName,
|
|
30
|
+
{
|
|
31
|
+
replicationCount: options.replication,
|
|
32
|
+
},
|
|
33
|
+
options.debug,
|
|
34
|
+
options.yes,
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
14
38
|
update
|
|
15
39
|
.command("package")
|
|
16
40
|
.description("Update a package.")
|
|
@@ -37,5 +61,4 @@ export const registerUpdateCommands = (
|
|
|
37
61
|
options.yes,
|
|
38
62
|
);
|
|
39
63
|
});
|
|
40
|
-
|
|
41
64
|
};
|