@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,597 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import sinon from "sinon";
|
|
6
|
+
import { PackagesApi } from "../../client/api";
|
|
7
|
+
import { ClientConfiguration } from "../../clientconfiguration";
|
|
8
|
+
import { logger } from "../../logger";
|
|
9
|
+
import { prettifyJson } from "../../utils";
|
|
10
|
+
|
|
11
|
+
// We need to stub archiver before publish.ts imports it.
|
|
12
|
+
// Since this is CommonJS, we replace archiver in the require cache.
|
|
13
|
+
let storedCloseCallback: Function | undefined;
|
|
14
|
+
let mockArchive: any;
|
|
15
|
+
|
|
16
|
+
function createMockArchive(sandbox: sinon.SinonSandbox) {
|
|
17
|
+
storedCloseCallback = undefined;
|
|
18
|
+
|
|
19
|
+
mockArchive = {
|
|
20
|
+
on: sandbox.stub().returnsThis(),
|
|
21
|
+
directory: sandbox.stub().returnsThis(),
|
|
22
|
+
pipe: sandbox.stub().returnsThis(),
|
|
23
|
+
finalize: sandbox.stub().callsFake(function () {
|
|
24
|
+
// Trigger the close event on the WriteStream when finalize is called
|
|
25
|
+
if (storedCloseCallback) {
|
|
26
|
+
// Use process.nextTick to ensure it fires after the promise is set up
|
|
27
|
+
process.nextTick(() => storedCloseCallback!());
|
|
28
|
+
}
|
|
29
|
+
return mockArchive;
|
|
30
|
+
}),
|
|
31
|
+
pointer: sandbox.stub().returns(1024),
|
|
32
|
+
};
|
|
33
|
+
return mockArchive;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe("publish", () => {
|
|
37
|
+
let sandbox: sinon.SinonSandbox;
|
|
38
|
+
let createOrUpdatePackageStub: sinon.SinonStub;
|
|
39
|
+
let loggerStub: sinon.SinonStubbedInstance<typeof logger>;
|
|
40
|
+
let getConfirmationStub: sinon.SinonStub;
|
|
41
|
+
let readFileSyncStub: sinon.SinonStub;
|
|
42
|
+
let existsSyncStub: sinon.SinonStub;
|
|
43
|
+
let unlinkStub: sinon.SinonStub;
|
|
44
|
+
let createWriteStreamStub: sinon.SinonStub;
|
|
45
|
+
let validateManifestStub: sinon.SinonStub;
|
|
46
|
+
let processCwdStub: sinon.SinonStub;
|
|
47
|
+
let publish: (
|
|
48
|
+
controlPlane: string,
|
|
49
|
+
replicationCount: number,
|
|
50
|
+
debug: boolean,
|
|
51
|
+
autoConfirm: boolean,
|
|
52
|
+
setLatest: boolean,
|
|
53
|
+
) => Promise<void>;
|
|
54
|
+
|
|
55
|
+
// Store the original archiver module so we can restore it
|
|
56
|
+
let originalArchiverModule: any;
|
|
57
|
+
const archiverModulePath = require.resolve("archiver");
|
|
58
|
+
|
|
59
|
+
beforeEach(() => {
|
|
60
|
+
sandbox = sinon.createSandbox();
|
|
61
|
+
|
|
62
|
+
// Create mock archive
|
|
63
|
+
const archive = createMockArchive(sandbox);
|
|
64
|
+
|
|
65
|
+
// Replace archiver in require cache with our mock factory
|
|
66
|
+
originalArchiverModule = require.cache[archiverModulePath];
|
|
67
|
+
require.cache[archiverModulePath] = {
|
|
68
|
+
id: archiverModulePath,
|
|
69
|
+
filename: archiverModulePath,
|
|
70
|
+
loaded: true,
|
|
71
|
+
exports: function () {
|
|
72
|
+
return archive;
|
|
73
|
+
},
|
|
74
|
+
} as any;
|
|
75
|
+
|
|
76
|
+
// Clear publish module from cache so it picks up the stubbed archiver
|
|
77
|
+
const publishModulePath = require.resolve("./publish");
|
|
78
|
+
delete require.cache[publishModulePath];
|
|
79
|
+
|
|
80
|
+
// Now require publish - it will get our mock archiver
|
|
81
|
+
publish = require("./publish").publish;
|
|
82
|
+
|
|
83
|
+
createOrUpdatePackageStub = sandbox.stub();
|
|
84
|
+
loggerStub = sandbox.stub(logger);
|
|
85
|
+
getConfirmationStub = sandbox.stub();
|
|
86
|
+
readFileSyncStub = sandbox.stub(fs, "readFileSync");
|
|
87
|
+
existsSyncStub = sandbox.stub(fs, "existsSync");
|
|
88
|
+
unlinkStub = sandbox.stub(fs, "unlink");
|
|
89
|
+
createWriteStreamStub = sandbox.stub(fs, "createWriteStream");
|
|
90
|
+
validateManifestStub = sandbox.stub();
|
|
91
|
+
sandbox.stub(console, "log");
|
|
92
|
+
processCwdStub = sandbox.stub(process, "cwd");
|
|
93
|
+
|
|
94
|
+
sandbox
|
|
95
|
+
.stub(ClientConfiguration.prototype, "getOrganization")
|
|
96
|
+
.returns("test-org");
|
|
97
|
+
sandbox
|
|
98
|
+
.stub(ClientConfiguration.prototype, "getProject")
|
|
99
|
+
.returns("test-project");
|
|
100
|
+
sandbox
|
|
101
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
102
|
+
.returns(true);
|
|
103
|
+
sandbox
|
|
104
|
+
.stub(ClientConfiguration.prototype, "isTokenValid")
|
|
105
|
+
.returns({ valid: true });
|
|
106
|
+
sandbox
|
|
107
|
+
.stub(ClientConfiguration.prototype, "getHeaders")
|
|
108
|
+
.returns({ Authorization: "Bearer test-token" });
|
|
109
|
+
|
|
110
|
+
sandbox
|
|
111
|
+
.stub(PackagesApi.prototype, "createOrUpdatePackage")
|
|
112
|
+
.callsFake(createOrUpdatePackageStub);
|
|
113
|
+
sandbox
|
|
114
|
+
.stub(require("../../utils"), "getConfirmation")
|
|
115
|
+
.callsFake(getConfirmationStub);
|
|
116
|
+
sandbox
|
|
117
|
+
.stub(require("../../validator"), "validateManifest")
|
|
118
|
+
.callsFake(validateManifestStub);
|
|
119
|
+
|
|
120
|
+
processCwdStub.returns("/test/package-name");
|
|
121
|
+
validateManifestStub.returns(true);
|
|
122
|
+
existsSyncStub.returns(true);
|
|
123
|
+
|
|
124
|
+
// Mock write stream that captures the close callback
|
|
125
|
+
const mockWriteStream = {
|
|
126
|
+
on: sandbox.stub().callsFake(function (
|
|
127
|
+
event: string,
|
|
128
|
+
callback: Function,
|
|
129
|
+
) {
|
|
130
|
+
if (event === "close") {
|
|
131
|
+
storedCloseCallback = callback;
|
|
132
|
+
}
|
|
133
|
+
return mockWriteStream;
|
|
134
|
+
}),
|
|
135
|
+
once: sandbox.stub().returnsThis(),
|
|
136
|
+
emit: sandbox.stub().returnsThis(),
|
|
137
|
+
write: sandbox.stub(),
|
|
138
|
+
end: sandbox.stub(),
|
|
139
|
+
pipe: sandbox.stub().returnsThis(),
|
|
140
|
+
};
|
|
141
|
+
createWriteStreamStub.returns(mockWriteStream);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
afterEach(() => {
|
|
145
|
+
sandbox.restore();
|
|
146
|
+
// Restore original archiver module
|
|
147
|
+
if (originalArchiverModule) {
|
|
148
|
+
require.cache[archiverModulePath] = originalArchiverModule;
|
|
149
|
+
} else {
|
|
150
|
+
delete require.cache[archiverModulePath];
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("should publish package successfully", async function () {
|
|
155
|
+
this.timeout(5000);
|
|
156
|
+
const mockManifest = {
|
|
157
|
+
name: "test-package",
|
|
158
|
+
version: "1.0.0",
|
|
159
|
+
description: "Test package",
|
|
160
|
+
};
|
|
161
|
+
const mockPackageData = Buffer.from("test package data");
|
|
162
|
+
const mockResponse = {
|
|
163
|
+
data: { name: "test-package", version: "1.0.0" },
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
167
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
168
|
+
return mockPackageData;
|
|
169
|
+
});
|
|
170
|
+
getConfirmationStub.resolves(true);
|
|
171
|
+
createOrUpdatePackageStub.resolves(mockResponse);
|
|
172
|
+
unlinkStub.callsArg(1);
|
|
173
|
+
|
|
174
|
+
await publish("http://test-server", 2, false, true, false);
|
|
175
|
+
|
|
176
|
+
expect(validateManifestStub.calledOnce).to.be.true;
|
|
177
|
+
expect(readFileSyncStub.calledWith("publisher.json")).to.be.true;
|
|
178
|
+
expect(createOrUpdatePackageStub.calledOnce).to.be.true;
|
|
179
|
+
expect(createOrUpdatePackageStub.firstCall.args[0]).to.equal("test-org");
|
|
180
|
+
expect(createOrUpdatePackageStub.firstCall.args[1]).to.equal(
|
|
181
|
+
"test-project",
|
|
182
|
+
);
|
|
183
|
+
expect(createOrUpdatePackageStub.firstCall.args[2]).to.equal(
|
|
184
|
+
"test-package",
|
|
185
|
+
);
|
|
186
|
+
expect(createOrUpdatePackageStub.firstCall.args[3]).to.deep.include({
|
|
187
|
+
name: "test-package",
|
|
188
|
+
description: "Test package",
|
|
189
|
+
replicationCount: 2,
|
|
190
|
+
});
|
|
191
|
+
expect(createOrUpdatePackageStub.firstCall.args[4]).to.deep.include({
|
|
192
|
+
id: "1.0.0",
|
|
193
|
+
});
|
|
194
|
+
expect(
|
|
195
|
+
loggerStub.info.calledWith(
|
|
196
|
+
sinon.match(prettifyJson(mockResponse.data)),
|
|
197
|
+
),
|
|
198
|
+
).to.be.true;
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("should set latest version when setLatest is true", async function () {
|
|
202
|
+
this.timeout(5000);
|
|
203
|
+
const mockManifest = {
|
|
204
|
+
name: "test-package",
|
|
205
|
+
version: "1.0.0",
|
|
206
|
+
description: "Test package",
|
|
207
|
+
};
|
|
208
|
+
const mockPackageData = Buffer.from("test package data");
|
|
209
|
+
|
|
210
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
211
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
212
|
+
return mockPackageData;
|
|
213
|
+
});
|
|
214
|
+
getConfirmationStub.resolves(true);
|
|
215
|
+
createOrUpdatePackageStub.resolves({ data: {} });
|
|
216
|
+
unlinkStub.callsArg(1);
|
|
217
|
+
|
|
218
|
+
await publish("http://test-server", 2, false, true, true);
|
|
219
|
+
|
|
220
|
+
expect(createOrUpdatePackageStub.firstCall.args[3]).to.deep.include({
|
|
221
|
+
latestVersion: "1.0.0",
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("should not set latest version when setLatest is false", async function () {
|
|
226
|
+
this.timeout(5000);
|
|
227
|
+
const mockManifest = {
|
|
228
|
+
name: "test-package",
|
|
229
|
+
version: "1.0.0",
|
|
230
|
+
description: "Test package",
|
|
231
|
+
};
|
|
232
|
+
const mockPackageData = Buffer.from("test package data");
|
|
233
|
+
|
|
234
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
235
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
236
|
+
return mockPackageData;
|
|
237
|
+
});
|
|
238
|
+
getConfirmationStub.resolves(true);
|
|
239
|
+
createOrUpdatePackageStub.resolves({ data: {} });
|
|
240
|
+
unlinkStub.callsArg(1);
|
|
241
|
+
|
|
242
|
+
await publish("http://test-server", 2, false, true, false);
|
|
243
|
+
|
|
244
|
+
expect(createOrUpdatePackageStub.firstCall.args[3]).to.not.have.property(
|
|
245
|
+
"latestVersion",
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it("should skip confirmation when autoConfirm is true", async function () {
|
|
250
|
+
this.timeout(5000);
|
|
251
|
+
const mockManifest = {
|
|
252
|
+
name: "test-package",
|
|
253
|
+
version: "1.0.0",
|
|
254
|
+
description: "Test package",
|
|
255
|
+
};
|
|
256
|
+
const mockPackageData = Buffer.from("test package data");
|
|
257
|
+
|
|
258
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
259
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
260
|
+
return mockPackageData;
|
|
261
|
+
});
|
|
262
|
+
createOrUpdatePackageStub.resolves({ data: {} });
|
|
263
|
+
unlinkStub.callsArg(1);
|
|
264
|
+
|
|
265
|
+
await publish("http://test-server", 2, false, true, false);
|
|
266
|
+
|
|
267
|
+
expect(getConfirmationStub.called).to.be.false;
|
|
268
|
+
expect(createOrUpdatePackageStub.calledOnce).to.be.true;
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("should use package name from cwd directory", async function () {
|
|
272
|
+
this.timeout(5000);
|
|
273
|
+
processCwdStub.returns("/some/path/my-cool-package");
|
|
274
|
+
const mockManifest = {
|
|
275
|
+
name: "test-package",
|
|
276
|
+
version: "1.0.0",
|
|
277
|
+
description: "Test package",
|
|
278
|
+
};
|
|
279
|
+
const mockPackageData = Buffer.from("test package data");
|
|
280
|
+
|
|
281
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
282
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
283
|
+
return mockPackageData;
|
|
284
|
+
});
|
|
285
|
+
createOrUpdatePackageStub.resolves({ data: {} });
|
|
286
|
+
unlinkStub.callsArg(1);
|
|
287
|
+
|
|
288
|
+
await publish("http://test-server", 2, false, true, false);
|
|
289
|
+
|
|
290
|
+
// The archive path should use the cwd directory name
|
|
291
|
+
expect(createWriteStreamStub.calledWith("/tmp/my-cool-package.zip")).to.be
|
|
292
|
+
.true;
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("should calculate MD5 hash correctly", async function () {
|
|
296
|
+
this.timeout(5000);
|
|
297
|
+
const mockManifest = {
|
|
298
|
+
name: "test-package",
|
|
299
|
+
version: "1.0.0",
|
|
300
|
+
description: "Test package",
|
|
301
|
+
};
|
|
302
|
+
const mockPackageData = Buffer.from("test package data");
|
|
303
|
+
const expectedHash = crypto
|
|
304
|
+
.createHash("md5")
|
|
305
|
+
.update(mockPackageData)
|
|
306
|
+
.digest("hex");
|
|
307
|
+
|
|
308
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
309
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
310
|
+
return mockPackageData;
|
|
311
|
+
});
|
|
312
|
+
getConfirmationStub.resolves(true);
|
|
313
|
+
createOrUpdatePackageStub.resolves({ data: {} });
|
|
314
|
+
unlinkStub.callsArg(1);
|
|
315
|
+
|
|
316
|
+
await publish("http://test-server", 2, false, true, false);
|
|
317
|
+
|
|
318
|
+
expect(createOrUpdatePackageStub.firstCall.args[6]).to.equal(
|
|
319
|
+
expectedHash,
|
|
320
|
+
);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it("should handle missing config", async () => {
|
|
324
|
+
sandbox.restore();
|
|
325
|
+
sandbox = sinon.createSandbox();
|
|
326
|
+
createOrUpdatePackageStub = sandbox.stub();
|
|
327
|
+
loggerStub = sandbox.stub(logger);
|
|
328
|
+
getConfirmationStub = sandbox.stub();
|
|
329
|
+
readFileSyncStub = sandbox.stub(fs, "readFileSync");
|
|
330
|
+
existsSyncStub = sandbox.stub(fs, "existsSync");
|
|
331
|
+
validateManifestStub = sandbox.stub();
|
|
332
|
+
|
|
333
|
+
sandbox
|
|
334
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
335
|
+
.returns(false);
|
|
336
|
+
sandbox
|
|
337
|
+
.stub(PackagesApi.prototype, "createOrUpdatePackage")
|
|
338
|
+
.callsFake(createOrUpdatePackageStub);
|
|
339
|
+
sandbox
|
|
340
|
+
.stub(require("../../utils"), "getConfirmation")
|
|
341
|
+
.callsFake(getConfirmationStub);
|
|
342
|
+
sandbox
|
|
343
|
+
.stub(require("../../validator"), "validateManifest")
|
|
344
|
+
.callsFake(validateManifestStub);
|
|
345
|
+
|
|
346
|
+
await publish("http://test-server", 2, false, true, false);
|
|
347
|
+
|
|
348
|
+
expect(createOrUpdatePackageStub.called).to.be.false;
|
|
349
|
+
expect(
|
|
350
|
+
loggerStub.error.calledWith(
|
|
351
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
352
|
+
),
|
|
353
|
+
).to.be.true;
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it("should handle invalid token", async () => {
|
|
357
|
+
sandbox.restore();
|
|
358
|
+
sandbox = sinon.createSandbox();
|
|
359
|
+
createOrUpdatePackageStub = sandbox.stub();
|
|
360
|
+
loggerStub = sandbox.stub(logger);
|
|
361
|
+
getConfirmationStub = sandbox.stub();
|
|
362
|
+
readFileSyncStub = sandbox.stub(fs, "readFileSync");
|
|
363
|
+
existsSyncStub = sandbox.stub(fs, "existsSync");
|
|
364
|
+
validateManifestStub = sandbox.stub();
|
|
365
|
+
|
|
366
|
+
sandbox
|
|
367
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
368
|
+
.returns(true);
|
|
369
|
+
sandbox
|
|
370
|
+
.stub(ClientConfiguration.prototype, "isTokenValid")
|
|
371
|
+
.returns({ valid: false, reason: "No token found. Please login." });
|
|
372
|
+
sandbox
|
|
373
|
+
.stub(PackagesApi.prototype, "createOrUpdatePackage")
|
|
374
|
+
.callsFake(createOrUpdatePackageStub);
|
|
375
|
+
sandbox
|
|
376
|
+
.stub(require("../../utils"), "getConfirmation")
|
|
377
|
+
.callsFake(getConfirmationStub);
|
|
378
|
+
sandbox
|
|
379
|
+
.stub(require("../../validator"), "validateManifest")
|
|
380
|
+
.callsFake(validateManifestStub);
|
|
381
|
+
|
|
382
|
+
await publish("http://test-server", 2, false, true, false);
|
|
383
|
+
|
|
384
|
+
expect(createOrUpdatePackageStub.called).to.be.false;
|
|
385
|
+
expect(
|
|
386
|
+
loggerStub.error.calledWith(
|
|
387
|
+
sinon.match("No token found. Please login."),
|
|
388
|
+
),
|
|
389
|
+
).to.be.true;
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it("should handle invalid manifest", async () => {
|
|
393
|
+
validateManifestStub.returns(false);
|
|
394
|
+
|
|
395
|
+
await publish("http://test-server", 2, false, true, false);
|
|
396
|
+
|
|
397
|
+
expect(createOrUpdatePackageStub.called).to.be.false;
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it("should handle missing organization", async () => {
|
|
401
|
+
sandbox.restore();
|
|
402
|
+
sandbox = sinon.createSandbox();
|
|
403
|
+
createOrUpdatePackageStub = sandbox.stub();
|
|
404
|
+
loggerStub = sandbox.stub(logger);
|
|
405
|
+
getConfirmationStub = sandbox.stub();
|
|
406
|
+
readFileSyncStub = sandbox.stub(fs, "readFileSync");
|
|
407
|
+
existsSyncStub = sandbox.stub(fs, "existsSync");
|
|
408
|
+
validateManifestStub = sandbox.stub();
|
|
409
|
+
|
|
410
|
+
sandbox
|
|
411
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
412
|
+
.returns(true);
|
|
413
|
+
sandbox
|
|
414
|
+
.stub(ClientConfiguration.prototype, "isTokenValid")
|
|
415
|
+
.returns({ valid: true });
|
|
416
|
+
sandbox
|
|
417
|
+
.stub(ClientConfiguration.prototype, "getOrganization")
|
|
418
|
+
.returns("");
|
|
419
|
+
validateManifestStub.returns(true);
|
|
420
|
+
sandbox
|
|
421
|
+
.stub(PackagesApi.prototype, "createOrUpdatePackage")
|
|
422
|
+
.callsFake(createOrUpdatePackageStub);
|
|
423
|
+
sandbox
|
|
424
|
+
.stub(require("../../utils"), "getConfirmation")
|
|
425
|
+
.callsFake(getConfirmationStub);
|
|
426
|
+
sandbox
|
|
427
|
+
.stub(require("../../validator"), "validateManifest")
|
|
428
|
+
.callsFake(validateManifestStub);
|
|
429
|
+
|
|
430
|
+
await publish("http://test-server", 2, false, true, false);
|
|
431
|
+
|
|
432
|
+
expect(createOrUpdatePackageStub.called).to.be.false;
|
|
433
|
+
expect(
|
|
434
|
+
loggerStub.error.calledWith(
|
|
435
|
+
sinon.match("Please, make sure that you are logged in"),
|
|
436
|
+
),
|
|
437
|
+
).to.be.true;
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it("should handle missing project", async () => {
|
|
441
|
+
sandbox.restore();
|
|
442
|
+
sandbox = sinon.createSandbox();
|
|
443
|
+
createOrUpdatePackageStub = sandbox.stub();
|
|
444
|
+
loggerStub = sandbox.stub(logger);
|
|
445
|
+
getConfirmationStub = sandbox.stub();
|
|
446
|
+
readFileSyncStub = sandbox.stub(fs, "readFileSync");
|
|
447
|
+
existsSyncStub = sandbox.stub(fs, "existsSync");
|
|
448
|
+
validateManifestStub = sandbox.stub();
|
|
449
|
+
|
|
450
|
+
sandbox
|
|
451
|
+
.stub(ClientConfiguration.prototype, "doesConfigExists")
|
|
452
|
+
.returns(true);
|
|
453
|
+
sandbox
|
|
454
|
+
.stub(ClientConfiguration.prototype, "isTokenValid")
|
|
455
|
+
.returns({ valid: true });
|
|
456
|
+
sandbox
|
|
457
|
+
.stub(ClientConfiguration.prototype, "getOrganization")
|
|
458
|
+
.returns("test-org");
|
|
459
|
+
sandbox.stub(ClientConfiguration.prototype, "getProject").returns("");
|
|
460
|
+
validateManifestStub.returns(true);
|
|
461
|
+
sandbox
|
|
462
|
+
.stub(PackagesApi.prototype, "createOrUpdatePackage")
|
|
463
|
+
.callsFake(createOrUpdatePackageStub);
|
|
464
|
+
sandbox
|
|
465
|
+
.stub(require("../../utils"), "getConfirmation")
|
|
466
|
+
.callsFake(getConfirmationStub);
|
|
467
|
+
sandbox
|
|
468
|
+
.stub(require("../../validator"), "validateManifest")
|
|
469
|
+
.callsFake(validateManifestStub);
|
|
470
|
+
|
|
471
|
+
await publish("http://test-server", 2, false, true, false);
|
|
472
|
+
|
|
473
|
+
expect(createOrUpdatePackageStub.called).to.be.false;
|
|
474
|
+
expect(
|
|
475
|
+
loggerStub.error.calledWith(
|
|
476
|
+
sinon.match("Please, make sure to set a project"),
|
|
477
|
+
),
|
|
478
|
+
).to.be.true;
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it("should handle missing publisher.json", async () => {
|
|
482
|
+
existsSyncStub.callsFake((filePath: string) => {
|
|
483
|
+
if (filePath === "publisher.json") return false;
|
|
484
|
+
return true;
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
await publish("http://test-server", 2, false, true, false);
|
|
488
|
+
|
|
489
|
+
expect(createOrUpdatePackageStub.called).to.be.false;
|
|
490
|
+
expect(readFileSyncStub.called).to.be.false;
|
|
491
|
+
expect(
|
|
492
|
+
loggerStub.error.calledWith(
|
|
493
|
+
sinon.match(
|
|
494
|
+
"Failed to publish the package. Could not find publisher.json, please ensure you are in a directory containing publisher.json",
|
|
495
|
+
),
|
|
496
|
+
),
|
|
497
|
+
).to.be.true;
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it("should request confirmation when autoConfirm is false", async function () {
|
|
501
|
+
this.timeout(5000);
|
|
502
|
+
const mockManifest = {
|
|
503
|
+
name: "test-package",
|
|
504
|
+
version: "1.0.0",
|
|
505
|
+
description: "Test package",
|
|
506
|
+
};
|
|
507
|
+
const mockPackageData = Buffer.from("test package data");
|
|
508
|
+
|
|
509
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
510
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
511
|
+
return mockPackageData;
|
|
512
|
+
});
|
|
513
|
+
getConfirmationStub.resolves(true);
|
|
514
|
+
createOrUpdatePackageStub.resolves({ data: {} });
|
|
515
|
+
unlinkStub.callsArg(1);
|
|
516
|
+
|
|
517
|
+
await publish("http://test-server", 2, false, false, false);
|
|
518
|
+
|
|
519
|
+
expect(getConfirmationStub.calledOnce).to.be.true;
|
|
520
|
+
expect(createOrUpdatePackageStub.calledOnce).to.be.true;
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it("should cancel when confirmation is denied", async () => {
|
|
524
|
+
const mockManifest = {
|
|
525
|
+
name: "test-package",
|
|
526
|
+
version: "1.0.0",
|
|
527
|
+
description: "Test package",
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
readFileSyncStub.returns(JSON.stringify(mockManifest));
|
|
531
|
+
getConfirmationStub.resolves(false);
|
|
532
|
+
|
|
533
|
+
await publish("http://test-server", 2, false, false, false);
|
|
534
|
+
|
|
535
|
+
expect(getConfirmationStub.calledOnce).to.be.true;
|
|
536
|
+
expect(createOrUpdatePackageStub.called).to.be.false;
|
|
537
|
+
expect(loggerStub.info.calledWith(sinon.match("Operation cancelled."))).to
|
|
538
|
+
.be.true;
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it("should handle API errors", async function () {
|
|
542
|
+
this.timeout(5000);
|
|
543
|
+
const mockManifest = {
|
|
544
|
+
name: "test-package",
|
|
545
|
+
version: "1.0.0",
|
|
546
|
+
description: "Test package",
|
|
547
|
+
};
|
|
548
|
+
const mockPackageData = Buffer.from("test package data");
|
|
549
|
+
const mockError = new Error("API Error");
|
|
550
|
+
|
|
551
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
552
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
553
|
+
return mockPackageData;
|
|
554
|
+
});
|
|
555
|
+
getConfirmationStub.resolves(true);
|
|
556
|
+
createOrUpdatePackageStub.rejects(mockError);
|
|
557
|
+
unlinkStub.callsArg(1);
|
|
558
|
+
|
|
559
|
+
await publish("http://test-server", 2, true, true, false);
|
|
560
|
+
|
|
561
|
+
expect(createOrUpdatePackageStub.calledOnce).to.be.true;
|
|
562
|
+
expect(
|
|
563
|
+
loggerStub.error.calledWith(sinon.match("Failed to publish package")),
|
|
564
|
+
).to.be.true;
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
it("should log package URL after successful publish", async function () {
|
|
568
|
+
this.timeout(5000);
|
|
569
|
+
const mockManifest = {
|
|
570
|
+
name: "test-package",
|
|
571
|
+
version: "1.0.0",
|
|
572
|
+
description: "Test package",
|
|
573
|
+
};
|
|
574
|
+
const mockPackageData = Buffer.from("test package data");
|
|
575
|
+
const mockResponse = {
|
|
576
|
+
data: { name: "test-package", version: "1.0.0" },
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
readFileSyncStub.callsFake((filePath: string) => {
|
|
580
|
+
if (filePath === "publisher.json") return JSON.stringify(mockManifest);
|
|
581
|
+
return mockPackageData;
|
|
582
|
+
});
|
|
583
|
+
getConfirmationStub.resolves(true);
|
|
584
|
+
createOrUpdatePackageStub.resolves(mockResponse);
|
|
585
|
+
unlinkStub.callsArg(1);
|
|
586
|
+
|
|
587
|
+
await publish("http://test-server", 2, false, true, false);
|
|
588
|
+
|
|
589
|
+
expect(
|
|
590
|
+
loggerStub.info.calledWith(
|
|
591
|
+
sinon.match(
|
|
592
|
+
"Package available at: test-org/test-project/test-package/1.0.0",
|
|
593
|
+
),
|
|
594
|
+
),
|
|
595
|
+
).to.be.true;
|
|
596
|
+
});
|
|
597
|
+
});
|
|
@@ -27,6 +27,14 @@ export async function publish(
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
const tokenValidation = clientConfig.isTokenValid();
|
|
31
|
+
if (!tokenValidation.valid) {
|
|
32
|
+
logger.error(
|
|
33
|
+
tokenValidation.reason || "Please, make sure that you are logged in",
|
|
34
|
+
);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
if (!validateManifest()) {
|
|
31
39
|
return;
|
|
32
40
|
}
|
|
@@ -34,11 +42,23 @@ export async function publish(
|
|
|
34
42
|
const projectName = clientConfig.getProject();
|
|
35
43
|
const organizationName = clientConfig.getOrganization();
|
|
36
44
|
|
|
45
|
+
if (!organizationName) {
|
|
46
|
+
logger.error("Please, make sure that you are logged in");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
37
50
|
if (!projectName) {
|
|
38
51
|
logger.error("Please, make sure to set a project");
|
|
39
52
|
return;
|
|
40
53
|
}
|
|
41
54
|
|
|
55
|
+
if (!fs.existsSync(PACKAGE_MANIFEST_NAME)) {
|
|
56
|
+
logger.error(
|
|
57
|
+
`Failed to publish the package. Could not find ${PACKAGE_MANIFEST_NAME}, please ensure you are in a directory containing ${PACKAGE_MANIFEST_NAME}`,
|
|
58
|
+
);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
42
62
|
const packageManifestJson = fs.readFileSync(PACKAGE_MANIFEST_NAME);
|
|
43
63
|
const packageManifest = JSON.parse(packageManifestJson.toString());
|
|
44
64
|
|
|
@@ -141,6 +161,18 @@ async function pushTmpPackageToRemoteServer(
|
|
|
141
161
|
.createHash("md5")
|
|
142
162
|
.update(fs.readFileSync(tmpPackagePath))
|
|
143
163
|
.digest("hex");
|
|
164
|
+
if (debug) {
|
|
165
|
+
logger.debug("Package contents: " + packageContents);
|
|
166
|
+
logger.debug("Organization name: " + organizationName);
|
|
167
|
+
logger.debug("Project name: " + projectName);
|
|
168
|
+
logger.debug("Name: " + name);
|
|
169
|
+
logger.debug("Package: " + JSON.stringify(_package));
|
|
170
|
+
logger.debug("Version: " + JSON.stringify(version));
|
|
171
|
+
logger.debug("Control plane: " + controlPlane);
|
|
172
|
+
logger.debug(
|
|
173
|
+
"Client config: " + JSON.stringify(clientConfig.getHeaders()),
|
|
174
|
+
);
|
|
175
|
+
}
|
|
144
176
|
const response = await packagesApi.createOrUpdatePackage(
|
|
145
177
|
organizationName,
|
|
146
178
|
projectName,
|