stackscan 0.1.6

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 (369) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +222 -0
  3. package/dist/add.d.mts +3 -0
  4. package/dist/add.d.ts +3 -0
  5. package/dist/add.js +83 -0
  6. package/dist/add.mjs +7 -0
  7. package/dist/batch-import.d.mts +6 -0
  8. package/dist/batch-import.d.ts +6 -0
  9. package/dist/batch-import.js +5724 -0
  10. package/dist/batch-import.mjs +12 -0
  11. package/dist/chunk-22J2UHU7.mjs +1980 -0
  12. package/dist/chunk-2KG7JDHY.mjs +19 -0
  13. package/dist/chunk-2O2NMD7M.mjs +127 -0
  14. package/dist/chunk-3HEYJTUE.mjs +157 -0
  15. package/dist/chunk-3LPZV7KA.mjs +15 -0
  16. package/dist/chunk-3O2C34CJ.mjs +174 -0
  17. package/dist/chunk-3R4TXOZA.mjs +179 -0
  18. package/dist/chunk-3RJHZIII.mjs +174 -0
  19. package/dist/chunk-3XKWCBY6.mjs +105 -0
  20. package/dist/chunk-4OMBB3R6.mjs +52 -0
  21. package/dist/chunk-4THN5TT4.mjs +185 -0
  22. package/dist/chunk-4WCVZS6B.mjs +178 -0
  23. package/dist/chunk-5MNAT56X.mjs +23 -0
  24. package/dist/chunk-5VH7N3X6.mjs +109 -0
  25. package/dist/chunk-6A4WEZDZ.mjs +14 -0
  26. package/dist/chunk-6MIRBLO4.mjs +15 -0
  27. package/dist/chunk-6RCTNUF4.mjs +17 -0
  28. package/dist/chunk-7F4KWGMM.mjs +45 -0
  29. package/dist/chunk-7KF2HEU2.mjs +56 -0
  30. package/dist/chunk-7KONWCSX.mjs +15 -0
  31. package/dist/chunk-7TIXAYVC.mjs +10122 -0
  32. package/dist/chunk-ADMVFPX7.mjs +150 -0
  33. package/dist/chunk-AFJCX5SK.mjs +22 -0
  34. package/dist/chunk-ATNEVZPV.mjs +25 -0
  35. package/dist/chunk-BBP27ZGZ.mjs +4841 -0
  36. package/dist/chunk-BGT3PANW.mjs +64 -0
  37. package/dist/chunk-BJIQZNKU.mjs +184 -0
  38. package/dist/chunk-BKQW4ZNZ.mjs +19 -0
  39. package/dist/chunk-BMQTYZOD.mjs +144 -0
  40. package/dist/chunk-CZADURZD.mjs +674 -0
  41. package/dist/chunk-D2DOGM2Y.mjs +19 -0
  42. package/dist/chunk-D32C3FU6.mjs +45 -0
  43. package/dist/chunk-D6FFDX4P.mjs +158 -0
  44. package/dist/chunk-DUAFJVBN.mjs +44 -0
  45. package/dist/chunk-E24PAHCZ.mjs +146 -0
  46. package/dist/chunk-E3OD2BXY.mjs +14 -0
  47. package/dist/chunk-E4K5XYFI.mjs +210767 -0
  48. package/dist/chunk-EH2SEQZP.mjs +10119 -0
  49. package/dist/chunk-EH4FWTP5.mjs +21 -0
  50. package/dist/chunk-EOKQCSHI.mjs +10 -0
  51. package/dist/chunk-EQ4WRCPP.mjs +16 -0
  52. package/dist/chunk-EYXTSAAW.mjs +64 -0
  53. package/dist/chunk-F6Z4WXOF.mjs +146 -0
  54. package/dist/chunk-FM5BCBKT.mjs +77 -0
  55. package/dist/chunk-GXKIDBAX.mjs +146 -0
  56. package/dist/chunk-H6HA3IZE.mjs +1980 -0
  57. package/dist/chunk-H7WNQ3SS.mjs +23 -0
  58. package/dist/chunk-HBJEQ63D.mjs +205 -0
  59. package/dist/chunk-HTTDBNRT.mjs +146 -0
  60. package/dist/chunk-HYUKJUPF.mjs +177 -0
  61. package/dist/chunk-IFEEO473.mjs +49 -0
  62. package/dist/chunk-IILZ43EE.mjs +25 -0
  63. package/dist/chunk-ITGRHGUT.mjs +158 -0
  64. package/dist/chunk-J5JVDMED.mjs +45 -0
  65. package/dist/chunk-JH3SW4KH.mjs +4896 -0
  66. package/dist/chunk-JHVWSHNY.mjs +32 -0
  67. package/dist/chunk-JLFOQXQG.mjs +26 -0
  68. package/dist/chunk-K4BNSVJP.mjs +16 -0
  69. package/dist/chunk-KCDUZXVN.mjs +157 -0
  70. package/dist/chunk-KMDEPBKS.mjs +685 -0
  71. package/dist/chunk-L4AQWDD2.mjs +92 -0
  72. package/dist/chunk-L7I4UC35.mjs +158 -0
  73. package/dist/chunk-LB3L25FS.mjs +1980 -0
  74. package/dist/chunk-LDA354A3.mjs +158 -0
  75. package/dist/chunk-LSUI3VI4.mjs +19 -0
  76. package/dist/chunk-MB2X3DXF.mjs +45 -0
  77. package/dist/chunk-MBL4CIFG.mjs +28 -0
  78. package/dist/chunk-MLAUEAUQ.mjs +27 -0
  79. package/dist/chunk-NGEKE4DQ.mjs +23 -0
  80. package/dist/chunk-NJ4FK5BO.mjs +19 -0
  81. package/dist/chunk-OJZZPNXQ.mjs +1985 -0
  82. package/dist/chunk-P24PKCUA.mjs +25 -0
  83. package/dist/chunk-PFQIKEIL.mjs +15 -0
  84. package/dist/chunk-Q5ASM7HE.mjs +45 -0
  85. package/dist/chunk-Q7X2R7N7.mjs +16 -0
  86. package/dist/chunk-QAIJCQWH.mjs +157 -0
  87. package/dist/chunk-QQAUZGVG.mjs +2166 -0
  88. package/dist/chunk-QUIF3FJ2.mjs +55 -0
  89. package/dist/chunk-RDFZ4GVM.mjs +23 -0
  90. package/dist/chunk-RFRKMUNA.mjs +49 -0
  91. package/dist/chunk-RIIQA6S6.mjs +2204 -0
  92. package/dist/chunk-SGOSAU2P.mjs +51 -0
  93. package/dist/chunk-SLYSEMYE.mjs +21 -0
  94. package/dist/chunk-SNKLZ7VB.mjs +36 -0
  95. package/dist/chunk-TKKUEAN6.mjs +45 -0
  96. package/dist/chunk-TMH7EUXF.mjs +179 -0
  97. package/dist/chunk-TP55TF47.mjs +1980 -0
  98. package/dist/chunk-U4AFTAZI.mjs +1980 -0
  99. package/dist/chunk-U4EXCWGR.mjs +174 -0
  100. package/dist/chunk-U4OINWJM.mjs +42 -0
  101. package/dist/chunk-U63TGBAS.mjs +179 -0
  102. package/dist/chunk-UESFH6US.mjs +210773 -0
  103. package/dist/chunk-UITLHBZA.mjs +164 -0
  104. package/dist/chunk-VFD26CTJ.mjs +16 -0
  105. package/dist/chunk-VSWWWPO7.mjs +205 -0
  106. package/dist/chunk-VUVPGH7A.mjs +157 -0
  107. package/dist/chunk-W34IFT2J.mjs +45 -0
  108. package/dist/chunk-WPSGF5DK.mjs +92 -0
  109. package/dist/chunk-WPU2XV5B.mjs +25 -0
  110. package/dist/chunk-WTPR7TOE.mjs +146 -0
  111. package/dist/chunk-X3ATBJ5Q.mjs +14 -0
  112. package/dist/chunk-XMZATJRD.mjs +23 -0
  113. package/dist/chunk-Y2Y225MR.mjs +117 -0
  114. package/dist/chunk-YNDKJ5QJ.mjs +89 -0
  115. package/dist/chunk-YPQNYUP3.mjs +92 -0
  116. package/dist/chunk-ZH22D4SN.mjs +179 -0
  117. package/dist/chunk-ZSJJGBQR.mjs +39 -0
  118. package/dist/chunk-ZSMMBZHO.mjs +64 -0
  119. package/dist/chunk-ZTXCA3NN.mjs +74 -0
  120. package/dist/chunk-ZYMQR24Z.mjs +145 -0
  121. package/dist/cli.d.mts +1 -0
  122. package/dist/cli.d.ts +1 -0
  123. package/dist/cli.js +5770 -0
  124. package/dist/cli.mjs +25 -0
  125. package/dist/config.d.mts +5 -0
  126. package/dist/config.d.ts +5 -0
  127. package/dist/config.js +41 -0
  128. package/dist/config.mjs +7 -0
  129. package/dist/defaults.d.mts +3 -0
  130. package/dist/defaults.d.ts +3 -0
  131. package/dist/defaults.js +47 -0
  132. package/dist/defaults.mjs +7 -0
  133. package/dist/detectors/ci.d.mts +5 -0
  134. package/dist/detectors/ci.d.ts +5 -0
  135. package/dist/detectors/ci.js +59 -0
  136. package/dist/detectors/ci.mjs +7 -0
  137. package/dist/detectors/docker.d.mts +5 -0
  138. package/dist/detectors/docker.d.ts +5 -0
  139. package/dist/detectors/docker.js +50 -0
  140. package/dist/detectors/docker.mjs +7 -0
  141. package/dist/detectors/next.d.mts +7 -0
  142. package/dist/detectors/next.d.ts +7 -0
  143. package/dist/detectors/next.js +49 -0
  144. package/dist/detectors/next.mjs +7 -0
  145. package/dist/detectors/prisma.d.mts +7 -0
  146. package/dist/detectors/prisma.d.ts +7 -0
  147. package/dist/detectors/prisma.js +48 -0
  148. package/dist/detectors/prisma.mjs +7 -0
  149. package/dist/import.d.mts +2 -0
  150. package/dist/import.d.ts +2 -0
  151. package/dist/import.js +2062 -0
  152. package/dist/import.mjs +53 -0
  153. package/dist/output.d.mts +7 -0
  154. package/dist/output.d.ts +7 -0
  155. package/dist/output.js +3619 -0
  156. package/dist/output.mjs +13 -0
  157. package/dist/scan.d.mts +7 -0
  158. package/dist/scan.d.ts +7 -0
  159. package/dist/scan.js +5725 -0
  160. package/dist/scan.mjs +12 -0
  161. package/dist/scanner.d.mts +5 -0
  162. package/dist/scanner.d.ts +5 -0
  163. package/dist/scanner.js +5514 -0
  164. package/dist/scanner.mjs +14 -0
  165. package/dist/simple-icons-hex.d.mts +6751 -0
  166. package/dist/simple-icons-hex.d.ts +6751 -0
  167. package/dist/simple-icons-hex.js +10118 -0
  168. package/dist/simple-icons-hex.mjs +6736 -0
  169. package/dist/sync.d.mts +7 -0
  170. package/dist/sync.d.ts +7 -0
  171. package/dist/sync.js +5725 -0
  172. package/dist/sync.mjs +160 -0
  173. package/dist/techDefinitions.d.mts +5 -0
  174. package/dist/techDefinitions.d.ts +5 -0
  175. package/dist/techDefinitions.js +2004 -0
  176. package/dist/techDefinitions.mjs +7 -0
  177. package/dist/techMap.d.mts +5 -0
  178. package/dist/techMap.d.ts +5 -0
  179. package/dist/techMap.js +2018 -0
  180. package/dist/techMap.mjs +8 -0
  181. package/dist/types.d.mts +24 -0
  182. package/dist/types.d.ts +24 -0
  183. package/dist/types.js +18 -0
  184. package/dist/types.mjs +1 -0
  185. package/dist/typescript-7Q5RIVZY.mjs +6 -0
  186. package/dist/typescript-T5HXSZZS.mjs +5 -0
  187. package/dist/watch.d.mts +3 -0
  188. package/dist/watch.d.ts +3 -0
  189. package/dist/watch.js +2122 -0
  190. package/dist/watch.mjs +13 -0
  191. package/package.json +57 -0
  192. package/public/assets/logos/ai/huggingface.svg +1 -0
  193. package/public/assets/logos/ai/langchain.svg +1 -0
  194. package/public/assets/logos/ai/openai.svg +1 -0
  195. package/public/assets/logos/ai/replicate.svg +1 -0
  196. package/public/assets/logos/ai/tensorflow.svg +1 -0
  197. package/public/assets/logos/api/apollographql.svg +1 -0
  198. package/public/assets/logos/api/graphql.svg +1 -0
  199. package/public/assets/logos/api/relay.svg +1 -0
  200. package/public/assets/logos/api/trpc.svg +1 -0
  201. package/public/assets/logos/auth/argo.svg +1 -0
  202. package/public/assets/logos/auth/auth0.svg +1 -0
  203. package/public/assets/logos/auth/authjs.svg +73 -0
  204. package/public/assets/logos/auth/clerk.svg +1 -0
  205. package/public/assets/logos/auth/firebase.svg +1 -0
  206. package/public/assets/logos/auth/jsonwebtokens.svg +1 -0
  207. package/public/assets/logos/auth/keycloak.svg +1 -0
  208. package/public/assets/logos/auth/passport.svg +1 -0
  209. package/public/assets/logos/automation/lerna.svg +1 -0
  210. package/public/assets/logos/automation/nx.svg +1 -0
  211. package/public/assets/logos/automation/turborepo.svg +1 -0
  212. package/public/assets/logos/backend/adonisjs.svg +1 -0
  213. package/public/assets/logos/backend/express.svg +1 -0
  214. package/public/assets/logos/backend/fastify.svg +1 -0
  215. package/public/assets/logos/backend/koa.svg +1 -0
  216. package/public/assets/logos/backend/nestjs.svg +1 -0
  217. package/public/assets/logos/build/babel.svg +1 -0
  218. package/public/assets/logos/build/esbuild.svg +1 -0
  219. package/public/assets/logos/build/rollupdotjs.svg +1 -0
  220. package/public/assets/logos/build/snowpack.svg +1 -0
  221. package/public/assets/logos/build/swc.svg +1 -0
  222. package/public/assets/logos/build/vite.svg +15 -0
  223. package/public/assets/logos/build/webpack.svg +1 -0
  224. package/public/assets/logos/ci/circleci.svg +1 -0
  225. package/public/assets/logos/ci/githubactions.svg +1 -0
  226. package/public/assets/logos/ci/gitlab.svg +1 -0
  227. package/public/assets/logos/ci/jenkins.svg +1 -0
  228. package/public/assets/logos/ci/travisci.svg +1 -0
  229. package/public/assets/logos/cloud/cloudflare.svg +1 -0
  230. package/public/assets/logos/cloud/googlecloud.svg +1 -0
  231. package/public/assets/logos/cloud/microsoftazure.svg +1 -0
  232. package/public/assets/logos/cms/contentful.svg +1 -0
  233. package/public/assets/logos/cms/directus.svg +1 -0
  234. package/public/assets/logos/cms/ghost.svg +1 -0
  235. package/public/assets/logos/cms/keystone.svg +1 -0
  236. package/public/assets/logos/cms/sanity.svg +1 -0
  237. package/public/assets/logos/cms/shopify.svg +1 -0
  238. package/public/assets/logos/cms/strapi.svg +1 -0
  239. package/public/assets/logos/cms/wordpress.svg +1 -0
  240. package/public/assets/logos/container/docker.svg +1 -0
  241. package/public/assets/logos/container/kubernetes.svg +1 -0
  242. package/public/assets/logos/css/antdesign.svg +1 -0
  243. package/public/assets/logos/css/bootstrap.svg +1 -0
  244. package/public/assets/logos/css/bulma.svg +1 -0
  245. package/public/assets/logos/css/chakraui.svg +1 -0
  246. package/public/assets/logos/css/daisyui.svg +1 -0
  247. package/public/assets/logos/css/fallback/mantine-logo.svg +1 -0
  248. package/public/assets/logos/css/fallback/shadcnui.svg +1 -0
  249. package/public/assets/logos/css/foundation.svg +1 -0
  250. package/public/assets/logos/css/headlessui.svg +1 -0
  251. package/public/assets/logos/css/less.svg +1 -0
  252. package/public/assets/logos/css/mui.svg +1 -0
  253. package/public/assets/logos/css/postcss.svg +1 -0
  254. package/public/assets/logos/css/radixui.svg +1 -0
  255. package/public/assets/logos/css/sass.svg +1 -0
  256. package/public/assets/logos/css/shadcnui.svg +1 -0
  257. package/public/assets/logos/css/styledcomponents.svg +1 -0
  258. package/public/assets/logos/css/tailwindcss.svg +1 -0
  259. package/public/assets/logos/database/amazondynamodb.svg +1 -0
  260. package/public/assets/logos/database/apachecassandra.svg +1 -0
  261. package/public/assets/logos/database/cockroachlabs.svg +1 -0
  262. package/public/assets/logos/database/duckdb.svg +1 -0
  263. package/public/assets/logos/database/elasticsearch.svg +1 -0
  264. package/public/assets/logos/database/fauna.svg +3 -0
  265. package/public/assets/logos/database/mariadb.svg +1 -0
  266. package/public/assets/logos/database/mongodb.svg +1 -0
  267. package/public/assets/logos/database/mysql.svg +1 -0
  268. package/public/assets/logos/database/planetscale.svg +1 -0
  269. package/public/assets/logos/database/postgresql.svg +1 -0
  270. package/public/assets/logos/database/redis.svg +1 -0
  271. package/public/assets/logos/database/sqlite.svg +1 -0
  272. package/public/assets/logos/database/supabase.svg +1 -0
  273. package/public/assets/logos/database/surrealdb.svg +1 -0
  274. package/public/assets/logos/devops/ansible.svg +1 -0
  275. package/public/assets/logos/devops/pulumi.svg +1 -0
  276. package/public/assets/logos/devops/serverless.svg +1 -0
  277. package/public/assets/logos/devops/terraform.svg +1 -0
  278. package/public/assets/logos/fallback/31557565.svg +32 -0
  279. package/public/assets/logos/fallback/Drizzle--Streamline-Simple-Icons.svg +7 -0
  280. package/public/assets/logos/fallback/changesets.svg +43 -0
  281. package/public/assets/logos/fallback/lemonsqueezy.svg +8 -0
  282. package/public/assets/logos/fallback/mantine-logo.svg +1 -0
  283. package/public/assets/logos/fallback/reactquery.svg +12 -0
  284. package/public/assets/logos/fallback/shadcnui.svg +21 -0
  285. package/public/assets/logos/fallback/stitches.svg +10 -0
  286. package/public/assets/logos/format/prettier.svg +1 -0
  287. package/public/assets/logos/frontend/alpinedotjs.svg +1 -0
  288. package/public/assets/logos/frontend/angular.svg +1 -0
  289. package/public/assets/logos/frontend/astro.svg +1 -0
  290. package/public/assets/logos/frontend/backbone.svg +1 -0
  291. package/public/assets/logos/frontend/emberdotjs.svg +1 -0
  292. package/public/assets/logos/frontend/htmx.svg +1 -0
  293. package/public/assets/logos/frontend/lit.svg +1 -0
  294. package/public/assets/logos/frontend/nextdotjs.svg +1 -0
  295. package/public/assets/logos/frontend/nuxt.svg +1 -0
  296. package/public/assets/logos/frontend/preact.svg +1 -0
  297. package/public/assets/logos/frontend/qwik.svg +1 -0
  298. package/public/assets/logos/frontend/react.svg +1 -0
  299. package/public/assets/logos/frontend/remix.svg +1 -0
  300. package/public/assets/logos/frontend/solid.svg +1 -0
  301. package/public/assets/logos/frontend/svelte.svg +1 -0
  302. package/public/assets/logos/frontend/vuedotjs.svg +1 -0
  303. package/public/assets/logos/hosting/netlify.svg +1 -0
  304. package/public/assets/logos/hosting/railway.svg +1 -0
  305. package/public/assets/logos/hosting/render.svg +1 -0
  306. package/public/assets/logos/hosting/vercel.svg +1 -0
  307. package/public/assets/logos/language/csharp.svg +1 -0
  308. package/public/assets/logos/language/go.svg +1 -0
  309. package/public/assets/logos/language/javascript.svg +1 -0
  310. package/public/assets/logos/language/openjdk.svg +1 -0
  311. package/public/assets/logos/language/php.svg +1 -0
  312. package/public/assets/logos/language/python.svg +1 -0
  313. package/public/assets/logos/language/ruby.svg +1 -0
  314. package/public/assets/logos/language/rust.svg +1 -0
  315. package/public/assets/logos/language/typescript.svg +1 -0
  316. package/public/assets/logos/lint/commitlint.svg +1 -0
  317. package/public/assets/logos/lint/eslint.svg +1 -0
  318. package/public/assets/logos/lint/husky.svg +3 -0
  319. package/public/assets/logos/lint/lintstaged.svg +3 -0
  320. package/public/assets/logos/mobile/capacitor.svg +1 -0
  321. package/public/assets/logos/mobile/expo.svg +1 -0
  322. package/public/assets/logos/mobile/flutter.svg +1 -0
  323. package/public/assets/logos/mobile/ionic.svg +1 -0
  324. package/public/assets/logos/mobile/react.svg +1 -0
  325. package/public/assets/logos/network/axios.svg +1 -0
  326. package/public/assets/logos/network/brandfetch.svg +1 -0
  327. package/public/assets/logos/network/grpc.svg +1 -0
  328. package/public/assets/logos/network/openapiinitiative.svg +1 -0
  329. package/public/assets/logos/network/swr.svg +1 -0
  330. package/public/assets/logos/orm/drizzle.svg +1 -0
  331. package/public/assets/logos/orm/mongoose.svg +1 -0
  332. package/public/assets/logos/orm/prisma.svg +1 -0
  333. package/public/assets/logos/orm/typeorm.svg +1 -0
  334. package/public/assets/logos/package/npm.svg +1 -0
  335. package/public/assets/logos/package/pnpm.svg +1 -0
  336. package/public/assets/logos/package/yarn.svg +1 -0
  337. package/public/assets/logos/payment/fallback/lemonsqueezy.svg +1 -0
  338. package/public/assets/logos/payment/paypal.svg +1 -0
  339. package/public/assets/logos/payment/stripe.svg +1 -0
  340. package/public/assets/logos/runtime/bun.svg +1 -0
  341. package/public/assets/logos/runtime/deno.svg +1 -0
  342. package/public/assets/logos/ssg/eleventy.svg +1 -0
  343. package/public/assets/logos/ssg/gatsby.svg +1 -0
  344. package/public/assets/logos/ssg/hugo.svg +1 -0
  345. package/public/assets/logos/ssg/jekyll.svg +1 -0
  346. package/public/assets/logos/state/mobx.svg +1 -0
  347. package/public/assets/logos/state/recoil.svg +1 -0
  348. package/public/assets/logos/state/redux.svg +1 -0
  349. package/public/assets/logos/state/xstate.svg +1 -0
  350. package/public/assets/logos/state/zustand.svg +1 -0
  351. package/public/assets/logos/testing/chai.svg +1 -0
  352. package/public/assets/logos/testing/cypress.svg +1 -0
  353. package/public/assets/logos/testing/jasmine.svg +1 -0
  354. package/public/assets/logos/testing/jest.svg +1 -0
  355. package/public/assets/logos/testing/mocha.svg +1 -0
  356. package/public/assets/logos/testing/playwright.svg +1 -0
  357. package/public/assets/logos/testing/puppeteer.svg +1 -0
  358. package/public/assets/logos/testing/storybook.svg +1 -0
  359. package/public/assets/logos/testing/testinglibrary.svg +1 -0
  360. package/public/assets/logos/testing/vitest.svg +1 -0
  361. package/public/assets/logos/utility/d3.svg +1 -0
  362. package/public/assets/logos/utility/leaflet.svg +1 -0
  363. package/public/assets/logos/utility/lodash.svg +1 -0
  364. package/public/assets/logos/utility/pyup.svg +1 -0
  365. package/public/assets/logos/utility/reactivex.svg +1 -0
  366. package/public/assets/logos/utility/threedotjs.svg +1 -0
  367. package/public/assets/logos/utility/zod.svg +1 -0
  368. package/public/stackscan-white.svg +26 -0
  369. package/public/stackscan.svg +26 -0
