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.mjs
CHANGED
|
@@ -1997,8 +1997,8 @@ var require_chance = __commonJS({
|
|
|
1997
1997
|
return i;
|
|
1998
1998
|
});
|
|
1999
1999
|
}
|
|
2000
|
-
function testRange(
|
|
2001
|
-
if (
|
|
2000
|
+
function testRange(test, errorMessage) {
|
|
2001
|
+
if (test) {
|
|
2002
2002
|
throw new RangeError(errorMessage);
|
|
2003
2003
|
}
|
|
2004
2004
|
}
|
|
@@ -54905,12 +54905,126 @@ ${k.ValidationErrorsFormatter.format(i2)}`);
|
|
|
54905
54905
|
// src/test-runtime.ts
|
|
54906
54906
|
import { transformSync } from "esbuild";
|
|
54907
54907
|
import { SourceMapConsumer } from "source-map";
|
|
54908
|
-
function
|
|
54908
|
+
function escapeRegex2(str) {
|
|
54909
54909
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
54910
54910
|
}
|
|
54911
|
+
function resolveTestLoader(filePath) {
|
|
54912
|
+
return /\.(?:ts|tsx|mts|cts)$/i.test(filePath) ? "ts" : "js";
|
|
54913
|
+
}
|
|
54914
|
+
function createTestTransformOptions(filePath, format2, sourcemap) {
|
|
54915
|
+
return {
|
|
54916
|
+
loader: resolveTestLoader(filePath),
|
|
54917
|
+
format: format2,
|
|
54918
|
+
sourcemap,
|
|
54919
|
+
sourcefile: filePath,
|
|
54920
|
+
target: "es2020",
|
|
54921
|
+
tsconfigRaw: {
|
|
54922
|
+
compilerOptions: {
|
|
54923
|
+
jsx: "react",
|
|
54924
|
+
jsxFactory: "h",
|
|
54925
|
+
jsxFragmentFactory: "Fragment"
|
|
54926
|
+
}
|
|
54927
|
+
}
|
|
54928
|
+
};
|
|
54929
|
+
}
|
|
54930
|
+
function resolveExistingTestModulePath(basePath) {
|
|
54931
|
+
const nodePath = __require("path");
|
|
54932
|
+
if (existsSync(basePath) && statSync(basePath).isFile()) {
|
|
54933
|
+
return basePath;
|
|
54934
|
+
}
|
|
54935
|
+
for (const extension of TEST_MODULE_EXTENSIONS) {
|
|
54936
|
+
const candidatePath = `${basePath}${extension}`;
|
|
54937
|
+
if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
|
|
54938
|
+
return candidatePath;
|
|
54939
|
+
}
|
|
54940
|
+
}
|
|
54941
|
+
if (existsSync(basePath) && statSync(basePath).isDirectory()) {
|
|
54942
|
+
const packageJsonPath = nodePath.join(basePath, "package.json");
|
|
54943
|
+
if (existsSync(packageJsonPath) && statSync(packageJsonPath).isFile()) {
|
|
54944
|
+
try {
|
|
54945
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
54946
|
+
for (const candidateEntry of [packageJson.main, packageJson.module]) {
|
|
54947
|
+
if (typeof candidateEntry !== "string" || candidateEntry.trim().length === 0) {
|
|
54948
|
+
continue;
|
|
54949
|
+
}
|
|
54950
|
+
try {
|
|
54951
|
+
return resolveExistingTestModulePath(nodePath.resolve(basePath, candidateEntry));
|
|
54952
|
+
} catch {
|
|
54953
|
+
continue;
|
|
54954
|
+
}
|
|
54955
|
+
}
|
|
54956
|
+
} catch {
|
|
54957
|
+
}
|
|
54958
|
+
}
|
|
54959
|
+
for (const extension of TEST_MODULE_EXTENSIONS) {
|
|
54960
|
+
const candidatePath = nodePath.join(basePath, `index${extension}`);
|
|
54961
|
+
if (existsSync(candidatePath) && statSync(candidatePath).isFile()) {
|
|
54962
|
+
return candidatePath;
|
|
54963
|
+
}
|
|
54964
|
+
}
|
|
54965
|
+
}
|
|
54966
|
+
return basePath;
|
|
54967
|
+
}
|
|
54968
|
+
function resolveTestModulePath(fromFilePath, specifier) {
|
|
54969
|
+
if (!specifier.startsWith(".") && !specifier.startsWith("/")) {
|
|
54970
|
+
return specifier;
|
|
54971
|
+
}
|
|
54972
|
+
const nodePath = __require("path");
|
|
54973
|
+
const basePath = specifier.startsWith(".") ? nodePath.resolve(dirname(fromFilePath), specifier) : specifier;
|
|
54974
|
+
return resolveExistingTestModulePath(basePath);
|
|
54975
|
+
}
|
|
54976
|
+
function shouldTranspileTestModule(filePath) {
|
|
54977
|
+
return /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i.test(filePath);
|
|
54978
|
+
}
|
|
54979
|
+
function createTestModuleRequire(fromFilePath, moduleCache) {
|
|
54980
|
+
return (specifier) => {
|
|
54981
|
+
if (specifier.startsWith("elit/") || specifier === "elit") {
|
|
54982
|
+
return __require(specifier);
|
|
54983
|
+
}
|
|
54984
|
+
const resolvedPath = resolveTestModulePath(fromFilePath, specifier);
|
|
54985
|
+
if (resolvedPath === specifier) {
|
|
54986
|
+
return __require(specifier);
|
|
54987
|
+
}
|
|
54988
|
+
if (!existsSync(resolvedPath) || !statSync(resolvedPath).isFile()) {
|
|
54989
|
+
return __require(resolvedPath);
|
|
54990
|
+
}
|
|
54991
|
+
if (!shouldTranspileTestModule(resolvedPath)) {
|
|
54992
|
+
return __require(resolvedPath);
|
|
54993
|
+
}
|
|
54994
|
+
return loadTranspiledTestModule(resolvedPath, moduleCache);
|
|
54995
|
+
};
|
|
54996
|
+
}
|
|
54997
|
+
function loadTranspiledTestModule(modulePath, moduleCache) {
|
|
54998
|
+
const cached = moduleCache.get(modulePath);
|
|
54999
|
+
if (cached) {
|
|
55000
|
+
return cached.exports;
|
|
55001
|
+
}
|
|
55002
|
+
const source = readFileSync(modulePath, "utf-8");
|
|
55003
|
+
let transpiled;
|
|
55004
|
+
try {
|
|
55005
|
+
transpiled = transformSync(source, createTestTransformOptions(modulePath, "cjs", false));
|
|
55006
|
+
} catch (error) {
|
|
55007
|
+
throw new Error(`Failed to transpile test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
55008
|
+
}
|
|
55009
|
+
const moduleRecord = { exports: {} };
|
|
55010
|
+
const moduleObj = { exports: moduleRecord.exports };
|
|
55011
|
+
moduleCache.set(modulePath, moduleRecord);
|
|
55012
|
+
try {
|
|
55013
|
+
const fn = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
|
|
55014
|
+
const requireFn = createTestModuleRequire(modulePath, moduleCache);
|
|
55015
|
+
fn(moduleObj, moduleObj.exports, requireFn, modulePath, dirname(modulePath));
|
|
55016
|
+
} catch (error) {
|
|
55017
|
+
throw new Error(`Failed to execute test dependency ${modulePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
55018
|
+
}
|
|
55019
|
+
moduleRecord.exports = moduleObj.exports;
|
|
55020
|
+
if (!modulePath.includes(".test.") && !modulePath.includes(".spec.")) {
|
|
55021
|
+
coveredFiles.add(modulePath);
|
|
55022
|
+
}
|
|
55023
|
+
return moduleRecord.exports;
|
|
55024
|
+
}
|
|
54911
55025
|
function createTestFunction(defaultTimeout = 5e3) {
|
|
54912
55026
|
const testFn = function(name, fn, timeout) {
|
|
54913
|
-
const
|
|
55027
|
+
const test = {
|
|
54914
55028
|
name,
|
|
54915
55029
|
fn,
|
|
54916
55030
|
skip: currentSuite.skip,
|
|
@@ -54919,10 +55033,10 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54919
55033
|
timeout: timeout ?? defaultTimeout,
|
|
54920
55034
|
suite: currentSuite
|
|
54921
55035
|
};
|
|
54922
|
-
currentSuite.tests.push(
|
|
55036
|
+
currentSuite.tests.push(test);
|
|
54923
55037
|
};
|
|
54924
55038
|
testFn.skip = (name, fn, timeout) => {
|
|
54925
|
-
const
|
|
55039
|
+
const test = {
|
|
54926
55040
|
name,
|
|
54927
55041
|
fn,
|
|
54928
55042
|
skip: true,
|
|
@@ -54931,11 +55045,11 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54931
55045
|
timeout: timeout ?? defaultTimeout,
|
|
54932
55046
|
suite: currentSuite
|
|
54933
55047
|
};
|
|
54934
|
-
currentSuite.tests.push(
|
|
55048
|
+
currentSuite.tests.push(test);
|
|
54935
55049
|
};
|
|
54936
55050
|
testFn.only = (name, fn, timeout) => {
|
|
54937
55051
|
hasOnly = true;
|
|
54938
|
-
const
|
|
55052
|
+
const test = {
|
|
54939
55053
|
name,
|
|
54940
55054
|
fn,
|
|
54941
55055
|
skip: false,
|
|
@@ -54944,10 +55058,10 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54944
55058
|
timeout: timeout ?? defaultTimeout,
|
|
54945
55059
|
suite: currentSuite
|
|
54946
55060
|
};
|
|
54947
|
-
currentSuite.tests.push(
|
|
55061
|
+
currentSuite.tests.push(test);
|
|
54948
55062
|
};
|
|
54949
55063
|
testFn.todo = (name, fn, timeout) => {
|
|
54950
|
-
const
|
|
55064
|
+
const test = {
|
|
54951
55065
|
name,
|
|
54952
55066
|
fn,
|
|
54953
55067
|
skip: false,
|
|
@@ -54956,7 +55070,7 @@ function createTestFunction(defaultTimeout = 5e3) {
|
|
|
54956
55070
|
timeout: timeout ?? defaultTimeout,
|
|
54957
55071
|
suite: currentSuite
|
|
54958
55072
|
};
|
|
54959
|
-
currentSuite.tests.push(
|
|
55073
|
+
currentSuite.tests.push(test);
|
|
54960
55074
|
};
|
|
54961
55075
|
return testFn;
|
|
54962
55076
|
}
|
|
@@ -55066,29 +55180,7 @@ async function runTests(options) {
|
|
|
55066
55180
|
try {
|
|
55067
55181
|
const source = await readFile(file, "utf-8");
|
|
55068
55182
|
const testFileDir = dirname(file);
|
|
55069
|
-
const
|
|
55070
|
-
const imports = {};
|
|
55071
|
-
let importIndex = 0;
|
|
55072
|
-
let codeWithoutImports = source.replace(importRegex, (_, named, path) => {
|
|
55073
|
-
const varName = `__import_${importIndex++}`;
|
|
55074
|
-
const trimmedNamed = named.trim();
|
|
55075
|
-
imports[varName] = { path, named: trimmedNamed };
|
|
55076
|
-
return `// ${trimmedNamed} import injected later
|
|
55077
|
-
`;
|
|
55078
|
-
});
|
|
55079
|
-
const result2 = transformSync(codeWithoutImports, {
|
|
55080
|
-
loader: file.endsWith(".ts") || file.endsWith(".tsx") ? "ts" : "js",
|
|
55081
|
-
format: "iife",
|
|
55082
|
-
sourcemap: "inline",
|
|
55083
|
-
target: "es2020",
|
|
55084
|
-
tsconfigRaw: {
|
|
55085
|
-
compilerOptions: {
|
|
55086
|
-
jsx: "react",
|
|
55087
|
-
jsxFactory: "h",
|
|
55088
|
-
jsxFragmentFactory: "Fragment"
|
|
55089
|
-
}
|
|
55090
|
-
}
|
|
55091
|
-
});
|
|
55183
|
+
const result2 = transformSync(source, createTestTransformOptions(file, "cjs", "inline"));
|
|
55092
55184
|
let code = result2.code;
|
|
55093
55185
|
const sourceMapMatch = code.match(/\/\/# sourceMappingURL=data:application\/json;base64,(.+)/);
|
|
55094
55186
|
if (sourceMapMatch) {
|
|
@@ -55099,99 +55191,15 @@ async function runTests(options) {
|
|
|
55099
55191
|
} else {
|
|
55100
55192
|
currentSourceMapConsumer = void 0;
|
|
55101
55193
|
}
|
|
55102
|
-
|
|
55103
|
-
const importParamNames = [];
|
|
55104
|
-
const importAssignments = [];
|
|
55105
|
-
if (Object.keys(imports).length > 0) {
|
|
55106
|
-
for (const [, { path, named }] of Object.entries(imports)) {
|
|
55107
|
-
let resolvedPath = path;
|
|
55108
|
-
if (path.startsWith(".")) {
|
|
55109
|
-
const nodePath = __require("path");
|
|
55110
|
-
resolvedPath = nodePath.resolve(testFileDir, path);
|
|
55111
|
-
}
|
|
55112
|
-
if (!resolvedPath.endsWith(".ts") && !resolvedPath.endsWith(".js") && !resolvedPath.endsWith(".mjs") && !resolvedPath.endsWith(".cjs")) {
|
|
55113
|
-
resolvedPath += ".ts";
|
|
55114
|
-
}
|
|
55115
|
-
if (resolvedPath.endsWith(".ts")) {
|
|
55116
|
-
try {
|
|
55117
|
-
const importSource = await readFile(resolvedPath, "utf-8");
|
|
55118
|
-
const transpiled = transformSync(importSource, {
|
|
55119
|
-
loader: "ts",
|
|
55120
|
-
format: "cjs",
|
|
55121
|
-
target: "es2020",
|
|
55122
|
-
tsconfigRaw: {
|
|
55123
|
-
compilerOptions: {
|
|
55124
|
-
jsx: "react",
|
|
55125
|
-
jsxFactory: "h",
|
|
55126
|
-
jsxFragmentFactory: "Fragment"
|
|
55127
|
-
}
|
|
55128
|
-
}
|
|
55129
|
-
});
|
|
55130
|
-
const moduleExports = {};
|
|
55131
|
-
const moduleObj = { exports: moduleExports };
|
|
55132
|
-
const fn2 = new Function("module", "exports", "require", "__filename", "__dirname", transpiled.code);
|
|
55133
|
-
const requireFn = (id) => {
|
|
55134
|
-
if (id.startsWith("elit/") || id === "elit") {
|
|
55135
|
-
return __require(id);
|
|
55136
|
-
}
|
|
55137
|
-
if (id.startsWith(".")) {
|
|
55138
|
-
const nodePath = __require("path");
|
|
55139
|
-
const absPath = nodePath.resolve(dirname(resolvedPath), id);
|
|
55140
|
-
return __require(absPath);
|
|
55141
|
-
}
|
|
55142
|
-
return __require(id);
|
|
55143
|
-
};
|
|
55144
|
-
fn2(moduleObj, moduleExports, requireFn, resolvedPath, dirname(resolvedPath));
|
|
55145
|
-
if (!resolvedPath.includes(".test.") && !resolvedPath.includes(".spec.")) {
|
|
55146
|
-
coveredFiles.add(resolvedPath);
|
|
55147
|
-
}
|
|
55148
|
-
let exportedValue = moduleObj.exports[named];
|
|
55149
|
-
if (exportedValue === void 0 && moduleObj.exports.default) {
|
|
55150
|
-
exportedValue = moduleObj.exports.default[named];
|
|
55151
|
-
}
|
|
55152
|
-
if (exportedValue === void 0 && typeof moduleObj.exports === "object") {
|
|
55153
|
-
exportedValue = moduleObj.exports[named];
|
|
55154
|
-
}
|
|
55155
|
-
const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
|
|
55156
|
-
importedValues[paramKey] = exportedValue;
|
|
55157
|
-
importParamNames.push(paramKey);
|
|
55158
|
-
importAssignments.push(`const ${named} = ${paramKey};`);
|
|
55159
|
-
} catch (err) {
|
|
55160
|
-
const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
|
|
55161
|
-
importedValues[paramKey] = null;
|
|
55162
|
-
importParamNames.push(paramKey);
|
|
55163
|
-
importAssignments.push(`const ${named} = ${paramKey}; /* Error importing ${resolvedPath}: ${err} */`);
|
|
55164
|
-
}
|
|
55165
|
-
} else {
|
|
55166
|
-
const requiredModule = __require(resolvedPath);
|
|
55167
|
-
const exportedValue = requiredModule[named];
|
|
55168
|
-
const paramKey = `__import_${Math.random().toString(36).substring(2, 11)}`;
|
|
55169
|
-
importedValues[paramKey] = exportedValue;
|
|
55170
|
-
importParamNames.push(paramKey);
|
|
55171
|
-
importAssignments.push(`const ${named} = ${paramKey};`);
|
|
55172
|
-
}
|
|
55173
|
-
}
|
|
55174
|
-
}
|
|
55175
|
-
let preamble = "";
|
|
55176
|
-
if (Object.keys(imports).length > 0) {
|
|
55177
|
-
const iifeStartMatch = code.match(/^(\s*(?:var\s+\w+\s*=\s*)?\(\(\)\s*=>\s*\{\n)/);
|
|
55178
|
-
if (iifeStartMatch) {
|
|
55179
|
-
const iifePrefix = iifeStartMatch[1];
|
|
55180
|
-
const assignments = `${importAssignments.join("\n")}
|
|
55181
|
-
`;
|
|
55182
|
-
preamble = iifePrefix;
|
|
55183
|
-
code = iifePrefix + assignments + code.slice(iifeStartMatch[1].length);
|
|
55184
|
-
} else {
|
|
55185
|
-
preamble = importAssignments.join("\n") + "\n";
|
|
55186
|
-
code = preamble + code;
|
|
55187
|
-
}
|
|
55188
|
-
}
|
|
55189
|
-
wrapperLineOffset = preamble.split("\n").length;
|
|
55194
|
+
wrapperLineOffset = 0;
|
|
55190
55195
|
setupGlobals();
|
|
55191
|
-
const
|
|
55192
|
-
const
|
|
55193
|
-
const
|
|
55194
|
-
|
|
55196
|
+
const moduleCache = /* @__PURE__ */ new Map();
|
|
55197
|
+
const moduleRecord = { exports: {} };
|
|
55198
|
+
const moduleObj = { exports: moduleRecord.exports };
|
|
55199
|
+
moduleCache.set(file, moduleRecord);
|
|
55200
|
+
const fn = new Function("module", "exports", "require", "__filename", "__dirname", code);
|
|
55201
|
+
const requireFn = createTestModuleRequire(file, moduleCache);
|
|
55202
|
+
await fn(moduleObj, moduleObj.exports, requireFn, file, testFileDir);
|
|
55195
55203
|
await executeSuite(currentSuite, timeout, bail);
|
|
55196
55204
|
if (currentSourceMapConsumer) {
|
|
55197
55205
|
currentSourceMapConsumer.destroy();
|
|
@@ -55226,13 +55234,13 @@ async function runTests(options) {
|
|
|
55226
55234
|
async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
55227
55235
|
let directMatch = false;
|
|
55228
55236
|
if (describePattern) {
|
|
55229
|
-
const escapedPattern =
|
|
55237
|
+
const escapedPattern = escapeRegex2(describePattern);
|
|
55230
55238
|
const regex = new RegExp(escapedPattern, "i");
|
|
55231
55239
|
directMatch = regex.test(suite.name);
|
|
55232
55240
|
}
|
|
55233
55241
|
function suiteOrDescendantMatches(s) {
|
|
55234
55242
|
if (!describePattern) return true;
|
|
55235
|
-
const escapedPattern =
|
|
55243
|
+
const escapedPattern = escapeRegex2(describePattern);
|
|
55236
55244
|
const regex = new RegExp(escapedPattern, "i");
|
|
55237
55245
|
if (regex.test(s.name)) return true;
|
|
55238
55246
|
for (const child of s.suites) {
|
|
@@ -55256,22 +55264,22 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55256
55264
|
for (const hook of beforeAllHooks) {
|
|
55257
55265
|
await hook();
|
|
55258
55266
|
}
|
|
55259
|
-
for (const
|
|
55260
|
-
if (hasOnly && !
|
|
55267
|
+
for (const test of suite.tests) {
|
|
55268
|
+
if (hasOnly && !test.only && !suite.only) {
|
|
55261
55269
|
continue;
|
|
55262
55270
|
}
|
|
55263
55271
|
let testMatches = true;
|
|
55264
55272
|
if (testPattern) {
|
|
55265
|
-
const escapedPattern =
|
|
55273
|
+
const escapedPattern = escapeRegex2(testPattern);
|
|
55266
55274
|
const regex = new RegExp(escapedPattern, "i");
|
|
55267
|
-
testMatches = regex.test(
|
|
55275
|
+
testMatches = regex.test(test.name);
|
|
55268
55276
|
}
|
|
55269
55277
|
if (!testMatches) {
|
|
55270
55278
|
continue;
|
|
55271
55279
|
}
|
|
55272
|
-
if (
|
|
55280
|
+
if (test.skip || suite.skip) {
|
|
55273
55281
|
testResults.push({
|
|
55274
|
-
name:
|
|
55282
|
+
name: test.name,
|
|
55275
55283
|
status: "skip",
|
|
55276
55284
|
duration: 0,
|
|
55277
55285
|
suite: suite.name,
|
|
@@ -55279,9 +55287,9 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55279
55287
|
});
|
|
55280
55288
|
continue;
|
|
55281
55289
|
}
|
|
55282
|
-
if (
|
|
55290
|
+
if (test.todo) {
|
|
55283
55291
|
testResults.push({
|
|
55284
|
-
name:
|
|
55292
|
+
name: test.name,
|
|
55285
55293
|
status: "todo",
|
|
55286
55294
|
duration: 0,
|
|
55287
55295
|
suite: suite.name,
|
|
@@ -55295,13 +55303,13 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55295
55303
|
const startTime = Date.now();
|
|
55296
55304
|
try {
|
|
55297
55305
|
await Promise.race([
|
|
55298
|
-
|
|
55306
|
+
test.fn(),
|
|
55299
55307
|
new Promise(
|
|
55300
|
-
(_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${
|
|
55308
|
+
(_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${test.timeout}ms`)), test.timeout)
|
|
55301
55309
|
)
|
|
55302
55310
|
]);
|
|
55303
55311
|
testResults.push({
|
|
55304
|
-
name:
|
|
55312
|
+
name: test.name,
|
|
55305
55313
|
status: "pass",
|
|
55306
55314
|
duration: Date.now() - startTime,
|
|
55307
55315
|
suite: suite.name,
|
|
@@ -55315,7 +55323,7 @@ async function executeSuite(suite, timeout, bail, parentMatched = false) {
|
|
|
55315
55323
|
codeSnippet = error.codeSnippet;
|
|
55316
55324
|
}
|
|
55317
55325
|
testResults.push({
|
|
55318
|
-
name:
|
|
55326
|
+
name: test.name,
|
|
55319
55327
|
status: "fail",
|
|
55320
55328
|
duration: Date.now() - startTime,
|
|
55321
55329
|
error,
|
|
@@ -55364,7 +55372,7 @@ function getCoveredFiles() {
|
|
|
55364
55372
|
function resetCoveredFiles() {
|
|
55365
55373
|
coveredFiles.clear();
|
|
55366
55374
|
}
|
|
55367
|
-
var AssertionError, currentSuite, testResults, hasOnly, coveredFiles, describePattern, testPattern, currentTestFile, currentSourceMapConsumer, wrapperLineOffset, Expect, vi, beforeAllHooks, afterAllHooks, beforeEachHooks, afterEachHooks, beforeAll, afterAll, beforeEach, afterEach, globals;
|
|
55375
|
+
var AssertionError, currentSuite, testResults, hasOnly, coveredFiles, describePattern, testPattern, currentTestFile, currentSourceMapConsumer, wrapperLineOffset, TEST_MODULE_EXTENSIONS, Expect, vi, beforeAllHooks, afterAllHooks, beforeEachHooks, afterEachHooks, beforeAll, afterAll, beforeEach, afterEach, globals;
|
|
55368
55376
|
var init_test_runtime = __esm({
|
|
55369
55377
|
"src/test-runtime.ts"() {
|
|
55370
55378
|
"use strict";
|
|
@@ -55395,6 +55403,7 @@ var init_test_runtime = __esm({
|
|
|
55395
55403
|
currentTestFile = void 0;
|
|
55396
55404
|
currentSourceMapConsumer = void 0;
|
|
55397
55405
|
wrapperLineOffset = 0;
|
|
55406
|
+
TEST_MODULE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
|
|
55398
55407
|
Expect = class _Expect {
|
|
55399
55408
|
constructor(actual, isNot = false, isAsync = false) {
|
|
55400
55409
|
this.actual = actual;
|
|
@@ -60460,6 +60469,71 @@ function lookup(path) {
|
|
|
60460
60469
|
// src/server.ts
|
|
60461
60470
|
init_runtime();
|
|
60462
60471
|
|
|
60472
|
+
// src/smtp-server.ts
|
|
60473
|
+
import { SMTPServer } from "smtp-server";
|
|
60474
|
+
var DEFAULT_SMTP_PORT = 2525;
|
|
60475
|
+
var DEFAULT_SMTP_HOST = "127.0.0.1";
|
|
60476
|
+
function resolveSmtpServerConfig(config = {}) {
|
|
60477
|
+
const { port = DEFAULT_SMTP_PORT, host = DEFAULT_SMTP_HOST, label, ...serverOptions } = config;
|
|
60478
|
+
return {
|
|
60479
|
+
...serverOptions,
|
|
60480
|
+
port,
|
|
60481
|
+
host,
|
|
60482
|
+
label
|
|
60483
|
+
};
|
|
60484
|
+
}
|
|
60485
|
+
function normalizeSmtpServerConfigs(input) {
|
|
60486
|
+
const configs = Array.isArray(input) ? input : input ? [input] : [];
|
|
60487
|
+
return configs.map((config) => resolveSmtpServerConfig(config));
|
|
60488
|
+
}
|
|
60489
|
+
function closeSmtpServer(server) {
|
|
60490
|
+
return new Promise((resolve9, reject) => {
|
|
60491
|
+
let settled = false;
|
|
60492
|
+
const finish = (error) => {
|
|
60493
|
+
if (settled) {
|
|
60494
|
+
return;
|
|
60495
|
+
}
|
|
60496
|
+
settled = true;
|
|
60497
|
+
if (error) {
|
|
60498
|
+
reject(error);
|
|
60499
|
+
return;
|
|
60500
|
+
}
|
|
60501
|
+
resolve9();
|
|
60502
|
+
};
|
|
60503
|
+
const handleCloseError = (error) => {
|
|
60504
|
+
const errorCode = error.code;
|
|
60505
|
+
if (errorCode === "ERR_SERVER_NOT_RUNNING") {
|
|
60506
|
+
finish();
|
|
60507
|
+
return;
|
|
60508
|
+
}
|
|
60509
|
+
finish(error);
|
|
60510
|
+
};
|
|
60511
|
+
try {
|
|
60512
|
+
server.close(() => finish());
|
|
60513
|
+
} catch (error) {
|
|
60514
|
+
handleCloseError(error);
|
|
60515
|
+
}
|
|
60516
|
+
});
|
|
60517
|
+
}
|
|
60518
|
+
function createSmtpServer(config = {}) {
|
|
60519
|
+
const resolvedConfig = resolveSmtpServerConfig(config);
|
|
60520
|
+
const { port, host, label: _label, ...serverOptions } = resolvedConfig;
|
|
60521
|
+
const server = new SMTPServer(serverOptions);
|
|
60522
|
+
return {
|
|
60523
|
+
server,
|
|
60524
|
+
config: resolvedConfig,
|
|
60525
|
+
listen(callback) {
|
|
60526
|
+
return callback ? server.listen(port, host, callback) : server.listen(port, host);
|
|
60527
|
+
},
|
|
60528
|
+
address() {
|
|
60529
|
+
return server.server.address();
|
|
60530
|
+
},
|
|
60531
|
+
close() {
|
|
60532
|
+
return closeSmtpServer(server);
|
|
60533
|
+
}
|
|
60534
|
+
};
|
|
60535
|
+
}
|
|
60536
|
+
|
|
60463
60537
|
// src/render-context.ts
|
|
60464
60538
|
var RUNTIME_TARGET_KEY = "__ELIT_RUNTIME_TARGET__";
|
|
60465
60539
|
var CAPTURED_RENDER_KEY = "__ELIT_CAPTURED_RENDER__";
|
|
@@ -60913,6 +60987,7 @@ var DomNode = class {
|
|
|
60913
60987
|
html += `</${tagName}>${newLine}`;
|
|
60914
60988
|
return html;
|
|
60915
60989
|
}
|
|
60990
|
+
const isRawText = tagName === "script" || tagName === "style";
|
|
60916
60991
|
if (children && children.length > 0) {
|
|
60917
60992
|
const resolvedChildren = children.map((c) => {
|
|
60918
60993
|
const resolved = this.resolveStateValue(c);
|
|
@@ -60928,11 +61003,11 @@ var DomNode = class {
|
|
|
60928
61003
|
if (Array.isArray(child)) {
|
|
60929
61004
|
for (const c of child) {
|
|
60930
61005
|
if (!shouldSkipChild(c)) {
|
|
60931
|
-
html += this.renderToString(c, { pretty, indent: indent5 + 1 });
|
|
61006
|
+
html += isRawText && typeof c === "string" ? c : this.renderToString(c, { pretty, indent: indent5 + 1 });
|
|
60932
61007
|
}
|
|
60933
61008
|
}
|
|
60934
61009
|
} else {
|
|
60935
|
-
html += this.renderToString(child, { pretty, indent: indent5 + 1 });
|
|
61010
|
+
html += isRawText && typeof child === "string" ? child : this.renderToString(child, { pretty, indent: indent5 + 1 });
|
|
60936
61011
|
}
|
|
60937
61012
|
}
|
|
60938
61013
|
html += indentStr;
|
|
@@ -60942,11 +61017,11 @@ var DomNode = class {
|
|
|
60942
61017
|
if (Array.isArray(child)) {
|
|
60943
61018
|
for (const c of child) {
|
|
60944
61019
|
if (!shouldSkipChild(c)) {
|
|
60945
|
-
html += this.renderToString(c, { pretty: false, indent: 0 });
|
|
61020
|
+
html += isRawText && typeof c === "string" ? c : this.renderToString(c, { pretty: false, indent: 0 });
|
|
60946
61021
|
}
|
|
60947
61022
|
}
|
|
60948
61023
|
} else {
|
|
60949
|
-
html += this.renderToString(child, { pretty: false, indent: 0 });
|
|
61024
|
+
html += isRawText && typeof child === "string" ? child : this.renderToString(child, { pretty: false, indent: 0 });
|
|
60950
61025
|
}
|
|
60951
61026
|
}
|
|
60952
61027
|
}
|
|
@@ -61874,6 +61949,56 @@ var defaultOptions = {
|
|
|
61874
61949
|
worker: [],
|
|
61875
61950
|
mode: "dev"
|
|
61876
61951
|
};
|
|
61952
|
+
function createSmtpBindingKey(config) {
|
|
61953
|
+
return `${config.host}:${config.port}`;
|
|
61954
|
+
}
|
|
61955
|
+
function createSmtpServerLabel(config) {
|
|
61956
|
+
return config.label || createSmtpBindingKey(config);
|
|
61957
|
+
}
|
|
61958
|
+
function formatSmtpServerAddress(address, fallback) {
|
|
61959
|
+
if (typeof address === "string") {
|
|
61960
|
+
return address;
|
|
61961
|
+
}
|
|
61962
|
+
if (address) {
|
|
61963
|
+
return `${address.address}:${address.port}`;
|
|
61964
|
+
}
|
|
61965
|
+
return createSmtpBindingKey(fallback);
|
|
61966
|
+
}
|
|
61967
|
+
function collectSmtpServerConfigs(config, usesClientArray) {
|
|
61968
|
+
const modeLabel = config.mode || "dev";
|
|
61969
|
+
const smtpConfigs = normalizeSmtpServerConfigs(config.smtp).map((smtpConfig, index) => ({
|
|
61970
|
+
...smtpConfig,
|
|
61971
|
+
label: smtpConfig.label || `${modeLabel}.smtp[${index}]`
|
|
61972
|
+
}));
|
|
61973
|
+
if (!usesClientArray || !config.clients) {
|
|
61974
|
+
return smtpConfigs;
|
|
61975
|
+
}
|
|
61976
|
+
for (let clientIndex = 0; clientIndex < config.clients.length; clientIndex += 1) {
|
|
61977
|
+
const client = config.clients[clientIndex];
|
|
61978
|
+
const clientDescriptor = client.basePath || client.root;
|
|
61979
|
+
const clientPrefix = clientDescriptor ? `${modeLabel}.clients[${clientIndex}] (${clientDescriptor})` : `${modeLabel}.clients[${clientIndex}]`;
|
|
61980
|
+
smtpConfigs.push(...normalizeSmtpServerConfigs(client.smtp).map((smtpConfig, smtpIndex) => ({
|
|
61981
|
+
...smtpConfig,
|
|
61982
|
+
label: smtpConfig.label || `${clientPrefix}.smtp[${smtpIndex}]`
|
|
61983
|
+
})));
|
|
61984
|
+
}
|
|
61985
|
+
return smtpConfigs;
|
|
61986
|
+
}
|
|
61987
|
+
function assertUniqueSmtpServerBindings(configs) {
|
|
61988
|
+
const seenBindings = /* @__PURE__ */ new Map();
|
|
61989
|
+
for (const smtpConfig of configs) {
|
|
61990
|
+
if (smtpConfig.port === 0) {
|
|
61991
|
+
continue;
|
|
61992
|
+
}
|
|
61993
|
+
const bindingKey = createSmtpBindingKey(smtpConfig);
|
|
61994
|
+
const currentLabel = createSmtpServerLabel(smtpConfig);
|
|
61995
|
+
const previousLabel = seenBindings.get(bindingKey);
|
|
61996
|
+
if (previousLabel) {
|
|
61997
|
+
throw new Error(`Duplicate SMTP server binding "${bindingKey}" configured for ${previousLabel} and ${currentLabel}`);
|
|
61998
|
+
}
|
|
61999
|
+
seenBindings.set(bindingKey, currentLabel);
|
|
62000
|
+
}
|
|
62001
|
+
}
|
|
61877
62002
|
function shouldUseClientFallbackRoot(primaryRoot, fallbackRoot, indexPath) {
|
|
61878
62003
|
if (!fallbackRoot) {
|
|
61879
62004
|
return false;
|
|
@@ -62008,6 +62133,7 @@ function createDevServer(options) {
|
|
|
62008
62133
|
const globalWebSocketEndpoints = usesClientArray ? normalizeWebSocketEndpoints(config.ws) : [];
|
|
62009
62134
|
const normalizedWebSocketEndpoints = [...normalizedClients.flatMap((client) => client.ws), ...globalWebSocketEndpoints];
|
|
62010
62135
|
const seenWebSocketPaths = /* @__PURE__ */ new Set();
|
|
62136
|
+
const smtpServerConfigs = collectSmtpServerConfigs(config, usesClientArray);
|
|
62011
62137
|
for (const endpoint of normalizedWebSocketEndpoints) {
|
|
62012
62138
|
if (endpoint.path === ELIT_INTERNAL_WS_PATH) {
|
|
62013
62139
|
throw new Error(`WebSocket path "${ELIT_INTERNAL_WS_PATH}" is reserved for Elit internals`);
|
|
@@ -62017,6 +62143,21 @@ function createDevServer(options) {
|
|
|
62017
62143
|
}
|
|
62018
62144
|
seenWebSocketPaths.add(endpoint.path);
|
|
62019
62145
|
}
|
|
62146
|
+
assertUniqueSmtpServerBindings(smtpServerConfigs);
|
|
62147
|
+
const smtpServers = smtpServerConfigs.map((smtpConfig) => {
|
|
62148
|
+
const smtpServer = createSmtpServer(smtpConfig);
|
|
62149
|
+
const smtpLabel = createSmtpServerLabel(smtpServer.config);
|
|
62150
|
+
smtpServer.server.on("error", (error) => {
|
|
62151
|
+
console.error(`[SMTP] ${smtpLabel} error:`, error);
|
|
62152
|
+
});
|
|
62153
|
+
if (config.logging) {
|
|
62154
|
+
smtpServer.server.server.once("listening", () => {
|
|
62155
|
+
console.log(`[SMTP] ${smtpLabel} listening on ${formatSmtpServerAddress(smtpServer.address(), smtpServer.config)}`);
|
|
62156
|
+
});
|
|
62157
|
+
}
|
|
62158
|
+
smtpServer.listen();
|
|
62159
|
+
return smtpServer;
|
|
62160
|
+
});
|
|
62020
62161
|
const globalProxyHandler = config.proxy ? createProxyHandler(config.proxy) : null;
|
|
62021
62162
|
const server = createServer(async (req, res) => {
|
|
62022
62163
|
const originalUrl = req.url || "/";
|
|
@@ -62557,6 +62698,15 @@ ${elitImportMap}`;
|
|
|
62557
62698
|
if (config.logging) console.log("\n[Server] Shutting down...");
|
|
62558
62699
|
transformCache.clear();
|
|
62559
62700
|
if (watcher) await watcher.close();
|
|
62701
|
+
if (smtpServers.length > 0) {
|
|
62702
|
+
await Promise.all(smtpServers.map(async (smtpServer) => {
|
|
62703
|
+
try {
|
|
62704
|
+
await smtpServer.close();
|
|
62705
|
+
} catch (error) {
|
|
62706
|
+
console.error(`[SMTP] ${createSmtpServerLabel(smtpServer.config)} close error:`, error);
|
|
62707
|
+
}
|
|
62708
|
+
}));
|
|
62709
|
+
}
|
|
62560
62710
|
if (webSocketServers.length > 0) {
|
|
62561
62711
|
webSocketServers.forEach((wsServer) => wsServer.close());
|
|
62562
62712
|
wsClients.clear();
|
|
@@ -62573,6 +62723,7 @@ ${elitImportMap}`;
|
|
|
62573
62723
|
return {
|
|
62574
62724
|
server,
|
|
62575
62725
|
wss,
|
|
62726
|
+
smtpServers,
|
|
62576
62727
|
url: primaryUrl,
|
|
62577
62728
|
state: stateManager,
|
|
62578
62729
|
close
|
|
@@ -74452,7 +74603,7 @@ var WAPK_AUTH_TAG_LENGTH = 16;
|
|
|
74452
74603
|
var WAPK_SCRYPT_OPTIONS = { N: 16384, r: 8, p: 1 };
|
|
74453
74604
|
var DEFAULT_GOOGLE_DRIVE_TOKEN_ENV = "GOOGLE_DRIVE_ACCESS_TOKEN";
|
|
74454
74605
|
var DEFAULT_WAPK_ONLINE_URL_ENV = "ELIT_WAPK_ONLINE_URL";
|
|
74455
|
-
var DEFAULT_WAPK_ONLINE_URLS = ["
|
|
74606
|
+
var DEFAULT_WAPK_ONLINE_URLS = ["http://wapk.d-osc.com/"];
|
|
74456
74607
|
var WAPK_ONLINE_CREATE_PATH = "/api/shared-session/create";
|
|
74457
74608
|
var WAPK_ONLINE_READ_PATH = "/api/shared-session/read";
|
|
74458
74609
|
var WAPK_ONLINE_CLOSE_PATH = "/api/shared-session/close";
|
|
@@ -74490,6 +74641,113 @@ function normalizeNonEmptyString(value) {
|
|
|
74490
74641
|
const normalized = value.trim();
|
|
74491
74642
|
return normalized.length > 0 ? normalized : void 0;
|
|
74492
74643
|
}
|
|
74644
|
+
function normalizeGeneratedIdentifier(value) {
|
|
74645
|
+
const normalized = value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
74646
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
74647
|
+
}
|
|
74648
|
+
function joinGeneratedIdentifier(...segments) {
|
|
74649
|
+
const normalizedSegments = segments.map((segment) => segment ? normalizeGeneratedIdentifier(segment) : void 0).filter((segment) => Boolean(segment));
|
|
74650
|
+
return normalizedSegments.length > 0 ? normalizedSegments.join(".") : void 0;
|
|
74651
|
+
}
|
|
74652
|
+
function parseScopedPackageName(value) {
|
|
74653
|
+
const normalizedValue = normalizeNonEmptyString(value);
|
|
74654
|
+
if (!normalizedValue) {
|
|
74655
|
+
return {};
|
|
74656
|
+
}
|
|
74657
|
+
if (!normalizedValue.startsWith("@")) {
|
|
74658
|
+
return {
|
|
74659
|
+
packageName: normalizedValue
|
|
74660
|
+
};
|
|
74661
|
+
}
|
|
74662
|
+
const scopeSeparatorIndex = normalizedValue.indexOf("/");
|
|
74663
|
+
if (scopeSeparatorIndex === -1) {
|
|
74664
|
+
return {
|
|
74665
|
+
packageName: normalizedValue
|
|
74666
|
+
};
|
|
74667
|
+
}
|
|
74668
|
+
return {
|
|
74669
|
+
scope: normalizedValue.slice(1, scopeSeparatorIndex),
|
|
74670
|
+
packageName: normalizedValue.slice(scopeSeparatorIndex + 1)
|
|
74671
|
+
};
|
|
74672
|
+
}
|
|
74673
|
+
function readPackageAuthorMetadata(value) {
|
|
74674
|
+
if (typeof value === "string") {
|
|
74675
|
+
const normalizedValue = value.trim();
|
|
74676
|
+
if (!normalizedValue) {
|
|
74677
|
+
return {};
|
|
74678
|
+
}
|
|
74679
|
+
const email = normalizedValue.match(/<([^>]+)>/)?.[1];
|
|
74680
|
+
const url = normalizedValue.match(/\(([^)]+)\)/)?.[1];
|
|
74681
|
+
const name = normalizedValue.replace(/<[^>]+>/g, " ").replace(/\([^)]+\)/g, " ").replace(/\s+/g, " ").trim();
|
|
74682
|
+
return {
|
|
74683
|
+
name: normalizeNonEmptyString(name),
|
|
74684
|
+
email: normalizeNonEmptyString(email),
|
|
74685
|
+
url: normalizeNonEmptyString(url)
|
|
74686
|
+
};
|
|
74687
|
+
}
|
|
74688
|
+
if (!isRecord(value)) {
|
|
74689
|
+
return {};
|
|
74690
|
+
}
|
|
74691
|
+
return {
|
|
74692
|
+
name: normalizeNonEmptyString(value.name),
|
|
74693
|
+
email: normalizeNonEmptyString(value.email),
|
|
74694
|
+
url: normalizeNonEmptyString(value.url)
|
|
74695
|
+
};
|
|
74696
|
+
}
|
|
74697
|
+
function extractPublisherIdFromRepository(value) {
|
|
74698
|
+
const repositoryUrl = typeof value === "string" ? value : isRecord(value) ? normalizeNonEmptyString(value.url) : void 0;
|
|
74699
|
+
const normalizedRepositoryUrl = normalizeNonEmptyString(repositoryUrl);
|
|
74700
|
+
if (!normalizedRepositoryUrl) {
|
|
74701
|
+
return void 0;
|
|
74702
|
+
}
|
|
74703
|
+
const shorthandMatch = normalizedRepositoryUrl.match(/^(?:github|gitlab|bitbucket):([^/]+)\/.+$/i);
|
|
74704
|
+
if (shorthandMatch?.[1]) {
|
|
74705
|
+
return normalizeGeneratedIdentifier(shorthandMatch[1]);
|
|
74706
|
+
}
|
|
74707
|
+
const sshMatch = normalizedRepositoryUrl.match(/^[^@]+@[^:]+:([^/]+)\/.+$/i);
|
|
74708
|
+
if (sshMatch?.[1]) {
|
|
74709
|
+
return normalizeGeneratedIdentifier(sshMatch[1]);
|
|
74710
|
+
}
|
|
74711
|
+
try {
|
|
74712
|
+
const parsed = new URL(normalizedRepositoryUrl.replace(/^git\+/, ""));
|
|
74713
|
+
const firstPathSegment = parsed.pathname.replace(/\.git$/i, "").split("/").filter(Boolean)[0];
|
|
74714
|
+
return normalizeGeneratedIdentifier(firstPathSegment ?? parsed.hostname.replace(/^www\./i, ""));
|
|
74715
|
+
} catch {
|
|
74716
|
+
return void 0;
|
|
74717
|
+
}
|
|
74718
|
+
}
|
|
74719
|
+
function extractPublisherIdFromUrl(value) {
|
|
74720
|
+
const normalizedValue = normalizeNonEmptyString(value);
|
|
74721
|
+
if (!normalizedValue) {
|
|
74722
|
+
return void 0;
|
|
74723
|
+
}
|
|
74724
|
+
try {
|
|
74725
|
+
const parsed = new URL(normalizedValue);
|
|
74726
|
+
return normalizeGeneratedIdentifier(parsed.hostname.replace(/^www\./i, ""));
|
|
74727
|
+
} catch {
|
|
74728
|
+
return void 0;
|
|
74729
|
+
}
|
|
74730
|
+
}
|
|
74731
|
+
function extractPublisherIdFromEmail(value) {
|
|
74732
|
+
const normalizedValue = normalizeNonEmptyString(value);
|
|
74733
|
+
if (!normalizedValue) {
|
|
74734
|
+
return void 0;
|
|
74735
|
+
}
|
|
74736
|
+
const domain = normalizedValue.split("@")[1];
|
|
74737
|
+
return domain ? normalizeGeneratedIdentifier(domain.replace(/^www\./i, "")) : void 0;
|
|
74738
|
+
}
|
|
74739
|
+
function resolveAutoGeneratedWapkAppId(packageName, fallbackName) {
|
|
74740
|
+
const scopedPackage = parseScopedPackageName(packageName);
|
|
74741
|
+
return joinGeneratedIdentifier(scopedPackage.scope, scopedPackage.packageName ?? fallbackName);
|
|
74742
|
+
}
|
|
74743
|
+
function resolveAutoGeneratedWapkPublisherId(packageJson, fallbackName) {
|
|
74744
|
+
const scopedPackage = parseScopedPackageName(typeof packageJson?.name === "string" ? packageJson.name : void 0);
|
|
74745
|
+
if (scopedPackage.scope) {
|
|
74746
|
+
return normalizeGeneratedIdentifier(scopedPackage.scope);
|
|
74747
|
+
}
|
|
74748
|
+
const author = readPackageAuthorMetadata(packageJson?.author);
|
|
74749
|
+
return extractPublisherIdFromRepository(packageJson?.repository) ?? extractPublisherIdFromUrl(packageJson?.homepage) ?? extractPublisherIdFromUrl(author.url) ?? extractPublisherIdFromEmail(author.email) ?? normalizeGeneratedIdentifier(author.name ?? fallbackName);
|
|
74750
|
+
}
|
|
74493
74751
|
function normalizeStringMap(value) {
|
|
74494
74752
|
if (!isRecord(value)) {
|
|
74495
74753
|
return void 0;
|
|
@@ -74529,6 +74787,8 @@ function normalizeWapkConfig(value) {
|
|
|
74529
74787
|
runtime: normalizeRuntime(value.runtime ?? value.engine),
|
|
74530
74788
|
entry: typeof value.entry === "string" ? value.entry : void 0,
|
|
74531
74789
|
scripts: normalizeStringMap(value.scripts ?? value.script),
|
|
74790
|
+
appId: normalizeNonEmptyString(value.appId),
|
|
74791
|
+
publisherId: normalizeNonEmptyString(value.publisherId),
|
|
74532
74792
|
port: normalizePort(value.port),
|
|
74533
74793
|
env: normalizeStringMap(value.env),
|
|
74534
74794
|
desktop: normalizeDesktopConfig(value.desktop),
|
|
@@ -74818,6 +75078,7 @@ async function readWapkProjectConfig(directory) {
|
|
|
74818
75078
|
const elitConfig = await loadConfig(directory);
|
|
74819
75079
|
const elitWapkConfig = normalizeWapkConfig(elitConfig?.wapk);
|
|
74820
75080
|
const packageJson = readJsonFile(packageJsonPath);
|
|
75081
|
+
const packageJsonWapk = isRecord(packageJson?.wapk) ? packageJson.wapk : void 0;
|
|
74821
75082
|
const packageScripts = normalizeStringMap(packageJson?.scripts) ?? {};
|
|
74822
75083
|
const selectedScripts = elitWapkConfig.scripts ?? packageScripts;
|
|
74823
75084
|
const inferred = inferRuntimeAndEntryFromScript(selectedScripts.start ?? packageScripts.start);
|
|
@@ -74841,12 +75102,16 @@ async function readWapkProjectConfig(directory) {
|
|
|
74841
75102
|
if (!existsSync2(entryPath) || !statSync2(entryPath).isFile()) {
|
|
74842
75103
|
throw new Error(`WAPK entry not found: ${entryPath}`);
|
|
74843
75104
|
}
|
|
75105
|
+
const appId = elitWapkConfig.appId ?? normalizeNonEmptyString(packageJson?.appId) ?? normalizeNonEmptyString(packageJsonWapk?.appId) ?? resolveAutoGeneratedWapkAppId(typeof packageJson?.name === "string" ? packageJson.name : void 0, name);
|
|
75106
|
+
const publisherId = elitWapkConfig.publisherId ?? normalizeNonEmptyString(packageJson?.publisherId) ?? normalizeNonEmptyString(packageJsonWapk?.publisherId) ?? resolveAutoGeneratedWapkPublisherId(packageJson, name);
|
|
74844
75107
|
return {
|
|
74845
75108
|
name,
|
|
74846
75109
|
version,
|
|
74847
75110
|
runtime: runtime2,
|
|
74848
75111
|
entry,
|
|
74849
75112
|
scripts: selectedScripts,
|
|
75113
|
+
appId,
|
|
75114
|
+
publisherId,
|
|
74850
75115
|
port: elitWapkConfig.port,
|
|
74851
75116
|
env: elitWapkConfig.env,
|
|
74852
75117
|
desktop: elitWapkConfig.desktop,
|
|
@@ -74856,11 +75121,14 @@ async function readWapkProjectConfig(directory) {
|
|
|
74856
75121
|
function readIgnorePatterns(directory) {
|
|
74857
75122
|
return readLineIgnorePatterns(join2(directory, ".wapkignore"));
|
|
74858
75123
|
}
|
|
75124
|
+
function parsePatternLines(content) {
|
|
75125
|
+
return content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && (!line.startsWith("#") || line.startsWith("\\#")));
|
|
75126
|
+
}
|
|
74859
75127
|
function readLineIgnorePatterns(filePath) {
|
|
74860
75128
|
if (!existsSync2(filePath)) {
|
|
74861
75129
|
return [];
|
|
74862
75130
|
}
|
|
74863
|
-
return readFileSync2(filePath, "utf8")
|
|
75131
|
+
return parsePatternLines(readFileSync2(filePath, "utf8"));
|
|
74864
75132
|
}
|
|
74865
75133
|
function normalizePackageEntry(value) {
|
|
74866
75134
|
const normalized = normalizeNonEmptyString(value)?.replace(/^[.][\\/]/, "").split("\\").join("/");
|
|
@@ -75041,23 +75309,188 @@ function resolveLinkedDependencyArchivePrefix(archivePrefix, dependencyName) {
|
|
|
75041
75309
|
}
|
|
75042
75310
|
return `${normalizedPrefix.slice(0, markerIndex + marker.length)}${dependencyName}`;
|
|
75043
75311
|
}
|
|
75044
|
-
function
|
|
75045
|
-
|
|
75312
|
+
function escapeRegex(text) {
|
|
75313
|
+
return text.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
|
|
75314
|
+
}
|
|
75315
|
+
function globPatternToRegex(pattern, options = {}) {
|
|
75316
|
+
let regex = "";
|
|
75317
|
+
for (let index = 0; index < pattern.length; index++) {
|
|
75318
|
+
const char = pattern[index];
|
|
75319
|
+
if (char === "*") {
|
|
75320
|
+
const nextChar = pattern[index + 1];
|
|
75321
|
+
const nextNextChar = pattern[index + 2];
|
|
75322
|
+
if (nextChar === "*") {
|
|
75323
|
+
if (nextNextChar === "/") {
|
|
75324
|
+
regex += "(?:.*?/)?";
|
|
75325
|
+
index += 2;
|
|
75326
|
+
continue;
|
|
75327
|
+
}
|
|
75328
|
+
regex += ".*";
|
|
75329
|
+
index += 1;
|
|
75330
|
+
continue;
|
|
75331
|
+
}
|
|
75332
|
+
regex += "[^/]*";
|
|
75333
|
+
continue;
|
|
75334
|
+
}
|
|
75335
|
+
if (char === "?") {
|
|
75336
|
+
regex += "[^/]";
|
|
75337
|
+
continue;
|
|
75338
|
+
}
|
|
75339
|
+
regex += escapeRegex(char);
|
|
75340
|
+
}
|
|
75341
|
+
const suffix = options.directoryOnly ? "(?:$|/.*)" : "$";
|
|
75342
|
+
const prefix = options.matchSegmentsOnly ? "^(?:.*?/)?" : "^";
|
|
75343
|
+
return new RegExp(`${prefix}${regex}${suffix}`);
|
|
75344
|
+
}
|
|
75345
|
+
function normalizeIgnorePattern(pattern) {
|
|
75346
|
+
let normalizedPattern = pattern.trim();
|
|
75347
|
+
if (!normalizedPattern) {
|
|
75348
|
+
return void 0;
|
|
75349
|
+
}
|
|
75350
|
+
let negate = false;
|
|
75351
|
+
if (normalizedPattern.startsWith("\\!") || normalizedPattern.startsWith("\\#")) {
|
|
75352
|
+
normalizedPattern = normalizedPattern.slice(1);
|
|
75353
|
+
} else if (normalizedPattern.startsWith("!")) {
|
|
75354
|
+
negate = true;
|
|
75355
|
+
normalizedPattern = normalizedPattern.slice(1).trim();
|
|
75356
|
+
}
|
|
75357
|
+
if (!normalizedPattern) {
|
|
75358
|
+
return void 0;
|
|
75359
|
+
}
|
|
75360
|
+
const directoryOnly = normalizedPattern.endsWith("/");
|
|
75361
|
+
if (directoryOnly) {
|
|
75362
|
+
normalizedPattern = normalizedPattern.replace(/\/+$/, "");
|
|
75363
|
+
}
|
|
75364
|
+
normalizedPattern = normalizedPattern.replace(/^\.\//, "").replace(/^\//, "").replace(/\\/g, "/");
|
|
75365
|
+
if (!normalizedPattern) {
|
|
75366
|
+
return void 0;
|
|
75367
|
+
}
|
|
75368
|
+
return {
|
|
75369
|
+
directoryOnly,
|
|
75370
|
+
matchSegmentsOnly: !normalizedPattern.includes("/"),
|
|
75371
|
+
negate,
|
|
75372
|
+
pattern: normalizedPattern
|
|
75373
|
+
};
|
|
75374
|
+
}
|
|
75375
|
+
function matchesIgnorePattern(relativePath2, pattern, isDirectory) {
|
|
75376
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75377
|
+
if (!normalizedRule) {
|
|
75378
|
+
return false;
|
|
75379
|
+
}
|
|
75380
|
+
if (normalizedRule.directoryOnly && !isDirectory) {
|
|
75381
|
+
return false;
|
|
75382
|
+
}
|
|
75383
|
+
const hasGlob = /[*?]/.test(normalizedRule.pattern);
|
|
75384
|
+
if (!hasGlob) {
|
|
75385
|
+
if (normalizedRule.matchSegmentsOnly) {
|
|
75386
|
+
return relativePath2 === normalizedRule.pattern || relativePath2.split("/").includes(normalizedRule.pattern);
|
|
75387
|
+
}
|
|
75388
|
+
return relativePath2 === normalizedRule.pattern;
|
|
75389
|
+
}
|
|
75390
|
+
if (normalizedRule.matchSegmentsOnly) {
|
|
75391
|
+
const segmentRegex = globPatternToRegex(normalizedRule.pattern);
|
|
75392
|
+
return relativePath2.split("/").some((segment) => segmentRegex.test(segment));
|
|
75393
|
+
}
|
|
75394
|
+
return globPatternToRegex(normalizedRule.pattern, { directoryOnly: normalizedRule.directoryOnly }).test(relativePath2);
|
|
75395
|
+
}
|
|
75396
|
+
function shouldIgnore(relativePath2, ignorePatterns, isDirectory) {
|
|
75397
|
+
let ignored = false;
|
|
75046
75398
|
for (const pattern of ignorePatterns) {
|
|
75047
|
-
|
|
75048
|
-
|
|
75399
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75400
|
+
if (!normalizedRule) {
|
|
75401
|
+
continue;
|
|
75049
75402
|
}
|
|
75050
|
-
if (pattern
|
|
75051
|
-
|
|
75052
|
-
if (relativePath2.startsWith(prefix) || pathParts.some((part) => part.startsWith(prefix))) {
|
|
75053
|
-
return true;
|
|
75054
|
-
}
|
|
75403
|
+
if (!matchesIgnorePattern(relativePath2, pattern, isDirectory)) {
|
|
75404
|
+
continue;
|
|
75055
75405
|
}
|
|
75056
|
-
|
|
75057
|
-
|
|
75406
|
+
ignored = !normalizedRule.negate;
|
|
75407
|
+
}
|
|
75408
|
+
return ignored;
|
|
75409
|
+
}
|
|
75410
|
+
function matchesPatchPattern(relativePath2, pattern) {
|
|
75411
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75412
|
+
if (!normalizedRule) {
|
|
75413
|
+
return false;
|
|
75414
|
+
}
|
|
75415
|
+
const normalizedPath = relativePath2.replace(/\\/g, "/");
|
|
75416
|
+
const subtreeSelector = normalizedRule.pattern.endsWith("/*") && !normalizedRule.pattern.slice(0, -2).includes("*") && !normalizedRule.pattern.slice(0, -2).includes("?");
|
|
75417
|
+
if (subtreeSelector) {
|
|
75418
|
+
const directoryPath = normalizedRule.pattern.slice(0, -2);
|
|
75419
|
+
return directoryPath.length > 0 && normalizedPath.startsWith(`${directoryPath}/`);
|
|
75420
|
+
}
|
|
75421
|
+
const hasGlob = /[*?]/.test(normalizedRule.pattern);
|
|
75422
|
+
if (!hasGlob) {
|
|
75423
|
+
if (normalizedRule.directoryOnly) {
|
|
75424
|
+
return normalizedPath === normalizedRule.pattern || normalizedPath.startsWith(`${normalizedRule.pattern}/`);
|
|
75425
|
+
}
|
|
75426
|
+
return normalizedPath === normalizedRule.pattern;
|
|
75427
|
+
}
|
|
75428
|
+
return globPatternToRegex(normalizedRule.pattern, {
|
|
75429
|
+
directoryOnly: normalizedRule.directoryOnly,
|
|
75430
|
+
matchSegmentsOnly: false
|
|
75431
|
+
}).test(normalizedPath);
|
|
75432
|
+
}
|
|
75433
|
+
function shouldPatchArchivePath(relativePath2, patchPatterns) {
|
|
75434
|
+
let selected = false;
|
|
75435
|
+
for (const pattern of patchPatterns) {
|
|
75436
|
+
const normalizedRule = normalizeIgnorePattern(pattern);
|
|
75437
|
+
if (!normalizedRule) {
|
|
75438
|
+
continue;
|
|
75439
|
+
}
|
|
75440
|
+
if (!matchesPatchPattern(relativePath2, pattern)) {
|
|
75441
|
+
continue;
|
|
75058
75442
|
}
|
|
75443
|
+
selected = !normalizedRule.negate;
|
|
75444
|
+
}
|
|
75445
|
+
return selected;
|
|
75446
|
+
}
|
|
75447
|
+
function resolvePatchManifestPatterns(files) {
|
|
75448
|
+
const patchManifest = files.find((file) => file.path === ".wapkpatch");
|
|
75449
|
+
if (!patchManifest) {
|
|
75450
|
+
throw new Error("Patch archive must include a .wapkpatch manifest file.");
|
|
75451
|
+
}
|
|
75452
|
+
const patterns = parsePatternLines(patchManifest.content.toString("utf8"));
|
|
75453
|
+
if (patterns.length === 0) {
|
|
75454
|
+
throw new Error("Patch archive .wapkpatch must define at least one patch rule.");
|
|
75455
|
+
}
|
|
75456
|
+
return patterns;
|
|
75457
|
+
}
|
|
75458
|
+
function applyPatchEntriesToFiles(targetFiles, patchFiles) {
|
|
75459
|
+
const fileMap = new Map(targetFiles.map((file) => [file.path, file]));
|
|
75460
|
+
const fileOrder = targetFiles.map((file) => file.path);
|
|
75461
|
+
const addedPaths = [];
|
|
75462
|
+
const updatedPaths = [];
|
|
75463
|
+
const unchangedPaths = [];
|
|
75464
|
+
for (const patchFile of [...patchFiles].sort((left, right) => left.path.localeCompare(right.path))) {
|
|
75465
|
+
const existing = fileMap.get(patchFile.path);
|
|
75466
|
+
const nextEntry = {
|
|
75467
|
+
path: patchFile.path,
|
|
75468
|
+
content: Buffer.from(patchFile.content),
|
|
75469
|
+
mode: patchFile.mode
|
|
75470
|
+
};
|
|
75471
|
+
if (!existing) {
|
|
75472
|
+
addedPaths.push(patchFile.path);
|
|
75473
|
+
fileOrder.push(patchFile.path);
|
|
75474
|
+
} else if (existing.mode === patchFile.mode && existing.content.equals(patchFile.content)) {
|
|
75475
|
+
unchangedPaths.push(patchFile.path);
|
|
75476
|
+
} else {
|
|
75477
|
+
updatedPaths.push(patchFile.path);
|
|
75478
|
+
}
|
|
75479
|
+
fileMap.set(patchFile.path, nextEntry);
|
|
75059
75480
|
}
|
|
75060
|
-
return
|
|
75481
|
+
return {
|
|
75482
|
+
files: fileOrder.map((filePath) => {
|
|
75483
|
+
const file = fileMap.get(filePath);
|
|
75484
|
+
if (!file) {
|
|
75485
|
+
throw new Error(`Internal WAPK patch error: missing file entry for ${filePath}`);
|
|
75486
|
+
}
|
|
75487
|
+
return file;
|
|
75488
|
+
}),
|
|
75489
|
+
patchedPaths: [...updatedPaths, ...addedPaths],
|
|
75490
|
+
addedPaths,
|
|
75491
|
+
updatedPaths,
|
|
75492
|
+
unchangedPaths
|
|
75493
|
+
};
|
|
75061
75494
|
}
|
|
75062
75495
|
function collectFiles(directory, baseDirectory, ignorePatterns) {
|
|
75063
75496
|
const files = [];
|
|
@@ -75065,7 +75498,7 @@ function collectFiles(directory, baseDirectory, ignorePatterns) {
|
|
|
75065
75498
|
for (const entry of entries) {
|
|
75066
75499
|
const fullPath = join2(directory, entry.name);
|
|
75067
75500
|
const relativePath2 = relative2(baseDirectory, fullPath).split("\\").join("/");
|
|
75068
|
-
if (shouldIgnore(relativePath2, ignorePatterns)) {
|
|
75501
|
+
if (shouldIgnore(relativePath2, ignorePatterns, entry.isDirectory())) {
|
|
75069
75502
|
continue;
|
|
75070
75503
|
}
|
|
75071
75504
|
if (entry.isSymbolicLink()) {
|
|
@@ -75214,6 +75647,8 @@ function decodeWapkPayload(buffer) {
|
|
|
75214
75647
|
runtime: normalizeRuntime(rawHeader.runtime ?? rawHeader.engine) ?? "node",
|
|
75215
75648
|
entry: typeof rawHeader.entry === "string" ? rawHeader.entry : "index.js",
|
|
75216
75649
|
scripts: normalizeStringMap(rawHeader.scripts) ?? {},
|
|
75650
|
+
appId: normalizeNonEmptyString(rawHeader.appId),
|
|
75651
|
+
publisherId: normalizeNonEmptyString(rawHeader.publisherId),
|
|
75217
75652
|
port: normalizePort(rawHeader.port),
|
|
75218
75653
|
env: normalizeStringMap(rawHeader.env),
|
|
75219
75654
|
desktop: normalizeDesktopConfig(rawHeader.desktop),
|
|
@@ -75711,11 +76146,14 @@ function sanitizeOnlineArchiveFileName(label, fallback) {
|
|
|
75711
76146
|
const fileName = sanitized.length > 0 ? sanitized : "app.wapk";
|
|
75712
76147
|
return fileName.toLowerCase().endsWith(".wapk") ? fileName : `${fileName}.wapk`;
|
|
75713
76148
|
}
|
|
76149
|
+
var WAPK_ONLINE_JOIN_SOURCE_QUERY_PARAM = "launchSource";
|
|
76150
|
+
var WAPK_ONLINE_JOIN_SOURCE_QUERY_VALUE = "elit-wapk-online";
|
|
75714
76151
|
function buildOnlineJoinUrl(baseUrl, joinKey) {
|
|
75715
76152
|
const joinUrl = new URL(baseUrl.toString());
|
|
75716
76153
|
joinUrl.search = "";
|
|
75717
76154
|
joinUrl.hash = "";
|
|
75718
76155
|
joinUrl.searchParams.set("join", joinKey);
|
|
76156
|
+
joinUrl.searchParams.set(WAPK_ONLINE_JOIN_SOURCE_QUERY_PARAM, WAPK_ONLINE_JOIN_SOURCE_QUERY_VALUE);
|
|
75719
76157
|
return joinUrl.toString();
|
|
75720
76158
|
}
|
|
75721
76159
|
async function probeOnlineLauncherUrl(url) {
|
|
@@ -75896,11 +76334,16 @@ async function closeWapkOnlineSharedSession(launcherUrl, session) {
|
|
|
75896
76334
|
function isPmWapkOnlineShutdownEnabled() {
|
|
75897
76335
|
return process.env[WAPK_ONLINE_PM_SHUTDOWN_ENV] === "1" && Boolean(process.stdin) && !process.stdin.isTTY;
|
|
75898
76336
|
}
|
|
75899
|
-
|
|
76337
|
+
function getWapkOnlineProcessDetails() {
|
|
76338
|
+
return `pid ${process.pid}, ppid ${process.ppid}`;
|
|
76339
|
+
}
|
|
76340
|
+
async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHandle, lock, options = {}) {
|
|
75900
76341
|
let snapshotRevision = 0;
|
|
75901
76342
|
let snapshotSyncPending = false;
|
|
75902
76343
|
let snapshotSyncPromise = Promise.resolve();
|
|
75903
76344
|
let lastSnapshotSyncError = null;
|
|
76345
|
+
const allowSigtermClose = options.allowSigtermClose === true;
|
|
76346
|
+
const processDetails = getWapkOnlineProcessDetails();
|
|
75904
76347
|
const syncGuestSnapshotUpdates = () => {
|
|
75905
76348
|
if (snapshotSyncPending) {
|
|
75906
76349
|
return snapshotSyncPromise;
|
|
@@ -75934,6 +76377,7 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
75934
76377
|
void syncGuestSnapshotUpdates();
|
|
75935
76378
|
}, WAPK_ONLINE_KEEPALIVE_INTERVAL_MS);
|
|
75936
76379
|
const pmManaged = isPmWapkOnlineShutdownEnabled();
|
|
76380
|
+
let ignoredSigTermLogged = false;
|
|
75937
76381
|
let stdinBuffer = "";
|
|
75938
76382
|
const cleanup = () => {
|
|
75939
76383
|
clearInterval(keepAlive);
|
|
@@ -75952,7 +76396,17 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
75952
76396
|
finish({ kind: "signal", signal: "SIGINT" });
|
|
75953
76397
|
};
|
|
75954
76398
|
const onSigTerm = () => {
|
|
75955
|
-
|
|
76399
|
+
if (allowSigtermClose) {
|
|
76400
|
+
finish({ kind: "signal", signal: "SIGTERM" });
|
|
76401
|
+
return;
|
|
76402
|
+
}
|
|
76403
|
+
if (ignoredSigTermLogged) {
|
|
76404
|
+
return;
|
|
76405
|
+
}
|
|
76406
|
+
ignoredSigTermLogged = true;
|
|
76407
|
+
console.warn(
|
|
76408
|
+
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.`
|
|
76409
|
+
);
|
|
75956
76410
|
};
|
|
75957
76411
|
const onStdinData = (chunk) => {
|
|
75958
76412
|
stdinBuffer += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
@@ -75977,9 +76431,12 @@ async function waitForWapkOnlineSessionShutdown(launcherUrl, session, archiveHan
|
|
|
75977
76431
|
if (shutdownTrigger.kind === "pm") {
|
|
75978
76432
|
console.log(`
|
|
75979
76433
|
[wapk] PM requested shutdown for shared session ${session.joinKey}...`);
|
|
76434
|
+
} else if (shutdownTrigger.signal === "SIGTERM") {
|
|
76435
|
+
console.log(`
|
|
76436
|
+
[wapk] Received SIGTERM for shared session ${session.joinKey} (${processDetails}); closing because --allow-sigterm-close is enabled...`);
|
|
75980
76437
|
} else {
|
|
75981
76438
|
console.log(`
|
|
75982
|
-
[wapk]
|
|
76439
|
+
[wapk] Received ${shutdownTrigger.signal}; closing shared session ${session.joinKey}...`);
|
|
75983
76440
|
}
|
|
75984
76441
|
try {
|
|
75985
76442
|
await closeWapkOnlineSharedSession(launcherUrl, session);
|
|
@@ -76019,7 +76476,9 @@ async function runWapkOnline(archiveSpecifier, options) {
|
|
|
76019
76476
|
process.exitCode = await waitForWapkOnlineSessionShutdown(launcherUrl, {
|
|
76020
76477
|
joinKey: response.joinKey,
|
|
76021
76478
|
adminToken: response.adminToken
|
|
76022
|
-
}, archiveHandle, onlineArchiveLock
|
|
76479
|
+
}, archiveHandle, onlineArchiveLock, {
|
|
76480
|
+
allowSigtermClose: options.allowSigtermClose
|
|
76481
|
+
});
|
|
76023
76482
|
}
|
|
76024
76483
|
async function writeWapkArchiveFromMemory(archiveHandle, header, files, lock) {
|
|
76025
76484
|
const updatedHeader = {
|
|
@@ -76276,6 +76735,8 @@ async function packWapkDirectory(directory, options = {}) {
|
|
|
76276
76735
|
runtime: config.runtime,
|
|
76277
76736
|
entry: config.entry,
|
|
76278
76737
|
scripts: config.scripts,
|
|
76738
|
+
appId: config.appId,
|
|
76739
|
+
publisherId: config.publisherId,
|
|
76279
76740
|
port: config.port,
|
|
76280
76741
|
env: config.env,
|
|
76281
76742
|
desktop: config.desktop,
|
|
@@ -76307,6 +76768,56 @@ function extractWapkArchive(wapkPath, outputDir = ".", options = {}) {
|
|
|
76307
76768
|
console.log(`Extracted ${archive.files.length} files to: ${extractDirectory}`);
|
|
76308
76769
|
return extractDirectory;
|
|
76309
76770
|
}
|
|
76771
|
+
async function patchWapkArchive(wapkPath, options) {
|
|
76772
|
+
const targetHandle = resolveArchiveHandle(wapkPath);
|
|
76773
|
+
const targetSnapshot = await targetHandle.readSnapshot();
|
|
76774
|
+
const targetEnvelope = parseWapkEnvelope(targetSnapshot.buffer);
|
|
76775
|
+
const targetArchive = decodeWapk(targetSnapshot.buffer, options);
|
|
76776
|
+
const targetLock = targetEnvelope.version === WAPK_LOCKED_VERSION ? resolveArchiveCredentials(options) : void 0;
|
|
76777
|
+
const patchArchive = readWapkArchive(options.from, {
|
|
76778
|
+
password: options.fromPassword ?? options.password
|
|
76779
|
+
});
|
|
76780
|
+
const patchPatterns = resolvePatchManifestPatterns(patchArchive.files);
|
|
76781
|
+
const selectedPatchFiles = patchArchive.files.filter((file) => file.path !== ".wapkpatch").filter((file) => shouldPatchArchivePath(file.path, patchPatterns));
|
|
76782
|
+
const patchResult = applyPatchEntriesToFiles(targetArchive.files, selectedPatchFiles);
|
|
76783
|
+
console.log(`[wapk] Target: ${targetSnapshot.label ?? targetHandle.label}`);
|
|
76784
|
+
console.log(`[wapk] Patch: ${options.from}`);
|
|
76785
|
+
console.log(`[wapk] Rules: ${patchPatterns.length}`);
|
|
76786
|
+
if (selectedPatchFiles.length === 0) {
|
|
76787
|
+
console.log("[wapk] No files matched .wapkpatch. Archive was not modified.");
|
|
76788
|
+
return {
|
|
76789
|
+
archiveLabel: targetSnapshot.label ?? targetHandle.label,
|
|
76790
|
+
patchedPaths: [],
|
|
76791
|
+
addedPaths: [],
|
|
76792
|
+
updatedPaths: [],
|
|
76793
|
+
unchangedPaths: []
|
|
76794
|
+
};
|
|
76795
|
+
}
|
|
76796
|
+
if (patchResult.patchedPaths.length === 0) {
|
|
76797
|
+
console.log("[wapk] Matching patch files were already up to date. Archive was not modified.");
|
|
76798
|
+
return {
|
|
76799
|
+
archiveLabel: targetSnapshot.label ?? targetHandle.label,
|
|
76800
|
+
patchedPaths: [],
|
|
76801
|
+
addedPaths: [],
|
|
76802
|
+
updatedPaths: [],
|
|
76803
|
+
unchangedPaths: patchResult.unchangedPaths
|
|
76804
|
+
};
|
|
76805
|
+
}
|
|
76806
|
+
const writeResult = await writeWapkArchiveFromMemory(
|
|
76807
|
+
targetHandle,
|
|
76808
|
+
targetArchive.header,
|
|
76809
|
+
patchResult.files,
|
|
76810
|
+
targetLock
|
|
76811
|
+
);
|
|
76812
|
+
console.log(`[wapk] Applied ${patchResult.patchedPaths.length} patch file${patchResult.patchedPaths.length === 1 ? "" : "s"}.`);
|
|
76813
|
+
return {
|
|
76814
|
+
archiveLabel: writeResult.label,
|
|
76815
|
+
patchedPaths: patchResult.patchedPaths,
|
|
76816
|
+
addedPaths: patchResult.addedPaths,
|
|
76817
|
+
updatedPaths: patchResult.updatedPaths,
|
|
76818
|
+
unchangedPaths: patchResult.unchangedPaths
|
|
76819
|
+
};
|
|
76820
|
+
}
|
|
76310
76821
|
async function prepareWapkApp(wapkPath, options = {}) {
|
|
76311
76822
|
const archiveHandle = resolveArchiveHandle(wapkPath, options.googleDrive);
|
|
76312
76823
|
const archivePath = archiveHandle.identifier;
|
|
@@ -76415,6 +76926,8 @@ function inspectWapkArchive(wapkPath, options = {}) {
|
|
|
76415
76926
|
console.log(`App: ${decoded.header.version}`);
|
|
76416
76927
|
console.log(`Runtime: ${decoded.header.runtime}`);
|
|
76417
76928
|
console.log(`Entry: ${decoded.header.entry}`);
|
|
76929
|
+
console.log(`App ID: ${decoded.header.appId ?? "n/a"}`);
|
|
76930
|
+
console.log(`Publisher:${decoded.header.publisherId ? ` ${decoded.header.publisherId}` : " n/a"}`);
|
|
76418
76931
|
console.log(`Port: ${decoded.header.port ?? "default"}`);
|
|
76419
76932
|
console.log(`Created: ${decoded.header.createdAt}`);
|
|
76420
76933
|
if (decoded.header.env && Object.keys(decoded.header.env).length > 0) {
|
|
@@ -76446,6 +76959,8 @@ function printWapkHelp() {
|
|
|
76446
76959
|
" elit wapk gdrive://<fileId> --online",
|
|
76447
76960
|
" elit wapk pack [directory]",
|
|
76448
76961
|
" elit wapk pack [directory] --password secret-123",
|
|
76962
|
+
" elit wapk patch <file.wapk> --from <patch.wapk>",
|
|
76963
|
+
" elit wapk patch <file.wapk> --use <patch.wapk>",
|
|
76449
76964
|
" elit wapk inspect <file.wapk>",
|
|
76450
76965
|
" elit wapk extract <file.wapk>",
|
|
76451
76966
|
"",
|
|
@@ -76457,24 +76972,32 @@ function printWapkHelp() {
|
|
|
76457
76972
|
" --archive-watch Pull external archive changes back into the temp workdir",
|
|
76458
76973
|
" --no-archive-watch Disable external archive read sync",
|
|
76459
76974
|
" --online Create an Elit Run share session, stay alive, and close on Ctrl+C",
|
|
76975
|
+
" --allow-sigterm-close Allow SIGTERM to close an online shared session",
|
|
76460
76976
|
" --online-url <url> Elit Run URL (default: auto-detect localhost:4177 or localhost:4179)",
|
|
76461
76977
|
" --google-drive-file-id <id> Run a remote .wapk directly from Google Drive",
|
|
76462
76978
|
" --google-drive-token-env <name> Env var containing the Google Drive OAuth token",
|
|
76463
76979
|
" --google-drive-access-token <value> OAuth token for Google Drive API calls",
|
|
76464
76980
|
" --google-drive-shared-drive Include supportsAllDrives=true for shared drives",
|
|
76981
|
+
" --from <file.wapk> Patch source archive for elit wapk patch",
|
|
76982
|
+
" --use <file.wapk> Alias for --from",
|
|
76983
|
+
" --from-password <value> Password for unlocking the patch archive",
|
|
76465
76984
|
" --include-deps Legacy compatibility flag; node_modules are packed by default",
|
|
76466
76985
|
" --password <value> Password for locking or unlocking the archive",
|
|
76467
76986
|
" -h, --help Show this help",
|
|
76468
76987
|
"",
|
|
76469
76988
|
"Notes:",
|
|
76470
76989
|
" - Pack reads wapk from elit.config.* and falls back to package.json.",
|
|
76471
|
-
" -
|
|
76990
|
+
" - If appId or publisherId is not configured, pack auto-generates stable defaults from package metadata.",
|
|
76991
|
+
" - Pack includes node_modules by default; use .wapkignore if you need to exclude them, and !pattern to re-include later matches.",
|
|
76992
|
+
" - Patch reads .wapkpatch from the patch archive and applies only matching archive-relative paths.",
|
|
76993
|
+
" - Patch keeps the target archive metadata and lock mode; use --from-password when the patch archive uses a different password.",
|
|
76472
76994
|
" - Run never installs dependencies automatically; archives must include the runtime dependencies they need.",
|
|
76473
76995
|
" - Run mode can read config.wapk.run for default file/runtime/live-sync options.",
|
|
76474
76996
|
" - Browser-style archives with scripts.start or wapk.script.start run that start script automatically.",
|
|
76475
76997
|
" - Run mode keeps files in RAM and syncs changes both to and from the archive source.",
|
|
76476
76998
|
" - Google Drive mode talks to the Drive API directly; no local archive file is required.",
|
|
76477
76999
|
" - Online mode creates a shared session on Elit Run directly, keeps the CLI alive, and closes it on Ctrl+C.",
|
|
77000
|
+
" - Online mode ignores SIGTERM by default; pass --allow-sigterm-close if an external supervisor should close the shared session with SIGTERM.",
|
|
76478
77001
|
" - Locked archives in online mode must provide --password so the CLI can build the shared snapshot.",
|
|
76479
77002
|
" - Locked archives require the same password for run/extract/inspect.",
|
|
76480
77003
|
" - Archives stay unlocked by default unless a password is provided.",
|
|
@@ -76524,6 +77047,7 @@ function parseRunArgs(args) {
|
|
|
76524
77047
|
let archiveSyncInterval;
|
|
76525
77048
|
let online;
|
|
76526
77049
|
let onlineUrl;
|
|
77050
|
+
let allowSigtermClose;
|
|
76527
77051
|
let password;
|
|
76528
77052
|
for (let index = 0; index < args.length; index++) {
|
|
76529
77053
|
const arg = args[index];
|
|
@@ -76575,6 +77099,10 @@ function parseRunArgs(args) {
|
|
|
76575
77099
|
onlineUrl = readRequiredOptionValue(args, ++index, "--online-url");
|
|
76576
77100
|
break;
|
|
76577
77101
|
}
|
|
77102
|
+
case "--allow-sigterm-close": {
|
|
77103
|
+
allowSigtermClose = true;
|
|
77104
|
+
break;
|
|
77105
|
+
}
|
|
76578
77106
|
case "--google-drive-file-id": {
|
|
76579
77107
|
googleDrive = {
|
|
76580
77108
|
...googleDrive,
|
|
@@ -76617,7 +77145,7 @@ function parseRunArgs(args) {
|
|
|
76617
77145
|
break;
|
|
76618
77146
|
}
|
|
76619
77147
|
}
|
|
76620
|
-
return { file, googleDrive, runtime: runtime2, syncInterval, useWatcher, watchArchive, archiveSyncInterval, online, onlineUrl, password };
|
|
77148
|
+
return { file, googleDrive, runtime: runtime2, syncInterval, useWatcher, watchArchive, archiveSyncInterval, online, onlineUrl, allowSigtermClose, password };
|
|
76621
77149
|
}
|
|
76622
77150
|
function parsePackArgs(args) {
|
|
76623
77151
|
let directory = ".";
|
|
@@ -76643,6 +77171,46 @@ function parsePackArgs(args) {
|
|
|
76643
77171
|
}
|
|
76644
77172
|
return { directory, includeDeps, password };
|
|
76645
77173
|
}
|
|
77174
|
+
function parsePatchArgs(args) {
|
|
77175
|
+
let file;
|
|
77176
|
+
let from;
|
|
77177
|
+
let password;
|
|
77178
|
+
let fromPassword;
|
|
77179
|
+
for (let index = 0; index < args.length; index++) {
|
|
77180
|
+
const arg = args[index];
|
|
77181
|
+
switch (arg) {
|
|
77182
|
+
case "--from":
|
|
77183
|
+
case "--use": {
|
|
77184
|
+
if (from) {
|
|
77185
|
+
throw new Error("WAPK patch accepts exactly one patch archive via --from or --use.");
|
|
77186
|
+
}
|
|
77187
|
+
from = readRequiredOptionValue(args, ++index, arg);
|
|
77188
|
+
break;
|
|
77189
|
+
}
|
|
77190
|
+
case "--password": {
|
|
77191
|
+
password = readRequiredOptionValue(args, ++index, "--password");
|
|
77192
|
+
break;
|
|
77193
|
+
}
|
|
77194
|
+
case "--from-password": {
|
|
77195
|
+
fromPassword = readRequiredOptionValue(args, ++index, "--from-password");
|
|
77196
|
+
break;
|
|
77197
|
+
}
|
|
77198
|
+
default:
|
|
77199
|
+
if (arg.startsWith("-")) {
|
|
77200
|
+
throw new Error(`Unknown WAPK option: ${arg}`);
|
|
77201
|
+
}
|
|
77202
|
+
if (file) {
|
|
77203
|
+
throw new Error("Usage: elit wapk patch <file.wapk> --from <patch.wapk>");
|
|
77204
|
+
}
|
|
77205
|
+
file = arg;
|
|
77206
|
+
break;
|
|
77207
|
+
}
|
|
77208
|
+
}
|
|
77209
|
+
if (!file || !from) {
|
|
77210
|
+
throw new Error("Usage: elit wapk patch <file.wapk> --from <patch.wapk>");
|
|
77211
|
+
}
|
|
77212
|
+
return { file, from, password, fromPassword };
|
|
77213
|
+
}
|
|
76646
77214
|
async function readConfiguredWapkRunDefaults(cwd) {
|
|
76647
77215
|
const config = await loadConfig(cwd);
|
|
76648
77216
|
const runConfig = normalizeWapkRunConfig(config?.wapk?.run);
|
|
@@ -76682,6 +77250,7 @@ function resolveConfiguredWapkRunOptions(options, defaults) {
|
|
|
76682
77250
|
archiveSyncInterval: options.archiveSyncInterval ?? defaults?.archiveSyncInterval,
|
|
76683
77251
|
online: options.online ?? defaults?.online ?? Boolean(onlineUrl),
|
|
76684
77252
|
onlineUrl,
|
|
77253
|
+
allowSigtermClose: options.allowSigtermClose === true,
|
|
76685
77254
|
password: options.password ?? defaults?.password
|
|
76686
77255
|
};
|
|
76687
77256
|
}
|
|
@@ -76714,6 +77283,15 @@ async function runWapkCommand(args, cwd = process.cwd()) {
|
|
|
76714
77283
|
});
|
|
76715
77284
|
return;
|
|
76716
77285
|
}
|
|
77286
|
+
if (args[0] === "patch") {
|
|
77287
|
+
const options = parsePatchArgs(args.slice(1));
|
|
77288
|
+
await patchWapkArchive(options.file, {
|
|
77289
|
+
from: options.from,
|
|
77290
|
+
password: options.password,
|
|
77291
|
+
fromPassword: options.fromPassword
|
|
77292
|
+
});
|
|
77293
|
+
return;
|
|
77294
|
+
}
|
|
76717
77295
|
if (args[0] === "inspect") {
|
|
76718
77296
|
const options = parseArchiveAccessArgs(args.slice(1), "Usage: elit wapk inspect <file.wapk>");
|
|
76719
77297
|
inspectWapkArchive(options.file, options);
|
|
@@ -76742,6 +77320,7 @@ async function runWapkCommand(args, cwd = process.cwd()) {
|
|
|
76742
77320
|
await runWapkOnline(archiveSpecifier, {
|
|
76743
77321
|
googleDrive: runOptions.googleDrive,
|
|
76744
77322
|
onlineUrl: runOptions.onlineUrl,
|
|
77323
|
+
allowSigtermClose: runOptions.allowSigtermClose,
|
|
76745
77324
|
password: runOptions.password
|
|
76746
77325
|
});
|
|
76747
77326
|
return;
|
|
@@ -83074,6 +83653,7 @@ WAPK Options:
|
|
|
83074
83653
|
elit wapk run [file.wapk] Run a packaged app or the configured default archive
|
|
83075
83654
|
elit wapk run --google-drive-file-id <id> Run a packaged app directly from Google Drive
|
|
83076
83655
|
elit wapk pack [directory] Pack a directory into a .wapk archive
|
|
83656
|
+
elit wapk patch <file.wapk> --from <patch.wapk> Apply a manifest-driven patch archive
|
|
83077
83657
|
elit wapk inspect <file.wapk> Inspect a .wapk archive
|
|
83078
83658
|
elit wapk extract <file.wapk> Extract a .wapk archive
|
|
83079
83659
|
elit wapk --runtime node|bun|deno [file] Override the packaged runtime
|