elit 3.6.4 → 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/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/README.md +14 -1
- package/dist/build.d.ts +4 -1
- package/dist/cli.cjs +746 -166
- package/dist/cli.mjs +746 -166
- 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/test-runtime.cjs +184 -141
- package/dist/test-runtime.js +193 -150
- package/dist/test-runtime.mjs +184 -141
- package/dist/test.cjs +143 -134
- package/dist/test.js +152 -143
- package/dist/test.mjs +143 -134
- package/dist/types.d.ts +34 -2
- package/dist/universal.d.ts +2 -0
- package/package.json +9 -1
package/dist/cli.cjs
CHANGED
|
@@ -1992,8 +1992,8 @@ var require_chance = __commonJS({
|
|
|
1992
1992
|
return i;
|
|
1993
1993
|
});
|
|
1994
1994
|
}
|
|
1995
|
-
function testRange(
|
|
1996
|
-
if (
|
|
1995
|
+
function testRange(test, errorMessage) {
|
|
1996
|
+
if (test) {
|
|
1997
1997
|
throw new RangeError(errorMessage);
|
|
1998
1998
|
}
|
|
1999
1999
|
}
|
|
@@ -54898,12 +54898,126 @@ ${k.ValidationErrorsFormatter.format(i2)}`);
|
|
|
54898
54898
|
});
|
|
54899
54899
|
|
|
54900
54900
|
// src/test-runtime.ts
|
|
54901
|
-
function
|
|
54901
|
+
function escapeRegex2(str) {
|
|
54902
54902
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
54903
54903
|
}
|
|
54904
|
+
function resolveTestLoader(filePath) {
|
|
54905
|
+
return /\.(?:ts|tsx|mts|cts)$/i.test(filePath) ? "ts" : "js";
|
|
54906
|
+
}
|
|
54907
|
+
function createTestTransformOptions(filePath, format2, sourcemap) {
|
|
54908
|
+
return {
|
|
54909
|
+
loader: resolveTestLoader(filePath),
|
|
54910
|
+
format: format2,
|
|
54911
|
+
sourcemap,
|
|
54912
|
+
sourcefile: filePath,
|
|
54913
|
+
target: "es2020",
|
|
54914
|
+
tsconfigRaw: {
|
|
54915
|
+
compilerOptions: {
|
|
54916
|
+
jsx: "react",
|
|
54917
|
+
jsxFactory: "h",
|
|
54918
|
+
jsxFragmentFactory: "Fragment"
|
|
54919
|
+
}
|
|
54920
|
+
}
|
|
54921
|
+
};
|
|
54922
|
+
}
|
|
54923
|
+
function resolveExistingTestModulePath(basePath) {
|
|
54924
|
+
const nodePath = require("path");
|
|
54925
|
+
if (existsSync(basePath) && statSync(basePath).isFile()) {
|
|
54926
|
+
return basePath;
|
|
54927
|
+
}
|
|
54928
|
+
for (const extension of TEST_MODULE_EXTENSIONS) {
|
|
54929
|
+
const candidatePath = `${basePath}${extension}`;
|
|
54930
|
+
if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
|
|
54931
|
+
return candidatePath;
|
|
54932
|
+
}
|
|
54933
|
+
}
|
|
54934
|
+
if (existsSync(basePath) && statSync(basePath).isDirectory()) {
|
|
54935
|
+
const packageJsonPath = nodePath.join(basePath, "package.json");
|
|
54936
|
+
if (existsSync(packageJsonPath) && statSync(packageJsonPath).isFile()) {
|
|
54937
|
+
try {
|
|
54938
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
54939
|
+
for (const candidateEntry of [packageJson.main, packageJson.module]) {
|
|
54940
|
+
if (typeof candidateEntry !== "string" || candidateEntry.trim().length === 0) {
|
|
54941
|
+
continue;
|
|
54942
|
+
}
|
|
54943
|
+
try {
|
|
54944
|
+
return resolveExistingTestModulePath(nodePath.resolve(basePath, candidateEntry));
|
|
54945
|
+
} catch {
|
|
54946
|
+
continue;
|
|
54947
|
+
}
|
|
54948
|
+
}
|
|
54949
|
+
} catch {
|
|
54950
|
+
}
|
|
54951
|
+
}
|
|
54952
|
+
for (const extension of TEST_MODULE_EXTENSIONS) {
|
|
54953
|
+
const candidatePath = nodePath.join(basePath, `index${extension}`);
|
|
54954
|
+
if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
|
|
54955
|
+
return candidatePath;
|
|
54956
|
+
}
|
|
54957
|
+
}
|
|
54958
|
+
}
|
|
54959
|
+
return basePath;
|
|
54960
|
+
}
|
|
54961
|
+
function resolveTestModulePath(fromFilePath, specifier) {
|
|
54962
|
+
if (!specifier.startsWith(".") && !specifier.startsWith("/")) {
|
|
54963
|
+
return specifier;
|
|
54964
|
+
}
|
|
54965
|
+
const nodePath = require("path");
|
|
54966
|
+
const basePath = specifier.startsWith(".") ? nodePath.resolve(dirname(fromFilePath), specifier) : specifier;
|
|
54967
|
+
return resolveExistingTestModulePath(basePath);
|
|
54968
|
+
}
|
|
54969
|
+
function shouldTranspileTestModule(filePath) {
|
|
54970
|
+
return /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i.test(filePath);
|
|
54971
|
+
}
|
|
54972
|
+
function createTestModuleRequire(fromFilePath, moduleCache) {
|
|
54973
|
+
return (specifier) => {
|
|
54974
|
+
if (specifier.startsWith("elit/") || specifier === "elit") {
|
|
54975
|
+
return require(specifier);
|
|
54976
|
+
}
|
|
54977
|
+
const resolvedPath = resolveTestModulePath(fromFilePath, specifier);
|
|
54978
|
+
if (resolvedPath === specifier) {
|
|
54979
|
+
return require(specifier);
|
|
54980
|
+
}
|
|
54981
|
+
if (!existsSync(resolvedPath) || !statSync(resolvedPath).isFile()) {
|
|
54982
|
+
return require(resolvedPath);
|
|
54983
|
+
}
|
|
54984
|
+
if (!shouldTranspileTestModule(resolvedPath)) {
|
|
54985
|
+
return require(resolvedPath);
|
|
54986
|
+
}
|
|
54987
|
+
return loadTranspiledTestModule(resolvedPath, moduleCache);
|
|
54988
|
+
};
|
|
54989
|
+
}
|
|
54990
|
+
function loadTranspiledTestModule(modulePath, moduleCache) {
|
|
54991
|
+
const cached = moduleCache.get(modulePath);
|
|
54992
|
+
if (cached) {
|
|
54993
|
+
return cached.exports;
|
|
54994
|
+
}
|
|
54995
|
+
const source = readFileSync(modulePath, "utf-8");
|
|
54996
|
+
let transpiled;
|
|
54997
|
+
try {
|
|
54998
|
+
transpiled = (0, import_esbuild3.transformSync)(source, createTestTransformOptions(modulePath, "cjs", false));
|
|
54999
|
+
} catch (error) {
|
|
55000
|
+
throw new Error(`Failed to transpile test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
55001
|
+
}
|
|
55002
|
+
const moduleRecord = { exports: {} };
|
|
55003
|
+
const moduleObj = { exports: moduleRecord.exports };
|
|
55004
|
+
moduleCache.set(modulePath, moduleRecord);
|
|
55005
|
+
try {
|
|
55006
|
+
const fn = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
|
|
55007
|
+
const requireFn = createTestModuleRequire(modulePath, moduleCache);
|
|
55008
|
+
fn(moduleObj, moduleObj.exports, requireFn, modulePath, dirname(modulePath));
|
|
55009
|
+
} catch (error) {
|
|
55010
|
+
throw new Error(`Failed to execute test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
55011
|
+
}
|
|
55012
|
+
moduleRecord.exports = moduleObj.exports;
|
|
55013
|
+
if (!modulePath.includes(".test.") && !modulePath.includes(".spec.")) {
|
|
55014
|
+
coveredFiles.add(modulePath);
|
|
55015
|
+
}
|
|
55016
|
+
return moduleRecord.exports;
|
|
55017
|
+
}
|
|
54904
55018
|
function createTestFunction(defaultTimeout = 5e3) {
|
|
54905
55019
|
const testFn = function(name, fn, timeout) {
|
|
54906
|
-
const
|
|
55020
|
+
const test = {
|
|
54907
55021
|
name,
|
|
54908
55022
|
fn,
|
|
54909
55023
|
skip: currentSuite.skip,
|
|
@@ -54912,10 +55026,10 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54912
55026
|
timeout: timeout ?? defaultTimeout,
|
|
54913
55027
|
suite: currentSuite
|
|
54914
55028
|
};
|
|
54915
|
-
currentSuite.tests.push(
|
|
55029
|
+
currentSuite.tests.push(test);
|
|
54916
55030
|
};
|
|
54917
55031
|
testFn.skip = (name, fn, timeout) => {
|
|
54918
|
-
const
|
|
55032
|
+
const test = {
|
|
54919
55033
|
name,
|
|
54920
55034
|
fn,
|
|
54921
55035
|
skip: true,
|
|
@@ -54924,11 +55038,11 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54924
55038
|
timeout: timeout ?? defaultTimeout,
|
|
54925
55039
|
suite: currentSuite
|
|
54926
55040
|
};
|
|
54927
|
-
currentSuite.tests.push(
|
|
55041
|
+
currentSuite.tests.push(test);
|
|
54928
55042
|
};
|
|
54929
55043
|
testFn.only = (name, fn, timeout) => {
|
|
54930
55044
|
hasOnly = true;
|
|
54931
|
-
const
|
|
55045
|
+
const test = {
|
|
54932
55046
|
name,
|
|
54933
55047
|
fn,
|
|
54934
55048
|
skip: false,
|
|
@@ -54937,10 +55051,10 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54937
55051
|
timeout: timeout ?? defaultTimeout,
|
|
54938
55052
|
suite: currentSuite
|
|
54939
55053
|
};
|
|
54940
|
-
currentSuite.tests.push(
|
|
55054
|
+
currentSuite.tests.push(test);
|
|
54941
55055
|
};
|
|
54942
55056
|
testFn.todo = (name, fn, timeout) => {
|
|
54943
|
-
const
|
|
55057
|
+
const test = {
|
|
54944
55058
|
name,
|
|
54945
55059
|
fn,
|
|
54946
55060
|
skip: false,
|
|
@@ -54949,7 +55063,7 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54949
55063
|
timeout: timeout ?? defaultTimeout,
|
|
54950
55064
|
suite: currentSuite
|
|
54951
55065
|
};
|
|
54952
|
-
currentSuite.tests.push(
|
|
55066
|
+
currentSuite.tests.push(test);
|
|
54953
55067
|
};
|
|
54954
55068
|
return testFn;
|
|
54955
55069
|
}
|
|
@@ -55059,29 +55173,7 @@ async function runTests(options) {
|
|
|
55059
55173
|
try {
|
|
55060
55174
|
const source = await readFile(file, "utf-8");
|
|
55061
55175
|
const testFileDir = dirname(file);
|
|
55062
|
-
const
|
|
55063
|
-
const imports = {};
|
|
55064
|
-
let importIndex = 0;
|
|
55065
|
-
let codeWithoutImports = source.replace(importRegex, (_, named, path) => {
|
|
55066
|
-
const varName = `__import_${importIndex++}`;
|
|
55067
|
-
const trimmedNamed = named.trim();
|
|
55068
|
-
imports[varName] = { path, named: trimmedNamed };
|
|
55069
|
-
return `// ${trimmedNamed} import injected later
|
|
55070
|
-
`;
|
|
55071
|
-
});
|
|
55072
|
-
const result2 = (0, import_esbuild3.transformSync)(codeWithoutImports, {
|
|
55073
|
-
loader: file.endsWith(".ts") || file.endsWith(".tsx") ? "ts" : "js",
|
|
55074
|
-
format: "iife",
|
|
55075
|
-
sourcemap: "inline",
|
|
55076
|
-
target: "es2020",
|
|
55077
|
-
tsconfigRaw: {
|
|
55078
|
-
compilerOptions: {
|
|
55079
|
-
jsx: "react",
|
|
55080
|
-
jsxFactory: "h",
|
|
55081
|
-
jsxFragmentFactory: "Fragment"
|
|
55082
|
-
}
|
|
55083
|
-
}
|
|
55084
|
-
});
|
|
55176
|
+
const result2 = (0, import_esbuild3.transformSync)(source, createTestTransformOptions(file, "cjs", "inline"));
|
|
55085
55177
|
let code = result2.code;
|
|
55086
55178
|
const sourceMapMatch = code.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.+)/);
|
|
55087
55179
|
if (sourceMapMatch) {
|
|
@@ -55092,99 +55184,15 @@ async function runTests(options) {
|
|
|
55092
55184
|
} else {
|
|
55093
55185
|
currentSourceMapConsumer = void 0;
|
|
55094
55186
|
}
|
|
55095
|
-
|
|
55096
|
-
const importParamNames = [];
|
|
55097
|
-
const importAssignments = [];
|
|
55098
|
-
if (Object.keys(imports).length > 0) {
|
|
55099
|
-
for (const [, { path, named }] of Object.entries(imports)) {
|
|
55100
|
-
let resolvedPath = path;
|
|
55101
|
-
if (path.startsWith(".")) {
|
|
55102
|
-
const nodePath = require("path");
|
|
55103
|
-
resolvedPath = nodePath.resolve(testFileDir, path);
|
|
55104
|
-
}
|
|
55105
|
-
if (!resolvedPath.endsWith(".ts") && !resolvedPath.endsWith(".js") && !resolvedPath.endsWith(".mjs") && !resolvedPath.endsWith(".cjs")) {
|
|
55106
|
-
resolvedPath += ".ts";
|
|
55107
|
-
}
|
|
55108
|
-
if (resolvedPath.endsWith(".ts")) {
|
|
55109
|
-
try {
|
|
55110
|
-
const importSource = await readFile(resolvedPath, "utf-8");
|
|
55111
|
-
const transpiled = (0, import_esbuild3.transformSync)(importSource, {
|
|
55112
|
-
loader: "ts",
|
|
55113
|
-
format: "cjs",
|
|
55114
|
-
target: "es2020",
|
|
55115
|
-
tsconfigRaw: {
|
|
55116
|
-
compilerOptions: {
|
|
55117
|
-
jsx: "react",
|
|
55118
|
-
jsxFactory: "h",
|
|
55119
|
-
jsxFragmentFactory: "Fragment"
|
|
55120
|
-
}
|
|
55121
|
-
}
|
|
55122
|
-
});
|
|
55123
|
-
const moduleExports = {};
|
|
55124
|
-
const moduleObj = { exports: moduleExports };
|
|
55125
|
-
const fn2 = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
|
|
55126
|
-
const requireFn = (id) => {
|
|
55127
|
-
if (id.startsWith("elit/") || id === "elit") {
|
|
55128
|
-
return require(id);
|
|
55129
|
-
}
|
|
55130
|
-
if (id.startsWith(".")) {
|
|
55131
|
-
const nodePath = require("path");
|
|
55132
|
-
const absPath = nodePath.resolve(dirname(resolvedPath), id);
|
|
55133
|
-
return require(absPath);
|
|
55134
|
-
}
|
|
55135
|
-
return require(id);
|
|
55136
|
-
};
|
|
55137
|
-
fn2(moduleObj, moduleExports, requireFn, resolvedPath, dirname(resolvedPath));
|
|
55138
|
-
if (!resolvedPath.includes(".test.") && !resolvedPath.includes(".spec.")) {
|
|
55139
|
-
coveredFiles.add(resolvedPath);
|
|
55140
|
-
}
|
|
55141
|
-
let exportedValue = moduleObj.exports[named];
|
|
55142
|
-
if (exportedValue === void 0 && moduleObj.exports.default) {
|
|
55143
|
-
exportedValue = moduleObj.exports.default[named];
|
|
55144
|
-
}
|
|
55145
|
-
if (exportedValue === void 0 && typeof moduleObj.exports === "object") {
|
|
55146
|
-
exportedValue = moduleObj.exports[named];
|
|
55147
|
-
}
|
|
55148
|
-
const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
|
|
55149
|
-
importedValues[paramKey] = exportedValue;
|
|
55150
|
-
importParamNames.push(paramKey);
|
|
55151
|
-
importAssignments.push(`const ${named} = ${paramKey};`);
|
|
55152
|
-
} catch (err) {
|
|
55153
|
-
const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
|
|
55154
|
-
importedValues[paramKey] = null;
|
|
55155
|
-
importParamNames.push(paramKey);
|
|
55156
|
-
importAssignments.push(`const ${named} = ${paramKey}; /* Error importing ${resolvedPath}: ${err} */`);
|
|
55157
|
-
}
|
|
55158
|
-
} else {
|
|
55159
|
-
const requiredModule = require(resolvedPath);
|
|
55160
|
-
const exportedValue = requiredModule[named];
|
|
55161
|
-
const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
|
|
55162
|
-
importedValues[paramKey] = exportedValue;
|
|
55163
|
-
importParamNames.push(paramKey);
|
|
55164
|
-
importAssignments.push(`const ${named} = ${paramKey};`);
|
|
55165
|
-
}
|
|
55166
|
-
}
|
|
55167
|
-
}
|
|
55168
|
-
let preamble = "";
|
|
55169
|
-
if (Object.keys(imports).length > 0) {
|
|
55170
|
-
const iifeStartMatch = code.match(/^(\s*(?:var\s+\w+\s*=\s*)?\(\(\)\s*=>\s*\{\n)/);
|
|
55171
|
-
if (iifeStartMatch) {
|
|
55172
|
-
const iifePrefix = iifeStartMatch[1];
|
|
55173
|
-
const assignments = `${importAssignments.join("\n")}
|
|
55174
|
-
`;
|
|
55175
|
-
preamble = iifePrefix;
|
|
55176
|
-
code = iifePrefix + assignments + code.slice(iifeStartMatch[1].length);
|
|
55177
|
-
} else {
|
|
55178
|
-
preamble = importAssignments.join("\n") + "\n";
|
|
55179
|
-
code = preamble + code;
|
|
55180
|
-
}
|
|
55181
|
-
}
|
|
55182
|
-
wrapperLineOffset = preamble.split("\n").length;
|
|
55187
|
+
wrapperLineOffset = 0;
|
|
55183
55188
|
setupGlobals();
|
|
55184
|
-
const
|
|
55185
|
-
const
|
|
55186
|
-
const
|
|
55187
|
-
|
|
55189
|
+
const moduleCache = /* @__PURE__ */ new Map();
|
|
55190
|
+
const moduleRecord = { exports: {} };
|
|
55191
|
+
const moduleObj = { exports: moduleRecord.exports };
|
|
55192
|
+
moduleCache.set(file, moduleRecord);
|
|
55193
|
+
const fn = new Function("module", "exports", "require", "__filename", "__dirname", code);
|
|
55194
|
+
const requireFn = createTestModuleRequire(file, moduleCache);
|
|
55195
|
+
await fn(moduleObj, moduleObj.exports, requireFn, file, testFileDir);
|
|
55188
55196
|
await executeSuite(currentSuite, timeout, bail);
|
|
55189
55197
|
if (currentSourceMapConsumer) {
|
|
55190
55198
|
currentSourceMapConsumer.destroy();
|
|
@@ -55219,13 +55227,13 @@ async function runTests(options) {
|
|
|
55219
55227
|
async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
55220
55228
|
let directMatch = false;
|
|
55221
55229
|
if (describePattern) {
|
|
55222
|
-
const escapedPattern =
|
|
55230
|
+
const escapedPattern = escapeRegex2(describePattern);
|
|
55223
55231
|
const regex = new RegExp(escapedPattern, "i");
|
|
55224
55232
|
directMatch = regex.test(suite.name);
|
|
55225
55233
|
}
|
|
55226
55234
|
function suiteOrDescendantMatches(s) {
|
|
55227
55235
|
if (!describePattern) return true;
|
|
55228
|
-
const escapedPattern =
|
|
55236
|
+
const escapedPattern = escapeRegex2(describePattern);
|
|
55229
55237
|
const regex = new RegExp(escapedPattern, "i");
|
|
55230
55238
|
if (regex.test(s.name)) return true;
|
|
55231
55239
|
for (const child of s.suites) {
|
|
@@ -55249,22 +55257,22 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55249
55257
|
for (const hook of beforeAllHooks) {
|
|
55250
55258
|
await hook();
|
|
55251
55259
|
}
|
|
55252
|
-
for (const
|
|
55253
|
-
if (hasOnly && !
|
|
55260
|
+
for (const test of suite.tests) {
|
|
55261
|
+
if (hasOnly && !test.only && !suite.only) {
|
|
55254
55262
|
continue;
|
|
55255
55263
|
}
|
|
55256
55264
|
let testMatches = true;
|
|
55257
55265
|
if (testPattern) {
|
|
55258
|
-
const escapedPattern =
|
|
55266
|
+
const escapedPattern = escapeRegex2(testPattern);
|
|
55259
55267
|
const regex = new RegExp(escapedPattern, "i");
|
|
55260
|
-
testMatches = regex.test(
|
|
55268
|
+
testMatches = regex.test(test.name);
|
|
55261
55269
|
}
|
|
55262
55270
|
if (!testMatches) {
|
|
55263
55271
|
continue;
|
|
55264
55272
|
}
|
|
55265
|
-
if (
|
|
55273
|
+
if (test.skip || suite.skip) {
|
|
55266
55274
|
testResults.push({
|
|
55267
|
-
name:
|
|
55275
|
+
name: test.name,
|
|
55268
55276
|
status: "skip",
|
|
55269
55277
|
duration: 0,
|
|
55270
55278
|
suite: suite.name,
|
|
@@ -55272,9 +55280,9 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55272
55280
|
});
|
|
55273
55281
|
continue;
|
|
55274
55282
|
}
|
|
55275
|
-
if (
|
|
55283
|
+
if (test.todo) {
|
|
55276
55284
|
testResults.push({
|
|
55277
|
-
name:
|
|
55285
|
+
name: test.name,
|
|
55278
55286
|
status: "todo",
|
|
55279
55287
|
duration: 0,
|
|
55280
55288
|
suite: suite.name,
|
|
@@ -55288,13 +55296,13 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55288
55296
|
const startTime = Date.now();
|
|
55289
55297
|
try {
|
|
55290
55298
|
await Promise.race([
|
|
55291
|
-
|
|
55299
|
+
test.fn(),
|
|
55292
55300
|
new Promise(
|
|
55293
|
-
(_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${
|
|
55301
|
+
(_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${test.timeout}ms`)), test.timeout)
|
|
55294
55302
|
)
|
|
55295
55303
|
]);
|
|
55296
55304
|
testResults.push({
|
|
55297
|
-
name:
|
|
55305
|
+
name: test.name,
|
|
55298
55306
|
status: "pass",
|
|
55299
55307
|
duration: Date.now() - startTime,
|
|
55300
55308
|
suite: suite.name,
|
|
@@ -55308,7 +55316,7 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55308
55316
|
codeSnippet = error.codeSnippet;
|
|
55309
55317
|
}
|
|
55310
55318
|
testResults.push({
|
|
55311
|
-
name:
|
|
55319
|
+
name: test.name,
|
|
55312
55320
|
status: "fail",
|
|
55313
55321
|
duration: Date.now() - startTime,
|
|
55314
55322
|
error,
|
|
@@ -55357,7 +55365,7 @@ function getCoveredFiles() {
|
|
|
55357
55365
|
function resetCoveredFiles() {
|
|
55358
55366
|
coveredFiles.clear();
|
|
55359
55367
|
}
|
|
55360
|
-
var import_esbuild3, import_source_map, AssertionError, currentSuite, testResults, hasOnly, coveredFiles, describePattern, testPattern, currentTestFile, currentSourceMapConsumer, wrapperLineOffset, Expect, vi, beforeAllHooks, afterAllHooks, beforeEachHooks, afterEachHooks, beforeAll, afterAll, beforeEach, afterEach, globals;
|
|
55368
|
+
var import_esbuild3, import_source_map, AssertionError, currentSuite, testResults, hasOnly, coveredFiles, describePattern, testPattern, currentTestFile, currentSourceMapConsumer, wrapperLineOffset, TEST_MODULE_EXTENSIONS, Expect, vi, beforeAllHooks, afterAllHooks, beforeEachHooks, afterEachHooks, beforeAll, afterAll, beforeEach, afterEach, globals;
|
|
55361
55369
|
var init_test_runtime = __esm({
|
|
55362
55370
|
"src/test-runtime.ts"() {
|
|
55363
55371
|
"use strict";
|
|
@@ -55390,6 +55398,7 @@ var init_test_runtime = __esm({
|
|
|
55390
55398
|
currentTestFile = void 0;
|
|
55391
55399
|
currentSourceMapConsumer = void 0;
|
|
55392
55400
|
wrapperLineOffset = 0;
|
|
55401
|
+
TEST_MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
|
|
55393
55402
|
Expect = class _Expect {
|
|
55394
55403
|
constructor(actual, isNot = false, isAsync = false) {
|
|
55395
55404
|
this.actual = actual;
|
|
@@ -60475,6 +60484,71 @@ function lookup(path) {
|
|
|
60475
60484
|
// src/server.ts
|
|
60476
60485
|
init_runtime();
|
|
60477
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
|
+
|
|
60478
60552
|
// src/render-context.ts
|
|
60479
60553
|
var RUNTIME_TARGET_KEY = "__ELIT_RUNTIME_TARGET__";
|
|
60480
60554
|
var CAPTURED_RENDER_KEY = "__ELIT_CAPTURED_RENDER__";
|
|
@@ -60928,6 +61002,7 @@ var DomNode = class {
|
|
|
60928
61002
|
html += `</${tagName}>${newLine}`;
|
|
60929
61003
|
return html;
|
|
60930
61004
|
}
|
|
61005
|
+
const isRawText = tagName === "script" || tagName === "style";
|
|
60931
61006
|
if (children && children.length > 0) {
|
|
60932
61007
|
const resolvedChildren = children.map((c) => {
|
|
60933
61008
|
const resolved = this.resolveStateValue(c);
|
|
@@ -60943,11 +61018,11 @@ var DomNode = class {
|
|
|
60943
61018
|
if (Array.isArray(child)) {
|
|
60944
61019
|
for (const c of child) {
|
|
60945
61020
|
if (!shouldSkipChild(c)) {
|
|
60946
|
-
html += this.renderToString(c, { pretty, indent: indent5 + 1 });
|
|
61021
|
+
html += isRawText && typeof c === "string" ? c : this.renderToString(c, { pretty, indent: indent5 + 1 });
|
|
60947
61022
|
}
|
|
60948
61023
|
}
|
|
60949
61024
|
} else {
|
|
60950
|
-
html += this.renderToString(child, { pretty, indent: indent5 + 1 });
|
|
61025
|
+
html += isRawText && typeof child === "string" ? child : this.renderToString(child, { pretty, indent: indent5 + 1 });
|
|
60951
61026
|
}
|
|
60952
61027
|
}
|
|
60953
61028
|
html += indentStr;
|
|
@@ -60957,11 +61032,11 @@ var DomNode = class {
|
|
|
60957
61032
|
if (Array.isArray(child)) {
|
|
60958
61033
|
for (const c of child) {
|
|
60959
61034
|
if (!shouldSkipChild(c)) {
|
|
60960
|
-
html += this.renderToString(c, { pretty: false, indent: 0 });
|
|
61035
|
+
html += isRawText && typeof c === "string" ? c : this.renderToString(c, { pretty: false, indent: 0 });
|
|
60961
61036
|
}
|
|
60962
61037
|
}
|
|
60963
61038
|
} else {
|
|
60964
|
-
html += this.renderToString(child, { pretty: false, indent: 0 });
|
|
61039
|
+
html += isRawText && typeof child === "string" ? child : this.renderToString(child, { pretty: false, indent: 0 });
|
|
60965
61040
|
}
|
|
60966
61041
|
}
|
|
60967
61042
|
}
|
|
@@ -61889,6 +61964,56 @@ var defaultOptions = {
|
|
|
61889
61964
|
worker: [],
|
|
61890
61965
|
mode: "dev"
|
|
61891
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
|
+
}
|
|
61892
62017
|
function shouldUseClientFallbackRoot(primaryRoot, fallbackRoot, indexPath) {
|
|
61893
62018
|
if (!fallbackRoot) {
|
|
61894
62019
|
return false;
|
|
@@ -62023,6 +62148,7 @@ function createDevServer(options) {
|
|
|
62023
62148
|
const globalWebSocketEndpoints = usesClientArray ? normalizeWebSocketEndpoints(config.ws) : [];
|
|
62024
62149
|
const normalizedWebSocketEndpoints = [...normalizedClients.flatMap((client) => client.ws), ...globalWebSocketEndpoints];
|
|
62025
62150
|
const seenWebSocketPaths = /* @__PURE__ */ new Set();
|
|
62151
|
+
const smtpServerConfigs = collectSmtpServerConfigs(config, usesClientArray);
|
|
62026
62152
|
for (const endpoint of normalizedWebSocketEndpoints) {
|
|
62027
62153
|
if (endpoint.path === ELIT_INTERNAL_WS_PATH) {
|
|
62028
62154
|
throw new Error(`WebSocket path "${ELIT_INTERNAL_WS_PATH}" is reserved for Elit internals`);
|
|
@@ -62032,6 +62158,21 @@ function createDevServer(options) {
|
|
|
62032
62158
|
}
|
|
62033
62159
|
seenWebSocketPaths.add(endpoint.path);
|
|
62034
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
|
+
});
|
|
62035
62176
|
const globalProxyHandler = config.proxy ? createProxyHandler(config.proxy) : null;
|
|
62036
62177
|
const server = createServer(async (req, res) => {
|
|
62037
62178
|
const originalUrl = req.url || "/";
|
|
@@ -62572,6 +62713,15 @@ ${elitImportMap}`;
|
|
|
62572
62713
|
if (config.logging) console.log("\n[Server] Shutting down...");
|
|
62573
62714
|
transformCache.clear();
|
|
62574
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
|
+
}
|
|
62575
62725
|
if (webSocketServers.length > 0) {
|
|
62576
62726
|
webSocketServers.forEach((wsServer) => wsServer.close());
|
|
62577
62727
|
wsClients.clear();
|
|
@@ -62588,6 +62738,7 @@ ${elitImportMap}`;
|
|
|
62588
62738
|
return {
|
|
62589
62739
|
server,
|
|
62590
62740
|
wss,
|
|
62741
|
+
smtpServers,
|
|
62591
62742
|
url: primaryUrl,
|
|
62592
62743
|
state: stateManager,
|
|
62593
62744
|
close
|
|
@@ -74467,7 +74618,7 @@ var WAPK_AUTH_TAG_LENGTH = 16;
|
|
|
74467
74618
|
var WAPK_SCRYPT_OPTIONS = { N: 16384, r: 8, p: 1 };
|
|
74468
74619
|
var DEFAULT_GOOGLE_DRIVE_TOKEN_ENV = "GOOGLE_DRIVE_ACCESS_TOKEN";
|
|
74469
74620
|
var DEFAULT_WAPK_ONLINE_URL_ENV = "ELIT_WAPK_ONLINE_URL";
|
|
74470
|
-
var DEFAULT_WAPK_ONLINE_URLS = ["
|
|
74621
|
+
var DEFAULT_WAPK_ONLINE_URLS = ["http://wapk.d-osc.com/"];
|
|
74471
74622
|
var WAPK_ONLINE_CREATE_PATH = "/api/shared-session/create";
|
|
74472
74623
|
var WAPK_ONLINE_READ_PATH = "/api/shared-session/read";
|
|
74473
74624
|
var WAPK_ONLINE_CLOSE_PATH = "/api/shared-session/close";
|
|
@@ -74505,6 +74656,113 @@ function normalizeNonEmptyString(value) {
|
|
|
74505
74656
|
const normalized = value.trim();
|
|
74506
74657
|
return normalized.length > 0 ? normalized : void 0;
|
|
74507
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
|
+
}
|
|
74508
74766
|
function normalizeStringMap(value) {
|
|
74509
74767
|
if (!isRecord(value)) {
|
|
74510
74768
|
return void 0;
|
|
@@ -74544,6 +74802,8 @@ function normalizeWapkConfig(value) {
|
|
|
74544
74802
|
runtime: normalizeRuntime(value.runtime ?? value.engine),
|
|
74545
74803
|
entry: typeof value.entry === "string" ? value.entry : void 0,
|
|
74546
74804
|
scripts: normalizeStringMap(value.scripts ?? value.script),
|
|
74805
|
+
appId: normalizeNonEmptyString(value.appId),
|
|
74806
|
+
publisherId: normalizeNonEmptyString(value.publisherId),
|
|
74547
74807
|
port: normalizePort(value.port),
|
|
74548
74808
|
env: normalizeStringMap(value.env),
|
|
74549
74809
|
desktop: normalizeDesktopConfig(value.desktop),
|
|
@@ -74833,6 +75093,7 @@ async function readWapkProjectConfig(directory) {
|
|
|
74833
75093
|
const elitConfig = await loadConfig(directory);
|
|
74834
75094
|
const elitWapkConfig = normalizeWapkConfig(elitConfig?.wapk);
|
|
74835
75095
|
const packageJson = readJsonFile(packageJsonPath);
|
|
75096
|
+
const packageJsonWapk = isRecord(packageJson?.wapk) ? packageJson.wapk : void 0;
|
|
74836
75097
|
const packageScripts = normalizeStringMap(packageJson?.scripts) ?? {};
|
|
74837
75098
|
const selectedScripts = elitWapkConfig.scripts ?? packageScripts;
|
|
74838
75099
|
const inferred = inferRuntimeAndEntryFromScript(selectedScripts.start ?? packageScripts.start);
|
|
@@ -74856,12 +75117,16 @@ async function readWapkProjectConfig(directory) {
|
|
|
74856
75117
|
if (!(0, import_node_fs2.existsSync)(entryPath) || !(0, import_node_fs2.statSync)(entryPath).isFile()) {
|
|
74857
75118
|
throw new Error(`WAPK entry not found: ${entryPath}`);
|
|
74858
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);
|
|
74859
75122
|
return {
|
|
74860
75123
|
name,
|
|
74861
75124
|
version,
|
|
74862
75125
|
runtime: runtime2,
|
|
74863
75126
|
entry,
|
|
74864
75127
|
scripts: selectedScripts,
|
|
75128
|
+
appId,
|
|
75129
|
+
publisherId,
|
|
74865
75130
|
port: elitWapkConfig.port,
|
|
74866
75131
|
env: elitWapkConfig.env,
|
|
74867
75132
|
desktop: elitWapkConfig.desktop,
|
|
@@ -74871,11 +75136,14 @@ async function readWapkProjectConfig(directory) {
|
|
|
74871
75136
|
function readIgnorePatterns(directory) {
|
|
74872
75137
|
return readLineIgnorePatterns((0, import_node_path2.join)(directory, ".wapkignore"));
|
|
74873
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
|
+
}
|
|
74874
75142
|
function readLineIgnorePatterns(filePath) {
|
|
74875
75143
|
if (!(0, import_node_fs2.existsSync)(filePath)) {
|
|
74876
75144
|
return [];
|
|
74877
75145
|
}
|
|
74878
|
-
return (0, import_node_fs2.readFileSync)(filePath, "utf8")
|
|
75146
|
+
return parsePatternLines((0, import_node_fs2.readFileSync)(filePath, "utf8"));
|
|
74879
75147
|
}
|
|
74880
75148
|
function normalizePackageEntry(value) {
|
|
74881
75149
|
const normalized = normalizeNonEmptyString(value)?.replace(/^[.][\\/]/, "").split("\\").join("/");
|
|
@@ -75056,23 +75324,188 @@ function resolveLinkedDependencyArchivePrefix(archivePrefix, dependencyName) {
|
|
|
75056
75324
|
}
|
|
75057
75325
|
return `${normalizedPrefix.slice(0, markerIndex + marker.length)}${dependencyName}`;
|
|
75058
75326
|
}
|
|
75059
|
-
function
|
|
75060
|
-
|
|
75327
|
+
function escapeRegex(text) {
|
|
75328
|
+
return text.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
|
|
75329
|
+
}
|
|
75330
|
+
function globPatternToRegex(pattern, options = {}) {
|
|
75331
|
+
let regex = "";
|
|
75332
|
+
for (let index = 0; index < pattern.length; index++) {
|
|
75333
|
+
const char = pattern[index];
|
|
75334
|
+
if (char === "*") {
|
|
75335
|
+
const nextChar = pattern[index + 1];
|
|
75336
|
+
const nextNextChar = pattern[index + 2];
|
|
75337
|
+
if (nextChar === "*") {
|
|
75338
|
+
if (nextNextChar === "/") {
|
|
75339
|
+
regex += "(?:.*?/)?";
|
|
75340
|
+
index += 2;
|
|
75341
|
+
continue;
|
|
75342
|
+
}
|
|
75343
|
+
regex += ".*";
|
|
75344
|
+
index += 1;
|
|
75345
|
+
continue;
|
|
75346
|
+
}
|
|
75347
|
+
regex += "[^/]*";
|
|
75348
|
+
continue;
|
|
75349
|
+
}
|
|
75350
|
+
if (char === "?") {
|
|
75351
|
+
regex += "[^/]";
|
|
75352
|
+
continue;
|
|
75353
|
+
}
|
|
75354
|
+
regex += escapeRegex(char);
|
|
75355
|
+
}
|
|
75356
|
+
const suffix = options.directoryOnly ? "(?:$|/.*)" : "$";
|
|
75357
|
+
const prefix = options.matchSegmentsOnly ? "^(?:.*?/)?" : "^";
|
|
75358
|
+
return new RegExp(`${prefix}${regex}${suffix}`);
|
|
75359
|
+
}
|
|
75360
|
+
function normalizeIgnorePattern(pattern) {
|
|
75361
|
+
let normalizedPattern = pattern.trim();
|
|
75362
|
+
if (!normalizedPattern) {
|
|
75363
|
+
return void 0;
|
|
75364
|
+
}
|
|
75365
|
+
let negate = false;
|
|
75366
|
+
if (normalizedPattern.startsWith("\\!") || normalizedPattern.startsWith("\\#")) {
|
|
75367
|
+
normalizedPattern = normalizedPattern.slice(1);
|
|
75368
|
+
} else if (normalizedPattern.startsWith("!")) {
|
|
75369
|
+
negate = true;
|
|
75370
|
+
normalizedPattern = normalizedPattern.slice(1).trim();
|
|
75371
|
+
}
|
|
75372
|
+
if (!normalizedPattern) {
|
|
75373
|
+
return void 0;
|
|
75374
|
+
}
|
|
75375
|
+
const directoryOnly = normalizedPattern.endsWith("/");
|
|
75376
|
+
if (directoryOnly) {
|
|
75377
|
+
normalizedPattern = normalizedPattern.replace(/\/+$/, "");
|
|
75378
|
+
}
|
|
75379
|
+
normalizedPattern = normalizedPattern.replace(/^\.\//, "").replace(/^\//, "").replace(/\\/g, "/");
|
|
75380
|
+
if (!normalizedPattern) {
|
|
75381
|
+
return void 0;
|
|
75382
|
+
}
|
|
75383
|
+
return {
|
|
75384
|
+
directoryOnly,
|
|
75385
|
+
matchSegmentsOnly: !normalizedPattern.includes("/"),
|
|
75386
|
+
negate,
|
|
75387
|
+
pattern: normalizedPattern
|
|
75388
|
+
};
|
|
75389
|
+
}
|
|
75390
|
+
function matchesIgnorePattern(relativePath2, pattern, isDirectory) {
|
|
75391
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75392
|
+
if (!normalizedRule) {
|
|
75393
|
+
return false;
|
|
75394
|
+
}
|
|
75395
|
+
if (normalizedRule.directoryOnly && !isDirectory) {
|
|
75396
|
+
return false;
|
|
75397
|
+
}
|
|
75398
|
+
const hasGlob = /[*?]/.test(normalizedRule.pattern);
|
|
75399
|
+
if (!hasGlob) {
|
|
75400
|
+
if (normalizedRule.matchSegmentsOnly) {
|
|
75401
|
+
return relativePath2 === normalizedRule.pattern || relativePath2.split("/").includes(normalizedRule.pattern);
|
|
75402
|
+
}
|
|
75403
|
+
return relativePath2 === normalizedRule.pattern;
|
|
75404
|
+
}
|
|
75405
|
+
if (normalizedRule.matchSegmentsOnly) {
|
|
75406
|
+
const segmentRegex = globPatternToRegex(normalizedRule.pattern);
|
|
75407
|
+
return relativePath2.split("/").some((segment) => segmentRegex.test(segment));
|
|
75408
|
+
}
|
|
75409
|
+
return globPatternToRegex(normalizedRule.pattern, { directoryOnly: normalizedRule.directoryOnly }).test(relativePath2);
|
|
75410
|
+
}
|
|
75411
|
+
function shouldIgnore(relativePath2, ignorePatterns, isDirectory) {
|
|
75412
|
+
let ignored = false;
|
|
75061
75413
|
for (const pattern of ignorePatterns) {
|
|
75062
|
-
|
|
75063
|
-
|
|
75414
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75415
|
+
if (!normalizedRule) {
|
|
75416
|
+
continue;
|
|
75064
75417
|
}
|
|
75065
|
-
if (pattern
|
|
75066
|
-
|
|
75067
|
-
if (relativePath2.startsWith(prefix) || pathParts.some((part) => part.startsWith(prefix))) {
|
|
75068
|
-
return true;
|
|
75069
|
-
}
|
|
75418
|
+
if (!matchesIgnorePattern(relativePath2, pattern, isDirectory)) {
|
|
75419
|
+
continue;
|
|
75070
75420
|
}
|
|
75071
|
-
|
|
75072
|
-
|
|
75421
|
+
ignored = !normalizedRule.negate;
|
|
75422
|
+
}
|
|
75423
|
+
return ignored;
|
|
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;
|
|
75073
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);
|
|
75074
75495
|
}
|
|
75075
|
-
return
|
|
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
|
+
};
|
|
75076
75509
|
}
|
|
75077
75510
|
function collectFiles(directory, baseDirectory, ignorePatterns) {
|
|
75078
75511
|
const files = [];
|
|
@@ -75080,7 +75513,7 @@ function collectFiles(directory, baseDirectory, ignorePatterns) {
|
|
|
75080
75513
|
for (const entry of entries) {
|
|
75081
75514
|
const fullPath = (0, import_node_path2.join)(directory, entry.name);
|
|
75082
75515
|
const relativePath2 = (0, import_node_path2.relative)(baseDirectory, fullPath).split("\\").join("/");
|
|
75083
|
-
if (shouldIgnore(relativePath2, ignorePatterns)) {
|
|
75516
|
+
if (shouldIgnore(relativePath2, ignorePatterns, entry.isDirectory())) {
|
|
75084
75517
|
continue;
|
|
75085
75518
|
}
|
|
75086
75519
|
if (entry.isSymbolicLink()) {
|
|
@@ -75229,6 +75662,8 @@ function decodeWapkPayload(buffer) {
|
|
|
75229
75662
|
runtime: normalizeRuntime(rawHeader.runtime ?? rawHeader.engine) ?? "node",
|
|
75230
75663
|
entry: typeof rawHeader.entry === "string" ? rawHeader.entry : "index.js",
|
|
75231
75664
|
scripts: normalizeStringMap(rawHeader.scripts) ?? {},
|
|
75665
|
+
appId: normalizeNonEmptyString(rawHeader.appId),
|
|
75666
|
+
publisherId: normalizeNonEmptyString(rawHeader.publisherId),
|
|
75232
75667
|
port: normalizePort(rawHeader.port),
|
|
75233
75668
|
env: normalizeStringMap(rawHeader.env),
|
|
75234
75669
|
desktop: normalizeDesktopConfig(rawHeader.desktop),
|
|
@@ -75726,11 +76161,14 @@ function sanitizeOnlineArchiveFileName(label, fallback) {
|
|
|
75726
76161
|
const fileName = sanitized.length > 0 ? sanitized : "app.wapk";
|
|
75727
76162
|
return fileName.toLowerCase().endsWith(".wapk") ? fileName : `${fileName}.wapk`;
|
|
75728
76163
|
}
|
|
76164
|
+
var WAPK_ONLINE_JOIN_SOURCE_QUERY_PARAM = "launchSource";
|
|
76165
|
+
var WAPK_ONLINE_JOIN_SOURCE_QUERY_VALUE = "elit-wapk-online";
|
|
75729
76166
|
function buildOnlineJoinUrl(baseUrl, joinKey) {
|
|
75730
76167
|
const joinUrl = new URL(baseUrl.toString());
|
|
75731
76168
|
joinUrl.search = "";
|
|
75732
76169
|
joinUrl.hash = "";
|
|
75733
76170
|
joinUrl.searchParams.set("join", joinKey);
|
|
76171
|
+
joinUrl.searchParams.set(WAPK_ONLINE_JOIN_SOURCE_QUERY_PARAM, WAPK_ONLINE_JOIN_SOURCE_QUERY_VALUE);
|
|
75734
76172
|
return joinUrl.toString();
|
|
75735
76173
|
}
|
|
75736
76174
|
async function probeOnlineLauncherUrl(url) {
|
|
@@ -75911,11 +76349,16 @@ async function closeWapkOnlineSharedSession(launcherUrl, session) {
|
|
|
75911
76349
|
function isPmWapkOnlineShutdownEnabled() {
|
|
75912
76350
|
return process.env[WAPK_ONLINE_PM_SHUTDOWN_ENV] === "1" && Boolean(process.stdin) && !process.stdin.isTTY;
|
|
75913
76351
|
}
|
|
75914
|
-
|
|
76352
|
+
function getWapkOnlineProcessDetails() {
|
|
76353
|
+
return `pid ${process.pid}, ppid ${process.ppid}`;
|
|
76354
|
+
}
|
|
76355
|
+
async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHandle, lock, options = {}) {
|
|
75915
76356
|
let snapshotRevision = 0;
|
|
75916
76357
|
let snapshotSyncPending = false;
|
|
75917
76358
|
let snapshotSyncPromise = Promise.resolve();
|
|
75918
76359
|
let lastSnapshotSyncError = null;
|
|
76360
|
+
const allowSigtermClose = options.allowSigtermClose === true;
|
|
76361
|
+
const processDetails = getWapkOnlineProcessDetails();
|
|
75919
76362
|
const syncGuestSnapshotUpdates = () => {
|
|
75920
76363
|
if (snapshotSyncPending) {
|
|
75921
76364
|
return snapshotSyncPromise;
|
|
@@ -75949,6 +76392,7 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
75949
76392
|
void syncGuestSnapshotUpdates();
|
|
75950
76393
|
}, WAPK_ONLINE_KEEPALIVE_INTERVAL_MS);
|
|
75951
76394
|
const pmManaged = isPmWapkOnlineShutdownEnabled();
|
|
76395
|
+
let ignoredSigTermLogged = false;
|
|
75952
76396
|
let stdinBuffer = "";
|
|
75953
76397
|
const cleanup = () => {
|
|
75954
76398
|
clearInterval(keepAlive);
|
|
@@ -75967,7 +76411,17 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
75967
76411
|
finish({ kind: "signal", signal: "SIGINT" });
|
|
75968
76412
|
};
|
|
75969
76413
|
const onSigTerm = () => {
|
|
75970
|
-
|
|
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
|
+
);
|
|
75971
76425
|
};
|
|
75972
76426
|
const onStdinData = (chunk) => {
|
|
75973
76427
|
stdinBuffer += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
@@ -75992,9 +76446,12 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
75992
76446
|
if (shutdownTrigger.kind === "pm") {
|
|
75993
76447
|
console.log(`
|
|
75994
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...`);
|
|
75995
76452
|
} else {
|
|
75996
76453
|
console.log(`
|
|
75997
|
-
[wapk]
|
|
76454
|
+
[wapk] Received ${shutdownTrigger.signal}; closing shared session ${session.joinKey}...`);
|
|
75998
76455
|
}
|
|
75999
76456
|
try {
|
|
76000
76457
|
await closeWapkOnlineSharedSession(launcherUrl, session);
|
|
@@ -76034,7 +76491,9 @@ async function runWapkOnline(archiveSpecifier, options) {
|
|
|
76034
76491
|
process.exitCode = await waitForWapkOnlineSessionShutdown(launcherUrl, {
|
|
76035
76492
|
joinKey: response.joinKey,
|
|
76036
76493
|
adminToken: response.adminToken
|
|
76037
|
-
}, archiveHandle, onlineArchiveLock
|
|
76494
|
+
}, archiveHandle, onlineArchiveLock, {
|
|
76495
|
+
allowSigtermClose: options.allowSigtermClose
|
|
76496
|
+
});
|
|
76038
76497
|
}
|
|
76039
76498
|
async function writeWapkArchiveFromMemory(archiveHandle, header, files, lock) {
|
|
76040
76499
|
const updatedHeader = {
|
|
@@ -76291,6 +76750,8 @@ async function packWapkDirectory(directory, options = {}) {
|
|
|
76291
76750
|
runtime: config.runtime,
|
|
76292
76751
|
entry: config.entry,
|
|
76293
76752
|
scripts: config.scripts,
|
|
76753
|
+
appId: config.appId,
|
|
76754
|
+
publisherId: config.publisherId,
|
|
76294
76755
|
port: config.port,
|
|
76295
76756
|
env: config.env,
|
|
76296
76757
|
desktop: config.desktop,
|
|
@@ -76322,6 +76783,56 @@ function extractWapkArchive(wapkPath, outputDir = ".", options = {}) {
|
|
|
76322
76783
|
console.log(`Extracted ${archive.files.length} files to: ${extractDirectory}`);
|
|
76323
76784
|
return extractDirectory;
|
|
76324
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
|
+
}
|
|
76325
76836
|
async function prepareWapkApp(wapkPath, options = {}) {
|
|
76326
76837
|
const archiveHandle = resolveArchiveHandle(wapkPath, options.googleDrive);
|
|
76327
76838
|
const archivePath = archiveHandle.identifier;
|
|
@@ -76430,6 +76941,8 @@ function inspectWapkArchive(wapkPath, options = {}) {
|
|
|
76430
76941
|
console.log(`App: ${decoded.header.version}`);
|
|
76431
76942
|
console.log(`Runtime: ${decoded.header.runtime}`);
|
|
76432
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"}`);
|
|
76433
76946
|
console.log(`Port: ${decoded.header.port ?? "default"}`);
|
|
76434
76947
|
console.log(`Created: ${decoded.header.createdAt}`);
|
|
76435
76948
|
if (decoded.header.env && Object.keys(decoded.header.env).length > 0) {
|
|
@@ -76461,6 +76974,8 @@ function printWapkHelp() {
|
|
|
76461
76974
|
" elit wapk gdrive://<fileId> --online",
|
|
76462
76975
|
" elit wapk pack [directory]",
|
|
76463
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>",
|
|
76464
76979
|
" elit wapk inspect <file.wapk>",
|
|
76465
76980
|
" elit wapk extract <file.wapk>",
|
|
76466
76981
|
"",
|
|
@@ -76472,24 +76987,32 @@ function printWapkHelp() {
|
|
|
76472
76987
|
" --archive-watch Pull external archive changes back into the temp workdir",
|
|
76473
76988
|
" --no-archive-watch Disable external archive read sync",
|
|
76474
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",
|
|
76475
76991
|
" --online-url <url> Elit Run URL (default: auto-detect localhost:4177 or localhost:4179)",
|
|
76476
76992
|
" --google-drive-file-id <id> Run a remote .wapk directly from Google Drive",
|
|
76477
76993
|
" --google-drive-token-env <name> Env var containing the Google Drive OAuth token",
|
|
76478
76994
|
" --google-drive-access-token <value> OAuth token for Google Drive API calls",
|
|
76479
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",
|
|
76480
76999
|
" --include-deps Legacy compatibility flag; node_modules are packed by default",
|
|
76481
77000
|
" --password <value> Password for locking or unlocking the archive",
|
|
76482
77001
|
" -h, --help Show this help",
|
|
76483
77002
|
"",
|
|
76484
77003
|
"Notes:",
|
|
76485
77004
|
" - Pack reads wapk from elit.config.* and falls back to package.json.",
|
|
76486
|
-
" -
|
|
77005
|
+
" - If appId or publisherId is not configured, pack auto-generates stable defaults from package metadata.",
|
|
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.",
|
|
76487
77009
|
" - Run never installs dependencies automatically; archives must include the runtime dependencies they need.",
|
|
76488
77010
|
" - Run mode can read config.wapk.run for default file/runtime/live-sync options.",
|
|
76489
77011
|
" - Browser-style archives with scripts.start or wapk.script.start run that start script automatically.",
|
|
76490
77012
|
" - Run mode keeps files in RAM and syncs changes both to and from the archive source.",
|
|
76491
77013
|
" - Google Drive mode talks to the Drive API directly; no local archive file is required.",
|
|
76492
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.",
|
|
76493
77016
|
" - Locked archives in online mode must provide --password so the CLI can build the shared snapshot.",
|
|
76494
77017
|
" - Locked archives require the same password for run/extract/inspect.",
|
|
76495
77018
|
" - Archives stay unlocked by default unless a password is provided.",
|
|
@@ -76539,6 +77062,7 @@ function parseRunArgs(args) {
|
|
|
76539
77062
|
let archiveSyncInterval;
|
|
76540
77063
|
let online;
|
|
76541
77064
|
let onlineUrl;
|
|
77065
|
+
let allowSigtermClose;
|
|
76542
77066
|
let password;
|
|
76543
77067
|
for (let index = 0; index < args.length; index++) {
|
|
76544
77068
|
const arg = args[index];
|
|
@@ -76590,6 +77114,10 @@ function parseRunArgs(args) {
|
|
|
76590
77114
|
onlineUrl = readRequiredOptionValue(args, ++index, "--online-url");
|
|
76591
77115
|
break;
|
|
76592
77116
|
}
|
|
77117
|
+
case "--allow-sigterm-close": {
|
|
77118
|
+
allowSigtermClose = true;
|
|
77119
|
+
break;
|
|
77120
|
+
}
|
|
76593
77121
|
case "--google-drive-file-id": {
|
|
76594
77122
|
googleDrive = {
|
|
76595
77123
|
...googleDrive,
|
|
@@ -76632,7 +77160,7 @@ function parseRunArgs(args) {
|
|
|
76632
77160
|
break;
|
|
76633
77161
|
}
|
|
76634
77162
|
}
|
|
76635
|
-
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 };
|
|
76636
77164
|
}
|
|
76637
77165
|
function parsePackArgs(args) {
|
|
76638
77166
|
let directory = ".";
|
|
@@ -76658,6 +77186,46 @@ function parsePackArgs(args) {
|
|
|
76658
77186
|
}
|
|
76659
77187
|
return { directory, includeDeps, password };
|
|
76660
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
|
+
}
|
|
76661
77229
|
async function readConfiguredWapkRunDefaults(cwd) {
|
|
76662
77230
|
const config = await loadConfig(cwd);
|
|
76663
77231
|
const runConfig = normalizeWapkRunConfig(config?.wapk?.run);
|
|
@@ -76697,6 +77265,7 @@ function resolveConfiguredWapkRunOptions(options, defaults) {
|
|
|
76697
77265
|
archiveSyncInterval: options.archiveSyncInterval ?? defaults?.archiveSyncInterval,
|
|
76698
77266
|
online: options.online ?? defaults?.online ?? Boolean(onlineUrl),
|
|
76699
77267
|
onlineUrl,
|
|
77268
|
+
allowSigtermClose: options.allowSigtermClose === true,
|
|
76700
77269
|
password: options.password ?? defaults?.password
|
|
76701
77270
|
};
|
|
76702
77271
|
}
|
|
@@ -76729,6 +77298,15 @@ async function runWapkCommand(args, cwd = process.cwd()) {
|
|
|
76729
77298
|
});
|
|
76730
77299
|
return;
|
|
76731
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
|
+
}
|
|
76732
77310
|
if (args[0] === "inspect") {
|
|
76733
77311
|
const options = parseArchiveAccessArgs(args.slice(1), "Usage: elit wapk inspect <file.wapk>");
|
|
76734
77312
|
inspectWapkArchive(options.file, options);
|
|
@@ -76757,6 +77335,7 @@ async function runWapkCommand(args, cwd = process.cwd()) {
|
|
|
76757
77335
|
await runWapkOnline(archiveSpecifier, {
|
|
76758
77336
|
googleDrive: runOptions.googleDrive,
|
|
76759
77337
|
onlineUrl: runOptions.onlineUrl,
|
|
77338
|
+
allowSigtermClose: runOptions.allowSigtermClose,
|
|
76760
77339
|
password: runOptions.password
|
|
76761
77340
|
});
|
|
76762
77341
|
return;
|
|
@@ -83080,6 +83659,7 @@ WAPK Options:
|
|
|
83080
83659
|
elit wapk run [file.wapk] Run a packaged app or the configured default archive
|
|
83081
83660
|
elit wapk run --google-drive-file-id <id> Run a packaged app directly from Google Drive
|
|
83082
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
|
|
83083
83663
|
elit wapk inspect <file.wapk> Inspect a .wapk archive
|
|
83084
83664
|
elit wapk extract <file.wapk> Extract a .wapk archive
|
|
83085
83665
|
elit wapk --runtime node|bun|deno [file] Override the packaged runtime
|