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.
- cg_code_graph-0.10.1.dist-info/METADATA +678 -0
- cg_code_graph-0.10.1.dist-info/RECORD +174 -0
- cg_code_graph-0.10.1.dist-info/WHEEL +5 -0
- cg_code_graph-0.10.1.dist-info/entry_points.txt +3 -0
- cg_code_graph-0.10.1.dist-info/licenses/LICENSE +21 -0
- cg_code_graph-0.10.1.dist-info/top_level.txt +1 -0
- codegraph/__init__.py +2 -0
- codegraph/aitools.py +129 -0
- codegraph/apps.py +76 -0
- codegraph/blindspots.py +428 -0
- codegraph/bridges.py +1701 -0
- codegraph/cli.py +725 -0
- codegraph/concepts.py +362 -0
- codegraph/config.py +559 -0
- codegraph/core/__init__.py +0 -0
- codegraph/core/cache.py +375 -0
- codegraph/core/detect.py +80 -0
- codegraph/core/extractors.py +187 -0
- codegraph/core/fsutil.py +61 -0
- codegraph/core/generated.py +575 -0
- codegraph/core/model.py +174 -0
- codegraph/core/paths.py +175 -0
- codegraph/core/plugin.py +160 -0
- codegraph/core/store.py +80 -0
- codegraph/core/syntax_errors.py +132 -0
- codegraph/coverage.py +928 -0
- codegraph/doctor.py +453 -0
- codegraph/external.py +613 -0
- codegraph/indexer.py +336 -0
- codegraph/link.py +434 -0
- codegraph/lint_async.py +524 -0
- codegraph/mcp_server.py +1303 -0
- codegraph/parity.py +473 -0
- codegraph/parity_structure.py +307 -0
- codegraph/payload.py +321 -0
- codegraph/plans.py +1285 -0
- codegraph/platform_scan.py +643 -0
- codegraph/platforms.py +1369 -0
- codegraph/plugins/__init__.py +0 -0
- codegraph/plugins/cfamily/__init__.py +0 -0
- codegraph/plugins/cfamily/plugin.py +930 -0
- codegraph/plugins/cfamily/syntax.py +881 -0
- codegraph/plugins/dart/__init__.py +0 -0
- codegraph/plugins/dart/bridges.py +345 -0
- codegraph/plugins/dart/extractor/bin/extract.dart +717 -0
- codegraph/plugins/dart/extractor/pubspec.lock +149 -0
- codegraph/plugins/dart/extractor/pubspec.yaml +7 -0
- codegraph/plugins/dart/http.py +904 -0
- codegraph/plugins/dart/models.py +308 -0
- codegraph/plugins/dart/plugin.py +625 -0
- codegraph/plugins/dart/program.py +907 -0
- codegraph/plugins/django/__init__.py +0 -0
- codegraph/plugins/django/extras.py +378 -0
- codegraph/plugins/django/models.py +508 -0
- codegraph/plugins/django/plugin.py +728 -0
- codegraph/plugins/django/schemas.py +339 -0
- codegraph/plugins/django/shapes.py +216 -0
- codegraph/plugins/django/urls.py +603 -0
- codegraph/plugins/express/__init__.py +0 -0
- codegraph/plugins/express/plugin.py +428 -0
- codegraph/plugins/flutter/__init__.py +0 -0
- codegraph/plugins/flutter/plugin.py +538 -0
- codegraph/plugins/kotlin/__init__.py +0 -0
- codegraph/plugins/kotlin/exact.py +457 -0
- codegraph/plugins/kotlin/plugin.py +1961 -0
- codegraph/plugins/kotlin/reparse.py +234 -0
- codegraph/plugins/laravel/__init__.py +0 -0
- codegraph/plugins/laravel/broadcast.py +351 -0
- codegraph/plugins/laravel/plugin.py +863 -0
- codegraph/plugins/laravel/tests.py +262 -0
- codegraph/plugins/laravel/values.py +728 -0
- codegraph/plugins/native/__init__.py +0 -0
- codegraph/plugins/native/gates.py +286 -0
- codegraph/plugins/native/runner.py +183 -0
- codegraph/plugins/native/scipread.py +194 -0
- codegraph/plugins/native/ts.py +54 -0
- codegraph/plugins/nest/__init__.py +0 -0
- codegraph/plugins/nest/plugin.py +654 -0
- codegraph/plugins/nextjs/__init__.py +0 -0
- codegraph/plugins/nextjs/plugin.py +336 -0
- codegraph/plugins/nuxt/__init__.py +0 -0
- codegraph/plugins/nuxt/plugin.py +308 -0
- codegraph/plugins/php/__init__.py +0 -0
- codegraph/plugins/php/extractor/composer.json +5 -0
- codegraph/plugins/php/extractor/composer.lock +76 -0
- codegraph/plugins/php/extractor/extract.php +743 -0
- codegraph/plugins/php/gating.py +573 -0
- codegraph/plugins/php/plugin.py +668 -0
- codegraph/plugins/php/strings.py +197 -0
- codegraph/plugins/python/__init__.py +0 -0
- codegraph/plugins/python/aitools.py +664 -0
- codegraph/plugins/python/external.py +245 -0
- codegraph/plugins/python/fields.py +107 -0
- codegraph/plugins/python/plugin.py +1733 -0
- codegraph/plugins/python/refs.py +485 -0
- codegraph/plugins/python/roots.py +412 -0
- codegraph/plugins/python/socketio.py +210 -0
- codegraph/plugins/python/subproc.py +864 -0
- codegraph/plugins/python/tests.py +1040 -0
- codegraph/plugins/python/values.py +179 -0
- codegraph/plugins/pyweb/__init__.py +0 -0
- codegraph/plugins/pyweb/plugin.py +1334 -0
- codegraph/plugins/pyweb/values.py +68 -0
- codegraph/plugins/rust/__init__.py +0 -0
- codegraph/plugins/rust/cargo.py +226 -0
- codegraph/plugins/rust/plugin.py +980 -0
- codegraph/plugins/rust/syntax.py +678 -0
- codegraph/plugins/scip/__init__.py +0 -0
- codegraph/plugins/scip/importer.py +129 -0
- codegraph/plugins/scip/scip.proto +962 -0
- codegraph/plugins/scip/scip_pb2.py +97 -0
- codegraph/plugins/stubs/__init__.py +0 -0
- codegraph/plugins/stubs/plugins.py +38 -0
- codegraph/plugins/swift/__init__.py +0 -0
- codegraph/plugins/swift/baseurl.py +109 -0
- codegraph/plugins/swift/exact.py +415 -0
- codegraph/plugins/swift/indexstore.py +209 -0
- codegraph/plugins/swift/packages.py +174 -0
- codegraph/plugins/swift/plugin.py +2890 -0
- codegraph/plugins/ts/__init__.py +0 -0
- codegraph/plugins/ts/baseurl.py +185 -0
- codegraph/plugins/ts/extractor/extract.mjs +2652 -0
- codegraph/plugins/ts/extractor/fw.mjs +685 -0
- codegraph/plugins/ts/extractor/package-lock.json +205 -0
- codegraph/plugins/ts/extractor/package.json +9 -0
- codegraph/plugins/ts/plugin.py +480 -0
- codegraph/plugins/tsweb/__init__.py +0 -0
- codegraph/plugins/tsweb/common.py +290 -0
- codegraph/plugins/tsweb/data.py +276 -0
- codegraph/presets/__init__.py +146 -0
- codegraph/presets/c_cpp.yaml +9 -0
- codegraph/presets/common.yaml +66 -0
- codegraph/presets/dart.yaml +9 -0
- codegraph/presets/django-ninja.yaml +15 -0
- codegraph/presets/django.yaml +25 -0
- codegraph/presets/djangorestframework.yaml +17 -0
- codegraph/presets/express.yaml +17 -0
- codegraph/presets/kotlin.yaml +11 -0
- codegraph/presets/laravel.yaml +40 -0
- codegraph/presets/nest.yaml +11 -0
- codegraph/presets/nextjs.yaml +15 -0
- codegraph/presets/nuxt.yaml +9 -0
- codegraph/presets/php.yaml +5 -0
- codegraph/presets/python.yaml +10 -0
- codegraph/presets/rust.yaml +5 -0
- codegraph/presets/swift.yaml +10 -0
- codegraph/presets/typescript.yaml +13 -0
- codegraph/process_runs.py +328 -0
- codegraph/protocols/__init__.py +299 -0
- codegraph/protocols/builtin.py +67 -0
- codegraph/protocols/matchers.py +144 -0
- codegraph/protocols/view.py +334 -0
- codegraph/query.py +2089 -0
- codegraph/realtime.py +260 -0
- codegraph/roundtrip.py +346 -0
- codegraph/routes.py +442 -0
- codegraph/starters.py +218 -0
- codegraph/tests_index.py +117 -0
- codegraph/viz/__init__.py +0 -0
- codegraph/viz/graph.py +369 -0
- codegraph/viz/server.py +198 -0
- codegraph/viz/static/app.css +148 -0
- codegraph/viz/static/app.js +1082 -0
- codegraph/viz/static/index.html +81 -0
- codegraph/viz/static/layered.js +237 -0
- codegraph/viz/static/vendor/VERSIONS.txt +4 -0
- codegraph/viz/static/vendor/cose-base.js +3214 -0
- codegraph/viz/static/vendor/cytoscape-fcose.js +1549 -0
- codegraph/viz/static/vendor/cytoscape.min.js +31 -0
- codegraph/viz/static/vendor/layout-base.js +5230 -0
- codegraph/viz/tools/package-lock.json +303 -0
- codegraph/viz/tools/package.json +7 -0
- codegraph/viz/tools/shoot.mjs +165 -0
- 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))
|