cg-code-graph 0.10.1__py3-none-any.whl

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 (174) hide show
  1. cg_code_graph-0.10.1.dist-info/METADATA +678 -0
  2. cg_code_graph-0.10.1.dist-info/RECORD +174 -0
  3. cg_code_graph-0.10.1.dist-info/WHEEL +5 -0
  4. cg_code_graph-0.10.1.dist-info/entry_points.txt +3 -0
  5. cg_code_graph-0.10.1.dist-info/licenses/LICENSE +21 -0
  6. cg_code_graph-0.10.1.dist-info/top_level.txt +1 -0
  7. codegraph/__init__.py +2 -0
  8. codegraph/aitools.py +129 -0
  9. codegraph/apps.py +76 -0
  10. codegraph/blindspots.py +428 -0
  11. codegraph/bridges.py +1701 -0
  12. codegraph/cli.py +725 -0
  13. codegraph/concepts.py +362 -0
  14. codegraph/config.py +559 -0
  15. codegraph/core/__init__.py +0 -0
  16. codegraph/core/cache.py +375 -0
  17. codegraph/core/detect.py +80 -0
  18. codegraph/core/extractors.py +187 -0
  19. codegraph/core/fsutil.py +61 -0
  20. codegraph/core/generated.py +575 -0
  21. codegraph/core/model.py +174 -0
  22. codegraph/core/paths.py +175 -0
  23. codegraph/core/plugin.py +160 -0
  24. codegraph/core/store.py +80 -0
  25. codegraph/core/syntax_errors.py +132 -0
  26. codegraph/coverage.py +928 -0
  27. codegraph/doctor.py +453 -0
  28. codegraph/external.py +613 -0
  29. codegraph/indexer.py +336 -0
  30. codegraph/link.py +434 -0
  31. codegraph/lint_async.py +524 -0
  32. codegraph/mcp_server.py +1303 -0
  33. codegraph/parity.py +473 -0
  34. codegraph/parity_structure.py +307 -0
  35. codegraph/payload.py +321 -0
  36. codegraph/plans.py +1285 -0
  37. codegraph/platform_scan.py +643 -0
  38. codegraph/platforms.py +1369 -0
  39. codegraph/plugins/__init__.py +0 -0
  40. codegraph/plugins/cfamily/__init__.py +0 -0
  41. codegraph/plugins/cfamily/plugin.py +930 -0
  42. codegraph/plugins/cfamily/syntax.py +881 -0
  43. codegraph/plugins/dart/__init__.py +0 -0
  44. codegraph/plugins/dart/bridges.py +345 -0
  45. codegraph/plugins/dart/extractor/bin/extract.dart +717 -0
  46. codegraph/plugins/dart/extractor/pubspec.lock +149 -0
  47. codegraph/plugins/dart/extractor/pubspec.yaml +7 -0
  48. codegraph/plugins/dart/http.py +904 -0
  49. codegraph/plugins/dart/models.py +308 -0
  50. codegraph/plugins/dart/plugin.py +625 -0
  51. codegraph/plugins/dart/program.py +907 -0
  52. codegraph/plugins/django/__init__.py +0 -0
  53. codegraph/plugins/django/extras.py +378 -0
  54. codegraph/plugins/django/models.py +508 -0
  55. codegraph/plugins/django/plugin.py +728 -0
  56. codegraph/plugins/django/schemas.py +339 -0
  57. codegraph/plugins/django/shapes.py +216 -0
  58. codegraph/plugins/django/urls.py +603 -0
  59. codegraph/plugins/express/__init__.py +0 -0
  60. codegraph/plugins/express/plugin.py +428 -0
  61. codegraph/plugins/flutter/__init__.py +0 -0
  62. codegraph/plugins/flutter/plugin.py +538 -0
  63. codegraph/plugins/kotlin/__init__.py +0 -0
  64. codegraph/plugins/kotlin/exact.py +457 -0
  65. codegraph/plugins/kotlin/plugin.py +1961 -0
  66. codegraph/plugins/kotlin/reparse.py +234 -0
  67. codegraph/plugins/laravel/__init__.py +0 -0
  68. codegraph/plugins/laravel/broadcast.py +351 -0
  69. codegraph/plugins/laravel/plugin.py +863 -0
  70. codegraph/plugins/laravel/tests.py +262 -0
  71. codegraph/plugins/laravel/values.py +728 -0
  72. codegraph/plugins/native/__init__.py +0 -0
  73. codegraph/plugins/native/gates.py +286 -0
  74. codegraph/plugins/native/runner.py +183 -0
  75. codegraph/plugins/native/scipread.py +194 -0
  76. codegraph/plugins/native/ts.py +54 -0
  77. codegraph/plugins/nest/__init__.py +0 -0
  78. codegraph/plugins/nest/plugin.py +654 -0
  79. codegraph/plugins/nextjs/__init__.py +0 -0
  80. codegraph/plugins/nextjs/plugin.py +336 -0
  81. codegraph/plugins/nuxt/__init__.py +0 -0
  82. codegraph/plugins/nuxt/plugin.py +308 -0
  83. codegraph/plugins/php/__init__.py +0 -0
  84. codegraph/plugins/php/extractor/composer.json +5 -0
  85. codegraph/plugins/php/extractor/composer.lock +76 -0
  86. codegraph/plugins/php/extractor/extract.php +743 -0
  87. codegraph/plugins/php/gating.py +573 -0
  88. codegraph/plugins/php/plugin.py +668 -0
  89. codegraph/plugins/php/strings.py +197 -0
  90. codegraph/plugins/python/__init__.py +0 -0
  91. codegraph/plugins/python/aitools.py +664 -0
  92. codegraph/plugins/python/external.py +245 -0
  93. codegraph/plugins/python/fields.py +107 -0
  94. codegraph/plugins/python/plugin.py +1733 -0
  95. codegraph/plugins/python/refs.py +485 -0
  96. codegraph/plugins/python/roots.py +412 -0
  97. codegraph/plugins/python/socketio.py +210 -0
  98. codegraph/plugins/python/subproc.py +864 -0
  99. codegraph/plugins/python/tests.py +1040 -0
  100. codegraph/plugins/python/values.py +179 -0
  101. codegraph/plugins/pyweb/__init__.py +0 -0
  102. codegraph/plugins/pyweb/plugin.py +1334 -0
  103. codegraph/plugins/pyweb/values.py +68 -0
  104. codegraph/plugins/rust/__init__.py +0 -0
  105. codegraph/plugins/rust/cargo.py +226 -0
  106. codegraph/plugins/rust/plugin.py +980 -0
  107. codegraph/plugins/rust/syntax.py +678 -0
  108. codegraph/plugins/scip/__init__.py +0 -0
  109. codegraph/plugins/scip/importer.py +129 -0
  110. codegraph/plugins/scip/scip.proto +962 -0
  111. codegraph/plugins/scip/scip_pb2.py +97 -0
  112. codegraph/plugins/stubs/__init__.py +0 -0
  113. codegraph/plugins/stubs/plugins.py +38 -0
  114. codegraph/plugins/swift/__init__.py +0 -0
  115. codegraph/plugins/swift/baseurl.py +109 -0
  116. codegraph/plugins/swift/exact.py +415 -0
  117. codegraph/plugins/swift/indexstore.py +209 -0
  118. codegraph/plugins/swift/packages.py +174 -0
  119. codegraph/plugins/swift/plugin.py +2890 -0
  120. codegraph/plugins/ts/__init__.py +0 -0
  121. codegraph/plugins/ts/baseurl.py +185 -0
  122. codegraph/plugins/ts/extractor/extract.mjs +2652 -0
  123. codegraph/plugins/ts/extractor/fw.mjs +685 -0
  124. codegraph/plugins/ts/extractor/package-lock.json +205 -0
  125. codegraph/plugins/ts/extractor/package.json +9 -0
  126. codegraph/plugins/ts/plugin.py +480 -0
  127. codegraph/plugins/tsweb/__init__.py +0 -0
  128. codegraph/plugins/tsweb/common.py +290 -0
  129. codegraph/plugins/tsweb/data.py +276 -0
  130. codegraph/presets/__init__.py +146 -0
  131. codegraph/presets/c_cpp.yaml +9 -0
  132. codegraph/presets/common.yaml +66 -0
  133. codegraph/presets/dart.yaml +9 -0
  134. codegraph/presets/django-ninja.yaml +15 -0
  135. codegraph/presets/django.yaml +25 -0
  136. codegraph/presets/djangorestframework.yaml +17 -0
  137. codegraph/presets/express.yaml +17 -0
  138. codegraph/presets/kotlin.yaml +11 -0
  139. codegraph/presets/laravel.yaml +40 -0
  140. codegraph/presets/nest.yaml +11 -0
  141. codegraph/presets/nextjs.yaml +15 -0
  142. codegraph/presets/nuxt.yaml +9 -0
  143. codegraph/presets/php.yaml +5 -0
  144. codegraph/presets/python.yaml +10 -0
  145. codegraph/presets/rust.yaml +5 -0
  146. codegraph/presets/swift.yaml +10 -0
  147. codegraph/presets/typescript.yaml +13 -0
  148. codegraph/process_runs.py +328 -0
  149. codegraph/protocols/__init__.py +299 -0
  150. codegraph/protocols/builtin.py +67 -0
  151. codegraph/protocols/matchers.py +144 -0
  152. codegraph/protocols/view.py +334 -0
  153. codegraph/query.py +2089 -0
  154. codegraph/realtime.py +260 -0
  155. codegraph/roundtrip.py +346 -0
  156. codegraph/routes.py +442 -0
  157. codegraph/starters.py +218 -0
  158. codegraph/tests_index.py +117 -0
  159. codegraph/viz/__init__.py +0 -0
  160. codegraph/viz/graph.py +369 -0
  161. codegraph/viz/server.py +198 -0
  162. codegraph/viz/static/app.css +148 -0
  163. codegraph/viz/static/app.js +1082 -0
  164. codegraph/viz/static/index.html +81 -0
  165. codegraph/viz/static/layered.js +237 -0
  166. codegraph/viz/static/vendor/VERSIONS.txt +4 -0
  167. codegraph/viz/static/vendor/cose-base.js +3214 -0
  168. codegraph/viz/static/vendor/cytoscape-fcose.js +1549 -0
  169. codegraph/viz/static/vendor/cytoscape.min.js +31 -0
  170. codegraph/viz/static/vendor/layout-base.js +5230 -0
  171. codegraph/viz/tools/package-lock.json +303 -0
  172. codegraph/viz/tools/package.json +7 -0
  173. codegraph/viz/tools/shoot.mjs +165 -0
  174. codegraph/xcode.py +251 -0
