typeslayer 0.1.3 → 0.1.5

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 CHANGED
@@ -30,6 +30,8 @@ in the root package you want to inspect (i.e. colocated to your package.json). T
30
30
  - why isn't this just a CLI tool?
31
31
  - A goal of the project is show intuitive/beautiful interactive visualizations like treemaps and force graphs, inherently not something a terminal can provide.
32
32
  - I don't like CLI tools. I view them as a last resort, at this point in engineering history. If you're someone that stays up late into the night staring at your dotfiles from neovim... I'm happy for you. Be happy for me too?
33
+ - will this work with ts-go?
34
+ - that's the hope but it ain't ready yet on the ts-go side
33
35
 
34
36
  ## Data / Security
35
37
 
package/bin/typeslayer.js CHANGED
@@ -45,7 +45,9 @@ try {
45
45
  const binaryInfo = getBinaryInfo();
46
46
 
47
47
  if (!existsSync(binaryInfo.path)) {
48
- console.error(`\n⚠️ Binary not found for ${binaryInfo.platform}. Attempting download...`);
48
+ console.error(
49
+ `\n⚠️ Binary not found for ${binaryInfo.platform}. Attempting download...`,
50
+ );
49
51
  const postinstallPath = join(__dirname, "..", "scripts", "postinstall.js");
50
52
  const res = spawnSync(process.execPath, [postinstallPath], {
51
53
  stdio: "inherit",
package/package.json CHANGED
@@ -1,99 +1,49 @@
1
1
  {
2
- "name": "typeslayer",
3
- "version": "0.1.3",
4
- "description": "Slay your TypeScript types",
5
- "private": false,
6
- "type": "module",
7
- "keywords": [
8
- "typescript",
9
- "ts",
10
- "tauri",
11
- "desktop",
12
- "benchmarking",
13
- "performance"
14
- ],
15
- "author": "Dimitri Mitropoulos",
16
- "license": "MIT",
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/dimitropoulos/typeslayer.git"
20
- },
21
- "bugs": {
22
- "url": "https://github.com/dimitropoulos/typeslayer/issues"
23
- },
24
- "homepage": "https://github.com/dimitropoulos/typeslayer#readme",
25
- "bin": {
26
- "typeslayer": "bin/typeslayer.js"
27
- },
28
- "files": [
29
- "bin",
30
- "scripts"
31
- ],
32
- "os": [
33
- "linux",
34
- "darwin",
35
- "win32"
36
- ],
37
- "cpu": [
38
- "x64",
39
- "arm64"
40
- ],
41
- "engines": {
42
- "node": ">=24.0.0",
43
- "pnpm": ">=10.0.0"
44
- },
45
- "packageManager": "pnpm@10.6.5",
46
- "scripts": {
47
- "postinstall": "node scripts/postinstall.js",
48
- "dev": "vite",
49
- "build": "tsc && vite build",
50
- "preview": "vite preview",
51
- "tauri": "tauri"
52
- },
53
- "dependencies": {
54
- "@tauri-apps/api": "2.9.0",
55
- "@tauri-apps/plugin-clipboard-manager": "~2",
56
- "@tauri-apps/plugin-dialog": "2.4.2",
57
- "@tauri-apps/plugin-opener": "2.5.2",
58
- "@tauri-apps/plugin-upload": "^2.3.2",
59
- "react": "19.2.0",
60
- "react-dom": "19.2.0"
61
- },
62
- "devDependencies": {
63
- "@emotion/react": "11.14.0",
64
- "@emotion/styled": "11.14.1",
65
- "@fastify/cors": "11.1.0",
66
- "@fastify/static": "8.3.0",
67
- "@fontsource/roboto": "5.2.9",
68
- "@mui/icons-material": "7.3.5",
69
- "@mui/material": "7.3.5",
70
- "@mui/x-tree-view": "8.19.0",
71
- "@tanstack/react-query": "5.90.10",
72
- "@tanstack/react-router": "1.139.3",
73
- "@tauri-apps/cli": "2.9.4",
74
- "@types/mime-types": "3.0.1",
75
- "@types/node": "24.10.1",
76
- "@types/ramda": "0.31.1",
77
- "@types/react": "19.2.6",
78
- "@types/react-dom": "19.2.3",
79
- "@typeslayer/analyze-trace": "workspace:*",
80
- "@typeslayer/validate": "workspace:*",
81
- "@vitejs/plugin-react": "5.1.1",
82
- "concurrently": "9.2.1",
83
- "fastify": "5.6.2",
84
- "mime-types": "3.0.2",
85
- "ramda": "0.32.0",
86
- "ramda-adjunct": "5.1.0",
87
- "react": "19.2.0",
88
- "react-dom": "19.2.0",
89
- "tsx": "4.20.6",
90
- "typescript": "5.9.3",
91
- "vite": "7.2.4",
92
- "zod": "4.1.12"
93
- },
94
- "pnpm": {
95
- "onlyBuiltDependencies": [
96
- "esbuild"
97
- ]
98
- }
2
+ "name": "typeslayer",
3
+ "version": "0.1.5",
4
+ "description": "Slay your TypeScript types",
5
+ "private": false,
6
+ "type": "module",
7
+ "keywords": [
8
+ "typescript",
9
+ "ts",
10
+ "tauri",
11
+ "desktop",
12
+ "benchmarking",
13
+ "performance"
14
+ ],
15
+ "author": "Dimitri Mitropoulos",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/dimitropoulos/typeslayer.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/dimitropoulos/typeslayer/issues"
23
+ },
24
+ "homepage": "https://github.com/dimitropoulos/typeslayer#readme",
25
+ "bin": {
26
+ "typeslayer": "bin/typeslayer.js"
27
+ },
28
+ "files": [
29
+ "bin",
30
+ "scripts"
31
+ ],
32
+ "os": [
33
+ "linux",
34
+ "darwin",
35
+ "win32"
36
+ ],
37
+ "cpu": [
38
+ "x64",
39
+ "arm64"
40
+ ],
41
+ "engines": {
42
+ "node": ">=24.0.0",
43
+ "pnpm": ">=10.0.0"
44
+ },
45
+ "packageManager": "pnpm@10.6.5",
46
+ "scripts": {
47
+ "postinstall": "node scripts/postinstall.js"
48
+ }
99
49
  }
@@ -1,94 +1,69 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { chmodSync, createWriteStream, existsSync, mkdirSync } from "node:fs";
4
- import { get } from "node:https";
3
+ import { execSync } from "node:child_process";
4
+ import { chmodSync, existsSync, mkdirSync } from "node:fs";
5
+ import { createRequire } from "node:module";
5
6
  import { arch, platform } from "node:os";
6
7
  import { dirname, join } from "node:path";
7
8
  import { fileURLToPath } from "node:url";
8
9
 
9
10
  const __filename = fileURLToPath(import.meta.url);
10
11
  const __dirname = dirname(__filename);
12
+ const require = createRequire(import.meta.url);
11
13
 
12
14
  const PACKAGE_VERSION = process.env.npm_package_version;
13
15
 
16
+ // Allow CI or callers to skip binary download (release assets may not exist yet in same run)
17
+ if (process.env.TYPESLAYER_SKIP_POSTINSTALL) {
18
+ console.log(
19
+ "⏭️ Skipping typeslayer binary download (TYPESLAYER_SKIP_POSTINSTALL set).",
20
+ );
21
+ process.exit(0);
22
+ }
23
+
24
+ // Also skip if we're in a pnpm workspace (local development)
25
+ if (
26
+ process.env.PNPM_HOME ||
27
+ process.env.npm_config_user_agent?.includes("pnpm")
28
+ ) {
29
+ console.log("⏭️ Skipping typeslayer binary download (in pnpm workspace).");
30
+ process.exit(0);
31
+ }
32
+
14
33
  const getBinaryInfo = () => {
15
34
  const plat = platform();
16
35
  const architecture = arch();
17
36
 
18
- let platformDir, binaryName, releaseAssetName;
37
+ let platformDir, binaryName, npmPackage;
19
38
 
20
39
  if (plat === "linux" && architecture === "x64") {
21
40
  platformDir = "linux-x64";
22
41
  binaryName = "typeslayer";
23
- releaseAssetName = "typeslayer-linux-x64";
42
+ npmPackage = "@typeslayer/linux-x64";
24
43
  } else if (plat === "darwin" && architecture === "x64") {
25
44
  platformDir = "darwin-x64";
26
45
  binaryName = "typeslayer";
27
- releaseAssetName = "typeslayer-darwin-x64";
46
+ npmPackage = "@typeslayer/darwin-x64";
28
47
  } else if (plat === "darwin" && architecture === "arm64") {
29
48
  platformDir = "darwin-arm64";
30
49
  binaryName = "typeslayer";
31
- releaseAssetName = "typeslayer-darwin-arm64";
50
+ npmPackage = "@typeslayer/darwin-arm64";
32
51
  } else if (plat === "win32" && architecture === "x64") {
33
52
  platformDir = "win32-x64";
34
53
  binaryName = "typeslayer.exe";
35
- releaseAssetName = "typeslayer-win32-x64.exe";
54
+ npmPackage = "@typeslayer/win32-x64";
36
55
  } else {
37
56
  console.warn(`⚠️ Platform ${plat}-${architecture} is not supported`);
38
57
  process.exit(0); // Don't fail the install, just skip
39
58
  }
40
59
 
41
- return { platformDir, binaryName, releaseAssetName };
42
- };
43
-
44
- const downloadBinary = (url, destPath) => {
45
- return new Promise((resolve, reject) => {
46
- console.log(`📦 Downloading binary from ${url}...`);
47
-
48
- get(url, (response) => {
49
- if (response.statusCode === 302 || response.statusCode === 301) {
50
- // Follow redirect
51
- return downloadBinary(response.headers.location, destPath).then(
52
- resolve,
53
- reject,
54
- );
55
- }
56
-
57
- if (response.statusCode !== 200) {
58
- reject(
59
- new Error(
60
- `Failed to download: ${response.statusCode} ${response.statusMessage}`,
61
- ),
62
- );
63
- return;
64
- }
65
-
66
- const fileStream = createWriteStream(destPath);
67
- response.pipe(fileStream);
68
-
69
- fileStream.on("finish", () => {
70
- fileStream.close();
71
- // Make executable on Unix-like systems
72
- if (process.platform !== "win32") {
73
- chmodSync(destPath, 0o755);
74
- }
75
- console.log("✅ Binary downloaded successfully");
76
- resolve();
77
- });
78
-
79
- fileStream.on("error", (err) => {
80
- reject(err);
81
- });
82
- }).on("error", (err) => {
83
- reject(err);
84
- });
85
- });
60
+ return { platformDir, binaryName, npmPackage };
86
61
  };
87
62
 
88
63
  (async () => {
89
64
  try {
90
- const { platformDir, binaryName, releaseAssetName } = getBinaryInfo();
91
- const binariesDir = join(__dirname, "..", "binaries", platformDir);
65
+ const { platformDir, binaryName, npmPackage } = getBinaryInfo();
66
+ const binariesDir = join(__dirname, "..", "..", "builds", platformDir);
92
67
  const binaryPath = join(binariesDir, binaryName);
93
68
 
94
69
  // Skip if binary already exists
@@ -100,10 +75,63 @@ const downloadBinary = (url, destPath) => {
100
75
  // Create directory if it doesn't exist
101
76
  mkdirSync(binariesDir, { recursive: true });
102
77
 
103
- // Download from GitHub release
104
- const releaseUrl = `https://github.com/dimitropoulos/typeslayer/releases/download/typeslayer-v${PACKAGE_VERSION}/${releaseAssetName}`;
78
+ // First, try to use the optionalDependency (esbuild pattern)
79
+ // This is the primary mechanism - npm installs the right platform package automatically
80
+ let binaryFound = false;
81
+ try {
82
+ const optionalPkgPath = require.resolve(`${npmPackage}/package.json`);
83
+ const optionalBinaryPath = join(dirname(optionalPkgPath), binaryName);
84
+ if (existsSync(optionalBinaryPath)) {
85
+ console.log(`📦 Using ${npmPackage} from optionalDependencies...`);
86
+ const fs = await import("node:fs/promises");
87
+ await fs.copyFile(optionalBinaryPath, binaryPath);
88
+ if (process.platform !== "win32") {
89
+ chmodSync(binaryPath, 0o755);
90
+ }
91
+ console.log("✅ Binary copied successfully");
92
+ binaryFound = true;
93
+ }
94
+ } catch {
95
+ // optionalDependency not available - fall back to downloading
96
+ console.warn(
97
+ `⚠️ ${npmPackage} not found in optionalDependencies (may have been installed with --no-optional flag)`,
98
+ );
99
+ }
100
+
101
+ if (!binaryFound) {
102
+ // Fallback: Install the platform-specific binary package from npm
103
+ console.log(`📦 Downloading ${npmPackage}@${PACKAGE_VERSION}...`);
104
+ execSync(`npm install --no-save "${npmPackage}@${PACKAGE_VERSION}"`, {
105
+ stdio: "inherit",
106
+ });
107
+
108
+ // Copy the binary from node_modules to our builds directory
109
+ const nodeModulesBinaryPath = join(
110
+ __dirname,
111
+ "..",
112
+ "..",
113
+ "..",
114
+ "node_modules",
115
+ npmPackage.replace("@", "").replace("/", "-"),
116
+ binaryName,
117
+ );
118
+
119
+ if (!existsSync(nodeModulesBinaryPath)) {
120
+ throw new Error(
121
+ `Binary not found at ${nodeModulesBinaryPath} after npm install`,
122
+ );
123
+ }
124
+
125
+ // Copy and make executable
126
+ const fs = await import("node:fs/promises");
127
+ await fs.copyFile(nodeModulesBinaryPath, binaryPath);
105
128
 
106
- await downloadBinary(releaseUrl, binaryPath);
129
+ if (process.platform !== "win32") {
130
+ chmodSync(binaryPath, 0o755);
131
+ }
132
+
133
+ console.log("✅ Binary installed successfully");
134
+ }
107
135
  } catch (error) {
108
136
  console.error("❌ Failed to download binary:", error.message);
109
137
  console.error(