@neat.is/core 0.6.2-dev.20260723 → 0.6.2

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.
@@ -4977,7 +4977,7 @@ function keywordArrayStrings(argsNode, key) {
4977
4977
  }
4978
4978
  return [];
4979
4979
  }
4980
- function collectApiRouterPrefixes(root) {
4980
+ function collectPythonRouterPrefixes(root) {
4981
4981
  const prefixes = /* @__PURE__ */ new Map();
4982
4982
  walk(root, (node) => {
4983
4983
  if (node.type !== "assignment") return;
@@ -4986,7 +4986,8 @@ function collectApiRouterPrefixes(root) {
4986
4986
  const fn = right.childForFieldName("function");
4987
4987
  if (!fn) return;
4988
4988
  const ctor = fn.type === "attribute" ? fn.childForFieldName("attribute")?.text : fn.text;
4989
- if (ctor !== "APIRouter") return;
4989
+ const prefixKey = ctor === "APIRouter" ? "prefix" : ctor === "Blueprint" ? "url_prefix" : null;
4990
+ if (!prefixKey) return;
4990
4991
  const left = node.childForFieldName("left");
4991
4992
  if (!left || left.type !== "identifier") return;
4992
4993
  const args = right.childForFieldName("arguments");
@@ -4994,7 +4995,7 @@ function collectApiRouterPrefixes(root) {
4994
4995
  for (let i = 0; i < args.namedChildCount; i++) {
4995
4996
  const arg = args.namedChild(i);
4996
4997
  if (arg?.type !== "keyword_argument") continue;
4997
- if (arg.childForFieldName("name")?.text !== "prefix") continue;
4998
+ if (arg.childForFieldName("name")?.text !== prefixKey) continue;
4998
4999
  const val = arg.childForFieldName("value");
4999
5000
  const p = val ? pyStaticStringText(val) : null;
5000
5001
  if (p !== null) prefixes.set(left.text, p);
@@ -5002,9 +5003,9 @@ function collectApiRouterPrefixes(root) {
5002
5003
  });
5003
5004
  return prefixes;
5004
5005
  }
5005
- function fastapiRoutesFromSource(source, parser) {
5006
+ function pythonRoutesFromSource(source, parser, framework) {
5006
5007
  const tree = parseSource2(parser, source);
5007
- const prefixes = collectApiRouterPrefixes(tree.rootNode);
5008
+ const prefixes = collectPythonRouterPrefixes(tree.rootNode);
5008
5009
  const out = [];
5009
5010
  walk(tree.rootNode, (node) => {
5010
5011
  if (node.type !== "decorator") return;
@@ -5015,7 +5016,9 @@ function fastapiRoutesFromSource(source, parser) {
5015
5016
  const method = fn.childForFieldName("attribute")?.text?.toLowerCase();
5016
5017
  if (!method) return;
5017
5018
  const isVerb = FASTAPI_METHODS.has(method);
5018
- if (!isVerb && method !== "api_route") return;
5019
+ const isFlaskRoute = method === "route";
5020
+ const isApiRoute = method === "api_route";
5021
+ if (!isVerb && !isFlaskRoute && !isApiRoute) return;
5019
5022
  const args = call.childForFieldName("arguments");
5020
5023
  const first = args?.namedChild(0);
5021
5024
  if (!first || first.type !== "string") return;
@@ -5026,17 +5029,41 @@ function fastapiRoutesFromSource(source, parser) {
5026
5029
  const pathTemplate = canonicalizeTemplate(prefix + rawPath);
5027
5030
  const line = node.startPosition.row + 1;
5028
5031
  if (isVerb) {
5029
- out.push({ method: method.toUpperCase(), pathTemplate, line, framework: "fastapi" });
5032
+ out.push({ method: method.toUpperCase(), pathTemplate, line, framework });
5030
5033
  return;
5031
5034
  }
5032
5035
  const methods = keywordArrayStrings(args, "methods");
5033
- const list = methods.length > 0 ? methods : ["ALL"];
5036
+ const list = methods.length > 0 ? methods : isFlaskRoute ? ["GET"] : ["ALL"];
5034
5037
  for (const m of list) {
5038
+ out.push({ method: m === "ALL" ? "ALL" : m.toUpperCase(), pathTemplate, line, framework });
5039
+ }
5040
+ });
5041
+ return out;
5042
+ }
5043
+ function djangoRoutesFromSource(source, parser) {
5044
+ const tree = parseSource2(parser, source);
5045
+ const out = [];
5046
+ walk(tree.rootNode, (node) => {
5047
+ if (node.type !== "assignment") return;
5048
+ if (node.childForFieldName("left")?.text !== "urlpatterns") return;
5049
+ const list = node.childForFieldName("right");
5050
+ if (!list || list.type !== "list") return;
5051
+ for (let i = 0; i < list.namedChildCount; i++) {
5052
+ const el = list.namedChild(i);
5053
+ if (el?.type !== "call") continue;
5054
+ if (el.childForFieldName("function")?.text !== "path") continue;
5055
+ const args = el.childForFieldName("arguments");
5056
+ const first = args?.namedChild(0);
5057
+ if (first?.type !== "string") continue;
5058
+ const raw = pyStaticStringText(first);
5059
+ if (raw === null) continue;
5060
+ const second = args?.namedChild(1);
5061
+ if (second?.type === "call" && second.childForFieldName("function")?.text === "include") continue;
5035
5062
  out.push({
5036
- method: m === "ALL" ? "ALL" : m.toUpperCase(),
5037
- pathTemplate,
5038
- line,
5039
- framework: "fastapi"
5063
+ method: "ALL",
5064
+ pathTemplate: canonicalizeTemplate(raw),
5065
+ line: el.startPosition.row + 1,
5066
+ framework: "django"
5040
5067
  });
5041
5068
  }
5042
5069
  });
@@ -5057,7 +5084,10 @@ async function addRoutes(graph, services) {
5057
5084
  const hasHono = deps["hono"] !== void 0;
5058
5085
  const hasNext = deps["next"] !== void 0;
5059
5086
  const hasFastapi = deps["fastapi"] !== void 0;
5060
- if (!hasExpress && !hasFastify && !hasHono && !hasNext && !hasFastapi) continue;
5087
+ const hasFlask = deps["flask"] !== void 0;
5088
+ const hasDjango = deps["django"] !== void 0;
5089
+ if (!hasExpress && !hasFastify && !hasHono && !hasNext && !hasFastapi && !hasFlask && !hasDjango)
5090
+ continue;
5061
5091
  const files = await loadSourceFiles(service.dir);
5062
5092
  for (const file of files) {
5063
5093
  if (isTestPath(file.path)) continue;
@@ -5068,7 +5098,8 @@ async function addRoutes(graph, services) {
5068
5098
  let routes;
5069
5099
  try {
5070
5100
  if (isPy) {
5071
- routes = hasFastapi ? fastapiRoutesFromSource(file.content, pyParser) : [];
5101
+ routes = hasFastapi || hasFlask ? pythonRoutesFromSource(file.content, pyParser, hasFastapi ? "fastapi" : "flask") : [];
5102
+ if (hasDjango) routes = routes.concat(djangoRoutesFromSource(file.content, pyParser));
5072
5103
  } else if (hasNext && (isNextAppRouteFile(relFile) || isNextPagesApiFile(relFile))) {
5073
5104
  routes = nextRoutesFromFile(file.content, relFile, jsParser);
5074
5105
  } else if (hasExpress || hasFastify || hasHono) {
@@ -9995,4 +10026,4 @@ export {
9995
10026
  recordConnectorPoll,
9996
10027
  buildApi
9997
10028
  };
9998
- //# sourceMappingURL=chunk-ZZ3VUCWL.js.map
10029
+ //# sourceMappingURL=chunk-AOWANF2K.js.map