File without changes
@@ -0,0 +1,185 @@
1
+ """Values of configured base URLs, so client paths built on them can be matched to backend routes.
2
+
3
+ The extractor turns runtime config / env reads into placeholders: `useRuntimeConfig().public.apiBase` ->
4
+ `{runtimeConfig.apiBase}`, `process.env.API_URL` / `import.meta.env.VITE_API_URL` -> `{env.API_URL}`. Here
5
+ their values are looked up, in this order:
6
+ 1. env files that configure a real run (.env, .env.local, .env.development, .env.development.local); for
7
+ runtime config also Nuxt's override variable NUXT_PUBLIC_<KEY> / NUXT_<KEY>;
8
+ 2. the default written in code: nuxt.config runtimeConfig (`apiBase: process.env.API_URL || 'http://...'`) or
9
+ an in-code `process.env.X || '...'` (recorded by the extractor);
10
+ 3. example env files (.env.example, .env.sample, .env.dist).
11
+ Only the path part matters for matching (`http://localhost:8000/api/v1` -> `/api/v1`)."""
12
+ from __future__ import annotations
13
+
14
+ import re
15
+ from pathlib import Path
16
+ from urllib.parse import urlsplit
17
+
18
+ REAL_ENV = (".env", ".env.local", ".env.development", ".env.development.local", ".env.dev")
19
+ EXAMPLE_ENV = (".env.example", ".env.sample", ".env.dist", ".env.template", ".env.local.example", ".env.development.example")
20
+ CONFIG_FILES = ("nuxt.config.ts", "nuxt.config.js", "nuxt.config.mjs", "app.config.ts")
21
+ STR = r"""(?:'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)"|`([^`$]*)`)"""
22
+ API_NAME = re.compile(r"api|backend|server|base_?url|baseurl|endpoint", re.I)
23
+
24
+
25
+ def parse_env(text: str) -> dict:
26
+ out = {}
27
+ for line in text.splitlines():
28
+ m = re.match(r"\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$", line)
29
+ if not m:
30
+ continue
31
+ v = m.group(2)
32
+ if v[:1] in "'\"" and v[-1:] == v[:1] and len(v) > 1:
33
+ v = v[1:-1]
34
+ else:
35
+ v = re.sub(r"\s+#.*$", "", v)
36
+ out[m.group(1)] = v
37
+ return out
38
+
39
+
40
+ def _block(text: str, start: int) -> str | None:
41
+ """Text of the balanced {...} block whose `{` is at or after start."""
42
+ i = text.find("{", start)
43
+ if i < 0:
44
+ return None
45
+ depth, j, q = 0, i, None
46
+ while j < len(text):
47
+ c = text[j]
48
+ if q:
49
+ if c == "\\":
50
+ j += 2
51
+ continue
52
+ if c == q:
53
+ q = None
54
+ elif c in "'\"`":
55
+ q = c
56
+ elif c == "{":
57
+ depth += 1
58
+ elif c == "}":
59
+ depth -= 1
60
+ if depth == 0:
61
+ return text[i + 1:j]
62
+ j += 1
63
+ return None
64
+
65
+
66
+ def _entries(block: str) -> list[tuple[str, str]]:
67
+ """Top-level `key: expr` entries of an object literal body."""
68
+ out, depth, q, cur = [], 0, None, ""
69
+ for c in block + ",":
70
+ if q:
71
+ cur += c
72
+ if c == q:
73
+ q = None
74
+ continue
75
+ if c in "'\"`":
76
+ q = c
77
+ elif c in "{[(":
78
+ depth += 1
79
+ elif c in "}])":
80
+ depth -= 1
81
+ if c == "," and depth == 0:
82
+ m = re.match(r"\s*(?://[^\n]*\n\s*)*['\"]?([A-Za-z_$][\w$-]*)['\"]?\s*:\s*(.*)$", cur, re.S)
83
+ if m:
84
+ out.append((m.group(1), m.group(2).strip()))
85
+ cur = ""
86
+ continue
87
+ cur += c
88
+ return out
89
+
90
+
91
+ def runtime_config_defaults(root: Path) -> dict:
92
+ """{key: (env names read, literal default, file:line)} for nuxt.config runtimeConfig (public and private)."""
93
+ out = {}
94
+ for name in CONFIG_FILES:
95
+ f = root / name
96
+ if not f.exists():
97
+ continue
98
+ text = f.read_text(errors="replace")
99
+ m = re.search(r"\bruntimeConfig\s*:", text)
100
+ if not m:
101
+ continue
102
+ body = _block(text, m.end())
103
+ if body is None:
104
+ continue
105
+ body_at = text.find("{", m.end()) + 1
106
+ for key, expr in _entries(body):
107
+ if key == "public":
108
+ pm = re.search(r"\bpublic\s*:", body)
109
+ sub = _block(body, pm.end()) if pm else None
110
+ items = _entries(sub) if sub else []
111
+ else:
112
+ items = [(key, expr)]
113
+ for k, e in items:
114
+ envs = re.findall(r"(?:process\.env|import\.meta\.env)\.([A-Za-z_][A-Za-z0-9_]*)", e)
115
+ envs += re.findall(r"(?:process\.env|import\.meta\.env)\[['\"]([A-Za-z_][A-Za-z0-9_]*)['\"]\]", e)
116
+ found = [m.group(1) or m.group(2) or m.group(3) or "" for m in re.finditer(STR, e)]
117
+ lits = [x for x in found if x and not x.startswith(("NUXT_", "VITE_"))]
118
+ if not lits and "" in found:
119
+ lits = [""] # `process.env.X || ''`: unset unless the env sets it
120
+ pos = body.find(f"{k}") + body_at
121
+ out.setdefault(k, (envs, lits[0] if lits else None, f"{name}:{text.count(chr(10), 0, pos) + 1}"))
122
+ return out
123
+
124
+
125
+ def snake_upper(k: str) -> str:
126
+ return re.sub(r"(?<=[a-z0-9])([A-Z])", r"_\1", k).upper()
127
+
128
+
129
+ class ConfigValues:
130
+ def __init__(self, root: Path, code_defaults: dict | None = None):
131
+ root = Path(root)
132
+ self.real, self.example = {}, {}
133
+ for names, dst in ((REAL_ENV, self.real), (EXAMPLE_ENV, self.example)):
134
+ for n in names:
135
+ f = root / n
136
+ if f.is_file():
137
+ for k, v in parse_env(f.read_text(errors="replace")).items():
138
+ dst.setdefault(k, (v, n))
139
+ self.rc = runtime_config_defaults(root)
140
+ self.code_defaults = code_defaults or {}
141
+
142
+ def lookup(self, ph: str) -> tuple[str, str] | None:
143
+ """'runtimeConfig.apiBase' | 'env.API_URL' -> (value, where from) or None."""
144
+ kind, _, key = ph.partition(".")
145
+ if kind == "env":
146
+ for src in (self.real,):
147
+ if key in src:
148
+ return src[key][0], src[key][1]
149
+ if ph in self.code_defaults:
150
+ return self.code_defaults[ph], "default in code"
151
+ if key in self.example:
152
+ return self.example[key][0], self.example[key][1]
153
+ return None
154
+ if kind != "runtimeConfig":
155
+ return None
156
+ envs, lit, at = self.rc.get(key, ([], None, None))
157
+ overrides = [f"NUXT_PUBLIC_{snake_upper(key)}", f"NUXT_{snake_upper(key)}"] + envs
158
+ for e in overrides:
159
+ if e in self.real:
160
+ return self.real[e][0], self.real[e][1]
161
+ if lit is not None:
162
+ return lit, at
163
+ if ph in self.code_defaults:
164
+ return self.code_defaults[ph], "default in code"
165
+ for e in overrides:
166
+ if e in self.example:
167
+ return self.example[e][0], self.example[e][1]
168
+ return None
169
+
170
+
171
+ def base_path(value: str) -> str | None:
172
+ """'http://localhost:8000/api/v1/' -> '/api/v1'; '/api' -> '/api'; 'http://host' -> ''; anything else -> None."""
173
+ v = (value or "").strip()
174
+ if re.match(r"^[a-zA-Z][a-zA-Z0-9+.-]*://", v):
175
+ p = urlsplit(v).path
176
+ elif v.startswith("/"):
177
+ p = v.split("?")[0]
178
+ else:
179
+ return None
180
+ p = re.sub(r"/{2,}", "/", p).rstrip("/")
181
+ return p
182
+
183
+
184
+ def is_config_ph(origin: str | None) -> bool:
185
+ return bool(origin) and bool(re.fullmatch(r"\{(runtimeConfig|env)\.[^{}]+\}", origin))