@dainprotocol/cli 1.2.28 → 1.2.31
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 +10 -27
- package/dist/__tests__/dev.test.js +189 -0
- package/dist/__tests__/init.test.js +290 -0
- package/dist/__tests__/integration.test.js +5 -22
- package/dist/__tests__/testchat.test.js +214 -0
- package/dist/__tests__/utils.test.js +324 -0
- package/dist/commands/build.js +29 -62
- package/dist/commands/deploy.js +96 -167
- package/dist/commands/dev.js +34 -84
- package/dist/commands/init.js +2 -9
- package/dist/commands/logs.js +35 -117
- package/dist/commands/start.js +15 -4
- package/dist/commands/status.js +14 -65
- package/dist/commands/undeploy.js +10 -66
- package/dist/index.js +0 -7
- package/dist/templates/default/dain.json +1 -1
- package/dist/utils.js +169 -35
- package/package.json +3 -3
package/dist/commands/deploy.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -58,31 +47,7 @@ var path_1 = __importDefault(require("path"));
|
|
|
58
47
|
var archiver_1 = __importDefault(require("archiver"));
|
|
59
48
|
var build_1 = __importDefault(require("./build"));
|
|
60
49
|
var START_DEPLOY_URI = "/api/app/data/deployments/start-deploy";
|
|
61
|
-
var
|
|
62
|
-
function fetchWithTimeout(url_1, options_1) {
|
|
63
|
-
return __awaiter(this, arguments, void 0, function (url, options, timeoutMs) {
|
|
64
|
-
var controller, timeoutId, response;
|
|
65
|
-
if (timeoutMs === void 0) { timeoutMs = FETCH_TIMEOUT_MS; }
|
|
66
|
-
return __generator(this, function (_a) {
|
|
67
|
-
switch (_a.label) {
|
|
68
|
-
case 0:
|
|
69
|
-
controller = new AbortController();
|
|
70
|
-
timeoutId = setTimeout(function () { return controller.abort(); }, timeoutMs);
|
|
71
|
-
_a.label = 1;
|
|
72
|
-
case 1:
|
|
73
|
-
_a.trys.push([1, , 3, 4]);
|
|
74
|
-
return [4 /*yield*/, fetch(url, __assign(__assign({}, options), { signal: controller.signal }))];
|
|
75
|
-
case 2:
|
|
76
|
-
response = _a.sent();
|
|
77
|
-
return [2 /*return*/, response];
|
|
78
|
-
case 3:
|
|
79
|
-
clearTimeout(timeoutId);
|
|
80
|
-
return [7 /*endfinally*/];
|
|
81
|
-
case 4: return [2 /*return*/];
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
}
|
|
50
|
+
var DEPLOY_TIMEOUT_MS = 120000;
|
|
86
51
|
function deploy(options) {
|
|
87
52
|
return __awaiter(this, void 0, void 0, function () {
|
|
88
53
|
var config, spinner, basePath, deployPath, isProduction, environmentName, _a, repoName, branchName, projectId, _b, result, response, envArray, _c, error_1;
|
|
@@ -91,8 +56,8 @@ function deploy(options) {
|
|
|
91
56
|
case 0:
|
|
92
57
|
config = (0, utils_1.getDainConfig)(options.config);
|
|
93
58
|
spinner = (0, ora_1.default)("Deploying project...").start();
|
|
94
|
-
basePath = config["api-base-url"] ||
|
|
95
|
-
deployPath =
|
|
59
|
+
basePath = config["api-base-url"] || utils_1.DEFAULT_API_BASE_URL;
|
|
60
|
+
deployPath = (0, utils_1.joinUrl)(basePath, START_DEPLOY_URI);
|
|
96
61
|
isProduction = config["environment"] === "production";
|
|
97
62
|
environmentName = config["environment"] || "production";
|
|
98
63
|
_a = checkGitConfig(), repoName = _a.repoName, branchName = _a.branchName;
|
|
@@ -112,30 +77,24 @@ function deploy(options) {
|
|
|
112
77
|
spinner.fail("No project found on platform linked to this repository.");
|
|
113
78
|
_d.label = 4;
|
|
114
79
|
case 4:
|
|
115
|
-
_d.trys.push([4,
|
|
80
|
+
_d.trys.push([4, 16, , 17]);
|
|
81
|
+
result = void 0;
|
|
116
82
|
if (!(projectId && repoName && branchName)) return [3 /*break*/, 7];
|
|
117
|
-
// Deploy project using github repository
|
|
118
83
|
spinner.info("Deploying project using github repository...").start();
|
|
119
|
-
return [4 /*yield*/, fetchWithTimeout(
|
|
84
|
+
return [4 /*yield*/, (0, utils_1.fetchWithTimeout)((0, utils_1.joinUrl)(basePath, "/api/app/codegen/data/projects/".concat(projectId, "/start-deploy")), {
|
|
120
85
|
method: "POST",
|
|
121
86
|
headers: { "Content-Type": "application/json" },
|
|
122
|
-
body: JSON.stringify({
|
|
123
|
-
|
|
124
|
-
isProduction: isProduction,
|
|
125
|
-
branch: branchName,
|
|
126
|
-
}),
|
|
127
|
-
})];
|
|
87
|
+
body: JSON.stringify({ environment: environmentName, isProduction: isProduction, branch: branchName }),
|
|
88
|
+
}, DEPLOY_TIMEOUT_MS)];
|
|
128
89
|
case 5:
|
|
129
90
|
response = _d.sent();
|
|
130
|
-
if (!response.ok)
|
|
91
|
+
if (!response.ok)
|
|
131
92
|
throw new Error("Deploy failed: ".concat(response.status, " ").concat(response.statusText));
|
|
132
|
-
}
|
|
133
93
|
return [4 /*yield*/, response.json()];
|
|
134
94
|
case 6:
|
|
135
95
|
result = _d.sent();
|
|
136
96
|
return [3 /*break*/, 14];
|
|
137
97
|
case 7:
|
|
138
|
-
// Deploy project using local files
|
|
139
98
|
spinner.info("Deploying project using local files...").start();
|
|
140
99
|
return [4 /*yield*/, loadAndValidateEnvVariables()];
|
|
141
100
|
case 8:
|
|
@@ -149,38 +108,30 @@ function deploy(options) {
|
|
|
149
108
|
_d.label = 11;
|
|
150
109
|
case 11:
|
|
151
110
|
_d.trys.push([11, 13, , 14]);
|
|
152
|
-
return [4 /*yield*/, fetchWithTimeout(result.service.url, { method: "GET" }, 10000)];
|
|
111
|
+
return [4 /*yield*/, (0, utils_1.fetchWithTimeout)(result.service.url, { method: "GET" }, 10000)];
|
|
153
112
|
case 12:
|
|
154
113
|
_d.sent();
|
|
155
114
|
return [3 /*break*/, 14];
|
|
156
115
|
case 13:
|
|
157
116
|
_c = _d.sent();
|
|
158
117
|
return [3 /*break*/, 14];
|
|
159
|
-
case 14:
|
|
160
|
-
if (!result) return [3 /*break*/, 16];
|
|
161
|
-
return [4 /*yield*/, updateDainJson(result)];
|
|
118
|
+
case 14: return [4 /*yield*/, updateDainJson(result)];
|
|
162
119
|
case 15:
|
|
163
120
|
_d.sent();
|
|
164
121
|
printDeploymentResult(result, spinner);
|
|
165
122
|
process.exit(0);
|
|
166
123
|
return [3 /*break*/, 17];
|
|
167
124
|
case 16:
|
|
168
|
-
spinner.fail("Deployment failed.");
|
|
169
|
-
process.exit(1);
|
|
170
|
-
_d.label = 17;
|
|
171
|
-
case 17: return [3 /*break*/, 19];
|
|
172
|
-
case 18:
|
|
173
125
|
error_1 = _d.sent();
|
|
174
126
|
spinner.fail("Deployment failed.");
|
|
175
127
|
(0, utils_1.logError)("Error during deployment: ", error_1);
|
|
176
128
|
process.exit(1);
|
|
177
|
-
return [3 /*break*/,
|
|
178
|
-
case
|
|
129
|
+
return [3 /*break*/, 17];
|
|
130
|
+
case 17: return [2 /*return*/];
|
|
179
131
|
}
|
|
180
132
|
});
|
|
181
133
|
});
|
|
182
134
|
}
|
|
183
|
-
// Loads and validates environment variables
|
|
184
135
|
function loadAndValidateEnvVariables() {
|
|
185
136
|
return __awaiter(this, void 0, void 0, function () {
|
|
186
137
|
var envArray;
|
|
@@ -202,7 +153,6 @@ function loadAndValidateEnvVariables() {
|
|
|
202
153
|
});
|
|
203
154
|
});
|
|
204
155
|
}
|
|
205
|
-
// Deploys and pushes files to the platform
|
|
206
156
|
function deployAndPushFiles(startDeployUrl, envArray, isProduction, environmentName) {
|
|
207
157
|
return __awaiter(this, void 0, void 0, function () {
|
|
208
158
|
var projectZip, projectZipBuffer, formData, response, errorText;
|
|
@@ -211,151 +161,130 @@ function deployAndPushFiles(startDeployUrl, envArray, isProduction, environmentN
|
|
|
211
161
|
case 0: return [4 /*yield*/, zipDirectory("./", "project.zip")];
|
|
212
162
|
case 1:
|
|
213
163
|
projectZip = _a.sent();
|
|
214
|
-
|
|
164
|
+
_a.label = 2;
|
|
215
165
|
case 2:
|
|
166
|
+
_a.trys.push([2, , 7, 9]);
|
|
167
|
+
return [4 /*yield*/, fs_extra_1.default.readFile(projectZip)];
|
|
168
|
+
case 3:
|
|
216
169
|
projectZipBuffer = _a.sent();
|
|
217
170
|
formData = new FormData();
|
|
218
171
|
formData.append("array", JSON.stringify(envArray));
|
|
219
172
|
formData.append("file", new Blob([new Uint8Array(projectZipBuffer)]), "project.zip");
|
|
220
173
|
formData.append("isProduction", isProduction.toString());
|
|
221
174
|
formData.append("environment", environmentName);
|
|
222
|
-
return [4 /*yield*/, fetchWithTimeout(startDeployUrl, {
|
|
223
|
-
|
|
224
|
-
body: formData,
|
|
225
|
-
})];
|
|
226
|
-
case 3:
|
|
175
|
+
return [4 /*yield*/, (0, utils_1.fetchWithTimeout)(startDeployUrl, { method: "POST", body: formData }, DEPLOY_TIMEOUT_MS)];
|
|
176
|
+
case 4:
|
|
227
177
|
response = _a.sent();
|
|
228
|
-
if (!!response.ok) return [3 /*break*/,
|
|
178
|
+
if (!!response.ok) return [3 /*break*/, 6];
|
|
229
179
|
return [4 /*yield*/, response.text()];
|
|
230
|
-
case
|
|
180
|
+
case 5:
|
|
231
181
|
errorText = _a.sent();
|
|
232
182
|
throw new Error("Deployment failed: ".concat(response.status, " ").concat(response.statusText, ". Response: ").concat(errorText));
|
|
233
|
-
case
|
|
183
|
+
case 6: return [2 /*return*/, response.json()];
|
|
184
|
+
case 7: return [4 /*yield*/, fs_extra_1.default.remove(projectZip).catch(function () { return undefined; })];
|
|
185
|
+
case 8:
|
|
186
|
+
_a.sent();
|
|
187
|
+
return [7 /*endfinally*/];
|
|
188
|
+
case 9: return [2 /*return*/];
|
|
234
189
|
}
|
|
235
190
|
});
|
|
236
191
|
});
|
|
237
192
|
}
|
|
238
|
-
// Reads the .env file and returns an array of key-value pairs
|
|
239
193
|
function loadEnvVariables() {
|
|
240
194
|
return __awaiter(this, void 0, void 0, function () {
|
|
241
|
-
var files, envFile,
|
|
242
|
-
return __generator(this, function (
|
|
243
|
-
switch (
|
|
195
|
+
var files, envFile, _a;
|
|
196
|
+
return __generator(this, function (_b) {
|
|
197
|
+
switch (_b.label) {
|
|
244
198
|
case 0: return [4 /*yield*/, fs_extra_1.default.readdir("./")];
|
|
245
199
|
case 1:
|
|
246
|
-
files =
|
|
200
|
+
files = _b.sent();
|
|
247
201
|
envFile = files.find(function (file) { return file === ".env"; });
|
|
248
202
|
if (!envFile) {
|
|
249
203
|
(0, utils_1.logError)("Environment file not found. Please create a .env file in the build directory.");
|
|
250
204
|
process.exit(1);
|
|
251
205
|
}
|
|
206
|
+
_a = utils_1.parseEnvContent;
|
|
252
207
|
return [4 /*yield*/, fs_extra_1.default.readFile(path_1.default.join("./", envFile), "utf-8")];
|
|
253
|
-
case 2:
|
|
254
|
-
envContent = _a.sent();
|
|
255
|
-
return [2 /*return*/, envContent
|
|
256
|
-
.split("\n")
|
|
257
|
-
.filter(function (line) { return line.trim() && !line.trim().startsWith("#"); })
|
|
258
|
-
.map(function (line) {
|
|
259
|
-
var equalsIndex = line.indexOf("=");
|
|
260
|
-
if (equalsIndex === -1)
|
|
261
|
-
return null;
|
|
262
|
-
var name = line.substring(0, equalsIndex).trim();
|
|
263
|
-
var value = line.substring(equalsIndex + 1).trim();
|
|
264
|
-
// Remove surrounding quotes if present
|
|
265
|
-
var unquotedValue = value.replace(/^["']|["']$/g, "");
|
|
266
|
-
return { name: name, value: unquotedValue };
|
|
267
|
-
})
|
|
268
|
-
.filter(function (env) {
|
|
269
|
-
return env !== null && env.name !== "" && env.value !== "";
|
|
270
|
-
})];
|
|
208
|
+
case 2: return [2 /*return*/, _a.apply(void 0, [_b.sent()])];
|
|
271
209
|
}
|
|
272
210
|
});
|
|
273
211
|
});
|
|
274
212
|
}
|
|
275
|
-
// Zips the current directory and returns the path to the zip file
|
|
276
213
|
function zipDirectory(sourceDir, outputZip) {
|
|
277
|
-
return
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
reject(err);
|
|
286
|
-
});
|
|
287
|
-
archive.pipe(output);
|
|
288
|
-
archive.glob("**/*", { ignore: ["node_modules/**", "project.zip"] });
|
|
289
|
-
archive.finalize();
|
|
290
|
-
})];
|
|
291
|
-
});
|
|
214
|
+
return new Promise(function (resolve, reject) {
|
|
215
|
+
var output = fs_extra_1.default.createWriteStream(outputZip);
|
|
216
|
+
var archive = (0, archiver_1.default)("zip", { zlib: { level: 9 } });
|
|
217
|
+
output.on("close", function () { return resolve(outputZip); });
|
|
218
|
+
archive.on("error", function (err) { (0, utils_1.logError)("Error during zipping: ", err); reject(err); });
|
|
219
|
+
archive.pipe(output);
|
|
220
|
+
archive.glob("**/*", { ignore: ["node_modules/**", "project.zip", ".git/**", ".env*", ".dain/**"] });
|
|
221
|
+
archive.finalize();
|
|
292
222
|
});
|
|
293
223
|
}
|
|
294
|
-
|
|
224
|
+
function checkGitConfig() {
|
|
225
|
+
var _a, _b, _c;
|
|
295
226
|
try {
|
|
296
|
-
// Read git config and get repo name
|
|
297
227
|
var gitConfig = fs_extra_1.default.readFileSync(".git/config", "utf-8");
|
|
298
|
-
var remote = gitConfig.match(/\[remote "origin"\]\
|
|
299
|
-
var
|
|
300
|
-
|
|
228
|
+
var remote = gitConfig.match(/\[remote "origin"\][\s\S]*?url = ([^\n]+)/);
|
|
229
|
+
var remoteUrl = remote ? remote[1].trim() : null;
|
|
230
|
+
var repoName = ((_a = remoteUrl === null || remoteUrl === void 0 ? void 0 : remoteUrl.match(/git@github.com:(.+)\.git/)) === null || _a === void 0 ? void 0 : _a[1])
|
|
231
|
+
|| ((_b = remoteUrl === null || remoteUrl === void 0 ? void 0 : remoteUrl.match(/https?:\/\/github.com\/(.+)\.git/)) === null || _b === void 0 ? void 0 : _b[1])
|
|
232
|
+
|| null;
|
|
301
233
|
var gitHead = fs_extra_1.default.readFileSync(".git/HEAD", "utf-8");
|
|
302
|
-
var
|
|
303
|
-
var branchName = branch ? branch[1] : null;
|
|
234
|
+
var branchName = ((_c = gitHead.match(/ref: refs\/heads\/(.*)/)) === null || _c === void 0 ? void 0 : _c[1]) || null;
|
|
304
235
|
return { repoName: repoName, branchName: branchName };
|
|
305
236
|
}
|
|
306
|
-
catch (
|
|
237
|
+
catch (_d) {
|
|
307
238
|
return { repoName: null, branchName: null };
|
|
308
239
|
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
240
|
+
}
|
|
241
|
+
function getProjectId(_a) {
|
|
242
|
+
return __awaiter(this, arguments, void 0, function (_b) {
|
|
243
|
+
var response, _c;
|
|
244
|
+
var basePath = _b.basePath, repoName = _b.repoName;
|
|
245
|
+
return __generator(this, function (_d) {
|
|
246
|
+
switch (_d.label) {
|
|
247
|
+
case 0:
|
|
248
|
+
_d.trys.push([0, 2, , 3]);
|
|
249
|
+
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" })];
|
|
250
|
+
case 1:
|
|
251
|
+
response = _d.sent();
|
|
252
|
+
return [2 /*return*/, response.ok ? response.json() : null];
|
|
253
|
+
case 2:
|
|
254
|
+
_c = _d.sent();
|
|
321
255
|
return [2 /*return*/, null];
|
|
322
|
-
return [2 /*return
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
return [2 /*return*/, null];
|
|
326
|
-
case 3: return [2 /*return*/];
|
|
327
|
-
}
|
|
256
|
+
case 3: return [2 /*return*/];
|
|
257
|
+
}
|
|
258
|
+
});
|
|
328
259
|
});
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
case 5: return [2 /*return*/];
|
|
355
|
-
}
|
|
260
|
+
}
|
|
261
|
+
function updateDainJson(result) {
|
|
262
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
263
|
+
var dainJson, _a, _b, error_2;
|
|
264
|
+
return __generator(this, function (_c) {
|
|
265
|
+
switch (_c.label) {
|
|
266
|
+
case 0:
|
|
267
|
+
_c.trys.push([0, 3, , 4]);
|
|
268
|
+
_b = (_a = JSON).parse;
|
|
269
|
+
return [4 /*yield*/, fs_extra_1.default.readFile("./dain.json", "utf-8")];
|
|
270
|
+
case 1:
|
|
271
|
+
dainJson = _b.apply(_a, [_c.sent()]);
|
|
272
|
+
dainJson["deployment-id"] = result.deploymentId;
|
|
273
|
+
dainJson["service-id"] = result.serviceId;
|
|
274
|
+
return [4 /*yield*/, fs_extra_1.default.writeFile("./dain.json", JSON.stringify(dainJson, null, 2))];
|
|
275
|
+
case 2:
|
|
276
|
+
_c.sent();
|
|
277
|
+
return [3 /*break*/, 4];
|
|
278
|
+
case 3:
|
|
279
|
+
error_2 = _c.sent();
|
|
280
|
+
(0, utils_1.logError)("Failed to update dain.json", error_2);
|
|
281
|
+
return [3 /*break*/, 4];
|
|
282
|
+
case 4: return [2 /*return*/];
|
|
283
|
+
}
|
|
284
|
+
});
|
|
356
285
|
});
|
|
357
|
-
}
|
|
358
|
-
|
|
286
|
+
}
|
|
287
|
+
function printDeploymentResult(result, spinner) {
|
|
359
288
|
console.log("\n-----------------------");
|
|
360
289
|
spinner.succeed("Deployment URL: ".concat(result.service.url));
|
|
361
290
|
spinner.succeed("Deployment ID: ".concat(result.deploymentId));
|
|
@@ -363,4 +292,4 @@ var printDeploymentResult = function (result, spinner) {
|
|
|
363
292
|
spinner.succeed("Deployment completed successfully.");
|
|
364
293
|
spinner.info("You can access logs using `dain logs -w` command.");
|
|
365
294
|
console.log("-----------------------");
|
|
366
|
-
}
|
|
295
|
+
}
|
package/dist/commands/dev.js
CHANGED
|
@@ -60,7 +60,6 @@ var miniflare_1 = require("miniflare");
|
|
|
60
60
|
var build_1 = __importDefault(require("./build"));
|
|
61
61
|
var fs_extra_1 = __importDefault(require("fs-extra"));
|
|
62
62
|
var net_1 = require("net");
|
|
63
|
-
// Module state
|
|
64
63
|
var childProcess = null;
|
|
65
64
|
var watcher = null;
|
|
66
65
|
var mf = null;
|
|
@@ -68,22 +67,22 @@ var tunnelUrl = null;
|
|
|
68
67
|
var isFirstStart = true;
|
|
69
68
|
var proxyServer = null;
|
|
70
69
|
var isCleaningUp = false;
|
|
70
|
+
var debounceTimer = null;
|
|
71
71
|
function isPortAvailable(port) {
|
|
72
72
|
return new Promise(function (resolve) {
|
|
73
73
|
var server = (0, net_1.createServer)()
|
|
74
|
-
.listen(port, function () {
|
|
75
|
-
|
|
76
|
-
resolve(true);
|
|
77
|
-
})
|
|
78
|
-
.on('error', function () {
|
|
79
|
-
resolve(false);
|
|
80
|
-
});
|
|
74
|
+
.listen(port, function () { server.close(); resolve(true); })
|
|
75
|
+
.on('error', function () { return resolve(false); });
|
|
81
76
|
});
|
|
82
77
|
}
|
|
83
78
|
function cleanup() {
|
|
84
79
|
if (isCleaningUp)
|
|
85
80
|
return;
|
|
86
81
|
isCleaningUp = true;
|
|
82
|
+
if (debounceTimer) {
|
|
83
|
+
clearTimeout(debounceTimer);
|
|
84
|
+
debounceTimer = null;
|
|
85
|
+
}
|
|
87
86
|
if (childProcess) {
|
|
88
87
|
childProcess.kill('SIGTERM');
|
|
89
88
|
childProcess = null;
|
|
@@ -134,14 +133,11 @@ function startProcess(mainFile, envVars, isRestart) {
|
|
|
134
133
|
}
|
|
135
134
|
var spinner = (0, ora_1.default)(isRestart ? 'Restarting development server...' : 'Starting development server...').start();
|
|
136
135
|
var hasStarted = false;
|
|
137
|
-
// Use spawn with args array to prevent command injection
|
|
138
136
|
var tsNodePath = path_1.default.join(process.cwd(), 'node_modules', '.bin', 'ts-node');
|
|
139
|
-
// Check if ts-node exists
|
|
140
137
|
if (!fs_extra_1.default.existsSync(tsNodePath)) {
|
|
141
138
|
spinner.fail('ts-node not found. Run: npm install ts-node typescript');
|
|
142
139
|
return;
|
|
143
140
|
}
|
|
144
|
-
// Check if main file exists
|
|
145
141
|
if (!fs_extra_1.default.existsSync(mainFile)) {
|
|
146
142
|
spinner.fail("Main file not found: ".concat(mainFile));
|
|
147
143
|
return;
|
|
@@ -149,7 +145,7 @@ function startProcess(mainFile, envVars, isRestart) {
|
|
|
149
145
|
childProcess = (0, child_process_1.spawn)(tsNodePath, [mainFile], {
|
|
150
146
|
env: __assign(__assign({}, process.env), envVars),
|
|
151
147
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
152
|
-
shell: false,
|
|
148
|
+
shell: false,
|
|
153
149
|
});
|
|
154
150
|
var markStarted = function (success) {
|
|
155
151
|
if (hasStarted)
|
|
@@ -166,58 +162,32 @@ function startProcess(mainFile, envVars, isRestart) {
|
|
|
166
162
|
spinner.fail('Development server error.');
|
|
167
163
|
}
|
|
168
164
|
};
|
|
169
|
-
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) {
|
|
170
|
-
markStarted(true);
|
|
171
|
-
process.stdout.write(data.toString());
|
|
172
|
-
});
|
|
165
|
+
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) { markStarted(true); process.stdout.write(data.toString()); });
|
|
173
166
|
(_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
174
167
|
var output = data.toString();
|
|
175
|
-
|
|
176
|
-
if (output.includes('Error:') || output.includes('error:')) {
|
|
177
|
-
markStarted(false);
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
markStarted(true);
|
|
181
|
-
}
|
|
168
|
+
markStarted(output.includes('Error:') || output.includes('error:') ? false : true);
|
|
182
169
|
process.stderr.write(output);
|
|
183
170
|
});
|
|
184
171
|
childProcess.on('close', function (code) {
|
|
185
|
-
if (code !== 0 && code !== null && !hasStarted)
|
|
172
|
+
if (code !== 0 && code !== null && !hasStarted)
|
|
186
173
|
spinner.fail("Development server exited with code ".concat(code));
|
|
187
|
-
}
|
|
188
|
-
childProcess = null;
|
|
189
|
-
});
|
|
190
|
-
childProcess.on('error', function (error) {
|
|
191
|
-
spinner.fail("Failed to start: ".concat(error.message));
|
|
192
174
|
childProcess = null;
|
|
193
175
|
});
|
|
176
|
+
childProcess.on('error', function (error) { spinner.fail("Failed to start: ".concat(error.message)); childProcess = null; });
|
|
194
177
|
}
|
|
195
178
|
function dev(options) {
|
|
196
179
|
return __awaiter(this, void 0, void 0, function () {
|
|
197
|
-
var config, port,
|
|
180
|
+
var config, port, portNumber, runtime, mainFile, resolvedMain, envVars, proxySetup, watchPaths, dainDir, outFile, MFconfig_1, error_1;
|
|
198
181
|
return __generator(this, function (_a) {
|
|
199
182
|
switch (_a.label) {
|
|
200
183
|
case 0:
|
|
201
184
|
config = (0, utils_1.getDainConfig)(options.config);
|
|
202
|
-
|
|
203
|
-
port = process.env.PORT;
|
|
204
|
-
portSource = '.env file';
|
|
205
|
-
}
|
|
206
|
-
else if (options.port) {
|
|
207
|
-
port = options.port;
|
|
208
|
-
portSource = 'command line argument';
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
port = '2022';
|
|
212
|
-
portSource = 'default value';
|
|
213
|
-
}
|
|
185
|
+
port = process.env.PORT || options.port || '2022';
|
|
214
186
|
portNumber = parseInt(port, 10);
|
|
215
187
|
if (isNaN(portNumber) || portNumber < 1 || portNumber > 65535) {
|
|
216
188
|
(0, utils_1.logError)("Invalid port: ".concat(port, ". Must be 1-65535. Using default port 2022"));
|
|
217
189
|
port = '2022';
|
|
218
|
-
portSource = 'default value (after invalid port)';
|
|
219
190
|
}
|
|
220
|
-
(0, utils_1.logInfo)("Using port ".concat(port, " (from ").concat(portSource, ")"));
|
|
221
191
|
runtime = options.runtime || config.runtime || 'node';
|
|
222
192
|
mainFile = config['main-file'];
|
|
223
193
|
resolvedMain = path_1.default.resolve(process.cwd(), mainFile);
|
|
@@ -232,32 +202,23 @@ function dev(options) {
|
|
|
232
202
|
DAIN_ENVIRONMENT: config['environment'],
|
|
233
203
|
DAIN_OUT_DIR: config['out-dir'],
|
|
234
204
|
};
|
|
235
|
-
// Register signal handlers once
|
|
236
205
|
process.once('SIGINT', function () { return gracefulShutdown(0); });
|
|
237
206
|
process.once('SIGTERM', function () { return gracefulShutdown(0); });
|
|
238
|
-
process.once('uncaughtException', function (error) {
|
|
239
|
-
|
|
240
|
-
gracefulShutdown(1);
|
|
241
|
-
});
|
|
242
|
-
process.once('unhandledRejection', function (reason) {
|
|
243
|
-
(0, utils_1.logError)('Unhandled Rejection:', reason);
|
|
244
|
-
gracefulShutdown(1);
|
|
245
|
-
});
|
|
207
|
+
process.once('uncaughtException', function (error) { (0, utils_1.logError)('Uncaught Exception:', error); gracefulShutdown(1); });
|
|
208
|
+
process.once('unhandledRejection', function (reason) { (0, utils_1.logError)('Unhandled Rejection:', reason); gracefulShutdown(1); });
|
|
246
209
|
_a.label = 1;
|
|
247
210
|
case 1:
|
|
248
211
|
_a.trys.push([1, 9, , 10]);
|
|
249
|
-
|
|
250
|
-
return [4 /*yield*/, isPortAvailable(parsedPort)];
|
|
212
|
+
return [4 /*yield*/, isPortAvailable(portNumber)];
|
|
251
213
|
case 2:
|
|
252
214
|
if (!(_a.sent())) {
|
|
253
|
-
(0, utils_1.logError)("Port ".concat(
|
|
215
|
+
(0, utils_1.logError)("Port ".concat(portNumber, " is already in use. Use --port to specify a different port."));
|
|
254
216
|
process.exit(1);
|
|
255
217
|
}
|
|
256
218
|
process.env.PORT = port;
|
|
257
219
|
if (!!options.noproxy) return [3 /*break*/, 4];
|
|
258
|
-
if (!config['api-key'])
|
|
220
|
+
if (!config['api-key'])
|
|
259
221
|
throw new Error("'api-key' is required when using development proxy");
|
|
260
|
-
}
|
|
261
222
|
return [4 /*yield*/, (0, utils_1.setupProxy)(port, config['api-key'], config)];
|
|
262
223
|
case 3:
|
|
263
224
|
proxySetup = _a.sent();
|
|
@@ -269,18 +230,16 @@ function dev(options) {
|
|
|
269
230
|
startProcess(mainFile, envVars);
|
|
270
231
|
watchPaths = [
|
|
271
232
|
path_1.default.dirname(mainFile),
|
|
272
|
-
config['static-dir']
|
|
273
|
-
? path_1.default.join(process.cwd(), config['static-dir'])
|
|
274
|
-
: (0, utils_1.getStaticFilesPath)(),
|
|
233
|
+
config['static-dir'] ? path_1.default.join(process.cwd(), config['static-dir']) : (0, utils_1.getStaticFilesPath)(),
|
|
275
234
|
].filter(function (p) { return fs_extra_1.default.existsSync(p); });
|
|
276
|
-
watcher = chokidar_1.default.watch(watchPaths, {
|
|
277
|
-
ignored: /(^|[\/\\])\../,
|
|
278
|
-
persistent: true,
|
|
279
|
-
ignoreInitial: true,
|
|
280
|
-
});
|
|
235
|
+
watcher = chokidar_1.default.watch(watchPaths, { ignored: /(^|[\/\\])\./, persistent: true, ignoreInitial: true });
|
|
281
236
|
watcher.on('change', function (changedPath) {
|
|
282
|
-
|
|
283
|
-
|
|
237
|
+
if (debounceTimer)
|
|
238
|
+
clearTimeout(debounceTimer);
|
|
239
|
+
debounceTimer = setTimeout(function () {
|
|
240
|
+
(0, utils_1.logInfo)("File ".concat(changedPath, " changed. Restarting..."));
|
|
241
|
+
startProcess(mainFile, envVars, true);
|
|
242
|
+
}, 300);
|
|
284
243
|
});
|
|
285
244
|
(0, utils_1.logInfo)('Watching for file changes...');
|
|
286
245
|
return [3 /*break*/, 8];
|
|
@@ -291,25 +250,16 @@ function dev(options) {
|
|
|
291
250
|
return [4 /*yield*/, (0, build_1.default)({ config: options.config, runtime: 'workers', watch: true })];
|
|
292
251
|
case 6:
|
|
293
252
|
_a.sent();
|
|
294
|
-
MFconfig_1 = {
|
|
295
|
-
scriptPath: outFile,
|
|
296
|
-
modules: true,
|
|
297
|
-
port: parseInt(port, 10),
|
|
298
|
-
log: new miniflare_1.Log(miniflare_1.LogLevel.DEBUG),
|
|
299
|
-
liveReload: true,
|
|
300
|
-
};
|
|
253
|
+
MFconfig_1 = { scriptPath: outFile, modules: true, port: parseInt(port, 10), log: new miniflare_1.Log(miniflare_1.LogLevel.DEBUG), liveReload: true };
|
|
301
254
|
mf = new miniflare_1.Miniflare(MFconfig_1);
|
|
302
255
|
(0, utils_1.logSuccess)("Miniflare server started on port ".concat(port));
|
|
303
|
-
debounceTimer_1 = null;
|
|
304
256
|
fs_extra_1.default.watch(dainDir, { recursive: true }, function (_eventType, filename) {
|
|
305
|
-
if (
|
|
306
|
-
clearTimeout(
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
}, 300);
|
|
257
|
+
if (debounceTimer)
|
|
258
|
+
clearTimeout(debounceTimer);
|
|
259
|
+
debounceTimer = setTimeout(function () { if (mf) {
|
|
260
|
+
mf.setOptions(MFconfig_1);
|
|
261
|
+
(0, utils_1.logInfo)("Build updated (".concat(filename, ")"));
|
|
262
|
+
} }, 300);
|
|
313
263
|
});
|
|
314
264
|
(0, utils_1.logInfo)('Watching for file changes in source and build directories...');
|
|
315
265
|
return [3 /*break*/, 8];
|
package/dist/commands/init.js
CHANGED
|
@@ -13,25 +13,19 @@ function init(projectName) {
|
|
|
13
13
|
var projectDir = path_1.default.join(process.cwd(), projectName);
|
|
14
14
|
var templateDir = path_1.default.join(__dirname, '..', '..', 'templates', 'default');
|
|
15
15
|
try {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var versionNum = Number(nodeVersion.slice(1).split('.')[0]);
|
|
19
|
-
if (versionNum < 20) {
|
|
16
|
+
var nodeVersion = Number(process.version.slice(1).split('.')[0]);
|
|
17
|
+
if (nodeVersion < 20) {
|
|
20
18
|
spinner.fail('Node.js version 20.7 or higher is required');
|
|
21
19
|
(0, utils_1.logError)('Please upgrade Node.js to version 20.7 or higher');
|
|
22
20
|
(0, utils_1.logInfo)('You can download it from: https://nodejs.org/');
|
|
23
21
|
process.exit(1);
|
|
24
22
|
}
|
|
25
|
-
// Check if directory already exists
|
|
26
23
|
if (fs_extra_1.default.existsSync(projectDir)) {
|
|
27
24
|
spinner.fail("Directory ".concat(projectName, " already exists"));
|
|
28
25
|
process.exit(1);
|
|
29
26
|
}
|
|
30
|
-
// Create project directory
|
|
31
27
|
fs_extra_1.default.ensureDirSync(projectDir);
|
|
32
|
-
// Copy template files
|
|
33
28
|
fs_extra_1.default.copySync(templateDir, projectDir);
|
|
34
|
-
// Modify package.json
|
|
35
29
|
var packageJsonPath = path_1.default.join(projectDir, 'package.json');
|
|
36
30
|
var packageJson = fs_extra_1.default.readJsonSync(packageJsonPath);
|
|
37
31
|
packageJson.name = projectName;
|
|
@@ -42,7 +36,6 @@ function init(projectName) {
|
|
|
42
36
|
(0, utils_1.logInfo)(" cd ".concat(projectName));
|
|
43
37
|
(0, utils_1.logInfo)(' npm install');
|
|
44
38
|
(0, utils_1.logInfo)(' npm run dev');
|
|
45
|
-
// Explicitly exit with success
|
|
46
39
|
process.exit(0);
|
|
47
40
|
}
|
|
48
41
|
catch (error) {
|