elit 3.5.3 → 3.5.4
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/README.md +79 -4
- package/dist/chokidar.d.ts.map +1 -1
- package/dist/chokidar.js +306 -16
- package/dist/chokidar.js.map +1 -1
- package/dist/chokidar.mjs +306 -16
- package/dist/chokidar.mjs.map +1 -1
- package/dist/cli.d.mts +15 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2540 -184
- package/dist/cli.mjs +81811 -0
- package/dist/config.d.mts +96 -1
- package/dist/config.d.ts +95 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/mobile-cli.d.ts.map +1 -1
- package/dist/pm-cli.d.ts +139 -0
- package/dist/pm-cli.d.ts.map +1 -0
- package/dist/server.js +220 -197
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +221 -198
- package/dist/server.mjs.map +1 -1
- package/dist/wapk-cli.d.ts +25 -4
- package/dist/wapk-cli.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/chokidar.ts +28 -2
- package/src/cli.ts +38 -4
- package/src/config.ts +101 -0
- package/src/desktop-cli.ts +2 -2
- package/src/mobile-cli.ts +52 -39
- package/src/pm-cli.ts +2369 -0
- package/src/wapk-cli.ts +717 -51
package/dist/cli.js
CHANGED
|
@@ -936,10 +936,10 @@ var init_http = __esm({
|
|
|
936
936
|
}
|
|
937
937
|
async text() {
|
|
938
938
|
if (isNode) {
|
|
939
|
-
return new Promise((
|
|
939
|
+
return new Promise((resolve9, reject) => {
|
|
940
940
|
const chunks = [];
|
|
941
941
|
this._req.on("data", (chunk) => chunks.push(chunk));
|
|
942
|
-
this._req.on("end", () =>
|
|
942
|
+
this._req.on("end", () => resolve9(Buffer.concat(chunks).toString("utf8")));
|
|
943
943
|
this._req.on("error", reject);
|
|
944
944
|
});
|
|
945
945
|
}
|
|
@@ -1083,8 +1083,8 @@ var init_http = __esm({
|
|
|
1083
1083
|
}
|
|
1084
1084
|
return this;
|
|
1085
1085
|
}
|
|
1086
|
-
_setResolver(
|
|
1087
|
-
this._resolve =
|
|
1086
|
+
_setResolver(resolve9) {
|
|
1087
|
+
this._resolve = resolve9;
|
|
1088
1088
|
}
|
|
1089
1089
|
// Express.js-like methods
|
|
1090
1090
|
json(data, statusCode = 200) {
|
|
@@ -1290,12 +1290,12 @@ var init_http = __esm({
|
|
|
1290
1290
|
headers
|
|
1291
1291
|
});
|
|
1292
1292
|
}
|
|
1293
|
-
return new Promise((
|
|
1293
|
+
return new Promise((resolve9) => {
|
|
1294
1294
|
serverResponse.end = (chunk) => {
|
|
1295
1295
|
if (chunk !== void 0) {
|
|
1296
1296
|
body += chunk;
|
|
1297
1297
|
}
|
|
1298
|
-
|
|
1298
|
+
resolve9(new Response(body, {
|
|
1299
1299
|
status: statusCode,
|
|
1300
1300
|
statusText: statusMessage,
|
|
1301
1301
|
headers
|
|
@@ -1311,10 +1311,10 @@ var init_http = __esm({
|
|
|
1311
1311
|
port,
|
|
1312
1312
|
hostname,
|
|
1313
1313
|
handler: (req) => {
|
|
1314
|
-
return new Promise((
|
|
1314
|
+
return new Promise((resolve9) => {
|
|
1315
1315
|
const incomingMessage = new IncomingMessage(req);
|
|
1316
1316
|
const serverResponse = new ServerResponse();
|
|
1317
|
-
serverResponse._setResolver(
|
|
1317
|
+
serverResponse._setResolver(resolve9);
|
|
1318
1318
|
if (self2.requestListener) {
|
|
1319
1319
|
self2.requestListener(incomingMessage, serverResponse);
|
|
1320
1320
|
} else {
|
|
@@ -25175,11 +25175,11 @@ var require_scope = __commonJS({
|
|
|
25175
25175
|
"use strict";
|
|
25176
25176
|
var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
25177
25177
|
function adopt(value) {
|
|
25178
|
-
return value instanceof P ? value : new P(function(
|
|
25179
|
-
|
|
25178
|
+
return value instanceof P ? value : new P(function(resolve9) {
|
|
25179
|
+
resolve9(value);
|
|
25180
25180
|
});
|
|
25181
25181
|
}
|
|
25182
|
-
return new (P || (P = Promise))(function(
|
|
25182
|
+
return new (P || (P = Promise))(function(resolve9, reject) {
|
|
25183
25183
|
function fulfilled(value) {
|
|
25184
25184
|
try {
|
|
25185
25185
|
step(generator.next(value));
|
|
@@ -25195,7 +25195,7 @@ var require_scope = __commonJS({
|
|
|
25195
25195
|
}
|
|
25196
25196
|
}
|
|
25197
25197
|
function step(result2) {
|
|
25198
|
-
result2.done ?
|
|
25198
|
+
result2.done ? resolve9(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
25199
25199
|
}
|
|
25200
25200
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25201
25201
|
});
|
|
@@ -25486,11 +25486,11 @@ var require_instantiation = __commonJS({
|
|
|
25486
25486
|
};
|
|
25487
25487
|
var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
25488
25488
|
function adopt(value) {
|
|
25489
|
-
return value instanceof P ? value : new P(function(
|
|
25490
|
-
|
|
25489
|
+
return value instanceof P ? value : new P(function(resolve9) {
|
|
25490
|
+
resolve9(value);
|
|
25491
25491
|
});
|
|
25492
25492
|
}
|
|
25493
|
-
return new (P || (P = Promise))(function(
|
|
25493
|
+
return new (P || (P = Promise))(function(resolve9, reject) {
|
|
25494
25494
|
function fulfilled(value) {
|
|
25495
25495
|
try {
|
|
25496
25496
|
step(generator.next(value));
|
|
@@ -25506,7 +25506,7 @@ var require_instantiation = __commonJS({
|
|
|
25506
25506
|
}
|
|
25507
25507
|
}
|
|
25508
25508
|
function step(result2) {
|
|
25509
|
-
result2.done ?
|
|
25509
|
+
result2.done ? resolve9(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
25510
25510
|
}
|
|
25511
25511
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25512
25512
|
});
|
|
@@ -25761,11 +25761,11 @@ var require_resolver = __commonJS({
|
|
|
25761
25761
|
};
|
|
25762
25762
|
var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
25763
25763
|
function adopt(value) {
|
|
25764
|
-
return value instanceof P ? value : new P(function(
|
|
25765
|
-
|
|
25764
|
+
return value instanceof P ? value : new P(function(resolve10) {
|
|
25765
|
+
resolve10(value);
|
|
25766
25766
|
});
|
|
25767
25767
|
}
|
|
25768
|
-
return new (P || (P = Promise))(function(
|
|
25768
|
+
return new (P || (P = Promise))(function(resolve10, reject) {
|
|
25769
25769
|
function fulfilled(value) {
|
|
25770
25770
|
try {
|
|
25771
25771
|
step(generator.next(value));
|
|
@@ -25781,7 +25781,7 @@ var require_resolver = __commonJS({
|
|
|
25781
25781
|
}
|
|
25782
25782
|
}
|
|
25783
25783
|
function step(result2) {
|
|
25784
|
-
result2.done ?
|
|
25784
|
+
result2.done ? resolve10(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
25785
25785
|
}
|
|
25786
25786
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25787
25787
|
});
|
|
@@ -25856,7 +25856,7 @@ var require_resolver = __commonJS({
|
|
|
25856
25856
|
}
|
|
25857
25857
|
};
|
|
25858
25858
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
25859
|
-
exports2.resolve =
|
|
25859
|
+
exports2.resolve = resolve9;
|
|
25860
25860
|
var ERROR_MSGS = __importStar(require_error_msgs());
|
|
25861
25861
|
var literal_types_1 = require_literal_types();
|
|
25862
25862
|
var planner_1 = require_planner();
|
|
@@ -26023,7 +26023,7 @@ var require_resolver = __commonJS({
|
|
|
26023
26023
|
};
|
|
26024
26024
|
return containersIterator;
|
|
26025
26025
|
};
|
|
26026
|
-
function
|
|
26026
|
+
function resolve9(context) {
|
|
26027
26027
|
var resolveRequestFunction = _resolveRequest(context.plan.rootRequest.requestScope);
|
|
26028
26028
|
return resolveRequestFunction(context.plan.rootRequest);
|
|
26029
26029
|
}
|
|
@@ -26818,11 +26818,11 @@ var require_container = __commonJS({
|
|
|
26818
26818
|
};
|
|
26819
26819
|
var __awaiter2 = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
26820
26820
|
function adopt(value) {
|
|
26821
|
-
return value instanceof P ? value : new P(function(
|
|
26822
|
-
|
|
26821
|
+
return value instanceof P ? value : new P(function(resolve9) {
|
|
26822
|
+
resolve9(value);
|
|
26823
26823
|
});
|
|
26824
26824
|
}
|
|
26825
|
-
return new (P || (P = Promise))(function(
|
|
26825
|
+
return new (P || (P = Promise))(function(resolve9, reject) {
|
|
26826
26826
|
function fulfilled(value) {
|
|
26827
26827
|
try {
|
|
26828
26828
|
step(generator.next(value));
|
|
@@ -26838,7 +26838,7 @@ var require_container = __commonJS({
|
|
|
26838
26838
|
}
|
|
26839
26839
|
}
|
|
26840
26840
|
function step(result2) {
|
|
26841
|
-
result2.done ?
|
|
26841
|
+
result2.done ? resolve9(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
26842
26842
|
}
|
|
26843
26843
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
26844
26844
|
});
|
|
@@ -29201,7 +29201,7 @@ var require_escodegen = __commonJS({
|
|
|
29201
29201
|
function noEmptySpace() {
|
|
29202
29202
|
return space ? space : " ";
|
|
29203
29203
|
}
|
|
29204
|
-
function
|
|
29204
|
+
function join8(left, right) {
|
|
29205
29205
|
var leftSource, rightSource, leftCharCode, rightCharCode;
|
|
29206
29206
|
leftSource = toSourceNodeWhenNeeded(left).toString();
|
|
29207
29207
|
if (leftSource.length === 0) {
|
|
@@ -29536,8 +29536,8 @@ var require_escodegen = __commonJS({
|
|
|
29536
29536
|
} else {
|
|
29537
29537
|
result2.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
|
|
29538
29538
|
}
|
|
29539
|
-
result2 =
|
|
29540
|
-
result2 = [
|
|
29539
|
+
result2 = join8(result2, operator);
|
|
29540
|
+
result2 = [join8(
|
|
29541
29541
|
result2,
|
|
29542
29542
|
that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)
|
|
29543
29543
|
), ")"];
|
|
@@ -29680,11 +29680,11 @@ var require_escodegen = __commonJS({
|
|
|
29680
29680
|
var result2, fragment;
|
|
29681
29681
|
result2 = ["class"];
|
|
29682
29682
|
if (stmt.id) {
|
|
29683
|
-
result2 =
|
|
29683
|
+
result2 = join8(result2, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
|
|
29684
29684
|
}
|
|
29685
29685
|
if (stmt.superClass) {
|
|
29686
|
-
fragment =
|
|
29687
|
-
result2 =
|
|
29686
|
+
fragment = join8("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
|
|
29687
|
+
result2 = join8(result2, fragment);
|
|
29688
29688
|
}
|
|
29689
29689
|
result2.push(space);
|
|
29690
29690
|
result2.push(this.generateStatement(stmt.body, S_TFFT));
|
|
@@ -29697,9 +29697,9 @@ var require_escodegen = __commonJS({
|
|
|
29697
29697
|
return escapeDirective(stmt.directive) + this.semicolon(flags);
|
|
29698
29698
|
},
|
|
29699
29699
|
DoWhileStatement: function(stmt, flags) {
|
|
29700
|
-
var result2 =
|
|
29700
|
+
var result2 = join8("do", this.maybeBlock(stmt.body, S_TFFF));
|
|
29701
29701
|
result2 = this.maybeBlockSuffix(stmt.body, result2);
|
|
29702
|
-
return
|
|
29702
|
+
return join8(result2, [
|
|
29703
29703
|
"while" + space + "(",
|
|
29704
29704
|
this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
|
|
29705
29705
|
")" + this.semicolon(flags)
|
|
@@ -29735,11 +29735,11 @@ var require_escodegen = __commonJS({
|
|
|
29735
29735
|
ExportDefaultDeclaration: function(stmt, flags) {
|
|
29736
29736
|
var result2 = ["export"], bodyFlags;
|
|
29737
29737
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
29738
|
-
result2 =
|
|
29738
|
+
result2 = join8(result2, "default");
|
|
29739
29739
|
if (isStatement(stmt.declaration)) {
|
|
29740
|
-
result2 =
|
|
29740
|
+
result2 = join8(result2, this.generateStatement(stmt.declaration, bodyFlags));
|
|
29741
29741
|
} else {
|
|
29742
|
-
result2 =
|
|
29742
|
+
result2 = join8(result2, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
|
|
29743
29743
|
}
|
|
29744
29744
|
return result2;
|
|
29745
29745
|
},
|
|
@@ -29747,15 +29747,15 @@ var require_escodegen = __commonJS({
|
|
|
29747
29747
|
var result2 = ["export"], bodyFlags, that = this;
|
|
29748
29748
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
29749
29749
|
if (stmt.declaration) {
|
|
29750
|
-
return
|
|
29750
|
+
return join8(result2, this.generateStatement(stmt.declaration, bodyFlags));
|
|
29751
29751
|
}
|
|
29752
29752
|
if (stmt.specifiers) {
|
|
29753
29753
|
if (stmt.specifiers.length === 0) {
|
|
29754
|
-
result2 =
|
|
29754
|
+
result2 = join8(result2, "{" + space + "}");
|
|
29755
29755
|
} else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
|
|
29756
|
-
result2 =
|
|
29756
|
+
result2 = join8(result2, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
|
|
29757
29757
|
} else {
|
|
29758
|
-
result2 =
|
|
29758
|
+
result2 = join8(result2, "{");
|
|
29759
29759
|
withIndent(function(indent6) {
|
|
29760
29760
|
var i, iz;
|
|
29761
29761
|
result2.push(newline);
|
|
@@ -29773,7 +29773,7 @@ var require_escodegen = __commonJS({
|
|
|
29773
29773
|
result2.push(base + "}");
|
|
29774
29774
|
}
|
|
29775
29775
|
if (stmt.source) {
|
|
29776
|
-
result2 =
|
|
29776
|
+
result2 = join8(result2, [
|
|
29777
29777
|
"from" + space,
|
|
29778
29778
|
// ModuleSpecifier
|
|
29779
29779
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -29793,7 +29793,7 @@ var require_escodegen = __commonJS({
|
|
|
29793
29793
|
if (stmt.exported) {
|
|
29794
29794
|
result2.push("as " + stmt.exported.name + " ");
|
|
29795
29795
|
}
|
|
29796
|
-
result2 =
|
|
29796
|
+
result2 = join8(result2, [
|
|
29797
29797
|
"from" + space,
|
|
29798
29798
|
// ModuleSpecifier
|
|
29799
29799
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -29867,7 +29867,7 @@ var require_escodegen = __commonJS({
|
|
|
29867
29867
|
];
|
|
29868
29868
|
cursor = 0;
|
|
29869
29869
|
if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
|
|
29870
|
-
result2 =
|
|
29870
|
+
result2 = join8(result2, [
|
|
29871
29871
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
29872
29872
|
]);
|
|
29873
29873
|
++cursor;
|
|
@@ -29877,7 +29877,7 @@ var require_escodegen = __commonJS({
|
|
|
29877
29877
|
result2.push(",");
|
|
29878
29878
|
}
|
|
29879
29879
|
if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
|
|
29880
|
-
result2 =
|
|
29880
|
+
result2 = join8(result2, [
|
|
29881
29881
|
space,
|
|
29882
29882
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
29883
29883
|
]);
|
|
@@ -29906,7 +29906,7 @@ var require_escodegen = __commonJS({
|
|
|
29906
29906
|
}
|
|
29907
29907
|
}
|
|
29908
29908
|
}
|
|
29909
|
-
result2 =
|
|
29909
|
+
result2 = join8(result2, [
|
|
29910
29910
|
"from" + space,
|
|
29911
29911
|
// ModuleSpecifier
|
|
29912
29912
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
@@ -29966,7 +29966,7 @@ var require_escodegen = __commonJS({
|
|
|
29966
29966
|
];
|
|
29967
29967
|
},
|
|
29968
29968
|
ThrowStatement: function(stmt, flags) {
|
|
29969
|
-
return [
|
|
29969
|
+
return [join8(
|
|
29970
29970
|
"throw",
|
|
29971
29971
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
29972
29972
|
), this.semicolon(flags)];
|
|
@@ -29977,7 +29977,7 @@ var require_escodegen = __commonJS({
|
|
|
29977
29977
|
result2 = this.maybeBlockSuffix(stmt.block, result2);
|
|
29978
29978
|
if (stmt.handlers) {
|
|
29979
29979
|
for (i = 0, iz = stmt.handlers.length; i < iz; ++i) {
|
|
29980
|
-
result2 =
|
|
29980
|
+
result2 = join8(result2, this.generateStatement(stmt.handlers[i], S_TFFF));
|
|
29981
29981
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
29982
29982
|
result2 = this.maybeBlockSuffix(stmt.handlers[i].body, result2);
|
|
29983
29983
|
}
|
|
@@ -29985,7 +29985,7 @@ var require_escodegen = __commonJS({
|
|
|
29985
29985
|
} else {
|
|
29986
29986
|
guardedHandlers = stmt.guardedHandlers || [];
|
|
29987
29987
|
for (i = 0, iz = guardedHandlers.length; i < iz; ++i) {
|
|
29988
|
-
result2 =
|
|
29988
|
+
result2 = join8(result2, this.generateStatement(guardedHandlers[i], S_TFFF));
|
|
29989
29989
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
29990
29990
|
result2 = this.maybeBlockSuffix(guardedHandlers[i].body, result2);
|
|
29991
29991
|
}
|
|
@@ -29993,13 +29993,13 @@ var require_escodegen = __commonJS({
|
|
|
29993
29993
|
if (stmt.handler) {
|
|
29994
29994
|
if (Array.isArray(stmt.handler)) {
|
|
29995
29995
|
for (i = 0, iz = stmt.handler.length; i < iz; ++i) {
|
|
29996
|
-
result2 =
|
|
29996
|
+
result2 = join8(result2, this.generateStatement(stmt.handler[i], S_TFFF));
|
|
29997
29997
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
29998
29998
|
result2 = this.maybeBlockSuffix(stmt.handler[i].body, result2);
|
|
29999
29999
|
}
|
|
30000
30000
|
}
|
|
30001
30001
|
} else {
|
|
30002
|
-
result2 =
|
|
30002
|
+
result2 = join8(result2, this.generateStatement(stmt.handler, S_TFFF));
|
|
30003
30003
|
if (stmt.finalizer) {
|
|
30004
30004
|
result2 = this.maybeBlockSuffix(stmt.handler.body, result2);
|
|
30005
30005
|
}
|
|
@@ -30007,7 +30007,7 @@ var require_escodegen = __commonJS({
|
|
|
30007
30007
|
}
|
|
30008
30008
|
}
|
|
30009
30009
|
if (stmt.finalizer) {
|
|
30010
|
-
result2 =
|
|
30010
|
+
result2 = join8(result2, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
|
|
30011
30011
|
}
|
|
30012
30012
|
return result2;
|
|
30013
30013
|
},
|
|
@@ -30041,7 +30041,7 @@ var require_escodegen = __commonJS({
|
|
|
30041
30041
|
withIndent(function() {
|
|
30042
30042
|
if (stmt.test) {
|
|
30043
30043
|
result2 = [
|
|
30044
|
-
|
|
30044
|
+
join8("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
|
|
30045
30045
|
":"
|
|
30046
30046
|
];
|
|
30047
30047
|
} else {
|
|
@@ -30089,9 +30089,9 @@ var require_escodegen = __commonJS({
|
|
|
30089
30089
|
result2.push(this.maybeBlock(stmt.consequent, S_TFFF));
|
|
30090
30090
|
result2 = this.maybeBlockSuffix(stmt.consequent, result2);
|
|
30091
30091
|
if (stmt.alternate.type === Syntax.IfStatement) {
|
|
30092
|
-
result2 =
|
|
30092
|
+
result2 = join8(result2, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
|
|
30093
30093
|
} else {
|
|
30094
|
-
result2 =
|
|
30094
|
+
result2 = join8(result2, join8("else", this.maybeBlock(stmt.alternate, bodyFlags)));
|
|
30095
30095
|
}
|
|
30096
30096
|
} else {
|
|
30097
30097
|
result2.push(this.maybeBlock(stmt.consequent, bodyFlags));
|
|
@@ -30192,7 +30192,7 @@ var require_escodegen = __commonJS({
|
|
|
30192
30192
|
},
|
|
30193
30193
|
ReturnStatement: function(stmt, flags) {
|
|
30194
30194
|
if (stmt.argument) {
|
|
30195
|
-
return [
|
|
30195
|
+
return [join8(
|
|
30196
30196
|
"return",
|
|
30197
30197
|
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
|
|
30198
30198
|
), this.semicolon(flags)];
|
|
@@ -30297,14 +30297,14 @@ var require_escodegen = __commonJS({
|
|
|
30297
30297
|
if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
|
|
30298
30298
|
result2 = [fragment, noEmptySpace(), expr.operator];
|
|
30299
30299
|
} else {
|
|
30300
|
-
result2 =
|
|
30300
|
+
result2 = join8(fragment, expr.operator);
|
|
30301
30301
|
}
|
|
30302
30302
|
fragment = this.generateExpression(expr.right, rightPrecedence, flags);
|
|
30303
30303
|
if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
|
|
30304
30304
|
result2.push(noEmptySpace());
|
|
30305
30305
|
result2.push(fragment);
|
|
30306
30306
|
} else {
|
|
30307
|
-
result2 =
|
|
30307
|
+
result2 = join8(result2, fragment);
|
|
30308
30308
|
}
|
|
30309
30309
|
if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
|
|
30310
30310
|
return ["(", result2, ")"];
|
|
@@ -30343,7 +30343,7 @@ var require_escodegen = __commonJS({
|
|
|
30343
30343
|
var result2, length2, i, iz, itemFlags;
|
|
30344
30344
|
length2 = expr["arguments"].length;
|
|
30345
30345
|
itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length2 === 0 ? E_TFT : E_TFF;
|
|
30346
|
-
result2 =
|
|
30346
|
+
result2 = join8(
|
|
30347
30347
|
"new",
|
|
30348
30348
|
this.generateExpression(expr.callee, Precedence.New, itemFlags)
|
|
30349
30349
|
);
|
|
@@ -30393,11 +30393,11 @@ var require_escodegen = __commonJS({
|
|
|
30393
30393
|
var result2, fragment, rightCharCode, leftSource, leftCharCode;
|
|
30394
30394
|
fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
|
|
30395
30395
|
if (space === "") {
|
|
30396
|
-
result2 =
|
|
30396
|
+
result2 = join8(expr.operator, fragment);
|
|
30397
30397
|
} else {
|
|
30398
30398
|
result2 = [expr.operator];
|
|
30399
30399
|
if (expr.operator.length > 2) {
|
|
30400
|
-
result2 =
|
|
30400
|
+
result2 = join8(result2, fragment);
|
|
30401
30401
|
} else {
|
|
30402
30402
|
leftSource = toSourceNodeWhenNeeded(result2).toString();
|
|
30403
30403
|
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
|
|
@@ -30420,7 +30420,7 @@ var require_escodegen = __commonJS({
|
|
|
30420
30420
|
result2 = "yield";
|
|
30421
30421
|
}
|
|
30422
30422
|
if (expr.argument) {
|
|
30423
|
-
result2 =
|
|
30423
|
+
result2 = join8(
|
|
30424
30424
|
result2,
|
|
30425
30425
|
this.generateExpression(expr.argument, Precedence.Yield, E_TTT)
|
|
30426
30426
|
);
|
|
@@ -30428,7 +30428,7 @@ var require_escodegen = __commonJS({
|
|
|
30428
30428
|
return parenthesize(result2, Precedence.Yield, precedence);
|
|
30429
30429
|
},
|
|
30430
30430
|
AwaitExpression: function(expr, precedence, flags) {
|
|
30431
|
-
var result2 =
|
|
30431
|
+
var result2 = join8(
|
|
30432
30432
|
expr.all ? "await*" : "await",
|
|
30433
30433
|
this.generateExpression(expr.argument, Precedence.Await, E_TTT)
|
|
30434
30434
|
);
|
|
@@ -30511,11 +30511,11 @@ var require_escodegen = __commonJS({
|
|
|
30511
30511
|
var result2, fragment;
|
|
30512
30512
|
result2 = ["class"];
|
|
30513
30513
|
if (expr.id) {
|
|
30514
|
-
result2 =
|
|
30514
|
+
result2 = join8(result2, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
|
|
30515
30515
|
}
|
|
30516
30516
|
if (expr.superClass) {
|
|
30517
|
-
fragment =
|
|
30518
|
-
result2 =
|
|
30517
|
+
fragment = join8("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
|
|
30518
|
+
result2 = join8(result2, fragment);
|
|
30519
30519
|
}
|
|
30520
30520
|
result2.push(space);
|
|
30521
30521
|
result2.push(this.generateStatement(expr.body, S_TFFT));
|
|
@@ -30530,7 +30530,7 @@ var require_escodegen = __commonJS({
|
|
|
30530
30530
|
}
|
|
30531
30531
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
30532
30532
|
fragment = [
|
|
30533
|
-
|
|
30533
|
+
join8(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
|
|
30534
30534
|
this.generateFunctionBody(expr.value)
|
|
30535
30535
|
];
|
|
30536
30536
|
} else {
|
|
@@ -30540,7 +30540,7 @@ var require_escodegen = __commonJS({
|
|
|
30540
30540
|
this.generateFunctionBody(expr.value)
|
|
30541
30541
|
];
|
|
30542
30542
|
}
|
|
30543
|
-
return
|
|
30543
|
+
return join8(result2, fragment);
|
|
30544
30544
|
},
|
|
30545
30545
|
PrivateIdentifier: function(expr, precedence, flags) {
|
|
30546
30546
|
return generateIdentifier(expr);
|
|
@@ -30753,7 +30753,7 @@ var require_escodegen = __commonJS({
|
|
|
30753
30753
|
for (i = 0, iz = expr.blocks.length; i < iz; ++i) {
|
|
30754
30754
|
fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
|
|
30755
30755
|
if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
30756
|
-
result2 =
|
|
30756
|
+
result2 = join8(result2, fragment);
|
|
30757
30757
|
} else {
|
|
30758
30758
|
result2.push(fragment);
|
|
30759
30759
|
}
|
|
@@ -30761,13 +30761,13 @@ var require_escodegen = __commonJS({
|
|
|
30761
30761
|
});
|
|
30762
30762
|
}
|
|
30763
30763
|
if (expr.filter) {
|
|
30764
|
-
result2 =
|
|
30764
|
+
result2 = join8(result2, "if" + space);
|
|
30765
30765
|
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
|
|
30766
|
-
result2 =
|
|
30766
|
+
result2 = join8(result2, ["(", fragment, ")"]);
|
|
30767
30767
|
}
|
|
30768
30768
|
if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
30769
30769
|
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
|
|
30770
|
-
result2 =
|
|
30770
|
+
result2 = join8(result2, fragment);
|
|
30771
30771
|
}
|
|
30772
30772
|
result2.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
|
|
30773
30773
|
return result2;
|
|
@@ -30783,8 +30783,8 @@ var require_escodegen = __commonJS({
|
|
|
30783
30783
|
} else {
|
|
30784
30784
|
fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
|
|
30785
30785
|
}
|
|
30786
|
-
fragment =
|
|
30787
|
-
fragment =
|
|
30786
|
+
fragment = join8(fragment, expr.of ? "of" : "in");
|
|
30787
|
+
fragment = join8(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
|
|
30788
30788
|
return ["for" + space + "(", fragment, ")"];
|
|
30789
30789
|
},
|
|
30790
30790
|
SpreadElement: function(expr, precedence, flags) {
|
|
@@ -33294,11 +33294,11 @@ var init_Validator = __esm({
|
|
|
33294
33294
|
init_ValidationExecutor();
|
|
33295
33295
|
__awaiter = function(thisArg, _arguments, P, generator) {
|
|
33296
33296
|
function adopt(value) {
|
|
33297
|
-
return value instanceof P ? value : new P(function(
|
|
33298
|
-
|
|
33297
|
+
return value instanceof P ? value : new P(function(resolve9) {
|
|
33298
|
+
resolve9(value);
|
|
33299
33299
|
});
|
|
33300
33300
|
}
|
|
33301
|
-
return new (P || (P = Promise))(function(
|
|
33301
|
+
return new (P || (P = Promise))(function(resolve9, reject) {
|
|
33302
33302
|
function fulfilled(value) {
|
|
33303
33303
|
try {
|
|
33304
33304
|
step(generator.next(value));
|
|
@@ -33314,7 +33314,7 @@ var init_Validator = __esm({
|
|
|
33314
33314
|
}
|
|
33315
33315
|
}
|
|
33316
33316
|
function step(result2) {
|
|
33317
|
-
result2.done ?
|
|
33317
|
+
result2.done ? resolve9(result2.value) : adopt(result2.value).then(fulfilled, rejected);
|
|
33318
33318
|
}
|
|
33319
33319
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
33320
33320
|
});
|
|
@@ -57437,13 +57437,13 @@ function readdirp(root, options = {}) {
|
|
|
57437
57437
|
options.root = root;
|
|
57438
57438
|
return new ReaddirpStream(options);
|
|
57439
57439
|
}
|
|
57440
|
-
var import_promises, import_node_stream,
|
|
57440
|
+
var import_promises, import_node_stream, import_node_path6, EntryTypes, defaultOptions3, RECURSIVE_ERROR_CODE, NORMAL_FLOW_ERRORS, ALL_TYPES, DIR_TYPES, FILE_TYPES, isNormalFlowError, wantBigintFsStats, emptyFn, normalizeFilter, ReaddirpStream;
|
|
57441
57441
|
var init_esm = __esm({
|
|
57442
57442
|
"node_modules/readdirp/esm/index.js"() {
|
|
57443
57443
|
"use strict";
|
|
57444
57444
|
import_promises = require("fs/promises");
|
|
57445
57445
|
import_node_stream = require("stream");
|
|
57446
|
-
|
|
57446
|
+
import_node_path6 = require("path");
|
|
57447
57447
|
EntryTypes = {
|
|
57448
57448
|
FILE_TYPE: "files",
|
|
57449
57449
|
DIR_TYPE: "directories",
|
|
@@ -57518,7 +57518,7 @@ var init_esm = __esm({
|
|
|
57518
57518
|
this._wantsDir = type ? DIR_TYPES.has(type) : false;
|
|
57519
57519
|
this._wantsFile = type ? FILE_TYPES.has(type) : false;
|
|
57520
57520
|
this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
|
|
57521
|
-
this._root = (0,
|
|
57521
|
+
this._root = (0, import_node_path6.resolve)(root);
|
|
57522
57522
|
this._isDirent = !opts.alwaysStat;
|
|
57523
57523
|
this._statsProp = this._isDirent ? "dirent" : "stats";
|
|
57524
57524
|
this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
|
|
@@ -57587,10 +57587,10 @@ var init_esm = __esm({
|
|
|
57587
57587
|
}
|
|
57588
57588
|
async _formatEntry(dirent, path) {
|
|
57589
57589
|
let entry;
|
|
57590
|
-
const
|
|
57590
|
+
const basename8 = this._isDirent ? dirent.name : dirent;
|
|
57591
57591
|
try {
|
|
57592
|
-
const fullPath = (0,
|
|
57593
|
-
entry = { path: (0,
|
|
57592
|
+
const fullPath = (0, import_node_path6.resolve)((0, import_node_path6.join)(path, basename8));
|
|
57593
|
+
entry = { path: (0, import_node_path6.relative)(this._root, fullPath), fullPath, basename: basename8 };
|
|
57594
57594
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
57595
57595
|
} catch (err) {
|
|
57596
57596
|
this._onError(err);
|
|
@@ -57624,7 +57624,7 @@ var init_esm = __esm({
|
|
|
57624
57624
|
}
|
|
57625
57625
|
if (entryRealPathStats.isDirectory()) {
|
|
57626
57626
|
const len = entryRealPath.length;
|
|
57627
|
-
if (full.startsWith(entryRealPath) && full.substr(len, 1) ===
|
|
57627
|
+
if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path6.sep) {
|
|
57628
57628
|
const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
|
|
57629
57629
|
recursiveError.code = RECURSIVE_ERROR_CODE;
|
|
57630
57630
|
return this._onError(recursiveError);
|
|
@@ -57655,7 +57655,7 @@ function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
|
|
|
57655
57655
|
}
|
|
57656
57656
|
};
|
|
57657
57657
|
try {
|
|
57658
|
-
return (0,
|
|
57658
|
+
return (0, import_fs7.watch)(path, {
|
|
57659
57659
|
persistent: options.persistent
|
|
57660
57660
|
}, handleEvent);
|
|
57661
57661
|
} catch (error) {
|
|
@@ -57663,11 +57663,11 @@ function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
|
|
|
57663
57663
|
return void 0;
|
|
57664
57664
|
}
|
|
57665
57665
|
}
|
|
57666
|
-
var
|
|
57666
|
+
var import_fs7, import_promises2, sysPath, import_os, STR_DATA, STR_END, STR_CLOSE, EMPTY_FN, pl, isWindows2, isMacos, isLinux, isFreeBSD, isIBMi, EVENTS, EV, THROTTLE_MODE_WATCH, statMethods, KEY_LISTENERS, KEY_ERR, KEY_RAW, HANDLER_KEYS, binaryExtensions, isBinaryPath, foreach, addAndConvert, clearItem, delFromSet, isEmptySet, FsWatchInstances, fsWatchBroadcast, setFsWatchListener, FsWatchFileInstances, setFsWatchFileListener, NodeFsHandler;
|
|
57667
57667
|
var init_handler = __esm({
|
|
57668
57668
|
"node_modules/chokidar/esm/handler.js"() {
|
|
57669
57669
|
"use strict";
|
|
57670
|
-
|
|
57670
|
+
import_fs7 = require("fs");
|
|
57671
57671
|
import_promises2 = require("fs/promises");
|
|
57672
57672
|
sysPath = __toESM(require("path"), 1);
|
|
57673
57673
|
import_os = require("os");
|
|
@@ -58071,7 +58071,7 @@ var init_handler = __esm({
|
|
|
58071
58071
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
58072
58072
|
const copts = cont && cont.options;
|
|
58073
58073
|
if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
|
|
58074
|
-
(0,
|
|
58074
|
+
(0, import_fs7.unwatchFile)(fullPath);
|
|
58075
58075
|
cont = void 0;
|
|
58076
58076
|
}
|
|
58077
58077
|
if (cont) {
|
|
@@ -58082,7 +58082,7 @@ var init_handler = __esm({
|
|
|
58082
58082
|
listeners: listener,
|
|
58083
58083
|
rawEmitters: rawEmitter,
|
|
58084
58084
|
options,
|
|
58085
|
-
watcher: (0,
|
|
58085
|
+
watcher: (0, import_fs7.watchFile)(fullPath, options, (curr, prev) => {
|
|
58086
58086
|
foreach(cont.rawEmitters, (rawEmitter2) => {
|
|
58087
58087
|
rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
|
|
58088
58088
|
});
|
|
@@ -58099,7 +58099,7 @@ var init_handler = __esm({
|
|
|
58099
58099
|
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
58100
58100
|
if (isEmptySet(cont.listeners)) {
|
|
58101
58101
|
FsWatchFileInstances.delete(fullPath);
|
|
58102
|
-
(0,
|
|
58102
|
+
(0, import_fs7.unwatchFile)(fullPath);
|
|
58103
58103
|
cont.options = cont.watcher = void 0;
|
|
58104
58104
|
Object.freeze(cont);
|
|
58105
58105
|
}
|
|
@@ -58119,9 +58119,9 @@ var init_handler = __esm({
|
|
|
58119
58119
|
_watchWithNodeFs(path, listener) {
|
|
58120
58120
|
const opts = this.fsw.options;
|
|
58121
58121
|
const directory = sysPath.dirname(path);
|
|
58122
|
-
const
|
|
58122
|
+
const basename8 = sysPath.basename(path);
|
|
58123
58123
|
const parent = this.fsw._getWatchedDir(directory);
|
|
58124
|
-
parent.add(
|
|
58124
|
+
parent.add(basename8);
|
|
58125
58125
|
const absolutePath = sysPath.resolve(path);
|
|
58126
58126
|
const options = {
|
|
58127
58127
|
persistent: opts.persistent
|
|
@@ -58131,7 +58131,7 @@ var init_handler = __esm({
|
|
|
58131
58131
|
let closer;
|
|
58132
58132
|
if (opts.usePolling) {
|
|
58133
58133
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
58134
|
-
options.interval = enableBin && isBinaryPath(
|
|
58134
|
+
options.interval = enableBin && isBinaryPath(basename8) ? opts.binaryInterval : opts.interval;
|
|
58135
58135
|
closer = setFsWatchFileListener(path, absolutePath, options, {
|
|
58136
58136
|
listener,
|
|
58137
58137
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -58153,11 +58153,11 @@ var init_handler = __esm({
|
|
|
58153
58153
|
if (this.fsw.closed) {
|
|
58154
58154
|
return;
|
|
58155
58155
|
}
|
|
58156
|
-
const
|
|
58157
|
-
const
|
|
58158
|
-
const parent = this.fsw._getWatchedDir(
|
|
58156
|
+
const dirname9 = sysPath.dirname(file);
|
|
58157
|
+
const basename8 = sysPath.basename(file);
|
|
58158
|
+
const parent = this.fsw._getWatchedDir(dirname9);
|
|
58159
58159
|
let prevStats = stats;
|
|
58160
|
-
if (parent.has(
|
|
58160
|
+
if (parent.has(basename8))
|
|
58161
58161
|
return;
|
|
58162
58162
|
const listener = async (path, newStats) => {
|
|
58163
58163
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
@@ -58182,9 +58182,9 @@ var init_handler = __esm({
|
|
|
58182
58182
|
prevStats = newStats2;
|
|
58183
58183
|
}
|
|
58184
58184
|
} catch (error) {
|
|
58185
|
-
this.fsw._remove(
|
|
58185
|
+
this.fsw._remove(dirname9, basename8);
|
|
58186
58186
|
}
|
|
58187
|
-
} else if (parent.has(
|
|
58187
|
+
} else if (parent.has(basename8)) {
|
|
58188
58188
|
const at = newStats.atimeMs;
|
|
58189
58189
|
const mt = newStats.mtimeMs;
|
|
58190
58190
|
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
@@ -58278,7 +58278,7 @@ var init_handler = __esm({
|
|
|
58278
58278
|
this._addToNodeFs(path, initialAdd, wh, depth + 1);
|
|
58279
58279
|
}
|
|
58280
58280
|
}).on(EV.ERROR, this._boundHandleError);
|
|
58281
|
-
return new Promise((
|
|
58281
|
+
return new Promise((resolve9, reject) => {
|
|
58282
58282
|
if (!stream)
|
|
58283
58283
|
return reject();
|
|
58284
58284
|
stream.once(STR_END, () => {
|
|
@@ -58287,7 +58287,7 @@ var init_handler = __esm({
|
|
|
58287
58287
|
return;
|
|
58288
58288
|
}
|
|
58289
58289
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
58290
|
-
|
|
58290
|
+
resolve9(void 0);
|
|
58291
58291
|
previous.getChildren().filter((item) => {
|
|
58292
58292
|
return item !== directory && !current.has(item);
|
|
58293
58293
|
}).forEach((item) => {
|
|
@@ -58484,11 +58484,11 @@ function watch3(paths, options = {}) {
|
|
|
58484
58484
|
watcher.add(paths);
|
|
58485
58485
|
return watcher;
|
|
58486
58486
|
}
|
|
58487
|
-
var
|
|
58487
|
+
var import_fs8, import_promises3, import_events4, sysPath2, SLASH, SLASH_SLASH, ONE_DOT, TWO_DOTS, STRING_TYPE, BACK_SLASH_RE, DOUBLE_SLASH_RE, DOT_RE, REPLACER_RE, isMatcherObject, unifyPaths, toUnix, normalizePathToUnix, normalizeIgnored, getAbsolutePath, EMPTY_SET, DirEntry, STAT_METHOD_F, STAT_METHOD_L, WatchHelper, FSWatcher2, esm_default;
|
|
58488
58488
|
var init_esm2 = __esm({
|
|
58489
58489
|
"node_modules/chokidar/esm/index.js"() {
|
|
58490
58490
|
"use strict";
|
|
58491
|
-
|
|
58491
|
+
import_fs8 = require("fs");
|
|
58492
58492
|
import_promises3 = require("fs/promises");
|
|
58493
58493
|
import_events4 = require("events");
|
|
58494
58494
|
sysPath2 = __toESM(require("path"), 1);
|
|
@@ -58966,7 +58966,7 @@ var init_esm2 = __esm({
|
|
|
58966
58966
|
const now = /* @__PURE__ */ new Date();
|
|
58967
58967
|
const writes = this._pendingWrites;
|
|
58968
58968
|
function awaitWriteFinishFn(prevStat) {
|
|
58969
|
-
(0,
|
|
58969
|
+
(0, import_fs8.stat)(fullPath, (err, curStat) => {
|
|
58970
58970
|
if (err || !writes.has(path)) {
|
|
58971
58971
|
if (err && err.code !== "ENOENT")
|
|
58972
58972
|
awfEmit(err);
|
|
@@ -59400,7 +59400,7 @@ var require_package3 = __commonJS({
|
|
|
59400
59400
|
"package.json"(exports2, module2) {
|
|
59401
59401
|
module2.exports = {
|
|
59402
59402
|
name: "elit",
|
|
59403
|
-
version: "3.5.
|
|
59403
|
+
version: "3.5.4",
|
|
59404
59404
|
description: "Optimized lightweight library for creating DOM elements with reactive state",
|
|
59405
59405
|
main: "dist/index.js",
|
|
59406
59406
|
module: "dist/index.mjs",
|
|
@@ -59558,6 +59558,7 @@ var require_package3 = __commonJS({
|
|
|
59558
59558
|
"test:run": "elit test --run",
|
|
59559
59559
|
"test:coverage": "elit test --coverage",
|
|
59560
59560
|
"test:e2e": "elit test --e2e",
|
|
59561
|
+
"test:wapk:google-drive": "elit test --run --file ./testing/unit/wapk.google-drive.integration.test.ts",
|
|
59561
59562
|
benchmark: "node benchmark/server-benchmark.js",
|
|
59562
59563
|
"benchmark:router": "node benchmark/router-benchmark.js",
|
|
59563
59564
|
"docs:dev": "npm run --prefix docs dev",
|
|
@@ -59639,6 +59640,7 @@ __export(cli_exports, {
|
|
|
59639
59640
|
runDev: () => runDev,
|
|
59640
59641
|
runMobile: () => runMobile,
|
|
59641
59642
|
runNative: () => runNative,
|
|
59643
|
+
runPm: () => runPm,
|
|
59642
59644
|
runPreview: () => runPreview,
|
|
59643
59645
|
runTest: () => runTest,
|
|
59644
59646
|
runWapk: () => runWapk
|
|
@@ -59731,9 +59733,9 @@ async function loadConfigFile(configPath) {
|
|
|
59731
59733
|
} else if (ext === "ts" || ext === "mts") {
|
|
59732
59734
|
try {
|
|
59733
59735
|
const { build: build2 } = await import("esbuild");
|
|
59734
|
-
const { join:
|
|
59735
|
-
const configDir =
|
|
59736
|
-
const tempFile =
|
|
59736
|
+
const { join: join8, dirname: dirname9 } = await Promise.resolve().then(() => (init_path(), path_exports));
|
|
59737
|
+
const configDir = dirname9(configPath);
|
|
59738
|
+
const tempFile = join8(configDir, `.elit-config-${Date.now()}.mjs`);
|
|
59737
59739
|
const externalAllPlugin = {
|
|
59738
59740
|
name: "external-all",
|
|
59739
59741
|
setup(build3) {
|
|
@@ -60297,6 +60299,8 @@ var WebSocketServer = class extends import_events2.EventEmitter {
|
|
|
60297
60299
|
|
|
60298
60300
|
// src/chokidar.ts
|
|
60299
60301
|
var import_events3 = require("events");
|
|
60302
|
+
init_fs();
|
|
60303
|
+
init_path();
|
|
60300
60304
|
init_runtime();
|
|
60301
60305
|
function normalizePath2(path) {
|
|
60302
60306
|
return path.replace(/\\/g, "/");
|
|
@@ -60418,18 +60422,35 @@ var FSWatcher = class extends import_events3.EventEmitter {
|
|
|
60418
60422
|
}
|
|
60419
60423
|
};
|
|
60420
60424
|
function getBaseDirectory(pattern) {
|
|
60421
|
-
const
|
|
60425
|
+
const normalizedPattern = normalizePath2(pattern);
|
|
60426
|
+
const parts = normalizedPattern.split(/[\\\/]/);
|
|
60422
60427
|
let baseDir = "";
|
|
60428
|
+
let sawGlob = false;
|
|
60423
60429
|
for (const part of parts) {
|
|
60424
60430
|
if (part.includes("*") || part.includes("?")) {
|
|
60431
|
+
sawGlob = true;
|
|
60425
60432
|
break;
|
|
60426
60433
|
}
|
|
60427
60434
|
baseDir = baseDir ? `${baseDir}/${part}` : part;
|
|
60428
60435
|
}
|
|
60429
|
-
|
|
60436
|
+
if (sawGlob) {
|
|
60437
|
+
return baseDir || ".";
|
|
60438
|
+
}
|
|
60439
|
+
if (normalizedPattern && existsSync(normalizedPattern)) {
|
|
60440
|
+
try {
|
|
60441
|
+
return statSync(normalizedPattern).isDirectory() ? normalizedPattern : normalizePath2(dirname(normalizedPattern)) || ".";
|
|
60442
|
+
} catch {
|
|
60443
|
+
return normalizePath2(dirname(normalizedPattern)) || ".";
|
|
60444
|
+
}
|
|
60445
|
+
}
|
|
60446
|
+
const lastSegment = parts[parts.length - 1] || "";
|
|
60447
|
+
if (lastSegment.includes(".") && !lastSegment.startsWith(".")) {
|
|
60448
|
+
return normalizePath2(dirname(normalizedPattern)) || ".";
|
|
60449
|
+
}
|
|
60450
|
+
return normalizedPattern || ".";
|
|
60430
60451
|
}
|
|
60431
60452
|
function matchesPattern(filePath, pattern) {
|
|
60432
|
-
const regexPattern = normalizePath2(pattern).replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
|
|
60453
|
+
const regexPattern = normalizePath2(pattern).replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
|
|
60433
60454
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
60434
60455
|
const normalizedPath = normalizePath2(filePath);
|
|
60435
60456
|
return regex.test(normalizedPath);
|
|
@@ -62505,10 +62526,10 @@ ${elitImportMap}`;
|
|
|
62505
62526
|
webSocketServers.forEach((wsServer) => wsServer.close());
|
|
62506
62527
|
wsClients.clear();
|
|
62507
62528
|
}
|
|
62508
|
-
return new Promise((
|
|
62529
|
+
return new Promise((resolve9) => {
|
|
62509
62530
|
server.close(() => {
|
|
62510
62531
|
if (config.logging) console.log("[Server] Closed");
|
|
62511
|
-
|
|
62532
|
+
resolve9();
|
|
62512
62533
|
});
|
|
62513
62534
|
});
|
|
62514
62535
|
};
|
|
@@ -74451,6 +74472,7 @@ var WAPK_SALT_LENGTH = 16;
|
|
|
74451
74472
|
var WAPK_IV_LENGTH = 12;
|
|
74452
74473
|
var WAPK_AUTH_TAG_LENGTH = 16;
|
|
74453
74474
|
var WAPK_SCRYPT_OPTIONS = { N: 16384, r: 8, p: 1 };
|
|
74475
|
+
var DEFAULT_GOOGLE_DRIVE_TOKEN_ENV = "GOOGLE_DRIVE_ACCESS_TOKEN";
|
|
74454
74476
|
function isRecord(value) {
|
|
74455
74477
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
74456
74478
|
}
|
|
@@ -74526,6 +74548,47 @@ function normalizeWapkConfig(value) {
|
|
|
74526
74548
|
lock: normalizeWapkLockConfig(value.lock)
|
|
74527
74549
|
};
|
|
74528
74550
|
}
|
|
74551
|
+
function normalizeWapkGoogleDriveConfig(value) {
|
|
74552
|
+
if (!isRecord(value)) {
|
|
74553
|
+
return void 0;
|
|
74554
|
+
}
|
|
74555
|
+
const normalized = {
|
|
74556
|
+
fileId: normalizeNonEmptyString(value.fileId),
|
|
74557
|
+
accessToken: normalizeNonEmptyString(value.accessToken),
|
|
74558
|
+
accessTokenEnv: normalizeNonEmptyString(value.accessTokenEnv),
|
|
74559
|
+
supportsAllDrives: normalizeBoolean(value.supportsAllDrives)
|
|
74560
|
+
};
|
|
74561
|
+
return Object.values(normalized).some((entry) => entry !== void 0) ? normalized : void 0;
|
|
74562
|
+
}
|
|
74563
|
+
function normalizeBoolean(value) {
|
|
74564
|
+
return typeof value === "boolean" ? value : void 0;
|
|
74565
|
+
}
|
|
74566
|
+
function normalizeSyncInterval(value) {
|
|
74567
|
+
if (value === void 0 || value === null || value === "") {
|
|
74568
|
+
return void 0;
|
|
74569
|
+
}
|
|
74570
|
+
const interval = typeof value === "number" ? value : Number(value);
|
|
74571
|
+
if (!Number.isFinite(interval) || interval < 50) {
|
|
74572
|
+
return void 0;
|
|
74573
|
+
}
|
|
74574
|
+
return Math.trunc(interval);
|
|
74575
|
+
}
|
|
74576
|
+
function normalizeWapkRunConfig(value) {
|
|
74577
|
+
if (!isRecord(value)) {
|
|
74578
|
+
return void 0;
|
|
74579
|
+
}
|
|
74580
|
+
const normalized = {
|
|
74581
|
+
file: normalizeNonEmptyString(value.file),
|
|
74582
|
+
googleDrive: normalizeWapkGoogleDriveConfig(value.googleDrive),
|
|
74583
|
+
runtime: normalizeRuntime(value.runtime),
|
|
74584
|
+
syncInterval: normalizeSyncInterval(value.syncInterval),
|
|
74585
|
+
useWatcher: normalizeBoolean(value.useWatcher),
|
|
74586
|
+
watchArchive: normalizeBoolean(value.watchArchive),
|
|
74587
|
+
archiveSyncInterval: normalizeSyncInterval(value.archiveSyncInterval),
|
|
74588
|
+
password: normalizeNonEmptyString(value.password)
|
|
74589
|
+
};
|
|
74590
|
+
return Object.values(normalized).some((entry) => entry !== void 0) ? normalized : void 0;
|
|
74591
|
+
}
|
|
74529
74592
|
function sanitizePackageName(name) {
|
|
74530
74593
|
const sanitized = name.trim().replace(/[<>:"/\\|?*\x00-\x1F]+/g, "-").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
74531
74594
|
return sanitized.length > 0 ? sanitized : "app";
|
|
@@ -74972,49 +75035,360 @@ function extractFiles(files, destination) {
|
|
|
74972
75035
|
}
|
|
74973
75036
|
}
|
|
74974
75037
|
function collectRuntimeSyncFiles(directory) {
|
|
74975
|
-
|
|
74976
|
-
|
|
75038
|
+
return filterRuntimeSyncFiles(collectFiles(directory, directory, []));
|
|
75039
|
+
}
|
|
75040
|
+
function filterRuntimeSyncFiles(files) {
|
|
75041
|
+
return [...files].filter((file) => {
|
|
74977
75042
|
const firstPart = file.path.split("/")[0] ?? "";
|
|
74978
75043
|
return !RUNTIME_SYNC_IGNORE.has(firstPart);
|
|
74979
75044
|
}).sort((left, right) => left.path.localeCompare(right.path));
|
|
74980
75045
|
}
|
|
74981
|
-
function
|
|
75046
|
+
function getLocalArchiveSignature(archivePath) {
|
|
75047
|
+
try {
|
|
75048
|
+
const stats = (0, import_node_fs2.statSync)(archivePath);
|
|
75049
|
+
return `${stats.size}:${stats.mtimeMs}`;
|
|
75050
|
+
} catch {
|
|
75051
|
+
return void 0;
|
|
75052
|
+
}
|
|
75053
|
+
}
|
|
75054
|
+
function createGoogleDriveArchiveSignature(metadata) {
|
|
75055
|
+
const signature = [metadata.modifiedTime, metadata.size, metadata.md5Checksum].filter((value) => typeof value === "string" && value.length > 0).join(":");
|
|
75056
|
+
return signature.length > 0 ? signature : void 0;
|
|
75057
|
+
}
|
|
75058
|
+
async function readResponseMessage(response) {
|
|
75059
|
+
try {
|
|
75060
|
+
const text = (await response.text()).trim();
|
|
75061
|
+
return text.length > 0 ? text.slice(0, 400) : response.statusText;
|
|
75062
|
+
} catch {
|
|
75063
|
+
return response.statusText;
|
|
75064
|
+
}
|
|
75065
|
+
}
|
|
75066
|
+
function buildGoogleDriveFileUrl(fileId, params) {
|
|
75067
|
+
const url = new URL(`https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}`);
|
|
75068
|
+
for (const [key, value] of Object.entries(params)) {
|
|
75069
|
+
if (value === void 0) {
|
|
75070
|
+
continue;
|
|
75071
|
+
}
|
|
75072
|
+
url.searchParams.set(key, typeof value === "boolean" ? String(value) : value);
|
|
75073
|
+
}
|
|
75074
|
+
return url.toString();
|
|
75075
|
+
}
|
|
75076
|
+
function buildGoogleDriveUploadUrl(fileId, params) {
|
|
75077
|
+
const url = new URL(`https://www.googleapis.com/upload/drive/v3/files/${encodeURIComponent(fileId)}`);
|
|
75078
|
+
for (const [key, value] of Object.entries(params)) {
|
|
75079
|
+
if (value === void 0) {
|
|
75080
|
+
continue;
|
|
75081
|
+
}
|
|
75082
|
+
url.searchParams.set(key, typeof value === "boolean" ? String(value) : value);
|
|
75083
|
+
}
|
|
75084
|
+
return url.toString();
|
|
75085
|
+
}
|
|
75086
|
+
async function fetchGoogleDriveMetadata(config) {
|
|
75087
|
+
const response = await fetch(buildGoogleDriveFileUrl(config.fileId, {
|
|
75088
|
+
fields: "id,name,modifiedTime,size,md5Checksum",
|
|
75089
|
+
supportsAllDrives: config.supportsAllDrives
|
|
75090
|
+
}), {
|
|
75091
|
+
headers: {
|
|
75092
|
+
Authorization: `Bearer ${config.accessToken}`
|
|
75093
|
+
}
|
|
75094
|
+
});
|
|
75095
|
+
if (!response.ok) {
|
|
75096
|
+
throw new Error(`Google Drive metadata request failed (${response.status}): ${await readResponseMessage(response)}`);
|
|
75097
|
+
}
|
|
75098
|
+
const payload = await response.json();
|
|
75099
|
+
return {
|
|
75100
|
+
name: normalizeNonEmptyString(payload?.name),
|
|
75101
|
+
modifiedTime: normalizeNonEmptyString(payload?.modifiedTime),
|
|
75102
|
+
size: normalizeNonEmptyString(payload?.size),
|
|
75103
|
+
md5Checksum: normalizeNonEmptyString(payload?.md5Checksum)
|
|
75104
|
+
};
|
|
75105
|
+
}
|
|
75106
|
+
async function downloadGoogleDriveArchive(config) {
|
|
75107
|
+
const metadata = await fetchGoogleDriveMetadata(config);
|
|
75108
|
+
const response = await fetch(buildGoogleDriveFileUrl(config.fileId, {
|
|
75109
|
+
alt: "media",
|
|
75110
|
+
supportsAllDrives: config.supportsAllDrives
|
|
75111
|
+
}), {
|
|
75112
|
+
headers: {
|
|
75113
|
+
Authorization: `Bearer ${config.accessToken}`
|
|
75114
|
+
}
|
|
75115
|
+
});
|
|
75116
|
+
if (!response.ok) {
|
|
75117
|
+
throw new Error(`Google Drive download failed (${response.status}): ${await readResponseMessage(response)}`);
|
|
75118
|
+
}
|
|
75119
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
75120
|
+
return {
|
|
75121
|
+
buffer: Buffer.from(arrayBuffer),
|
|
75122
|
+
signature: createGoogleDriveArchiveSignature(metadata),
|
|
75123
|
+
label: metadata.name ?? `Google Drive:${config.fileId}`
|
|
75124
|
+
};
|
|
75125
|
+
}
|
|
75126
|
+
async function uploadGoogleDriveArchive(config, buffer) {
|
|
75127
|
+
const response = await fetch(buildGoogleDriveUploadUrl(config.fileId, {
|
|
75128
|
+
uploadType: "media",
|
|
75129
|
+
fields: "id,name,modifiedTime,size,md5Checksum",
|
|
75130
|
+
supportsAllDrives: config.supportsAllDrives
|
|
75131
|
+
}), {
|
|
75132
|
+
method: "PATCH",
|
|
75133
|
+
headers: {
|
|
75134
|
+
Authorization: `Bearer ${config.accessToken}`,
|
|
75135
|
+
"Content-Type": "application/octet-stream"
|
|
75136
|
+
},
|
|
75137
|
+
body: new Uint8Array(buffer)
|
|
75138
|
+
});
|
|
75139
|
+
if (!response.ok) {
|
|
75140
|
+
throw new Error(`Google Drive upload failed (${response.status}): ${await readResponseMessage(response)}`);
|
|
75141
|
+
}
|
|
75142
|
+
const payload = await response.json();
|
|
75143
|
+
const metadata = {
|
|
75144
|
+
name: normalizeNonEmptyString(payload?.name),
|
|
75145
|
+
modifiedTime: normalizeNonEmptyString(payload?.modifiedTime),
|
|
75146
|
+
size: normalizeNonEmptyString(payload?.size),
|
|
75147
|
+
md5Checksum: normalizeNonEmptyString(payload?.md5Checksum)
|
|
75148
|
+
};
|
|
75149
|
+
return {
|
|
75150
|
+
buffer,
|
|
75151
|
+
signature: createGoogleDriveArchiveSignature(metadata),
|
|
75152
|
+
label: metadata.name ?? `Google Drive:${config.fileId}`
|
|
75153
|
+
};
|
|
75154
|
+
}
|
|
75155
|
+
function resolveGoogleDriveAccessToken(config) {
|
|
75156
|
+
const explicitToken = normalizeNonEmptyString(config?.accessToken);
|
|
75157
|
+
const configuredEnvName = normalizeNonEmptyString(config?.accessTokenEnv);
|
|
75158
|
+
const configuredEnvToken = configuredEnvName ? normalizeNonEmptyString(process.env[configuredEnvName]) : void 0;
|
|
75159
|
+
const defaultEnvToken = normalizeNonEmptyString(process.env[DEFAULT_GOOGLE_DRIVE_TOKEN_ENV]);
|
|
75160
|
+
const token = explicitToken ?? configuredEnvToken ?? defaultEnvToken;
|
|
75161
|
+
if (token) {
|
|
75162
|
+
return token;
|
|
75163
|
+
}
|
|
75164
|
+
if (configuredEnvName) {
|
|
75165
|
+
throw new Error(`Google Drive access token not found in environment variable ${configuredEnvName}.`);
|
|
75166
|
+
}
|
|
75167
|
+
throw new Error(`Google Drive access token is required. Provide googleDrive.accessToken, googleDrive.accessTokenEnv, or set ${DEFAULT_GOOGLE_DRIVE_TOKEN_ENV}.`);
|
|
75168
|
+
}
|
|
75169
|
+
function parseGoogleDriveArchiveSpecifier(value) {
|
|
75170
|
+
const match = value.match(/^(?:gdrive|google-drive):\/\/(.+)$/i);
|
|
75171
|
+
if (!match) {
|
|
75172
|
+
return void 0;
|
|
75173
|
+
}
|
|
75174
|
+
const fileId = match[1]?.trim();
|
|
75175
|
+
return fileId && fileId.length > 0 ? fileId : void 0;
|
|
75176
|
+
}
|
|
75177
|
+
function resolveGoogleDriveConfig(archiveSpecifier, googleDrive) {
|
|
75178
|
+
const fileId = normalizeNonEmptyString(googleDrive?.fileId) ?? parseGoogleDriveArchiveSpecifier(archiveSpecifier);
|
|
75179
|
+
if (!fileId) {
|
|
75180
|
+
return void 0;
|
|
75181
|
+
}
|
|
75182
|
+
return {
|
|
75183
|
+
fileId,
|
|
75184
|
+
accessToken: resolveGoogleDriveAccessToken(googleDrive),
|
|
75185
|
+
accessTokenEnv: normalizeNonEmptyString(googleDrive?.accessTokenEnv),
|
|
75186
|
+
supportsAllDrives: googleDrive?.supportsAllDrives ?? false
|
|
75187
|
+
};
|
|
75188
|
+
}
|
|
75189
|
+
function createLocalArchiveHandle(archivePath) {
|
|
75190
|
+
const resolvedArchivePath = (0, import_node_path2.resolve)(archivePath);
|
|
75191
|
+
const readLocalBuffer = () => {
|
|
75192
|
+
if (!(0, import_node_fs2.existsSync)(resolvedArchivePath)) {
|
|
75193
|
+
throw new Error(`WAPK file not found: ${resolvedArchivePath}`);
|
|
75194
|
+
}
|
|
75195
|
+
return (0, import_node_fs2.readFileSync)(resolvedArchivePath);
|
|
75196
|
+
};
|
|
75197
|
+
return {
|
|
75198
|
+
identifier: resolvedArchivePath,
|
|
75199
|
+
label: (0, import_node_path2.basename)(resolvedArchivePath),
|
|
75200
|
+
readSnapshot: async () => ({
|
|
75201
|
+
buffer: readLocalBuffer(),
|
|
75202
|
+
signature: getLocalArchiveSignature(resolvedArchivePath),
|
|
75203
|
+
label: (0, import_node_path2.basename)(resolvedArchivePath)
|
|
75204
|
+
}),
|
|
75205
|
+
getSignature: async () => getLocalArchiveSignature(resolvedArchivePath),
|
|
75206
|
+
writeBuffer: async (buffer) => {
|
|
75207
|
+
(0, import_node_fs2.writeFileSync)(resolvedArchivePath, buffer);
|
|
75208
|
+
return {
|
|
75209
|
+
buffer,
|
|
75210
|
+
signature: getLocalArchiveSignature(resolvedArchivePath),
|
|
75211
|
+
label: (0, import_node_path2.basename)(resolvedArchivePath)
|
|
75212
|
+
};
|
|
75213
|
+
}
|
|
75214
|
+
};
|
|
75215
|
+
}
|
|
75216
|
+
function createGoogleDriveArchiveHandle(config) {
|
|
75217
|
+
const identifier = `gdrive://${config.fileId}`;
|
|
75218
|
+
const label = `Google Drive:${config.fileId}`;
|
|
75219
|
+
return {
|
|
75220
|
+
identifier,
|
|
75221
|
+
label,
|
|
75222
|
+
readSnapshot: async () => downloadGoogleDriveArchive(config),
|
|
75223
|
+
getSignature: async () => createGoogleDriveArchiveSignature(await fetchGoogleDriveMetadata(config)),
|
|
75224
|
+
writeBuffer: async (buffer) => uploadGoogleDriveArchive(config, buffer)
|
|
75225
|
+
};
|
|
75226
|
+
}
|
|
75227
|
+
function resolveArchiveHandle(archiveSpecifier, googleDrive) {
|
|
75228
|
+
const googleDriveConfig = resolveGoogleDriveConfig(archiveSpecifier, googleDrive);
|
|
75229
|
+
if (googleDriveConfig) {
|
|
75230
|
+
return createGoogleDriveArchiveHandle(googleDriveConfig);
|
|
75231
|
+
}
|
|
75232
|
+
return createLocalArchiveHandle(archiveSpecifier);
|
|
75233
|
+
}
|
|
75234
|
+
async function writeWapkArchiveFromMemory(archiveHandle, header, files, lock) {
|
|
74982
75235
|
const updatedHeader = {
|
|
74983
75236
|
...header,
|
|
74984
75237
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
74985
75238
|
};
|
|
74986
|
-
|
|
75239
|
+
const snapshot = await archiveHandle.writeBuffer(encodeWapk(updatedHeader, files, lock));
|
|
75240
|
+
return {
|
|
75241
|
+
header: updatedHeader,
|
|
75242
|
+
signature: snapshot.signature,
|
|
75243
|
+
label: snapshot.label ?? archiveHandle.label
|
|
75244
|
+
};
|
|
75245
|
+
}
|
|
75246
|
+
function removeEmptyParentDirectories(directory, rootDir) {
|
|
75247
|
+
let currentDir = directory;
|
|
75248
|
+
while (true) {
|
|
75249
|
+
const relativeDir = (0, import_node_path2.relative)(rootDir, currentDir);
|
|
75250
|
+
if (!relativeDir || relativeDir.startsWith("..") || (0, import_node_path2.isAbsolute)(relativeDir)) {
|
|
75251
|
+
return;
|
|
75252
|
+
}
|
|
75253
|
+
try {
|
|
75254
|
+
if ((0, import_node_fs2.readdirSync)(currentDir).length > 0) {
|
|
75255
|
+
return;
|
|
75256
|
+
}
|
|
75257
|
+
(0, import_node_fs2.rmSync)(currentDir, { recursive: false, force: true });
|
|
75258
|
+
} catch {
|
|
75259
|
+
return;
|
|
75260
|
+
}
|
|
75261
|
+
currentDir = (0, import_node_path2.dirname)(currentDir);
|
|
75262
|
+
}
|
|
75263
|
+
}
|
|
75264
|
+
function applyArchiveFilesToWorkDir(directory, files) {
|
|
75265
|
+
const existingFiles = collectRuntimeSyncFiles(directory);
|
|
75266
|
+
const nextPaths = new Set(files.map((file) => file.path));
|
|
75267
|
+
for (const file of existingFiles) {
|
|
75268
|
+
if (nextPaths.has(file.path)) {
|
|
75269
|
+
continue;
|
|
75270
|
+
}
|
|
75271
|
+
const filePath = (0, import_node_path2.join)(directory, ...file.path.split("/"));
|
|
75272
|
+
(0, import_node_fs2.rmSync)(filePath, { force: true });
|
|
75273
|
+
removeEmptyParentDirectories((0, import_node_path2.dirname)(filePath), directory);
|
|
75274
|
+
}
|
|
75275
|
+
extractFiles(files, directory);
|
|
75276
|
+
}
|
|
75277
|
+
async function readArchiveRuntimeState(archiveHandle, lock) {
|
|
75278
|
+
const snapshot = await archiveHandle.readSnapshot();
|
|
75279
|
+
const decoded = decodeWapk(snapshot.buffer, lock ? { password: lock.password } : {});
|
|
75280
|
+
return {
|
|
75281
|
+
header: decoded.header,
|
|
75282
|
+
files: filterRuntimeSyncFiles(decoded.files),
|
|
75283
|
+
signature: snapshot.signature,
|
|
75284
|
+
label: snapshot.label ?? archiveHandle.label
|
|
75285
|
+
};
|
|
74987
75286
|
}
|
|
74988
75287
|
function createWapkLiveSync(prepared) {
|
|
74989
75288
|
let memoryFiles = collectRuntimeSyncFiles(prepared.workDir);
|
|
74990
75289
|
const syncInterval = prepared.syncInterval ?? 300;
|
|
75290
|
+
const archiveSyncInterval = prepared.archiveSyncInterval ?? syncInterval;
|
|
75291
|
+
const watchArchive = prepared.watchArchive ?? true;
|
|
75292
|
+
let currentHeader = prepared.header;
|
|
75293
|
+
let currentArchiveLabel = prepared.archiveLabel;
|
|
74991
75294
|
let stopped = false;
|
|
74992
|
-
|
|
74993
|
-
|
|
74994
|
-
|
|
74995
|
-
|
|
74996
|
-
|
|
75295
|
+
let lastArchiveSignature = prepared.archiveSignature;
|
|
75296
|
+
let lastArchivePollAt = 0;
|
|
75297
|
+
let pendingOperation = Promise.resolve();
|
|
75298
|
+
const reportSyncError = (error) => {
|
|
75299
|
+
console.warn(
|
|
75300
|
+
`[wapk] Sync error for ${currentArchiveLabel}: ${error instanceof Error ? error.message : String(error)}`
|
|
75301
|
+
);
|
|
75302
|
+
};
|
|
75303
|
+
const pullArchiveChanges = async () => {
|
|
75304
|
+
if (!watchArchive) {
|
|
75305
|
+
return false;
|
|
75306
|
+
}
|
|
75307
|
+
const archiveSignature = await prepared.archiveHandle.getSignature();
|
|
75308
|
+
if (!archiveSignature || archiveSignature === lastArchiveSignature) {
|
|
75309
|
+
return false;
|
|
75310
|
+
}
|
|
75311
|
+
try {
|
|
75312
|
+
const archiveState = await readArchiveRuntimeState(prepared.archiveHandle, prepared.lock);
|
|
75313
|
+
lastArchiveSignature = archiveState.signature ?? archiveSignature;
|
|
75314
|
+
currentHeader = archiveState.header;
|
|
75315
|
+
currentArchiveLabel = archiveState.label;
|
|
75316
|
+
if (filesEqual(memoryFiles, archiveState.files)) {
|
|
75317
|
+
return false;
|
|
75318
|
+
}
|
|
75319
|
+
applyArchiveFilesToWorkDir(prepared.workDir, archiveState.files);
|
|
75320
|
+
memoryFiles = archiveState.files;
|
|
75321
|
+
return true;
|
|
75322
|
+
} catch (error) {
|
|
75323
|
+
console.warn(
|
|
75324
|
+
`[wapk] Failed to pull external archive changes from ${currentArchiveLabel}: ${error instanceof Error ? error.message : String(error)}`
|
|
75325
|
+
);
|
|
75326
|
+
return false;
|
|
74997
75327
|
}
|
|
74998
|
-
|
|
74999
|
-
|
|
75328
|
+
};
|
|
75329
|
+
const flush = () => {
|
|
75330
|
+
pendingOperation = pendingOperation.catch(() => void 0).then(async () => {
|
|
75331
|
+
if (stopped) return;
|
|
75332
|
+
const nextFiles = collectRuntimeSyncFiles(prepared.workDir);
|
|
75333
|
+
const localDirty = !filesEqual(memoryFiles, nextFiles);
|
|
75334
|
+
const now = Date.now();
|
|
75335
|
+
const shouldPollArchive = watchArchive && (lastArchivePollAt === 0 || now - lastArchivePollAt >= archiveSyncInterval);
|
|
75336
|
+
if (!localDirty && shouldPollArchive) {
|
|
75337
|
+
lastArchivePollAt = now;
|
|
75338
|
+
await pullArchiveChanges();
|
|
75339
|
+
return;
|
|
75340
|
+
}
|
|
75341
|
+
if (!localDirty) {
|
|
75342
|
+
return;
|
|
75343
|
+
}
|
|
75344
|
+
if (shouldPollArchive) {
|
|
75345
|
+
lastArchivePollAt = now;
|
|
75346
|
+
const archiveSignature = await prepared.archiveHandle.getSignature();
|
|
75347
|
+
if (archiveSignature && archiveSignature !== lastArchiveSignature) {
|
|
75348
|
+
console.warn(
|
|
75349
|
+
`[wapk] Both the workdir and ${currentArchiveLabel} changed; writing local workdir changes back to the archive.`
|
|
75350
|
+
);
|
|
75351
|
+
}
|
|
75352
|
+
}
|
|
75353
|
+
memoryFiles = nextFiles;
|
|
75354
|
+
const writeResult = await writeWapkArchiveFromMemory(prepared.archiveHandle, currentHeader, memoryFiles, prepared.lock);
|
|
75355
|
+
currentHeader = writeResult.header;
|
|
75356
|
+
currentArchiveLabel = writeResult.label;
|
|
75357
|
+
lastArchiveSignature = writeResult.signature ?? await prepared.archiveHandle.getSignature();
|
|
75358
|
+
});
|
|
75359
|
+
return pendingOperation;
|
|
75360
|
+
};
|
|
75361
|
+
const scheduleFlush = () => {
|
|
75362
|
+
void flush().catch(reportSyncError);
|
|
75000
75363
|
};
|
|
75001
75364
|
if (prepared.useWatcher) {
|
|
75002
75365
|
const watcher = (0, import_node_fs2.watch)(prepared.workDir, { recursive: true }, () => {
|
|
75003
|
-
|
|
75366
|
+
scheduleFlush();
|
|
75004
75367
|
});
|
|
75005
|
-
const
|
|
75006
|
-
|
|
75007
|
-
|
|
75368
|
+
const archiveTimer = watchArchive ? setInterval(() => {
|
|
75369
|
+
scheduleFlush();
|
|
75370
|
+
}, archiveSyncInterval) : void 0;
|
|
75371
|
+
archiveTimer?.unref?.();
|
|
75372
|
+
const stop2 = async () => {
|
|
75373
|
+
if (stopped) return pendingOperation;
|
|
75008
75374
|
watcher.close();
|
|
75375
|
+
if (archiveTimer) {
|
|
75376
|
+
clearInterval(archiveTimer);
|
|
75377
|
+
}
|
|
75378
|
+
await flush();
|
|
75379
|
+
stopped = true;
|
|
75380
|
+
await pendingOperation;
|
|
75009
75381
|
};
|
|
75010
75382
|
return { flush, stop: stop2 };
|
|
75011
75383
|
}
|
|
75012
|
-
const timer = setInterval(
|
|
75384
|
+
const timer = setInterval(scheduleFlush, watchArchive ? Math.min(syncInterval, archiveSyncInterval) : syncInterval);
|
|
75013
75385
|
timer.unref?.();
|
|
75014
|
-
const stop = () => {
|
|
75015
|
-
|
|
75016
|
-
stopped = true;
|
|
75386
|
+
const stop = async () => {
|
|
75387
|
+
if (stopped) return;
|
|
75017
75388
|
clearInterval(timer);
|
|
75389
|
+
await flush();
|
|
75390
|
+
stopped = true;
|
|
75391
|
+
await pendingOperation;
|
|
75018
75392
|
};
|
|
75019
75393
|
return { flush, stop };
|
|
75020
75394
|
}
|
|
@@ -75155,12 +75529,11 @@ function extractWapkArchive(wapkPath, outputDir = ".", options = {}) {
|
|
|
75155
75529
|
console.log(`Extracted ${archive.files.length} files to: ${extractDirectory}`);
|
|
75156
75530
|
return extractDirectory;
|
|
75157
75531
|
}
|
|
75158
|
-
function prepareWapkApp(wapkPath, options = {}) {
|
|
75159
|
-
const
|
|
75160
|
-
|
|
75161
|
-
|
|
75162
|
-
|
|
75163
|
-
const buffer = (0, import_node_fs2.readFileSync)(archivePath);
|
|
75532
|
+
async function prepareWapkApp(wapkPath, options = {}) {
|
|
75533
|
+
const archiveHandle = resolveArchiveHandle(wapkPath, options.googleDrive);
|
|
75534
|
+
const archivePath = archiveHandle.identifier;
|
|
75535
|
+
const snapshot = await archiveHandle.readSnapshot();
|
|
75536
|
+
const buffer = snapshot.buffer;
|
|
75164
75537
|
const envelope = parseWapkEnvelope(buffer);
|
|
75165
75538
|
const lock = envelope.version === WAPK_LOCKED_VERSION ? resolveArchiveCredentials(options) : void 0;
|
|
75166
75539
|
const decoded = decodeWapk(buffer, options);
|
|
@@ -75175,12 +75548,17 @@ function prepareWapkApp(wapkPath, options = {}) {
|
|
|
75175
75548
|
}
|
|
75176
75549
|
return {
|
|
75177
75550
|
archivePath,
|
|
75551
|
+
archiveLabel: snapshot.label ?? archiveHandle.label,
|
|
75552
|
+
archiveHandle,
|
|
75553
|
+
archiveSignature: snapshot.signature,
|
|
75178
75554
|
workDir,
|
|
75179
75555
|
entryPath,
|
|
75180
75556
|
header: decoded.header,
|
|
75181
75557
|
runtime: runtime2,
|
|
75182
75558
|
syncInterval: options.syncInterval,
|
|
75183
75559
|
useWatcher: options.useWatcher,
|
|
75560
|
+
watchArchive: options.watchArchive,
|
|
75561
|
+
archiveSyncInterval: options.archiveSyncInterval,
|
|
75184
75562
|
lock
|
|
75185
75563
|
};
|
|
75186
75564
|
}
|
|
@@ -75219,7 +75597,7 @@ async function runPreparedWapkApp(prepared) {
|
|
|
75219
75597
|
} finally {
|
|
75220
75598
|
process.off("SIGINT", onSigInt);
|
|
75221
75599
|
process.off("SIGTERM", onSigTerm);
|
|
75222
|
-
sync.stop();
|
|
75600
|
+
await sync.stop();
|
|
75223
75601
|
(0, import_node_fs2.rmSync)(prepared.workDir, { recursive: true, force: true });
|
|
75224
75602
|
}
|
|
75225
75603
|
}
|
|
@@ -75263,11 +75641,13 @@ function printWapkHelp() {
|
|
|
75263
75641
|
"WAPK packaging for Elit",
|
|
75264
75642
|
"",
|
|
75265
75643
|
"Usage:",
|
|
75266
|
-
" elit wapk
|
|
75267
|
-
" elit wapk
|
|
75268
|
-
" elit wapk run
|
|
75269
|
-
" elit wapk run <
|
|
75270
|
-
" elit wapk run
|
|
75644
|
+
" elit wapk [file.wapk]",
|
|
75645
|
+
" elit wapk gdrive://<fileId>",
|
|
75646
|
+
" elit wapk run [file.wapk]",
|
|
75647
|
+
" elit wapk run --google-drive-file-id <fileId> --google-drive-token-env <env>",
|
|
75648
|
+
" elit wapk run [file.wapk] --runtime node|bun|deno",
|
|
75649
|
+
" elit wapk run [file.wapk] --sync-interval 100",
|
|
75650
|
+
" elit wapk run [file.wapk] --watcher",
|
|
75271
75651
|
" elit wapk pack [directory]",
|
|
75272
75652
|
" elit wapk pack [directory] --password secret-123",
|
|
75273
75653
|
" elit wapk pack [directory] --include-deps",
|
|
@@ -75277,14 +75657,23 @@ function printWapkHelp() {
|
|
|
75277
75657
|
"Options:",
|
|
75278
75658
|
" -r, --runtime <name> Runtime override: node, bun, deno",
|
|
75279
75659
|
" --sync-interval <ms> Polling interval for live sync (ms, default 300)",
|
|
75660
|
+
" --archive-sync-interval <ms> Polling interval for reading archive source changes",
|
|
75280
75661
|
" --watcher, --use-watcher Use event-driven file watcher instead of polling",
|
|
75662
|
+
" --archive-watch Pull external archive changes back into the temp workdir",
|
|
75663
|
+
" --no-archive-watch Disable external archive read sync",
|
|
75664
|
+
" --google-drive-file-id <id> Run a remote .wapk directly from Google Drive",
|
|
75665
|
+
" --google-drive-token-env <name> Env var containing the Google Drive OAuth token",
|
|
75666
|
+
" --google-drive-access-token <value> OAuth token for Google Drive API calls",
|
|
75667
|
+
" --google-drive-shared-drive Include supportsAllDrives=true for shared drives",
|
|
75281
75668
|
" --include-deps Include node_modules in the archive",
|
|
75282
75669
|
" --password <value> Password for locking or unlocking the archive",
|
|
75283
75670
|
" -h, --help Show this help",
|
|
75284
75671
|
"",
|
|
75285
75672
|
"Notes:",
|
|
75286
75673
|
" - Pack reads wapk from elit.config.* and falls back to package.json.",
|
|
75287
|
-
" - Run mode
|
|
75674
|
+
" - Run mode can read config.wapk.run for default file/runtime/live-sync options.",
|
|
75675
|
+
" - Run mode keeps files in RAM and syncs changes both to and from the archive source.",
|
|
75676
|
+
" - Google Drive mode talks to the Drive API directly; no local archive file is required.",
|
|
75288
75677
|
" - Locked archives require the same password for run/extract/inspect.",
|
|
75289
75678
|
" - Archives stay unlocked by default unless a password is provided.",
|
|
75290
75679
|
" - Use --watcher for faster file change detection (less CPU usage).",
|
|
@@ -75325,9 +75714,12 @@ function parseArchiveAccessArgs(args, usage) {
|
|
|
75325
75714
|
}
|
|
75326
75715
|
function parseRunArgs(args) {
|
|
75327
75716
|
let file;
|
|
75717
|
+
let googleDrive;
|
|
75328
75718
|
let runtime2;
|
|
75329
75719
|
let syncInterval;
|
|
75330
|
-
let useWatcher
|
|
75720
|
+
let useWatcher;
|
|
75721
|
+
let watchArchive;
|
|
75722
|
+
let archiveSyncInterval;
|
|
75331
75723
|
let password;
|
|
75332
75724
|
for (let index = 0; index < args.length; index++) {
|
|
75333
75725
|
const arg = args[index];
|
|
@@ -75349,11 +75741,55 @@ function parseRunArgs(args) {
|
|
|
75349
75741
|
syncInterval = value;
|
|
75350
75742
|
break;
|
|
75351
75743
|
}
|
|
75744
|
+
case "--archive-sync-interval": {
|
|
75745
|
+
const value = parseInt(readRequiredOptionValue(args, ++index, "--archive-sync-interval"), 10);
|
|
75746
|
+
if (Number.isNaN(value) || value < 50) {
|
|
75747
|
+
throw new Error("--archive-sync-interval must be a number >= 50 (milliseconds)");
|
|
75748
|
+
}
|
|
75749
|
+
archiveSyncInterval = value;
|
|
75750
|
+
break;
|
|
75751
|
+
}
|
|
75352
75752
|
case "--use-watcher":
|
|
75353
75753
|
case "--watcher": {
|
|
75354
75754
|
useWatcher = true;
|
|
75355
75755
|
break;
|
|
75356
75756
|
}
|
|
75757
|
+
case "--archive-watch": {
|
|
75758
|
+
watchArchive = true;
|
|
75759
|
+
break;
|
|
75760
|
+
}
|
|
75761
|
+
case "--no-archive-watch": {
|
|
75762
|
+
watchArchive = false;
|
|
75763
|
+
break;
|
|
75764
|
+
}
|
|
75765
|
+
case "--google-drive-file-id": {
|
|
75766
|
+
googleDrive = {
|
|
75767
|
+
...googleDrive,
|
|
75768
|
+
fileId: readRequiredOptionValue(args, ++index, "--google-drive-file-id")
|
|
75769
|
+
};
|
|
75770
|
+
break;
|
|
75771
|
+
}
|
|
75772
|
+
case "--google-drive-token-env": {
|
|
75773
|
+
googleDrive = {
|
|
75774
|
+
...googleDrive,
|
|
75775
|
+
accessTokenEnv: readRequiredOptionValue(args, ++index, "--google-drive-token-env")
|
|
75776
|
+
};
|
|
75777
|
+
break;
|
|
75778
|
+
}
|
|
75779
|
+
case "--google-drive-access-token": {
|
|
75780
|
+
googleDrive = {
|
|
75781
|
+
...googleDrive,
|
|
75782
|
+
accessToken: readRequiredOptionValue(args, ++index, "--google-drive-access-token")
|
|
75783
|
+
};
|
|
75784
|
+
break;
|
|
75785
|
+
}
|
|
75786
|
+
case "--google-drive-shared-drive": {
|
|
75787
|
+
googleDrive = {
|
|
75788
|
+
...googleDrive,
|
|
75789
|
+
supportsAllDrives: true
|
|
75790
|
+
};
|
|
75791
|
+
break;
|
|
75792
|
+
}
|
|
75357
75793
|
case "--password":
|
|
75358
75794
|
password = readRequiredOptionValue(args, ++index, "--password");
|
|
75359
75795
|
break;
|
|
@@ -75368,10 +75804,7 @@ function parseRunArgs(args) {
|
|
|
75368
75804
|
break;
|
|
75369
75805
|
}
|
|
75370
75806
|
}
|
|
75371
|
-
|
|
75372
|
-
throw new Error("Usage: elit wapk run <file.wapk>");
|
|
75373
|
-
}
|
|
75374
|
-
return { file, runtime: runtime2, syncInterval, useWatcher, password };
|
|
75807
|
+
return { file, googleDrive, runtime: runtime2, syncInterval, useWatcher, watchArchive, archiveSyncInterval, password };
|
|
75375
75808
|
}
|
|
75376
75809
|
function parsePackArgs(args) {
|
|
75377
75810
|
let directory = ".";
|
|
@@ -75397,8 +75830,63 @@ function parsePackArgs(args) {
|
|
|
75397
75830
|
}
|
|
75398
75831
|
return { directory, includeDeps, password };
|
|
75399
75832
|
}
|
|
75400
|
-
async function
|
|
75401
|
-
|
|
75833
|
+
async function readConfiguredWapkRunDefaults(cwd) {
|
|
75834
|
+
const config = await loadConfig(cwd);
|
|
75835
|
+
const runConfig = normalizeWapkRunConfig(config?.wapk?.run);
|
|
75836
|
+
const fallbackPassword = normalizeNonEmptyString(config?.wapk?.lock?.password);
|
|
75837
|
+
if (!runConfig) {
|
|
75838
|
+
return fallbackPassword ? { password: fallbackPassword } : void 0;
|
|
75839
|
+
}
|
|
75840
|
+
if (!runConfig.password && fallbackPassword) {
|
|
75841
|
+
runConfig.password = fallbackPassword;
|
|
75842
|
+
}
|
|
75843
|
+
if (runConfig.file && runConfig.googleDrive?.fileId) {
|
|
75844
|
+
throw new Error("config.wapk.run.file and config.wapk.run.googleDrive.fileId are mutually exclusive.");
|
|
75845
|
+
}
|
|
75846
|
+
return runConfig;
|
|
75847
|
+
}
|
|
75848
|
+
function mergeGoogleDriveRunConfig(cliConfig, defaultConfig) {
|
|
75849
|
+
if (!cliConfig && !defaultConfig) {
|
|
75850
|
+
return void 0;
|
|
75851
|
+
}
|
|
75852
|
+
const merged = {
|
|
75853
|
+
fileId: normalizeNonEmptyString(cliConfig?.fileId) ?? normalizeNonEmptyString(defaultConfig?.fileId),
|
|
75854
|
+
accessToken: normalizeNonEmptyString(cliConfig?.accessToken) ?? normalizeNonEmptyString(defaultConfig?.accessToken),
|
|
75855
|
+
accessTokenEnv: normalizeNonEmptyString(cliConfig?.accessTokenEnv) ?? normalizeNonEmptyString(defaultConfig?.accessTokenEnv),
|
|
75856
|
+
supportsAllDrives: cliConfig?.supportsAllDrives ?? defaultConfig?.supportsAllDrives
|
|
75857
|
+
};
|
|
75858
|
+
return Object.values(merged).some((entry) => entry !== void 0) ? merged : void 0;
|
|
75859
|
+
}
|
|
75860
|
+
function resolveConfiguredWapkRunOptions(options, defaults) {
|
|
75861
|
+
return {
|
|
75862
|
+
file: options.file ?? defaults?.file,
|
|
75863
|
+
googleDrive: mergeGoogleDriveRunConfig(options.googleDrive, defaults?.googleDrive),
|
|
75864
|
+
runtime: options.runtime ?? defaults?.runtime,
|
|
75865
|
+
syncInterval: options.syncInterval ?? defaults?.syncInterval,
|
|
75866
|
+
useWatcher: options.useWatcher ?? defaults?.useWatcher,
|
|
75867
|
+
watchArchive: options.watchArchive ?? defaults?.watchArchive,
|
|
75868
|
+
archiveSyncInterval: options.archiveSyncInterval ?? defaults?.archiveSyncInterval,
|
|
75869
|
+
password: options.password ?? defaults?.password
|
|
75870
|
+
};
|
|
75871
|
+
}
|
|
75872
|
+
function resolveRunArchivePath(file, cwd) {
|
|
75873
|
+
return (0, import_node_path2.isAbsolute)(file) ? file : (0, import_node_path2.resolve)(cwd, file);
|
|
75874
|
+
}
|
|
75875
|
+
function resolveRunArchiveSpecifier(file, googleDrive, cwd) {
|
|
75876
|
+
const googleDriveFileId = normalizeNonEmptyString(googleDrive?.fileId);
|
|
75877
|
+
if (googleDriveFileId) {
|
|
75878
|
+
if (file && !parseGoogleDriveArchiveSpecifier(file)) {
|
|
75879
|
+
throw new Error("WAPK run cannot use both a local archive file and googleDrive.fileId at the same time.");
|
|
75880
|
+
}
|
|
75881
|
+
return `gdrive://${googleDriveFileId}`;
|
|
75882
|
+
}
|
|
75883
|
+
if (!file) {
|
|
75884
|
+
return void 0;
|
|
75885
|
+
}
|
|
75886
|
+
return parseGoogleDriveArchiveSpecifier(file) ? file : resolveRunArchivePath(file, cwd);
|
|
75887
|
+
}
|
|
75888
|
+
async function runWapkCommand(args, cwd = process.cwd()) {
|
|
75889
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
75402
75890
|
printWapkHelp();
|
|
75403
75891
|
return;
|
|
75404
75892
|
}
|
|
@@ -75420,11 +75908,24 @@ async function runWapkCommand(args) {
|
|
|
75420
75908
|
extractWapkArchive(options.file, ".", options);
|
|
75421
75909
|
return;
|
|
75422
75910
|
}
|
|
75423
|
-
const
|
|
75424
|
-
const
|
|
75911
|
+
const parsedRunOptions = args[0] === "run" ? parseRunArgs(args.slice(1)) : parseRunArgs(args);
|
|
75912
|
+
const configuredRunDefaults = await readConfiguredWapkRunDefaults(cwd);
|
|
75913
|
+
const runOptions = resolveConfiguredWapkRunOptions(parsedRunOptions, configuredRunDefaults);
|
|
75914
|
+
const archiveSpecifier = resolveRunArchiveSpecifier(runOptions.file, runOptions.googleDrive, cwd);
|
|
75915
|
+
if (!archiveSpecifier) {
|
|
75916
|
+
if (args.length === 0) {
|
|
75917
|
+
printWapkHelp();
|
|
75918
|
+
return;
|
|
75919
|
+
}
|
|
75920
|
+
throw new Error("Usage: elit wapk run <file.wapk>");
|
|
75921
|
+
}
|
|
75922
|
+
const prepared = await prepareWapkApp(archiveSpecifier, {
|
|
75923
|
+
googleDrive: runOptions.googleDrive,
|
|
75425
75924
|
runtime: runOptions.runtime,
|
|
75426
75925
|
syncInterval: runOptions.syncInterval,
|
|
75427
75926
|
useWatcher: runOptions.useWatcher,
|
|
75927
|
+
watchArchive: runOptions.watchArchive,
|
|
75928
|
+
archiveSyncInterval: runOptions.archiveSyncInterval,
|
|
75428
75929
|
password: runOptions.password
|
|
75429
75930
|
});
|
|
75430
75931
|
const exitCode = await runPreparedWapkApp(prepared);
|
|
@@ -75851,7 +76352,7 @@ async function runDesktopWapkCommand(args, config) {
|
|
|
75851
76352
|
return;
|
|
75852
76353
|
}
|
|
75853
76354
|
const options = parseDesktopWapkRunArgs(args, config?.wapk);
|
|
75854
|
-
const preparedApp = prepareWapkApp(options.file, {
|
|
76355
|
+
const preparedApp = await prepareWapkApp(options.file, {
|
|
75855
76356
|
runtime: options.runtime,
|
|
75856
76357
|
syncInterval: options.syncInterval,
|
|
75857
76358
|
useWatcher: options.useWatcher,
|
|
@@ -75870,7 +76371,7 @@ async function runDesktopWapkCommand(args, config) {
|
|
|
75870
76371
|
process.exit(exitCode);
|
|
75871
76372
|
}
|
|
75872
76373
|
} finally {
|
|
75873
|
-
liveSync.stop();
|
|
76374
|
+
await liveSync.stop();
|
|
75874
76375
|
(0, import_node_fs3.rmSync)(preparedApp.workDir, { recursive: true, force: true });
|
|
75875
76376
|
cleanupPreparedEntry(preparedEntry);
|
|
75876
76377
|
}
|
|
@@ -76953,7 +77454,7 @@ function openMobileProject(platform, options) {
|
|
|
76953
77454
|
throw new Error(`Android project not found at ${projectPath}. Run "elit mobile init" first.`);
|
|
76954
77455
|
}
|
|
76955
77456
|
if (process.platform === "win32") {
|
|
76956
|
-
runCommand("
|
|
77457
|
+
runCommand("explorer.exe", [projectPath], options.cwd);
|
|
76957
77458
|
return;
|
|
76958
77459
|
}
|
|
76959
77460
|
if (process.platform === "darwin") {
|
|
@@ -77159,10 +77660,11 @@ function commandExists(command, cwd) {
|
|
|
77159
77660
|
});
|
|
77160
77661
|
return result2.status === 0;
|
|
77161
77662
|
}
|
|
77162
|
-
function resolveCommandPath(command, cwd) {
|
|
77663
|
+
function resolveCommandPath(command, cwd, env) {
|
|
77163
77664
|
const checker = process.platform === "win32" ? "where" : "which";
|
|
77164
77665
|
const result2 = (0, import_node_child_process3.spawnSync)(checker, [command], {
|
|
77165
77666
|
cwd,
|
|
77667
|
+
env,
|
|
77166
77668
|
encoding: "utf8",
|
|
77167
77669
|
shell: false
|
|
77168
77670
|
});
|
|
@@ -77223,7 +77725,13 @@ function runGradle(cwd, args) {
|
|
|
77223
77725
|
'[mobile] Gradle not found. Install Gradle and add it to PATH, or generate wrapper files in android/ with "gradle wrapper".'
|
|
77224
77726
|
);
|
|
77225
77727
|
}
|
|
77226
|
-
|
|
77728
|
+
const env = gradleCommand.prependPath ? prependCommandPath(gradleCommand.prependPath) : void 0;
|
|
77729
|
+
if (process.platform === "win32" && gradleCommand.useWindowsBatchShell) {
|
|
77730
|
+
const shellCommand = gradleCommand.batchCommandPath ?? resolveCommandPath(gradleCommand.command, androidRoot, env) ?? gradleCommand.command;
|
|
77731
|
+
runWindowsBatchCommand(shellCommand, args, androidRoot);
|
|
77732
|
+
return;
|
|
77733
|
+
}
|
|
77734
|
+
runCommand(gradleCommand.command, args, androidRoot, env);
|
|
77227
77735
|
}
|
|
77228
77736
|
function resolveGradleCommand(cwd) {
|
|
77229
77737
|
const androidRoot = (0, import_node_path4.join)(cwd, "android");
|
|
@@ -77232,22 +77740,31 @@ function resolveGradleCommand(cwd) {
|
|
|
77232
77740
|
if ((0, import_node_fs4.existsSync)(wrapperPath)) {
|
|
77233
77741
|
return {
|
|
77234
77742
|
command: wrapper,
|
|
77235
|
-
|
|
77743
|
+
batchCommandPath: wrapperPath,
|
|
77744
|
+
details: "Using project gradle wrapper.",
|
|
77745
|
+
useWindowsBatchShell: process.platform === "win32"
|
|
77236
77746
|
};
|
|
77237
77747
|
}
|
|
77238
77748
|
if (commandExists("gradle", androidRoot)) {
|
|
77239
77749
|
return {
|
|
77240
77750
|
command: "gradle",
|
|
77241
|
-
|
|
77751
|
+
batchCommandPath: process.platform === "win32" ? resolveCommandPath("gradle", androidRoot) ?? "gradle" : void 0,
|
|
77752
|
+
details: "Using Gradle from PATH.",
|
|
77753
|
+
useWindowsBatchShell: process.platform === "win32"
|
|
77242
77754
|
};
|
|
77243
77755
|
}
|
|
77244
77756
|
const fallbackGradle = resolveFallbackGradleExecutable();
|
|
77245
77757
|
if (!fallbackGradle) {
|
|
77246
77758
|
return void 0;
|
|
77247
77759
|
}
|
|
77760
|
+
const prependPath = process.platform === "win32" ? (0, import_node_path4.dirname)(fallbackGradle) : void 0;
|
|
77761
|
+
const fallbackEnv = prependPath ? prependCommandPath(prependPath) : void 0;
|
|
77248
77762
|
return {
|
|
77249
|
-
command: fallbackGradle,
|
|
77250
|
-
|
|
77763
|
+
command: process.platform === "win32" ? "gradle" : fallbackGradle,
|
|
77764
|
+
batchCommandPath: process.platform === "win32" ? resolveCommandPath("gradle", androidRoot, fallbackEnv) ?? void 0 : void 0,
|
|
77765
|
+
details: `Using fallback Gradle at ${fallbackGradle}.`,
|
|
77766
|
+
prependPath,
|
|
77767
|
+
useWindowsBatchShell: process.platform === "win32"
|
|
77251
77768
|
};
|
|
77252
77769
|
}
|
|
77253
77770
|
function resolveFallbackGradleExecutable() {
|
|
@@ -77403,26 +77920,28 @@ function upsertXmlAttribute(tag, name, value) {
|
|
|
77403
77920
|
}
|
|
77404
77921
|
return `${tag.slice(0, -1)} ${name}='${value}'>`;
|
|
77405
77922
|
}
|
|
77406
|
-
|
|
77407
|
-
|
|
77408
|
-
const
|
|
77409
|
-
|
|
77410
|
-
|
|
77411
|
-
|
|
77412
|
-
|
|
77413
|
-
|
|
77414
|
-
|
|
77415
|
-
|
|
77416
|
-
|
|
77923
|
+
function prependCommandPath(pathEntry) {
|
|
77924
|
+
const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path") ?? "PATH";
|
|
77925
|
+
const currentPath = process.env[pathKey];
|
|
77926
|
+
const delimiter2 = process.platform === "win32" ? ";" : ":";
|
|
77927
|
+
return {
|
|
77928
|
+
...process.env,
|
|
77929
|
+
[pathKey]: currentPath && currentPath.length > 0 ? `${pathEntry}${delimiter2}${currentPath}` : pathEntry
|
|
77930
|
+
};
|
|
77931
|
+
}
|
|
77932
|
+
function runWindowsBatchCommand(command, args, cwd) {
|
|
77933
|
+
const result2 = (0, import_node_child_process3.spawnSync)((0, import_node_path4.normalize)(command), args, {
|
|
77417
77934
|
cwd,
|
|
77418
|
-
stdio,
|
|
77419
|
-
shell: false
|
|
77420
|
-
windowsVerbatimArguments: true
|
|
77935
|
+
stdio: "inherit",
|
|
77936
|
+
shell: false
|
|
77421
77937
|
});
|
|
77938
|
+
if (typeof result2.status === "number" && result2.status !== 0) {
|
|
77939
|
+
process.exit(result2.status);
|
|
77940
|
+
}
|
|
77422
77941
|
}
|
|
77423
|
-
function runCommand(command, args, cwd) {
|
|
77942
|
+
function runCommand(command, args, cwd, env) {
|
|
77424
77943
|
const normalizedCommand = (0, import_node_path4.normalize)(command);
|
|
77425
|
-
const result2 =
|
|
77944
|
+
const result2 = (0, import_node_child_process3.spawnSync)(normalizedCommand, args, { cwd, env, stdio: "inherit", shell: false });
|
|
77426
77945
|
if (typeof result2.status === "number" && result2.status !== 0) {
|
|
77427
77946
|
process.exit(result2.status);
|
|
77428
77947
|
}
|
|
@@ -78555,8 +79074,1812 @@ Notes:
|
|
|
78555
79074
|
`);
|
|
78556
79075
|
}
|
|
78557
79076
|
|
|
79077
|
+
// src/pm-cli.ts
|
|
79078
|
+
var import_node_child_process4 = require("child_process");
|
|
79079
|
+
var import_node_fs5 = require("fs");
|
|
79080
|
+
var import_node_os2 = require("os");
|
|
79081
|
+
var import_node_path5 = require("path");
|
|
79082
|
+
var DEFAULT_PM_DATA_DIR = (0, import_node_path5.join)(".elit", "pm");
|
|
79083
|
+
var DEFAULT_PM_DUMP_FILE = "dump.json";
|
|
79084
|
+
var DEFAULT_RESTART_DELAY = 1e3;
|
|
79085
|
+
var DEFAULT_MAX_RESTARTS = 10;
|
|
79086
|
+
var DEFAULT_WATCH_DEBOUNCE = 250;
|
|
79087
|
+
var DEFAULT_MIN_UPTIME = 0;
|
|
79088
|
+
var DEFAULT_HEALTHCHECK_GRACE_PERIOD = 5e3;
|
|
79089
|
+
var DEFAULT_HEALTHCHECK_INTERVAL = 1e4;
|
|
79090
|
+
var DEFAULT_HEALTHCHECK_TIMEOUT = 3e3;
|
|
79091
|
+
var DEFAULT_HEALTHCHECK_MAX_FAILURES = 3;
|
|
79092
|
+
var DEFAULT_LOG_LINES = 40;
|
|
79093
|
+
var PM_RECORD_EXTENSION = ".json";
|
|
79094
|
+
var SUPPORTED_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]);
|
|
79095
|
+
var DEFAULT_WATCH_IGNORE = ["**/.git/**", "**/node_modules/**", "**/.elit/**"];
|
|
79096
|
+
function normalizePmRuntime(value, optionName = "--runtime") {
|
|
79097
|
+
if (value === void 0 || value === null || value === "") {
|
|
79098
|
+
return void 0;
|
|
79099
|
+
}
|
|
79100
|
+
if (typeof value !== "string") {
|
|
79101
|
+
throw new Error(`${optionName} must be one of: node, bun, deno`);
|
|
79102
|
+
}
|
|
79103
|
+
const runtime2 = value.trim().toLowerCase();
|
|
79104
|
+
if (runtime2 === "node" || runtime2 === "bun" || runtime2 === "deno") {
|
|
79105
|
+
return runtime2;
|
|
79106
|
+
}
|
|
79107
|
+
throw new Error(`${optionName} must be one of: node, bun, deno`);
|
|
79108
|
+
}
|
|
79109
|
+
function normalizePmRestartPolicy(value, optionName = "--restart-policy") {
|
|
79110
|
+
if (value === void 0 || value === null || value === "") {
|
|
79111
|
+
return void 0;
|
|
79112
|
+
}
|
|
79113
|
+
if (typeof value !== "string") {
|
|
79114
|
+
throw new Error(`${optionName} must be one of: always, on-failure, never`);
|
|
79115
|
+
}
|
|
79116
|
+
const policy = value.trim().toLowerCase();
|
|
79117
|
+
if (policy === "always" || policy === "on-failure" || policy === "never") {
|
|
79118
|
+
return policy;
|
|
79119
|
+
}
|
|
79120
|
+
throw new Error(`${optionName} must be one of: always, on-failure, never`);
|
|
79121
|
+
}
|
|
79122
|
+
function normalizeIntegerOption(value, optionName, min2 = 0) {
|
|
79123
|
+
const parsed = Number.parseInt(value, 10);
|
|
79124
|
+
if (!Number.isFinite(parsed) || parsed < min2) {
|
|
79125
|
+
throw new Error(`${optionName} must be a number >= ${min2}`);
|
|
79126
|
+
}
|
|
79127
|
+
return parsed;
|
|
79128
|
+
}
|
|
79129
|
+
function normalizeNonEmptyString2(value) {
|
|
79130
|
+
if (typeof value !== "string") {
|
|
79131
|
+
return void 0;
|
|
79132
|
+
}
|
|
79133
|
+
const normalized = value.trim();
|
|
79134
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
79135
|
+
}
|
|
79136
|
+
function hasPmGoogleDriveConfig(config) {
|
|
79137
|
+
return Boolean(
|
|
79138
|
+
normalizeNonEmptyString2(config?.fileId) || normalizeNonEmptyString2(config?.accessToken) || normalizeNonEmptyString2(config?.accessTokenEnv) || typeof config?.supportsAllDrives === "boolean"
|
|
79139
|
+
);
|
|
79140
|
+
}
|
|
79141
|
+
function hasPmWapkRunConfig(config) {
|
|
79142
|
+
return Boolean(
|
|
79143
|
+
normalizeNonEmptyString2(config?.file) || hasPmGoogleDriveConfig(config?.googleDrive) || normalizeNonEmptyString2(config?.runtime) || typeof config?.syncInterval === "number" || typeof config?.useWatcher === "boolean" || typeof config?.watchArchive === "boolean" || typeof config?.archiveSyncInterval === "number" || normalizeNonEmptyString2(config?.password)
|
|
79144
|
+
);
|
|
79145
|
+
}
|
|
79146
|
+
function mergePmWapkRunConfig(base, override) {
|
|
79147
|
+
if (!base && !override) {
|
|
79148
|
+
return void 0;
|
|
79149
|
+
}
|
|
79150
|
+
const googleDrive = hasPmGoogleDriveConfig(base?.googleDrive) || hasPmGoogleDriveConfig(override?.googleDrive) ? {
|
|
79151
|
+
fileId: override?.googleDrive?.fileId ?? base?.googleDrive?.fileId,
|
|
79152
|
+
accessToken: override?.googleDrive?.accessToken ?? base?.googleDrive?.accessToken,
|
|
79153
|
+
accessTokenEnv: override?.googleDrive?.accessTokenEnv ?? base?.googleDrive?.accessTokenEnv,
|
|
79154
|
+
supportsAllDrives: override?.googleDrive?.supportsAllDrives ?? base?.googleDrive?.supportsAllDrives
|
|
79155
|
+
} : void 0;
|
|
79156
|
+
const merged = {
|
|
79157
|
+
file: override?.file ?? base?.file,
|
|
79158
|
+
googleDrive,
|
|
79159
|
+
runtime: override?.runtime ?? base?.runtime,
|
|
79160
|
+
syncInterval: override?.syncInterval ?? base?.syncInterval,
|
|
79161
|
+
useWatcher: override?.useWatcher ?? base?.useWatcher,
|
|
79162
|
+
watchArchive: override?.watchArchive ?? base?.watchArchive,
|
|
79163
|
+
archiveSyncInterval: override?.archiveSyncInterval ?? base?.archiveSyncInterval,
|
|
79164
|
+
password: override?.password ?? base?.password
|
|
79165
|
+
};
|
|
79166
|
+
return hasPmWapkRunConfig(merged) ? merged : void 0;
|
|
79167
|
+
}
|
|
79168
|
+
function stripPmWapkSourceFromRunConfig(config) {
|
|
79169
|
+
if (!config) {
|
|
79170
|
+
return void 0;
|
|
79171
|
+
}
|
|
79172
|
+
const googleDrive = hasPmGoogleDriveConfig({
|
|
79173
|
+
...config.googleDrive,
|
|
79174
|
+
fileId: void 0
|
|
79175
|
+
}) ? {
|
|
79176
|
+
...config.googleDrive,
|
|
79177
|
+
fileId: void 0
|
|
79178
|
+
} : void 0;
|
|
79179
|
+
const stripped = {
|
|
79180
|
+
file: void 0,
|
|
79181
|
+
googleDrive,
|
|
79182
|
+
runtime: void 0,
|
|
79183
|
+
syncInterval: config.syncInterval,
|
|
79184
|
+
useWatcher: config.useWatcher,
|
|
79185
|
+
watchArchive: config.watchArchive,
|
|
79186
|
+
archiveSyncInterval: config.archiveSyncInterval,
|
|
79187
|
+
password: void 0
|
|
79188
|
+
};
|
|
79189
|
+
return hasPmWapkRunConfig(stripped) ? stripped : void 0;
|
|
79190
|
+
}
|
|
79191
|
+
function isRemoteWapkArchiveSpecifier(value) {
|
|
79192
|
+
return /^(?:gdrive|google-drive):\/\/.+/i.test(value.trim());
|
|
79193
|
+
}
|
|
79194
|
+
function isWapkArchiveSpecifier(value) {
|
|
79195
|
+
const normalized = value.trim();
|
|
79196
|
+
return normalized.toLowerCase().endsWith(".wapk") || isRemoteWapkArchiveSpecifier(normalized);
|
|
79197
|
+
}
|
|
79198
|
+
function buildGoogleDriveWapkSpecifier(fileId) {
|
|
79199
|
+
return `gdrive://${fileId}`;
|
|
79200
|
+
}
|
|
79201
|
+
function resolvePmWapkSource(value, cwd) {
|
|
79202
|
+
const normalized = normalizeNonEmptyString2(value);
|
|
79203
|
+
if (!normalized) {
|
|
79204
|
+
return void 0;
|
|
79205
|
+
}
|
|
79206
|
+
return isRemoteWapkArchiveSpecifier(normalized) ? normalized : (0, import_node_path5.resolve)(cwd, normalized);
|
|
79207
|
+
}
|
|
79208
|
+
function resolvePmWapkSourceToken(wapk, wapkRun) {
|
|
79209
|
+
const googleDriveFileId = normalizeNonEmptyString2(wapkRun?.googleDrive?.fileId);
|
|
79210
|
+
return normalizeNonEmptyString2(wapk) ?? normalizeNonEmptyString2(wapkRun?.file) ?? (googleDriveFileId ? buildGoogleDriveWapkSpecifier(googleDriveFileId) : void 0);
|
|
79211
|
+
}
|
|
79212
|
+
function countDefinedPmWapkSources(wapk, wapkRun) {
|
|
79213
|
+
const values = [
|
|
79214
|
+
normalizeNonEmptyString2(wapk),
|
|
79215
|
+
normalizeNonEmptyString2(wapkRun?.file),
|
|
79216
|
+
normalizeNonEmptyString2(wapkRun?.googleDrive?.fileId)
|
|
79217
|
+
].filter((entry) => Boolean(entry));
|
|
79218
|
+
return new Set(values).size;
|
|
79219
|
+
}
|
|
79220
|
+
function appendPmWapkRunArgs(args, previewParts, wapkRun) {
|
|
79221
|
+
if (!wapkRun) {
|
|
79222
|
+
return;
|
|
79223
|
+
}
|
|
79224
|
+
if (typeof wapkRun.syncInterval === "number" && Number.isFinite(wapkRun.syncInterval) && wapkRun.syncInterval >= 50) {
|
|
79225
|
+
const value = String(Math.trunc(wapkRun.syncInterval));
|
|
79226
|
+
args.push("--sync-interval", value);
|
|
79227
|
+
previewParts.push("--sync-interval", value);
|
|
79228
|
+
}
|
|
79229
|
+
if (wapkRun.useWatcher) {
|
|
79230
|
+
args.push("--watcher");
|
|
79231
|
+
previewParts.push("--watcher");
|
|
79232
|
+
}
|
|
79233
|
+
if (typeof wapkRun.watchArchive === "boolean") {
|
|
79234
|
+
const flag = wapkRun.watchArchive ? "--archive-watch" : "--no-archive-watch";
|
|
79235
|
+
args.push(flag);
|
|
79236
|
+
previewParts.push(flag);
|
|
79237
|
+
}
|
|
79238
|
+
if (typeof wapkRun.archiveSyncInterval === "number" && Number.isFinite(wapkRun.archiveSyncInterval) && wapkRun.archiveSyncInterval >= 50) {
|
|
79239
|
+
const value = String(Math.trunc(wapkRun.archiveSyncInterval));
|
|
79240
|
+
args.push("--archive-sync-interval", value);
|
|
79241
|
+
previewParts.push("--archive-sync-interval", value);
|
|
79242
|
+
}
|
|
79243
|
+
const tokenEnv = normalizeNonEmptyString2(wapkRun.googleDrive?.accessTokenEnv);
|
|
79244
|
+
if (tokenEnv) {
|
|
79245
|
+
args.push("--google-drive-token-env", tokenEnv);
|
|
79246
|
+
previewParts.push("--google-drive-token-env", tokenEnv);
|
|
79247
|
+
}
|
|
79248
|
+
const accessToken = normalizeNonEmptyString2(wapkRun.googleDrive?.accessToken);
|
|
79249
|
+
if (accessToken) {
|
|
79250
|
+
args.push("--google-drive-access-token", accessToken);
|
|
79251
|
+
previewParts.push("--google-drive-access-token", "******");
|
|
79252
|
+
}
|
|
79253
|
+
if (wapkRun.googleDrive?.supportsAllDrives) {
|
|
79254
|
+
args.push("--google-drive-shared-drive");
|
|
79255
|
+
previewParts.push("--google-drive-shared-drive");
|
|
79256
|
+
}
|
|
79257
|
+
}
|
|
79258
|
+
function buildPmWapkPreview(wapk, runtime2, password, wapkRun) {
|
|
79259
|
+
const previewParts = ["elit", "wapk", "run", quoteCommandSegment(wapk)];
|
|
79260
|
+
if (runtime2) {
|
|
79261
|
+
previewParts.push("--runtime", runtime2);
|
|
79262
|
+
}
|
|
79263
|
+
if (password) {
|
|
79264
|
+
previewParts.push("--password", "******");
|
|
79265
|
+
}
|
|
79266
|
+
appendPmWapkRunArgs([], previewParts, wapkRun);
|
|
79267
|
+
return previewParts.join(" ");
|
|
79268
|
+
}
|
|
79269
|
+
function sanitizePmProcessName(name) {
|
|
79270
|
+
const sanitized = name.trim().toLowerCase().replace(/[<>:"/\\|?*\x00-\x1f]+/g, "-").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
79271
|
+
return sanitized.length > 0 ? sanitized : "process";
|
|
79272
|
+
}
|
|
79273
|
+
function isTypescriptFile(filePath) {
|
|
79274
|
+
const extension = (0, import_node_path5.extname)(filePath).toLowerCase();
|
|
79275
|
+
return extension === ".ts" || extension === ".mts" || extension === ".cts";
|
|
79276
|
+
}
|
|
79277
|
+
function normalizeStringArray(value) {
|
|
79278
|
+
if (!Array.isArray(value)) {
|
|
79279
|
+
return [];
|
|
79280
|
+
}
|
|
79281
|
+
return value.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
79282
|
+
}
|
|
79283
|
+
function toWatchGlob(candidatePath) {
|
|
79284
|
+
if (!(0, import_node_fs5.existsSync)(candidatePath)) {
|
|
79285
|
+
return candidatePath;
|
|
79286
|
+
}
|
|
79287
|
+
try {
|
|
79288
|
+
return (0, import_node_fs5.statSync)(candidatePath).isDirectory() ? (0, import_node_path5.join)(candidatePath, "**", "*").replace(/\\/g, "/") : candidatePath;
|
|
79289
|
+
} catch {
|
|
79290
|
+
return candidatePath;
|
|
79291
|
+
}
|
|
79292
|
+
}
|
|
79293
|
+
function normalizeWatchPatterns(paths, cwd) {
|
|
79294
|
+
return paths.map((entry) => (0, import_node_path5.resolve)(cwd, entry)).map(toWatchGlob).map((entry) => entry.replace(/\\/g, "/"));
|
|
79295
|
+
}
|
|
79296
|
+
function normalizeWatchIgnorePatterns(paths, cwd) {
|
|
79297
|
+
return paths.map((entry) => entry.trim()).filter((entry) => entry.length > 0).map((entry) => {
|
|
79298
|
+
if (entry.includes("*") || entry.includes("?")) {
|
|
79299
|
+
return entry.replace(/\\/g, "/");
|
|
79300
|
+
}
|
|
79301
|
+
const resolvedPath = (0, import_node_path5.resolve)(cwd, entry);
|
|
79302
|
+
return toWatchGlob(resolvedPath).replace(/\\/g, "/");
|
|
79303
|
+
});
|
|
79304
|
+
}
|
|
79305
|
+
function matchesGlobPattern(filePath, pattern) {
|
|
79306
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
79307
|
+
const normalizedPattern = pattern.replace(/\\/g, "/");
|
|
79308
|
+
const regexPattern = normalizedPattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
|
|
79309
|
+
return new RegExp(`^${regexPattern}$`).test(normalizedPath);
|
|
79310
|
+
}
|
|
79311
|
+
function isIgnoredWatchPath(filePath, patterns) {
|
|
79312
|
+
return patterns.some((pattern) => matchesGlobPattern(filePath, pattern));
|
|
79313
|
+
}
|
|
79314
|
+
function normalizeHealthCheckConfig(value) {
|
|
79315
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
79316
|
+
return void 0;
|
|
79317
|
+
}
|
|
79318
|
+
const config = value;
|
|
79319
|
+
if (typeof config.url !== "string" || config.url.trim().length === 0) {
|
|
79320
|
+
return void 0;
|
|
79321
|
+
}
|
|
79322
|
+
return {
|
|
79323
|
+
url: config.url.trim(),
|
|
79324
|
+
gracePeriod: typeof config.gracePeriod === "number" && Number.isFinite(config.gracePeriod) ? Math.max(0, Math.trunc(config.gracePeriod)) : DEFAULT_HEALTHCHECK_GRACE_PERIOD,
|
|
79325
|
+
interval: typeof config.interval === "number" && Number.isFinite(config.interval) ? Math.max(250, Math.trunc(config.interval)) : DEFAULT_HEALTHCHECK_INTERVAL,
|
|
79326
|
+
timeout: typeof config.timeout === "number" && Number.isFinite(config.timeout) ? Math.max(250, Math.trunc(config.timeout)) : DEFAULT_HEALTHCHECK_TIMEOUT,
|
|
79327
|
+
maxFailures: typeof config.maxFailures === "number" && Number.isFinite(config.maxFailures) ? Math.max(1, Math.trunc(config.maxFailures)) : DEFAULT_HEALTHCHECK_MAX_FAILURES
|
|
79328
|
+
};
|
|
79329
|
+
}
|
|
79330
|
+
function looksLikeManagedFile(value, cwd) {
|
|
79331
|
+
const normalized = value.trim();
|
|
79332
|
+
if (!normalized) {
|
|
79333
|
+
return false;
|
|
79334
|
+
}
|
|
79335
|
+
if (isRemoteWapkArchiveSpecifier(normalized)) {
|
|
79336
|
+
return false;
|
|
79337
|
+
}
|
|
79338
|
+
if (normalized.toLowerCase().endsWith(".wapk")) {
|
|
79339
|
+
return true;
|
|
79340
|
+
}
|
|
79341
|
+
const extension = (0, import_node_path5.extname)(normalized).toLowerCase();
|
|
79342
|
+
if (SUPPORTED_FILE_EXTENSIONS.has(extension)) {
|
|
79343
|
+
return true;
|
|
79344
|
+
}
|
|
79345
|
+
if (normalized.includes("/") || normalized.includes("\\") || normalized.startsWith(".")) {
|
|
79346
|
+
return (0, import_node_fs5.existsSync)((0, import_node_path5.resolve)(cwd, normalized));
|
|
79347
|
+
}
|
|
79348
|
+
return false;
|
|
79349
|
+
}
|
|
79350
|
+
function normalizeEnvMap(value) {
|
|
79351
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
79352
|
+
return {};
|
|
79353
|
+
}
|
|
79354
|
+
const normalized = {};
|
|
79355
|
+
for (const [key, entryValue] of Object.entries(value)) {
|
|
79356
|
+
if (typeof entryValue === "string") {
|
|
79357
|
+
normalized[key] = entryValue;
|
|
79358
|
+
continue;
|
|
79359
|
+
}
|
|
79360
|
+
if (typeof entryValue === "number" || typeof entryValue === "boolean") {
|
|
79361
|
+
normalized[key] = String(entryValue);
|
|
79362
|
+
}
|
|
79363
|
+
}
|
|
79364
|
+
return normalized;
|
|
79365
|
+
}
|
|
79366
|
+
function parsePmEnvEntry(input) {
|
|
79367
|
+
const separatorIndex = input.indexOf("=");
|
|
79368
|
+
if (separatorIndex <= 0) {
|
|
79369
|
+
throw new Error("--env expects KEY=VALUE");
|
|
79370
|
+
}
|
|
79371
|
+
const key = input.slice(0, separatorIndex).trim();
|
|
79372
|
+
const value = input.slice(separatorIndex + 1);
|
|
79373
|
+
if (!key) {
|
|
79374
|
+
throw new Error("--env expects KEY=VALUE");
|
|
79375
|
+
}
|
|
79376
|
+
return [key, value];
|
|
79377
|
+
}
|
|
79378
|
+
function readRequiredValue(args, index, optionName) {
|
|
79379
|
+
const value = args[index];
|
|
79380
|
+
if (value === void 0) {
|
|
79381
|
+
throw new Error(`${optionName} requires a value.`);
|
|
79382
|
+
}
|
|
79383
|
+
return value;
|
|
79384
|
+
}
|
|
79385
|
+
function parsePmTarget(parsed, workspaceRoot) {
|
|
79386
|
+
if (parsed.script) {
|
|
79387
|
+
return { script: parsed.script };
|
|
79388
|
+
}
|
|
79389
|
+
if (parsed.file) {
|
|
79390
|
+
return { file: parsed.file };
|
|
79391
|
+
}
|
|
79392
|
+
if (parsed.wapk) {
|
|
79393
|
+
return { wapk: parsed.wapk };
|
|
79394
|
+
}
|
|
79395
|
+
if (!parsed.targetToken) {
|
|
79396
|
+
return {};
|
|
79397
|
+
}
|
|
79398
|
+
if (isWapkArchiveSpecifier(parsed.targetToken)) {
|
|
79399
|
+
return { wapk: parsed.targetToken };
|
|
79400
|
+
}
|
|
79401
|
+
if (looksLikeManagedFile(parsed.targetToken, (0, import_node_path5.resolve)(workspaceRoot, parsed.cwd ?? "."))) {
|
|
79402
|
+
return { file: parsed.targetToken };
|
|
79403
|
+
}
|
|
79404
|
+
return { configName: parsed.targetToken };
|
|
79405
|
+
}
|
|
79406
|
+
function getConfiguredPmApps(config) {
|
|
79407
|
+
return Array.isArray(config?.pm?.apps) ? config.pm.apps : [];
|
|
79408
|
+
}
|
|
79409
|
+
function defaultProcessName(base, explicitName) {
|
|
79410
|
+
if (explicitName && explicitName.trim()) {
|
|
79411
|
+
return explicitName.trim();
|
|
79412
|
+
}
|
|
79413
|
+
if (base.file) {
|
|
79414
|
+
const fileName = (0, import_node_path5.basename)(base.file, (0, import_node_path5.extname)(base.file));
|
|
79415
|
+
return fileName || "process";
|
|
79416
|
+
}
|
|
79417
|
+
if (base.wapk) {
|
|
79418
|
+
const fileName = (0, import_node_path5.basename)(base.wapk, (0, import_node_path5.extname)(base.wapk));
|
|
79419
|
+
return fileName || "wapk-app";
|
|
79420
|
+
}
|
|
79421
|
+
if (base.script) {
|
|
79422
|
+
const candidate = base.script.trim().split(/\s+/).slice(0, 2).join("-");
|
|
79423
|
+
return candidate || "process";
|
|
79424
|
+
}
|
|
79425
|
+
return "process";
|
|
79426
|
+
}
|
|
79427
|
+
function countDefinedTargets(app) {
|
|
79428
|
+
return [app.script, app.file, app.wapk].filter(Boolean).length;
|
|
79429
|
+
}
|
|
79430
|
+
function resolvePmPaths(config, workspaceRoot) {
|
|
79431
|
+
const dataDir = (0, import_node_path5.resolve)(workspaceRoot, config?.dataDir ?? DEFAULT_PM_DATA_DIR);
|
|
79432
|
+
const dumpFile = config?.dumpFile ? (0, import_node_path5.resolve)(workspaceRoot, config.dumpFile) : (0, import_node_path5.join)(dataDir, DEFAULT_PM_DUMP_FILE);
|
|
79433
|
+
return {
|
|
79434
|
+
dataDir,
|
|
79435
|
+
appsDir: (0, import_node_path5.join)(dataDir, "apps"),
|
|
79436
|
+
logsDir: (0, import_node_path5.join)(dataDir, "logs"),
|
|
79437
|
+
dumpFile
|
|
79438
|
+
};
|
|
79439
|
+
}
|
|
79440
|
+
function ensurePmDirectories(paths) {
|
|
79441
|
+
(0, import_node_fs5.mkdirSync)(paths.dataDir, { recursive: true });
|
|
79442
|
+
(0, import_node_fs5.mkdirSync)(paths.appsDir, { recursive: true });
|
|
79443
|
+
(0, import_node_fs5.mkdirSync)(paths.logsDir, { recursive: true });
|
|
79444
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path5.dirname)(paths.dumpFile), { recursive: true });
|
|
79445
|
+
}
|
|
79446
|
+
function getPmRecordPath(paths, id) {
|
|
79447
|
+
return (0, import_node_path5.join)(paths.appsDir, `${id}${PM_RECORD_EXTENSION}`);
|
|
79448
|
+
}
|
|
79449
|
+
function readPmRecord(filePath) {
|
|
79450
|
+
return JSON.parse((0, import_node_fs5.readFileSync)(filePath, "utf8"));
|
|
79451
|
+
}
|
|
79452
|
+
function writePmRecord(filePath, record) {
|
|
79453
|
+
(0, import_node_fs5.writeFileSync)(filePath, JSON.stringify(record, null, 2));
|
|
79454
|
+
}
|
|
79455
|
+
function toSavedAppDefinition(record) {
|
|
79456
|
+
return {
|
|
79457
|
+
name: record.name,
|
|
79458
|
+
type: record.type,
|
|
79459
|
+
cwd: record.cwd,
|
|
79460
|
+
runtime: record.runtime,
|
|
79461
|
+
env: record.env,
|
|
79462
|
+
script: record.script,
|
|
79463
|
+
file: record.file,
|
|
79464
|
+
wapk: record.wapk,
|
|
79465
|
+
password: record.password,
|
|
79466
|
+
wapkRun: record.wapkRun,
|
|
79467
|
+
restartPolicy: record.restartPolicy,
|
|
79468
|
+
autorestart: record.autorestart,
|
|
79469
|
+
restartDelay: record.restartDelay,
|
|
79470
|
+
maxRestarts: record.maxRestarts,
|
|
79471
|
+
minUptime: record.minUptime,
|
|
79472
|
+
watch: record.watch,
|
|
79473
|
+
watchPaths: record.watchPaths,
|
|
79474
|
+
watchIgnore: record.watchIgnore,
|
|
79475
|
+
watchDebounce: record.watchDebounce,
|
|
79476
|
+
healthCheck: record.healthCheck
|
|
79477
|
+
};
|
|
79478
|
+
}
|
|
79479
|
+
function writePmDumpFile(filePath, apps) {
|
|
79480
|
+
const dump = {
|
|
79481
|
+
version: 1,
|
|
79482
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
79483
|
+
apps
|
|
79484
|
+
};
|
|
79485
|
+
(0, import_node_fs5.writeFileSync)(filePath, JSON.stringify(dump, null, 2));
|
|
79486
|
+
}
|
|
79487
|
+
function readPmDumpFile(filePath) {
|
|
79488
|
+
const parsed = JSON.parse((0, import_node_fs5.readFileSync)(filePath, "utf8"));
|
|
79489
|
+
if (parsed.version !== 1 || !Array.isArray(parsed.apps)) {
|
|
79490
|
+
throw new Error(`Invalid PM dump file: ${filePath}`);
|
|
79491
|
+
}
|
|
79492
|
+
return {
|
|
79493
|
+
version: 1,
|
|
79494
|
+
savedAt: typeof parsed.savedAt === "string" ? parsed.savedAt : (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
79495
|
+
apps: parsed.apps
|
|
79496
|
+
};
|
|
79497
|
+
}
|
|
79498
|
+
function deriveDefaultWatchPaths(type, cwd, file, wapk) {
|
|
79499
|
+
if (type === "file" && file) {
|
|
79500
|
+
return [file];
|
|
79501
|
+
}
|
|
79502
|
+
if (type === "wapk" && wapk) {
|
|
79503
|
+
return [isRemoteWapkArchiveSpecifier(wapk) ? cwd : wapk];
|
|
79504
|
+
}
|
|
79505
|
+
return [cwd];
|
|
79506
|
+
}
|
|
79507
|
+
function normalizeResolvedWatchPaths(paths, cwd, type, file, wapk) {
|
|
79508
|
+
const sourcePaths = paths.length > 0 ? paths : deriveDefaultWatchPaths(type, cwd, file, wapk);
|
|
79509
|
+
return normalizeWatchPatterns(sourcePaths, cwd);
|
|
79510
|
+
}
|
|
79511
|
+
function listPmRecordMatches(paths) {
|
|
79512
|
+
if (!(0, import_node_fs5.existsSync)(paths.appsDir)) {
|
|
79513
|
+
return [];
|
|
79514
|
+
}
|
|
79515
|
+
return (0, import_node_fs5.readdirSync)(paths.appsDir).filter((entry) => entry.endsWith(PM_RECORD_EXTENSION)).map((entry) => {
|
|
79516
|
+
const filePath = (0, import_node_path5.join)(paths.appsDir, entry);
|
|
79517
|
+
return {
|
|
79518
|
+
filePath,
|
|
79519
|
+
record: readPmRecord(filePath)
|
|
79520
|
+
};
|
|
79521
|
+
}).sort((left, right) => left.record.name.localeCompare(right.record.name));
|
|
79522
|
+
}
|
|
79523
|
+
function findPmRecordMatch(paths, nameOrId) {
|
|
79524
|
+
const directPath = getPmRecordPath(paths, sanitizePmProcessName(nameOrId));
|
|
79525
|
+
if ((0, import_node_fs5.existsSync)(directPath)) {
|
|
79526
|
+
return {
|
|
79527
|
+
filePath: directPath,
|
|
79528
|
+
record: readPmRecord(directPath)
|
|
79529
|
+
};
|
|
79530
|
+
}
|
|
79531
|
+
return listPmRecordMatches(paths).find((match) => match.record.name === nameOrId);
|
|
79532
|
+
}
|
|
79533
|
+
function isProcessAlive(pid) {
|
|
79534
|
+
if (!pid || pid <= 0) {
|
|
79535
|
+
return false;
|
|
79536
|
+
}
|
|
79537
|
+
try {
|
|
79538
|
+
process.kill(pid, 0);
|
|
79539
|
+
return true;
|
|
79540
|
+
} catch (error) {
|
|
79541
|
+
const code = error.code;
|
|
79542
|
+
return code === "EPERM";
|
|
79543
|
+
}
|
|
79544
|
+
}
|
|
79545
|
+
function syncPmRecordLiveness(match) {
|
|
79546
|
+
const { record } = match;
|
|
79547
|
+
if (record.desiredState === "running" && record.runnerPid && !isProcessAlive(record.runnerPid)) {
|
|
79548
|
+
const updated = {
|
|
79549
|
+
...record,
|
|
79550
|
+
status: record.status === "stopping" ? "stopped" : record.status === "errored" ? "errored" : "exited",
|
|
79551
|
+
runnerPid: void 0,
|
|
79552
|
+
childPid: void 0,
|
|
79553
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
79554
|
+
};
|
|
79555
|
+
writePmRecord(match.filePath, updated);
|
|
79556
|
+
return { ...match, record: updated };
|
|
79557
|
+
}
|
|
79558
|
+
if (record.childPid && !isProcessAlive(record.childPid)) {
|
|
79559
|
+
const updated = {
|
|
79560
|
+
...record,
|
|
79561
|
+
childPid: void 0,
|
|
79562
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
79563
|
+
};
|
|
79564
|
+
writePmRecord(match.filePath, updated);
|
|
79565
|
+
return { ...match, record: updated };
|
|
79566
|
+
}
|
|
79567
|
+
return match;
|
|
79568
|
+
}
|
|
79569
|
+
function readCurrentCliInvocation() {
|
|
79570
|
+
const cliEntry = process.argv[1];
|
|
79571
|
+
if (!cliEntry) {
|
|
79572
|
+
throw new Error("Unable to resolve the current Elit CLI entrypoint for pm runner startup.");
|
|
79573
|
+
}
|
|
79574
|
+
return {
|
|
79575
|
+
command: process.execPath,
|
|
79576
|
+
args: [...process.execArgv, cliEntry]
|
|
79577
|
+
};
|
|
79578
|
+
}
|
|
79579
|
+
function preferCurrentExecutable(runtime2) {
|
|
79580
|
+
const executableName = (0, import_node_path5.basename)(process.execPath).toLowerCase();
|
|
79581
|
+
if (runtime2 === "node" && process.release?.name === "node" && executableName.startsWith("node")) {
|
|
79582
|
+
return process.execPath;
|
|
79583
|
+
}
|
|
79584
|
+
if (runtime2 === "bun" && process.versions?.bun && executableName.startsWith("bun")) {
|
|
79585
|
+
return process.execPath;
|
|
79586
|
+
}
|
|
79587
|
+
return runtime2;
|
|
79588
|
+
}
|
|
79589
|
+
function commandExists2(command) {
|
|
79590
|
+
if (command.includes("\\") || command.includes("/")) {
|
|
79591
|
+
return (0, import_node_fs5.existsSync)(command);
|
|
79592
|
+
}
|
|
79593
|
+
const result2 = (0, import_node_child_process4.spawnSync)(command, ["--version"], {
|
|
79594
|
+
stdio: "ignore",
|
|
79595
|
+
windowsHide: true
|
|
79596
|
+
});
|
|
79597
|
+
return !result2.error;
|
|
79598
|
+
}
|
|
79599
|
+
function ensureCommandAvailable(command, displayName) {
|
|
79600
|
+
if (commandExists2(command)) {
|
|
79601
|
+
return;
|
|
79602
|
+
}
|
|
79603
|
+
throw new Error(`${displayName} was not found in PATH.`);
|
|
79604
|
+
}
|
|
79605
|
+
function resolveTsxExecutable(cwd) {
|
|
79606
|
+
const localPath = (0, import_node_path5.join)(cwd, "node_modules", ".bin", process.platform === "win32" ? "tsx.cmd" : "tsx");
|
|
79607
|
+
if ((0, import_node_fs5.existsSync)(localPath)) {
|
|
79608
|
+
return localPath;
|
|
79609
|
+
}
|
|
79610
|
+
const globalCommand = process.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
79611
|
+
return commandExists2(globalCommand) ? globalCommand : void 0;
|
|
79612
|
+
}
|
|
79613
|
+
function inferRuntimeFromFile(filePath) {
|
|
79614
|
+
if (isTypescriptFile(filePath) && commandExists2("bun")) {
|
|
79615
|
+
return "bun";
|
|
79616
|
+
}
|
|
79617
|
+
return "node";
|
|
79618
|
+
}
|
|
79619
|
+
var SIMPLE_PREVIEW_SEGMENT = /^[A-Za-z0-9_./:=+-]+$/;
|
|
79620
|
+
function quoteCommandSegment(value) {
|
|
79621
|
+
return SIMPLE_PREVIEW_SEGMENT.test(value) ? value : JSON.stringify(value);
|
|
79622
|
+
}
|
|
79623
|
+
function buildPmCommand(record) {
|
|
79624
|
+
if (record.type === "script") {
|
|
79625
|
+
return {
|
|
79626
|
+
command: record.script,
|
|
79627
|
+
args: [],
|
|
79628
|
+
shell: true,
|
|
79629
|
+
runtime: record.runtime,
|
|
79630
|
+
preview: record.script
|
|
79631
|
+
};
|
|
79632
|
+
}
|
|
79633
|
+
if (record.type === "wapk") {
|
|
79634
|
+
const cliInvocation = readCurrentCliInvocation();
|
|
79635
|
+
const args = [
|
|
79636
|
+
...cliInvocation.args,
|
|
79637
|
+
"wapk",
|
|
79638
|
+
"run",
|
|
79639
|
+
record.wapk
|
|
79640
|
+
];
|
|
79641
|
+
const previewParts = ["elit", "wapk", "run", quoteCommandSegment(record.wapk)];
|
|
79642
|
+
if (record.runtime) {
|
|
79643
|
+
args.push("--runtime", record.runtime);
|
|
79644
|
+
previewParts.push("--runtime", record.runtime);
|
|
79645
|
+
}
|
|
79646
|
+
if (record.password) {
|
|
79647
|
+
args.push("--password", record.password);
|
|
79648
|
+
previewParts.push("--password", "******");
|
|
79649
|
+
}
|
|
79650
|
+
appendPmWapkRunArgs(args, previewParts, record.wapkRun);
|
|
79651
|
+
return {
|
|
79652
|
+
command: cliInvocation.command,
|
|
79653
|
+
args,
|
|
79654
|
+
preview: previewParts.join(" "),
|
|
79655
|
+
runtime: record.runtime
|
|
79656
|
+
};
|
|
79657
|
+
}
|
|
79658
|
+
const runtime2 = record.runtime ?? inferRuntimeFromFile(record.file);
|
|
79659
|
+
if (runtime2 === "bun") {
|
|
79660
|
+
const executable2 = preferCurrentExecutable("bun");
|
|
79661
|
+
ensureCommandAvailable(executable2, "Bun runtime");
|
|
79662
|
+
return {
|
|
79663
|
+
command: executable2,
|
|
79664
|
+
args: ["run", record.file],
|
|
79665
|
+
runtime: runtime2,
|
|
79666
|
+
preview: `${(0, import_node_path5.basename)(executable2)} run ${quoteCommandSegment(record.file)}`
|
|
79667
|
+
};
|
|
79668
|
+
}
|
|
79669
|
+
if (runtime2 === "deno") {
|
|
79670
|
+
const executable2 = preferCurrentExecutable("deno");
|
|
79671
|
+
ensureCommandAvailable(executable2, "Deno runtime");
|
|
79672
|
+
return {
|
|
79673
|
+
command: executable2,
|
|
79674
|
+
args: ["run", "--allow-all", record.file],
|
|
79675
|
+
runtime: runtime2,
|
|
79676
|
+
preview: `${(0, import_node_path5.basename)(executable2)} run --allow-all ${quoteCommandSegment(record.file)}`
|
|
79677
|
+
};
|
|
79678
|
+
}
|
|
79679
|
+
if (isTypescriptFile(record.file)) {
|
|
79680
|
+
const tsxExecutable = resolveTsxExecutable(record.cwd);
|
|
79681
|
+
if (!tsxExecutable) {
|
|
79682
|
+
throw new Error('TypeScript file execution with runtime "node" requires tsx to be installed, or use --runtime bun.');
|
|
79683
|
+
}
|
|
79684
|
+
return {
|
|
79685
|
+
command: tsxExecutable,
|
|
79686
|
+
args: [record.file],
|
|
79687
|
+
runtime: runtime2,
|
|
79688
|
+
preview: `${(0, import_node_path5.basename)(tsxExecutable)} ${quoteCommandSegment(record.file)}`
|
|
79689
|
+
};
|
|
79690
|
+
}
|
|
79691
|
+
const executable = preferCurrentExecutable("node");
|
|
79692
|
+
ensureCommandAvailable(executable, "Node.js runtime");
|
|
79693
|
+
return {
|
|
79694
|
+
command: executable,
|
|
79695
|
+
args: [record.file],
|
|
79696
|
+
runtime: runtime2,
|
|
79697
|
+
preview: `${(0, import_node_path5.basename)(executable)} ${quoteCommandSegment(record.file)}`
|
|
79698
|
+
};
|
|
79699
|
+
}
|
|
79700
|
+
function createRecordFromDefinition(definition, paths, existing) {
|
|
79701
|
+
const id = sanitizePmProcessName(definition.name);
|
|
79702
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
79703
|
+
const preview = definition.type === "script" ? definition.script : definition.type === "wapk" ? buildPmWapkPreview(definition.wapk, definition.runtime, definition.password, definition.wapkRun) : `${definition.runtime ?? "auto"} ${quoteCommandSegment(definition.file)}`;
|
|
79704
|
+
return {
|
|
79705
|
+
id,
|
|
79706
|
+
name: definition.name,
|
|
79707
|
+
type: definition.type,
|
|
79708
|
+
source: definition.source,
|
|
79709
|
+
cwd: definition.cwd,
|
|
79710
|
+
runtime: definition.runtime,
|
|
79711
|
+
env: definition.env,
|
|
79712
|
+
script: definition.script,
|
|
79713
|
+
file: definition.file,
|
|
79714
|
+
wapk: definition.wapk,
|
|
79715
|
+
wapkRun: definition.wapkRun,
|
|
79716
|
+
autorestart: definition.autorestart,
|
|
79717
|
+
restartDelay: definition.restartDelay,
|
|
79718
|
+
maxRestarts: definition.maxRestarts,
|
|
79719
|
+
password: definition.password,
|
|
79720
|
+
restartPolicy: definition.restartPolicy,
|
|
79721
|
+
minUptime: definition.minUptime,
|
|
79722
|
+
watch: definition.watch,
|
|
79723
|
+
watchPaths: definition.watchPaths,
|
|
79724
|
+
watchIgnore: definition.watchIgnore,
|
|
79725
|
+
watchDebounce: definition.watchDebounce,
|
|
79726
|
+
healthCheck: definition.healthCheck,
|
|
79727
|
+
desiredState: "running",
|
|
79728
|
+
status: "starting",
|
|
79729
|
+
commandPreview: preview,
|
|
79730
|
+
createdAt: existing?.createdAt ?? now,
|
|
79731
|
+
updatedAt: now,
|
|
79732
|
+
startedAt: void 0,
|
|
79733
|
+
stoppedAt: void 0,
|
|
79734
|
+
runnerPid: void 0,
|
|
79735
|
+
childPid: void 0,
|
|
79736
|
+
restartCount: existing?.restartCount ?? 0,
|
|
79737
|
+
lastExitCode: existing?.lastExitCode,
|
|
79738
|
+
error: void 0,
|
|
79739
|
+
logFiles: existing?.logFiles ?? {
|
|
79740
|
+
out: (0, import_node_path5.join)(paths.logsDir, `${id}.out.log`),
|
|
79741
|
+
err: (0, import_node_path5.join)(paths.logsDir, `${id}.err.log`)
|
|
79742
|
+
}
|
|
79743
|
+
};
|
|
79744
|
+
}
|
|
79745
|
+
function terminateProcessTree(pid) {
|
|
79746
|
+
if (process.platform === "win32") {
|
|
79747
|
+
const result2 = (0, import_node_child_process4.spawnSync)("taskkill", ["/PID", String(pid), "/T", "/F"], {
|
|
79748
|
+
stdio: "ignore",
|
|
79749
|
+
windowsHide: true
|
|
79750
|
+
});
|
|
79751
|
+
if (result2.error && result2.error.code !== "ENOENT") {
|
|
79752
|
+
throw result2.error;
|
|
79753
|
+
}
|
|
79754
|
+
return;
|
|
79755
|
+
}
|
|
79756
|
+
try {
|
|
79757
|
+
process.kill(pid, "SIGTERM");
|
|
79758
|
+
} catch (error) {
|
|
79759
|
+
const code = error.code;
|
|
79760
|
+
if (code !== "ESRCH") {
|
|
79761
|
+
throw error;
|
|
79762
|
+
}
|
|
79763
|
+
}
|
|
79764
|
+
}
|
|
79765
|
+
async function startManagedProcess(definition, paths) {
|
|
79766
|
+
ensurePmDirectories(paths);
|
|
79767
|
+
const id = sanitizePmProcessName(definition.name);
|
|
79768
|
+
const recordPath = getPmRecordPath(paths, id);
|
|
79769
|
+
const existingMatch = (0, import_node_fs5.existsSync)(recordPath) ? syncPmRecordLiveness({ filePath: recordPath, record: readPmRecord(recordPath) }) : void 0;
|
|
79770
|
+
if (existingMatch?.record.runnerPid && isProcessAlive(existingMatch.record.runnerPid)) {
|
|
79771
|
+
throw new Error(`Process "${definition.name}" is already running.`);
|
|
79772
|
+
}
|
|
79773
|
+
const record = createRecordFromDefinition(definition, paths, existingMatch?.record);
|
|
79774
|
+
writePmRecord(recordPath, record);
|
|
79775
|
+
const cliInvocation = readCurrentCliInvocation();
|
|
79776
|
+
const runner = (0, import_node_child_process4.spawn)(cliInvocation.command, [
|
|
79777
|
+
...cliInvocation.args,
|
|
79778
|
+
"pm",
|
|
79779
|
+
"__run",
|
|
79780
|
+
"--data-dir",
|
|
79781
|
+
paths.dataDir,
|
|
79782
|
+
"--id",
|
|
79783
|
+
record.id
|
|
79784
|
+
], {
|
|
79785
|
+
cwd: definition.cwd,
|
|
79786
|
+
detached: true,
|
|
79787
|
+
stdio: "ignore",
|
|
79788
|
+
windowsHide: true,
|
|
79789
|
+
env: {
|
|
79790
|
+
...process.env,
|
|
79791
|
+
ELIT_PM_INTERNAL: "1"
|
|
79792
|
+
}
|
|
79793
|
+
});
|
|
79794
|
+
if (!runner.pid) {
|
|
79795
|
+
throw new Error(`Failed to start process runner for "${definition.name}".`);
|
|
79796
|
+
}
|
|
79797
|
+
runner.unref();
|
|
79798
|
+
const startedRecord = {
|
|
79799
|
+
...record,
|
|
79800
|
+
runnerPid: runner.pid,
|
|
79801
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
79802
|
+
};
|
|
79803
|
+
writePmRecord(recordPath, startedRecord);
|
|
79804
|
+
return startedRecord;
|
|
79805
|
+
}
|
|
79806
|
+
function readLatestPmRecord(filePath, fallback) {
|
|
79807
|
+
return (0, import_node_fs5.existsSync)(filePath) ? readPmRecord(filePath) : fallback;
|
|
79808
|
+
}
|
|
79809
|
+
function writePmLog(stream, message) {
|
|
79810
|
+
stream.write(`[elit pm] ${(/* @__PURE__ */ new Date()).toISOString()} ${message}${import_node_os2.EOL}`);
|
|
79811
|
+
}
|
|
79812
|
+
function waitForExit(code, signal) {
|
|
79813
|
+
if (typeof code === "number") {
|
|
79814
|
+
return code;
|
|
79815
|
+
}
|
|
79816
|
+
if (signal === "SIGINT" || signal === "SIGTERM") {
|
|
79817
|
+
return 0;
|
|
79818
|
+
}
|
|
79819
|
+
return 1;
|
|
79820
|
+
}
|
|
79821
|
+
async function delay(milliseconds) {
|
|
79822
|
+
await new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds));
|
|
79823
|
+
}
|
|
79824
|
+
async function waitForManagedChildExit(child) {
|
|
79825
|
+
return await new Promise((resolvePromise) => {
|
|
79826
|
+
let resolved = false;
|
|
79827
|
+
child.once("error", (error) => {
|
|
79828
|
+
if (resolved) {
|
|
79829
|
+
return;
|
|
79830
|
+
}
|
|
79831
|
+
resolved = true;
|
|
79832
|
+
resolvePromise({ code: 1, signal: null, error: error instanceof Error ? error.message : String(error) });
|
|
79833
|
+
});
|
|
79834
|
+
child.once("close", (code, signal) => {
|
|
79835
|
+
if (resolved) {
|
|
79836
|
+
return;
|
|
79837
|
+
}
|
|
79838
|
+
resolved = true;
|
|
79839
|
+
resolvePromise({ code, signal });
|
|
79840
|
+
});
|
|
79841
|
+
});
|
|
79842
|
+
}
|
|
79843
|
+
async function createPmWatchController(record, onChange, onError) {
|
|
79844
|
+
if (!record.watch || record.watchPaths.length === 0) {
|
|
79845
|
+
return {
|
|
79846
|
+
async close() {
|
|
79847
|
+
}
|
|
79848
|
+
};
|
|
79849
|
+
}
|
|
79850
|
+
const watcher = watch(record.watchPaths);
|
|
79851
|
+
let debounceTimer = null;
|
|
79852
|
+
const scheduleRestart = (filePath) => {
|
|
79853
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
79854
|
+
if (isIgnoredWatchPath(normalizedPath, record.watchIgnore)) {
|
|
79855
|
+
return;
|
|
79856
|
+
}
|
|
79857
|
+
if (debounceTimer) {
|
|
79858
|
+
clearTimeout(debounceTimer);
|
|
79859
|
+
}
|
|
79860
|
+
debounceTimer = setTimeout(() => {
|
|
79861
|
+
debounceTimer = null;
|
|
79862
|
+
onChange(normalizedPath);
|
|
79863
|
+
}, record.watchDebounce);
|
|
79864
|
+
debounceTimer.unref?.();
|
|
79865
|
+
};
|
|
79866
|
+
watcher.on("add", scheduleRestart);
|
|
79867
|
+
watcher.on("change", scheduleRestart);
|
|
79868
|
+
watcher.on("unlink", scheduleRestart);
|
|
79869
|
+
watcher.on("error", (error) => onError(error instanceof Error ? error.message : String(error)));
|
|
79870
|
+
return {
|
|
79871
|
+
async close() {
|
|
79872
|
+
if (debounceTimer) {
|
|
79873
|
+
clearTimeout(debounceTimer);
|
|
79874
|
+
debounceTimer = null;
|
|
79875
|
+
}
|
|
79876
|
+
await watcher.close();
|
|
79877
|
+
}
|
|
79878
|
+
};
|
|
79879
|
+
}
|
|
79880
|
+
function createPmHealthMonitor(record, onFailure, onLog) {
|
|
79881
|
+
if (!record.healthCheck) {
|
|
79882
|
+
return {
|
|
79883
|
+
stop() {
|
|
79884
|
+
}
|
|
79885
|
+
};
|
|
79886
|
+
}
|
|
79887
|
+
const healthCheck = record.healthCheck;
|
|
79888
|
+
let stopped = false;
|
|
79889
|
+
let timer = null;
|
|
79890
|
+
let initialDelay = null;
|
|
79891
|
+
let inFlight = false;
|
|
79892
|
+
let failureCount = 0;
|
|
79893
|
+
const runHealthCheck = async () => {
|
|
79894
|
+
if (stopped || inFlight) {
|
|
79895
|
+
return;
|
|
79896
|
+
}
|
|
79897
|
+
inFlight = true;
|
|
79898
|
+
const controller = new AbortController();
|
|
79899
|
+
const timeoutId = setTimeout(() => controller.abort(), healthCheck.timeout);
|
|
79900
|
+
timeoutId.unref?.();
|
|
79901
|
+
try {
|
|
79902
|
+
const response = await fetch(healthCheck.url, {
|
|
79903
|
+
method: "GET",
|
|
79904
|
+
signal: controller.signal
|
|
79905
|
+
});
|
|
79906
|
+
if (!response.ok) {
|
|
79907
|
+
throw new Error(`health check returned ${response.status}`);
|
|
79908
|
+
}
|
|
79909
|
+
failureCount = 0;
|
|
79910
|
+
} catch (error) {
|
|
79911
|
+
failureCount += 1;
|
|
79912
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
79913
|
+
onLog(`health check failed (${failureCount}/${healthCheck.maxFailures}): ${message}`);
|
|
79914
|
+
if (failureCount >= healthCheck.maxFailures) {
|
|
79915
|
+
stopped = true;
|
|
79916
|
+
onFailure(`health check failed ${failureCount} times: ${message}`);
|
|
79917
|
+
}
|
|
79918
|
+
} finally {
|
|
79919
|
+
clearTimeout(timeoutId);
|
|
79920
|
+
inFlight = false;
|
|
79921
|
+
}
|
|
79922
|
+
};
|
|
79923
|
+
initialDelay = setTimeout(() => {
|
|
79924
|
+
void runHealthCheck();
|
|
79925
|
+
timer = setInterval(() => {
|
|
79926
|
+
void runHealthCheck();
|
|
79927
|
+
}, healthCheck.interval);
|
|
79928
|
+
timer.unref?.();
|
|
79929
|
+
}, healthCheck.gracePeriod);
|
|
79930
|
+
initialDelay.unref?.();
|
|
79931
|
+
return {
|
|
79932
|
+
stop() {
|
|
79933
|
+
stopped = true;
|
|
79934
|
+
if (initialDelay) {
|
|
79935
|
+
clearTimeout(initialDelay);
|
|
79936
|
+
initialDelay = null;
|
|
79937
|
+
}
|
|
79938
|
+
if (timer) {
|
|
79939
|
+
clearInterval(timer);
|
|
79940
|
+
timer = null;
|
|
79941
|
+
}
|
|
79942
|
+
}
|
|
79943
|
+
};
|
|
79944
|
+
}
|
|
79945
|
+
function readPlannedRestartRequest(state) {
|
|
79946
|
+
return state.request;
|
|
79947
|
+
}
|
|
79948
|
+
async function runManagedProcessLoop(filePath, initialRecord) {
|
|
79949
|
+
let record = initialRecord;
|
|
79950
|
+
let activeChild = null;
|
|
79951
|
+
let stopRequested = false;
|
|
79952
|
+
const restartState = { request: null };
|
|
79953
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path5.dirname)(initialRecord.logFiles.out), { recursive: true });
|
|
79954
|
+
(0, import_node_fs5.mkdirSync)((0, import_node_path5.dirname)(initialRecord.logFiles.err), { recursive: true });
|
|
79955
|
+
const stdoutLog = (0, import_node_fs5.createWriteStream)(initialRecord.logFiles.out, { flags: "a" });
|
|
79956
|
+
const stderrLog = (0, import_node_fs5.createWriteStream)(initialRecord.logFiles.err, { flags: "a" });
|
|
79957
|
+
const persist = (mutator) => {
|
|
79958
|
+
const current = readLatestPmRecord(filePath, record);
|
|
79959
|
+
record = mutator(current);
|
|
79960
|
+
writePmRecord(filePath, record);
|
|
79961
|
+
return record;
|
|
79962
|
+
};
|
|
79963
|
+
const stopActiveChild = () => {
|
|
79964
|
+
if (activeChild?.pid && isProcessAlive(activeChild.pid)) {
|
|
79965
|
+
terminateProcessTree(activeChild.pid);
|
|
79966
|
+
}
|
|
79967
|
+
};
|
|
79968
|
+
const handleStopSignal = (signal) => {
|
|
79969
|
+
stopRequested = true;
|
|
79970
|
+
persist((current) => ({
|
|
79971
|
+
...current,
|
|
79972
|
+
desiredState: "stopped",
|
|
79973
|
+
status: "stopping",
|
|
79974
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
79975
|
+
}));
|
|
79976
|
+
writePmLog(stdoutLog, `received ${signal}, stopping managed process`);
|
|
79977
|
+
stopActiveChild();
|
|
79978
|
+
};
|
|
79979
|
+
process.on("SIGINT", handleStopSignal);
|
|
79980
|
+
process.on("SIGTERM", handleStopSignal);
|
|
79981
|
+
persist((current) => ({
|
|
79982
|
+
...current,
|
|
79983
|
+
runnerPid: process.pid,
|
|
79984
|
+
desiredState: "running",
|
|
79985
|
+
status: "starting",
|
|
79986
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
79987
|
+
}));
|
|
79988
|
+
try {
|
|
79989
|
+
while (!stopRequested) {
|
|
79990
|
+
restartState.request = null;
|
|
79991
|
+
const latest = readLatestPmRecord(filePath, record);
|
|
79992
|
+
if (latest.desiredState === "stopped") {
|
|
79993
|
+
break;
|
|
79994
|
+
}
|
|
79995
|
+
let command;
|
|
79996
|
+
try {
|
|
79997
|
+
command = buildPmCommand(latest);
|
|
79998
|
+
} catch (error) {
|
|
79999
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80000
|
+
writePmLog(stderrLog, message);
|
|
80001
|
+
persist((current2) => ({
|
|
80002
|
+
...current2,
|
|
80003
|
+
status: "errored",
|
|
80004
|
+
error: message,
|
|
80005
|
+
runnerPid: void 0,
|
|
80006
|
+
childPid: void 0,
|
|
80007
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80008
|
+
}));
|
|
80009
|
+
return;
|
|
80010
|
+
}
|
|
80011
|
+
const child = (0, import_node_child_process4.spawn)(command.command, command.args, {
|
|
80012
|
+
cwd: latest.cwd,
|
|
80013
|
+
env: {
|
|
80014
|
+
...process.env,
|
|
80015
|
+
...latest.env,
|
|
80016
|
+
ELIT_PM_NAME: latest.name,
|
|
80017
|
+
ELIT_PM_ID: latest.id
|
|
80018
|
+
},
|
|
80019
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
80020
|
+
windowsHide: true,
|
|
80021
|
+
shell: command.shell
|
|
80022
|
+
});
|
|
80023
|
+
const childStartedAt = Date.now();
|
|
80024
|
+
activeChild = child;
|
|
80025
|
+
if (child.stdout) {
|
|
80026
|
+
child.stdout.pipe(stdoutLog, { end: false });
|
|
80027
|
+
}
|
|
80028
|
+
if (child.stderr) {
|
|
80029
|
+
child.stderr.pipe(stderrLog, { end: false });
|
|
80030
|
+
}
|
|
80031
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
80032
|
+
persist((current2) => ({
|
|
80033
|
+
...current2,
|
|
80034
|
+
status: "online",
|
|
80035
|
+
commandPreview: command.preview,
|
|
80036
|
+
runtime: command.runtime ?? current2.runtime,
|
|
80037
|
+
runnerPid: process.pid,
|
|
80038
|
+
childPid: child.pid,
|
|
80039
|
+
startedAt,
|
|
80040
|
+
stoppedAt: void 0,
|
|
80041
|
+
error: void 0,
|
|
80042
|
+
updatedAt: startedAt
|
|
80043
|
+
}));
|
|
80044
|
+
writePmLog(stdoutLog, `started ${command.preview}${child.pid ? ` (pid ${child.pid})` : ""}`);
|
|
80045
|
+
const requestPlannedRestart = (kind, detail) => {
|
|
80046
|
+
if (stopRequested || restartState.request) {
|
|
80047
|
+
return;
|
|
80048
|
+
}
|
|
80049
|
+
restartState.request = { kind, detail };
|
|
80050
|
+
writePmLog(kind === "health" ? stderrLog : stdoutLog, `${kind} restart requested: ${detail}`);
|
|
80051
|
+
persist((current2) => ({
|
|
80052
|
+
...current2,
|
|
80053
|
+
status: "restarting",
|
|
80054
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80055
|
+
}));
|
|
80056
|
+
stopActiveChild();
|
|
80057
|
+
};
|
|
80058
|
+
const watchController = await createPmWatchController(
|
|
80059
|
+
latest,
|
|
80060
|
+
(changedPath) => requestPlannedRestart("watch", changedPath),
|
|
80061
|
+
(message) => writePmLog(stderrLog, `watch error: ${message}`)
|
|
80062
|
+
);
|
|
80063
|
+
const healthMonitor = createPmHealthMonitor(
|
|
80064
|
+
latest,
|
|
80065
|
+
(message) => requestPlannedRestart("health", message),
|
|
80066
|
+
(message) => writePmLog(stdoutLog, message)
|
|
80067
|
+
);
|
|
80068
|
+
const exitResult = await waitForManagedChildExit(child);
|
|
80069
|
+
await watchController.close();
|
|
80070
|
+
healthMonitor.stop();
|
|
80071
|
+
activeChild = null;
|
|
80072
|
+
const exitCode = waitForExit(exitResult.code, exitResult.signal);
|
|
80073
|
+
const current = readLatestPmRecord(filePath, record);
|
|
80074
|
+
const plannedRestart = readPlannedRestartRequest(restartState);
|
|
80075
|
+
const uptime = Math.max(0, Date.now() - childStartedAt);
|
|
80076
|
+
const wasStable = current.minUptime > 0 && uptime >= current.minUptime;
|
|
80077
|
+
if (exitResult.error) {
|
|
80078
|
+
writePmLog(stderrLog, exitResult.error);
|
|
80079
|
+
} else if (!plannedRestart) {
|
|
80080
|
+
writePmLog(stdoutLog, `process exited with code ${exitCode}`);
|
|
80081
|
+
}
|
|
80082
|
+
if (stopRequested || current.desiredState === "stopped") {
|
|
80083
|
+
break;
|
|
80084
|
+
}
|
|
80085
|
+
const shouldRestartForExit = plannedRestart ? true : current.restartPolicy === "always" ? true : current.restartPolicy === "on-failure" ? exitCode !== 0 || Boolean(exitResult.error) : false;
|
|
80086
|
+
if (!shouldRestartForExit) {
|
|
80087
|
+
persist((latestRecord) => ({
|
|
80088
|
+
...latestRecord,
|
|
80089
|
+
status: exitCode === 0 && !exitResult.error ? "exited" : "errored",
|
|
80090
|
+
childPid: void 0,
|
|
80091
|
+
runnerPid: void 0,
|
|
80092
|
+
lastExitCode: exitCode,
|
|
80093
|
+
error: exitCode === 0 && !exitResult.error ? void 0 : exitResult.error ?? `Process exited with code ${exitCode}.`,
|
|
80094
|
+
stoppedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80095
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80096
|
+
}));
|
|
80097
|
+
return;
|
|
80098
|
+
}
|
|
80099
|
+
const shouldCountRestart = plannedRestart?.kind !== "watch";
|
|
80100
|
+
const baseRestartCount = wasStable ? 0 : current.restartCount ?? 0;
|
|
80101
|
+
const nextRestartCount = shouldCountRestart ? baseRestartCount + 1 : current.restartCount ?? 0;
|
|
80102
|
+
if (nextRestartCount > current.maxRestarts) {
|
|
80103
|
+
persist((latestRecord) => ({
|
|
80104
|
+
...latestRecord,
|
|
80105
|
+
status: "errored",
|
|
80106
|
+
childPid: void 0,
|
|
80107
|
+
runnerPid: void 0,
|
|
80108
|
+
restartCount: nextRestartCount,
|
|
80109
|
+
lastExitCode: exitCode,
|
|
80110
|
+
error: plannedRestart ? `Reached max restart attempts (${current.maxRestarts}) after ${plannedRestart.kind} restart requests.` : `Reached max restart attempts (${current.maxRestarts}).`,
|
|
80111
|
+
stoppedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80112
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80113
|
+
}));
|
|
80114
|
+
writePmLog(stderrLog, `max restart attempts reached (${current.maxRestarts})`);
|
|
80115
|
+
return;
|
|
80116
|
+
}
|
|
80117
|
+
persist((latestRecord) => ({
|
|
80118
|
+
...latestRecord,
|
|
80119
|
+
status: "restarting",
|
|
80120
|
+
childPid: void 0,
|
|
80121
|
+
lastExitCode: exitCode,
|
|
80122
|
+
restartCount: nextRestartCount,
|
|
80123
|
+
error: void 0,
|
|
80124
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80125
|
+
}));
|
|
80126
|
+
if (plannedRestart) {
|
|
80127
|
+
writePmLog(
|
|
80128
|
+
plannedRestart.kind === "health" ? stderrLog : stdoutLog,
|
|
80129
|
+
`restarting in ${current.restartDelay}ms after ${plannedRestart.kind}: ${plannedRestart.detail}`
|
|
80130
|
+
);
|
|
80131
|
+
} else {
|
|
80132
|
+
writePmLog(stdoutLog, `restarting in ${current.restartDelay}ms`);
|
|
80133
|
+
}
|
|
80134
|
+
await delay(current.restartDelay);
|
|
80135
|
+
}
|
|
80136
|
+
} finally {
|
|
80137
|
+
stopRequested = true;
|
|
80138
|
+
stopActiveChild();
|
|
80139
|
+
const finalRecord = readLatestPmRecord(filePath, record);
|
|
80140
|
+
writePmRecord(filePath, {
|
|
80141
|
+
...finalRecord,
|
|
80142
|
+
desiredState: "stopped",
|
|
80143
|
+
status: finalRecord.status === "errored" ? "errored" : finalRecord.status === "exited" ? "exited" : "stopped",
|
|
80144
|
+
runnerPid: void 0,
|
|
80145
|
+
childPid: void 0,
|
|
80146
|
+
stoppedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80147
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80148
|
+
});
|
|
80149
|
+
process.off("SIGINT", handleStopSignal);
|
|
80150
|
+
process.off("SIGTERM", handleStopSignal);
|
|
80151
|
+
await new Promise((resolvePromise) => stdoutLog.end(resolvePromise));
|
|
80152
|
+
await new Promise((resolvePromise) => stderrLog.end(resolvePromise));
|
|
80153
|
+
}
|
|
80154
|
+
}
|
|
80155
|
+
function resolveStartSelection(configApps, parsed, workspaceRoot) {
|
|
80156
|
+
const target = parsePmTarget(parsed, workspaceRoot);
|
|
80157
|
+
const hasExplicitWapkSource = Boolean(resolvePmWapkSourceToken(parsed.wapk, parsed.wapkRun));
|
|
80158
|
+
const selectedName = target.configName ?? (!target.script && !target.file && !target.wapk && !hasExplicitWapkSource ? parsed.name : void 0);
|
|
80159
|
+
const selected = selectedName ? configApps.find((app) => app.name === selectedName) : void 0;
|
|
80160
|
+
return {
|
|
80161
|
+
selected,
|
|
80162
|
+
startAll: !target.script && !target.file && !target.wapk && !hasExplicitWapkSource && !selectedName,
|
|
80163
|
+
target
|
|
80164
|
+
};
|
|
80165
|
+
}
|
|
80166
|
+
function toPmAppConfig(record) {
|
|
80167
|
+
return {
|
|
80168
|
+
name: record.name,
|
|
80169
|
+
script: record.script,
|
|
80170
|
+
file: record.file,
|
|
80171
|
+
wapk: record.wapk,
|
|
80172
|
+
wapkRun: record.wapkRun,
|
|
80173
|
+
runtime: record.runtime,
|
|
80174
|
+
cwd: record.cwd,
|
|
80175
|
+
env: record.env,
|
|
80176
|
+
autorestart: record.autorestart,
|
|
80177
|
+
restartDelay: record.restartDelay,
|
|
80178
|
+
maxRestarts: record.maxRestarts,
|
|
80179
|
+
password: record.password,
|
|
80180
|
+
restartPolicy: record.restartPolicy,
|
|
80181
|
+
minUptime: record.minUptime,
|
|
80182
|
+
watch: record.watch,
|
|
80183
|
+
watchPaths: record.watchPaths,
|
|
80184
|
+
watchIgnore: record.watchIgnore,
|
|
80185
|
+
watchDebounce: record.watchDebounce,
|
|
80186
|
+
healthCheck: record.healthCheck
|
|
80187
|
+
};
|
|
80188
|
+
}
|
|
80189
|
+
function toSavedPmAppConfig(app) {
|
|
80190
|
+
return {
|
|
80191
|
+
name: app.name,
|
|
80192
|
+
script: app.script,
|
|
80193
|
+
file: app.file,
|
|
80194
|
+
wapk: app.wapk,
|
|
80195
|
+
wapkRun: app.wapkRun,
|
|
80196
|
+
runtime: app.runtime,
|
|
80197
|
+
cwd: app.cwd,
|
|
80198
|
+
env: app.env,
|
|
80199
|
+
autorestart: app.autorestart,
|
|
80200
|
+
restartDelay: app.restartDelay,
|
|
80201
|
+
maxRestarts: app.maxRestarts,
|
|
80202
|
+
password: app.password,
|
|
80203
|
+
restartPolicy: app.restartPolicy,
|
|
80204
|
+
minUptime: app.minUptime,
|
|
80205
|
+
watch: app.watch,
|
|
80206
|
+
watchPaths: app.watchPaths,
|
|
80207
|
+
watchIgnore: app.watchIgnore,
|
|
80208
|
+
watchDebounce: app.watchDebounce,
|
|
80209
|
+
healthCheck: app.healthCheck
|
|
80210
|
+
};
|
|
80211
|
+
}
|
|
80212
|
+
function resolvePmAppDefinition(base, parsed, workspaceRoot, source) {
|
|
80213
|
+
const target = parsePmTarget(parsed, workspaceRoot);
|
|
80214
|
+
const resolvedCwd = (0, import_node_path5.resolve)(workspaceRoot, parsed.cwd ?? base?.cwd ?? ".");
|
|
80215
|
+
if (countDefinedPmWapkSources(parsed.wapk, parsed.wapkRun) > 1) {
|
|
80216
|
+
throw new Error("Use only one WAPK archive source per pm start: --wapk or --google-drive-file-id.");
|
|
80217
|
+
}
|
|
80218
|
+
if (countDefinedPmWapkSources(base?.wapk, base?.wapkRun) > 1) {
|
|
80219
|
+
throw new Error(`Configured pm app "${base?.name ?? parsed.name ?? "app"}" must define only one WAPK archive source.`);
|
|
80220
|
+
}
|
|
80221
|
+
const explicitWapk = resolvePmWapkSource(resolvePmWapkSourceToken(target.wapk, parsed.wapkRun), resolvedCwd);
|
|
80222
|
+
const baseWapk = resolvePmWapkSource(resolvePmWapkSourceToken(base?.wapk, base?.wapkRun), resolvedCwd);
|
|
80223
|
+
const hasExplicitTarget = Boolean(target.script || target.file || explicitWapk);
|
|
80224
|
+
const script = target.script ?? (hasExplicitTarget ? void 0 : base?.script);
|
|
80225
|
+
const file = target.file ? (0, import_node_path5.resolve)(resolvedCwd, target.file) : hasExplicitTarget ? void 0 : base?.file ? (0, import_node_path5.resolve)(resolvedCwd, base.file) : void 0;
|
|
80226
|
+
const wapk = explicitWapk ?? (hasExplicitTarget ? void 0 : baseWapk);
|
|
80227
|
+
const targetCount = countDefinedTargets({ script, file, wapk });
|
|
80228
|
+
if (targetCount === 0) {
|
|
80229
|
+
throw new Error("pm start requires one target: --script, --file, --wapk, or a configured app name.");
|
|
80230
|
+
}
|
|
80231
|
+
if (targetCount > 1) {
|
|
80232
|
+
throw new Error("A pm app must define exactly one of script, file, or wapk.");
|
|
80233
|
+
}
|
|
80234
|
+
const name = defaultProcessName({ script, file, wapk }, parsed.name ?? base?.name);
|
|
80235
|
+
const mergedWapkRun = mergePmWapkRunConfig(base?.wapkRun, parsed.wapkRun);
|
|
80236
|
+
const runtime2 = normalizePmRuntime(parsed.runtime ?? mergedWapkRun?.runtime ?? base?.runtime, "--runtime");
|
|
80237
|
+
let restartPolicy = normalizePmRestartPolicy(parsed.restartPolicy ?? base?.restartPolicy, "--restart-policy") ?? (base?.autorestart ?? true ? "always" : "never");
|
|
80238
|
+
if (parsed.autorestart === false) {
|
|
80239
|
+
restartPolicy = "never";
|
|
80240
|
+
}
|
|
80241
|
+
const autorestart = restartPolicy !== "never";
|
|
80242
|
+
const watch4 = parsed.watch ?? base?.watch ?? false;
|
|
80243
|
+
const configuredWatchPaths = parsed.watchPaths.length > 0 ? parsed.watchPaths : normalizeStringArray(base?.watchPaths);
|
|
80244
|
+
const configuredWatchIgnore = [
|
|
80245
|
+
...DEFAULT_WATCH_IGNORE,
|
|
80246
|
+
...normalizeStringArray(base?.watchIgnore),
|
|
80247
|
+
...parsed.watchIgnore
|
|
80248
|
+
];
|
|
80249
|
+
const healthCheck = normalizeHealthCheckConfig(parsed.healthCheckUrl ? {
|
|
80250
|
+
url: parsed.healthCheckUrl,
|
|
80251
|
+
gracePeriod: parsed.healthCheckGracePeriod,
|
|
80252
|
+
interval: parsed.healthCheckInterval,
|
|
80253
|
+
timeout: parsed.healthCheckTimeout,
|
|
80254
|
+
maxFailures: parsed.healthCheckMaxFailures
|
|
80255
|
+
} : base?.healthCheck);
|
|
80256
|
+
const password = parsed.password ?? mergedWapkRun?.password ?? base?.password;
|
|
80257
|
+
const wapkRun = stripPmWapkSourceFromRunConfig(mergedWapkRun);
|
|
80258
|
+
if (password && !wapk) {
|
|
80259
|
+
throw new Error("--password is only supported when starting a WAPK app.");
|
|
80260
|
+
}
|
|
80261
|
+
if (wapkRun && !wapk) {
|
|
80262
|
+
throw new Error("WAPK run options are only supported when starting a WAPK app.");
|
|
80263
|
+
}
|
|
80264
|
+
return {
|
|
80265
|
+
name,
|
|
80266
|
+
type: script ? "script" : wapk ? "wapk" : "file",
|
|
80267
|
+
source,
|
|
80268
|
+
cwd: resolvedCwd,
|
|
80269
|
+
runtime: runtime2,
|
|
80270
|
+
env: {
|
|
80271
|
+
...normalizeEnvMap(base?.env),
|
|
80272
|
+
...parsed.env
|
|
80273
|
+
},
|
|
80274
|
+
script,
|
|
80275
|
+
file,
|
|
80276
|
+
wapk,
|
|
80277
|
+
wapkRun,
|
|
80278
|
+
autorestart,
|
|
80279
|
+
restartDelay: parsed.restartDelay ?? base?.restartDelay ?? DEFAULT_RESTART_DELAY,
|
|
80280
|
+
maxRestarts: parsed.maxRestarts ?? base?.maxRestarts ?? DEFAULT_MAX_RESTARTS,
|
|
80281
|
+
password,
|
|
80282
|
+
restartPolicy,
|
|
80283
|
+
minUptime: parsed.minUptime ?? base?.minUptime ?? DEFAULT_MIN_UPTIME,
|
|
80284
|
+
watch: watch4,
|
|
80285
|
+
watchPaths: watch4 ? normalizeResolvedWatchPaths(configuredWatchPaths, resolvedCwd, script ? "script" : wapk ? "wapk" : "file", file, wapk) : [],
|
|
80286
|
+
watchIgnore: watch4 ? normalizeWatchIgnorePatterns(configuredWatchIgnore, resolvedCwd) : [],
|
|
80287
|
+
watchDebounce: parsed.watchDebounce ?? base?.watchDebounce ?? DEFAULT_WATCH_DEBOUNCE,
|
|
80288
|
+
healthCheck
|
|
80289
|
+
};
|
|
80290
|
+
}
|
|
80291
|
+
function resolvePmStartDefinitions(parsed, config, workspaceRoot) {
|
|
80292
|
+
const configApps = getConfiguredPmApps(config);
|
|
80293
|
+
const selection = resolveStartSelection(configApps, parsed, workspaceRoot);
|
|
80294
|
+
if (selection.startAll) {
|
|
80295
|
+
if (configApps.length === 0) {
|
|
80296
|
+
throw new Error("No pm apps configured in elit.config.* and no start target was provided.");
|
|
80297
|
+
}
|
|
80298
|
+
return configApps.map((app) => resolvePmAppDefinition(app, { ...parsed, name: app.name }, workspaceRoot, "config"));
|
|
80299
|
+
}
|
|
80300
|
+
if (selection.selected) {
|
|
80301
|
+
return [resolvePmAppDefinition(selection.selected, parsed, workspaceRoot, "config")];
|
|
80302
|
+
}
|
|
80303
|
+
return [resolvePmAppDefinition(void 0, parsed, workspaceRoot, "cli")];
|
|
80304
|
+
}
|
|
80305
|
+
function parsePmStartArgs(args) {
|
|
80306
|
+
const parsed = {
|
|
80307
|
+
env: {},
|
|
80308
|
+
watchPaths: [],
|
|
80309
|
+
watchIgnore: []
|
|
80310
|
+
};
|
|
80311
|
+
for (let index = 0; index < args.length; index++) {
|
|
80312
|
+
const arg = args[index];
|
|
80313
|
+
switch (arg) {
|
|
80314
|
+
case "--script":
|
|
80315
|
+
parsed.script = readRequiredValue(args, ++index, "--script");
|
|
80316
|
+
break;
|
|
80317
|
+
case "--file":
|
|
80318
|
+
case "-f":
|
|
80319
|
+
parsed.file = readRequiredValue(args, ++index, arg);
|
|
80320
|
+
break;
|
|
80321
|
+
case "--wapk":
|
|
80322
|
+
parsed.wapk = readRequiredValue(args, ++index, "--wapk");
|
|
80323
|
+
break;
|
|
80324
|
+
case "--google-drive-file-id":
|
|
80325
|
+
parsed.wapkRun = {
|
|
80326
|
+
...parsed.wapkRun,
|
|
80327
|
+
googleDrive: {
|
|
80328
|
+
...parsed.wapkRun?.googleDrive,
|
|
80329
|
+
fileId: readRequiredValue(args, ++index, "--google-drive-file-id")
|
|
80330
|
+
}
|
|
80331
|
+
};
|
|
80332
|
+
break;
|
|
80333
|
+
case "--google-drive-token-env":
|
|
80334
|
+
parsed.wapkRun = {
|
|
80335
|
+
...parsed.wapkRun,
|
|
80336
|
+
googleDrive: {
|
|
80337
|
+
...parsed.wapkRun?.googleDrive,
|
|
80338
|
+
accessTokenEnv: readRequiredValue(args, ++index, "--google-drive-token-env")
|
|
80339
|
+
}
|
|
80340
|
+
};
|
|
80341
|
+
break;
|
|
80342
|
+
case "--google-drive-access-token":
|
|
80343
|
+
parsed.wapkRun = {
|
|
80344
|
+
...parsed.wapkRun,
|
|
80345
|
+
googleDrive: {
|
|
80346
|
+
...parsed.wapkRun?.googleDrive,
|
|
80347
|
+
accessToken: readRequiredValue(args, ++index, "--google-drive-access-token")
|
|
80348
|
+
}
|
|
80349
|
+
};
|
|
80350
|
+
break;
|
|
80351
|
+
case "--google-drive-shared-drive":
|
|
80352
|
+
parsed.wapkRun = {
|
|
80353
|
+
...parsed.wapkRun,
|
|
80354
|
+
googleDrive: {
|
|
80355
|
+
...parsed.wapkRun?.googleDrive,
|
|
80356
|
+
supportsAllDrives: true
|
|
80357
|
+
}
|
|
80358
|
+
};
|
|
80359
|
+
break;
|
|
80360
|
+
case "--runtime":
|
|
80361
|
+
case "-r":
|
|
80362
|
+
parsed.runtime = normalizePmRuntime(readRequiredValue(args, ++index, arg), arg);
|
|
80363
|
+
break;
|
|
80364
|
+
case "--name":
|
|
80365
|
+
case "-n":
|
|
80366
|
+
parsed.name = readRequiredValue(args, ++index, arg);
|
|
80367
|
+
break;
|
|
80368
|
+
case "--cwd":
|
|
80369
|
+
parsed.cwd = readRequiredValue(args, ++index, "--cwd");
|
|
80370
|
+
break;
|
|
80371
|
+
case "--env": {
|
|
80372
|
+
const [key, value] = parsePmEnvEntry(readRequiredValue(args, ++index, "--env"));
|
|
80373
|
+
parsed.env[key] = value;
|
|
80374
|
+
break;
|
|
80375
|
+
}
|
|
80376
|
+
case "--password":
|
|
80377
|
+
parsed.password = readRequiredValue(args, ++index, "--password");
|
|
80378
|
+
break;
|
|
80379
|
+
case "--sync-interval":
|
|
80380
|
+
parsed.wapkRun = {
|
|
80381
|
+
...parsed.wapkRun,
|
|
80382
|
+
syncInterval: normalizeIntegerOption(readRequiredValue(args, ++index, "--sync-interval"), "--sync-interval", 50)
|
|
80383
|
+
};
|
|
80384
|
+
break;
|
|
80385
|
+
case "--watcher":
|
|
80386
|
+
case "--use-watcher":
|
|
80387
|
+
parsed.wapkRun = {
|
|
80388
|
+
...parsed.wapkRun,
|
|
80389
|
+
useWatcher: true
|
|
80390
|
+
};
|
|
80391
|
+
break;
|
|
80392
|
+
case "--archive-watch":
|
|
80393
|
+
parsed.wapkRun = {
|
|
80394
|
+
...parsed.wapkRun,
|
|
80395
|
+
watchArchive: true
|
|
80396
|
+
};
|
|
80397
|
+
break;
|
|
80398
|
+
case "--no-archive-watch":
|
|
80399
|
+
parsed.wapkRun = {
|
|
80400
|
+
...parsed.wapkRun,
|
|
80401
|
+
watchArchive: false
|
|
80402
|
+
};
|
|
80403
|
+
break;
|
|
80404
|
+
case "--archive-sync-interval":
|
|
80405
|
+
parsed.wapkRun = {
|
|
80406
|
+
...parsed.wapkRun,
|
|
80407
|
+
archiveSyncInterval: normalizeIntegerOption(readRequiredValue(args, ++index, "--archive-sync-interval"), "--archive-sync-interval", 50)
|
|
80408
|
+
};
|
|
80409
|
+
break;
|
|
80410
|
+
case "--restart-policy":
|
|
80411
|
+
parsed.restartPolicy = normalizePmRestartPolicy(readRequiredValue(args, ++index, "--restart-policy"));
|
|
80412
|
+
break;
|
|
80413
|
+
case "--min-uptime":
|
|
80414
|
+
parsed.minUptime = normalizeIntegerOption(readRequiredValue(args, ++index, "--min-uptime"), "--min-uptime");
|
|
80415
|
+
break;
|
|
80416
|
+
case "--watch":
|
|
80417
|
+
parsed.watch = true;
|
|
80418
|
+
break;
|
|
80419
|
+
case "--watch-path":
|
|
80420
|
+
parsed.watch = true;
|
|
80421
|
+
parsed.watchPaths.push(readRequiredValue(args, ++index, "--watch-path"));
|
|
80422
|
+
break;
|
|
80423
|
+
case "--watch-ignore":
|
|
80424
|
+
parsed.watch = true;
|
|
80425
|
+
parsed.watchIgnore.push(readRequiredValue(args, ++index, "--watch-ignore"));
|
|
80426
|
+
break;
|
|
80427
|
+
case "--watch-debounce":
|
|
80428
|
+
parsed.watch = true;
|
|
80429
|
+
parsed.watchDebounce = normalizeIntegerOption(readRequiredValue(args, ++index, "--watch-debounce"), "--watch-debounce");
|
|
80430
|
+
break;
|
|
80431
|
+
case "--health-url":
|
|
80432
|
+
parsed.healthCheckUrl = readRequiredValue(args, ++index, "--health-url");
|
|
80433
|
+
break;
|
|
80434
|
+
case "--health-grace-period":
|
|
80435
|
+
parsed.healthCheckGracePeriod = normalizeIntegerOption(readRequiredValue(args, ++index, "--health-grace-period"), "--health-grace-period");
|
|
80436
|
+
break;
|
|
80437
|
+
case "--health-interval":
|
|
80438
|
+
parsed.healthCheckInterval = normalizeIntegerOption(readRequiredValue(args, ++index, "--health-interval"), "--health-interval", 250);
|
|
80439
|
+
break;
|
|
80440
|
+
case "--health-timeout":
|
|
80441
|
+
parsed.healthCheckTimeout = normalizeIntegerOption(readRequiredValue(args, ++index, "--health-timeout"), "--health-timeout", 250);
|
|
80442
|
+
break;
|
|
80443
|
+
case "--health-max-failures":
|
|
80444
|
+
parsed.healthCheckMaxFailures = normalizeIntegerOption(readRequiredValue(args, ++index, "--health-max-failures"), "--health-max-failures", 1);
|
|
80445
|
+
break;
|
|
80446
|
+
case "--no-autorestart":
|
|
80447
|
+
parsed.autorestart = false;
|
|
80448
|
+
break;
|
|
80449
|
+
case "--restart-delay":
|
|
80450
|
+
parsed.restartDelay = normalizeIntegerOption(readRequiredValue(args, ++index, "--restart-delay"), "--restart-delay");
|
|
80451
|
+
break;
|
|
80452
|
+
case "--max-restarts":
|
|
80453
|
+
parsed.maxRestarts = normalizeIntegerOption(readRequiredValue(args, ++index, "--max-restarts"), "--max-restarts");
|
|
80454
|
+
break;
|
|
80455
|
+
default:
|
|
80456
|
+
if (arg.startsWith("-")) {
|
|
80457
|
+
throw new Error(`Unknown pm option: ${arg}`);
|
|
80458
|
+
}
|
|
80459
|
+
if (parsed.targetToken) {
|
|
80460
|
+
throw new Error("pm start accepts at most one positional target.");
|
|
80461
|
+
}
|
|
80462
|
+
parsed.targetToken = arg;
|
|
80463
|
+
break;
|
|
80464
|
+
}
|
|
80465
|
+
}
|
|
80466
|
+
if (countDefinedPmWapkSources(parsed.wapk, parsed.wapkRun) > 1) {
|
|
80467
|
+
throw new Error("Use only one WAPK archive source per pm start: --wapk or --google-drive-file-id.");
|
|
80468
|
+
}
|
|
80469
|
+
const explicitTargets = [parsed.script, parsed.file, resolvePmWapkSourceToken(parsed.wapk, parsed.wapkRun)].filter(Boolean);
|
|
80470
|
+
if (explicitTargets.length > 1) {
|
|
80471
|
+
throw new Error("Use only one target type per pm start: --script, --file, or --wapk.");
|
|
80472
|
+
}
|
|
80473
|
+
if (parsed.healthCheckUrl && !/^https?:\/\//i.test(parsed.healthCheckUrl)) {
|
|
80474
|
+
throw new Error("--health-url must be an absolute http:// or https:// URL");
|
|
80475
|
+
}
|
|
80476
|
+
return parsed;
|
|
80477
|
+
}
|
|
80478
|
+
function padCell(value, width) {
|
|
80479
|
+
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
80480
|
+
}
|
|
80481
|
+
function tailLogFile(filePath, lineCount) {
|
|
80482
|
+
if (!(0, import_node_fs5.existsSync)(filePath)) {
|
|
80483
|
+
return "";
|
|
80484
|
+
}
|
|
80485
|
+
const lines = (0, import_node_fs5.readFileSync)(filePath, "utf8").split(/\r?\n/).filter((line) => line.length > 0);
|
|
80486
|
+
return lines.slice(-lineCount).join(import_node_os2.EOL);
|
|
80487
|
+
}
|
|
80488
|
+
function parseRunnerArgs(args) {
|
|
80489
|
+
let dataDir;
|
|
80490
|
+
let id;
|
|
80491
|
+
for (let index = 0; index < args.length; index++) {
|
|
80492
|
+
const arg = args[index];
|
|
80493
|
+
switch (arg) {
|
|
80494
|
+
case "--data-dir":
|
|
80495
|
+
dataDir = readRequiredValue(args, ++index, "--data-dir");
|
|
80496
|
+
break;
|
|
80497
|
+
case "--id":
|
|
80498
|
+
id = readRequiredValue(args, ++index, "--id");
|
|
80499
|
+
break;
|
|
80500
|
+
default:
|
|
80501
|
+
throw new Error(`Unknown internal pm runner option: ${arg}`);
|
|
80502
|
+
}
|
|
80503
|
+
}
|
|
80504
|
+
if (!dataDir || !id) {
|
|
80505
|
+
throw new Error("Usage: elit pm __run --data-dir <dir> --id <name>");
|
|
80506
|
+
}
|
|
80507
|
+
return {
|
|
80508
|
+
dataDir: (0, import_node_path5.resolve)(dataDir),
|
|
80509
|
+
id
|
|
80510
|
+
};
|
|
80511
|
+
}
|
|
80512
|
+
async function runPmRunner(args) {
|
|
80513
|
+
const options = parseRunnerArgs(args);
|
|
80514
|
+
const paths = {
|
|
80515
|
+
dataDir: options.dataDir,
|
|
80516
|
+
appsDir: (0, import_node_path5.join)(options.dataDir, "apps"),
|
|
80517
|
+
logsDir: (0, import_node_path5.join)(options.dataDir, "logs"),
|
|
80518
|
+
dumpFile: (0, import_node_path5.join)(options.dataDir, DEFAULT_PM_DUMP_FILE)
|
|
80519
|
+
};
|
|
80520
|
+
const match = findPmRecordMatch(paths, options.id);
|
|
80521
|
+
if (!match) {
|
|
80522
|
+
throw new Error(`PM record not found: ${options.id}`);
|
|
80523
|
+
}
|
|
80524
|
+
await runManagedProcessLoop(match.filePath, match.record);
|
|
80525
|
+
}
|
|
80526
|
+
async function runPmStart(args) {
|
|
80527
|
+
const parsed = parsePmStartArgs(args);
|
|
80528
|
+
const workspaceRoot = process.cwd();
|
|
80529
|
+
const config = await loadConfig(workspaceRoot);
|
|
80530
|
+
const paths = resolvePmPaths(config?.pm, workspaceRoot);
|
|
80531
|
+
const definitions = resolvePmStartDefinitions(parsed, config, workspaceRoot);
|
|
80532
|
+
const errors = [];
|
|
80533
|
+
for (const definition of definitions) {
|
|
80534
|
+
try {
|
|
80535
|
+
const record = await startManagedProcess(definition, paths);
|
|
80536
|
+
console.log(`[pm] started ${record.name} (${record.type})`);
|
|
80537
|
+
} catch (error) {
|
|
80538
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80539
|
+
errors.push(`[pm] ${definition.name}: ${message}`);
|
|
80540
|
+
}
|
|
80541
|
+
}
|
|
80542
|
+
if (errors.length > 0) {
|
|
80543
|
+
throw new Error(errors.join(import_node_os2.EOL));
|
|
80544
|
+
}
|
|
80545
|
+
}
|
|
80546
|
+
async function loadPmContext() {
|
|
80547
|
+
const workspaceRoot = process.cwd();
|
|
80548
|
+
const config = await loadConfig(workspaceRoot);
|
|
80549
|
+
return {
|
|
80550
|
+
config,
|
|
80551
|
+
paths: resolvePmPaths(config?.pm, workspaceRoot)
|
|
80552
|
+
};
|
|
80553
|
+
}
|
|
80554
|
+
function resolveNamedMatches(paths, value) {
|
|
80555
|
+
if (value === "all") {
|
|
80556
|
+
return listPmRecordMatches(paths).map(syncPmRecordLiveness);
|
|
80557
|
+
}
|
|
80558
|
+
const match = findPmRecordMatch(paths, value);
|
|
80559
|
+
return match ? [syncPmRecordLiveness(match)] : [];
|
|
80560
|
+
}
|
|
80561
|
+
function printPmList(paths) {
|
|
80562
|
+
const matches2 = listPmRecordMatches(paths).map(syncPmRecordLiveness);
|
|
80563
|
+
if (matches2.length === 0) {
|
|
80564
|
+
console.log("No managed processes found.");
|
|
80565
|
+
return;
|
|
80566
|
+
}
|
|
80567
|
+
const headers = [
|
|
80568
|
+
padCell("name", 20),
|
|
80569
|
+
padCell("status", 12),
|
|
80570
|
+
padCell("pid", 8),
|
|
80571
|
+
padCell("restarts", 10),
|
|
80572
|
+
padCell("type", 8),
|
|
80573
|
+
"runtime"
|
|
80574
|
+
];
|
|
80575
|
+
console.log(headers.join(" "));
|
|
80576
|
+
for (const { record } of matches2) {
|
|
80577
|
+
console.log([
|
|
80578
|
+
padCell(record.name, 20),
|
|
80579
|
+
padCell(record.status, 12),
|
|
80580
|
+
padCell(record.childPid ? String(record.childPid) : "-", 8),
|
|
80581
|
+
padCell(String(record.restartCount ?? 0), 10),
|
|
80582
|
+
padCell(record.type, 8),
|
|
80583
|
+
record.runtime ?? "-"
|
|
80584
|
+
].join(" "));
|
|
80585
|
+
}
|
|
80586
|
+
}
|
|
80587
|
+
function stopPmMatches(matches2) {
|
|
80588
|
+
let stopped = 0;
|
|
80589
|
+
for (const match of matches2) {
|
|
80590
|
+
const current = syncPmRecordLiveness(match);
|
|
80591
|
+
const updated = {
|
|
80592
|
+
...current.record,
|
|
80593
|
+
desiredState: "stopped",
|
|
80594
|
+
status: current.record.runnerPid ? "stopping" : "stopped",
|
|
80595
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80596
|
+
stoppedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80597
|
+
};
|
|
80598
|
+
writePmRecord(current.filePath, updated);
|
|
80599
|
+
if (current.record.runnerPid && isProcessAlive(current.record.runnerPid)) {
|
|
80600
|
+
terminateProcessTree(current.record.runnerPid);
|
|
80601
|
+
} else if (current.record.childPid && isProcessAlive(current.record.childPid)) {
|
|
80602
|
+
terminateProcessTree(current.record.childPid);
|
|
80603
|
+
}
|
|
80604
|
+
writePmRecord(current.filePath, {
|
|
80605
|
+
...updated,
|
|
80606
|
+
runnerPid: void 0,
|
|
80607
|
+
childPid: void 0,
|
|
80608
|
+
status: "stopped",
|
|
80609
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
80610
|
+
});
|
|
80611
|
+
stopped += 1;
|
|
80612
|
+
}
|
|
80613
|
+
return stopped;
|
|
80614
|
+
}
|
|
80615
|
+
async function runPmStop(args) {
|
|
80616
|
+
const target = args[0];
|
|
80617
|
+
if (!target) {
|
|
80618
|
+
throw new Error("Usage: elit pm stop <name|all>");
|
|
80619
|
+
}
|
|
80620
|
+
const { paths } = await loadPmContext();
|
|
80621
|
+
const matches2 = resolveNamedMatches(paths, target);
|
|
80622
|
+
if (matches2.length === 0) {
|
|
80623
|
+
throw new Error(`No managed process found for: ${target}`);
|
|
80624
|
+
}
|
|
80625
|
+
const count = stopPmMatches(matches2);
|
|
80626
|
+
console.log(`[pm] stopped ${count} process${count === 1 ? "" : "es"}`);
|
|
80627
|
+
}
|
|
80628
|
+
async function runPmRestart(args) {
|
|
80629
|
+
const target = args[0];
|
|
80630
|
+
if (!target) {
|
|
80631
|
+
throw new Error("Usage: elit pm restart <name|all>");
|
|
80632
|
+
}
|
|
80633
|
+
const { paths } = await loadPmContext();
|
|
80634
|
+
const matches2 = resolveNamedMatches(paths, target);
|
|
80635
|
+
if (matches2.length === 0) {
|
|
80636
|
+
throw new Error(`No managed process found for: ${target}`);
|
|
80637
|
+
}
|
|
80638
|
+
stopPmMatches(matches2);
|
|
80639
|
+
const restarted = [];
|
|
80640
|
+
for (const match of matches2) {
|
|
80641
|
+
const definition = resolvePmAppDefinition(
|
|
80642
|
+
toPmAppConfig(match.record),
|
|
80643
|
+
{ name: match.record.name, env: {}, watchPaths: [], watchIgnore: [] },
|
|
80644
|
+
process.cwd(),
|
|
80645
|
+
match.record.source
|
|
80646
|
+
);
|
|
80647
|
+
await startManagedProcess(definition, paths);
|
|
80648
|
+
restarted.push(match.record.name);
|
|
80649
|
+
}
|
|
80650
|
+
console.log(`[pm] restarted ${restarted.join(", ")}`);
|
|
80651
|
+
}
|
|
80652
|
+
async function runPmSave() {
|
|
80653
|
+
const { paths } = await loadPmContext();
|
|
80654
|
+
ensurePmDirectories(paths);
|
|
80655
|
+
const runningApps = listPmRecordMatches(paths).map(syncPmRecordLiveness).filter((match) => match.record.desiredState === "running" && (match.record.status === "starting" || match.record.status === "online" || match.record.status === "restarting")).map((match) => toSavedAppDefinition(match.record));
|
|
80656
|
+
writePmDumpFile(paths.dumpFile, runningApps);
|
|
80657
|
+
console.log(`[pm] saved ${runningApps.length} process${runningApps.length === 1 ? "" : "es"} to ${paths.dumpFile}`);
|
|
80658
|
+
}
|
|
80659
|
+
async function runPmResurrect() {
|
|
80660
|
+
const { paths } = await loadPmContext();
|
|
80661
|
+
if (!(0, import_node_fs5.existsSync)(paths.dumpFile)) {
|
|
80662
|
+
throw new Error(`PM dump file not found: ${paths.dumpFile}`);
|
|
80663
|
+
}
|
|
80664
|
+
const dump = readPmDumpFile(paths.dumpFile);
|
|
80665
|
+
if (dump.apps.length === 0) {
|
|
80666
|
+
console.log("[pm] dump file is empty, nothing to resurrect");
|
|
80667
|
+
return;
|
|
80668
|
+
}
|
|
80669
|
+
const errors = [];
|
|
80670
|
+
let restored = 0;
|
|
80671
|
+
for (const app of dump.apps) {
|
|
80672
|
+
try {
|
|
80673
|
+
const definition = resolvePmAppDefinition(
|
|
80674
|
+
toSavedPmAppConfig(app),
|
|
80675
|
+
{ name: app.name, env: {}, watchPaths: [], watchIgnore: [] },
|
|
80676
|
+
process.cwd(),
|
|
80677
|
+
"cli"
|
|
80678
|
+
);
|
|
80679
|
+
await startManagedProcess(definition, paths);
|
|
80680
|
+
restored += 1;
|
|
80681
|
+
} catch (error) {
|
|
80682
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80683
|
+
errors.push(`[pm] ${app.name}: ${message}`);
|
|
80684
|
+
}
|
|
80685
|
+
}
|
|
80686
|
+
if (errors.length > 0) {
|
|
80687
|
+
throw new Error([`[pm] resurrected ${restored} process${restored === 1 ? "" : "es"}`, ...errors].join(import_node_os2.EOL));
|
|
80688
|
+
}
|
|
80689
|
+
console.log(`[pm] resurrected ${restored} process${restored === 1 ? "" : "es"} from ${paths.dumpFile}`);
|
|
80690
|
+
}
|
|
80691
|
+
async function runPmDelete(args) {
|
|
80692
|
+
const target = args[0];
|
|
80693
|
+
if (!target) {
|
|
80694
|
+
throw new Error("Usage: elit pm delete <name|all>");
|
|
80695
|
+
}
|
|
80696
|
+
const { paths } = await loadPmContext();
|
|
80697
|
+
const matches2 = resolveNamedMatches(paths, target);
|
|
80698
|
+
if (matches2.length === 0) {
|
|
80699
|
+
throw new Error(`No managed process found for: ${target}`);
|
|
80700
|
+
}
|
|
80701
|
+
stopPmMatches(matches2);
|
|
80702
|
+
for (const match of matches2) {
|
|
80703
|
+
if ((0, import_node_fs5.existsSync)(match.record.logFiles.out)) {
|
|
80704
|
+
(0, import_node_fs5.rmSync)(match.record.logFiles.out, { force: true });
|
|
80705
|
+
}
|
|
80706
|
+
if ((0, import_node_fs5.existsSync)(match.record.logFiles.err)) {
|
|
80707
|
+
(0, import_node_fs5.rmSync)(match.record.logFiles.err, { force: true });
|
|
80708
|
+
}
|
|
80709
|
+
(0, import_node_fs5.rmSync)(match.filePath, { force: true });
|
|
80710
|
+
}
|
|
80711
|
+
console.log(`[pm] deleted ${matches2.length} process${matches2.length === 1 ? "" : "es"}`);
|
|
80712
|
+
}
|
|
80713
|
+
async function runPmLogs(args) {
|
|
80714
|
+
if (args.length === 0) {
|
|
80715
|
+
throw new Error("Usage: elit pm logs <name> [--lines <n>] [--stderr]");
|
|
80716
|
+
}
|
|
80717
|
+
let name;
|
|
80718
|
+
let lineCount = DEFAULT_LOG_LINES;
|
|
80719
|
+
let stderrOnly = false;
|
|
80720
|
+
for (let index = 0; index < args.length; index++) {
|
|
80721
|
+
const arg = args[index];
|
|
80722
|
+
switch (arg) {
|
|
80723
|
+
case "--lines":
|
|
80724
|
+
lineCount = normalizeIntegerOption(readRequiredValue(args, ++index, "--lines"), "--lines", 1);
|
|
80725
|
+
break;
|
|
80726
|
+
case "--stderr":
|
|
80727
|
+
stderrOnly = true;
|
|
80728
|
+
break;
|
|
80729
|
+
default:
|
|
80730
|
+
if (arg.startsWith("-")) {
|
|
80731
|
+
throw new Error(`Unknown pm logs option: ${arg}`);
|
|
80732
|
+
}
|
|
80733
|
+
if (name) {
|
|
80734
|
+
throw new Error("pm logs accepts exactly one process name.");
|
|
80735
|
+
}
|
|
80736
|
+
name = arg;
|
|
80737
|
+
break;
|
|
80738
|
+
}
|
|
80739
|
+
}
|
|
80740
|
+
if (!name) {
|
|
80741
|
+
throw new Error("Usage: elit pm logs <name> [--lines <n>] [--stderr]");
|
|
80742
|
+
}
|
|
80743
|
+
const { paths } = await loadPmContext();
|
|
80744
|
+
const match = findPmRecordMatch(paths, name);
|
|
80745
|
+
if (!match) {
|
|
80746
|
+
throw new Error(`No managed process found for: ${name}`);
|
|
80747
|
+
}
|
|
80748
|
+
const stdoutContent = stderrOnly ? "" : tailLogFile(match.record.logFiles.out, lineCount);
|
|
80749
|
+
const stderrContent = tailLogFile(match.record.logFiles.err, lineCount);
|
|
80750
|
+
if (!stderrOnly) {
|
|
80751
|
+
console.log(`== stdout: ${match.record.logFiles.out} ==`);
|
|
80752
|
+
console.log(stdoutContent || "(empty)");
|
|
80753
|
+
}
|
|
80754
|
+
console.log(`== stderr: ${match.record.logFiles.err} ==`);
|
|
80755
|
+
console.log(stderrContent || "(empty)");
|
|
80756
|
+
}
|
|
80757
|
+
function printPmHelp() {
|
|
80758
|
+
console.log([
|
|
80759
|
+
"",
|
|
80760
|
+
"Elit PM - lightweight process manager",
|
|
80761
|
+
"",
|
|
80762
|
+
"Usage:",
|
|
80763
|
+
' elit pm start --script "npm start" --name my-app --runtime node',
|
|
80764
|
+
" elit pm start --wapk ./test.wapk --name my-app",
|
|
80765
|
+
" elit pm start --wapk gdrive://<fileId> --name my-app",
|
|
80766
|
+
" elit pm start --google-drive-file-id <fileId> --name my-app",
|
|
80767
|
+
" elit pm start ./app.ts --name my-app",
|
|
80768
|
+
" elit pm start --file ./app.js --name my-app",
|
|
80769
|
+
" elit pm start my-app",
|
|
80770
|
+
" elit pm start",
|
|
80771
|
+
" elit pm list",
|
|
80772
|
+
" elit pm stop <name|all>",
|
|
80773
|
+
" elit pm restart <name|all>",
|
|
80774
|
+
" elit pm delete <name|all>",
|
|
80775
|
+
" elit pm save",
|
|
80776
|
+
" elit pm resurrect",
|
|
80777
|
+
" elit pm logs <name> --lines 100",
|
|
80778
|
+
"",
|
|
80779
|
+
"Start Options:",
|
|
80780
|
+
" --script <command> Run a shell command, for example: npm start",
|
|
80781
|
+
" --file, -f <path> Run a .js/.mjs/.cjs/.ts file",
|
|
80782
|
+
" --wapk <source> Run a local .wapk file or a remote source like gdrive://<fileId>",
|
|
80783
|
+
" --google-drive-file-id <id> Run a WAPK archive directly from Google Drive",
|
|
80784
|
+
" --google-drive-token-env <name> Env var containing the Google Drive OAuth token",
|
|
80785
|
+
" --google-drive-access-token <value> OAuth token forwarded to elit wapk run",
|
|
80786
|
+
" --google-drive-shared-drive Forward supportsAllDrives=true for shared drives",
|
|
80787
|
+
" --runtime, -r <name> Runtime override: node, bun, deno",
|
|
80788
|
+
" --name, -n <name> Process name used by list/stop/restart",
|
|
80789
|
+
" --cwd <dir> Working directory for the managed process",
|
|
80790
|
+
" --env KEY=VALUE Add or override an environment variable",
|
|
80791
|
+
" --password <value> Password for locked WAPK archives",
|
|
80792
|
+
" --sync-interval <ms> Forward WAPK live-sync write interval (>= 50ms)",
|
|
80793
|
+
" --watcher, --use-watcher Forward event-driven WAPK file watching",
|
|
80794
|
+
" --archive-watch Pull archive source changes back into the temp WAPK workdir",
|
|
80795
|
+
" --no-archive-watch Disable archive-source read sync for WAPK apps",
|
|
80796
|
+
" --archive-sync-interval <ms> Forward WAPK archive read-sync interval (>= 50ms)",
|
|
80797
|
+
" --restart-policy <mode> Restart policy: always, on-failure, never",
|
|
80798
|
+
" --min-uptime <ms> Reset crash counter after this healthy uptime",
|
|
80799
|
+
" --watch Restart when watched files change",
|
|
80800
|
+
" --watch-path <path> Add a file or directory to watch",
|
|
80801
|
+
" --watch-ignore <pattern> Ignore watched paths matching this glob-like pattern",
|
|
80802
|
+
" --watch-debounce <ms> Debounce file-triggered restarts (default 250)",
|
|
80803
|
+
" --health-url <url> Poll an HTTP endpoint and restart after repeated failures",
|
|
80804
|
+
" --health-grace-period <ms> Delay before the first health check (default 5000)",
|
|
80805
|
+
" --health-interval <ms> Health check interval (default 10000)",
|
|
80806
|
+
" --health-timeout <ms> Per-request health check timeout (default 3000)",
|
|
80807
|
+
" --health-max-failures <n> Consecutive failures before restart (default 3)",
|
|
80808
|
+
" --no-autorestart Disable automatic restart",
|
|
80809
|
+
" --restart-delay <ms> Delay between restart attempts (default 1000)",
|
|
80810
|
+
" --max-restarts <count> Maximum restart attempts (default 10)",
|
|
80811
|
+
"",
|
|
80812
|
+
"Config:",
|
|
80813
|
+
" Add pm.apps[] to elit.config.* and run elit pm start to boot all configured apps.",
|
|
80814
|
+
"",
|
|
80815
|
+
"Example:",
|
|
80816
|
+
" export default {",
|
|
80817
|
+
" pm: {",
|
|
80818
|
+
" apps: [",
|
|
80819
|
+
' { name: "api", script: "npm start", cwd: ".", runtime: "node" },',
|
|
80820
|
+
' { name: "worker", file: "./src/worker.ts", runtime: "bun" },',
|
|
80821
|
+
' { name: "desktop-app", wapk: "./dist/app.wapk", runtime: "node" },',
|
|
80822
|
+
' { name: "drive-app", wapkRun: { googleDrive: { fileId: "1AbCdEfGhIjKlMnOp", accessTokenEnv: "GOOGLE_DRIVE_ACCESS_TOKEN" }, useWatcher: true, watchArchive: true } }',
|
|
80823
|
+
" ]",
|
|
80824
|
+
" }",
|
|
80825
|
+
" }",
|
|
80826
|
+
"",
|
|
80827
|
+
"Notes:",
|
|
80828
|
+
" - PM state and logs are stored in ./.elit/pm by default.",
|
|
80829
|
+
" - elit pm save persists running apps to pm.dumpFile or ./.elit/pm/dump.json.",
|
|
80830
|
+
" - elit pm resurrect restarts whatever was last saved by elit pm save.",
|
|
80831
|
+
" - elit pm start <name> starts a configured app by name.",
|
|
80832
|
+
" - TypeScript files with runtime node require tsx, otherwise use --runtime bun.",
|
|
80833
|
+
" - WAPK processes are executed through elit wapk run inside the manager.",
|
|
80834
|
+
" - WAPK PM apps can use local archives, gdrive://<fileId>, or pm.apps[].wapkRun.googleDrive."
|
|
80835
|
+
].join("\n"));
|
|
80836
|
+
}
|
|
80837
|
+
async function runPmCommand(args) {
|
|
80838
|
+
if (args.length === 0 || args[0] === "help" || args.includes("--help") || args.includes("-h")) {
|
|
80839
|
+
printPmHelp();
|
|
80840
|
+
return;
|
|
80841
|
+
}
|
|
80842
|
+
const command = args[0];
|
|
80843
|
+
switch (command) {
|
|
80844
|
+
case "start":
|
|
80845
|
+
await runPmStart(args.slice(1));
|
|
80846
|
+
return;
|
|
80847
|
+
case "list":
|
|
80848
|
+
case "ls": {
|
|
80849
|
+
const { paths } = await loadPmContext();
|
|
80850
|
+
printPmList(paths);
|
|
80851
|
+
return;
|
|
80852
|
+
}
|
|
80853
|
+
case "stop":
|
|
80854
|
+
await runPmStop(args.slice(1));
|
|
80855
|
+
return;
|
|
80856
|
+
case "restart":
|
|
80857
|
+
await runPmRestart(args.slice(1));
|
|
80858
|
+
return;
|
|
80859
|
+
case "delete":
|
|
80860
|
+
case "remove":
|
|
80861
|
+
case "rm":
|
|
80862
|
+
await runPmDelete(args.slice(1));
|
|
80863
|
+
return;
|
|
80864
|
+
case "save":
|
|
80865
|
+
await runPmSave();
|
|
80866
|
+
return;
|
|
80867
|
+
case "resurrect":
|
|
80868
|
+
await runPmResurrect();
|
|
80869
|
+
return;
|
|
80870
|
+
case "logs":
|
|
80871
|
+
await runPmLogs(args.slice(1));
|
|
80872
|
+
return;
|
|
80873
|
+
case "__run":
|
|
80874
|
+
await runPmRunner(args.slice(1));
|
|
80875
|
+
return;
|
|
80876
|
+
default:
|
|
80877
|
+
throw new Error(`Unknown pm command: ${command}`);
|
|
80878
|
+
}
|
|
80879
|
+
}
|
|
80880
|
+
|
|
78558
80881
|
// src/cli.ts
|
|
78559
|
-
var COMMANDS = ["dev", "build", "preview", "test", "desktop", "mobile", "native", "wapk", "help", "version"];
|
|
80882
|
+
var COMMANDS = ["dev", "build", "preview", "test", "desktop", "mobile", "native", "pm", "wapk", "help", "version"];
|
|
78560
80883
|
function setupShutdownHandlers(closeFunc) {
|
|
78561
80884
|
const shutdown = async () => {
|
|
78562
80885
|
console.log("\n[Server] Shutting down...");
|
|
@@ -78629,6 +80952,9 @@ async function main() {
|
|
|
78629
80952
|
case "native":
|
|
78630
80953
|
await runNative(args.slice(1));
|
|
78631
80954
|
break;
|
|
80955
|
+
case "pm":
|
|
80956
|
+
await runPm(args.slice(1));
|
|
80957
|
+
break;
|
|
78632
80958
|
case "wapk":
|
|
78633
80959
|
await runWapk(args.slice(1));
|
|
78634
80960
|
break;
|
|
@@ -78849,6 +81175,14 @@ async function runWapk(args) {
|
|
|
78849
81175
|
process.exit(1);
|
|
78850
81176
|
}
|
|
78851
81177
|
}
|
|
81178
|
+
async function runPm(args) {
|
|
81179
|
+
try {
|
|
81180
|
+
await runPmCommand(args);
|
|
81181
|
+
} catch (error) {
|
|
81182
|
+
console.error(error instanceof Error ? error.message : error);
|
|
81183
|
+
process.exit(1);
|
|
81184
|
+
}
|
|
81185
|
+
}
|
|
78852
81186
|
function parseTestArgs(args) {
|
|
78853
81187
|
const options = {};
|
|
78854
81188
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -79046,6 +81380,7 @@ Commands:
|
|
|
79046
81380
|
desktop Run or build a native desktop app
|
|
79047
81381
|
mobile Run native mobile workflow commands
|
|
79048
81382
|
native Generate native target code from an Elit entry
|
|
81383
|
+
pm Manage background processes and packaged apps
|
|
79049
81384
|
wapk Pack, inspect, extract, or run a .wapk app
|
|
79050
81385
|
version Show version number
|
|
79051
81386
|
help Show this help message
|
|
@@ -79092,18 +81427,38 @@ Native Options:
|
|
|
79092
81427
|
elit native generate ... --export <name> Select a specific module export
|
|
79093
81428
|
|
|
79094
81429
|
WAPK Options:
|
|
79095
|
-
elit wapk
|
|
79096
|
-
elit wapk
|
|
81430
|
+
elit wapk [file.wapk] Run a packaged app or the configured default archive
|
|
81431
|
+
elit wapk gdrive://<fileId> Run a packaged app directly from Google Drive
|
|
81432
|
+
elit wapk run [file.wapk] Run a packaged app or the configured default archive
|
|
81433
|
+
elit wapk run --google-drive-file-id <id> Run a packaged app directly from Google Drive
|
|
79097
81434
|
elit wapk pack [directory] Pack a directory into a .wapk archive
|
|
79098
81435
|
elit wapk inspect <file.wapk> Inspect a .wapk archive
|
|
79099
81436
|
elit wapk extract <file.wapk> Extract a .wapk archive
|
|
79100
|
-
elit wapk --runtime node|bun|deno
|
|
81437
|
+
elit wapk --runtime node|bun|deno [file] Override the packaged runtime
|
|
81438
|
+
|
|
81439
|
+
PM Options:
|
|
81440
|
+
elit pm start --script "npm start" -n my-app Start a shell command in the background
|
|
81441
|
+
elit pm start ./app.ts -n my-app Start a file with inferred runtime
|
|
81442
|
+
elit pm start --wapk ./app.wapk -n my-app Start a WAPK app through the manager
|
|
81443
|
+
elit pm start --wapk gdrive://<fileId> -n my-app Start a Google Drive WAPK app through the manager
|
|
81444
|
+
elit pm start --google-drive-file-id <id> -n my-app Start a Google Drive WAPK app without a positional source
|
|
81445
|
+
elit pm start my-app --watch Start one configured app with file watching enabled
|
|
81446
|
+
elit pm start Start all pm.apps[] entries from elit.config.*
|
|
81447
|
+
elit pm start my-app Start one configured app by name
|
|
81448
|
+
elit pm list Show managed process status
|
|
81449
|
+
elit pm stop <name|all> Stop one or all managed processes
|
|
81450
|
+
elit pm restart <name|all> Restart one or all managed processes
|
|
81451
|
+
elit pm delete <name|all> Remove process metadata and logs
|
|
81452
|
+
elit pm save Persist the running process list to pm.dumpFile
|
|
81453
|
+
elit pm resurrect Restart the last saved process list
|
|
81454
|
+
elit pm logs <name> --lines 100 Show recent stdout/stderr logs
|
|
79101
81455
|
|
|
79102
81456
|
Note: Build configuration supports both single and multiple builds:
|
|
79103
81457
|
- Single build: build: { entry: 'src/app.ts', outDir: 'dist' }
|
|
79104
81458
|
- Multiple builds: build: [{ entry: 'src/app1.ts' }, { entry: 'src/app2.ts' }]
|
|
79105
81459
|
When using array, all builds run sequentially.
|
|
79106
81460
|
Desktop commands can read desktop.entry or desktop.native.entry from elit.config.ts when [entry] is omitted, depending on desktop.mode.
|
|
81461
|
+
PM commands read pm.apps[], pm.dataDir, and pm.dumpFile from elit.config.* when present.
|
|
79107
81462
|
|
|
79108
81463
|
Preview Options:
|
|
79109
81464
|
-p, --port <number> Port to run server on (default: 4173)
|
|
@@ -79419,6 +81774,7 @@ main().catch((error) => {
|
|
|
79419
81774
|
runDev,
|
|
79420
81775
|
runMobile,
|
|
79421
81776
|
runNative,
|
|
81777
|
+
runPm,
|
|
79422
81778
|
runPreview,
|
|
79423
81779
|
runTest,
|
|
79424
81780
|
runWapk
|