@chamuka-labs/drawit-cli 0.1.1 → 0.2.0

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 (3) hide show
  1. package/README.md +2 -2
  2. package/dist/index.js +248 -18
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@chamuka-labs/drawit-cli)](https://www.npmjs.com/package/@chamuka-labs/drawit-cli)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@chamuka-labs/drawit-cli)](https://www.npmjs.com/package/@chamuka-labs/drawit-cli)
5
5
  [![Node.js 18+](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
6
- [![License](https://img.shields.io/badge/license-Commercial-blue)](https://drawit.chamuka.ai)
6
+ [![License](https://img.shields.io/badge/license-Proprietary-red)](https://drawit.chamuka.ai)
7
7
 
8
8
  A command-line tool for validating, inspecting, and exporting `.drawit` diagram files. Part of the [Chamuka DrawIt](https://drawit.chamuka.ai) ecosystem.
9
9
 
@@ -147,4 +147,4 @@ Node.js 18 or later.
147
147
 
148
148
  ## License
149
149
 
150
- CommercialPart of the [Chamuka DrawIt](https://drawit.chamuka.ai) ecosystem.
150
+ Proprietary© 2026 Chamuka Inc. All rights reserved. Unauthorized copying, distribution, or modification is strictly prohibited. For licensing inquiries contact [hello@chamuka.ai](mailto:hello@chamuka.ai).
package/dist/index.js CHANGED
@@ -1130,6 +1130,15 @@ var import_node_path = require("path");
1130
1130
  var IMPORT_REGEX = /^\s*import\s+(?:(?:[\w*{][^'"]*)\s+from\s+)?['"]([^'"]+)['"]/gm;
1131
1131
  var EXPORT_FROM_REGEX = /^\s*export\s+(?:\{[^}]*\}|\*(?:\s+as\s+\w+)?)\s+from\s+['"]([^'"]+)['"]/gm;
1132
1132
  var REQUIRE_REGEX = /(?:^|[^.])\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/gm;
1133
+ var PY_RELATIVE_IMPORT = /^\s*from\s+(\.+[\w.]*)\s+import/gm;
1134
+ var RB_REQUIRE_RELATIVE = /require_relative\s+['"]([^'"]+)['"]/gm;
1135
+ var TF_MODULE_SOURCE = /source\s*=\s*["'](\.{1,2}[^"'\s]+)["']/gm;
1136
+ function pythonRelativeToPath(importStr) {
1137
+ const dots = importStr.match(/^\.+/)?.[0].length ?? 1;
1138
+ const rest = importStr.slice(dots).replace(/\./g, "/");
1139
+ const prefix = dots === 1 ? "./" : "../".repeat(dots - 1);
1140
+ return rest ? prefix + rest : prefix;
1141
+ }
1133
1142
  function sanitizeId(relativePath) {
1134
1143
  return "f_" + relativePath.replace(/[^a-zA-Z0-9]/g, "_");
1135
1144
  }
@@ -1163,20 +1172,36 @@ function isExcluded(name, relPath, patterns) {
1163
1172
  }
1164
1173
  return false;
1165
1174
  }
1166
- function extractImportPaths(content) {
1175
+ var JS_TS_EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"]);
1176
+ function extractImportPaths(content, ext) {
1167
1177
  const paths = [];
1168
1178
  let match;
1169
- IMPORT_REGEX.lastIndex = 0;
1170
- while ((match = IMPORT_REGEX.exec(content)) !== null) {
1171
- paths.push(match[1]);
1179
+ if (JS_TS_EXTS.has(ext)) {
1180
+ IMPORT_REGEX.lastIndex = 0;
1181
+ while ((match = IMPORT_REGEX.exec(content)) !== null) paths.push(match[1]);
1182
+ EXPORT_FROM_REGEX.lastIndex = 0;
1183
+ while ((match = EXPORT_FROM_REGEX.exec(content)) !== null) paths.push(match[1]);
1184
+ REQUIRE_REGEX.lastIndex = 0;
1185
+ while ((match = REQUIRE_REGEX.exec(content)) !== null) paths.push(match[1]);
1186
+ }
1187
+ if (ext === ".py") {
1188
+ PY_RELATIVE_IMPORT.lastIndex = 0;
1189
+ while ((match = PY_RELATIVE_IMPORT.exec(content)) !== null) {
1190
+ paths.push(pythonRelativeToPath(match[1]));
1191
+ }
1172
1192
  }
1173
- EXPORT_FROM_REGEX.lastIndex = 0;
1174
- while ((match = EXPORT_FROM_REGEX.exec(content)) !== null) {
1175
- paths.push(match[1]);
1193
+ if (ext === ".rb") {
1194
+ RB_REQUIRE_RELATIVE.lastIndex = 0;
1195
+ while ((match = RB_REQUIRE_RELATIVE.exec(content)) !== null) {
1196
+ const p = match[1];
1197
+ paths.push(p.startsWith(".") ? p : `./${p}`);
1198
+ }
1176
1199
  }
1177
- REQUIRE_REGEX.lastIndex = 0;
1178
- while ((match = REQUIRE_REGEX.exec(content)) !== null) {
1179
- paths.push(match[1]);
1200
+ if (ext === ".tf") {
1201
+ TF_MODULE_SOURCE.lastIndex = 0;
1202
+ while ((match = TF_MODULE_SOURCE.exec(content)) !== null) {
1203
+ paths.push(match[1]);
1204
+ }
1180
1205
  }
1181
1206
  return [...new Set(paths)];
1182
1207
  }
@@ -1185,7 +1210,11 @@ function resolveLocalImport(fromFile, importPath, pathToId, extensions) {
1185
1210
  const candidates = [
1186
1211
  base,
1187
1212
  ...extensions.map((ext) => base + ext),
1188
- ...extensions.map((ext) => (0, import_node_path.join)(base, "index" + ext))
1213
+ ...extensions.map((ext) => (0, import_node_path.join)(base, "index" + ext)),
1214
+ // Python: package directory with __init__.py
1215
+ (0, import_node_path.join)(base, "__init__.py"),
1216
+ // Terraform: module directory conventionally has main.tf
1217
+ (0, import_node_path.join)(base, "main.tf")
1189
1218
  ];
1190
1219
  for (const candidate of candidates) {
1191
1220
  const id = pathToId.get(candidate);
@@ -1220,7 +1249,7 @@ function analyzeCodebase(rootDir, options) {
1220
1249
  for (const entry of entries) {
1221
1250
  try {
1222
1251
  const content = (0, import_node_fs2.readFileSync)(entry.absolutePath, "utf-8");
1223
- const rawImports = extractImportPaths(content);
1252
+ const rawImports = extractImportPaths(content, entry.ext);
1224
1253
  for (const importPath of rawImports) {
1225
1254
  if (!importPath.startsWith("./") && !importPath.startsWith("../")) continue;
1226
1255
  const resolvedId = resolveLocalImport(
@@ -1494,7 +1523,51 @@ function layoutTree(root) {
1494
1523
  }
1495
1524
 
1496
1525
  // src/commands/map.ts
1497
- var DEFAULT_EXCLUDE = "node_modules,dist,build,.next,.git,out,coverage,.turbo";
1526
+ var DEFAULT_EXCLUDE = [
1527
+ // JS/TS
1528
+ "node_modules",
1529
+ "dist",
1530
+ "build",
1531
+ ".next",
1532
+ "out",
1533
+ "coverage",
1534
+ ".turbo",
1535
+ // Python
1536
+ "__pycache__",
1537
+ ".venv",
1538
+ "venv",
1539
+ "env",
1540
+ ".pytest_cache",
1541
+ "htmlcov",
1542
+ ".mypy_cache",
1543
+ // Go
1544
+ "vendor",
1545
+ // Rust / Java / Maven / Gradle
1546
+ "target",
1547
+ ".gradle",
1548
+ ".m2",
1549
+ // .NET
1550
+ "bin",
1551
+ "obj",
1552
+ // iOS / Swift
1553
+ "Pods",
1554
+ "DerivedData",
1555
+ // Elixir / Phoenix
1556
+ "_build",
1557
+ "deps",
1558
+ // Ruby
1559
+ ".bundle",
1560
+ // Terraform
1561
+ ".terraform",
1562
+ // Elm
1563
+ "elm-stuff",
1564
+ // Generic
1565
+ "tmp",
1566
+ "log",
1567
+ "logs",
1568
+ "temp",
1569
+ ".git"
1570
+ ].join(",");
1498
1571
  var AUTO_THRESHOLD = 80;
1499
1572
  function makeAnalyzeOptions(opts) {
1500
1573
  return {
@@ -1515,20 +1588,135 @@ function tryOpenInVSCode(path) {
1515
1588
  }
1516
1589
  }
1517
1590
  function getFileNodeStyle(ext, fileName) {
1518
- if (fileName.includes(".test.") || fileName.includes(".spec.")) {
1591
+ if (fileName.includes(".test.") || fileName.includes(".spec.") || fileName.endsWith("_test.go") || fileName.endsWith("_test.py") || fileName.startsWith("test_") && ext === ".py") {
1519
1592
  return { fillStyle: "#78350f", strokeStyle: "#d97706" };
1520
1593
  }
1521
- if ([".json", ".yaml", ".yml", ".toml", ".env"].includes(ext)) {
1522
- return { fillStyle: "#1e1b4b", strokeStyle: "#7c3aed" };
1523
- }
1524
1594
  switch (ext) {
1595
+ // ── TypeScript / JavaScript ──────────────────────────────────────────
1525
1596
  case ".tsx":
1526
1597
  case ".jsx":
1527
1598
  return { fillStyle: "#0c4a6e", strokeStyle: "#0ea5e9" };
1599
+ // sky
1528
1600
  case ".ts":
1601
+ case ".mts":
1602
+ case ".cts":
1529
1603
  return { fillStyle: "#1e3a5f", strokeStyle: "#3b82f6" };
1604
+ // blue
1530
1605
  case ".js":
1606
+ case ".mjs":
1607
+ case ".cjs":
1531
1608
  return { fillStyle: "#422006", strokeStyle: "#f59e0b" };
1609
+ // amber
1610
+ // ── Frontend frameworks ──────────────────────────────────────────────
1611
+ case ".vue":
1612
+ return { fillStyle: "#052e16", strokeStyle: "#22c55e" };
1613
+ // green
1614
+ case ".svelte":
1615
+ return { fillStyle: "#431407", strokeStyle: "#f97316" };
1616
+ // orange
1617
+ case ".html":
1618
+ case ".htm":
1619
+ return { fillStyle: "#422006", strokeStyle: "#fb923c" };
1620
+ // orange-light
1621
+ case ".css":
1622
+ case ".scss":
1623
+ case ".sass":
1624
+ case ".less":
1625
+ return { fillStyle: "#500724", strokeStyle: "#ec4899" };
1626
+ // pink
1627
+ // ── Python ───────────────────────────────────────────────────────────
1628
+ case ".py":
1629
+ case ".pyw":
1630
+ return { fillStyle: "#064e3b", strokeStyle: "#10b981" };
1631
+ // emerald
1632
+ // ── Go ───────────────────────────────────────────────────────────────
1633
+ case ".go":
1634
+ return { fillStyle: "#0d3d47", strokeStyle: "#06b6d4" };
1635
+ // cyan
1636
+ // ── Rust ─────────────────────────────────────────────────────────────
1637
+ case ".rs":
1638
+ return { fillStyle: "#431407", strokeStyle: "#ea580c" };
1639
+ // rust-orange
1640
+ // ── Ruby ─────────────────────────────────────────────────────────────
1641
+ case ".rb":
1642
+ case ".rake":
1643
+ case ".gemspec":
1644
+ return { fillStyle: "#450a0a", strokeStyle: "#dc2626" };
1645
+ // red
1646
+ // ── Java / JVM ───────────────────────────────────────────────────────
1647
+ case ".java":
1648
+ return { fillStyle: "#431407", strokeStyle: "#f97316" };
1649
+ // java-orange
1650
+ case ".kt":
1651
+ case ".kts":
1652
+ return { fillStyle: "#2d1b69", strokeStyle: "#8b5cf6" };
1653
+ // kotlin-purple
1654
+ case ".scala":
1655
+ return { fillStyle: "#450a0a", strokeStyle: "#ef4444" };
1656
+ // scala-red
1657
+ case ".groovy":
1658
+ return { fillStyle: "#052e16", strokeStyle: "#4ade80" };
1659
+ // groovy-green
1660
+ // ── .NET ─────────────────────────────────────────────────────────────
1661
+ case ".cs":
1662
+ return { fillStyle: "#312e81", strokeStyle: "#818cf8" };
1663
+ // indigo
1664
+ case ".fs":
1665
+ case ".fsx":
1666
+ return { fillStyle: "#1e3a5f", strokeStyle: "#60a5fa" };
1667
+ // fsharp-blue
1668
+ // ── Swift / Dart ─────────────────────────────────────────────────────
1669
+ case ".swift":
1670
+ return { fillStyle: "#431407", strokeStyle: "#fb923c" };
1671
+ // swift-orange
1672
+ case ".dart":
1673
+ return { fillStyle: "#0c4a6e", strokeStyle: "#38bdf8" };
1674
+ // dart-sky
1675
+ // ── PHP ──────────────────────────────────────────────────────────────
1676
+ case ".php":
1677
+ return { fillStyle: "#2e1065", strokeStyle: "#7c3aed" };
1678
+ // php-violet
1679
+ // ── Infrastructure / IaC ─────────────────────────────────────────────
1680
+ case ".tf":
1681
+ case ".tfvars":
1682
+ case ".hcl":
1683
+ return { fillStyle: "#1e1035", strokeStyle: "#9333ea" };
1684
+ // terraform-purple
1685
+ // ── Shell scripts ────────────────────────────────────────────────────
1686
+ case ".sh":
1687
+ case ".bash":
1688
+ case ".zsh":
1689
+ case ".fish":
1690
+ case ".ps1":
1691
+ case ".psm1":
1692
+ return { fillStyle: "#1a2e05", strokeStyle: "#84cc16" };
1693
+ // lime
1694
+ // ── Data / API ───────────────────────────────────────────────────────
1695
+ case ".sql":
1696
+ return { fillStyle: "#042f2e", strokeStyle: "#0d9488" };
1697
+ // teal
1698
+ case ".graphql":
1699
+ case ".gql":
1700
+ return { fillStyle: "#500724", strokeStyle: "#e879f9" };
1701
+ // fuchsia
1702
+ case ".proto":
1703
+ return { fillStyle: "#0f2744", strokeStyle: "#60a5fa" };
1704
+ // proto-blue
1705
+ // ── Config / data (keep existing purple group) ───────────────────────
1706
+ case ".json":
1707
+ case ".yaml":
1708
+ case ".yml":
1709
+ case ".toml":
1710
+ case ".env":
1711
+ case ".ini":
1712
+ case ".conf":
1713
+ return { fillStyle: "#1e1b4b", strokeStyle: "#7c3aed" };
1714
+ // violet
1715
+ // ── Markup / docs ────────────────────────────────────────────────────
1716
+ case ".md":
1717
+ case ".mdx":
1718
+ return { fillStyle: "#1e293b", strokeStyle: "#94a3b8" };
1719
+ // slate
1532
1720
  default:
1533
1721
  return { fillStyle: "#1e293b", strokeStyle: "#64748b" };
1534
1722
  }
@@ -1640,9 +1828,47 @@ function getDirNodeStyle(dominantExt) {
1640
1828
  case ".jsx":
1641
1829
  return { fillStyle: "#0c3d5e", strokeStyle: "#0ea5e9" };
1642
1830
  case ".ts":
1831
+ case ".mts":
1643
1832
  return { fillStyle: "#1a2f52", strokeStyle: "#3b82f6" };
1644
1833
  case ".js":
1834
+ case ".mjs":
1645
1835
  return { fillStyle: "#3d1f00", strokeStyle: "#f59e0b" };
1836
+ case ".vue":
1837
+ return { fillStyle: "#052e16", strokeStyle: "#22c55e" };
1838
+ case ".svelte":
1839
+ return { fillStyle: "#3d1f00", strokeStyle: "#f97316" };
1840
+ case ".py":
1841
+ return { fillStyle: "#052e1e", strokeStyle: "#10b981" };
1842
+ case ".go":
1843
+ return { fillStyle: "#0d3340", strokeStyle: "#06b6d4" };
1844
+ case ".rs":
1845
+ return { fillStyle: "#3d1f00", strokeStyle: "#ea580c" };
1846
+ case ".rb":
1847
+ return { fillStyle: "#3d0000", strokeStyle: "#dc2626" };
1848
+ case ".java":
1849
+ return { fillStyle: "#3d1f00", strokeStyle: "#f97316" };
1850
+ case ".kt":
1851
+ case ".kts":
1852
+ return { fillStyle: "#1e0d4a", strokeStyle: "#8b5cf6" };
1853
+ case ".cs":
1854
+ return { fillStyle: "#1e1b4b", strokeStyle: "#818cf8" };
1855
+ case ".swift":
1856
+ return { fillStyle: "#3d1f00", strokeStyle: "#fb923c" };
1857
+ case ".php":
1858
+ return { fillStyle: "#1e0063", strokeStyle: "#7c3aed" };
1859
+ case ".tf":
1860
+ case ".tfvars":
1861
+ case ".hcl":
1862
+ return { fillStyle: "#1e1035", strokeStyle: "#9333ea" };
1863
+ case ".sh":
1864
+ case ".bash":
1865
+ case ".zsh":
1866
+ return { fillStyle: "#1a2e05", strokeStyle: "#84cc16" };
1867
+ case ".sql":
1868
+ return { fillStyle: "#042f2e", strokeStyle: "#0d9488" };
1869
+ case ".graphql":
1870
+ case ".gql":
1871
+ return { fillStyle: "#3d0024", strokeStyle: "#e879f9" };
1646
1872
  default:
1647
1873
  return { fillStyle: "#1a2040", strokeStyle: "#6366f1" };
1648
1874
  }
@@ -1786,7 +2012,11 @@ function runSplitMode(targetDir, analyzeOptions, outputDir, drawEdges) {
1786
2012
  function registerMapCommand(program2) {
1787
2013
  program2.command("map [path]").description(
1788
2014
  "Analyze a codebase and generate a .drawit map (auto-scales: dirs mode for large repos)"
1789
- ).option("--output <file>", "Output file path (default: <dirname>-map.drawit)").option("--depth <n>", "Max directory depth to scan", "4").option("--include <pattern>", "File extensions to include", "**/*.{ts,tsx,js,jsx}").option("--exclude <patterns>", "Comma-separated names to exclude", DEFAULT_EXCLUDE).option("--no-edges", "Skip import dependency edges (files mode only)").option("--open", "Open generated file(s) in VS Code").option(
2015
+ ).option("--output <file>", "Output file path (default: <dirname>-map.drawit)").option("--depth <n>", "Max directory depth to scan", "4").option(
2016
+ "--include <pattern>",
2017
+ "File extensions to include",
2018
+ "**/*.{ts,tsx,js,jsx,mjs,cjs,vue,svelte,py,go,rb,rs,java,kt,kts,cs,swift,dart,php,tf,tfvars,hcl,sh,bash,zsh,sql,graphql,gql,proto,html,css,scss,sass,less,md,mdx}"
2019
+ ).option("--exclude <patterns>", "Comma-separated names to exclude", DEFAULT_EXCLUDE).option("--no-edges", "Skip import dependency edges (files mode only)").option("--open", "Open generated file(s) in VS Code").option(
1790
2020
  "--mode <auto|files|dirs>",
1791
2021
  "Map mode: auto detects by file count, files=import graph, dirs=directory tree",
1792
2022
  "auto"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chamuka-labs/drawit-cli",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "CLI tool for validating, inspecting, and exporting DrawIt diagram files",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "export"
27
27
  ],
28
28
  "author": "Chamuka",
29
- "license": "Commercial",
29
+ "license": "Proprietary",
30
30
  "publishConfig": {
31
31
  "access": "public"
32
32
  },