@wrongstack/plugins 0.307.1 → 0.308.1

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.
@@ -1,17 +1,32 @@
1
1
  // src/file-watcher/index.ts
2
2
  import { watch as fsWatch } from "node:fs";
3
- import { isAbsolute, join, relative, resolve } from "node:path";
4
- var API_VERSION = "^0.1.10";
3
+ import { join } from "node:path";
4
+
5
+ // src/runtime/index.ts
6
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
+
8
+ // src/runtime/local-bin.ts
9
+ import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
10
+
11
+ // src/runtime/index.ts
12
+ var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
13
+ function hasLeadingDash(arg) {
14
+ return arg.length > 0 && arg.startsWith("-");
15
+ }
16
+ function withinProjectPath(projectRoot, candidate) {
17
+ if (candidate.length === 0 || candidate.length > 4096) return false;
18
+ if (hasLeadingDash(candidate)) return false;
19
+ const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
20
+ const rel = relative(projectRoot, resolved);
21
+ return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
22
+ }
5
23
  function withinProject(p) {
6
- if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
7
- const root = process.cwd();
8
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
9
- const rel = relative(root, resolved);
10
- if (rel === "" || rel === ".") return true;
11
- if (rel.startsWith("..")) return false;
12
- if (isAbsolute(rel)) return false;
13
- return true;
24
+ const cwd = process.cwd();
25
+ return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
14
26
  }
27
+
28
+ // src/file-watcher/index.ts
29
+ var API_VERSION = "^0.1.10";
15
30
  var watch_idCounter = 0;
16
31
  function nextId() {
17
32
  return `watch_${++watch_idCounter}_${Date.now().toString(36)}`;
@@ -328,6 +328,7 @@ async function formatFile(filePath, timeoutMs) {
328
328
  }
329
329
  const formatter = resolveFormatter();
330
330
  if (!formatter) return null;
331
+ const started = Date.now();
331
332
  let bytesBefore;
332
333
  try {
333
334
  bytesBefore = (await stat(filePath)).size;
@@ -372,14 +373,15 @@ async function formatFile(filePath, timeoutMs) {
372
373
  } catch {
373
374
  return null;
374
375
  }
376
+ const durationMs = Date.now() - started;
375
377
  if (bytesAfter !== bytesBefore) {
376
- return { changed: true, bytesBefore, bytesAfter };
378
+ return { changed: true, bytesBefore, bytesAfter, durationMs };
377
379
  }
378
380
  const hashAfter = await sha256File(filePath);
379
381
  if (hashBefore === null || hashAfter === null) {
380
- return { changed: false, bytesBefore, bytesAfter };
382
+ return { changed: false, bytesBefore, bytesAfter, durationMs };
381
383
  }
382
- return { changed: hashBefore !== hashAfter, bytesBefore, bytesAfter };
384
+ return { changed: hashBefore !== hashAfter, bytesBefore, bytesAfter, durationMs };
383
385
  }
384
386
  var plugin = {
385
387
  name: "format-on-save",
@@ -468,6 +470,7 @@ var plugin = {
468
470
  changed: result.changed,
469
471
  bytesBefore: result.bytesBefore,
470
472
  bytesAfter: result.bytesAfter,
473
+ durationMs: result.durationMs,
471
474
  when: (/* @__PURE__ */ new Date()).toISOString()
472
475
  };
473
476
  if (result.changed) {
@@ -522,7 +525,10 @@ var plugin = {
522
525
  formatted: state.formattedCount,
523
526
  clean: state.cleanCount,
524
527
  errors: state.errorCount,
525
- coveredSkips: state.coveredSkipCount
528
+ coveredSkips: state.coveredSkipCount,
529
+ bytesBefore: state.lastResult?.bytesBefore ?? 0,
530
+ bytesAfter: state.lastResult?.bytesAfter ?? 0,
531
+ durationMs: state.lastResult?.durationMs ?? 0
526
532
  },
527
533
  lastResult: state.lastResult
528
534
  };
@@ -45,6 +45,10 @@
45
45
  * @public
46
46
  */
47
47
  import type { Plugin } from '@wrongstack/core/types';
48
+ export declare function resolveAllowedCommand(command: string): {
49
+ cmd: string;
50
+ args: string[];
51
+ } | null;
48
52
  declare const plugin: Plugin;
49
53
  export default plugin;
50
54
  //# sourceMappingURL=index.d.ts.map
@@ -37,6 +37,9 @@ function cachePut(key, value) {
37
37
  binCache.set(key, { value, cachedAt: Date.now() });
38
38
  return value;
39
39
  }
40
+ function clearLocalBinCache() {
41
+ binCache.clear();
42
+ }
40
43
  function resolveNodeBin(packageName, binName, cwd, extraArgs = []) {
41
44
  const key = `${packageName}|${binName}|${cwd}`;
42
45
  const cached = binCache.get(key);
@@ -137,6 +140,20 @@ function resolveAllowedCommand(command) {
137
140
  const tokens = command.split(/\s+/).filter(Boolean);
138
141
  if (tokens.length === 0) return null;
139
142
  const head = tokens[0];
143
+ if (PACKAGE_RUNNERS.has(head)) {
144
+ let i = 1;
145
+ while (i < tokens.length && (tokens[i] === "exec" || tokens[i] === "dlx" || tokens[i] === "run")) {
146
+ i++;
147
+ }
148
+ const toolToken = tokens[i];
149
+ if (!toolToken || !(toolToken in LOCAL_BIN_PACKAGES)) return null;
150
+ }
151
+ if (head === "node") {
152
+ const target = tokens[1];
153
+ if (!target) return null;
154
+ const base = basename2(target);
155
+ if (!(base in LOCAL_BIN_PACKAGES) && !ALLOWED_FIRST_TOKENS.has(base)) return null;
156
+ }
140
157
  const local = ALLOWED_FIRST_TOKENS.has(head) ? resolveLocalToolCommand(tokens) : null;
141
158
  if (local) return local;
142
159
  if (ALLOWED_FIRST_TOKENS.has(head)) {
@@ -374,6 +391,12 @@ var plugin = {
374
391
  bytesAfter: result.bytesAfter,
375
392
  when: (/* @__PURE__ */ new Date()).toISOString()
376
393
  };
394
+ if (/\boxlint\b/.test(result.command)) {
395
+ return {
396
+ additionalContext: `
397
+ \u{1F4E6} import-organizer: oxlint has no import-organize support \u2014 ran '${result.command}' as a no-op for import sorting on '${filePath}'.`
398
+ };
399
+ }
377
400
  if (result.changed) {
378
401
  state.organizedCount += 1;
379
402
  const delta = result.bytesAfter - result.bytesBefore;
@@ -430,6 +453,7 @@ ${result.stderr.trim()}`
430
453
  });
431
454
  },
432
455
  teardown(api) {
456
+ clearLocalBinCache();
433
457
  if (state.hookUnregister) {
434
458
  try {
435
459
  state.hookUnregister();
@@ -470,5 +494,6 @@ ${result.stderr.trim()}`
470
494
  };
471
495
  var import_organizer_default = plugin;
472
496
  export {
473
- import_organizer_default as default
497
+ import_organizer_default as default,
498
+ resolveAllowedCommand
474
499
  };