no-mistakes 0.19.0 → 0.20.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.
package/index.d.ts CHANGED
@@ -12,6 +12,7 @@ import type {
12
12
  ProjectOptions,
13
13
  QueueReport,
14
14
  ReactComponentFacts,
15
+ ReactUsagesReport,
15
16
  ReactViolation,
16
17
  ServerRoutesReport,
17
18
  SymbolsOptions,
@@ -55,5 +56,8 @@ export function serverRouteEdges(options?: ProjectOptions): Promise<GraphEdge[]>
55
56
  export function serverRouteRelated(options: ProjectOptions): Promise<GraphEdge[]>;
56
57
  export function reactAnalyze(options?: ProjectOptions): Promise<ReactComponentFacts[]>;
57
58
  export function reactCheck(options?: ProjectOptions): Promise<ReactViolation[]>;
59
+ export function reactUsages(
60
+ options: ProjectOptions & { target: string },
61
+ ): Promise<ReactUsagesReport>;
58
62
  export function lockfileDiff(options: LockfileDiffOptions): Promise<LockfileDiffEntry[]>;
59
63
  export function version(): Promise<string>;
package/index.js CHANGED
@@ -114,6 +114,10 @@ async function reactCheck(options) {
114
114
  return callJson(native.reactCheckJson, options);
115
115
  }
116
116
 
117
+ async function reactUsages(options) {
118
+ return callJson(native.reactUsagesJson, options);
119
+ }
120
+
117
121
  async function lockfileDiff(options) {
118
122
  return callJson(native.lockfileDiffJson, options);
119
123
  }
@@ -139,6 +143,7 @@ module.exports = {
139
143
  queueRelated,
140
144
  reactAnalyze,
141
145
  reactCheck,
146
+ reactUsages,
142
147
  related,
143
148
  serverRouteEdges,
144
149
  serverRouteList,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "no-mistakes",
3
- "version": "0.19.0",
3
+ "version": "0.20.1",
4
4
  "description": "Static codebase analysis tools for TS/JS dependencies, dependents, and symbols",
5
5
  "license": "MIT",
6
6
  "repository": {
package/report-types.d.ts CHANGED
@@ -138,3 +138,22 @@ export interface ReactViolation {
138
138
  rule: string;
139
139
  detail?: string;
140
140
  }
141
+
142
+ export interface ReactCallsite {
143
+ file: string;
144
+ line: number;
145
+ component: string;
146
+ props: string[];
147
+ hasSpread: boolean;
148
+ }
149
+
150
+ export interface ReactUsagesReport {
151
+ target: { file: string; symbol?: string };
152
+ callsites: ReactCallsite[];
153
+ /** Story files importing the target. Omitted when `props`/`tests`-only `include`. */
154
+ stories?: string[];
155
+ /** Test files importing the target. */
156
+ tests?: string[];
157
+ /** Exported prop type/interface names declared in the target file. */
158
+ propTypes?: string[];
159
+ }
@@ -60,8 +60,26 @@ function request(
60
60
  reject(new Error(`Redirect missing Location header while downloading ${url}`));
61
61
  return;
62
62
  }
63
+
64
+ let redirectedUrl;
65
+ try {
66
+ redirectedUrl = new URL(response.headers.location, url);
67
+ } catch {
68
+ reject(
69
+ new Error(
70
+ `Invalid redirect Location header while downloading ${url}: ${response.headers.location}`,
71
+ ),
72
+ );
73
+ return;
74
+ }
75
+
76
+ if (redirectedUrl.protocol !== "http:" && redirectedUrl.protocol !== "https:") {
77
+ reject(new Error(`Unsupported redirect protocol: ${redirectedUrl.protocol}`));
78
+ return;
79
+ }
80
+
63
81
  request(
64
- new URL(response.headers.location, url).toString(),
82
+ redirectedUrl.toString(),
65
83
  handleResponse,
66
84
  redirects + 1,
67
85
  clients,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- const { createHash } = require("node:crypto");
3
+ const { createHash, randomBytes } = require("node:crypto");
4
4
  const { closeSync, createReadStream, existsSync, openSync, readSync } = require("node:fs");
5
5
  const { chmod, mkdir, rename, rm } = require("node:fs/promises");
6
6
  const { join } = require("node:path");
@@ -60,7 +60,7 @@ async function install(binName, repository, options = {}) {
60
60
  const validateReleaseDownloadUrl = (url) =>
61
61
  validateReleaseBaseUrl(url, repository, { enforcePath: false });
62
62
 
63
- const temp = `${destination}.tmp-${process.pid}`;
63
+ const temp = `${destination}.tmp-${randomBytes(8).toString("hex")}`;
64
64
 
65
65
  await mkdir(vendorDir, { recursive: true });
66
66
 
@@ -114,6 +114,10 @@ export interface ProjectOptions {
114
114
  depth?: number;
115
115
  assertNoFetch?: boolean;
116
116
  direction?: "deps" | "dependents" | "both";
117
+ /** `reactUsages` target component (`path` or `path#Symbol`). */
118
+ target?: string;
119
+ /** `reactUsages` `--include` spec: comma-separated `stories,tests,props`. */
120
+ include?: string;
117
121
  }
118
122
 
119
123
  type BatchedProjectOptions = Omit<ProjectOptions, "root" | "tsconfig" | "config">;