elit 3.6.5 → 3.6.6
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 +6 -0
- package/dist/build.d.ts +4 -1
- package/dist/cli.cjs +502 -11
- package/dist/cli.mjs +502 -11
- package/dist/config.d.ts +8 -1
- package/dist/coverage.d.ts +4 -1
- package/dist/desktop-auto-render.cjs +5 -4
- package/dist/desktop-auto-render.d.ts +4 -1
- package/dist/desktop-auto-render.js +5 -4
- package/dist/desktop-auto-render.mjs +5 -4
- package/dist/dom.cjs +5 -4
- package/dist/dom.d.ts +2 -0
- package/dist/dom.js +5 -4
- package/dist/dom.mjs +5 -4
- package/dist/el.d.ts +2 -0
- package/dist/index.cjs +5 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -4
- package/dist/index.mjs +5 -4
- package/dist/native.cjs +5 -4
- package/dist/native.d.ts +2 -0
- package/dist/native.js +5 -4
- package/dist/native.mjs +5 -4
- package/dist/render-context.d.ts +4 -1
- package/dist/router.cjs +5 -4
- package/dist/router.d.ts +2 -0
- package/dist/router.js +5 -4
- package/dist/router.mjs +5 -4
- package/dist/{server-CcBFc2F5.d.ts → server-uMQvZAll.d.ts} +9 -0
- package/dist/server.cjs +146 -4
- package/dist/server.d.ts +4 -1
- package/dist/server.js +4494 -285
- package/dist/server.mjs +146 -4
- package/dist/smtp-server.cjs +115 -0
- package/dist/smtp-server.d.ts +41 -0
- package/dist/smtp-server.js +4186 -0
- package/dist/smtp-server.mjs +87 -0
- package/dist/state.cjs +5 -4
- package/dist/state.d.ts +2 -0
- package/dist/state.js +5 -4
- package/dist/state.mjs +5 -4
- package/dist/types.d.ts +34 -2
- package/dist/universal.d.ts +2 -0
- package/package.json +9 -1
package/dist/cli.cjs
CHANGED
|
@@ -60484,6 +60484,71 @@ function lookup(path) {
|
|
|
60484
60484
|
// src/server.ts
|
|
60485
60485
|
init_runtime();
|
|
60486
60486
|
|
|
60487
|
+
// src/smtp-server.ts
|
|
60488
|
+
var import_smtp_server = require("smtp-server");
|
|
60489
|
+
var DEFAULT_SMTP_PORT = 2525;
|
|
60490
|
+
var DEFAULT_SMTP_HOST = "127.0.0.1";
|
|
60491
|
+
function resolveSmtpServerConfig(config = {}) {
|
|
60492
|
+
const { port = DEFAULT_SMTP_PORT, host = DEFAULT_SMTP_HOST, label, ...serverOptions } = config;
|
|
60493
|
+
return {
|
|
60494
|
+
...serverOptions,
|
|
60495
|
+
port,
|
|
60496
|
+
host,
|
|
60497
|
+
label
|
|
60498
|
+
};
|
|
60499
|
+
}
|
|
60500
|
+
function normalizeSmtpServerConfigs(input) {
|
|
60501
|
+
const configs = Array.isArray(input) ? input : input ? [input] : [];
|
|
60502
|
+
return configs.map((config) => resolveSmtpServerConfig(config));
|
|
60503
|
+
}
|
|
60504
|
+
function closeSmtpServer(server) {
|
|
60505
|
+
return new Promise((resolve9, reject) => {
|
|
60506
|
+
let settled = false;
|
|
60507
|
+
const finish = (error) => {
|
|
60508
|
+
if (settled) {
|
|
60509
|
+
return;
|
|
60510
|
+
}
|
|
60511
|
+
settled = true;
|
|
60512
|
+
if (error) {
|
|
60513
|
+
reject(error);
|
|
60514
|
+
return;
|
|
60515
|
+
}
|
|
60516
|
+
resolve9();
|
|
60517
|
+
};
|
|
60518
|
+
const handleCloseError = (error) => {
|
|
60519
|
+
const errorCode = error.code;
|
|
60520
|
+
if (errorCode === "ERR_SERVER_NOT_RUNNING") {
|
|
60521
|
+
finish();
|
|
60522
|
+
return;
|
|
60523
|
+
}
|
|
60524
|
+
finish(error);
|
|
60525
|
+
};
|
|
60526
|
+
try {
|
|
60527
|
+
server.close(() => finish());
|
|
60528
|
+
} catch (error) {
|
|
60529
|
+
handleCloseError(error);
|
|
60530
|
+
}
|
|
60531
|
+
});
|
|
60532
|
+
}
|
|
60533
|
+
function createSmtpServer(config = {}) {
|
|
60534
|
+
const resolvedConfig = resolveSmtpServerConfig(config);
|
|
60535
|
+
const { port, host, label: _label, ...serverOptions } = resolvedConfig;
|
|
60536
|
+
const server = new import_smtp_server.SMTPServer(serverOptions);
|
|
60537
|
+
return {
|
|
60538
|
+
server,
|
|
60539
|
+
config: resolvedConfig,
|
|
60540
|
+
listen(callback) {
|
|
60541
|
+
return callback ? server.listen(port, host, callback) : server.listen(port, host);
|
|
60542
|
+
},
|
|
60543
|
+
address() {
|
|
60544
|
+
return server.server.address();
|
|
60545
|
+
},
|
|
60546
|
+
close() {
|
|
60547
|
+
return closeSmtpServer(server);
|
|
60548
|
+
}
|
|
60549
|
+
};
|
|
60550
|
+
}
|
|
60551
|
+
|
|
60487
60552
|
// src/render-context.ts
|
|
60488
60553
|
var RUNTIME_TARGET_KEY = "__ELIT_RUNTIME_TARGET__";
|
|
60489
60554
|
var CAPTURED_RENDER_KEY = "__ELIT_CAPTURED_RENDER__";
|
|
@@ -60937,6 +61002,7 @@ var DomNode = class {
|
|
|
60937
61002
|
html += `</${tagName}>${newLine}`;
|
|
60938
61003
|
return html;
|
|
60939
61004
|
}
|
|
61005
|
+
const isRawText = tagName === "script" || tagName === "style";
|
|
60940
61006
|
if (children && children.length > 0) {
|
|
60941
61007
|
const resolvedChildren = children.map((c) => {
|
|
60942
61008
|
const resolved = this.resolveStateValue(c);
|
|
@@ -60952,11 +61018,11 @@ var DomNode = class {
|
|
|
60952
61018
|
if (Array.isArray(child)) {
|
|
60953
61019
|
for (const c of child) {
|
|
60954
61020
|
if (!shouldSkipChild(c)) {
|
|
60955
|
-
html += this.renderToString(c, { pretty, indent: indent5 + 1 });
|
|
61021
|
+
html += isRawText && typeof c === "string" ? c : this.renderToString(c, { pretty, indent: indent5 + 1 });
|
|
60956
61022
|
}
|
|
60957
61023
|
}
|
|
60958
61024
|
} else {
|
|
60959
|
-
html += this.renderToString(child, { pretty, indent: indent5 + 1 });
|
|
61025
|
+
html += isRawText && typeof child === "string" ? child : this.renderToString(child, { pretty, indent: indent5 + 1 });
|
|
60960
61026
|
}
|
|
60961
61027
|
}
|
|
60962
61028
|
html += indentStr;
|
|
@@ -60966,11 +61032,11 @@ var DomNode = class {
|
|
|
60966
61032
|
if (Array.isArray(child)) {
|
|
60967
61033
|
for (const c of child) {
|
|
60968
61034
|
if (!shouldSkipChild(c)) {
|
|
60969
|
-
html += this.renderToString(c, { pretty: false, indent: 0 });
|
|
61035
|
+
html += isRawText && typeof c === "string" ? c : this.renderToString(c, { pretty: false, indent: 0 });
|
|
60970
61036
|
}
|
|
60971
61037
|
}
|
|
60972
61038
|
} else {
|
|
60973
|
-
html += this.renderToString(child, { pretty: false, indent: 0 });
|
|
61039
|
+
html += isRawText && typeof child === "string" ? child : this.renderToString(child, { pretty: false, indent: 0 });
|
|
60974
61040
|
}
|
|
60975
61041
|
}
|
|
60976
61042
|
}
|
|
@@ -61898,6 +61964,56 @@ var defaultOptions = {
|
|
|
61898
61964
|
worker: [],
|
|
61899
61965
|
mode: "dev"
|
|
61900
61966
|
};
|
|
61967
|
+
function createSmtpBindingKey(config) {
|
|
61968
|
+
return `${config.host}:${config.port}`;
|
|
61969
|
+
}
|
|
61970
|
+
function createSmtpServerLabel(config) {
|
|
61971
|
+
return config.label || createSmtpBindingKey(config);
|
|
61972
|
+
}
|
|
61973
|
+
function formatSmtpServerAddress(address, fallback) {
|
|
61974
|
+
if (typeof address === "string") {
|
|
61975
|
+
return address;
|
|
61976
|
+
}
|
|
61977
|
+
if (address) {
|
|
61978
|
+
return `${address.address}:${address.port}`;
|
|
61979
|
+
}
|
|
61980
|
+
return createSmtpBindingKey(fallback);
|
|
61981
|
+
}
|
|
61982
|
+
function collectSmtpServerConfigs(config, usesClientArray) {
|
|
61983
|
+
const modeLabel = config.mode || "dev";
|
|
61984
|
+
const smtpConfigs = normalizeSmtpServerConfigs(config.smtp).map((smtpConfig, index) => ({
|
|
61985
|
+
...smtpConfig,
|
|
61986
|
+
label: smtpConfig.label || `${modeLabel}.smtp[${index}]`
|
|
61987
|
+
}));
|
|
61988
|
+
if (!usesClientArray || !config.clients) {
|
|
61989
|
+
return smtpConfigs;
|
|
61990
|
+
}
|
|
61991
|
+
for (let clientIndex = 0; clientIndex < config.clients.length; clientIndex += 1) {
|
|
61992
|
+
const client = config.clients[clientIndex];
|
|
61993
|
+
const clientDescriptor = client.basePath || client.root;
|
|
61994
|
+
const clientPrefix = clientDescriptor ? `${modeLabel}.clients[${clientIndex}] (${clientDescriptor})` : `${modeLabel}.clients[${clientIndex}]`;
|
|
61995
|
+
smtpConfigs.push(...normalizeSmtpServerConfigs(client.smtp).map((smtpConfig, smtpIndex) => ({
|
|
61996
|
+
...smtpConfig,
|
|
61997
|
+
label: smtpConfig.label || `${clientPrefix}.smtp[${smtpIndex}]`
|
|
61998
|
+
})));
|
|
61999
|
+
}
|
|
62000
|
+
return smtpConfigs;
|
|
62001
|
+
}
|
|
62002
|
+
function assertUniqueSmtpServerBindings(configs) {
|
|
62003
|
+
const seenBindings = /* @__PURE__ */ new Map();
|
|
62004
|
+
for (const smtpConfig of configs) {
|
|
62005
|
+
if (smtpConfig.port === 0) {
|
|
62006
|
+
continue;
|
|
62007
|
+
}
|
|
62008
|
+
const bindingKey = createSmtpBindingKey(smtpConfig);
|
|
62009
|
+
const currentLabel = createSmtpServerLabel(smtpConfig);
|
|
62010
|
+
const previousLabel = seenBindings.get(bindingKey);
|
|
62011
|
+
if (previousLabel) {
|
|
62012
|
+
throw new Error(`Duplicate SMTP server binding "${bindingKey}" configured for ${previousLabel} and ${currentLabel}`);
|
|
62013
|
+
}
|
|
62014
|
+
seenBindings.set(bindingKey, currentLabel);
|
|
62015
|
+
}
|
|
62016
|
+
}
|
|
61901
62017
|
function shouldUseClientFallbackRoot(primaryRoot, fallbackRoot, indexPath) {
|
|
61902
62018
|
if (!fallbackRoot) {
|
|
61903
62019
|
return false;
|
|
@@ -62032,6 +62148,7 @@ function createDevServer(options) {
|
|
|
62032
62148
|
const globalWebSocketEndpoints = usesClientArray ? normalizeWebSocketEndpoints(config.ws) : [];
|
|
62033
62149
|
const normalizedWebSocketEndpoints = [...normalizedClients.flatMap((client) => client.ws), ...globalWebSocketEndpoints];
|
|
62034
62150
|
const seenWebSocketPaths = /* @__PURE__ */ new Set();
|
|
62151
|
+
const smtpServerConfigs = collectSmtpServerConfigs(config, usesClientArray);
|
|
62035
62152
|
for (const endpoint of normalizedWebSocketEndpoints) {
|
|
62036
62153
|
if (endpoint.path === ELIT_INTERNAL_WS_PATH) {
|
|
62037
62154
|
throw new Error(`WebSocket path "${ELIT_INTERNAL_WS_PATH}" is reserved for Elit internals`);
|
|
@@ -62041,6 +62158,21 @@ function createDevServer(options) {
|
|
|
62041
62158
|
}
|
|
62042
62159
|
seenWebSocketPaths.add(endpoint.path);
|
|
62043
62160
|
}
|
|
62161
|
+
assertUniqueSmtpServerBindings(smtpServerConfigs);
|
|
62162
|
+
const smtpServers = smtpServerConfigs.map((smtpConfig) => {
|
|
62163
|
+
const smtpServer = createSmtpServer(smtpConfig);
|
|
62164
|
+
const smtpLabel = createSmtpServerLabel(smtpServer.config);
|
|
62165
|
+
smtpServer.server.on("error", (error) => {
|
|
62166
|
+
console.error(`[SMTP] ${smtpLabel} error:`, error);
|
|
62167
|
+
});
|
|
62168
|
+
if (config.logging) {
|
|
62169
|
+
smtpServer.server.server.once("listening", () => {
|
|
62170
|
+
console.log(`[SMTP] ${smtpLabel} listening on ${formatSmtpServerAddress(smtpServer.address(), smtpServer.config)}`);
|
|
62171
|
+
});
|
|
62172
|
+
}
|
|
62173
|
+
smtpServer.listen();
|
|
62174
|
+
return smtpServer;
|
|
62175
|
+
});
|
|
62044
62176
|
const globalProxyHandler = config.proxy ? createProxyHandler(config.proxy) : null;
|
|
62045
62177
|
const server = createServer(async (req, res) => {
|
|
62046
62178
|
const originalUrl = req.url || "/";
|
|
@@ -62581,6 +62713,15 @@ ${elitImportMap}`;
|
|
|
62581
62713
|
if (config.logging) console.log("\n[Server] Shutting down...");
|
|
62582
62714
|
transformCache.clear();
|
|
62583
62715
|
if (watcher) await watcher.close();
|
|
62716
|
+
if (smtpServers.length > 0) {
|
|
62717
|
+
await Promise.all(smtpServers.map(async (smtpServer) => {
|
|
62718
|
+
try {
|
|
62719
|
+
await smtpServer.close();
|
|
62720
|
+
} catch (error) {
|
|
62721
|
+
console.error(`[SMTP] ${createSmtpServerLabel(smtpServer.config)} close error:`, error);
|
|
62722
|
+
}
|
|
62723
|
+
}));
|
|
62724
|
+
}
|
|
62584
62725
|
if (webSocketServers.length > 0) {
|
|
62585
62726
|
webSocketServers.forEach((wsServer) => wsServer.close());
|
|
62586
62727
|
wsClients.clear();
|
|
@@ -62597,6 +62738,7 @@ ${elitImportMap}`;
|
|
|
62597
62738
|
return {
|
|
62598
62739
|
server,
|
|
62599
62740
|
wss,
|
|
62741
|
+
smtpServers,
|
|
62600
62742
|
url: primaryUrl,
|
|
62601
62743
|
state: stateManager,
|
|
62602
62744
|
close
|
|
@@ -74476,7 +74618,7 @@ var WAPK_AUTH_TAG_LENGTH = 16;
|
|
|
74476
74618
|
var WAPK_SCRYPT_OPTIONS = { N: 16384, r: 8, p: 1 };
|
|
74477
74619
|
var DEFAULT_GOOGLE_DRIVE_TOKEN_ENV = "GOOGLE_DRIVE_ACCESS_TOKEN";
|
|
74478
74620
|
var DEFAULT_WAPK_ONLINE_URL_ENV = "ELIT_WAPK_ONLINE_URL";
|
|
74479
|
-
var DEFAULT_WAPK_ONLINE_URLS = ["
|
|
74621
|
+
var DEFAULT_WAPK_ONLINE_URLS = ["http://wapk.d-osc.com/"];
|
|
74480
74622
|
var WAPK_ONLINE_CREATE_PATH = "/api/shared-session/create";
|
|
74481
74623
|
var WAPK_ONLINE_READ_PATH = "/api/shared-session/read";
|
|
74482
74624
|
var WAPK_ONLINE_CLOSE_PATH = "/api/shared-session/close";
|
|
@@ -74514,6 +74656,113 @@ function normalizeNonEmptyString(value) {
|
|
|
74514
74656
|
const normalized = value.trim();
|
|
74515
74657
|
return normalized.length > 0 ? normalized : void 0;
|
|
74516
74658
|
}
|
|
74659
|
+
function normalizeGeneratedIdentifier(value) {
|
|
74660
|
+
const normalized = value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
74661
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
74662
|
+
}
|
|
74663
|
+
function joinGeneratedIdentifier(...segments) {
|
|
74664
|
+
const normalizedSegments = segments.map((segment) => segment ? normalizeGeneratedIdentifier(segment) : void 0).filter((segment) => Boolean(segment));
|
|
74665
|
+
return normalizedSegments.length > 0 ? normalizedSegments.join(".") : void 0;
|
|
74666
|
+
}
|
|
74667
|
+
function parseScopedPackageName(value) {
|
|
74668
|
+
const normalizedValue = normalizeNonEmptyString(value);
|
|
74669
|
+
if (!normalizedValue) {
|
|
74670
|
+
return {};
|
|
74671
|
+
}
|
|
74672
|
+
if (!normalizedValue.startsWith("@")) {
|
|
74673
|
+
return {
|
|
74674
|
+
packageName: normalizedValue
|
|
74675
|
+
};
|
|
74676
|
+
}
|
|
74677
|
+
const scopeSeparatorIndex = normalizedValue.indexOf("/");
|
|
74678
|
+
if (scopeSeparatorIndex === -1) {
|
|
74679
|
+
return {
|
|
74680
|
+
packageName: normalizedValue
|
|
74681
|
+
};
|
|
74682
|
+
}
|
|
74683
|
+
return {
|
|
74684
|
+
scope: normalizedValue.slice(1, scopeSeparatorIndex),
|
|
74685
|
+
packageName: normalizedValue.slice(scopeSeparatorIndex + 1)
|
|
74686
|
+
};
|
|
74687
|
+
}
|
|
74688
|
+
function readPackageAuthorMetadata(value) {
|
|
74689
|
+
if (typeof value === "string") {
|
|
74690
|
+
const normalizedValue = value.trim();
|
|
74691
|
+
if (!normalizedValue) {
|
|
74692
|
+
return {};
|
|
74693
|
+
}
|
|
74694
|
+
const email = normalizedValue.match(/<([^>]+)>/)?.[1];
|
|
74695
|
+
const url = normalizedValue.match(/\(([^)]+)\)/)?.[1];
|
|
74696
|
+
const name = normalizedValue.replace(/<[^>]+>/g, " ").replace(/\([^)]+\)/g, " ").replace(/\s+/g, " ").trim();
|
|
74697
|
+
return {
|
|
74698
|
+
name: normalizeNonEmptyString(name),
|
|
74699
|
+
email: normalizeNonEmptyString(email),
|
|
74700
|
+
url: normalizeNonEmptyString(url)
|
|
74701
|
+
};
|
|
74702
|
+
}
|
|
74703
|
+
if (!isRecord(value)) {
|
|
74704
|
+
return {};
|
|
74705
|
+
}
|
|
74706
|
+
return {
|
|
74707
|
+
name: normalizeNonEmptyString(value.name),
|
|
74708
|
+
email: normalizeNonEmptyString(value.email),
|
|
74709
|
+
url: normalizeNonEmptyString(value.url)
|
|
74710
|
+
};
|
|
74711
|
+
}
|
|
74712
|
+
function extractPublisherIdFromRepository(value) {
|
|
74713
|
+
const repositoryUrl = typeof value === "string" ? value : isRecord(value) ? normalizeNonEmptyString(value.url) : void 0;
|
|
74714
|
+
const normalizedRepositoryUrl = normalizeNonEmptyString(repositoryUrl);
|
|
74715
|
+
if (!normalizedRepositoryUrl) {
|
|
74716
|
+
return void 0;
|
|
74717
|
+
}
|
|
74718
|
+
const shorthandMatch = normalizedRepositoryUrl.match(/^(?:github|gitlab|bitbucket):([^/]+)\/.+$/i);
|
|
74719
|
+
if (shorthandMatch?.[1]) {
|
|
74720
|
+
return normalizeGeneratedIdentifier(shorthandMatch[1]);
|
|
74721
|
+
}
|
|
74722
|
+
const sshMatch = normalizedRepositoryUrl.match(/^[^@]+@[^:]+:([^/]+)\/.+$/i);
|
|
74723
|
+
if (sshMatch?.[1]) {
|
|
74724
|
+
return normalizeGeneratedIdentifier(sshMatch[1]);
|
|
74725
|
+
}
|
|
74726
|
+
try {
|
|
74727
|
+
const parsed = new URL(normalizedRepositoryUrl.replace(/^git\+/, ""));
|
|
74728
|
+
const firstPathSegment = parsed.pathname.replace(/\.git$/i, "").split("/").filter(Boolean)[0];
|
|
74729
|
+
return normalizeGeneratedIdentifier(firstPathSegment ?? parsed.hostname.replace(/^www\./i, ""));
|
|
74730
|
+
} catch {
|
|
74731
|
+
return void 0;
|
|
74732
|
+
}
|
|
74733
|
+
}
|
|
74734
|
+
function extractPublisherIdFromUrl(value) {
|
|
74735
|
+
const normalizedValue = normalizeNonEmptyString(value);
|
|
74736
|
+
if (!normalizedValue) {
|
|
74737
|
+
return void 0;
|
|
74738
|
+
}
|
|
74739
|
+
try {
|
|
74740
|
+
const parsed = new URL(normalizedValue);
|
|
74741
|
+
return normalizeGeneratedIdentifier(parsed.hostname.replace(/^www\./i, ""));
|
|
74742
|
+
} catch {
|
|
74743
|
+
return void 0;
|
|
74744
|
+
}
|
|
74745
|
+
}
|
|
74746
|
+
function extractPublisherIdFromEmail(value) {
|
|
74747
|
+
const normalizedValue = normalizeNonEmptyString(value);
|
|
74748
|
+
if (!normalizedValue) {
|
|
74749
|
+
return void 0;
|
|
74750
|
+
}
|
|
74751
|
+
const domain = normalizedValue.split("@")[1];
|
|
74752
|
+
return domain ? normalizeGeneratedIdentifier(domain.replace(/^www\./i, "")) : void 0;
|
|
74753
|
+
}
|
|
74754
|
+
function resolveAutoGeneratedWapkAppId(packageName, fallbackName) {
|
|
74755
|
+
const scopedPackage = parseScopedPackageName(packageName);
|
|
74756
|
+
return joinGeneratedIdentifier(scopedPackage.scope, scopedPackage.packageName ?? fallbackName);
|
|
74757
|
+
}
|
|
74758
|
+
function resolveAutoGeneratedWapkPublisherId(packageJson, fallbackName) {
|
|
74759
|
+
const scopedPackage = parseScopedPackageName(typeof packageJson?.name === "string" ? packageJson.name : void 0);
|
|
74760
|
+
if (scopedPackage.scope) {
|
|
74761
|
+
return normalizeGeneratedIdentifier(scopedPackage.scope);
|
|
74762
|
+
}
|
|
74763
|
+
const author = readPackageAuthorMetadata(packageJson?.author);
|
|
74764
|
+
return extractPublisherIdFromRepository(packageJson?.repository) ?? extractPublisherIdFromUrl(packageJson?.homepage) ?? extractPublisherIdFromUrl(author.url) ?? extractPublisherIdFromEmail(author.email) ?? normalizeGeneratedIdentifier(author.name ?? fallbackName);
|
|
74765
|
+
}
|
|
74517
74766
|
function normalizeStringMap(value) {
|
|
74518
74767
|
if (!isRecord(value)) {
|
|
74519
74768
|
return void 0;
|
|
@@ -74553,6 +74802,8 @@ function normalizeWapkConfig(value) {
|
|
|
74553
74802
|
runtime: normalizeRuntime(value.runtime ?? value.engine),
|
|
74554
74803
|
entry: typeof value.entry === "string" ? value.entry : void 0,
|
|
74555
74804
|
scripts: normalizeStringMap(value.scripts ?? value.script),
|
|
74805
|
+
appId: normalizeNonEmptyString(value.appId),
|
|
74806
|
+
publisherId: normalizeNonEmptyString(value.publisherId),
|
|
74556
74807
|
port: normalizePort(value.port),
|
|
74557
74808
|
env: normalizeStringMap(value.env),
|
|
74558
74809
|
desktop: normalizeDesktopConfig(value.desktop),
|
|
@@ -74842,6 +75093,7 @@ async function readWapkProjectConfig(directory) {
|
|
|
74842
75093
|
const elitConfig = await loadConfig(directory);
|
|
74843
75094
|
const elitWapkConfig = normalizeWapkConfig(elitConfig?.wapk);
|
|
74844
75095
|
const packageJson = readJsonFile(packageJsonPath);
|
|
75096
|
+
const packageJsonWapk = isRecord(packageJson?.wapk) ? packageJson.wapk : void 0;
|
|
74845
75097
|
const packageScripts = normalizeStringMap(packageJson?.scripts) ?? {};
|
|
74846
75098
|
const selectedScripts = elitWapkConfig.scripts ?? packageScripts;
|
|
74847
75099
|
const inferred = inferRuntimeAndEntryFromScript(selectedScripts.start ?? packageScripts.start);
|
|
@@ -74865,12 +75117,16 @@ async function readWapkProjectConfig(directory) {
|
|
|
74865
75117
|
if (!(0, import_node_fs2.existsSync)(entryPath) || !(0, import_node_fs2.statSync)(entryPath).isFile()) {
|
|
74866
75118
|
throw new Error(`WAPK entry not found: ${entryPath}`);
|
|
74867
75119
|
}
|
|
75120
|
+
const appId = elitWapkConfig.appId ?? normalizeNonEmptyString(packageJson?.appId) ?? normalizeNonEmptyString(packageJsonWapk?.appId) ?? resolveAutoGeneratedWapkAppId(typeof packageJson?.name === "string" ? packageJson.name : void 0, name);
|
|
75121
|
+
const publisherId = elitWapkConfig.publisherId ?? normalizeNonEmptyString(packageJson?.publisherId) ?? normalizeNonEmptyString(packageJsonWapk?.publisherId) ?? resolveAutoGeneratedWapkPublisherId(packageJson, name);
|
|
74868
75122
|
return {
|
|
74869
75123
|
name,
|
|
74870
75124
|
version,
|
|
74871
75125
|
runtime: runtime2,
|
|
74872
75126
|
entry,
|
|
74873
75127
|
scripts: selectedScripts,
|
|
75128
|
+
appId,
|
|
75129
|
+
publisherId,
|
|
74874
75130
|
port: elitWapkConfig.port,
|
|
74875
75131
|
env: elitWapkConfig.env,
|
|
74876
75132
|
desktop: elitWapkConfig.desktop,
|
|
@@ -74880,11 +75136,14 @@ async function readWapkProjectConfig(directory) {
|
|
|
74880
75136
|
function readIgnorePatterns(directory) {
|
|
74881
75137
|
return readLineIgnorePatterns((0, import_node_path2.join)(directory, ".wapkignore"));
|
|
74882
75138
|
}
|
|
75139
|
+
function parsePatternLines(content) {
|
|
75140
|
+
return content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && (!line.startsWith("#") || line.startsWith("\\#")));
|
|
75141
|
+
}
|
|
74883
75142
|
function readLineIgnorePatterns(filePath) {
|
|
74884
75143
|
if (!(0, import_node_fs2.existsSync)(filePath)) {
|
|
74885
75144
|
return [];
|
|
74886
75145
|
}
|
|
74887
|
-
return (0, import_node_fs2.readFileSync)(filePath, "utf8")
|
|
75146
|
+
return parsePatternLines((0, import_node_fs2.readFileSync)(filePath, "utf8"));
|
|
74888
75147
|
}
|
|
74889
75148
|
function normalizePackageEntry(value) {
|
|
74890
75149
|
const normalized = normalizeNonEmptyString(value)?.replace(/^[.][\\/]/, "").split("\\").join("/");
|
|
@@ -75163,6 +75422,91 @@ function shouldIgnore(relativePath2, ignorePatterns, isDirectory) {
|
|
|
75163
75422
|
}
|
|
75164
75423
|
return ignored;
|
|
75165
75424
|
}
|
|
75425
|
+
function matchesPatchPattern(relativePath2, pattern) {
|
|
75426
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75427
|
+
if (!normalizedRule) {
|
|
75428
|
+
return false;
|
|
75429
|
+
}
|
|
75430
|
+
const normalizedPath = relativePath2.replace(/\\/g, "/");
|
|
75431
|
+
const subtreeSelector = normalizedRule.pattern.endsWith("/*") && !normalizedRule.pattern.slice(0, -2).includes("*") && !normalizedRule.pattern.slice(0, -2).includes("?");
|
|
75432
|
+
if (subtreeSelector) {
|
|
75433
|
+
const directoryPath = normalizedRule.pattern.slice(0, -2);
|
|
75434
|
+
return directoryPath.length > 0 && normalizedPath.startsWith(`${directoryPath}/`);
|
|
75435
|
+
}
|
|
75436
|
+
const hasGlob = /[*?]/.test(normalizedRule.pattern);
|
|
75437
|
+
if (!hasGlob) {
|
|
75438
|
+
if (normalizedRule.directoryOnly) {
|
|
75439
|
+
return normalizedPath === normalizedRule.pattern || normalizedPath.startsWith(`${normalizedRule.pattern}/`);
|
|
75440
|
+
}
|
|
75441
|
+
return normalizedPath === normalizedRule.pattern;
|
|
75442
|
+
}
|
|
75443
|
+
return globPatternToRegex(normalizedRule.pattern, {
|
|
75444
|
+
directoryOnly: normalizedRule.directoryOnly,
|
|
75445
|
+
matchSegmentsOnly: false
|
|
75446
|
+
}).test(normalizedPath);
|
|
75447
|
+
}
|
|
75448
|
+
function shouldPatchArchivePath(relativePath2, patchPatterns) {
|
|
75449
|
+
let selected = false;
|
|
75450
|
+
for (const pattern of patchPatterns) {
|
|
75451
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75452
|
+
if (!normalizedRule) {
|
|
75453
|
+
continue;
|
|
75454
|
+
}
|
|
75455
|
+
if (!matchesPatchPattern(relativePath2, pattern)) {
|
|
75456
|
+
continue;
|
|
75457
|
+
}
|
|
75458
|
+
selected = !normalizedRule.negate;
|
|
75459
|
+
}
|
|
75460
|
+
return selected;
|
|
75461
|
+
}
|
|
75462
|
+
function resolvePatchManifestPatterns(files) {
|
|
75463
|
+
const patchManifest = files.find((file) => file.path === ".wapkpatch");
|
|
75464
|
+
if (!patchManifest) {
|
|
75465
|
+
throw new Error("Patch archive must include a .wapkpatch manifest file.");
|
|
75466
|
+
}
|
|
75467
|
+
const patterns = parsePatternLines(patchManifest.content.toString("utf8"));
|
|
75468
|
+
if (patterns.length === 0) {
|
|
75469
|
+
throw new Error("Patch archive .wapkpatch must define at least one patch rule.");
|
|
75470
|
+
}
|
|
75471
|
+
return patterns;
|
|
75472
|
+
}
|
|
75473
|
+
function applyPatchEntriesToFiles(targetFiles, patchFiles) {
|
|
75474
|
+
const fileMap = new Map(targetFiles.map((file) => [file.path, file]));
|
|
75475
|
+
const fileOrder = targetFiles.map((file) => file.path);
|
|
75476
|
+
const addedPaths = [];
|
|
75477
|
+
const updatedPaths = [];
|
|
75478
|
+
const unchangedPaths = [];
|
|
75479
|
+
for (const patchFile of [...patchFiles].sort((left, right) => left.path.localeCompare(right.path))) {
|
|
75480
|
+
const existing = fileMap.get(patchFile.path);
|
|
75481
|
+
const nextEntry = {
|
|
75482
|
+
path: patchFile.path,
|
|
75483
|
+
content: Buffer.from(patchFile.content),
|
|
75484
|
+
mode: patchFile.mode
|
|
75485
|
+
};
|
|
75486
|
+
if (!existing) {
|
|
75487
|
+
addedPaths.push(patchFile.path);
|
|
75488
|
+
fileOrder.push(patchFile.path);
|
|
75489
|
+
} else if (existing.mode === patchFile.mode && existing.content.equals(patchFile.content)) {
|
|
75490
|
+
unchangedPaths.push(patchFile.path);
|
|
75491
|
+
} else {
|
|
75492
|
+
updatedPaths.push(patchFile.path);
|
|
75493
|
+
}
|
|
75494
|
+
fileMap.set(patchFile.path, nextEntry);
|
|
75495
|
+
}
|
|
75496
|
+
return {
|
|
75497
|
+
files: fileOrder.map((filePath) => {
|
|
75498
|
+
const file = fileMap.get(filePath);
|
|
75499
|
+
if (!file) {
|
|
75500
|
+
throw new Error(`Internal WAPK patch error: missing file entry for ${filePath}`);
|
|
75501
|
+
}
|
|
75502
|
+
return file;
|
|
75503
|
+
}),
|
|
75504
|
+
patchedPaths: [...updatedPaths, ...addedPaths],
|
|
75505
|
+
addedPaths,
|
|
75506
|
+
updatedPaths,
|
|
75507
|
+
unchangedPaths
|
|
75508
|
+
};
|
|
75509
|
+
}
|
|
75166
75510
|
function collectFiles(directory, baseDirectory, ignorePatterns) {
|
|
75167
75511
|
const files = [];
|
|
75168
75512
|
const entries = (0, import_node_fs2.readdirSync)(directory, { withFileTypes: true });
|
|
@@ -75318,6 +75662,8 @@ function decodeWapkPayload(buffer) {
|
|
|
75318
75662
|
runtime: normalizeRuntime(rawHeader.runtime ?? rawHeader.engine) ?? "node",
|
|
75319
75663
|
entry: typeof rawHeader.entry === "string" ? rawHeader.entry : "index.js",
|
|
75320
75664
|
scripts: normalizeStringMap(rawHeader.scripts) ?? {},
|
|
75665
|
+
appId: normalizeNonEmptyString(rawHeader.appId),
|
|
75666
|
+
publisherId: normalizeNonEmptyString(rawHeader.publisherId),
|
|
75321
75667
|
port: normalizePort(rawHeader.port),
|
|
75322
75668
|
env: normalizeStringMap(rawHeader.env),
|
|
75323
75669
|
desktop: normalizeDesktopConfig(rawHeader.desktop),
|
|
@@ -75815,11 +76161,14 @@ function sanitizeOnlineArchiveFileName(label, fallback) {
|
|
|
75815
76161
|
const fileName = sanitized.length > 0 ? sanitized : "app.wapk";
|
|
75816
76162
|
return fileName.toLowerCase().endsWith(".wapk") ? fileName : `${fileName}.wapk`;
|
|
75817
76163
|
}
|
|
76164
|
+
var WAPK_ONLINE_JOIN_SOURCE_QUERY_PARAM = "launchSource";
|
|
76165
|
+
var WAPK_ONLINE_JOIN_SOURCE_QUERY_VALUE = "elit-wapk-online";
|
|
75818
76166
|
function buildOnlineJoinUrl(baseUrl, joinKey) {
|
|
75819
76167
|
const joinUrl = new URL(baseUrl.toString());
|
|
75820
76168
|
joinUrl.search = "";
|
|
75821
76169
|
joinUrl.hash = "";
|
|
75822
76170
|
joinUrl.searchParams.set("join", joinKey);
|
|
76171
|
+
joinUrl.searchParams.set(WAPK_ONLINE_JOIN_SOURCE_QUERY_PARAM, WAPK_ONLINE_JOIN_SOURCE_QUERY_VALUE);
|
|
75823
76172
|
return joinUrl.toString();
|
|
75824
76173
|
}
|
|
75825
76174
|
async function probeOnlineLauncherUrl(url) {
|
|
@@ -76000,11 +76349,16 @@ async function closeWapkOnlineSharedSession(launcherUrl, session) {
|
|
|
76000
76349
|
function isPmWapkOnlineShutdownEnabled() {
|
|
76001
76350
|
return process.env[WAPK_ONLINE_PM_SHUTDOWN_ENV] === "1" && Boolean(process.stdin) && !process.stdin.isTTY;
|
|
76002
76351
|
}
|
|
76003
|
-
|
|
76352
|
+
function getWapkOnlineProcessDetails() {
|
|
76353
|
+
return `pid ${process.pid}, ppid ${process.ppid}`;
|
|
76354
|
+
}
|
|
76355
|
+
async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHandle, lock, options = {}) {
|
|
76004
76356
|
let snapshotRevision = 0;
|
|
76005
76357
|
let snapshotSyncPending = false;
|
|
76006
76358
|
let snapshotSyncPromise = Promise.resolve();
|
|
76007
76359
|
let lastSnapshotSyncError = null;
|
|
76360
|
+
const allowSigtermClose = options.allowSigtermClose === true;
|
|
76361
|
+
const processDetails = getWapkOnlineProcessDetails();
|
|
76008
76362
|
const syncGuestSnapshotUpdates = () => {
|
|
76009
76363
|
if (snapshotSyncPending) {
|
|
76010
76364
|
return snapshotSyncPromise;
|
|
@@ -76038,6 +76392,7 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
76038
76392
|
void syncGuestSnapshotUpdates();
|
|
76039
76393
|
}, WAPK_ONLINE_KEEPALIVE_INTERVAL_MS);
|
|
76040
76394
|
const pmManaged = isPmWapkOnlineShutdownEnabled();
|
|
76395
|
+
let ignoredSigTermLogged = false;
|
|
76041
76396
|
let stdinBuffer = "";
|
|
76042
76397
|
const cleanup = () => {
|
|
76043
76398
|
clearInterval(keepAlive);
|
|
@@ -76056,7 +76411,17 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
76056
76411
|
finish({ kind: "signal", signal: "SIGINT" });
|
|
76057
76412
|
};
|
|
76058
76413
|
const onSigTerm = () => {
|
|
76059
|
-
|
|
76414
|
+
if (allowSigtermClose) {
|
|
76415
|
+
finish({ kind: "signal", signal: "SIGTERM" });
|
|
76416
|
+
return;
|
|
76417
|
+
}
|
|
76418
|
+
if (ignoredSigTermLogged) {
|
|
76419
|
+
return;
|
|
76420
|
+
}
|
|
76421
|
+
ignoredSigTermLogged = true;
|
|
76422
|
+
console.warn(
|
|
76423
|
+
pmManaged ? `[wapk] Ignoring SIGTERM while shared session ${session.joinKey} is active (${processDetails}). Use elit pm stop, restart, or delete to close the session.` : `[wapk] Ignoring SIGTERM while shared session ${session.joinKey} is active (${processDetails}). Press Ctrl+C to stop sharing, or pass --allow-sigterm-close to close on SIGTERM.`
|
|
76424
|
+
);
|
|
76060
76425
|
};
|
|
76061
76426
|
const onStdinData = (chunk) => {
|
|
76062
76427
|
stdinBuffer += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
@@ -76081,9 +76446,12 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
76081
76446
|
if (shutdownTrigger.kind === "pm") {
|
|
76082
76447
|
console.log(`
|
|
76083
76448
|
[wapk] PM requested shutdown for shared session ${session.joinKey}...`);
|
|
76449
|
+
} else if (shutdownTrigger.signal === "SIGTERM") {
|
|
76450
|
+
console.log(`
|
|
76451
|
+
[wapk] Received SIGTERM for shared session ${session.joinKey} (${processDetails}); closing because --allow-sigterm-close is enabled...`);
|
|
76084
76452
|
} else {
|
|
76085
76453
|
console.log(`
|
|
76086
|
-
[wapk]
|
|
76454
|
+
[wapk] Received ${shutdownTrigger.signal}; closing shared session ${session.joinKey}...`);
|
|
76087
76455
|
}
|
|
76088
76456
|
try {
|
|
76089
76457
|
await closeWapkOnlineSharedSession(launcherUrl, session);
|
|
@@ -76123,7 +76491,9 @@ async function runWapkOnline(archiveSpecifier, options) {
|
|
|
76123
76491
|
process.exitCode = await waitForWapkOnlineSessionShutdown(launcherUrl, {
|
|
76124
76492
|
joinKey: response.joinKey,
|
|
76125
76493
|
adminToken: response.adminToken
|
|
76126
|
-
}, archiveHandle, onlineArchiveLock
|
|
76494
|
+
}, archiveHandle, onlineArchiveLock, {
|
|
76495
|
+
allowSigtermClose: options.allowSigtermClose
|
|
76496
|
+
});
|
|
76127
76497
|
}
|
|
76128
76498
|
async function writeWapkArchiveFromMemory(archiveHandle, header, files, lock) {
|
|
76129
76499
|
const updatedHeader = {
|
|
@@ -76380,6 +76750,8 @@ async function packWapkDirectory(directory, options = {}) {
|
|
|
76380
76750
|
runtime: config.runtime,
|
|
76381
76751
|
entry: config.entry,
|
|
76382
76752
|
scripts: config.scripts,
|
|
76753
|
+
appId: config.appId,
|
|
76754
|
+
publisherId: config.publisherId,
|
|
76383
76755
|
port: config.port,
|
|
76384
76756
|
env: config.env,
|
|
76385
76757
|
desktop: config.desktop,
|
|
@@ -76411,6 +76783,56 @@ function extractWapkArchive(wapkPath, outputDir = ".", options = {}) {
|
|
|
76411
76783
|
console.log(`Extracted ${archive.files.length} files to: ${extractDirectory}`);
|
|
76412
76784
|
return extractDirectory;
|
|
76413
76785
|
}
|
|
76786
|
+
async function patchWapkArchive(wapkPath, options) {
|
|
76787
|
+
const targetHandle = resolveArchiveHandle(wapkPath);
|
|
76788
|
+
const targetSnapshot = await targetHandle.readSnapshot();
|
|
76789
|
+
const targetEnvelope = parseWapkEnvelope(targetSnapshot.buffer);
|
|
76790
|
+
const targetArchive = decodeWapk(targetSnapshot.buffer, options);
|
|
76791
|
+
const targetLock = targetEnvelope.version === WAPK_LOCKED_VERSION ? resolveArchiveCredentials(options) : void 0;
|
|
76792
|
+
const patchArchive = readWapkArchive(options.from, {
|
|
76793
|
+
password: options.fromPassword ?? options.password
|
|
76794
|
+
});
|
|
76795
|
+
const patchPatterns = resolvePatchManifestPatterns(patchArchive.files);
|
|
76796
|
+
const selectedPatchFiles = patchArchive.files.filter((file) => file.path !== ".wapkpatch").filter((file) => shouldPatchArchivePath(file.path, patchPatterns));
|
|
76797
|
+
const patchResult = applyPatchEntriesToFiles(targetArchive.files, selectedPatchFiles);
|
|
76798
|
+
console.log(`[wapk] Target: ${targetSnapshot.label ?? targetHandle.label}`);
|
|
76799
|
+
console.log(`[wapk] Patch: ${options.from}`);
|
|
76800
|
+
console.log(`[wapk] Rules: ${patchPatterns.length}`);
|
|
76801
|
+
if (selectedPatchFiles.length === 0) {
|
|
76802
|
+
console.log("[wapk] No files matched .wapkpatch. Archive was not modified.");
|
|
76803
|
+
return {
|
|
76804
|
+
archiveLabel: targetSnapshot.label ?? targetHandle.label,
|
|
76805
|
+
patchedPaths: [],
|
|
76806
|
+
addedPaths: [],
|
|
76807
|
+
updatedPaths: [],
|
|
76808
|
+
unchangedPaths: []
|
|
76809
|
+
};
|
|
76810
|
+
}
|
|
76811
|
+
if (patchResult.patchedPaths.length === 0) {
|
|
76812
|
+
console.log("[wapk] Matching patch files were already up to date. Archive was not modified.");
|
|
76813
|
+
return {
|
|
76814
|
+
archiveLabel: targetSnapshot.label ?? targetHandle.label,
|
|
76815
|
+
patchedPaths: [],
|
|
76816
|
+
addedPaths: [],
|
|
76817
|
+
updatedPaths: [],
|
|
76818
|
+
unchangedPaths: patchResult.unchangedPaths
|
|
76819
|
+
};
|
|
76820
|
+
}
|
|
76821
|
+
const writeResult = await writeWapkArchiveFromMemory(
|
|
76822
|
+
targetHandle,
|
|
76823
|
+
targetArchive.header,
|
|
76824
|
+
patchResult.files,
|
|
76825
|
+
targetLock
|
|
76826
|
+
);
|
|
76827
|
+
console.log(`[wapk] Applied ${patchResult.patchedPaths.length} patch file${patchResult.patchedPaths.length === 1 ? "" : "s"}.`);
|
|
76828
|
+
return {
|
|
76829
|
+
archiveLabel: writeResult.label,
|
|
76830
|
+
patchedPaths: patchResult.patchedPaths,
|
|
76831
|
+
addedPaths: patchResult.addedPaths,
|
|
76832
|
+
updatedPaths: patchResult.updatedPaths,
|
|
76833
|
+
unchangedPaths: patchResult.unchangedPaths
|
|
76834
|
+
};
|
|
76835
|
+
}
|
|
76414
76836
|
async function prepareWapkApp(wapkPath, options = {}) {
|
|
76415
76837
|
const archiveHandle = resolveArchiveHandle(wapkPath, options.googleDrive);
|
|
76416
76838
|
const archivePath = archiveHandle.identifier;
|
|
@@ -76519,6 +76941,8 @@ function inspectWapkArchive(wapkPath, options = {}) {
|
|
|
76519
76941
|
console.log(`App: ${decoded.header.version}`);
|
|
76520
76942
|
console.log(`Runtime: ${decoded.header.runtime}`);
|
|
76521
76943
|
console.log(`Entry: ${decoded.header.entry}`);
|
|
76944
|
+
console.log(`App ID: ${decoded.header.appId ?? "n/a"}`);
|
|
76945
|
+
console.log(`Publisher:${decoded.header.publisherId ? ` ${decoded.header.publisherId}` : " n/a"}`);
|
|
76522
76946
|
console.log(`Port: ${decoded.header.port ?? "default"}`);
|
|
76523
76947
|
console.log(`Created: ${decoded.header.createdAt}`);
|
|
76524
76948
|
if (decoded.header.env && Object.keys(decoded.header.env).length > 0) {
|
|
@@ -76550,6 +76974,8 @@ function printWapkHelp() {
|
|
|
76550
76974
|
" elit wapk gdrive://<fileId> --online",
|
|
76551
76975
|
" elit wapk pack [directory]",
|
|
76552
76976
|
" elit wapk pack [directory] --password secret-123",
|
|
76977
|
+
" elit wapk patch <file.wapk> --from <patch.wapk>",
|
|
76978
|
+
" elit wapk patch <file.wapk> --use <patch.wapk>",
|
|
76553
76979
|
" elit wapk inspect <file.wapk>",
|
|
76554
76980
|
" elit wapk extract <file.wapk>",
|
|
76555
76981
|
"",
|
|
@@ -76561,24 +76987,32 @@ function printWapkHelp() {
|
|
|
76561
76987
|
" --archive-watch Pull external archive changes back into the temp workdir",
|
|
76562
76988
|
" --no-archive-watch Disable external archive read sync",
|
|
76563
76989
|
" --online Create an Elit Run share session, stay alive, and close on Ctrl+C",
|
|
76990
|
+
" --allow-sigterm-close Allow SIGTERM to close an online shared session",
|
|
76564
76991
|
" --online-url <url> Elit Run URL (default: auto-detect localhost:4177 or localhost:4179)",
|
|
76565
76992
|
" --google-drive-file-id <id> Run a remote .wapk directly from Google Drive",
|
|
76566
76993
|
" --google-drive-token-env <name> Env var containing the Google Drive OAuth token",
|
|
76567
76994
|
" --google-drive-access-token <value> OAuth token for Google Drive API calls",
|
|
76568
76995
|
" --google-drive-shared-drive Include supportsAllDrives=true for shared drives",
|
|
76996
|
+
" --from <file.wapk> Patch source archive for elit wapk patch",
|
|
76997
|
+
" --use <file.wapk> Alias for --from",
|
|
76998
|
+
" --from-password <value> Password for unlocking the patch archive",
|
|
76569
76999
|
" --include-deps Legacy compatibility flag; node_modules are packed by default",
|
|
76570
77000
|
" --password <value> Password for locking or unlocking the archive",
|
|
76571
77001
|
" -h, --help Show this help",
|
|
76572
77002
|
"",
|
|
76573
77003
|
"Notes:",
|
|
76574
77004
|
" - Pack reads wapk from elit.config.* and falls back to package.json.",
|
|
77005
|
+
" - If appId or publisherId is not configured, pack auto-generates stable defaults from package metadata.",
|
|
76575
77006
|
" - Pack includes node_modules by default; use .wapkignore if you need to exclude them, and !pattern to re-include later matches.",
|
|
77007
|
+
" - Patch reads .wapkpatch from the patch archive and applies only matching archive-relative paths.",
|
|
77008
|
+
" - Patch keeps the target archive metadata and lock mode; use --from-password when the patch archive uses a different password.",
|
|
76576
77009
|
" - Run never installs dependencies automatically; archives must include the runtime dependencies they need.",
|
|
76577
77010
|
" - Run mode can read config.wapk.run for default file/runtime/live-sync options.",
|
|
76578
77011
|
" - Browser-style archives with scripts.start or wapk.script.start run that start script automatically.",
|
|
76579
77012
|
" - Run mode keeps files in RAM and syncs changes both to and from the archive source.",
|
|
76580
77013
|
" - Google Drive mode talks to the Drive API directly; no local archive file is required.",
|
|
76581
77014
|
" - Online mode creates a shared session on Elit Run directly, keeps the CLI alive, and closes it on Ctrl+C.",
|
|
77015
|
+
" - Online mode ignores SIGTERM by default; pass --allow-sigterm-close if an external supervisor should close the shared session with SIGTERM.",
|
|
76582
77016
|
" - Locked archives in online mode must provide --password so the CLI can build the shared snapshot.",
|
|
76583
77017
|
" - Locked archives require the same password for run/extract/inspect.",
|
|
76584
77018
|
" - Archives stay unlocked by default unless a password is provided.",
|
|
@@ -76628,6 +77062,7 @@ function parseRunArgs(args) {
|
|
|
76628
77062
|
let archiveSyncInterval;
|
|
76629
77063
|
let online;
|
|
76630
77064
|
let onlineUrl;
|
|
77065
|
+
let allowSigtermClose;
|
|
76631
77066
|
let password;
|
|
76632
77067
|
for (let index = 0; index < args.length; index++) {
|
|
76633
77068
|
const arg = args[index];
|
|
@@ -76679,6 +77114,10 @@ function parseRunArgs(args) {
|
|
|
76679
77114
|
onlineUrl = readRequiredOptionValue(args, ++index, "--online-url");
|
|
76680
77115
|
break;
|
|
76681
77116
|
}
|
|
77117
|
+
case "--allow-sigterm-close": {
|
|
77118
|
+
allowSigtermClose = true;
|
|
77119
|
+
break;
|
|
77120
|
+
}
|
|
76682
77121
|
case "--google-drive-file-id": {
|
|
76683
77122
|
googleDrive = {
|
|
76684
77123
|
...googleDrive,
|
|
@@ -76721,7 +77160,7 @@ function parseRunArgs(args) {
|
|
|
76721
77160
|
break;
|
|
76722
77161
|
}
|
|
76723
77162
|
}
|
|
76724
|
-
return { file, googleDrive, runtime: runtime2, syncInterval, useWatcher, watchArchive, archiveSyncInterval, online, onlineUrl, password };
|
|
77163
|
+
return { file, googleDrive, runtime: runtime2, syncInterval, useWatcher, watchArchive, archiveSyncInterval, online, onlineUrl, allowSigtermClose, password };
|
|
76725
77164
|
}
|
|
76726
77165
|
function parsePackArgs(args) {
|
|
76727
77166
|
let directory = ".";
|
|
@@ -76747,6 +77186,46 @@ function parsePackArgs(args) {
|
|
|
76747
77186
|
}
|
|
76748
77187
|
return { directory, includeDeps, password };
|
|
76749
77188
|
}
|
|
77189
|
+
function parsePatchArgs(args) {
|
|
77190
|
+
let file;
|
|
77191
|
+
let from;
|
|
77192
|
+
let password;
|
|
77193
|
+
let fromPassword;
|
|
77194
|
+
for (let index = 0; index < args.length; index++) {
|
|
77195
|
+
const arg = args[index];
|
|
77196
|
+
switch (arg) {
|
|
77197
|
+
case "--from":
|
|
77198
|
+
case "--use": {
|
|
77199
|
+
if (from) {
|
|
77200
|
+
throw new Error("WAPK patch accepts exactly one patch archive via --from or --use.");
|
|
77201
|
+
}
|
|
77202
|
+
from = readRequiredOptionValue(args, ++index, arg);
|
|
77203
|
+
break;
|
|
77204
|
+
}
|
|
77205
|
+
case "--password": {
|
|
77206
|
+
password = readRequiredOptionValue(args, ++index, "--password");
|
|
77207
|
+
break;
|
|
77208
|
+
}
|
|
77209
|
+
case "--from-password": {
|
|
77210
|
+
fromPassword = readRequiredOptionValue(args, ++index, "--from-password");
|
|
77211
|
+
break;
|
|
77212
|
+
}
|
|
77213
|
+
default:
|
|
77214
|
+
if (arg.startsWith("-")) {
|
|
77215
|
+
throw new Error(`Unknown WAPK option: ${arg}`);
|
|
77216
|
+
}
|
|
77217
|
+
if (file) {
|
|
77218
|
+
throw new Error("Usage: elit wapk patch <file.wapk> --from <patch.wapk>");
|
|
77219
|
+
}
|
|
77220
|
+
file = arg;
|
|
77221
|
+
break;
|
|
77222
|
+
}
|
|
77223
|
+
}
|
|
77224
|
+
if (!file || !from) {
|
|
77225
|
+
throw new Error("Usage: elit wapk patch <file.wapk> --from <patch.wapk>");
|
|
77226
|
+
}
|
|
77227
|
+
return { file, from, password, fromPassword };
|
|
77228
|
+
}
|
|
76750
77229
|
async function readConfiguredWapkRunDefaults(cwd) {
|
|
76751
77230
|
const config = await loadConfig(cwd);
|
|
76752
77231
|
const runConfig = normalizeWapkRunConfig(config?.wapk?.run);
|
|
@@ -76786,6 +77265,7 @@ function resolveConfiguredWapkRunOptions(options, defaults) {
|
|
|
76786
77265
|
archiveSyncInterval: options.archiveSyncInterval ?? defaults?.archiveSyncInterval,
|
|
76787
77266
|
online: options.online ?? defaults?.online ?? Boolean(onlineUrl),
|
|
76788
77267
|
onlineUrl,
|
|
77268
|
+
allowSigtermClose: options.allowSigtermClose === true,
|
|
76789
77269
|
password: options.password ?? defaults?.password
|
|
76790
77270
|
};
|
|
76791
77271
|
}
|
|
@@ -76818,6 +77298,15 @@ async function runWapkCommand(args, cwd = process.cwd()) {
|
|
|
76818
77298
|
});
|
|
76819
77299
|
return;
|
|
76820
77300
|
}
|
|
77301
|
+
if (args[0] === "patch") {
|
|
77302
|
+
const options = parsePatchArgs(args.slice(1));
|
|
77303
|
+
await patchWapkArchive(options.file, {
|
|
77304
|
+
from: options.from,
|
|
77305
|
+
password: options.password,
|
|
77306
|
+
fromPassword: options.fromPassword
|
|
77307
|
+
});
|
|
77308
|
+
return;
|
|
77309
|
+
}
|
|
76821
77310
|
if (args[0] === "inspect") {
|
|
76822
77311
|
const options = parseArchiveAccessArgs(args.slice(1), "Usage: elit wapk inspect <file.wapk>");
|
|
76823
77312
|
inspectWapkArchive(options.file, options);
|
|
@@ -76846,6 +77335,7 @@ async function runWapkCommand(args, cwd = process.cwd()) {
|
|
|
76846
77335
|
await runWapkOnline(archiveSpecifier, {
|
|
76847
77336
|
googleDrive: runOptions.googleDrive,
|
|
76848
77337
|
onlineUrl: runOptions.onlineUrl,
|
|
77338
|
+
allowSigtermClose: runOptions.allowSigtermClose,
|
|
76849
77339
|
password: runOptions.password
|
|
76850
77340
|
});
|
|
76851
77341
|
return;
|
|
@@ -83169,6 +83659,7 @@ WAPK Options:
|
|
|
83169
83659
|
elit wapk run [file.wapk] Run a packaged app or the configured default archive
|
|
83170
83660
|
elit wapk run --google-drive-file-id <id> Run a packaged app directly from Google Drive
|
|
83171
83661
|
elit wapk pack [directory] Pack a directory into a .wapk archive
|
|
83662
|
+
elit wapk patch <file.wapk> --from <patch.wapk> Apply a manifest-driven patch archive
|
|
83172
83663
|
elit wapk inspect <file.wapk> Inspect a .wapk archive
|
|
83173
83664
|
elit wapk extract <file.wapk> Extract a .wapk archive
|
|
83174
83665
|
elit wapk --runtime node|bun|deno [file] Override the packaged runtime
|