@@ -0,0 +1,174 @@
1
+ import {
2
+ DEFAULT_CATEGORY_ICONS
3
+ } from "./chunk-NGEKE4DQ.mjs";
4
+ import {
5
+ __dirname
6
+ } from "./chunk-EOKQCSHI.mjs";
7
+ import {
8
+ simple_icons_hex_default
9
+ } from "./chunk-EH2SEQZP.mjs";
10
+
11
+ // src/output.ts
12
+ import fs from "fs-extra";
13
+ import path from "path";
14
+ import chalk from "chalk";
15
+ import { createRequire } from "module";
16
+ var require2 = createRequire(import.meta.url);
17
+ async function writeOutput(outPath, techs, config, format = "json", assetsOutPath) {
18
+ const outDirectory = path.dirname(outPath);
19
+ await fs.ensureDir(outDirectory);
20
+ let availableLogos = /* @__PURE__ */ new Set();
21
+ if (assetsOutPath) {
22
+ availableLogos = await copyAssets(techs, assetsOutPath, config);
23
+ }
24
+ if (format === "json") {
25
+ await fs.writeJSON(
26
+ outPath,
27
+ {
28
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
29
+ tech: techs
30
+ },
31
+ { spaces: 2 }
32
+ );
33
+ console.log(chalk.blue(`\u2192 Saved ${techs.length} tech entries to ${outPath}`));
34
+ } else if (format === "markdown") {
35
+ const relativeAssetsPath = assetsOutPath ? path.relative(outDirectory, assetsOutPath).replace(/\\/g, "/") : void 0;
36
+ const mdContent = generateMarkdown(techs, relativeAssetsPath, availableLogos);
37
+ const mdPath = outPath.endsWith(".json") ? outPath.replace(/\.json$/, ".md") : outPath;
38
+ await fs.writeFile(mdPath, mdContent);
39
+ console.log(chalk.blue(`\u2192 Saved markdown to ${mdPath}`));
40
+ }
41
+ }
42
+ async function copyAssets(techs, dest, config) {
43
+ const srcDir = path.resolve(__dirname, "../assets/logos");
44
+ let lucideDir;
45
+ try {
46
+ lucideDir = path.join(path.dirname(require2.resolve("lucide-static/package.json")), "icons");
47
+ } catch (e) {
48
+ lucideDir = path.resolve(__dirname, "../node_modules/lucide-static/icons");
49
+ }
50
+ const copied = /* @__PURE__ */ new Set();
51
+ let count = 0;
52
+ for (const t of techs) {
53
+ let srcFile = t.logo ? path.join(srcDir, t.logo) : null;
54
+ let destFile = t.logo ? path.join(dest, t.logo) : null;
55
+ let isDefault = false;
56
+ if (!srcFile || !await fs.pathExists(srcFile)) {
57
+ const defaultIconName = DEFAULT_CATEGORY_ICONS[t.type];
58
+ if (defaultIconName) {
59
+ const lucideFile = path.join(lucideDir, `${defaultIconName}.svg`);
60
+ if (await fs.pathExists(lucideFile)) {
61
+ srcFile = lucideFile;
62
+ const newLogoPath = `defaults/${defaultIconName}.svg`;
63
+ destFile = path.join(dest, newLogoPath);
64
+ t.logo = newLogoPath;
65
+ isDefault = true;
66
+ }
67
+ }
68
+ }
69
+ if (srcFile && destFile && await fs.pathExists(srcFile)) {
70
+ await fs.ensureDir(path.dirname(destFile));
71
+ let svgContent = await fs.readFile(srcFile, "utf8");
72
+ let color;
73
+ if (config.iconColors && config.iconColors[t.name]) {
74
+ color = config.iconColors[t.name];
75
+ } else if (config.colorMode === "white") {
76
+ color = "#FFFFFF";
77
+ } else if (config.colorMode === "black") {
78
+ color = "#000000";
79
+ } else if (config.colorMode === "custom" && config.customColor) {
80
+ color = config.customColor;
81
+ } else if (config.colorMode === "default" || !config.colorMode) {
82
+ if (!isDefault) {
83
+ const slug = path.basename(t.logo, ".svg");
84
+ const brandHex = simple_icons_hex_default[slug];
85
+ if (brandHex) {
86
+ color = `#${brandHex}`;
87
+ }
88
+ }
89
+ }
90
+ if (color) {
91
+ if (isDefault) {
92
+ if (svgContent.includes("stroke=")) {
93
+ svgContent = svgContent.replace(/stroke="[^"]*"/g, `stroke="${color}"`);
94
+ } else {
95
+ svgContent = svgContent.replace("<svg", `<svg stroke="${color}"`);
96
+ }
97
+ } else {
98
+ if (svgContent.includes("fill=")) {
99
+ svgContent = svgContent.replace(/fill="[^"]*"/g, `fill="${color}"`);
100
+ } else {
101
+ svgContent = svgContent.replace("<svg", `<svg fill="${color}"`);
102
+ }
103
+ }
104
+ }
105
+ await fs.writeFile(destFile, svgContent);
106
+ copied.add(t.logo);
107
+ if (!isDefault) count++;
108
+ } else {
109
+ }
110
+ }
111
+ if (count > 0) {
112
+ console.log(chalk.blue(`\u2192 Copied ${count} logos to ${dest}`));
113
+ }
114
+ return copied;
115
+ }
116
+ function generateMarkdown(techs, assetsPath, availableLogos) {
117
+ const grouped = {};
118
+ for (const t of techs) {
119
+ const type = t.type || "misc";
120
+ if (!grouped[type]) grouped[type] = [];
121
+ grouped[type].push(t);
122
+ }
123
+ let md = "# Tech Stack\n\n";
124
+ const order = [
125
+ "language",
126
+ "frontend",
127
+ "backend",
128
+ "framework",
129
+ "library",
130
+ "database",
131
+ "orm",
132
+ "auth",
133
+ "api",
134
+ "cloud",
135
+ "hosting",
136
+ "ci",
137
+ "devops",
138
+ "container",
139
+ "testing",
140
+ "build",
141
+ "tooling",
142
+ "misc"
143
+ ];
144
+ const sortedKeys = Object.keys(grouped).sort((a, b) => {
145
+ const idxA = order.indexOf(a);
146
+ const idxB = order.indexOf(b);
147
+ if (idxA === -1 && idxB === -1) return a.localeCompare(b);
148
+ if (idxA === -1) return 1;
149
+ if (idxB === -1) return -1;
150
+ return idxA - idxB;
151
+ });
152
+ for (const type of sortedKeys) {
153
+ const title = type.charAt(0).toUpperCase() + type.slice(1);
154
+ md += `## ${title}
155
+
156
+ `;
157
+ for (const t of grouped[type]) {
158
+ if (assetsPath && t.logo && availableLogos?.has(t.logo)) {
159
+ const logoUrl = `${assetsPath}/${t.logo}`;
160
+ md += `- <img src="${logoUrl}" alt="${t.name}" width="24" height="24" /> **${t.name}**
161
+ `;
162
+ } else {
163
+ md += `- **${t.name}**
164
+ `;
165
+ }
166
+ }
167
+ md += "\n";
168
+ }
169
+ return md;
170
+ }
171
+
172
+ export {
173
+ writeOutput
174
+ };
@@ -0,0 +1,105 @@
1
+ // src/output.ts
2
+ import fs from "fs-extra";
3
+ import path from "path";
4
+ import chalk from "chalk";
5
+ async function writeOutput(outPath, techs, config, format = "json", assetsOutPath) {
6
+ const outDirectory = path.dirname(outPath);
7
+ await fs.ensureDir(outDirectory);
8
+ if (assetsOutPath) {
9
+ await copyAssets(techs, assetsOutPath);
10
+ }
11
+ if (format === "json") {
12
+ await fs.writeJSON(
13
+ outPath,
14
+ {
15
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
16
+ tech: techs
17
+ },
18
+ { spaces: 2 }
19
+ );
20
+ console.log(chalk.blue(`\u2192 Saved ${techs.length} tech entries to ${outPath}`));
21
+ } else if (format === "markdown") {
22
+ const relativeAssetsPath = assetsOutPath ? path.relative(outDirectory, assetsOutPath).replace(/\\/g, "/") : void 0;
23
+ const mdContent = generateMarkdown(techs, relativeAssetsPath);
24
+ const mdPath = outPath.endsWith(".json") ? outPath.replace(/\.json$/, ".md") : outPath;
25
+ await fs.writeFile(mdPath, mdContent);
26
+ console.log(chalk.blue(`\u2192 Saved markdown to ${mdPath}`));
27
+ }
28
+ }
29
+ async function copyAssets(techs, dest) {
30
+ const srcDir = path.resolve(__dirname, "../assets/logos");
31
+ let count = 0;
32
+ for (const t of techs) {
33
+ if (!t.logo) continue;
34
+ const srcFile = path.join(srcDir, t.logo);
35
+ const destFile = path.join(dest, t.logo);
36
+ if (await fs.pathExists(srcFile)) {
37
+ await fs.ensureDir(path.dirname(destFile));
38
+ await fs.copy(srcFile, destFile);
39
+ count++;
40
+ } else {
41
+ }
42
+ }
43
+ if (count > 0) {
44
+ console.log(chalk.blue(`\u2192 Copied ${count} logos to ${dest}`));
45
+ }
46
+ }
47
+ function generateMarkdown(techs, assetsPath) {
48
+ const grouped = {};
49
+ for (const t of techs) {
50
+ const type = t.type || "misc";
51
+ if (!grouped[type]) grouped[type] = [];
52
+ grouped[type].push(t);
53
+ }
54
+ let md = "# Tech Stack\n\n";
55
+ const order = [
56
+ "language",
57
+ "frontend",
58
+ "backend",
59
+ "framework",
60
+ "library",
61
+ "database",
62
+ "orm",
63
+ "auth",
64
+ "api",
65
+ "cloud",
66
+ "hosting",
67
+ "ci",
68
+ "devops",
69
+ "container",
70
+ "testing",
71
+ "build",
72
+ "tooling",
73
+ "misc"
74
+ ];
75
+ const sortedKeys = Object.keys(grouped).sort((a, b) => {
76
+ const idxA = order.indexOf(a);
77
+ const idxB = order.indexOf(b);
78
+ if (idxA === -1 && idxB === -1) return a.localeCompare(b);
79
+ if (idxA === -1) return 1;
80
+ if (idxB === -1) return -1;
81
+ return idxA - idxB;
82
+ });
83
+ for (const type of sortedKeys) {
84
+ const title = type.charAt(0).toUpperCase() + type.slice(1);
85
+ md += `## ${title}
86
+
87
+ `;
88
+ for (const t of grouped[type]) {
89
+ if (assetsPath && t.logo) {
90
+ const logoUrl = `${assetsPath}/${t.logo}`;
91
+ md += `- <img src="${logoUrl}" alt="${t.name}" width="24" height="24" /> **${t.name}**
92
+ `;
93
+ } else {
94
+ md += `- **${t.name}**
95
+ `;
96
+ }
97
+ }
98
+ md += "\n";
99
+ }
100
+ return md;
101
+ }
102
+
103
+ export {
104
+ writeOutput
105
+ };
@@ -0,0 +1,52 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __typeError = (msg) => {
8
+ throw TypeError(msg);
9
+ };
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
12
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
13
+ }) : x)(function(x) {
14
+ if (typeof require !== "undefined") return require.apply(this, arguments);
15
+ throw Error('Dynamic require of "' + x + '" is not supported');
16
+ });
17
+ var __commonJS = (cb, mod) => function __require2() {
18
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
37
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
38
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
39
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
40
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
41
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
42
+
43
+ export {
44
+ __require,
45
+ __commonJS,
46
+ __toESM,
47
+ __publicField,
48
+ __privateGet,
49
+ __privateAdd,
50
+ __privateSet,
51
+ __privateMethod
52
+ };
@@ -0,0 +1,185 @@
1
+ import {
2
+ copyAssets,
3
+ generateMarkdown
4
+ } from "./chunk-ZH22D4SN.mjs";
5
+ import {
6
+ simple_icons_hex_default
7
+ } from "./chunk-EH2SEQZP.mjs";
8
+ import {
9
+ techMap
10
+ } from "./chunk-2KG7JDHY.mjs";
11
+
12
+ // src/sync.ts
13
+ import fs from "fs";
14
+ import path from "path";
15
+ var BASE_DIR = path.join(process.cwd(), "stacksync");
16
+ function organizePackageFiles() {
17
+ if (!fs.existsSync(BASE_DIR)) return;
18
+ const entries = fs.readdirSync(BASE_DIR, { withFileTypes: true });
19
+ const packageFiles = entries.filter(
20
+ (dirent) => dirent.isFile() && dirent.name.startsWith("package") && dirent.name.endsWith(".json")
21
+ );
22
+ if (packageFiles.length > 0) {
23
+ console.log(`\u{1F4E6} Found ${packageFiles.length} loose package.json files. Organizing...`);
24
+ }
25
+ for (const file of packageFiles) {
26
+ const filePath = path.join(BASE_DIR, file.name);
27
+ try {
28
+ const content = fs.readFileSync(filePath, "utf-8");
29
+ const pkg = JSON.parse(content);
30
+ if (!pkg.name) {
31
+ console.warn(`\u26A0\uFE0F Skipping ${file.name}: No "name" field found in package.json`);
32
+ continue;
33
+ }
34
+ const baseFolderName = pkg.name.replace(/^@/, "").replace(/\//g, "-");
35
+ let folderName = baseFolderName;
36
+ let targetDir = path.join(BASE_DIR, folderName);
37
+ let counter = 1;
38
+ while (fs.existsSync(targetDir)) {
39
+ folderName = `${baseFolderName}-${counter}`;
40
+ targetDir = path.join(BASE_DIR, folderName);
41
+ counter++;
42
+ }
43
+ const targetFile = path.join(targetDir, "package.json");
44
+ if (!fs.existsSync(targetDir)) {
45
+ fs.mkdirSync(targetDir, { recursive: true });
46
+ }
47
+ fs.renameSync(filePath, targetFile);
48
+ console.log(`\u2705 Moved ${file.name} -> ${folderName}/package.json`);
49
+ } catch (error) {
50
+ console.error(`\u274C Error processing ${file.name}:`, error);
51
+ }
52
+ }
53
+ }
54
+ async function sync(options = {}) {
55
+ console.log("\u{1F680} Starting Sync...");
56
+ if (options.color) {
57
+ console.log(`\u{1F3A8} Color mode: ${options.color}`);
58
+ }
59
+ if (!fs.existsSync(BASE_DIR)) {
60
+ console.log(`Creating stacksync directory at: ${BASE_DIR}`);
61
+ fs.mkdirSync(BASE_DIR, { recursive: true });
62
+ console.log('Please place your project folders inside "stacksync/" and run this command again.');
63
+ process.exit(0);
64
+ }
65
+ organizePackageFiles();
66
+ const entries = fs.readdirSync(BASE_DIR, { withFileTypes: true });
67
+ const projectDirs = entries.filter((dirent) => dirent.isDirectory() && dirent.name !== "input" && dirent.name !== "output");
68
+ if (projectDirs.length === 0) {
69
+ console.log('\u26A0\uFE0F No project directories found in "stacksync/".');
70
+ return;
71
+ }
72
+ console.log(`Found ${projectDirs.length} projects to process.
73
+ `);
74
+ const allProjects = [];
75
+ const allTechs = [];
76
+ for (const dir of projectDirs) {
77
+ const projectPath = path.join(BASE_DIR, dir.name);
78
+ const packageJsonPath = path.join(projectPath, "package.json");
79
+ if (fs.existsSync(packageJsonPath)) {
80
+ try {
81
+ const content = fs.readFileSync(packageJsonPath, "utf-8");
82
+ const pkg = JSON.parse(content);
83
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
84
+ const detectedTechs = [];
85
+ Object.keys(allDeps).forEach((dep) => {
86
+ if (techMap[dep]) {
87
+ const tech = techMap[dep];
88
+ let color = null;
89
+ if (options.color === "white") color = "#FFFFFF";
90
+ else if (options.color === "black") color = "#000000";
91
+ else if (options.color && options.color.startsWith("#")) color = options.color;
92
+ else {
93
+ const depSlug = dep.toLowerCase();
94
+ const nameSlug = tech.name.toLowerCase();
95
+ const nameSlugNoSpaces = tech.name.toLowerCase().replace(/\s+/g, "");
96
+ const hex = simple_icons_hex_default[depSlug] || simple_icons_hex_default[nameSlug] || simple_icons_hex_default[nameSlugNoSpaces];
97
+ if (hex) color = `#${hex}`;
98
+ }
99
+ detectedTechs.push({
100
+ name: tech.name,
101
+ slug: dep,
102
+ logo: `https://raw.githubusercontent.com/benjamindotdev/stacksync/main/public/assets/logos/${tech.logo}`,
103
+ relativePath: `public/assets/logos/${tech.logo}`,
104
+ color
105
+ });
106
+ }
107
+ });
108
+ const uniqueTechs = Array.from(new Set(detectedTechs.map((t) => t.slug))).map((slug) => detectedTechs.find((t) => t.slug === slug));
109
+ allTechs.push(...uniqueTechs);
110
+ fs.writeFileSync(
111
+ path.join(projectPath, "stack.json"),
112
+ JSON.stringify(uniqueTechs, null, 2)
113
+ );
114
+ const mdContent = generateMarkdown(uniqueTechs);
115
+ fs.writeFileSync(path.join(projectPath, "stack.md"), mdContent);
116
+ allProjects.push({
117
+ name: dir.name,
118
+ techs: uniqueTechs
119
+ });
120
+ console.log(`\u2705 ${dir.name.padEnd(20)} -> stack.json (${uniqueTechs.length} techs)`);
121
+ } catch (err) {
122
+ console.error(`\u274C Error processing ${dir.name}:`, err.message);
123
+ }
124
+ } else {
125
+ console.warn(`\u26A0\uFE0F Skipping "${dir.name}": No package.json found.`);
126
+ }
127
+ }
128
+ if (allProjects.length > 0) {
129
+ const assetsDir = path.join(process.cwd(), "assets", "logos");
130
+ const uniqueAllTechs = Array.from(new Set(allTechs.map((t) => t.slug))).map((slug) => allTechs.find((t) => t.slug === slug));
131
+ const techsForCopy = uniqueAllTechs.map((t) => ({
132
+ ...t,
133
+ logo: t.relativePath.replace("public/assets/logos/", "")
134
+ // Restore "frameworks/react.svg"
135
+ }));
136
+ await copyAssets(techsForCopy, assetsDir, { colorMode: options.color });
137
+ updateRootReadme(allProjects);
138
+ }
139
+ console.log("\n\u2728 Sync complete.");
140
+ }
141
+ function updateRootReadme(projects) {
142
+ const readmePath = path.join(process.cwd(), "README.md");
143
+ if (!fs.existsSync(readmePath)) {
144
+ console.log("\u26A0\uFE0F No root README.md found to update.");
145
+ return;
146
+ }
147
+ let readmeContent = fs.readFileSync(readmePath, "utf-8");
148
+ const startMarker = "<!-- STACKSYNC_START -->";
149
+ const endMarker = "<!-- STACKSYNC_END -->";
150
+ let newSection = `${startMarker}
151
+ ## My Projects
152
+
153
+ `;
154
+ for (const p of projects) {
155
+ newSection += `### ${p.name}
156
+ `;
157
+ newSection += `<p>
158
+ `;
159
+ for (const t of p.techs) {
160
+ const src = t.relativePath || t.logo;
161
+ newSection += ` <img src="${src}" alt="${t.name}" height="25" style="margin-right: 10px;" />
162
+ `;
163
+ }
164
+ newSection += `</p>
165
+
166
+ `;
167
+ }
168
+ newSection += `${endMarker}`;
169
+ if (readmeContent.includes(startMarker) && readmeContent.includes(endMarker)) {
170
+ const regex = new RegExp(`${startMarker}[\\s\\S]*?${endMarker}`);
171
+ readmeContent = readmeContent.replace(regex, newSection);
172
+ console.log(`\u{1F4DD} Updated root README.md with ${projects.length} projects.`);
173
+ } else {
174
+ readmeContent += `
175
+
176
+ ${newSection}`;
177
+ console.log(`\u{1F4DD} Appended projects to root README.md.`);
178
+ }
179
+ fs.writeFileSync(readmePath, readmeContent);
180
+ }
181
+
182
+ export {
183
+ organizePackageFiles,
184
+ sync
185
+ };
@@ -0,0 +1,178 @@
1
+ import {
2
+ DEFAULT_CATEGORY_ICONS
3
+ } from "./chunk-NGEKE4DQ.mjs";
4
+ import {
5
+ __dirname
6
+ } from "./chunk-EOKQCSHI.mjs";
7
+ import {
8
+ simple_icons_hex_default
9
+ } from "./chunk-EH2SEQZP.mjs";
10
+
11
+ // src/output.ts
12
+ import fs from "fs-extra";
13
+ import path from "path";
14
+ import chalk from "chalk";
15
+ import { createRequire } from "module";
16
+ var require2 = createRequire(import.meta.url);
17
+ async function writeOutput(outPath, techs, config, format = "json", assetsOutPath) {
18
+ const outDirectory = path.dirname(outPath);
19
+ await fs.ensureDir(outDirectory);
20
+ let availableLogos = /* @__PURE__ */ new Set();
21
+ if (assetsOutPath) {
22
+ availableLogos = await copyAssets(techs, assetsOutPath, config);
23
+ }
24
+ if (format === "json") {
25
+ await fs.writeJSON(
26
+ outPath,
27
+ {
28
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
29
+ tech: techs
30
+ },
31
+ { spaces: 2 }
32
+ );
33
+ console.log(chalk.blue(`\u2192 Saved ${techs.length} tech entries to ${outPath}`));
34
+ } else if (format === "markdown") {
35
+ const relativeAssetsPath = assetsOutPath ? path.relative(outDirectory, assetsOutPath).replace(/\\/g, "/") : void 0;
36
+ const mdContent = generateMarkdown(techs, relativeAssetsPath, availableLogos);
37
+ const mdPath = outPath.endsWith(".json") ? outPath.replace(/\.json$/, ".md") : outPath;
38
+ await fs.writeFile(mdPath, mdContent);
39
+ console.log(chalk.blue(`\u2192 Saved markdown to ${mdPath}`));
40
+ }
41
+ }
42
+ async function copyAssets(techs, dest, config) {
43
+ const srcDir = path.resolve(__dirname, "../assets/logos");
44
+ let lucideDir;
45
+ try {
46
+ lucideDir = path.join(path.dirname(require2.resolve("lucide-static/package.json")), "icons");
47
+ } catch (e) {
48
+ lucideDir = path.resolve(__dirname, "../node_modules/lucide-static/icons");
49
+ }
50
+ const copied = /* @__PURE__ */ new Set();
51
+ let count = 0;
52
+ for (const t of techs) {
53
+ let srcFile = t.logo ? path.join(srcDir, t.logo) : null;
54
+ let destFile = t.logo ? path.join(dest, t.logo) : null;
55
+ let isDefault = false;
56
+ if (!srcFile || !await fs.pathExists(srcFile)) {
57
+ const defaultIconName = DEFAULT_CATEGORY_ICONS[t.type];
58
+ if (defaultIconName) {
59
+ const lucideFile = path.join(lucideDir, `${defaultIconName}.svg`);
60
+ if (await fs.pathExists(lucideFile)) {
61
+ srcFile = lucideFile;
62
+ const newLogoPath = `defaults/${defaultIconName}.svg`;
63
+ destFile = path.join(dest, newLogoPath);
64
+ t.logo = newLogoPath;
65
+ isDefault = true;
66
+ }
67
+ }
68
+ }
69
+ if (srcFile && destFile && await fs.pathExists(srcFile)) {
70
+ await fs.ensureDir(path.dirname(destFile));
71
+ let svgContent = await fs.readFile(srcFile, "utf8");
72
+ let color;
73
+ if (config.iconColors && config.iconColors[t.name]) {
74
+ color = config.iconColors[t.name];
75
+ } else if (config.colorMode === "white") {
76
+ color = "#FFFFFF";
77
+ } else if (config.colorMode === "black") {
78
+ color = "#000000";
79
+ } else if (config.colorMode === "custom" && config.customColor) {
80
+ color = config.customColor;
81
+ } else if (config.colorMode === "default" || !config.colorMode) {
82
+ if (!isDefault) {
83
+ const slug = path.basename(t.logo, ".svg");
84
+ const brandHex = simple_icons_hex_default[slug];
85
+ if (brandHex) {
86
+ color = `#${brandHex}`;
87
+ }
88
+ }
89
+ }
90
+ if (color) {
91
+ if (isDefault) {
92
+ if (svgContent.includes("stroke=")) {
93
+ svgContent = svgContent.replace(/stroke="[^"]*"/g, `stroke="${color}"`);
94
+ } else {
95
+ svgContent = svgContent.replace("<svg", `<svg stroke="${color}"`);
96
+ }
97
+ } else {
98
+ if (svgContent.includes("fill=")) {
99
+ svgContent = svgContent.replace(/fill="[^"]*"/g, `fill="${color}"`);
100
+ } else {
101
+ svgContent = svgContent.replace("<svg", `<svg fill="${color}"`);
102
+ }
103
+ }
104
+ }
105
+ await fs.writeFile(destFile, svgContent);
106
+ copied.add(t.logo);
107
+ if (!isDefault) count++;
108
+ } else {
109
+ }
110
+ }
111
+ if (count > 0) {
112
+ console.log(chalk.blue(`\u2192 Copied ${count} logos to ${dest}`));
113
+ }
114
+ return copied;
115
+ }
116
+ function generateMarkdown(techs, assetsPath, availableLogos) {
117
+ const grouped = {};
118
+ for (const t of techs) {
119
+ const type = t.type || "misc";
120
+ if (!grouped[type]) grouped[type] = [];
121
+ grouped[type].push(t);
122
+ }
123
+ let md = "# Tech Stack\n\n";
124
+ const order = [
125
+ "language",
126
+ "frontend",
127
+ "backend",
128
+ "framework",
129
+ "library",
130
+ "database",
131
+ "orm",
132
+ "auth",
133
+ "api",
134
+ "cloud",
135
+ "hosting",
136
+ "ci",
137
+ "devops",
138
+ "container",
139
+ "testing",
140
+ "build",
141
+ "tooling",
142
+ "misc"
143
+ ];
144
+ const sortedKeys = Object.keys(grouped).sort((a, b) => {
145
+ const idxA = order.indexOf(a);
146
+ const idxB = order.indexOf(b);
147
+ if (idxA === -1 && idxB === -1) return a.localeCompare(b);
148
+ if (idxA === -1) return 1;
149
+ if (idxB === -1) return -1;
150
+ return idxA - idxB;
151
+ });
152
+ for (const type of sortedKeys) {
153
+ const title = type.charAt(0).toUpperCase() + type.slice(1);
154
+ md += `## ${title}
155
+
156
+ `;
157
+ for (const t of grouped[type]) {
158
+ if (t.logo && (t.logo.startsWith("http") || t.logo.startsWith("//"))) {
159
+ md += `- <img src="${t.logo}" alt="${t.name}" width="24" height="24" /> **${t.name}**
160
+ `;
161
+ } else if (assetsPath && t.logo && availableLogos?.has(t.logo)) {
162
+ const logoUrl = `${assetsPath}/${t.logo}`;
163
+ md += `- <img src="${logoUrl}" alt="${t.name}" width="24" height="24" /> **${t.name}**
164
+ `;
165
+ } else {
166
+ md += `- **${t.name}**
167
+ `;
168
+ }
169
+ }
170
+ md += "\n";
171
+ }
172
+ return md;
173
+ }
174
+
175
+ export {
176
+ writeOutput,
177
+ generateMarkdown
178
+ };