@open-flow/workbench-engine 0.5.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.
- package/LICENSE +10 -0
- package/bin/workbench.mjs +142 -0
- package/package.json +28 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
© Ecorona LLC — Todos los derechos reservados.
|
|
2
|
+
|
|
3
|
+
Este software se distribuye únicamente en forma compilada. Se autoriza su
|
|
4
|
+
instalación y uso; queda prohibida la redistribución, la descompilación y la
|
|
5
|
+
ingeniería inversa del binario o del código publicado.
|
|
6
|
+
|
|
7
|
+
El código fuente es propiedad de Ecorona LLC y no forma parte de esta
|
|
8
|
+
distribución.
|
|
9
|
+
|
|
10
|
+
[BORRADOR — pendiente de revisión legal por Ecorona LLC.]
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Find the platform binary and hand it the arguments.
|
|
4
|
+
*
|
|
5
|
+
* The scanner is a compiled binary published as one optional dependency per
|
|
6
|
+
* platform — the pattern esbuild and swc use. npm installs only the one that
|
|
7
|
+
* matches, so a Mac does not download a Linux executable.
|
|
8
|
+
*
|
|
9
|
+
* There is deliberately **no JavaScript fallback**. A second implementation of
|
|
10
|
+
* the scan is exactly the duplication this whole tool exists to remove, and one
|
|
11
|
+
* that only ran when the binary was missing would be the least-tested code in
|
|
12
|
+
* the repository. A missing platform is an error with instructions, not a
|
|
13
|
+
* silent downgrade to a different answer.
|
|
14
|
+
*/
|
|
15
|
+
import { spawnSync } from "node:child_process";
|
|
16
|
+
import { accessSync, chmodSync, constants, existsSync } from "node:fs";
|
|
17
|
+
import { createRequire } from "node:module";
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
|
|
21
|
+
const require = createRequire(import.meta.url);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* npm's own platform vocabulary, which is what the package names encode.
|
|
25
|
+
*
|
|
26
|
+
* No libc suffix on the Linux entries, and this shim does not detect one. The
|
|
27
|
+
* Linux binaries are statically linked against musl, so they carry no libc
|
|
28
|
+
* dependency and run on glibc and musl systems alike.
|
|
29
|
+
*
|
|
30
|
+
* That is not cosmetic. The first Linux build was dynamically linked against the
|
|
31
|
+
* glibc of the image that produced it, and Vercel refused it outright:
|
|
32
|
+
* `/lib64/libc.so.6: version GLIBC_2.39 not found`. A binary published for
|
|
33
|
+
* "linux x64" has to run on whatever "linux x64" turns out to mean.
|
|
34
|
+
*/
|
|
35
|
+
const PACKAGES = {
|
|
36
|
+
"darwin arm64": "@open-flow/workbench-darwin-arm64",
|
|
37
|
+
"darwin x64": "@open-flow/workbench-darwin-x64",
|
|
38
|
+
"linux arm64": "@open-flow/workbench-linux-arm64",
|
|
39
|
+
"linux x64": "@open-flow/workbench-linux-x64",
|
|
40
|
+
"win32 x64": "@open-flow/workbench-win32-x64-msvc",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const key = `${process.platform} ${process.arch}`;
|
|
44
|
+
const packageName = PACKAGES[key];
|
|
45
|
+
|
|
46
|
+
if (!packageName) {
|
|
47
|
+
console.error(
|
|
48
|
+
`workbench: no hay binario para ${key}.\n` +
|
|
49
|
+
` Plataformas publicadas: ${Object.keys(PACKAGES).join(", ")}.\n` +
|
|
50
|
+
` Puedes compilarlo tú: cargo build --release -p workbench-cli`,
|
|
51
|
+
);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const executable = process.platform === "win32" ? "workbench.exe" : "workbench";
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* A cargo build in an ancestor directory.
|
|
59
|
+
*
|
|
60
|
+
* Only reachable when this repository *is* the checkout — inside a consumer's
|
|
61
|
+
* `node_modules` there is no `crates/` above us, so this cannot silently
|
|
62
|
+
* shadow a published binary with a stale local one. It exists so that
|
|
63
|
+
* developing the package does not require publishing it first.
|
|
64
|
+
*/
|
|
65
|
+
function locallyBuilt() {
|
|
66
|
+
let directory = dirname(fileURLToPath(import.meta.url));
|
|
67
|
+
for (let depth = 0; depth < 6; depth++) {
|
|
68
|
+
const candidate = join(directory, "target", "release", executable);
|
|
69
|
+
if (existsSync(candidate) && existsSync(join(directory, "crates"))) return candidate;
|
|
70
|
+
const parent = dirname(directory);
|
|
71
|
+
if (parent === directory) break;
|
|
72
|
+
directory = parent;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// The cargo build wins over an installed package, not the other way around:
|
|
78
|
+
// inside this checkout the published binary is by definition at least one
|
|
79
|
+
// release old, and it once silently shadowed the local build for days — the
|
|
80
|
+
// example's manifest said `workbench 0.1.3` while Cargo.toml said 0.1.4.
|
|
81
|
+
// `locallyBuilt()` only resolves when `crates/` is an ancestor, so consumers
|
|
82
|
+
// never take this branch.
|
|
83
|
+
let binary = locallyBuilt();
|
|
84
|
+
if (!binary) {
|
|
85
|
+
try {
|
|
86
|
+
// Resolving the package's own manifest rather than a path inside it: the
|
|
87
|
+
// package exports nothing importable, so `require.resolve(name)` would
|
|
88
|
+
// throw even when it is installed.
|
|
89
|
+
//
|
|
90
|
+
// `manifest` is already a filesystem path — round-tripping it through
|
|
91
|
+
// `new URL("file://…")` truncated at `#` and broke on Windows.
|
|
92
|
+
const manifest = require.resolve(`${packageName}/package.json`);
|
|
93
|
+
binary = join(dirname(manifest), "bin", executable);
|
|
94
|
+
} catch {
|
|
95
|
+
binary = null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!binary || !existsSync(binary)) {
|
|
100
|
+
console.error(
|
|
101
|
+
`workbench: falta ${packageName}.\n` +
|
|
102
|
+
` Suele significar que la instalación se hizo con --no-optional.\n` +
|
|
103
|
+
` Reinstala las dependencias y vuelve a intentarlo.`,
|
|
104
|
+
);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Make sure the binary is executable, because the tarball may say otherwise.
|
|
110
|
+
*
|
|
111
|
+
* The file is written 0755 by `scripts/release/prepare.mjs`, but that mode does
|
|
112
|
+
* not reliably survive being packed and unpacked: measured with `pnpm pack`, the
|
|
113
|
+
* entry comes back 0644, and the only symptom is `spawnSync … EACCES` from a
|
|
114
|
+
* package that installed without a single warning. A `postinstall` script cannot
|
|
115
|
+
* be the fix — this is an OPTIONAL dependency, and `--ignore-scripts` is common
|
|
116
|
+
* in CI — so the check belongs at the one place that is guaranteed to run.
|
|
117
|
+
*
|
|
118
|
+
* Cheap and idempotent: one `access` call on the happy path, and the `chmod` is
|
|
119
|
+
* attempted only when it would otherwise fail. If the chmod is refused too (a
|
|
120
|
+
* read-only store, a different owner), the spawn below reports the real error
|
|
121
|
+
* rather than this one, which is the more useful of the two.
|
|
122
|
+
*/
|
|
123
|
+
try {
|
|
124
|
+
accessSync(binary, constants.X_OK);
|
|
125
|
+
} catch {
|
|
126
|
+
try {
|
|
127
|
+
chmodSync(binary, 0o755);
|
|
128
|
+
} catch {
|
|
129
|
+
// Fall through: let the spawn produce the authoritative failure.
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// `stdio: inherit` so stdin reaches `workbench ticket --json`, and so the
|
|
134
|
+
// scanner's progress and warnings appear as they happen rather than at the end.
|
|
135
|
+
const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
136
|
+
|
|
137
|
+
if (result.error) {
|
|
138
|
+
console.error(`workbench: no se pudo ejecutar ${binary} — ${result.error.message}`);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
// A signal has no exit code; report it as a shell would.
|
|
142
|
+
process.exit(result.status ?? (result.signal ? 1 : 0));
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@open-flow/workbench-engine",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "El motor de workbench: el escáner compilado. El binario es público; el código fuente en Rust no lo es — lo que gobierna el uso es la licencia, no la descarga.",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Ecorona-LLC/workbench.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"bin": {
|
|
12
|
+
"workbench": "./bin/workbench.mjs"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"optionalDependencies": {
|
|
22
|
+
"@open-flow/workbench-darwin-arm64": "0.5.0",
|
|
23
|
+
"@open-flow/workbench-darwin-x64": "0.5.0",
|
|
24
|
+
"@open-flow/workbench-linux-arm64": "0.5.0",
|
|
25
|
+
"@open-flow/workbench-linux-x64": "0.5.0",
|
|
26
|
+
"@open-flow/workbench-win32-x64-msvc": "0.5.0"
|
|
27
|
+
}
|
|
28
|
+
}
|