@dainprotocol/cli 1.2.26 → 1.2.30
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/dist/__tests__/build.test.js +289 -0
- package/dist/__tests__/deploy.test.js +126 -0
- package/dist/__tests__/dev.test.js +321 -0
- package/dist/__tests__/init.test.js +290 -0
- package/dist/__tests__/integration.test.js +134 -0
- package/dist/__tests__/logs.test.js +135 -0
- package/dist/__tests__/testchat.test.js +214 -0
- package/dist/__tests__/utils.test.js +324 -0
- package/dist/commands/build.js +28 -61
- package/dist/commands/deploy.js +123 -162
- package/dist/commands/dev.js +118 -164
- package/dist/commands/init.js +2 -9
- package/dist/commands/logs.js +94 -88
- package/dist/commands/start.js +15 -4
- package/dist/commands/status.js +27 -31
- package/dist/commands/undeploy.js +29 -41
- package/dist/index.js +0 -7
- package/dist/templates/default/dain.json +1 -1
- package/dist/utils.js +112 -37
- package/package.json +12 -5
package/dist/commands/deploy.js
CHANGED
|
@@ -46,18 +46,18 @@ var fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
46
46
|
var path_1 = __importDefault(require("path"));
|
|
47
47
|
var archiver_1 = __importDefault(require("archiver"));
|
|
48
48
|
var build_1 = __importDefault(require("./build"));
|
|
49
|
-
var status_1 = __importDefault(require("./status"));
|
|
50
49
|
var START_DEPLOY_URI = "/api/app/data/deployments/start-deploy";
|
|
50
|
+
var DEPLOY_TIMEOUT_MS = 120000;
|
|
51
51
|
function deploy(options) {
|
|
52
52
|
return __awaiter(this, void 0, void 0, function () {
|
|
53
|
-
var config, spinner, basePath, deployPath, isProduction, environmentName, _a, repoName, branchName, projectId, _b, result, response, envArray, error_1;
|
|
54
|
-
return __generator(this, function (
|
|
55
|
-
switch (
|
|
53
|
+
var config, spinner, basePath, deployPath, isProduction, environmentName, _a, repoName, branchName, projectId, _b, result, response, envArray, _c, error_1;
|
|
54
|
+
return __generator(this, function (_d) {
|
|
55
|
+
switch (_d.label) {
|
|
56
56
|
case 0:
|
|
57
57
|
config = (0, utils_1.getDainConfig)(options.config);
|
|
58
58
|
spinner = (0, ora_1.default)("Deploying project...").start();
|
|
59
|
-
basePath = config["api-base-url"] ||
|
|
60
|
-
deployPath =
|
|
59
|
+
basePath = config["api-base-url"] || utils_1.DEFAULT_API_BASE_URL;
|
|
60
|
+
deployPath = (0, utils_1.joinUrl)(basePath, START_DEPLOY_URI);
|
|
61
61
|
isProduction = config["environment"] === "production";
|
|
62
62
|
environmentName = config["environment"] || "production";
|
|
63
63
|
_a = checkGitConfig(), repoName = _a.repoName, branchName = _a.branchName;
|
|
@@ -66,78 +66,78 @@ function deploy(options) {
|
|
|
66
66
|
if (!(repoName && branchName)) return [3 /*break*/, 2];
|
|
67
67
|
return [4 /*yield*/, getProjectId({ basePath: basePath, repoName: repoName })];
|
|
68
68
|
case 1:
|
|
69
|
-
_b =
|
|
69
|
+
_b = _d.sent();
|
|
70
70
|
return [3 /*break*/, 3];
|
|
71
71
|
case 2:
|
|
72
72
|
_b = null;
|
|
73
|
-
|
|
73
|
+
_d.label = 3;
|
|
74
74
|
case 3:
|
|
75
75
|
projectId = _b;
|
|
76
76
|
if (!projectId && repoName && branchName)
|
|
77
77
|
spinner.fail("No project found on platform linked to this repository.");
|
|
78
|
-
|
|
78
|
+
_d.label = 4;
|
|
79
79
|
case 4:
|
|
80
|
-
|
|
80
|
+
_d.trys.push([4, 18, , 19]);
|
|
81
81
|
if (!(projectId && repoName && branchName)) return [3 /*break*/, 7];
|
|
82
|
-
// Deploy project using github repository
|
|
83
82
|
spinner.info("Deploying project using github repository...").start();
|
|
84
|
-
return [4 /*yield*/,
|
|
83
|
+
return [4 /*yield*/, (0, utils_1.fetchWithTimeout)((0, utils_1.joinUrl)(basePath, "/api/app/codegen/data/projects/".concat(projectId, "/start-deploy")), {
|
|
85
84
|
method: "POST",
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
branch: branchName,
|
|
90
|
-
}),
|
|
91
|
-
})];
|
|
85
|
+
headers: { "Content-Type": "application/json" },
|
|
86
|
+
body: JSON.stringify({ environment: environmentName, isProduction: isProduction, branch: branchName }),
|
|
87
|
+
}, DEPLOY_TIMEOUT_MS)];
|
|
92
88
|
case 5:
|
|
93
|
-
response =
|
|
89
|
+
response = _d.sent();
|
|
90
|
+
if (!response.ok)
|
|
91
|
+
throw new Error("Deploy failed: ".concat(response.status, " ").concat(response.statusText));
|
|
94
92
|
return [4 /*yield*/, response.json()];
|
|
95
93
|
case 6:
|
|
96
|
-
result =
|
|
97
|
-
return [3 /*break*/,
|
|
94
|
+
result = _d.sent();
|
|
95
|
+
return [3 /*break*/, 14];
|
|
98
96
|
case 7:
|
|
99
|
-
// Deploy project using local files
|
|
100
97
|
spinner.info("Deploying project using local files...").start();
|
|
101
98
|
return [4 /*yield*/, loadAndValidateEnvVariables()];
|
|
102
99
|
case 8:
|
|
103
|
-
envArray =
|
|
100
|
+
envArray = _d.sent();
|
|
104
101
|
return [4 /*yield*/, (0, build_1.default)({ config: options.config, deploy: true })];
|
|
105
102
|
case 9:
|
|
106
|
-
|
|
103
|
+
_d.sent();
|
|
107
104
|
return [4 /*yield*/, deployAndPushFiles(deployPath, envArray, isProduction, environmentName)];
|
|
108
105
|
case 10:
|
|
109
|
-
result =
|
|
110
|
-
|
|
111
|
-
method: "GET",
|
|
112
|
-
})];
|
|
106
|
+
result = _d.sent();
|
|
107
|
+
_d.label = 11;
|
|
113
108
|
case 11:
|
|
114
|
-
|
|
115
|
-
|
|
109
|
+
_d.trys.push([11, 13, , 14]);
|
|
110
|
+
return [4 /*yield*/, (0, utils_1.fetchWithTimeout)(result.service.url, { method: "GET" }, 10000)];
|
|
116
111
|
case 12:
|
|
117
|
-
|
|
118
|
-
return [
|
|
112
|
+
_d.sent();
|
|
113
|
+
return [3 /*break*/, 14];
|
|
119
114
|
case 13:
|
|
120
|
-
_c.sent();
|
|
115
|
+
_c = _d.sent();
|
|
116
|
+
return [3 /*break*/, 14];
|
|
117
|
+
case 14:
|
|
118
|
+
if (!result) return [3 /*break*/, 16];
|
|
119
|
+
return [4 /*yield*/, updateDainJson(result)];
|
|
120
|
+
case 15:
|
|
121
|
+
_d.sent();
|
|
121
122
|
printDeploymentResult(result, spinner);
|
|
122
123
|
process.exit(0);
|
|
123
|
-
return [3 /*break*/,
|
|
124
|
-
case
|
|
124
|
+
return [3 /*break*/, 17];
|
|
125
|
+
case 16:
|
|
125
126
|
spinner.fail("Deployment failed.");
|
|
126
127
|
process.exit(1);
|
|
127
|
-
|
|
128
|
-
case
|
|
129
|
-
case
|
|
130
|
-
error_1 =
|
|
128
|
+
_d.label = 17;
|
|
129
|
+
case 17: return [3 /*break*/, 19];
|
|
130
|
+
case 18:
|
|
131
|
+
error_1 = _d.sent();
|
|
131
132
|
spinner.fail("Deployment failed.");
|
|
132
133
|
(0, utils_1.logError)("Error during deployment: ", error_1);
|
|
133
134
|
process.exit(1);
|
|
134
|
-
return [3 /*break*/,
|
|
135
|
-
case
|
|
135
|
+
return [3 /*break*/, 19];
|
|
136
|
+
case 19: return [2 /*return*/];
|
|
136
137
|
}
|
|
137
138
|
});
|
|
138
139
|
});
|
|
139
140
|
}
|
|
140
|
-
// Loads and validates environment variables
|
|
141
141
|
function loadAndValidateEnvVariables() {
|
|
142
142
|
return __awaiter(this, void 0, void 0, function () {
|
|
143
143
|
var envArray;
|
|
@@ -159,177 +159,138 @@ function loadAndValidateEnvVariables() {
|
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
|
-
// Deploys and pushes files to the platform
|
|
163
162
|
function deployAndPushFiles(startDeployUrl, envArray, isProduction, environmentName) {
|
|
164
163
|
return __awaiter(this, void 0, void 0, function () {
|
|
165
|
-
var projectZip, projectZipBuffer, formData, response, errorText
|
|
164
|
+
var projectZip, projectZipBuffer, formData, response, errorText;
|
|
166
165
|
return __generator(this, function (_a) {
|
|
167
166
|
switch (_a.label) {
|
|
168
167
|
case 0: return [4 /*yield*/, zipDirectory("./", "project.zip")];
|
|
169
168
|
case 1:
|
|
170
169
|
projectZip = _a.sent();
|
|
171
|
-
|
|
170
|
+
_a.label = 2;
|
|
172
171
|
case 2:
|
|
172
|
+
_a.trys.push([2, , 7, 9]);
|
|
173
|
+
return [4 /*yield*/, fs_extra_1.default.readFile(projectZip)];
|
|
174
|
+
case 3:
|
|
173
175
|
projectZipBuffer = _a.sent();
|
|
174
176
|
formData = new FormData();
|
|
175
177
|
formData.append("array", JSON.stringify(envArray));
|
|
176
178
|
formData.append("file", new Blob([new Uint8Array(projectZipBuffer)]), "project.zip");
|
|
177
179
|
formData.append("isProduction", isProduction.toString());
|
|
178
180
|
formData.append("environment", environmentName);
|
|
179
|
-
|
|
180
|
-
case 3:
|
|
181
|
-
_a.trys.push([3, 8, , 9]);
|
|
182
|
-
return [4 /*yield*/, fetch(startDeployUrl, {
|
|
183
|
-
method: "POST",
|
|
184
|
-
body: formData,
|
|
185
|
-
})];
|
|
181
|
+
return [4 /*yield*/, (0, utils_1.fetchWithTimeout)(startDeployUrl, { method: "POST", body: formData }, DEPLOY_TIMEOUT_MS)];
|
|
186
182
|
case 4:
|
|
187
183
|
response = _a.sent();
|
|
188
184
|
if (!!response.ok) return [3 /*break*/, 6];
|
|
189
185
|
return [4 /*yield*/, response.text()];
|
|
190
186
|
case 5:
|
|
191
187
|
errorText = _a.sent();
|
|
192
|
-
throw new Error("Deployment failed: ".concat(response.statusText, ". Response: ").concat(errorText));
|
|
193
|
-
case 6: return [
|
|
194
|
-
case 7:
|
|
195
|
-
result = _a.sent();
|
|
196
|
-
return [2 /*return*/, result];
|
|
188
|
+
throw new Error("Deployment failed: ".concat(response.status, " ").concat(response.statusText, ". Response: ").concat(errorText));
|
|
189
|
+
case 6: return [2 /*return*/, response.json()];
|
|
190
|
+
case 7: return [4 /*yield*/, fs_extra_1.default.remove(projectZip).catch(function () { return undefined; })];
|
|
197
191
|
case 8:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
console.error("Detailed error:", error_2);
|
|
201
|
-
process.exit(1);
|
|
202
|
-
return [3 /*break*/, 9];
|
|
192
|
+
_a.sent();
|
|
193
|
+
return [7 /*endfinally*/];
|
|
203
194
|
case 9: return [2 /*return*/];
|
|
204
195
|
}
|
|
205
196
|
});
|
|
206
197
|
});
|
|
207
198
|
}
|
|
208
|
-
// Reads the .env file and returns an array of key-value pairs
|
|
209
199
|
function loadEnvVariables() {
|
|
210
200
|
return __awaiter(this, void 0, void 0, function () {
|
|
211
|
-
var files, envFile,
|
|
212
|
-
return __generator(this, function (
|
|
213
|
-
switch (
|
|
201
|
+
var files, envFile, _a;
|
|
202
|
+
return __generator(this, function (_b) {
|
|
203
|
+
switch (_b.label) {
|
|
214
204
|
case 0: return [4 /*yield*/, fs_extra_1.default.readdir("./")];
|
|
215
205
|
case 1:
|
|
216
|
-
files =
|
|
206
|
+
files = _b.sent();
|
|
217
207
|
envFile = files.find(function (file) { return file === ".env"; });
|
|
218
208
|
if (!envFile) {
|
|
219
209
|
(0, utils_1.logError)("Environment file not found. Please create a .env file in the build directory.");
|
|
220
210
|
process.exit(1);
|
|
221
211
|
}
|
|
212
|
+
_a = utils_1.parseEnvContent;
|
|
222
213
|
return [4 /*yield*/, fs_extra_1.default.readFile(path_1.default.join("./", envFile), "utf-8")];
|
|
223
|
-
case 2:
|
|
224
|
-
envContent = _a.sent();
|
|
225
|
-
return [2 /*return*/, envContent
|
|
226
|
-
.split("\n")
|
|
227
|
-
.map(function (line) {
|
|
228
|
-
var _a = line.split("="), name = _a[0], value = _a[1];
|
|
229
|
-
return { name: name, value: value };
|
|
230
|
-
})
|
|
231
|
-
.filter(function (env) { return env.name && env.value; })];
|
|
214
|
+
case 2: return [2 /*return*/, _a.apply(void 0, [_b.sent()])];
|
|
232
215
|
}
|
|
233
216
|
});
|
|
234
217
|
});
|
|
235
218
|
}
|
|
236
|
-
// Zips the current directory and returns the path to the zip file
|
|
237
219
|
function zipDirectory(sourceDir, outputZip) {
|
|
238
|
-
return
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
reject(err);
|
|
247
|
-
});
|
|
248
|
-
archive.pipe(output);
|
|
249
|
-
archive.glob("**/*", { ignore: ["node_modules/**", "project.zip"] });
|
|
250
|
-
archive.finalize();
|
|
251
|
-
})];
|
|
252
|
-
});
|
|
220
|
+
return new Promise(function (resolve, reject) {
|
|
221
|
+
var output = fs_extra_1.default.createWriteStream(outputZip);
|
|
222
|
+
var archive = (0, archiver_1.default)("zip", { zlib: { level: 9 } });
|
|
223
|
+
output.on("close", function () { return resolve(outputZip); });
|
|
224
|
+
archive.on("error", function (err) { (0, utils_1.logError)("Error during zipping: ", err); reject(err); });
|
|
225
|
+
archive.pipe(output);
|
|
226
|
+
archive.glob("**/*", { ignore: ["node_modules/**", "project.zip", ".git/**", ".env*", ".dain/**"] });
|
|
227
|
+
archive.finalize();
|
|
253
228
|
});
|
|
254
229
|
}
|
|
255
|
-
|
|
256
|
-
var
|
|
257
|
-
return __generator(this, function (_a) {
|
|
258
|
-
switch (_a.label) {
|
|
259
|
-
case 0: return [4 /*yield*/, (0, status_1.default)({}, deploymentId, environmentName, serviceId)];
|
|
260
|
-
case 1:
|
|
261
|
-
statusResult = _a.sent();
|
|
262
|
-
if (statusResult.status === "RUNNING") {
|
|
263
|
-
return [2 /*return*/];
|
|
264
|
-
}
|
|
265
|
-
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 15000); })];
|
|
266
|
-
case 2:
|
|
267
|
-
_a.sent();
|
|
268
|
-
return [4 /*yield*/, recursiveStatusUntilRunning(config, deploymentId, environmentName, serviceId)];
|
|
269
|
-
case 3:
|
|
270
|
-
_a.sent();
|
|
271
|
-
return [2 /*return*/];
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
}); };
|
|
275
|
-
var checkGitConfig = function () {
|
|
230
|
+
function checkGitConfig() {
|
|
231
|
+
var _a, _b, _c;
|
|
276
232
|
try {
|
|
277
|
-
// Read git config and get repo name
|
|
278
233
|
var gitConfig = fs_extra_1.default.readFileSync(".git/config", "utf-8");
|
|
279
|
-
var remote = gitConfig.match(/\[remote "origin"\]\
|
|
280
|
-
var
|
|
281
|
-
|
|
234
|
+
var remote = gitConfig.match(/\[remote "origin"\][\s\S]*?url = ([^\n]+)/);
|
|
235
|
+
var remoteUrl = remote ? remote[1].trim() : null;
|
|
236
|
+
var repoName = ((_a = remoteUrl === null || remoteUrl === void 0 ? void 0 : remoteUrl.match(/git@github.com:(.+)\.git/)) === null || _a === void 0 ? void 0 : _a[1])
|
|
237
|
+
|| ((_b = remoteUrl === null || remoteUrl === void 0 ? void 0 : remoteUrl.match(/https?:\/\/github.com\/(.+)\.git/)) === null || _b === void 0 ? void 0 : _b[1])
|
|
238
|
+
|| null;
|
|
282
239
|
var gitHead = fs_extra_1.default.readFileSync(".git/HEAD", "utf-8");
|
|
283
|
-
var
|
|
284
|
-
var branchName = branch ? branch[1] : null;
|
|
240
|
+
var branchName = ((_c = gitHead.match(/ref: refs\/heads\/(.*)/)) === null || _c === void 0 ? void 0 : _c[1]) || null;
|
|
285
241
|
return { repoName: repoName, branchName: branchName };
|
|
286
242
|
}
|
|
287
|
-
catch (
|
|
243
|
+
catch (_d) {
|
|
288
244
|
return { repoName: null, branchName: null };
|
|
289
245
|
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
246
|
+
}
|
|
247
|
+
function getProjectId(_a) {
|
|
248
|
+
return __awaiter(this, arguments, void 0, function (_b) {
|
|
249
|
+
var response, _c;
|
|
250
|
+
var basePath = _b.basePath, repoName = _b.repoName;
|
|
251
|
+
return __generator(this, function (_d) {
|
|
252
|
+
switch (_d.label) {
|
|
253
|
+
case 0:
|
|
254
|
+
_d.trys.push([0, 2, , 3]);
|
|
255
|
+
return [4 /*yield*/, (0, utils_1.fetchWithTimeout)((0, utils_1.joinUrl)(basePath, "/api/app/codegen/data/projects/get-by-repo?repo=".concat(encodeURIComponent(repoName))), { method: "GET" })];
|
|
256
|
+
case 1:
|
|
257
|
+
response = _d.sent();
|
|
258
|
+
return [2 /*return*/, response.ok ? response.json() : null];
|
|
259
|
+
case 2:
|
|
260
|
+
_c = _d.sent();
|
|
261
|
+
return [2 /*return*/, null];
|
|
262
|
+
case 3: return [2 /*return*/];
|
|
263
|
+
}
|
|
264
|
+
});
|
|
310
265
|
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
266
|
+
}
|
|
267
|
+
function updateDainJson(result) {
|
|
268
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
269
|
+
var dainJson, _a, _b, error_2;
|
|
270
|
+
return __generator(this, function (_c) {
|
|
271
|
+
switch (_c.label) {
|
|
272
|
+
case 0:
|
|
273
|
+
_c.trys.push([0, 3, , 4]);
|
|
274
|
+
_b = (_a = JSON).parse;
|
|
275
|
+
return [4 /*yield*/, fs_extra_1.default.readFile("./dain.json", "utf-8")];
|
|
276
|
+
case 1:
|
|
277
|
+
dainJson = _b.apply(_a, [_c.sent()]);
|
|
278
|
+
dainJson["deployment-id"] = result.deploymentId;
|
|
279
|
+
dainJson["service-id"] = result.serviceId;
|
|
280
|
+
return [4 /*yield*/, fs_extra_1.default.writeFile("./dain.json", JSON.stringify(dainJson, null, 2))];
|
|
281
|
+
case 2:
|
|
282
|
+
_c.sent();
|
|
283
|
+
return [3 /*break*/, 4];
|
|
284
|
+
case 3:
|
|
285
|
+
error_2 = _c.sent();
|
|
286
|
+
(0, utils_1.logError)("Failed to update dain.json", error_2);
|
|
287
|
+
return [3 /*break*/, 4];
|
|
288
|
+
case 4: return [2 /*return*/];
|
|
289
|
+
}
|
|
290
|
+
});
|
|
330
291
|
});
|
|
331
|
-
}
|
|
332
|
-
|
|
292
|
+
}
|
|
293
|
+
function printDeploymentResult(result, spinner) {
|
|
333
294
|
console.log("\n-----------------------");
|
|
334
295
|
spinner.succeed("Deployment URL: ".concat(result.service.url));
|
|
335
296
|
spinner.succeed("Deployment ID: ".concat(result.deploymentId));
|
|
@@ -337,4 +298,4 @@ var printDeploymentResult = function (result, spinner) {
|
|
|
337
298
|
spinner.succeed("Deployment completed successfully.");
|
|
338
299
|
spinner.info("You can access logs using `dain logs -w` command.");
|
|
339
300
|
console.log("-----------------------");
|
|
340
|
-
}
|
|
301
|
+
}
|