elit 3.6.6 → 3.6.7
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/dist/build.cjs +421 -331
- package/dist/build.d.ts +1 -19
- package/dist/build.js +420 -330
- package/dist/build.mjs +420 -330
- package/dist/chokidar.cjs +219 -182
- package/dist/chokidar.d.ts +25 -10
- package/dist/chokidar.js +217 -182
- package/dist/chokidar.mjs +218 -183
- package/dist/cli.cjs +22439 -21563
- package/dist/cli.d.ts +19 -37
- package/dist/cli.mjs +24113 -23252
- package/dist/config.cjs +357 -350
- package/dist/config.d.ts +17 -245
- package/dist/config.js +520 -515
- package/dist/config.mjs +346 -341
- package/dist/contracts-BeW9k0yZ.d.ts +54 -0
- package/dist/contracts-D7KIS-TK.d.ts +36 -0
- package/dist/coverage.cjs +448 -485
- package/dist/coverage.d.ts +13 -62
- package/dist/coverage.js +447 -484
- package/dist/coverage.mjs +447 -484
- package/dist/database.cjs +819 -828
- package/dist/database.d.ts +8 -24
- package/dist/database.js +818 -829
- package/dist/database.mjs +818 -829
- package/dist/desktop-auto-render.cjs +1700 -1523
- package/dist/desktop-auto-render.d.ts +4 -12
- package/dist/desktop-auto-render.js +1695 -1518
- package/dist/desktop-auto-render.mjs +1696 -1519
- package/dist/desktop.cjs +3 -1
- package/dist/desktop.d.ts +4 -1
- package/dist/desktop.js +1 -1
- package/dist/desktop.mjs +1 -1
- package/dist/dev-build.cjs +830 -0
- package/dist/dev-build.d.ts +53 -0
- package/dist/dev-build.js +3318 -0
- package/dist/dev-build.mjs +797 -0
- package/dist/dom.cjs +717 -591
- package/dist/dom.d.ts +2 -17
- package/dist/dom.js +714 -588
- package/dist/dom.mjs +716 -590
- package/dist/el.cjs +62 -52
- package/dist/el.d.ts +5 -12
- package/dist/el.js +60 -52
- package/dist/el.mjs +60 -52
- package/dist/fs.cjs +72 -63
- package/dist/fs.d.ts +22 -19
- package/dist/fs.js +71 -62
- package/dist/fs.mjs +71 -62
- package/dist/hmr.cjs +40 -14
- package/dist/hmr.d.ts +11 -23
- package/dist/hmr.js +38 -14
- package/dist/hmr.mjs +38 -14
- package/dist/http.cjs +251 -99
- package/dist/http.d.ts +38 -104
- package/dist/http.js +249 -99
- package/dist/http.mjs +249 -99
- package/dist/https.cjs +524 -228
- package/dist/https.d.ts +44 -36
- package/dist/https.js +520 -226
- package/dist/https.mjs +522 -228
- package/dist/index.cjs +7502 -7691
- package/dist/index.d.ts +6 -3
- package/dist/index.js +7486 -7677
- package/dist/index.mjs +7497 -7687
- package/dist/mime-types.cjs +10 -4
- package/dist/mime-types.d.ts +8 -11
- package/dist/mime-types.js +9 -3
- package/dist/mime-types.mjs +9 -3
- package/dist/native.cjs +8616 -8870
- package/dist/native.d.ts +7 -10
- package/dist/native.js +8682 -8936
- package/dist/native.mjs +8615 -8869
- package/dist/path.cjs +83 -77
- package/dist/path.d.ts +29 -29
- package/dist/path.js +82 -76
- package/dist/path.mjs +82 -76
- package/dist/pm.cjs +3300 -0
- package/dist/pm.d.ts +256 -0
- package/dist/pm.js +5638 -0
- package/dist/pm.mjs +3196 -0
- package/dist/preview-build.cjs +712 -0
- package/dist/preview-build.d.ts +59 -0
- package/dist/preview-build.js +3194 -0
- package/dist/preview-build.mjs +676 -0
- package/dist/render-context.cjs +13 -2
- package/dist/render-context.d.ts +9 -34
- package/dist/render-context.js +11 -2
- package/dist/render-context.mjs +11 -2
- package/dist/router.cjs +787 -646
- package/dist/router.d.ts +8 -14
- package/dist/router.js +786 -645
- package/dist/router.mjs +786 -645
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/server.cjs +3254 -2684
- package/dist/server.d.ts +47 -5
- package/dist/server.js +3427 -2859
- package/dist/server.mjs +3397 -2829
- package/dist/smtp-server.cjs +16 -3
- package/dist/smtp-server.d.ts +12 -26
- package/dist/smtp-server.js +18 -5
- package/dist/smtp-server.mjs +16 -3
- package/dist/state-DvEkDehk.d.ts +195 -0
- package/dist/state.cjs +768 -659
- package/dist/state.d.ts +11 -71
- package/dist/state.js +760 -651
- package/dist/state.mjs +767 -658
- package/dist/style.cjs +1011 -968
- package/dist/style.d.ts +13 -127
- package/dist/style.js +1009 -970
- package/dist/style.mjs +1011 -971
- package/dist/test-reporter.cjs +332 -316
- package/dist/test-reporter.d.ts +28 -33
- package/dist/test-reporter.js +328 -312
- package/dist/test-reporter.mjs +328 -312
- package/dist/test-runtime.cjs +927 -968
- package/dist/test-runtime.d.ts +24 -99
- package/dist/test-runtime.js +922 -965
- package/dist/test-runtime.mjs +922 -965
- package/dist/test.cjs +4428 -4273
- package/dist/test.d.ts +2 -8
- package/dist/test.js +4307 -4154
- package/dist/test.mjs +4419 -4267
- package/dist/types-BONVzPtp.d.ts +59 -0
- package/dist/types-BR4wMiVx.d.ts +32 -0
- package/dist/types-C4gKykuG.d.ts +23 -0
- package/dist/types-CIhpN1-K.d.ts +64 -0
- package/dist/types-Ckj8md_j.d.ts +84 -0
- package/dist/types-CpjQTAkX.d.ts +24 -0
- package/dist/types-D0LjrYjS.d.ts +14 -0
- package/dist/types-DAisuVr5.d.ts +75 -0
- package/dist/types-tJn88E1N.d.ts +242 -0
- package/dist/types.d.ts +50 -237
- package/dist/universal.cjs +1 -1
- package/dist/universal.d.ts +1 -7
- package/dist/universal.js +1 -1
- package/dist/universal.mjs +1 -1
- package/dist/websocket-XfyK23zD.d.ts +119 -0
- package/dist/ws.cjs +129 -108
- package/dist/ws.d.ts +21 -131
- package/dist/ws.js +128 -109
- package/dist/ws.mjs +128 -109
- package/dist/wss.cjs +757 -479
- package/dist/wss.d.ts +31 -28
- package/dist/wss.js +755 -479
- package/dist/wss.mjs +758 -482
- package/package.json +8 -1
- package/vendor/epaint-0.31.1/src/image.rs +418 -0
- package/dist/server-uMQvZAll.d.ts +0 -458
package/dist/database.js
CHANGED
|
@@ -29,577 +29,438 @@
|
|
|
29
29
|
mod
|
|
30
30
|
));
|
|
31
31
|
|
|
32
|
-
// src/database.ts
|
|
33
|
-
var import_node_vm = __toESM(__require("vm"));
|
|
32
|
+
// src/server/database/operations.ts
|
|
34
33
|
var import_node_fs = __toESM(__require("fs"));
|
|
35
34
|
var import_node_path = __toESM(__require("path"));
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (cachedEsbuildTransformSync !== void 0) {
|
|
41
|
-
return cachedEsbuildTransformSync;
|
|
42
|
-
}
|
|
43
|
-
if (typeof nodeModule.createRequire !== "function") {
|
|
44
|
-
cachedEsbuildTransformSync = null;
|
|
45
|
-
return cachedEsbuildTransformSync;
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
const requireFromApp = nodeModule.createRequire(import_node_path.default.join(process.cwd(), "package.json"));
|
|
49
|
-
const esbuildModule = requireFromApp("esbuild");
|
|
50
|
-
cachedEsbuildTransformSync = typeof esbuildModule?.transformSync === "function" ? esbuildModule.transformSync.bind(esbuildModule) : null;
|
|
51
|
-
} catch {
|
|
52
|
-
cachedEsbuildTransformSync = null;
|
|
53
|
-
}
|
|
54
|
-
return cachedEsbuildTransformSync;
|
|
55
|
-
}
|
|
56
|
-
function parseModuleBindings(specifiers) {
|
|
57
|
-
return specifiers.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0).map((entry) => {
|
|
58
|
-
const [imported, local] = entry.split(/\s+as\s+/);
|
|
59
|
-
return {
|
|
60
|
-
imported: (imported || "").trim(),
|
|
61
|
-
local: (local || imported || "").trim()
|
|
62
|
-
};
|
|
63
|
-
}).filter((entry) => entry.imported.length > 0 && entry.local.length > 0);
|
|
64
|
-
}
|
|
65
|
-
function formatNamedImportBindings(specifiers) {
|
|
66
|
-
return parseModuleBindings(specifiers).map(({ imported, local }) => imported === local ? imported : `${imported}: ${local}`).join(", ");
|
|
67
|
-
}
|
|
68
|
-
function formatNamedExportAssignments(specifiers) {
|
|
69
|
-
return parseModuleBindings(specifiers).map(({ imported, local }) => `module.exports.${local} = ${imported};`).join("\n");
|
|
35
|
+
|
|
36
|
+
// src/server/database/source-utils.ts
|
|
37
|
+
function escapeRegExp(value) {
|
|
38
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
70
39
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (
|
|
79
|
-
|
|
40
|
+
function findMatchingBlockEnd(source, openIndex) {
|
|
41
|
+
let depth = 0;
|
|
42
|
+
let stringChar = null;
|
|
43
|
+
for (let index = openIndex; index < source.length; index += 1) {
|
|
44
|
+
const char = source[index];
|
|
45
|
+
const nextChar = source[index + 1];
|
|
46
|
+
if (stringChar) {
|
|
47
|
+
if (char === "\\") {
|
|
48
|
+
index += 1;
|
|
49
|
+
continue;
|
|
80
50
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
51
|
+
if (char === stringChar) {
|
|
52
|
+
stringChar = null;
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (char === "/" && nextChar === "/") {
|
|
57
|
+
index += 2;
|
|
58
|
+
while (index < source.length && source[index] !== "\n") {
|
|
59
|
+
index += 1;
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (char === "/" && nextChar === "*") {
|
|
64
|
+
index += 2;
|
|
65
|
+
while (index < source.length && !(source[index] === "*" && source[index + 1] === "/")) {
|
|
66
|
+
index += 1;
|
|
67
|
+
}
|
|
68
|
+
index += 1;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
72
|
+
stringChar = char;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (char === "{") {
|
|
76
|
+
depth += 1;
|
|
77
|
+
} else if (char === "}") {
|
|
78
|
+
depth -= 1;
|
|
79
|
+
if (depth === 0) {
|
|
80
|
+
return index;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
89
83
|
}
|
|
84
|
+
return source.length - 1;
|
|
90
85
|
}
|
|
91
|
-
function
|
|
92
|
-
|
|
86
|
+
function findInitializerEnd(source, startIndex) {
|
|
87
|
+
let braceDepth = 0;
|
|
88
|
+
let bracketDepth = 0;
|
|
89
|
+
let parenDepth = 0;
|
|
90
|
+
let stringChar = null;
|
|
91
|
+
for (let index = startIndex; index < source.length; index += 1) {
|
|
92
|
+
const char = source[index];
|
|
93
|
+
const nextChar = source[index + 1];
|
|
94
|
+
if (stringChar) {
|
|
95
|
+
if (char === "\\") {
|
|
96
|
+
index += 1;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (char === stringChar) {
|
|
100
|
+
stringChar = null;
|
|
101
|
+
}
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (char === "/" && nextChar === "/") {
|
|
105
|
+
index += 2;
|
|
106
|
+
while (index < source.length && source[index] !== "\n") {
|
|
107
|
+
index += 1;
|
|
108
|
+
}
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (char === "/" && nextChar === "*") {
|
|
112
|
+
index += 2;
|
|
113
|
+
while (index < source.length && !(source[index] === "*" && source[index + 1] === "/")) {
|
|
114
|
+
index += 1;
|
|
115
|
+
}
|
|
116
|
+
index += 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
120
|
+
stringChar = char;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (char === "{") {
|
|
124
|
+
braceDepth += 1;
|
|
125
|
+
} else if (char === "}") {
|
|
126
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
127
|
+
} else if (char === "[") {
|
|
128
|
+
bracketDepth += 1;
|
|
129
|
+
} else if (char === "]") {
|
|
130
|
+
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
131
|
+
} else if (char === "(") {
|
|
132
|
+
parenDepth += 1;
|
|
133
|
+
} else if (char === ")") {
|
|
134
|
+
parenDepth = Math.max(0, parenDepth - 1);
|
|
135
|
+
} else if (char === ";" && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
|
|
136
|
+
return index;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return source.length;
|
|
93
140
|
}
|
|
94
|
-
function
|
|
95
|
-
const trimmed =
|
|
96
|
-
return
|
|
141
|
+
function looksLikeDeclarationSnippet(source) {
|
|
142
|
+
const trimmed = source.trim();
|
|
143
|
+
return /^(?:export\s+)?(?:async\s+function\b|function\b|class\b|(?:const|let|var)\b)/.test(trimmed);
|
|
97
144
|
}
|
|
98
|
-
function
|
|
99
|
-
const
|
|
100
|
-
|
|
145
|
+
function replaceExistingBindingValue(source, bindingName, serializedValue) {
|
|
146
|
+
const escapedName = escapeRegExp(bindingName);
|
|
147
|
+
const declarationRegex = new RegExp(`(?:export\\s+)?(?:const|let|var)\\s+${escapedName}(?:\\s*:\\s*[^=;]+)?\\s*=`, "m");
|
|
148
|
+
const declarationMatch = declarationRegex.exec(source);
|
|
149
|
+
if (!declarationMatch || declarationMatch.index === void 0) {
|
|
101
150
|
return null;
|
|
102
151
|
}
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
152
|
+
const equalsIndex = source.indexOf("=", declarationMatch.index);
|
|
153
|
+
if (equalsIndex === -1) {
|
|
105
154
|
return null;
|
|
106
155
|
}
|
|
107
|
-
|
|
156
|
+
const initializerEnd = findInitializerEnd(source, equalsIndex + 1);
|
|
157
|
+
const suffix = initializerEnd < source.length ? source.slice(initializerEnd) : ";";
|
|
158
|
+
return `${source.slice(0, equalsIndex + 1)} ${serializedValue}${suffix}`;
|
|
108
159
|
}
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
|
|
160
|
+
function toInitializerSource(code) {
|
|
161
|
+
if (typeof code === "function") {
|
|
162
|
+
return code.toString().trim();
|
|
163
|
+
}
|
|
164
|
+
if (typeof code === "string") {
|
|
165
|
+
const trimmed = code.trim();
|
|
166
|
+
if (looksLikeDeclarationSnippet(trimmed) || /=>/.test(trimmed) || /^(?:\{|\[|\(|"|'|`|\d|-\d|true\b|false\b|null\b|undefined\b|new\b|await\b)/.test(trimmed)) {
|
|
167
|
+
return trimmed;
|
|
168
|
+
}
|
|
169
|
+
return valueToCode(code, 0);
|
|
170
|
+
}
|
|
171
|
+
return valueToCode(code, 0);
|
|
112
172
|
}
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
173
|
+
function shouldUseDeclarationSource(code) {
|
|
174
|
+
return typeof code === "function" || typeof code === "string" && looksLikeDeclarationSnippet(code);
|
|
175
|
+
}
|
|
176
|
+
function normalizeFunctionDeclaration(name, code) {
|
|
177
|
+
const trimmed = code.trim().replace(/^export\s+/, "");
|
|
178
|
+
if (/^async\s+function\s+[A-Za-z_$][\w$]*/.test(trimmed)) {
|
|
179
|
+
return trimmed.replace(/^async\s+function\s+[A-Za-z_$][\w$]*/, `async function ${name}`);
|
|
118
180
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (sideEffectModulePath !== null) {
|
|
122
|
-
return `${indentation}require(${JSON.stringify(sideEffectModulePath)});`;
|
|
181
|
+
if (/^async\s+function\s*\(/.test(trimmed)) {
|
|
182
|
+
return trimmed.replace(/^async\s+function\s*\(/, `async function ${name}(`);
|
|
123
183
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return null;
|
|
184
|
+
if (/^function\s+[A-Za-z_$][\w$]*/.test(trimmed)) {
|
|
185
|
+
return trimmed.replace(/^function\s+[A-Za-z_$][\w$]*/, `function ${name}`);
|
|
127
186
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (!clause || modulePath === null) {
|
|
131
|
-
return null;
|
|
187
|
+
if (/^function\s*\(/.test(trimmed)) {
|
|
188
|
+
return trimmed.replace(/^function\s*\(/, `function ${name}(`);
|
|
132
189
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
`${indentation}const ${bindingName} = require(${JSON.stringify(modulePath)});`,
|
|
142
|
-
`${indentation}const ${defaultName} = ${resolveDefaultImport(bindingName)};`
|
|
143
|
-
].join("\n")
|
|
144
|
-
};
|
|
145
|
-
};
|
|
146
|
-
if (clause.startsWith("* as ")) {
|
|
147
|
-
const namespaceName = clause.slice(5).trim();
|
|
148
|
-
return isSimpleIdentifier(namespaceName) ? `${indentation}const ${namespaceName} = require(${JSON.stringify(modulePath)});` : null;
|
|
190
|
+
return `function ${name}() {
|
|
191
|
+
${trimmed}
|
|
192
|
+
}`;
|
|
193
|
+
}
|
|
194
|
+
function normalizeClassDeclaration(name, code) {
|
|
195
|
+
const trimmed = code.trim().replace(/^export\s+/, "");
|
|
196
|
+
if (/^class\s+[A-Za-z_$][\w$]*/.test(trimmed)) {
|
|
197
|
+
return trimmed.replace(/^class\s+[A-Za-z_$][\w$]*/, `class ${name}`);
|
|
149
198
|
}
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
return namedBindings.length > 0 ? `${indentation}const { ${formatNamedImportBindings(namedBindings)} } = require(${JSON.stringify(modulePath)});` : null;
|
|
199
|
+
if (/^class(?:\s+extends\b|\s*\{)/.test(trimmed)) {
|
|
200
|
+
return trimmed.replace(/^class/, `class ${name}`);
|
|
153
201
|
}
|
|
154
|
-
|
|
155
|
-
if (commaIndex !== -1) {
|
|
156
|
-
const defaultName = clause.slice(0, commaIndex).trim();
|
|
157
|
-
const remainder = clause.slice(commaIndex + 1).trim();
|
|
158
|
-
const defaultImport = buildDefaultImport(defaultName);
|
|
159
|
-
if (!defaultImport) {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
if (remainder.startsWith("* as ")) {
|
|
163
|
-
const namespaceName = remainder.slice(5).trim();
|
|
164
|
-
if (!isSimpleIdentifier(namespaceName)) {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
return `${defaultImport.code}
|
|
168
|
-
${indentation}const ${namespaceName} = ${defaultImport.bindingName};`;
|
|
169
|
-
}
|
|
170
|
-
if (remainder.startsWith("{") && remainder.endsWith("}")) {
|
|
171
|
-
const namedBindings = remainder.slice(1, -1).trim();
|
|
172
|
-
if (!namedBindings) {
|
|
173
|
-
return null;
|
|
174
|
-
}
|
|
175
|
-
return `${defaultImport.code}
|
|
176
|
-
${indentation}const { ${formatNamedImportBindings(namedBindings)} } = ${defaultImport.bindingName};`;
|
|
177
|
-
}
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
return buildDefaultImport(clause)?.code ?? null;
|
|
202
|
+
return `class ${name} ${trimmed}`;
|
|
181
203
|
}
|
|
182
|
-
function
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return `${indentation}${trimmed.slice("export ".length)}`;
|
|
204
|
+
function findDeclaration(source, name) {
|
|
205
|
+
const escaped = escapeRegExp(name);
|
|
206
|
+
const matches = [];
|
|
207
|
+
const valueRegex = new RegExp(`(?:export\\s+)?(?:const|let|var)\\s+${escaped}(?:\\s*:\\s*[^=;]+)?\\s*=`, "m");
|
|
208
|
+
const valueMatch = valueRegex.exec(source);
|
|
209
|
+
if (valueMatch && valueMatch.index !== void 0) {
|
|
210
|
+
const equalsIndex = source.indexOf("=", valueMatch.index);
|
|
211
|
+
if (equalsIndex !== -1) {
|
|
212
|
+
const initializerEnd = findInitializerEnd(source, equalsIndex + 1);
|
|
213
|
+
const end = initializerEnd < source.length && source[initializerEnd] === ";" ? initializerEnd + 1 : initializerEnd;
|
|
214
|
+
matches.push({
|
|
215
|
+
kind: "valueDecl",
|
|
216
|
+
start: valueMatch.index,
|
|
217
|
+
end,
|
|
218
|
+
exported: /^\s*export\b/.test(valueMatch[0]),
|
|
219
|
+
prefixEnd: equalsIndex + 1
|
|
220
|
+
});
|
|
221
|
+
}
|
|
201
222
|
}
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
223
|
+
const functionRegex = new RegExp(`(?:export\\s+)?(?:async\\s+)?function\\s+${escaped}\\s*\\(`, "m");
|
|
224
|
+
const functionMatch = functionRegex.exec(source);
|
|
225
|
+
if (functionMatch && functionMatch.index !== void 0) {
|
|
226
|
+
const braceOpen = source.indexOf("{", functionMatch.index);
|
|
227
|
+
if (braceOpen !== -1) {
|
|
228
|
+
const braceClose = findMatchingBlockEnd(source, braceOpen);
|
|
229
|
+
const end = braceClose + 1 < source.length && source[braceClose + 1] === ";" ? braceClose + 2 : braceClose + 1;
|
|
230
|
+
matches.push({
|
|
231
|
+
kind: "functionDecl",
|
|
232
|
+
start: functionMatch.index,
|
|
233
|
+
end,
|
|
234
|
+
exported: /^\s*export\b/.test(functionMatch[0])
|
|
235
|
+
});
|
|
236
|
+
}
|
|
206
237
|
}
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
238
|
+
const classRegex = new RegExp(`(?:export\\s+)?class\\s+${escaped}(?=\\s|\\{)`, "m");
|
|
239
|
+
const classMatch = classRegex.exec(source);
|
|
240
|
+
if (classMatch && classMatch.index !== void 0) {
|
|
241
|
+
const braceOpen = source.indexOf("{", classMatch.index);
|
|
242
|
+
if (braceOpen !== -1) {
|
|
243
|
+
const braceClose = findMatchingBlockEnd(source, braceOpen);
|
|
244
|
+
const end = braceClose + 1 < source.length && source[braceClose + 1] === ";" ? braceClose + 2 : braceClose + 1;
|
|
245
|
+
matches.push({
|
|
246
|
+
kind: "classDecl",
|
|
247
|
+
start: classMatch.index,
|
|
248
|
+
end,
|
|
249
|
+
exported: /^\s*export\b/.test(classMatch[0])
|
|
250
|
+
});
|
|
251
|
+
}
|
|
211
252
|
}
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
return specifiers.length > 0 ? `${indentation}${formatNamedExportAssignments(specifiers)}` : null;
|
|
253
|
+
if (matches.length === 0) {
|
|
254
|
+
return null;
|
|
215
255
|
}
|
|
216
|
-
|
|
256
|
+
matches.sort((left, right) => left.start - right.start);
|
|
257
|
+
return matches[0];
|
|
217
258
|
}
|
|
218
|
-
function
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const namedExports = /* @__PURE__ */ new Set();
|
|
222
|
-
const nextImportBinding = () => `__vm_import_${importCounter++}`;
|
|
223
|
-
const resolveDefaultImport = (bindingName) => `${bindingName} && Object.prototype.hasOwnProperty.call(${bindingName}, "default") ? ${bindingName}.default : ${bindingName}`;
|
|
224
|
-
const code = source.split(/\r?\n/).map((line) => rewriteImportLine(line, nextImportBinding, resolveDefaultImport) ?? rewriteExportLine(line, namedExports, () => {
|
|
225
|
-
hasDefaultExport = true;
|
|
226
|
-
}) ?? line).join("\n");
|
|
227
|
-
const exportFooter = [...namedExports].map((name) => `module.exports.${name} = ${name};`);
|
|
228
|
-
if (hasDefaultExport) {
|
|
229
|
-
exportFooter.push("module.exports.default = module.exports;");
|
|
259
|
+
function createStructuredReplacement(kind, name, code) {
|
|
260
|
+
if (!shouldUseDeclarationSource(code)) {
|
|
261
|
+
return `const ${name} = ${toInitializerSource(code)};`;
|
|
230
262
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
` : code;
|
|
263
|
+
const source = code.toString();
|
|
264
|
+
return kind === "functionDecl" ? normalizeFunctionDeclaration(name, source) : normalizeClassDeclaration(name, source);
|
|
234
265
|
}
|
|
235
|
-
function
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (!esbuildTransformSync) {
|
|
241
|
-
throw new Error(`JSX database execution requires the esbuild package (${filename}).`);
|
|
266
|
+
function createDeclarationSnippet(name, code) {
|
|
267
|
+
if (typeof code === "function") {
|
|
268
|
+
const fnSource = code.toString().trim();
|
|
269
|
+
if (/^(?:async\s+)?function\b/.test(fnSource)) {
|
|
270
|
+
return `export ${normalizeFunctionDeclaration(name, fnSource)}`;
|
|
242
271
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
272
|
+
if (/^class\b/.test(fnSource)) {
|
|
273
|
+
return `export ${normalizeClassDeclaration(name, fnSource)}`;
|
|
274
|
+
}
|
|
275
|
+
return `export const ${name} = ${fnSource};`;
|
|
247
276
|
}
|
|
248
|
-
if (
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
};
|
|
253
|
-
} catch (error) {
|
|
254
|
-
const esbuildTransformSync = getEsbuildTransformSync();
|
|
255
|
-
if (!esbuildTransformSync) {
|
|
256
|
-
throw error;
|
|
257
|
-
}
|
|
258
|
-
return esbuildTransformSync(source, {
|
|
259
|
-
loader,
|
|
260
|
-
format: options.format
|
|
261
|
-
});
|
|
277
|
+
if (typeof code === "string") {
|
|
278
|
+
const trimmed = code.trim();
|
|
279
|
+
if (looksLikeDeclarationSnippet(trimmed)) {
|
|
280
|
+
return trimmed;
|
|
262
281
|
}
|
|
263
282
|
}
|
|
264
|
-
return {
|
|
265
|
-
code: rewriteModuleSyntaxToCommonJs(source)
|
|
266
|
-
};
|
|
283
|
+
return `export const ${name} = ${toInitializerSource(code)};`;
|
|
267
284
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (import_node_fs.default.existsSync(pkgPath)) {
|
|
282
|
-
this.pkgScriptDB = JSON.parse(import_node_fs.default.readFileSync(pkgPath, "utf8"));
|
|
283
|
-
}
|
|
284
|
-
this.language = options?.language || "ts";
|
|
285
|
-
this.transpiler = transpileVmModule;
|
|
286
|
-
this.registerModules = options?.registerModules || {};
|
|
287
|
-
this._registerModules = { ...this.registerModules };
|
|
288
|
-
this._registerModules.require = ((moduleId) => this.createRequire(moduleId)).bind(this);
|
|
289
|
-
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
285
|
+
function valueToCode(val, depth = 0) {
|
|
286
|
+
const indentUnit = " ";
|
|
287
|
+
const indent = indentUnit.repeat(depth);
|
|
288
|
+
const indentInner = indentUnit.repeat(depth + 1);
|
|
289
|
+
if (val === null) return "null";
|
|
290
|
+
const t = typeof val;
|
|
291
|
+
if (t === "string") return JSON.stringify(val);
|
|
292
|
+
if (t === "number" || t === "boolean") return String(val);
|
|
293
|
+
if (t === "function") return val.toString();
|
|
294
|
+
if (Array.isArray(val)) {
|
|
295
|
+
if (val.length === 0) return "[]";
|
|
296
|
+
const items = val.map((v) => valueToCode(v, depth + 1));
|
|
297
|
+
return "[\n" + items.map((it) => indentInner + it).join(",\n") + "\n" + indent + "]";
|
|
290
298
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
return originalRequire(moduleId);
|
|
301
|
-
}
|
|
302
|
-
throw e;
|
|
303
|
-
}
|
|
304
|
-
}).bind(this);
|
|
305
|
-
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
299
|
+
if (t === "object") {
|
|
300
|
+
const keys = Object.keys(val);
|
|
301
|
+
if (keys.length === 0) return "{}";
|
|
302
|
+
const entries = keys.map((k) => {
|
|
303
|
+
const keyPart = isIdentifier(k) ? k : JSON.stringify(k);
|
|
304
|
+
const v = valueToCode(val[k], depth + 1);
|
|
305
|
+
return indentInner + keyPart + ": " + v;
|
|
306
|
+
});
|
|
307
|
+
return "{\n" + entries.join(",\n") + "\n" + indent + "}";
|
|
306
308
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
moduleId = "./" + relativePath;
|
|
316
|
-
console.log("[createRequire] Resolved @db/ alias to:", moduleId);
|
|
317
|
-
}
|
|
318
|
-
if (moduleId.startsWith("./") || moduleId.startsWith("../")) {
|
|
319
|
-
const dbDir = this.DATABASE_DIR || process.cwd();
|
|
320
|
-
const fullPath = import_node_path.default.join(dbDir, moduleId);
|
|
321
|
-
console.log("[createRequire] Full path:", fullPath);
|
|
322
|
-
let actualPath = fullPath;
|
|
323
|
-
if (import_node_fs.default.existsSync(fullPath)) {
|
|
324
|
-
actualPath = fullPath;
|
|
325
|
-
} else {
|
|
326
|
-
const extensions = [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs"];
|
|
327
|
-
for (const ext of extensions) {
|
|
328
|
-
if (import_node_fs.default.existsSync(fullPath + ext)) {
|
|
329
|
-
actualPath = fullPath + ext;
|
|
330
|
-
break;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
console.log("[createRequire] Actual path:", actualPath);
|
|
335
|
-
if (!actualPath || !import_node_fs.default.existsSync(actualPath)) {
|
|
336
|
-
console.log("[createRequire] File not found, throwing error");
|
|
337
|
-
throw new Error(`Module '${moduleId}' not found at ${fullPath}`);
|
|
338
|
-
}
|
|
339
|
-
if (actualPath.endsWith(".ts") || actualPath.endsWith(".tsx") || actualPath.endsWith(".mts") || actualPath.endsWith(".cts") || actualPath.endsWith(".js") || actualPath.endsWith(".mjs")) {
|
|
340
|
-
const content = import_node_fs.default.readFileSync(actualPath, "utf8");
|
|
341
|
-
const loader = actualPath.endsWith(".ts") || actualPath.endsWith(".mts") || actualPath.endsWith(".cts") ? "ts" : actualPath.endsWith(".tsx") ? "tsx" : "js";
|
|
342
|
-
const js = this.transpiler(content, {
|
|
343
|
-
loader,
|
|
344
|
-
format: "cjs",
|
|
345
|
-
filename: actualPath
|
|
346
|
-
}).code;
|
|
347
|
-
const moduleWrapper = { exports: {} };
|
|
348
|
-
const moduleContext = import_node_vm.default.createContext({
|
|
349
|
-
...this._registerModules,
|
|
350
|
-
module: moduleWrapper,
|
|
351
|
-
exports: moduleWrapper.exports
|
|
352
|
-
});
|
|
353
|
-
import_node_vm.default.runInContext(js, moduleContext, { filename: actualPath });
|
|
354
|
-
console.log("[createRequire] Returning exports:", moduleWrapper.exports);
|
|
355
|
-
return moduleWrapper.exports;
|
|
356
|
-
}
|
|
357
|
-
const result = __require(actualPath);
|
|
358
|
-
console.log("[createRequire] Returning (JS):", result);
|
|
359
|
-
return result;
|
|
360
|
-
}
|
|
361
|
-
return __require(moduleId);
|
|
309
|
+
return String(val);
|
|
310
|
+
}
|
|
311
|
+
function isIdentifier(key) {
|
|
312
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
|
|
313
|
+
}
|
|
314
|
+
function buildDatabaseModuleSource(dbName, code, existingSource) {
|
|
315
|
+
if (typeof code === "string") {
|
|
316
|
+
return code;
|
|
362
317
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
let resolvedPath = query;
|
|
366
|
-
for (const [alias, target] of Object.entries(aliases)) {
|
|
367
|
-
if (resolvedPath.startsWith(alias + "/")) {
|
|
368
|
-
resolvedPath = resolvedPath.replace(alias, target);
|
|
369
|
-
break;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
resolvedPath = import_node_path.default.normalize(resolvedPath);
|
|
373
|
-
return fileList.find((file) => {
|
|
374
|
-
const normalizedFile = import_node_path.default.normalize(file);
|
|
375
|
-
const fileWithoutExt = normalizedFile.replace(/\.[^/.]+$/, "");
|
|
376
|
-
return normalizedFile === resolvedPath || fileWithoutExt === resolvedPath || normalizedFile === resolvedPath + ".ts" || normalizedFile === resolvedPath + ".js";
|
|
377
|
-
});
|
|
318
|
+
if (typeof code === "function") {
|
|
319
|
+
return code.toString();
|
|
378
320
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
console.log("[moduleLinker] Resolved path:", dbResult);
|
|
385
|
-
if (dbResult) {
|
|
386
|
-
try {
|
|
387
|
-
const actualModule = await import(dbResult);
|
|
388
|
-
const exportNames = Object.keys(actualModule);
|
|
389
|
-
return new import_node_vm.default.SyntheticModule(
|
|
390
|
-
exportNames,
|
|
391
|
-
function() {
|
|
392
|
-
exportNames.forEach((key) => {
|
|
393
|
-
this.setExport(key, actualModule[key]);
|
|
394
|
-
});
|
|
395
|
-
},
|
|
396
|
-
{ identifier: specifier, context: referencingModule.context }
|
|
397
|
-
);
|
|
398
|
-
} catch (err) {
|
|
399
|
-
console.error(`Failed to load database module ${specifier}:`, err);
|
|
400
|
-
throw err;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
const allowedPackages = Object.keys(this.pkgScriptDB.dependencies || {});
|
|
404
|
-
if (allowedPackages.includes(specifier)) {
|
|
405
|
-
try {
|
|
406
|
-
const modulePath = import_node_path.default.join(this.SCRIPTDB_DIR, "node_modules", specifier);
|
|
407
|
-
const actualModule = await import(modulePath);
|
|
408
|
-
const exportNames = Object.keys(actualModule);
|
|
409
|
-
return new import_node_vm.default.SyntheticModule(
|
|
410
|
-
exportNames,
|
|
411
|
-
function() {
|
|
412
|
-
exportNames.forEach((key) => {
|
|
413
|
-
this.setExport(key, actualModule[key]);
|
|
414
|
-
});
|
|
415
|
-
},
|
|
416
|
-
{ identifier: specifier, context: referencingModule.context }
|
|
417
|
-
);
|
|
418
|
-
} catch (err) {
|
|
419
|
-
console.error(`Failed to load workspace module ${specifier}:`, err);
|
|
420
|
-
throw err;
|
|
421
|
-
}
|
|
321
|
+
const serializedValue = valueToCode(code, 0);
|
|
322
|
+
if (existingSource && isIdentifier(dbName)) {
|
|
323
|
+
const updatedSource = replaceExistingBindingValue(existingSource, dbName, serializedValue);
|
|
324
|
+
if (updatedSource) {
|
|
325
|
+
return updatedSource;
|
|
422
326
|
}
|
|
423
|
-
throw new Error(`Module ${specifier} is not allowed or not found.`);
|
|
424
327
|
}
|
|
425
|
-
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
return `const { ${imports} } = require(${quote}${modulePath}${quote});`;
|
|
465
|
-
}
|
|
466
|
-
);
|
|
467
|
-
processedCode = processedCode.replace(
|
|
468
|
-
/import\s+(\w+)\s+from\s+(['"])([^'"]+)\2/g,
|
|
469
|
-
(_match, name, quote, modulePath) => {
|
|
470
|
-
return `const ${name} = require(${quote}${modulePath}${quote});`;
|
|
328
|
+
if (isIdentifier(dbName)) {
|
|
329
|
+
return `const ${dbName} = ${serializedValue};
|
|
330
|
+
|
|
331
|
+
export { ${dbName} };
|
|
332
|
+
export default ${dbName};
|
|
333
|
+
`;
|
|
334
|
+
}
|
|
335
|
+
return `const value = ${serializedValue};
|
|
336
|
+
|
|
337
|
+
export default value;
|
|
338
|
+
`;
|
|
339
|
+
}
|
|
340
|
+
function removeDatabaseModuleEntry(source, fnName) {
|
|
341
|
+
let nextSource = source;
|
|
342
|
+
const escaped = fnName.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
343
|
+
const startRe = new RegExp(
|
|
344
|
+
`function\\s+${escaped}\\s*\\(|\\bclass\\s+${escaped}\\b|\\b(?:const|let|var)\\s+${escaped}\\s*=\\s*(?:function\\b|class\\b|\\(|\\{|\\[)`,
|
|
345
|
+
"m"
|
|
346
|
+
);
|
|
347
|
+
const startMatch = nextSource.match(startRe);
|
|
348
|
+
if (startMatch && startMatch.index !== void 0) {
|
|
349
|
+
const startIdx = startMatch.index;
|
|
350
|
+
const len = nextSource.length;
|
|
351
|
+
const idxCurly = nextSource.indexOf("{", startIdx);
|
|
352
|
+
const idxBracket = nextSource.indexOf("[", startIdx);
|
|
353
|
+
let braceOpen = -1;
|
|
354
|
+
if (idxCurly === -1) braceOpen = idxBracket;
|
|
355
|
+
else if (idxBracket === -1) braceOpen = idxCurly;
|
|
356
|
+
else braceOpen = Math.min(idxCurly, idxBracket);
|
|
357
|
+
if (braceOpen !== -1) {
|
|
358
|
+
const openingChar = nextSource[braceOpen];
|
|
359
|
+
const closingChar = openingChar === "[" ? "]" : "}";
|
|
360
|
+
let index = braceOpen + 1;
|
|
361
|
+
let depth = 1;
|
|
362
|
+
while (index < len && depth > 0) {
|
|
363
|
+
const char = nextSource[index];
|
|
364
|
+
if (char === openingChar) depth += 1;
|
|
365
|
+
else if (char === closingChar) depth -= 1;
|
|
366
|
+
index += 1;
|
|
471
367
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
console.log("[run] DATABASE_DIR:", this.DATABASE_DIR);
|
|
477
|
-
try {
|
|
478
|
-
const moduleWrapper = { exports: {} };
|
|
479
|
-
const initialExports = moduleWrapper.exports;
|
|
480
|
-
const originalModule = this._registerModules.module;
|
|
481
|
-
const originalExports = this._registerModules.exports;
|
|
482
|
-
this._registerModules.module = moduleWrapper;
|
|
483
|
-
this._registerModules.exports = moduleWrapper.exports;
|
|
484
|
-
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
485
|
-
let result;
|
|
486
|
-
try {
|
|
487
|
-
result = import_node_vm.default.runInContext(processedCode, this.ctx, {
|
|
488
|
-
filename: import_node_path.default.join(this.SCRIPTDB_DIR, "virtual-entry.js")
|
|
489
|
-
});
|
|
490
|
-
} finally {
|
|
491
|
-
if (originalModule) {
|
|
492
|
-
this._registerModules.module = originalModule;
|
|
493
|
-
} else {
|
|
494
|
-
delete this._registerModules.module;
|
|
495
|
-
}
|
|
496
|
-
if (originalExports) {
|
|
497
|
-
this._registerModules.exports = originalExports;
|
|
498
|
-
} else {
|
|
499
|
-
delete this._registerModules.exports;
|
|
500
|
-
}
|
|
501
|
-
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
368
|
+
const braceClose = index;
|
|
369
|
+
let endIdx = braceClose;
|
|
370
|
+
if (nextSource.slice(braceClose, braceClose + 1) === ";") {
|
|
371
|
+
endIdx = braceClose + 1;
|
|
502
372
|
}
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
373
|
+
const before = nextSource.slice(0, startIdx);
|
|
374
|
+
const after = nextSource.slice(endIdx);
|
|
375
|
+
nextSource = before + after;
|
|
376
|
+
} else {
|
|
377
|
+
const semi = nextSource.indexOf(";", startIdx);
|
|
378
|
+
let endIdx = semi !== -1 ? semi + 1 : nextSource.indexOf("\n\n", startIdx);
|
|
379
|
+
if (endIdx === -1) endIdx = len;
|
|
380
|
+
nextSource = nextSource.slice(0, startIdx) + nextSource.slice(endIdx);
|
|
511
381
|
}
|
|
512
382
|
}
|
|
513
|
-
|
|
383
|
+
const exportRe = new RegExp(
|
|
384
|
+
`export\\s+const\\s+${escaped}\\s*:\\s*any\\s*=\\s*${escaped}\\s*;?`,
|
|
385
|
+
"g"
|
|
386
|
+
);
|
|
387
|
+
nextSource = nextSource.replace(exportRe, "");
|
|
388
|
+
return nextSource.replace(/\n{3,}/g, "\n\n");
|
|
389
|
+
}
|
|
390
|
+
function updateDatabaseModuleSource(source, fnName, code) {
|
|
391
|
+
let nextSource = source;
|
|
392
|
+
const declaration = findDeclaration(nextSource, fnName);
|
|
393
|
+
if (declaration) {
|
|
394
|
+
if (declaration.kind === "valueDecl" && declaration.prefixEnd !== void 0) {
|
|
395
|
+
const initializer = toInitializerSource(code);
|
|
396
|
+
nextSource = nextSource.slice(0, declaration.start) + nextSource.slice(declaration.start, declaration.prefixEnd) + ` ${initializer};` + nextSource.slice(declaration.end);
|
|
397
|
+
} else if (declaration.kind === "functionDecl") {
|
|
398
|
+
const replacement = createStructuredReplacement("functionDecl", fnName, code);
|
|
399
|
+
nextSource = nextSource.slice(0, declaration.start) + `${declaration.exported ? "export " : ""}${replacement.replace(/^export\s+/, "")}` + nextSource.slice(declaration.end);
|
|
400
|
+
} else {
|
|
401
|
+
const replacement = createStructuredReplacement("classDecl", fnName, code);
|
|
402
|
+
nextSource = nextSource.slice(0, declaration.start) + `${declaration.exported ? "export " : ""}${replacement.replace(/^export\s+/, "")}` + nextSource.slice(declaration.end);
|
|
403
|
+
}
|
|
404
|
+
} else {
|
|
405
|
+
const snippet = createDeclarationSnippet(fnName, code);
|
|
406
|
+
const separator = nextSource.trim().length > 0 ? "\n\n" : "";
|
|
407
|
+
nextSource = `${nextSource.trimEnd()}${separator}${snippet}
|
|
408
|
+
`;
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
source: nextSource,
|
|
412
|
+
changed: nextSource !== source
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/server/database/operations.ts
|
|
417
|
+
function getDatabaseDirectory(options) {
|
|
418
|
+
return options?.dir || import_node_path.default.join(process.cwd(), "databases");
|
|
419
|
+
}
|
|
420
|
+
function getDatabasePath(dbName, options) {
|
|
421
|
+
return import_node_path.default.join(getDatabaseDirectory(options), `${dbName}.ts`);
|
|
422
|
+
}
|
|
514
423
|
function create(dbName, code, options) {
|
|
515
|
-
const
|
|
516
|
-
const dbPath = import_node_path.default.join(DIR, `${dbName}.ts`);
|
|
424
|
+
const dbPath = getDatabasePath(dbName, options);
|
|
517
425
|
import_node_fs.default.appendFileSync(dbPath, code.toString(), "utf8");
|
|
518
426
|
}
|
|
519
427
|
function read(dbName, options) {
|
|
520
|
-
const
|
|
521
|
-
const dbPath = import_node_path.default.join(DIR, `${dbName}.ts`);
|
|
428
|
+
const dbPath = getDatabasePath(dbName, options);
|
|
522
429
|
if (!import_node_fs.default.existsSync(dbPath)) {
|
|
523
430
|
throw new Error(`Database '${dbName}' not found`);
|
|
524
431
|
}
|
|
525
432
|
return import_node_fs.default.readFileSync(dbPath, "utf8");
|
|
526
433
|
}
|
|
527
434
|
function remove(dbName, fnName, options) {
|
|
528
|
-
const
|
|
529
|
-
const dbPath = import_node_path.default.join(DIR, `${dbName}.ts`);
|
|
435
|
+
const dbPath = getDatabasePath(dbName, options);
|
|
530
436
|
if (!import_node_fs.default.existsSync(dbPath)) return false;
|
|
531
437
|
if (!fnName) {
|
|
532
438
|
const bak2 = `${dbPath}.bak`;
|
|
533
439
|
try {
|
|
534
440
|
import_node_fs.default.copyFileSync(dbPath, bak2);
|
|
535
|
-
} catch
|
|
441
|
+
} catch {
|
|
536
442
|
}
|
|
537
443
|
try {
|
|
538
444
|
import_node_fs.default.unlinkSync(dbPath);
|
|
539
445
|
return "Removed successfully";
|
|
540
|
-
} catch
|
|
446
|
+
} catch {
|
|
541
447
|
return "Removed failed";
|
|
542
448
|
}
|
|
543
449
|
}
|
|
544
450
|
const bak = `${dbPath}.bak`;
|
|
545
451
|
try {
|
|
546
452
|
import_node_fs.default.copyFileSync(dbPath, bak);
|
|
547
|
-
} catch
|
|
548
|
-
}
|
|
549
|
-
let src = import_node_fs.default.readFileSync(dbPath, "utf8");
|
|
550
|
-
const escaped = fnName.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
551
|
-
const startRe = new RegExp(
|
|
552
|
-
`function\\s+${escaped}\\s*\\(|\\bclass\\s+${escaped}\\b|\\b(?:const|let|var)\\s+${escaped}\\s*=\\s*(?:function\\b|class\\b|\\(|\\{|\\[)`,
|
|
553
|
-
"m"
|
|
554
|
-
);
|
|
555
|
-
const startMatch = src.match(startRe);
|
|
556
|
-
if (startMatch) {
|
|
557
|
-
const startIdx = startMatch.index;
|
|
558
|
-
const len = src.length;
|
|
559
|
-
const idxCurly = src.indexOf("{", startIdx);
|
|
560
|
-
const idxBracket = src.indexOf("[", startIdx);
|
|
561
|
-
let braceOpen = -1;
|
|
562
|
-
if (idxCurly === -1) braceOpen = idxBracket;
|
|
563
|
-
else if (idxBracket === -1) braceOpen = idxCurly;
|
|
564
|
-
else braceOpen = Math.min(idxCurly, idxBracket);
|
|
565
|
-
if (braceOpen !== -1) {
|
|
566
|
-
const openingChar = src[braceOpen];
|
|
567
|
-
const closingChar = openingChar === "[" ? "]" : "}";
|
|
568
|
-
let i = braceOpen + 1;
|
|
569
|
-
let depth = 1;
|
|
570
|
-
while (i < len && depth > 0) {
|
|
571
|
-
const ch = src[i];
|
|
572
|
-
if (ch === openingChar) depth++;
|
|
573
|
-
else if (ch === closingChar) depth--;
|
|
574
|
-
i++;
|
|
575
|
-
}
|
|
576
|
-
let braceClose = i;
|
|
577
|
-
let endIdx = braceClose;
|
|
578
|
-
if (src.slice(braceClose, braceClose + 1) === ";")
|
|
579
|
-
endIdx = braceClose + 1;
|
|
580
|
-
const before = src.slice(0, startIdx);
|
|
581
|
-
const after = src.slice(endIdx);
|
|
582
|
-
src = before + after;
|
|
583
|
-
} else {
|
|
584
|
-
const semi = src.indexOf(";", startIdx);
|
|
585
|
-
let endIdx = semi !== -1 ? semi + 1 : src.indexOf("\n\n", startIdx);
|
|
586
|
-
if (endIdx === -1) endIdx = len;
|
|
587
|
-
src = src.slice(0, startIdx) + src.slice(endIdx);
|
|
588
|
-
}
|
|
453
|
+
} catch {
|
|
589
454
|
}
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
);
|
|
594
|
-
src = src.replace(exportRe, "");
|
|
595
|
-
src = src.replace(/\n{3,}/g, "\n\n");
|
|
596
|
-
import_node_fs.default.writeFileSync(dbPath, src, "utf8");
|
|
455
|
+
const source = import_node_fs.default.readFileSync(dbPath, "utf8");
|
|
456
|
+
const nextSource = removeDatabaseModuleEntry(source, fnName);
|
|
457
|
+
import_node_fs.default.writeFileSync(dbPath, nextSource, "utf8");
|
|
597
458
|
return `Removed ${fnName} from database ${dbName}.`;
|
|
598
459
|
}
|
|
599
460
|
function rename(oldName, newName, options) {
|
|
600
|
-
const
|
|
601
|
-
const oldPath = import_node_path.default.join(
|
|
602
|
-
const newPath = import_node_path.default.join(
|
|
461
|
+
const dir = getDatabaseDirectory(options);
|
|
462
|
+
const oldPath = import_node_path.default.join(dir, `${oldName}.ts`);
|
|
463
|
+
const newPath = import_node_path.default.join(dir, `${newName}.ts`);
|
|
603
464
|
if (!import_node_fs.default.existsSync(oldPath)) {
|
|
604
465
|
return `Error: File '${oldName}.ts' does not exist in the database`;
|
|
605
466
|
}
|
|
@@ -613,352 +474,271 @@ ${exportFooter.join("\n")}
|
|
|
613
474
|
return `Error renaming file: ${error instanceof Error ? error.message : String(error)}`;
|
|
614
475
|
}
|
|
615
476
|
}
|
|
616
|
-
function
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
let stringChar = null;
|
|
622
|
-
for (let index = openIndex; index < source.length; index += 1) {
|
|
623
|
-
const char = source[index];
|
|
624
|
-
const nextChar = source[index + 1];
|
|
625
|
-
if (stringChar) {
|
|
626
|
-
if (char === "\\") {
|
|
627
|
-
index += 1;
|
|
628
|
-
continue;
|
|
629
|
-
}
|
|
630
|
-
if (char === stringChar) {
|
|
631
|
-
stringChar = null;
|
|
632
|
-
}
|
|
633
|
-
continue;
|
|
634
|
-
}
|
|
635
|
-
if (char === "/" && nextChar === "/") {
|
|
636
|
-
index += 2;
|
|
637
|
-
while (index < source.length && source[index] !== "\n") {
|
|
638
|
-
index += 1;
|
|
639
|
-
}
|
|
640
|
-
continue;
|
|
641
|
-
}
|
|
642
|
-
if (char === "/" && nextChar === "*") {
|
|
643
|
-
index += 2;
|
|
644
|
-
while (index < source.length && !(source[index] === "*" && source[index + 1] === "/")) {
|
|
645
|
-
index += 1;
|
|
646
|
-
}
|
|
647
|
-
index += 1;
|
|
648
|
-
continue;
|
|
649
|
-
}
|
|
650
|
-
if (char === '"' || char === "'" || char === "`") {
|
|
651
|
-
stringChar = char;
|
|
652
|
-
continue;
|
|
653
|
-
}
|
|
654
|
-
if (char === "{") {
|
|
655
|
-
depth += 1;
|
|
656
|
-
} else if (char === "}") {
|
|
657
|
-
depth -= 1;
|
|
658
|
-
if (depth === 0) {
|
|
659
|
-
return index;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
return source.length - 1;
|
|
477
|
+
function save(dbName, code, options) {
|
|
478
|
+
const dbPath = getDatabasePath(dbName, options);
|
|
479
|
+
const existingSource = import_node_fs.default.existsSync(dbPath) ? import_node_fs.default.readFileSync(dbPath, "utf8") : void 0;
|
|
480
|
+
const fileContent = buildDatabaseModuleSource(dbName, code, existingSource);
|
|
481
|
+
import_node_fs.default.writeFileSync(dbPath, fileContent, "utf8");
|
|
664
482
|
}
|
|
665
|
-
function
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
const nextChar = source[index + 1];
|
|
673
|
-
if (stringChar) {
|
|
674
|
-
if (char === "\\") {
|
|
675
|
-
index += 1;
|
|
676
|
-
continue;
|
|
677
|
-
}
|
|
678
|
-
if (char === stringChar) {
|
|
679
|
-
stringChar = null;
|
|
680
|
-
}
|
|
681
|
-
continue;
|
|
682
|
-
}
|
|
683
|
-
if (char === "/" && nextChar === "/") {
|
|
684
|
-
index += 2;
|
|
685
|
-
while (index < source.length && source[index] !== "\n") {
|
|
686
|
-
index += 1;
|
|
687
|
-
}
|
|
688
|
-
continue;
|
|
689
|
-
}
|
|
690
|
-
if (char === "/" && nextChar === "*") {
|
|
691
|
-
index += 2;
|
|
692
|
-
while (index < source.length && !(source[index] === "*" && source[index + 1] === "/")) {
|
|
693
|
-
index += 1;
|
|
694
|
-
}
|
|
695
|
-
index += 1;
|
|
696
|
-
continue;
|
|
697
|
-
}
|
|
698
|
-
if (char === '"' || char === "'" || char === "`") {
|
|
699
|
-
stringChar = char;
|
|
700
|
-
continue;
|
|
701
|
-
}
|
|
702
|
-
if (char === "{") {
|
|
703
|
-
braceDepth += 1;
|
|
704
|
-
} else if (char === "}") {
|
|
705
|
-
braceDepth = Math.max(0, braceDepth - 1);
|
|
706
|
-
} else if (char === "[") {
|
|
707
|
-
bracketDepth += 1;
|
|
708
|
-
} else if (char === "]") {
|
|
709
|
-
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
710
|
-
} else if (char === "(") {
|
|
711
|
-
parenDepth += 1;
|
|
712
|
-
} else if (char === ")") {
|
|
713
|
-
parenDepth = Math.max(0, parenDepth - 1);
|
|
714
|
-
} else if (char === ";" && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
|
|
715
|
-
return index;
|
|
483
|
+
function update(dbName, fnName, code, options) {
|
|
484
|
+
const dbPath = getDatabasePath(dbName, options);
|
|
485
|
+
if (!import_node_fs.default.existsSync(dbPath)) {
|
|
486
|
+
try {
|
|
487
|
+
import_node_fs.default.writeFileSync(dbPath, "", "utf8");
|
|
488
|
+
} catch {
|
|
489
|
+
return `Failed to create dbPath file: ${dbPath}`;
|
|
716
490
|
}
|
|
717
491
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
}
|
|
724
|
-
function replaceExistingBindingValue(source, bindingName, serializedValue) {
|
|
725
|
-
const escapedName = escapeRegExp(bindingName);
|
|
726
|
-
const declarationRegex = new RegExp(`(?:export\\s+)?(?:const|let|var)\\s+${escapedName}(?:\\s*:\\s*[^=;]+)?\\s*=`, "m");
|
|
727
|
-
const declarationMatch = declarationRegex.exec(source);
|
|
728
|
-
if (!declarationMatch || declarationMatch.index === void 0) {
|
|
729
|
-
return null;
|
|
730
|
-
}
|
|
731
|
-
const equalsIndex = source.indexOf("=", declarationMatch.index);
|
|
732
|
-
if (equalsIndex === -1) {
|
|
733
|
-
return null;
|
|
492
|
+
const source = import_node_fs.default.readFileSync(dbPath, "utf8");
|
|
493
|
+
const result = updateDatabaseModuleSource(source, fnName, code);
|
|
494
|
+
import_node_fs.default.writeFileSync(dbPath, result.source, "utf8");
|
|
495
|
+
if (!result.changed) {
|
|
496
|
+
return `Saved ${fnName} to database ${dbName}.`;
|
|
734
497
|
}
|
|
735
|
-
|
|
736
|
-
const suffix = initializerEnd < source.length ? source.slice(initializerEnd) : ";";
|
|
737
|
-
return `${source.slice(0, equalsIndex + 1)} ${serializedValue}${suffix}`;
|
|
498
|
+
return `Updated ${dbName} with ${fnName}.`;
|
|
738
499
|
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
500
|
+
|
|
501
|
+
// src/server/database/vm.ts
|
|
502
|
+
var import_node_fs2 = __toESM(__require("fs"));
|
|
503
|
+
var import_node_path3 = __toESM(__require("path"));
|
|
504
|
+
var import_node_vm = __toESM(__require("vm"));
|
|
505
|
+
|
|
506
|
+
// src/server/database/transpile.ts
|
|
507
|
+
var import_node_path2 = __toESM(__require("path"));
|
|
508
|
+
var nodeModule = __toESM(__require("module"));
|
|
509
|
+
var stripTypeScriptTypes2 = typeof nodeModule.stripTypeScriptTypes === "function" ? nodeModule.stripTypeScriptTypes : void 0;
|
|
510
|
+
var cachedEsbuildTransformSync;
|
|
511
|
+
function getEsbuildTransformSync() {
|
|
512
|
+
if (cachedEsbuildTransformSync !== void 0) {
|
|
513
|
+
return cachedEsbuildTransformSync;
|
|
742
514
|
}
|
|
743
|
-
if (typeof
|
|
744
|
-
|
|
515
|
+
if (typeof nodeModule.createRequire !== "function") {
|
|
516
|
+
cachedEsbuildTransformSync = null;
|
|
517
|
+
return cachedEsbuildTransformSync;
|
|
745
518
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
}
|
|
519
|
+
try {
|
|
520
|
+
const requireFromApp = nodeModule.createRequire(import_node_path2.default.join(process.cwd(), "package.json"));
|
|
521
|
+
const esbuildModule = requireFromApp("esbuild");
|
|
522
|
+
cachedEsbuildTransformSync = typeof esbuildModule?.transformSync === "function" ? esbuildModule.transformSync.bind(esbuildModule) : null;
|
|
523
|
+
} catch {
|
|
524
|
+
cachedEsbuildTransformSync = null;
|
|
753
525
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
526
|
+
return cachedEsbuildTransformSync;
|
|
527
|
+
}
|
|
528
|
+
function parseModuleBindings(specifiers) {
|
|
529
|
+
return specifiers.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0).map((entry) => {
|
|
530
|
+
const [imported, local] = entry.split(/\s+as\s+/);
|
|
531
|
+
return {
|
|
532
|
+
imported: (imported || "").trim(),
|
|
533
|
+
local: (local || imported || "").trim()
|
|
534
|
+
};
|
|
535
|
+
}).filter((entry) => entry.imported.length > 0 && entry.local.length > 0);
|
|
536
|
+
}
|
|
537
|
+
function formatNamedImportBindings(specifiers) {
|
|
538
|
+
return parseModuleBindings(specifiers).map(({ imported, local }) => imported === local ? imported : `${imported}: ${local}`).join(", ");
|
|
539
|
+
}
|
|
540
|
+
function formatNamedExportAssignments(specifiers) {
|
|
541
|
+
return parseModuleBindings(specifiers).map(({ imported, local }) => `module.exports.${local} = ${imported};`).join("\n");
|
|
542
|
+
}
|
|
543
|
+
function stripTypescriptSource(source, filename) {
|
|
544
|
+
if (!stripTypeScriptTypes2) {
|
|
545
|
+
throw new Error("TypeScript database execution requires Node.js 22+ or the esbuild package.");
|
|
546
|
+
}
|
|
547
|
+
const originalEmitWarning = process.emitWarning;
|
|
548
|
+
try {
|
|
549
|
+
process.emitWarning = ((warning, ...args) => {
|
|
550
|
+
if (typeof warning === "string" && warning.includes("stripTypeScriptTypes")) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
return originalEmitWarning.call(process, warning, ...args);
|
|
554
|
+
});
|
|
555
|
+
return stripTypeScriptTypes2(source, {
|
|
556
|
+
mode: "transform",
|
|
557
|
+
sourceUrl: filename
|
|
558
|
+
});
|
|
559
|
+
} finally {
|
|
560
|
+
process.emitWarning = originalEmitWarning;
|
|
760
561
|
}
|
|
761
|
-
return `const value = ${serializedValue};
|
|
762
|
-
|
|
763
|
-
export default value;
|
|
764
|
-
`;
|
|
765
562
|
}
|
|
766
|
-
function
|
|
767
|
-
|
|
768
|
-
|
|
563
|
+
function isSimpleIdentifier(value) {
|
|
564
|
+
return /^[A-Za-z_$][\w$]*$/.test(value);
|
|
565
|
+
}
|
|
566
|
+
function stripOptionalLineTerminator(value) {
|
|
567
|
+
const trimmed = value.trim();
|
|
568
|
+
return trimmed.endsWith(";") ? trimmed.slice(0, -1).trimEnd() : trimmed;
|
|
569
|
+
}
|
|
570
|
+
function parseQuotedModulePath(value) {
|
|
571
|
+
const trimmed = value.trim();
|
|
572
|
+
if (trimmed.length < 2) {
|
|
573
|
+
return null;
|
|
769
574
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
return trimmed;
|
|
774
|
-
}
|
|
775
|
-
return valueToCode(code, 0);
|
|
575
|
+
const quote = trimmed[0];
|
|
576
|
+
if (quote !== '"' && quote !== "'" || trimmed[trimmed.length - 1] !== quote) {
|
|
577
|
+
return null;
|
|
776
578
|
}
|
|
777
|
-
return
|
|
579
|
+
return trimmed.slice(1, -1);
|
|
778
580
|
}
|
|
779
|
-
function
|
|
780
|
-
|
|
581
|
+
function getLineIndentation(line) {
|
|
582
|
+
const match = line.match(/^\s*/);
|
|
583
|
+
return match?.[0] ?? "";
|
|
781
584
|
}
|
|
782
|
-
function
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
585
|
+
function rewriteImportLine(line, nextImportBinding, resolveDefaultImport) {
|
|
586
|
+
const indentation = getLineIndentation(line);
|
|
587
|
+
const trimmed = stripOptionalLineTerminator(line);
|
|
588
|
+
if (!trimmed.startsWith("import ")) {
|
|
589
|
+
return null;
|
|
786
590
|
}
|
|
787
|
-
|
|
788
|
-
|
|
591
|
+
const importBody = trimmed.slice("import ".length).trim();
|
|
592
|
+
const sideEffectModulePath = parseQuotedModulePath(importBody);
|
|
593
|
+
if (sideEffectModulePath !== null) {
|
|
594
|
+
return `${indentation}require(${JSON.stringify(sideEffectModulePath)});`;
|
|
789
595
|
}
|
|
790
|
-
|
|
791
|
-
|
|
596
|
+
const fromIndex = importBody.lastIndexOf(" from ");
|
|
597
|
+
if (fromIndex === -1) {
|
|
598
|
+
return null;
|
|
792
599
|
}
|
|
793
|
-
|
|
794
|
-
|
|
600
|
+
const clause = importBody.slice(0, fromIndex).trim();
|
|
601
|
+
const modulePath = parseQuotedModulePath(importBody.slice(fromIndex + 6));
|
|
602
|
+
if (!clause || modulePath === null) {
|
|
603
|
+
return null;
|
|
795
604
|
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
605
|
+
const buildDefaultImport = (defaultName) => {
|
|
606
|
+
if (!isSimpleIdentifier(defaultName)) {
|
|
607
|
+
return null;
|
|
608
|
+
}
|
|
609
|
+
const bindingName = nextImportBinding();
|
|
610
|
+
return {
|
|
611
|
+
bindingName,
|
|
612
|
+
code: [
|
|
613
|
+
`${indentation}const ${bindingName} = require(${JSON.stringify(modulePath)});`,
|
|
614
|
+
`${indentation}const ${defaultName} = ${resolveDefaultImport(bindingName)};`
|
|
615
|
+
].join("\n")
|
|
616
|
+
};
|
|
617
|
+
};
|
|
618
|
+
if (clause.startsWith("* as ")) {
|
|
619
|
+
const namespaceName = clause.slice(5).trim();
|
|
620
|
+
return isSimpleIdentifier(namespaceName) ? `${indentation}const ${namespaceName} = require(${JSON.stringify(modulePath)});` : null;
|
|
804
621
|
}
|
|
805
|
-
if (
|
|
806
|
-
|
|
622
|
+
if (clause.startsWith("{") && clause.endsWith("}")) {
|
|
623
|
+
const namedBindings = clause.slice(1, -1).trim();
|
|
624
|
+
return namedBindings.length > 0 ? `${indentation}const { ${formatNamedImportBindings(namedBindings)} } = require(${JSON.stringify(modulePath)});` : null;
|
|
807
625
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
if (valueMatch && valueMatch.index !== void 0) {
|
|
816
|
-
const equalsIndex = source.indexOf("=", valueMatch.index);
|
|
817
|
-
if (equalsIndex !== -1) {
|
|
818
|
-
const initializerEnd = findInitializerEnd(source, equalsIndex + 1);
|
|
819
|
-
const end = initializerEnd < source.length && source[initializerEnd] === ";" ? initializerEnd + 1 : initializerEnd;
|
|
820
|
-
matches.push({
|
|
821
|
-
kind: "valueDecl",
|
|
822
|
-
start: valueMatch.index,
|
|
823
|
-
end,
|
|
824
|
-
exported: /^\s*export\b/.test(valueMatch[0]),
|
|
825
|
-
prefixEnd: equalsIndex + 1
|
|
826
|
-
});
|
|
626
|
+
const commaIndex = clause.indexOf(",");
|
|
627
|
+
if (commaIndex !== -1) {
|
|
628
|
+
const defaultName = clause.slice(0, commaIndex).trim();
|
|
629
|
+
const remainder = clause.slice(commaIndex + 1).trim();
|
|
630
|
+
const defaultImport = buildDefaultImport(defaultName);
|
|
631
|
+
if (!defaultImport) {
|
|
632
|
+
return null;
|
|
827
633
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const end = braceClose + 1 < source.length && source[braceClose + 1] === ";" ? braceClose + 2 : braceClose + 1;
|
|
836
|
-
matches.push({
|
|
837
|
-
kind: "functionDecl",
|
|
838
|
-
start: functionMatch.index,
|
|
839
|
-
end,
|
|
840
|
-
exported: /^\s*export\b/.test(functionMatch[0])
|
|
841
|
-
});
|
|
634
|
+
if (remainder.startsWith("* as ")) {
|
|
635
|
+
const namespaceName = remainder.slice(5).trim();
|
|
636
|
+
if (!isSimpleIdentifier(namespaceName)) {
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
return `${defaultImport.code}
|
|
640
|
+
${indentation}const ${namespaceName} = ${defaultImport.bindingName};`;
|
|
842
641
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
const end = braceClose + 1 < source.length && source[braceClose + 1] === ";" ? braceClose + 2 : braceClose + 1;
|
|
851
|
-
matches.push({
|
|
852
|
-
kind: "classDecl",
|
|
853
|
-
start: classMatch.index,
|
|
854
|
-
end,
|
|
855
|
-
exported: /^\s*export\b/.test(classMatch[0])
|
|
856
|
-
});
|
|
642
|
+
if (remainder.startsWith("{") && remainder.endsWith("}")) {
|
|
643
|
+
const namedBindings = remainder.slice(1, -1).trim();
|
|
644
|
+
if (!namedBindings) {
|
|
645
|
+
return null;
|
|
646
|
+
}
|
|
647
|
+
return `${defaultImport.code}
|
|
648
|
+
${indentation}const { ${formatNamedImportBindings(namedBindings)} } = ${defaultImport.bindingName};`;
|
|
857
649
|
}
|
|
858
|
-
}
|
|
859
|
-
if (matches.length === 0) {
|
|
860
650
|
return null;
|
|
861
651
|
}
|
|
862
|
-
|
|
863
|
-
return matches[0];
|
|
652
|
+
return buildDefaultImport(clause)?.code ?? null;
|
|
864
653
|
}
|
|
865
|
-
function
|
|
866
|
-
|
|
867
|
-
|
|
654
|
+
function rewriteExportLine(line, namedExports, markDefaultExport) {
|
|
655
|
+
const trimmed = stripOptionalLineTerminator(line);
|
|
656
|
+
if (!trimmed.startsWith("export ")) {
|
|
657
|
+
return null;
|
|
868
658
|
}
|
|
869
|
-
const
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
if (typeof code === "function") {
|
|
874
|
-
const fnSource = code.toString().trim();
|
|
875
|
-
if (/^(?:async\s+)?function\b/.test(fnSource)) {
|
|
876
|
-
return `export ${normalizeFunctionDeclaration(name, fnSource)}`;
|
|
877
|
-
}
|
|
878
|
-
if (/^class\b/.test(fnSource)) {
|
|
879
|
-
return `export ${normalizeClassDeclaration(name, fnSource)}`;
|
|
880
|
-
}
|
|
881
|
-
return `export const ${name} = ${fnSource};`;
|
|
659
|
+
const indentation = getLineIndentation(line);
|
|
660
|
+
if (trimmed.startsWith("export default ")) {
|
|
661
|
+
markDefaultExport();
|
|
662
|
+
return `${indentation}module.exports = ${trimmed.slice("export default ".length)}`;
|
|
882
663
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
}
|
|
664
|
+
const valueDeclarationMatch = /^export\s+(const|let|var)\s+([A-Za-z_$][\w$]*)\b/.exec(trimmed);
|
|
665
|
+
if (valueDeclarationMatch) {
|
|
666
|
+
namedExports.add(valueDeclarationMatch[2]);
|
|
667
|
+
return `${indentation}${trimmed.slice("export ".length)}`;
|
|
888
668
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
const dbPath = import_node_path.default.join(DIR, `${dbName}.ts`);
|
|
894
|
-
const fileContent = buildDatabaseModuleSource(dbName, code, dbPath);
|
|
895
|
-
import_node_fs.default.writeFileSync(dbPath, fileContent, "utf8");
|
|
896
|
-
}
|
|
897
|
-
function update(dbName, fnName, code, options) {
|
|
898
|
-
const DIR = options?.dir || import_node_path.default.join(process.cwd(), "databases");
|
|
899
|
-
const dbPath = import_node_path.default.join(DIR, `${dbName}.ts`);
|
|
900
|
-
if (!import_node_fs.default.existsSync(dbPath)) {
|
|
901
|
-
try {
|
|
902
|
-
import_node_fs.default.writeFileSync(dbPath, "", "utf8");
|
|
903
|
-
} catch {
|
|
904
|
-
return `Failed to create dbPath file: ${dbPath}`;
|
|
905
|
-
}
|
|
669
|
+
const asyncFunctionMatch = /^export\s+async\s+function\s+([A-Za-z_$][\w$]*)\b/.exec(trimmed);
|
|
670
|
+
if (asyncFunctionMatch) {
|
|
671
|
+
namedExports.add(asyncFunctionMatch[1]);
|
|
672
|
+
return `${indentation}${trimmed.slice("export ".length)}`;
|
|
906
673
|
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
if (declaration.kind === "valueDecl" && declaration.prefixEnd !== void 0) {
|
|
912
|
-
const initializer = toInitializerSource(code);
|
|
913
|
-
src = src.slice(0, declaration.start) + src.slice(declaration.start, declaration.prefixEnd) + ` ${initializer};` + src.slice(declaration.end);
|
|
914
|
-
} else if (declaration.kind === "functionDecl") {
|
|
915
|
-
const replacement = createStructuredReplacement("functionDecl", fnName, code);
|
|
916
|
-
src = src.slice(0, declaration.start) + `${declaration.exported ? "export " : ""}${replacement.replace(/^export\s+/, "")}` + src.slice(declaration.end);
|
|
917
|
-
} else {
|
|
918
|
-
const replacement = createStructuredReplacement("classDecl", fnName, code);
|
|
919
|
-
src = src.slice(0, declaration.start) + `${declaration.exported ? "export " : ""}${replacement.replace(/^export\s+/, "")}` + src.slice(declaration.end);
|
|
920
|
-
}
|
|
921
|
-
} else {
|
|
922
|
-
const snippet = createDeclarationSnippet(fnName, code);
|
|
923
|
-
const separator = src.trim().length > 0 ? "\n\n" : "";
|
|
924
|
-
src = `${src.trimEnd()}${separator}${snippet}
|
|
925
|
-
`;
|
|
674
|
+
const functionMatch = /^export\s+function\s+([A-Za-z_$][\w$]*)\b/.exec(trimmed);
|
|
675
|
+
if (functionMatch) {
|
|
676
|
+
namedExports.add(functionMatch[1]);
|
|
677
|
+
return `${indentation}${trimmed.slice("export ".length)}`;
|
|
926
678
|
}
|
|
927
|
-
|
|
928
|
-
if (
|
|
929
|
-
|
|
679
|
+
const classMatch = /^export\s+class\s+([A-Za-z_$][\w$]*)\b/.exec(trimmed);
|
|
680
|
+
if (classMatch) {
|
|
681
|
+
namedExports.add(classMatch[1]);
|
|
682
|
+
return `${indentation}${trimmed.slice("export ".length)}`;
|
|
930
683
|
}
|
|
931
|
-
|
|
684
|
+
if (trimmed.startsWith("export {") && trimmed.endsWith("}")) {
|
|
685
|
+
const specifiers = trimmed.slice("export {".length, -1).trim();
|
|
686
|
+
return specifiers.length > 0 ? `${indentation}${formatNamedExportAssignments(specifiers)}` : null;
|
|
687
|
+
}
|
|
688
|
+
return null;
|
|
932
689
|
}
|
|
933
|
-
function
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
return "[\n" + items.map((it) => indentInner + it).join(",\n") + "\n" + indent + "]";
|
|
690
|
+
function rewriteModuleSyntaxToCommonJs(source) {
|
|
691
|
+
let importCounter = 0;
|
|
692
|
+
let hasDefaultExport = false;
|
|
693
|
+
const namedExports = /* @__PURE__ */ new Set();
|
|
694
|
+
const nextImportBinding = () => `__vm_import_${importCounter++}`;
|
|
695
|
+
const resolveDefaultImport = (bindingName) => `${bindingName} && Object.prototype.hasOwnProperty.call(${bindingName}, "default") ? ${bindingName}.default : ${bindingName}`;
|
|
696
|
+
const code = source.split(/\r?\n/).map((line) => rewriteImportLine(line, nextImportBinding, resolveDefaultImport) ?? rewriteExportLine(line, namedExports, () => {
|
|
697
|
+
hasDefaultExport = true;
|
|
698
|
+
}) ?? line).join("\n");
|
|
699
|
+
const exportFooter = [...namedExports].map((name) => `module.exports.${name} = ${name};`);
|
|
700
|
+
if (hasDefaultExport) {
|
|
701
|
+
exportFooter.push("module.exports.default = module.exports;");
|
|
946
702
|
}
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
703
|
+
return exportFooter.length > 0 ? `${code.trimEnd()}
|
|
704
|
+
${exportFooter.join("\n")}
|
|
705
|
+
` : code;
|
|
706
|
+
}
|
|
707
|
+
function transpileVmModule(source, options = {}) {
|
|
708
|
+
const loader = options.loader || "js";
|
|
709
|
+
const filename = options.filename || `virtual.${loader}`;
|
|
710
|
+
if (loader === "tsx" || loader === "jsx") {
|
|
711
|
+
const esbuildTransformSync = getEsbuildTransformSync();
|
|
712
|
+
if (!esbuildTransformSync) {
|
|
713
|
+
throw new Error(`JSX database execution requires the esbuild package (${filename}).`);
|
|
714
|
+
}
|
|
715
|
+
return esbuildTransformSync(source, {
|
|
716
|
+
loader,
|
|
717
|
+
format: options.format
|
|
954
718
|
});
|
|
955
|
-
return "{\n" + entries.join(",\n") + "\n" + indent + "}";
|
|
956
719
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
720
|
+
if (loader === "ts") {
|
|
721
|
+
try {
|
|
722
|
+
return {
|
|
723
|
+
code: rewriteModuleSyntaxToCommonJs(stripTypescriptSource(source, filename))
|
|
724
|
+
};
|
|
725
|
+
} catch (error) {
|
|
726
|
+
const esbuildTransformSync = getEsbuildTransformSync();
|
|
727
|
+
if (!esbuildTransformSync) {
|
|
728
|
+
throw error;
|
|
729
|
+
}
|
|
730
|
+
return esbuildTransformSync(source, {
|
|
731
|
+
loader,
|
|
732
|
+
format: options.format
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return {
|
|
737
|
+
code: rewriteModuleSyntaxToCommonJs(source)
|
|
738
|
+
};
|
|
961
739
|
}
|
|
740
|
+
|
|
741
|
+
// src/server/database/vm.ts
|
|
962
742
|
async function SystemModuleResolver(customOptions) {
|
|
963
743
|
const moduleRegistry = /* @__PURE__ */ new Map();
|
|
964
744
|
moduleRegistry.set("update", (dbName, fnName, code) => update(dbName, fnName, code, customOptions));
|
|
@@ -967,7 +747,6 @@ ${trimmed}
|
|
|
967
747
|
moduleRegistry.set("save", (dbName, code) => save(dbName, code, customOptions));
|
|
968
748
|
moduleRegistry.set("read", (dbName) => read(dbName, customOptions));
|
|
969
749
|
const context = {
|
|
970
|
-
// Add require-like functionality
|
|
971
750
|
require: (moduleName) => {
|
|
972
751
|
const module = moduleRegistry.get(moduleName);
|
|
973
752
|
if (!module) {
|
|
@@ -975,7 +754,6 @@ ${trimmed}
|
|
|
975
754
|
}
|
|
976
755
|
return module.default || module;
|
|
977
756
|
},
|
|
978
|
-
// Add import functionality (simulated)
|
|
979
757
|
import: async (moduleName) => {
|
|
980
758
|
const module = moduleRegistry.get(moduleName);
|
|
981
759
|
if (!module) {
|
|
@@ -991,6 +769,236 @@ ${trimmed}
|
|
|
991
769
|
}
|
|
992
770
|
return context;
|
|
993
771
|
}
|
|
772
|
+
var VM = class {
|
|
773
|
+
constructor(options) {
|
|
774
|
+
this.pkgScriptDB = {};
|
|
775
|
+
this.options = options || {};
|
|
776
|
+
this.DATABASE_DIR = options?.dir || import_node_path3.default.join(process.cwd(), "databases");
|
|
777
|
+
this.SCRIPTDB_DIR = process.cwd();
|
|
778
|
+
if (!import_node_fs2.default.existsSync(this.DATABASE_DIR)) {
|
|
779
|
+
import_node_fs2.default.mkdirSync(this.DATABASE_DIR, { recursive: true });
|
|
780
|
+
}
|
|
781
|
+
if (!import_node_fs2.default.existsSync(this.SCRIPTDB_DIR)) {
|
|
782
|
+
import_node_fs2.default.mkdirSync(this.SCRIPTDB_DIR, { recursive: true });
|
|
783
|
+
}
|
|
784
|
+
const pkgPath = import_node_path3.default.join(this.SCRIPTDB_DIR, "package.json");
|
|
785
|
+
if (import_node_fs2.default.existsSync(pkgPath)) {
|
|
786
|
+
this.pkgScriptDB = JSON.parse(import_node_fs2.default.readFileSync(pkgPath, "utf8"));
|
|
787
|
+
}
|
|
788
|
+
this.language = options?.language || "ts";
|
|
789
|
+
this.transpiler = transpileVmModule;
|
|
790
|
+
this.registerModules = options?.registerModules || {};
|
|
791
|
+
this._registerModules = { ...this.registerModules };
|
|
792
|
+
this._registerModules.require = ((moduleId) => this.createRequire(moduleId)).bind(this);
|
|
793
|
+
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
794
|
+
}
|
|
795
|
+
register(context) {
|
|
796
|
+
this.registerModules = { ...this.registerModules, ...context };
|
|
797
|
+
this._registerModules = { ...this._registerModules, ...context };
|
|
798
|
+
const originalRequire = context.require;
|
|
799
|
+
this._registerModules.require = ((moduleId) => {
|
|
800
|
+
try {
|
|
801
|
+
return this.createRequire(moduleId);
|
|
802
|
+
} catch (error) {
|
|
803
|
+
if (originalRequire && !moduleId.startsWith("@db/") && !moduleId.startsWith("./") && !moduleId.startsWith("../")) {
|
|
804
|
+
return originalRequire(moduleId);
|
|
805
|
+
}
|
|
806
|
+
throw error;
|
|
807
|
+
}
|
|
808
|
+
}).bind(this);
|
|
809
|
+
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
810
|
+
}
|
|
811
|
+
createRequire(moduleId) {
|
|
812
|
+
if (!moduleId) {
|
|
813
|
+
console.error("[createRequire] moduleId is undefined");
|
|
814
|
+
return {};
|
|
815
|
+
}
|
|
816
|
+
if (moduleId.startsWith("@db/")) {
|
|
817
|
+
const relativePath = moduleId.substring(4);
|
|
818
|
+
moduleId = "./" + relativePath;
|
|
819
|
+
}
|
|
820
|
+
if (moduleId.startsWith("./") || moduleId.startsWith("../")) {
|
|
821
|
+
const dbDir = this.DATABASE_DIR || process.cwd();
|
|
822
|
+
const fullPath = import_node_path3.default.join(dbDir, moduleId);
|
|
823
|
+
let actualPath = fullPath;
|
|
824
|
+
if (import_node_fs2.default.existsSync(fullPath)) {
|
|
825
|
+
actualPath = fullPath;
|
|
826
|
+
} else {
|
|
827
|
+
const extensions = [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs"];
|
|
828
|
+
for (const ext of extensions) {
|
|
829
|
+
if (import_node_fs2.default.existsSync(fullPath + ext)) {
|
|
830
|
+
actualPath = fullPath + ext;
|
|
831
|
+
break;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (!actualPath || !import_node_fs2.default.existsSync(actualPath)) {
|
|
836
|
+
throw new Error(`Module '${moduleId}' not found at ${fullPath}`);
|
|
837
|
+
}
|
|
838
|
+
if (actualPath.endsWith(".ts") || actualPath.endsWith(".tsx") || actualPath.endsWith(".mts") || actualPath.endsWith(".cts") || actualPath.endsWith(".js") || actualPath.endsWith(".mjs")) {
|
|
839
|
+
const content = import_node_fs2.default.readFileSync(actualPath, "utf8");
|
|
840
|
+
const loader = actualPath.endsWith(".ts") || actualPath.endsWith(".mts") || actualPath.endsWith(".cts") ? "ts" : actualPath.endsWith(".tsx") ? "tsx" : "js";
|
|
841
|
+
const js = this.transpiler(content, {
|
|
842
|
+
loader,
|
|
843
|
+
format: "cjs",
|
|
844
|
+
filename: actualPath
|
|
845
|
+
}).code;
|
|
846
|
+
const moduleWrapper = { exports: {} };
|
|
847
|
+
const moduleContext = import_node_vm.default.createContext({
|
|
848
|
+
...this._registerModules,
|
|
849
|
+
module: moduleWrapper,
|
|
850
|
+
exports: moduleWrapper.exports
|
|
851
|
+
});
|
|
852
|
+
import_node_vm.default.runInContext(js, moduleContext, { filename: actualPath });
|
|
853
|
+
return moduleWrapper.exports;
|
|
854
|
+
}
|
|
855
|
+
return __require(actualPath);
|
|
856
|
+
}
|
|
857
|
+
return __require(moduleId);
|
|
858
|
+
}
|
|
859
|
+
resolvePath(fileList, query) {
|
|
860
|
+
const aliases = { "@db": this.DATABASE_DIR };
|
|
861
|
+
let resolvedPath = query;
|
|
862
|
+
for (const [alias, target] of Object.entries(aliases)) {
|
|
863
|
+
if (resolvedPath.startsWith(alias + "/")) {
|
|
864
|
+
resolvedPath = resolvedPath.replace(alias, target);
|
|
865
|
+
break;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
resolvedPath = import_node_path3.default.normalize(resolvedPath);
|
|
869
|
+
return fileList.find((file) => {
|
|
870
|
+
const normalizedFile = import_node_path3.default.normalize(file);
|
|
871
|
+
const fileWithoutExt = normalizedFile.replace(/\.[^/.]+$/, "");
|
|
872
|
+
return normalizedFile === resolvedPath || fileWithoutExt === resolvedPath || normalizedFile === resolvedPath + ".ts" || normalizedFile === resolvedPath + ".js";
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
async moduleLinker(specifier, referencingModule) {
|
|
876
|
+
const dbFiles = import_node_fs2.default.readdirSync(this.DATABASE_DIR).filter((file) => file.endsWith(".ts")).map((file) => import_node_path3.default.join(this.DATABASE_DIR, file));
|
|
877
|
+
const dbResult = this.resolvePath(dbFiles, specifier);
|
|
878
|
+
if (dbResult) {
|
|
879
|
+
try {
|
|
880
|
+
const actualModule = await import(dbResult);
|
|
881
|
+
const exportNames = Object.keys(actualModule);
|
|
882
|
+
return new import_node_vm.default.SyntheticModule(
|
|
883
|
+
exportNames,
|
|
884
|
+
function() {
|
|
885
|
+
exportNames.forEach((key) => {
|
|
886
|
+
this.setExport(key, actualModule[key]);
|
|
887
|
+
});
|
|
888
|
+
},
|
|
889
|
+
{ identifier: specifier, context: referencingModule.context }
|
|
890
|
+
);
|
|
891
|
+
} catch (err) {
|
|
892
|
+
console.error(`Failed to load database module ${specifier}:`, err);
|
|
893
|
+
throw err;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
const allowedPackages = Object.keys(this.pkgScriptDB.dependencies || {});
|
|
897
|
+
if (allowedPackages.includes(specifier)) {
|
|
898
|
+
try {
|
|
899
|
+
const modulePath = import_node_path3.default.join(this.SCRIPTDB_DIR, "node_modules", specifier);
|
|
900
|
+
const actualModule = await import(modulePath);
|
|
901
|
+
const exportNames = Object.keys(actualModule);
|
|
902
|
+
return new import_node_vm.default.SyntheticModule(
|
|
903
|
+
exportNames,
|
|
904
|
+
function() {
|
|
905
|
+
exportNames.forEach((key) => {
|
|
906
|
+
this.setExport(key, actualModule[key]);
|
|
907
|
+
});
|
|
908
|
+
},
|
|
909
|
+
{ identifier: specifier, context: referencingModule.context }
|
|
910
|
+
);
|
|
911
|
+
} catch (err) {
|
|
912
|
+
console.error(`Failed to load workspace module ${specifier}:`, err);
|
|
913
|
+
throw err;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
throw new Error(`Module ${specifier} is not allowed or not found.`);
|
|
917
|
+
}
|
|
918
|
+
async run(code) {
|
|
919
|
+
const logs = [];
|
|
920
|
+
const customConsole = ["log", "error", "warn", "info", "debug", "trace"].reduce((acc, type) => {
|
|
921
|
+
acc[type] = (...args) => logs.push({ type, args });
|
|
922
|
+
return acc;
|
|
923
|
+
}, {});
|
|
924
|
+
this.register({
|
|
925
|
+
console: customConsole
|
|
926
|
+
});
|
|
927
|
+
const systemModules = await SystemModuleResolver(this.options);
|
|
928
|
+
this.register(systemModules);
|
|
929
|
+
const js = this.transpiler(code, {
|
|
930
|
+
loader: this.language,
|
|
931
|
+
format: "cjs",
|
|
932
|
+
filename: import_node_path3.default.join(this.SCRIPTDB_DIR, `virtual-entry.${this.language}`)
|
|
933
|
+
}).code;
|
|
934
|
+
const SourceTextModule = import_node_vm.default.SourceTextModule;
|
|
935
|
+
if (typeof SourceTextModule === "function") {
|
|
936
|
+
const mod = new SourceTextModule(js, { context: this.ctx, identifier: import_node_path3.default.join(this.SCRIPTDB_DIR, "virtual-entry.js") });
|
|
937
|
+
await mod.link(this.moduleLinker.bind(this));
|
|
938
|
+
await mod.evaluate();
|
|
939
|
+
return {
|
|
940
|
+
namespace: mod.namespace,
|
|
941
|
+
logs
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
let processedCode = js;
|
|
945
|
+
processedCode = processedCode.replace(
|
|
946
|
+
/var\s+(\w+)\s+=\s+require\((['"])([^'"]+)\2\);/g,
|
|
947
|
+
(_match, varName, quote, modulePath) => {
|
|
948
|
+
return `const ${varName} = require(${quote}${modulePath}${quote});`;
|
|
949
|
+
}
|
|
950
|
+
);
|
|
951
|
+
processedCode = processedCode.replace(
|
|
952
|
+
/import\s+\{([^}]+)\}\s+from\s+(['"])([^'"]+)\2/g,
|
|
953
|
+
(_match, imports, quote, modulePath) => {
|
|
954
|
+
return `const { ${imports} } = require(${quote}${modulePath}${quote});`;
|
|
955
|
+
}
|
|
956
|
+
);
|
|
957
|
+
processedCode = processedCode.replace(
|
|
958
|
+
/import\s+(\w+)\s+from\s+(['"])([^'"]+)\2/g,
|
|
959
|
+
(_match, name, quote, modulePath) => {
|
|
960
|
+
return `const ${name} = require(${quote}${modulePath}${quote});`;
|
|
961
|
+
}
|
|
962
|
+
);
|
|
963
|
+
processedCode = processedCode.replace(/import\(([^)]+)\)/g, "require($1)");
|
|
964
|
+
try {
|
|
965
|
+
const moduleWrapper = { exports: {} };
|
|
966
|
+
const initialExports = moduleWrapper.exports;
|
|
967
|
+
const originalModule = this._registerModules.module;
|
|
968
|
+
const originalExports = this._registerModules.exports;
|
|
969
|
+
this._registerModules.module = moduleWrapper;
|
|
970
|
+
this._registerModules.exports = moduleWrapper.exports;
|
|
971
|
+
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
972
|
+
let result;
|
|
973
|
+
try {
|
|
974
|
+
result = import_node_vm.default.runInContext(processedCode, this.ctx, {
|
|
975
|
+
filename: import_node_path3.default.join(this.SCRIPTDB_DIR, "virtual-entry.js")
|
|
976
|
+
});
|
|
977
|
+
} finally {
|
|
978
|
+
if (originalModule) {
|
|
979
|
+
this._registerModules.module = originalModule;
|
|
980
|
+
} else {
|
|
981
|
+
delete this._registerModules.module;
|
|
982
|
+
}
|
|
983
|
+
if (originalExports) {
|
|
984
|
+
this._registerModules.exports = originalExports;
|
|
985
|
+
} else {
|
|
986
|
+
delete this._registerModules.exports;
|
|
987
|
+
}
|
|
988
|
+
this.ctx = import_node_vm.default.createContext(this._registerModules);
|
|
989
|
+
}
|
|
990
|
+
const hasExplicitExports = moduleWrapper.exports !== initialExports || typeof initialExports === "object" && initialExports !== null && Object.keys(initialExports).length > 0;
|
|
991
|
+
return {
|
|
992
|
+
namespace: hasExplicitExports ? moduleWrapper.exports : result,
|
|
993
|
+
logs
|
|
994
|
+
};
|
|
995
|
+
} catch (error) {
|
|
996
|
+
throw error;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
|
|
1001
|
+
// src/server/database/database.ts
|
|
994
1002
|
var Database = class {
|
|
995
1003
|
constructor(options) {
|
|
996
1004
|
this.options = {
|
|
@@ -1006,40 +1014,21 @@ ${trimmed}
|
|
|
1006
1014
|
async execute(code) {
|
|
1007
1015
|
return await this.vm.run(code);
|
|
1008
1016
|
}
|
|
1009
|
-
// ===== Database Helper Methods =====
|
|
1010
|
-
/**
|
|
1011
|
-
* Create a new database file with the given code
|
|
1012
|
-
*/
|
|
1013
1017
|
create(dbName, code) {
|
|
1014
1018
|
return create(dbName, code, this.options);
|
|
1015
1019
|
}
|
|
1016
|
-
/**
|
|
1017
|
-
* Read the contents of a database file
|
|
1018
|
-
*/
|
|
1019
1020
|
read(dbName) {
|
|
1020
1021
|
return read(dbName, this.options);
|
|
1021
1022
|
}
|
|
1022
|
-
/**
|
|
1023
|
-
* Remove a function or the entire database file
|
|
1024
|
-
*/
|
|
1025
1023
|
remove(dbName, fnName) {
|
|
1026
1024
|
return remove(dbName, fnName || "", this.options);
|
|
1027
1025
|
}
|
|
1028
|
-
/**
|
|
1029
|
-
* Rename a database file
|
|
1030
|
-
*/
|
|
1031
1026
|
rename(oldName, newName) {
|
|
1032
1027
|
return rename(oldName, newName, this.options);
|
|
1033
1028
|
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Save code to a database file (overwrites existing content)
|
|
1036
|
-
*/
|
|
1037
1029
|
save(dbName, code) {
|
|
1038
1030
|
return save(dbName, code, this.options);
|
|
1039
1031
|
}
|
|
1040
|
-
/**
|
|
1041
|
-
* Update a function in a database file
|
|
1042
|
-
*/
|
|
1043
1032
|
update(dbName, fnName, code) {
|
|
1044
1033
|
return update(dbName, fnName, code, this.options);
|
|
1045
1034
|
}
|