supascan 0.0.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/README.md +165 -0
- package/commands/analyze.command.ts +187 -0
- package/commands/dump.command.ts +98 -0
- package/commands/rpc.command.ts +205 -0
- package/context.ts +84 -0
- package/index.ts +94 -0
- package/package.json +43 -0
- package/services/analyzer.service.test.ts +193 -0
- package/services/analyzer.service.ts +190 -0
- package/services/extractor.service.test.ts +194 -0
- package/services/extractor.service.ts +230 -0
- package/services/html-renderer.service.tsx +1246 -0
- package/services/supabase.service.test.ts +352 -0
- package/services/supabase.service.ts +316 -0
- package/utils.ts +127 -0
- package/version.ts +3 -0
package/utils.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import { createConsola } from "consola";
|
|
3
|
+
import { writeFileSync } from "fs";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import type { CLIContext } from "./context";
|
|
7
|
+
|
|
8
|
+
export type Ok<T> = {
|
|
9
|
+
value: T;
|
|
10
|
+
success: true;
|
|
11
|
+
error?: undefined;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type Err<T> = {
|
|
15
|
+
value?: undefined;
|
|
16
|
+
error: Error;
|
|
17
|
+
success: false;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type Result<T> = Ok<T> | Err<T>;
|
|
21
|
+
|
|
22
|
+
export const ok = <T>(value: T): Result<T> => ({ value, success: true });
|
|
23
|
+
|
|
24
|
+
export const err = <T>(error: Error): Result<T> => ({ error, success: false });
|
|
25
|
+
|
|
26
|
+
const baseLogger = createConsola({
|
|
27
|
+
level: 4,
|
|
28
|
+
formatOptions: { compact: true },
|
|
29
|
+
stdout: process.stderr,
|
|
30
|
+
stderr: process.stderr,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export const log = {
|
|
34
|
+
debug: (ctx: CLIContext, message: any, ...args: any[]) => {
|
|
35
|
+
if (ctx.debug) {
|
|
36
|
+
baseLogger.debug(message, ...args);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
info: (message: any, ...args: any[]) => baseLogger.info(message, ...args),
|
|
40
|
+
success: (message: any, ...args: any[]) =>
|
|
41
|
+
baseLogger.success(message, ...args),
|
|
42
|
+
warn: (message: any, ...args: any[]) => baseLogger.warn(message, ...args),
|
|
43
|
+
error: (message: any, ...args: any[]) => baseLogger.error(message, ...args),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const onlyOnce = <T>(fn: () => T) => {
|
|
47
|
+
let result = false;
|
|
48
|
+
return () => {
|
|
49
|
+
if (!result) {
|
|
50
|
+
try {
|
|
51
|
+
return fn();
|
|
52
|
+
} catch (error) {
|
|
53
|
+
result = true;
|
|
54
|
+
throw error;
|
|
55
|
+
} finally {
|
|
56
|
+
result = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const parseRPCArgs = (argsString: string): Record<string, any> => {
|
|
63
|
+
try {
|
|
64
|
+
const processedString = argsString.replace(
|
|
65
|
+
/\$([A-Z_][A-Z0-9_]*)/g,
|
|
66
|
+
(match, varName) => {
|
|
67
|
+
const envValue = process.env[varName];
|
|
68
|
+
if (envValue === undefined) {
|
|
69
|
+
throw new Error(`Environment variable ${varName} not found`);
|
|
70
|
+
}
|
|
71
|
+
return JSON.stringify(envValue);
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return JSON.parse(processedString);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Failed to parse RPC arguments: ${error instanceof Error ? error.message : String(error)}`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
let suppressExperimentalWarnings = false;
|
|
84
|
+
|
|
85
|
+
export const setExperimentalWarnings = (suppress: boolean) => {
|
|
86
|
+
suppressExperimentalWarnings = suppress;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const experimentalWarning = onlyOnce(() => {
|
|
90
|
+
if (!suppressExperimentalWarnings) {
|
|
91
|
+
log.warn(
|
|
92
|
+
"This feature is experimental and may have bugs. You can suppress this with --suppress-experimental-warnings.",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export const generateTempFilePath = (): string => {
|
|
98
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
99
|
+
return join(tmpdir(), `supascan-${timestamp}.html`);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const writeHtmlFile = (filePath: string, content: string): void => {
|
|
103
|
+
writeFileSync(filePath, content, "utf8");
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const openInBrowser = (filePath: string): void => {
|
|
107
|
+
const platform = process.platform;
|
|
108
|
+
let command: string;
|
|
109
|
+
let args: string[];
|
|
110
|
+
|
|
111
|
+
switch (platform) {
|
|
112
|
+
case "darwin":
|
|
113
|
+
command = "open";
|
|
114
|
+
args = [filePath];
|
|
115
|
+
break;
|
|
116
|
+
case "win32":
|
|
117
|
+
command = "start";
|
|
118
|
+
args = [filePath];
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
command = "xdg-open";
|
|
122
|
+
args = [filePath];
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
spawn(command, args, { detached: true, stdio: "ignore" });
|
|
127
|
+
};
|
package/version.ts
ADDED