@linghun/pre-engine-win32-x64 0.1.0

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.
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ const readline = require("readline");
3
+ const path = require("path");
4
+ const { execFileSync, spawnSync } = require("child_process");
5
+
6
+ let cachedPyrightPath = null;
7
+ let cachedRoot = null;
8
+
9
+ function findPyright(root) {
10
+ if (cachedPyrightPath && cachedRoot === root) return cachedPyrightPath;
11
+
12
+ const candidates = [
13
+ path.join(root, "node_modules", ".bin", "pyright"),
14
+ path.join(root, "node_modules", ".bin", "pyright.cmd"),
15
+ ];
16
+ const fs = require("fs");
17
+ for (const c of candidates) {
18
+ if (fs.existsSync(c)) {
19
+ cachedPyrightPath = c;
20
+ cachedRoot = root;
21
+ return c;
22
+ }
23
+ }
24
+
25
+ const whichCmd = process.platform === "win32" ? "where.exe" : "which";
26
+ const result = spawnSync(whichCmd, ["pyright"], {
27
+ encoding: "utf8",
28
+ stdio: ["ignore", "pipe", "ignore"],
29
+ windowsHide: true,
30
+ });
31
+ if (result.status === 0) {
32
+ const lines = result.stdout.split(/\r?\n/).map(l => l.trim()).filter(Boolean);
33
+ // On Windows prefer .cmd over extensionless shell script
34
+ const preferred = lines.find(l => l.endsWith(".cmd")) || lines[0];
35
+ if (preferred) {
36
+ cachedPyrightPath = preferred;
37
+ cachedRoot = root;
38
+ return preferred;
39
+ }
40
+ }
41
+
42
+ try {
43
+ const resolved = require.resolve("pyright");
44
+ if (resolved) {
45
+ cachedPyrightPath = resolved;
46
+ cachedRoot = root;
47
+ return resolved;
48
+ }
49
+ } catch {}
50
+
51
+ return null;
52
+ }
53
+
54
+ function runCheck(root, files, pyrightconfig) {
55
+ const pyrightPath = findPyright(root);
56
+ if (!pyrightPath) return { error: "pyright not found" };
57
+
58
+ const args = ["--outputjson"];
59
+ if (pyrightconfig) {
60
+ args.push("--project", pyrightconfig);
61
+ }
62
+ for (const f of files) {
63
+ const abs = path.isAbsolute(f) ? f : path.join(root, f);
64
+ args.push(abs);
65
+ }
66
+
67
+ let result;
68
+ try {
69
+ const isCmd = pyrightPath.endsWith(".cmd");
70
+ const cmd = isCmd ? process.env.ComSpec || "cmd.exe" : pyrightPath;
71
+ const execArgs = isCmd ? ["/c", pyrightPath, ...args] : args;
72
+
73
+ result = spawnSync(cmd, execArgs, {
74
+ cwd: root,
75
+ encoding: "utf8",
76
+ stdio: ["ignore", "pipe", "pipe"],
77
+ windowsHide: true,
78
+ timeout: 30000,
79
+ });
80
+ } catch (e) {
81
+ return { error: `pyright exec failed: ${e.message}` };
82
+ }
83
+
84
+ if (result.error) {
85
+ if (result.error.code === "ETIMEDOUT") {
86
+ return { error: "pyright timeout (30s)" };
87
+ }
88
+ return { error: `pyright spawn error: ${result.error.message}` };
89
+ }
90
+
91
+ const stdout = result.stdout || "";
92
+ let parsed;
93
+ try {
94
+ parsed = JSON.parse(stdout);
95
+ } catch {
96
+ if (result.status === 0) return { issues: [] };
97
+ return { error: `pyright non-json output (exit=${result.status})` };
98
+ }
99
+
100
+ const issues = [];
101
+ const diagnostics = parsed.generalDiagnostics || [];
102
+ for (const d of diagnostics) {
103
+ if (d.severity !== "error") continue;
104
+ const filePath = d.file || "";
105
+ const rel = path.isAbsolute(filePath)
106
+ ? path.relative(root, filePath).replace(/\\/g, "/")
107
+ : filePath.replace(/\\/g, "/");
108
+
109
+ const targetFiles = files.map(f =>
110
+ (path.isAbsolute(f) ? path.relative(root, f) : f).replace(/\\/g, "/")
111
+ );
112
+ if (!targetFiles.includes(rel)) continue;
113
+
114
+ issues.push({
115
+ file: rel,
116
+ line: (d.range && d.range.start && d.range.start.line != null)
117
+ ? d.range.start.line + 1
118
+ : 1,
119
+ kind: "type_error",
120
+ detail: d.message || "unknown error",
121
+ source: "python-deep-layer",
122
+ });
123
+ }
124
+ return { issues };
125
+ }
126
+
127
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
128
+ rl.on("line", line => {
129
+ line = line.trim();
130
+ if (!line) return;
131
+ let req;
132
+ try { req = JSON.parse(line); } catch { return; }
133
+ const t0 = Date.now();
134
+ let resp;
135
+ try {
136
+ const result = runCheck(req.root, req.files || [], req.pyrightconfig || null);
137
+ resp = { ...result, elapsed_ms: Date.now() - t0 };
138
+ } catch (e) {
139
+ resp = { error: String(e), elapsed_ms: Date.now() - t0 };
140
+ }
141
+ process.stdout.write(JSON.stringify(resp) + "\n");
142
+ });
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ const readline = require("readline");
3
+ const path = require("path");
4
+ const { spawnSync } = require("child_process");
5
+
6
+ function findRuby() {
7
+ const whichCmd = process.platform === "win32" ? "where.exe" : "which";
8
+ const r = spawnSync(whichCmd, ["ruby"], {
9
+ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], windowsHide: true,
10
+ });
11
+ if (r.status === 0) {
12
+ const line = r.stdout.split(/\r?\n/).map(l => l.trim()).filter(Boolean)[0];
13
+ return line || null;
14
+ }
15
+ return null;
16
+ }
17
+
18
+ function runRubyCheck(root, files) {
19
+ const ruby = findRuby();
20
+ if (!ruby) return null;
21
+
22
+ const issues = [];
23
+ for (const f of files) {
24
+ const abs = path.isAbsolute(f) ? f : path.join(root, f);
25
+ let r;
26
+ try {
27
+ r = spawnSync(ruby, ["-c", abs], {
28
+ cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"],
29
+ windowsHide: true, timeout: 30000,
30
+ });
31
+ } catch (e) { continue; }
32
+
33
+ if (r.error) continue;
34
+
35
+ if (r.status !== 0) {
36
+ const rel = path.relative(root, abs).replace(/\\/g, "/");
37
+ const stderr = (r.stderr || "").trim();
38
+ const m = stderr.match(/^.+?:(\d+):\s*(.+)$/m);
39
+ if (m) {
40
+ issues.push({
41
+ file: rel,
42
+ line: parseInt(m[1], 10),
43
+ col: 1,
44
+ kind: "error",
45
+ message: m[2].trim(),
46
+ source: "ruby-deep-layer",
47
+ });
48
+ } else {
49
+ issues.push({
50
+ file: rel, line: 1, col: 1,
51
+ kind: "error", message: stderr.split(/\r?\n/)[0] || "syntax error",
52
+ source: "ruby-deep-layer",
53
+ });
54
+ }
55
+ }
56
+ }
57
+ return { issues };
58
+ }
59
+
60
+ async function handleRequest(req) {
61
+ const t0 = Date.now();
62
+ const root = req.root || process.cwd();
63
+ const files = req.files || [];
64
+ if (files.length === 0) {
65
+ return { issues: [], status: "clean", reason: "no_files", elapsed_ms: 0 };
66
+ }
67
+
68
+ const lintResult = runRubyCheck(root, files);
69
+ if (lintResult) {
70
+ return {
71
+ issues: lintResult.issues,
72
+ status: lintResult.issues.length > 0 ? "ruby_error" : "clean",
73
+ reason: "ruby",
74
+ elapsed_ms: Date.now() - t0,
75
+ };
76
+ }
77
+
78
+ return {
79
+ issues: [],
80
+ status: "unavailable",
81
+ reason: "ruby_not_found",
82
+ elapsed_ms: Date.now() - t0,
83
+ };
84
+ }
85
+
86
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
87
+ rl.on("line", (line) => {
88
+ const trimmed = line.trim();
89
+ if (!trimmed) return;
90
+ let req;
91
+ try { req = JSON.parse(trimmed); } catch { return; }
92
+ handleRequest(req).then((result) => {
93
+ process.stdout.write(JSON.stringify(result) + "\n");
94
+ }).catch((err) => {
95
+ process.stdout.write(JSON.stringify({ issues: [], status: "error", error: String(err), elapsed_ms: 0 }) + "\n");
96
+ });
97
+ });
98
+ rl.on("close", () => { process.exit(0); });