stackscan 0.1.23 → 0.1.29

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.
Files changed (61) hide show
  1. package/README.md +16 -8
  2. package/dist/add.mjs +3 -2
  3. package/dist/chunk-24PM76MV.mjs +235 -0
  4. package/dist/chunk-2ZANNQYS.mjs +162 -0
  5. package/dist/chunk-5AYPCRZA.mjs +21 -0
  6. package/dist/chunk-CFGUYUPP.mjs +42 -0
  7. package/dist/chunk-DF3YGYKJ.mjs +2241 -0
  8. package/dist/chunk-E75XPZ2U.mjs +2237 -0
  9. package/dist/chunk-GFZMRHRT.mjs +181 -0
  10. package/dist/chunk-HKCVFKM4.mjs +19 -0
  11. package/dist/chunk-HT4RZGLE.mjs +267 -0
  12. package/dist/chunk-IFB4PCXR.mjs +28 -0
  13. package/dist/chunk-MFJXW5RR.mjs +6 -0
  14. package/dist/chunk-SECL5E42.mjs +23 -0
  15. package/dist/chunk-STCTH5AY.mjs +15619 -0
  16. package/dist/chunk-XNTLNSF6.mjs +158 -0
  17. package/dist/chunk-ZYFKPOWH.mjs +54 -0
  18. package/dist/cli.js +48 -15
  19. package/dist/cli.mjs +11 -7
  20. package/dist/defaults.mjs +3 -2
  21. package/dist/defaults.test.d.mts +2 -0
  22. package/dist/defaults.test.d.ts +2 -0
  23. package/dist/defaults.test.js +17007 -0
  24. package/dist/defaults.test.mjs +30 -0
  25. package/dist/index.d.mts +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +50 -17
  28. package/dist/index.mjs +18 -12
  29. package/dist/magic-string.es-WH4FGKAB.mjs +1315 -0
  30. package/dist/output.d.mts +3 -3
  31. package/dist/output.d.ts +3 -3
  32. package/dist/output.mjs +4 -3
  33. package/dist/output.test.d.mts +2 -0
  34. package/dist/output.test.d.ts +2 -0
  35. package/dist/output.test.js +20687 -0
  36. package/dist/output.test.mjs +160 -0
  37. package/dist/scan.js +48 -15
  38. package/dist/scan.mjs +7 -6
  39. package/dist/scan.test.d.mts +2 -0
  40. package/dist/scan.test.d.ts +2 -0
  41. package/dist/scan.test.js +23184 -0
  42. package/dist/scan.test.mjs +183 -0
  43. package/dist/simple-icons-hex.mjs +1 -0
  44. package/dist/sync.js +15 -10
  45. package/dist/sync.mjs +7 -6
  46. package/dist/techDefinitions.js +13 -8
  47. package/dist/techDefinitions.mjs +3 -2
  48. package/dist/techMap.js +13 -8
  49. package/dist/techMap.mjs +4 -3
  50. package/dist/techMap.test.d.mts +2 -0
  51. package/dist/techMap.test.d.ts +2 -0
  52. package/dist/techMap.test.js +19240 -0
  53. package/dist/techMap.test.mjs +38 -0
  54. package/dist/types.d.mts +2 -2
  55. package/dist/types.d.ts +2 -2
  56. package/dist/types.mjs +3 -2
  57. package/package.json +9 -4
  58. package/public/assets/logos/defaults/package.svg +18 -18
  59. package/public/assets/logos/defaults/terminal.svg +16 -16
  60. package/public/assets/logos/defaults/wrench.svg +15 -15
  61. package/public/assets/logos/testing/vitest.svg +1 -1
