@wrongstack/tools 0.7.8 → 0.8.2

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/dist/builtin.js CHANGED
@@ -7,7 +7,7 @@ import * as fs11 from 'node:fs/promises';
7
7
  import { stat } from 'node:fs/promises';
8
8
  import { createRequire } from 'node:module';
9
9
  import * as fs from 'node:fs';
10
- import { statSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs';
10
+ import { statSync, mkdirSync, writeFileSync } from 'node:fs';
11
11
  import * as ts from 'typescript';
12
12
  import * as dns from 'node:dns/promises';
13
13
  import * as net from 'node:net';
@@ -1487,6 +1487,7 @@ import (
1487
1487
  "go/ast"
1488
1488
  "go/parser"
1489
1489
  "go/token"
1490
+ "io"
1490
1491
  "os"
1491
1492
  "strings"
1492
1493
  )
@@ -1501,17 +1502,13 @@ type Sym struct {
1501
1502
  }
1502
1503
 
1503
1504
  func main() {
1504
- if len(os.Args) < 2 {
1505
- fmt.Print("[]")
1506
- return
1507
- }
1508
- src, err := os.ReadFile(os.Args[1])
1505
+ src, err := io.ReadAll(os.Stdin)
1509
1506
  if err != nil {
1510
1507
  fmt.Print("[]")
1511
1508
  return
1512
1509
  }
1513
1510
  fset := token.NewFileSet()
1514
- node, err := parser.ParseFile(fset, os.Args[1], src, 0)
1511
+ node, err := parser.ParseFile(fset, "src.go", src, 0)
1515
1512
  if err != nil {
1516
1513
  fmt.Print("[]")
1517
1514
  return
@@ -1655,7 +1652,7 @@ func formatMethods(fields []*ast.Field) string {
1655
1652
  return formatFields(fields)
1656
1653
  }
1657
1654
 
1658
- func formatTypeParams(tp *ast.TypeParams) string {
1655
+ func formatTypeParams(tp *ast.FieldList) string {
1659
1656
  if tp == nil || len(tp.List) == 0 {
1660
1657
  return ""
1661
1658
  }
@@ -1698,30 +1695,33 @@ func formatType(t ast.Expr) string {
1698
1695
  return "chan " + formatType(v.Value)
1699
1696
  case *ast.BasicLit:
1700
1697
  return v.Value
1698
+ case *ast.IndexExpr:
1699
+ // Generic instantiation with one type arg, e.g. Logger[int].
1700
+ return formatType(v.X) + "[" + formatType(v.Index) + "]"
1701
+ case *ast.IndexListExpr:
1702
+ // Generic instantiation with multiple type args, e.g. Map[K, V].
1703
+ args := make([]string, len(v.Indices))
1704
+ for i, idx := range v.Indices {
1705
+ args[i] = formatType(idx)
1706
+ }
1707
+ return formatType(v.X) + "[" + strings.Join(args, ", ") + "]"
1701
1708
  default:
1702
1709
  return "?"
1703
1710
  }
1704
1711
  }
1705
1712
  `;
1706
- function syncGoParse(filePath, _content, lang) {
1707
- const tmpDir = path.join(process.env.TEMP ?? "/tmp", "ws-go-parse");
1713
+ function syncGoParse(filePath, content, lang) {
1714
+ const tmpDir = path.join(os.tmpdir(), "ws-go-parse");
1708
1715
  try {
1709
1716
  mkdirSync(tmpDir, { recursive: true });
1710
1717
  const scriptPath = path.join(tmpDir, "parse.go");
1711
1718
  writeFileSync(scriptPath, GO_PARSE_SCRIPT, "utf8");
1712
- let stdout;
1713
- try {
1714
- stdout = execSync(`go run "${scriptPath}" "${filePath}"`, {
1715
- timeout: 15e3,
1716
- encoding: "utf8",
1717
- windowsHide: true
1718
- });
1719
- } finally {
1720
- try {
1721
- unlinkSync(scriptPath);
1722
- } catch {
1723
- }
1724
- }
1719
+ const stdout = execSync(`go run "${scriptPath}"`, {
1720
+ input: content,
1721
+ timeout: 15e3,
1722
+ encoding: "utf8",
1723
+ windowsHide: true
1724
+ });
1725
1725
  if (!stdout.trim()) {
1726
1726
  return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
1727
1727
  }
@@ -1958,7 +1958,11 @@ print(json.dumps([s.to_dict() for s in syms]))
1958
1958
  `;
1959
1959
  function syncPyParse(filePath, lang) {
1960
1960
  try {
1961
- const stdout = execSync(`python -c "${PY_PARSE_SCRIPT.replace(/"/g, '\\"')}" "${filePath}"`, {
1961
+ const tmpDir = path.join(os.tmpdir(), "ws-py-parse");
1962
+ mkdirSync(tmpDir, { recursive: true });
1963
+ const scriptPath = path.join(tmpDir, "parse.py");
1964
+ writeFileSync(scriptPath, PY_PARSE_SCRIPT, "utf8");
1965
+ const stdout = execSync(`python "${scriptPath}" "${filePath}"`, {
1962
1966
  timeout: 15e3,
1963
1967
  encoding: "utf8",
1964
1968
  windowsHide: true
@@ -2016,8 +2020,8 @@ function tryNativeParse(file, content) {
2016
2020
  const toolsDir = path.join(process.cwd(), "tools");
2017
2021
  const crateDir = path.join(toolsDir, "syn-parser");
2018
2022
  const tmpFile = path.join(crateDir, "src", "input.rs");
2019
- const { writeFileSync: writeFileSync2 } = __require("node:fs");
2020
- writeFileSync2(tmpFile, content, "utf8");
2023
+ const { writeFileSync: writeFileSync3 } = __require("node:fs");
2024
+ writeFileSync3(tmpFile, content, "utf8");
2021
2025
  const result = spawnSync(
2022
2026
  "cargo",
2023
2027
  ["run", "--manifest-path", path.join(toolsDir, "Cargo.toml")],
@@ -3333,8 +3337,11 @@ var BLOCKED_ARG_PATTERNS = {
3333
3337
  docker: [/^build$/, /^run$/, /^exec$/, /^push$/, /^pull$/],
3334
3338
  // find -exec/-ok/-execdir execute arbitrary commands
3335
3339
  find: [/^-exec$/, /^-exec;$/, /^-ok$/, /^-ok;$/, /^-execdir$/, /^-execdir;$/, /^-exec=/, /^-ok=/, /^-execdir=/],
3336
- // rm -rf / is catastrophic — block absolute paths, home, and dot-dir targets
3337
- rm: [/^\//, /^~/, /^\.{1,2}$/],
3340
+ // rm -rf / is catastrophic — block absolute paths, home, dot-dirs,
3341
+ // and glob patterns that could expand to dangerous targets.
3342
+ // `rm -rf ./src/*` expands to project files; `rm -rf ../../` escapes upward;
3343
+ // `rm -rf /*` targets the filesystem root. All are blocked.
3344
+ rm: [/^\//, /^~\//, /^~$/, /^\.$/, /^\.\.$/, /\*$/, /\/$/, /\/\*$/, /\.\//],
3338
3345
  // npm run/exec/create/pack/publish can execute arbitrary scripts or publish malware
3339
3346
  npm: [/^run$/, /^exec$/, /^create$/, /^init$/, /^pack$/, /^publish$/, /^deploy$/],
3340
3347
  // pnpm run/dlx/exec/create can execute arbitrary scripts
@@ -4549,7 +4556,7 @@ var installTool = {
4549
4556
  ) : [];
4550
4557
  const PKG_NAME_RE = /^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+$/i;
4551
4558
  for (const pkg of pkgList) {
4552
- if (!PKG_NAME_RE.test(pkg) || pkg.startsWith("-")) {
4559
+ if (!PKG_NAME_RE.test(pkg) || pkg.startsWith("-") || pkg.length > 200) {
4553
4560
  yield {
4554
4561
  type: "final",
4555
4562
  output: {
@@ -4674,8 +4681,8 @@ var jsonTool = {
4674
4681
  };
4675
4682
  }
4676
4683
  };
4677
- function query(data, path17) {
4678
- const parts = path17.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
4684
+ function query(data, path18) {
4685
+ const parts = path18.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
4679
4686
  let current = data;
4680
4687
  for (const part of parts) {
4681
4688
  if (current === null || current === void 0) return void 0;
@@ -4929,7 +4936,7 @@ async function dockerLogs(service, lines, filterRe, cwd, signal, since) {
4929
4936
  });
4930
4937
  }
4931
4938
  var MAX_TAIL_LINES = 1e5;
4932
- async function fileLogs(path17, lines, filterRe, stream) {
4939
+ async function fileLogs(path18, lines, filterRe, stream) {
4933
4940
  const { createInterface } = await import('node:readline');
4934
4941
  const { createReadStream } = await import('node:fs');
4935
4942
  const entries = [];
@@ -4938,7 +4945,7 @@ async function fileLogs(path17, lines, filterRe, stream) {
4938
4945
  let writeIdx = 0;
4939
4946
  let totalLines = 0;
4940
4947
  const rl = createInterface({
4941
- input: createReadStream(path17),
4948
+ input: createReadStream(path18),
4942
4949
  crlfDelay: Number.POSITIVE_INFINITY
4943
4950
  });
4944
4951
  for await (const line of rl) {
@@ -4959,7 +4966,7 @@ async function fileLogs(path17, lines, filterRe, stream) {
4959
4966
  if (parsed) entries.push(parsed);
4960
4967
  }
4961
4968
  return {
4962
- source: path17,
4969
+ source: path18,
4963
4970
  entries,
4964
4971
  total: entries.length,
4965
4972
  truncated: totalLines > effLines,