@@ -0,0 +1,158 @@
1
+ import {
2
+ techMap
3
+ } from "./chunk-HKCVFKM4.mjs";
4
+ import {
5
+ copyAssets,
6
+ generateMarkdown
7
+ } from "./chunk-UJM3S22V.mjs";
8
+ import {
9
+ simple_icons_hex_default
10
+ } from "./chunk-EH2SEQZP.mjs";
11
+
12
+ // src/sync.ts
13
+ import fs from "fs";
14
+ import path from "path";
15
+ var BASE_DIR = path.join(process.cwd(), "public", "stackscan");
16
+ var SKIPPED_TECHS = [
17
+ "react-dom"
18
+ ];
19
+ async function sync(options = {}) {
20
+ console.log("\u{1F680} Starting Sync...");
21
+ if (options.color) {
22
+ console.log(`\u{1F3A8} Color mode: ${options.color}`);
23
+ }
24
+ if (!fs.existsSync(BASE_DIR)) {
25
+ console.log(`Creating stackscan directory at: ${BASE_DIR}`);
26
+ fs.mkdirSync(BASE_DIR, { recursive: true });
27
+ console.log('Please place your project folders inside "public/stackscan/" and run this command again.');
28
+ process.exit(0);
29
+ }
30
+ const entries = fs.readdirSync(BASE_DIR, { withFileTypes: true });
31
+ const projectDirs = entries.filter((dirent) => dirent.isDirectory() && dirent.name !== "input" && dirent.name !== "output");
32
+ if (projectDirs.length === 0) {
33
+ console.log('\u26A0\uFE0F No project directories found in "public/stackscan/".');
34
+ return;
35
+ }
36
+ console.log(`Found ${projectDirs.length} projects to process.
37
+ `);
38
+ const allProjects = [];
39
+ const allTechs = [];
40
+ for (const dir of projectDirs) {
41
+ const projectPath = path.join(BASE_DIR, dir.name);
42
+ const packageJsonPath = path.join(projectPath, "package.json");
43
+ if (fs.existsSync(packageJsonPath)) {
44
+ try {
45
+ const content = fs.readFileSync(packageJsonPath, "utf-8");
46
+ const pkg = JSON.parse(content);
47
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
48
+ const detectedTechs = [];
49
+ Object.keys(allDeps).forEach((dep) => {
50
+ if (SKIPPED_TECHS.includes(dep)) return;
51
+ if (techMap[dep]) {
52
+ const tech = techMap[dep];
53
+ let color = null;
54
+ if (options.color === "white") color = "#FFFFFF";
55
+ else if (options.color === "black") color = "#000000";
56
+ else if (options.color && options.color.startsWith("#")) color = options.color;
57
+ else {
58
+ const depSlug = dep.toLowerCase();
59
+ const nameSlug = tech.name.toLowerCase();
60
+ const nameSlugNoSpaces = tech.name.toLowerCase().replace(/\s+/g, "");
61
+ const hex = simple_icons_hex_default[depSlug] || simple_icons_hex_default[nameSlug] || simple_icons_hex_default[nameSlugNoSpaces];
62
+ if (hex) color = `#${hex}`;
63
+ }
64
+ detectedTechs.push({
65
+ name: tech.name,
66
+ slug: dep,
67
+ logo: tech.logo,
68
+ // Raw path for resolution
69
+ color
70
+ });
71
+ }
72
+ });
73
+ let uniqueTechs = Array.from(new Set(detectedTechs.map((t) => t.slug))).map((slug) => detectedTechs.find((t) => t.slug === slug));
74
+ const seenLogos = /* @__PURE__ */ new Set();
75
+ uniqueTechs = uniqueTechs.filter((t) => {
76
+ if (seenLogos.has(t.logo)) {
77
+ return false;
78
+ }
79
+ seenLogos.add(t.logo);
80
+ return true;
81
+ });
82
+ const assetsDir = path.join(process.cwd(), "public", "assets", "logos");
83
+ if (options.copyAssets !== false) {
84
+ await copyAssets(uniqueTechs, assetsDir, { colorMode: options.color });
85
+ }
86
+ const techsWithUrls = uniqueTechs.map((t) => ({
87
+ ...t,
88
+ logo: `https://raw.githubusercontent.com/benjamindotdev/stackscan/main/public/assets/logos/${t.logo}`,
89
+ relativePath: `./public/assets/logos/${t.logo}`
90
+ }));
91
+ allTechs.push(...techsWithUrls);
92
+ fs.writeFileSync(
93
+ path.join(projectPath, "stack.json"),
94
+ JSON.stringify(techsWithUrls, null, 2)
95
+ );
96
+ const mdContent = generateMarkdown(techsWithUrls);
97
+ fs.writeFileSync(path.join(projectPath, "stack.md"), mdContent);
98
+ allProjects.push({
99
+ name: dir.name,
100
+ techs: techsWithUrls
101
+ });
102
+ console.log(`\u2705 ${dir.name.padEnd(20)} -> stack.json (${uniqueTechs.length} techs)`);
103
+ } catch (err) {
104
+ console.error(`\u274C Error processing ${dir.name}:`, err.message);
105
+ }
106
+ } else {
107
+ console.warn(`\u26A0\uFE0F Skipping "${dir.name}": No package.json found.`);
108
+ }
109
+ }
110
+ if (allProjects.length > 0) {
111
+ updateRootReadme(allProjects);
112
+ }
113
+ console.log("\n\u2728 Sync complete.");
114
+ }
115
+ function updateRootReadme(projects) {
116
+ const readmePath = path.join(process.cwd(), "README.md");
117
+ if (!fs.existsSync(readmePath)) {
118
+ console.log("\u26A0\uFE0F No root README.md found to update.");
119
+ return;
120
+ }
121
+ let readmeContent = fs.readFileSync(readmePath, "utf-8");
122
+ const startMarker = "<!-- STACKSCAN_START -->";
123
+ const endMarker = "<!-- STACKSCAN_END -->";
124
+ let newSection = `${startMarker}
125
+ ## My Projects
126
+
127
+ `;
128
+ for (const p of projects) {
129
+ newSection += `### ${p.name}
130
+ `;
131
+ newSection += `<p>
132
+ `;
133
+ for (const t of p.techs) {
134
+ const src = t.relativePath || t.logo;
135
+ newSection += ` <img src="${src}" alt="${t.name}" height="25" style="margin-right: 10px;" />
136
+ `;
137
+ }
138
+ newSection += `</p>
139
+
140
+ `;
141
+ }
142
+ newSection += `${endMarker}`;
143
+ if (readmeContent.includes(startMarker) && readmeContent.includes(endMarker)) {
144
+ const regex = new RegExp(`${startMarker}[\\s\\S]*?${endMarker}`);
145
+ readmeContent = readmeContent.replace(regex, newSection);
146
+ console.log(`\u{1F4DD} Updated root README.md with ${projects.length} projects.`);
147
+ } else {
148
+ readmeContent += `
149
+
150
+ ${newSection}`;
151
+ console.log(`\u{1F4DD} Appended projects to root README.md.`);
152
+ }
153
+ fs.writeFileSync(readmePath, readmeContent);
154
+ }
155
+
156
+ export {
157
+ sync
158
+ };
@@ -0,0 +1,54 @@
1
+ import {
2
+ init_esm_shims
3
+ } from "./chunk-5AYPCRZA.mjs";
4
+
5
+ // src/add.ts
6
+ init_esm_shims();
7
+ import fs from "fs-extra";
8
+ import path from "path";
9
+ import chalk from "chalk";
10
+ var BASE_DIR = path.join(process.cwd(), "public", "stackscan");
11
+ async function add(sourcePath) {
12
+ let absoluteSourcePath = path.resolve(sourcePath);
13
+ if (!fs.existsSync(absoluteSourcePath)) {
14
+ console.error(chalk.red(`\u274C Path not found: ${sourcePath}`));
15
+ process.exit(1);
16
+ }
17
+ if (fs.statSync(absoluteSourcePath).isDirectory()) {
18
+ absoluteSourcePath = path.join(absoluteSourcePath, "package.json");
19
+ if (!fs.existsSync(absoluteSourcePath)) {
20
+ console.error(chalk.red(`\u274C No package.json found in directory: ${sourcePath}`));
21
+ process.exit(1);
22
+ }
23
+ }
24
+ try {
25
+ const content = fs.readFileSync(absoluteSourcePath, "utf-8");
26
+ const pkg = JSON.parse(content);
27
+ if (!pkg.name) {
28
+ console.error(chalk.red(`\u274C No "name" field found in ${sourcePath}`));
29
+ process.exit(1);
30
+ }
31
+ const baseFolderName = pkg.name.replace(/^@/, "").replace(/\//g, "-");
32
+ let folderName = baseFolderName;
33
+ let targetDir = path.join(BASE_DIR, folderName);
34
+ let counter = 1;
35
+ while (fs.existsSync(targetDir)) {
36
+ folderName = `${baseFolderName}-${counter}`;
37
+ targetDir = path.join(BASE_DIR, folderName);
38
+ counter++;
39
+ }
40
+ const targetFile = path.join(targetDir, "package.json");
41
+ if (!fs.existsSync(targetDir)) {
42
+ fs.mkdirSync(targetDir, { recursive: true });
43
+ }
44
+ fs.copyFileSync(absoluteSourcePath, targetFile);
45
+ console.log(chalk.green(`\u2705 Added project "${pkg.name}" to public/stackscan/${folderName}`));
46
+ } catch (error) {
47
+ console.error(chalk.red(`\u274C Error processing ${sourcePath}:`), error);
48
+ process.exit(1);
49
+ }
50
+ }
51
+
52
+ export {
53
+ add
54
+ };
package/dist/cli.js CHANGED
@@ -573,7 +573,7 @@ var techDefinitions = [
573
573
  "id": "rtkquery",
574
574
  "name": "RTK Query",
575
575
  "aliases": [
576
- "@reduxjs/toolkit"
576
+ "@rtk-query/graphql-request-base-query"
577
577
  ],
578
578
  "category": "state",
579
579
  "logo": "state/redux.svg",
@@ -868,7 +868,8 @@ var techDefinitions = [
868
868
  "id": "figma",
869
869
  "name": "Figma",
870
870
  "aliases": [
871
- "figma"
871
+ "figma",
872
+ "figma-api"
872
873
  ],
873
874
  "category": "utility",
874
875
  "logo": "utility/figma.svg",
@@ -878,7 +879,8 @@ var techDefinitions = [
878
879
  "id": "notion",
879
880
  "name": "Notion",
880
881
  "aliases": [
881
- "notion"
882
+ "notion",
883
+ "@notionhq/client"
882
884
  ],
883
885
  "category": "utility",
884
886
  "logo": "utility/notion.svg",
@@ -888,7 +890,8 @@ var techDefinitions = [
888
890
  "id": "slack",
889
891
  "name": "Slack",
890
892
  "aliases": [
891
- "slack"
893
+ "slack",
894
+ "@slack/web-api"
892
895
  ],
893
896
  "category": "utility",
894
897
  "logo": "utility/slack.svg",
@@ -908,7 +911,8 @@ var techDefinitions = [
908
911
  "id": "githubcopilot",
909
912
  "name": "GitHub Copilot",
910
913
  "aliases": [
911
- "github-copilot"
914
+ "github-copilot",
915
+ "github-copilot-extension"
912
916
  ],
913
917
  "category": "ai",
914
918
  "logo": "ai/githubcopilot.svg",
@@ -1540,7 +1544,8 @@ var techDefinitions = [
1540
1544
  "id": "docker",
1541
1545
  "name": "Docker",
1542
1546
  "aliases": [
1543
- "docker"
1547
+ "docker",
1548
+ "dockerode"
1544
1549
  ],
1545
1550
  "category": "container",
1546
1551
  "logo": "container/docker.svg",
@@ -1612,7 +1617,6 @@ var techDefinitions = [
1612
1617
  "aliases": [
1613
1618
  "aws-sdk",
1614
1619
  "@aws-sdk/client-s3",
1615
- "@aws-sdk/client-dynamodb",
1616
1620
  "@aws-sdk/client-lambda"
1617
1621
  ],
1618
1622
  "category": "cloud",
@@ -1653,7 +1657,8 @@ var techDefinitions = [
1653
1657
  "id": "netlify",
1654
1658
  "name": "Netlify",
1655
1659
  "aliases": [
1656
- "netlify"
1660
+ "netlify",
1661
+ "netlify-cli"
1657
1662
  ],
1658
1663
  "category": "hosting",
1659
1664
  "logo": "hosting/netlify.svg",
@@ -5826,6 +5831,36 @@ var BASE_DIR = import_path2.default.join(process.cwd(), "public", "stackscan");
5826
5831
  var SKIPPED_TECHS = [
5827
5832
  "react-dom"
5828
5833
  ];
5834
+ function getPackageJson(projectPath) {
5835
+ const pkgPath = import_path2.default.join(projectPath, "package.json");
5836
+ const pkgPathUnderscore = import_path2.default.join(projectPath, "_package.json");
5837
+ const isInsideStackScanDir = projectPath.includes(import_path2.default.join("public", "stackscan"));
5838
+ if (import_fs.default.existsSync(pkgPath) && isInsideStackScanDir) {
5839
+ try {
5840
+ console.log(`Renaming ${pkgPath} to ${pkgPathUnderscore}`);
5841
+ import_fs.default.renameSync(pkgPath, pkgPathUnderscore);
5842
+ } catch (e) {
5843
+ console.warn(`Failed to rename package.json to _package.json: ${e.message}`);
5844
+ }
5845
+ }
5846
+ if (import_fs.default.existsSync(pkgPathUnderscore)) {
5847
+ try {
5848
+ const content = import_fs.default.readFileSync(pkgPathUnderscore, "utf-8");
5849
+ return JSON.parse(content);
5850
+ } catch (e) {
5851
+ throw new Error(`Failed to read _package.json: ${e.message}`);
5852
+ }
5853
+ }
5854
+ if (import_fs.default.existsSync(pkgPath)) {
5855
+ try {
5856
+ const content = import_fs.default.readFileSync(pkgPath, "utf-8");
5857
+ return JSON.parse(content);
5858
+ } catch (e) {
5859
+ throw new Error(`Failed to read package.json: ${e.message}`);
5860
+ }
5861
+ }
5862
+ return null;
5863
+ }
5829
5864
  var CATEGORY_PRIORITY = [
5830
5865
  "language",
5831
5866
  "framework",
@@ -5862,12 +5897,10 @@ var getCategoryPriority = (cat) => {
5862
5897
  return idx === -1 ? 999 : idx;
5863
5898
  };
5864
5899
  async function analyzeProject(projectPath, options) {
5865
- const packageJsonPath = import_path2.default.join(projectPath, "package.json");
5866
- if (!import_fs.default.existsSync(packageJsonPath)) {
5867
- throw new Error(`No package.json found at ${packageJsonPath}`);
5900
+ const pkg = getPackageJson(projectPath);
5901
+ if (!pkg) {
5902
+ throw new Error(`No package.json or _package.json found at ${projectPath}`);
5868
5903
  }
5869
- const content = import_fs.default.readFileSync(packageJsonPath, "utf-8");
5870
- const pkg = JSON.parse(content);
5871
5904
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
5872
5905
  const detectedTechs = [];
5873
5906
  Object.keys(allDeps).forEach((dep) => {
@@ -6006,8 +6039,8 @@ function updateRootReadme(projects) {
6006
6039
  return;
6007
6040
  }
6008
6041
  let readmeContent = import_fs.default.readFileSync(readmePath, "utf-8");
6009
- const startMarker = "<!-- STACKSYNC_START -->";
6010
- const endMarker = "<!-- STACKSYNC_END -->";
6042
+ const startMarker = "<!-- STACKSCAN_START -->";
6043
+ const endMarker = "<!-- STACKSCAN_END -->";
6011
6044
  let newSection = `${startMarker}
6012
6045
  ## My Projects
6013
6046
 
package/dist/cli.mjs CHANGED
@@ -1,18 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  add
4
- } from "./chunk-ACCTMJVS.mjs";
4
+ } from "./chunk-ZYFKPOWH.mjs";
5
5
  import {
6
6
  scan
7
- } from "./chunk-7UBBON7U.mjs";
8
- import "./chunk-ZI6X666F.mjs";
9
- import "./chunk-QBOEIUY2.mjs";
10
- import "./chunk-UJM3S22V.mjs";
11
- import "./chunk-NGEKE4DQ.mjs";
12
- import "./chunk-EOKQCSHI.mjs";
7
+ } from "./chunk-HT4RZGLE.mjs";
8
+ import "./chunk-SECL5E42.mjs";
9
+ import "./chunk-DF3YGYKJ.mjs";
10
+ import "./chunk-GFZMRHRT.mjs";
13
11
  import "./chunk-EH2SEQZP.mjs";
12
+ import "./chunk-IFB4PCXR.mjs";
13
+ import {
14
+ init_esm_shims
15
+ } from "./chunk-5AYPCRZA.mjs";
16
+ import "./chunk-CFGUYUPP.mjs";
14
17
 
15
18
  // src/cli.ts
19
+ init_esm_shims();
16
20
  import { Command } from "commander";
17
21
  var program = new Command();
18
22
  program.name("stackscan").description("Auto-detect tech stacks and generate tech.json or markdown.").version("0.1.0");
package/dist/defaults.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  DEFAULT_CATEGORY_ICONS
3
- } from "./chunk-NGEKE4DQ.mjs";
4
- import "./chunk-EOKQCSHI.mjs";
3
+ } from "./chunk-IFB4PCXR.mjs";
4
+ import "./chunk-5AYPCRZA.mjs";
5
+ import "./chunk-CFGUYUPP.mjs";
5
6
  export {
6
7
  DEFAULT_CATEGORY_ICONS
7
8
  };
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }