@descryy/adapter-python 0.1.0 → 0.3.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.
package/dist/module.d.ts CHANGED
@@ -1,46 +1,33 @@
1
1
  /**
2
2
  * Python module paths and import resolution — the whole of R1.
3
3
  *
4
- * ## Where the last adapter lost three quarters of its graph
4
+ * DEC-059: the TypeScript adapter ignored the repository's path
5
+ * configuration, failing every aliased import and cross-directory edge with
6
+ * it. Python's equivalents (`src/` layouts, `PYTHONPATH`, namespace
7
+ * packages, `pyproject.toml`'s package table) are the same defect in a
8
+ * different spelling, so layout is read from the repository, not assumed,
9
+ * and what can't be read is disclosed.
5
10
  *
6
- * DEC-059: the TypeScript adapter ignored the repository's own path
7
- * configuration, so every aliased import failed and every cross-directory edge
8
- * with it. Python's equivalents are `src/` layouts, `PYTHONPATH`, namespace
9
- * packages and `pyproject.toml`'s package table — **the same defect in a
10
- * different spelling** — so the layout is read from the repository here rather
11
- * than assumed, and what could not be read is disclosed.
12
- *
13
- * ## The two hard cases, both in the corpus
14
- *
15
- * `from . import validate_order` — level 1, **no module name**. The dots are the
16
- * whole address, and they are not recoverable from the specifier text: this is
17
- * why the Python side reports `ImportFrom.level` rather than a string. It
18
- * resolves to the containing package's `__init__.py`, which is the re-export hop
19
- * golden pattern 03 turns on.
20
- *
21
- * `from .money import format_money` — level 1 with a module. Resolves to a
22
- * sibling file, and the imported name is a *symbol* in it rather than a module.
23
- * Deciding which of the two a name is cannot be done from the import alone —
24
- * `from .pkg import mod` and `from .mod import fn` are identical in shape — so
25
- * both candidates are returned and the caller picks by what exists.
11
+ * Two hard cases, both in the corpus: `from . import validate_order` (level
12
+ * 1, no module name — the dots are the whole address, resolving to the
13
+ * containing package's `__init__.py`, golden pattern 03's re-export hop) and
14
+ * `from .money import format_money` (level 1 with a module, where the name
15
+ * could be a submodule or a symbol — `.pkg import mod` and `.mod import fn`
16
+ * are identical in shape, so both candidates are returned and the caller
17
+ * picks by what exists).
26
18
  */
27
19
  /** `src/order_service.py` -> `["src", "order_service"]`; `src/__init__.py` -> `["src"]`. */
28
20
  export declare function modulePathOf(repoRelativeFile: string): readonly string[];
29
21
  /**
30
- * The display name of a module node.
31
- *
32
- * A package takes its directory's name — the corpus binds the `barrel` role to
33
- * the symbol `src` at `src/__init__.py`, so `__init__` would fail to bind and
34
- * the failure would read as a missing node rather than as a naming choice.
22
+ * The display name of a module node. A package takes its directory's name —
23
+ * the corpus binds the `barrel` role to `src` at `src/__init__.py`, so
24
+ * `__init__` would fail to bind and read as a missing node.
35
25
  */
36
26
  export declare function moduleNameOf(repoRelativeFile: string): string;
37
27
  /**
38
- * The project's distribution name, read rather than guessed.
39
- *
40
- * `pyproject.toml` first, then `setup.cfg`. Parsed with a narrow regex on
41
- * purpose: a TOML dependency would buy correctness on a field nothing else in
42
- * this adapter reads, and the fallback is disclosed through
43
- * `capabilities().nodeIdentityFallback` either way.
28
+ * The project's distribution name, read rather than guessed —
29
+ * `pyproject.toml` then `setup.cfg`, parsed with a narrow regex since a full
30
+ * TOML dependency would buy correctness on a field nothing else here reads.
44
31
  */
45
32
  export declare function projectName(absoluteRoot: string): {
46
33
  name: string;
@@ -67,21 +54,15 @@ export interface ResolveOptions {
67
54
  /** Repo-relative files this run analysed. Nothing outside it can be a target. */
68
55
  readonly known: ReadonlySet<string>;
69
56
  /**
70
- * Directories that are import roots, repo-relative, longest first.
71
- *
72
- * A `src/` layout means `from myapp.models import X` resolves under `src/`,
73
- * not under the repository root. Discovered rather than assumed — see
74
- * `importRoots`.
57
+ * Import root directories, repo-relative, longest first — a `src/` layout
58
+ * means `from myapp.models import X` resolves under `src/`. Discovered, not assumed; see `importRoots`.
75
59
  */
76
60
  readonly roots: readonly string[];
77
61
  }
78
62
  /**
79
63
  * Resolve one import to a file, and to a symbol inside it when it names one.
80
- *
81
- * Returns `file: undefined` for anything outside the analysed set — the standard
82
- * library, an installed package, a namespace package this run did not read.
83
- * That is a scope boundary rather than a failure, and DEC-050 keeps the two
84
- * apart in the ledger.
64
+ * `file: undefined` for anything outside the analysed set (stdlib, an
65
+ * installed package) — a scope boundary, not a failure; DEC-050 keeps the two apart in the ledger.
85
66
  */
86
67
  export declare function resolveImport(record: ImportRecord, fromFile: string, options: ResolveOptions): ImportTarget;
87
68
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAQxE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAwBpF;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAeD,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,GACtB,YAAY,CA0Dd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAwCvE"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAOxE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAuBpF;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAYD,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,cAAc,GACtB,YAAY,CA0Dd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAwCvE"}
package/dist/module.js CHANGED
@@ -1,28 +1,20 @@
1
1
  /**
2
2
  * Python module paths and import resolution — the whole of R1.
3
3
  *
4
- * ## Where the last adapter lost three quarters of its graph
4
+ * DEC-059: the TypeScript adapter ignored the repository's path
5
+ * configuration, failing every aliased import and cross-directory edge with
6
+ * it. Python's equivalents (`src/` layouts, `PYTHONPATH`, namespace
7
+ * packages, `pyproject.toml`'s package table) are the same defect in a
8
+ * different spelling, so layout is read from the repository, not assumed,
9
+ * and what can't be read is disclosed.
5
10
  *
6
- * DEC-059: the TypeScript adapter ignored the repository's own path
7
- * configuration, so every aliased import failed and every cross-directory edge
8
- * with it. Python's equivalents are `src/` layouts, `PYTHONPATH`, namespace
9
- * packages and `pyproject.toml`'s package table — **the same defect in a
10
- * different spelling** — so the layout is read from the repository here rather
11
- * than assumed, and what could not be read is disclosed.
12
- *
13
- * ## The two hard cases, both in the corpus
14
- *
15
- * `from . import validate_order` — level 1, **no module name**. The dots are the
16
- * whole address, and they are not recoverable from the specifier text: this is
17
- * why the Python side reports `ImportFrom.level` rather than a string. It
18
- * resolves to the containing package's `__init__.py`, which is the re-export hop
19
- * golden pattern 03 turns on.
20
- *
21
- * `from .money import format_money` — level 1 with a module. Resolves to a
22
- * sibling file, and the imported name is a *symbol* in it rather than a module.
23
- * Deciding which of the two a name is cannot be done from the import alone —
24
- * `from .pkg import mod` and `from .mod import fn` are identical in shape — so
25
- * both candidates are returned and the caller picks by what exists.
11
+ * Two hard cases, both in the corpus: `from . import validate_order` (level
12
+ * 1, no module name — the dots are the whole address, resolving to the
13
+ * containing package's `__init__.py`, golden pattern 03's re-export hop) and
14
+ * `from .money import format_money` (level 1 with a module, where the name
15
+ * could be a submodule or a symbol — `.pkg import mod` and `.mod import fn`
16
+ * are identical in shape, so both candidates are returned and the caller
17
+ * picks by what exists).
26
18
  */
27
19
  import { existsSync, readFileSync } from "node:fs";
28
20
  import { join } from "node:path";
@@ -30,31 +22,25 @@ import { join } from "node:path";
30
22
  export function modulePathOf(repoRelativeFile) {
31
23
  const withoutExtension = repoRelativeFile.replace(/\.pyi?$/, "");
32
24
  const parts = withoutExtension.split("/").filter((p) => p !== "" && p !== ".");
33
- // A package *is* its directory. `src/__init__.py` and the directory `src` are
34
- // one module, and emitting two nodes for them would split every import into
35
- // the package across two targets.
25
+ // A package is its directory: `src/__init__.py` and directory `src` are
26
+ // one module, or every import into the package would split across two targets.
36
27
  if (parts[parts.length - 1] === "__init__")
37
28
  parts.pop();
38
29
  return parts;
39
30
  }
40
31
  /**
41
- * The display name of a module node.
42
- *
43
- * A package takes its directory's name — the corpus binds the `barrel` role to
44
- * the symbol `src` at `src/__init__.py`, so `__init__` would fail to bind and
45
- * the failure would read as a missing node rather than as a naming choice.
32
+ * The display name of a module node. A package takes its directory's name —
33
+ * the corpus binds the `barrel` role to `src` at `src/__init__.py`, so
34
+ * `__init__` would fail to bind and read as a missing node.
46
35
  */
47
36
  export function moduleNameOf(repoRelativeFile) {
48
37
  const path = modulePathOf(repoRelativeFile);
49
38
  return path[path.length - 1] ?? "";
50
39
  }
51
40
  /**
52
- * The project's distribution name, read rather than guessed.
53
- *
54
- * `pyproject.toml` first, then `setup.cfg`. Parsed with a narrow regex on
55
- * purpose: a TOML dependency would buy correctness on a field nothing else in
56
- * this adapter reads, and the fallback is disclosed through
57
- * `capabilities().nodeIdentityFallback` either way.
41
+ * The project's distribution name, read rather than guessed —
42
+ * `pyproject.toml` then `setup.cfg`, parsed with a narrow regex since a full
43
+ * TOML dependency would buy correctness on a field nothing else here reads.
58
44
  */
59
45
  export function projectName(absoluteRoot) {
60
46
  const pyproject = join(absoluteRoot, "pyproject.toml");
@@ -75,18 +61,14 @@ export function projectName(absoluteRoot) {
75
61
  }
76
62
  return {
77
63
  name: ".",
78
- // The same shape of admission DEC-024 required of the TypeScript adapter:
79
- // without a declared name, node identity rests on the module path alone.
64
+ // Same admission DEC-024 required of the TypeScript adapter.
80
65
  evidence: "no pyproject.toml or setup.cfg declares a project name, so node identity falls back to " +
81
66
  "the module path alone (DEC-024, DEC-054)",
82
67
  };
83
68
  }
84
69
  /**
85
- * Candidate files for a dotted module path, in Python's own order.
86
- *
87
- * A package's `__init__.py` is checked before a same-named module, because that
88
- * is what the interpreter does and a graph that disagrees with the interpreter
89
- * is wrong regardless of which is nicer.
70
+ * Candidate files for a dotted module path, in Python's own order — a
71
+ * package's `__init__.py` before a same-named module, matching the interpreter.
90
72
  */
91
73
  function candidates(parts) {
92
74
  if (parts.length === 0)
@@ -96,11 +78,8 @@ function candidates(parts) {
96
78
  }
97
79
  /**
98
80
  * Resolve one import to a file, and to a symbol inside it when it names one.
99
- *
100
- * Returns `file: undefined` for anything outside the analysed set — the standard
101
- * library, an installed package, a namespace package this run did not read.
102
- * That is a scope boundary rather than a failure, and DEC-050 keeps the two
103
- * apart in the ledger.
81
+ * `file: undefined` for anything outside the analysed set (stdlib, an
82
+ * installed package) — a scope boundary, not a failure; DEC-050 keeps the two apart in the ledger.
104
83
  */
105
84
  export function resolveImport(record, fromFile, options) {
106
85
  const miss = { file: undefined, symbol: undefined, viaPackageInit: false };
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
package/dist/orm.d.ts CHANGED
@@ -1,25 +1,21 @@
1
1
  /**
2
2
  * The ORM framework extractor for Python — SQLAlchemy and Django.
3
3
  *
4
- * **A `MODEL` is a framework claim, and this file is where the claim is earned.**
5
- * Golden pattern 07 states the constraint that produced it: in the conformance
6
- * corpus `Order` and `CreateOrderRequest` are structurally identical, so any
7
- * classification a *language* adapter made between them would be a name
8
- * heuristic — the one thing pattern 12 exists to punish. The evidence that
9
- * separates them is a persistence mapping: a declarative base, a table binding,
10
- * a column declaration. All three are written in the source, and this file reads
11
- * them rather than inferring them.
4
+ * A `MODEL` is a framework claim, earned here: golden pattern 07's
5
+ * conformance corpus has `Order` and `CreateOrderRequest` structurally
6
+ * identical, so classifying between them by name would be exactly what
7
+ * pattern 12 punishes. The evidence is a persistence mapping — declarative
8
+ * base, table binding, column declaration — all written in source and read,
9
+ * not inferred.
12
10
  *
13
- * Nothing here is a name rule. `isTestSuiteClass` in `extract.ts` deliberately
14
- * keeps one — a base whose name ends in `TestCase` — because the cost of being
15
- * wrong is a test attributed to the wrong suite. The cost of being wrong here is
16
- * a `MODEL` node that no database backs, which corrupts every data-propagation
17
- * traversal above it, so provenance or a chain to provenance is the only
18
- * admission. A class named `Model` proves nothing.
11
+ * Nothing here is a name rule (unlike `isTestSuiteClass` in `extract.ts`,
12
+ * which keeps one deliberately since misattributing a test costs little). A
13
+ * wrong `MODEL` corrupts every data-propagation traversal above it, so
14
+ * provenance or a chain to provenance is the only admission — a class named
15
+ * `Model` proves nothing.
19
16
  *
20
- * The split with `extract.py` is the same one the rest of this adapter uses: the
21
- * Python side records syntactic form and names no framework, and every decision
22
- * about what a form *means* is taken here.
17
+ * `extract.py` records syntactic form and names no framework; every
18
+ * "what does this form mean" decision is taken here.
23
19
  */
24
20
  /** One assignment in a class body, as `extract.py` recorded it. */
25
21
  export interface PyAttribute {
@@ -49,50 +45,39 @@ export interface OrmShape {
49
45
  readonly table: string | null;
50
46
  readonly fields: readonly OrmField[];
51
47
  /**
52
- * Fields whose nullability is written in a form this reader cannot evaluate.
53
- *
54
- * Listed rather than guessed, and listed rather than dropped. `nullable=FLAG`
55
- * is a stated answer this reader failed to read, and letting the framework
56
- * default stand in for it would report the opposite of the source as fact.
48
+ * Fields whose nullability (e.g. `nullable=FLAG`) can't be evaluated.
49
+ * Listed, not guessed or dropped — the framework default standing in
50
+ * would report the opposite of the source as fact.
57
51
  */
58
52
  readonly undecided: readonly string[];
59
53
  }
60
54
  /**
61
- * Modules whose names, if a base class came from one, make the framework certain.
62
- *
63
- * Provenance is written in the import statement and needs no resolution, which
64
- * is why a model is recognisable at R0. Only the cross-file *chain* — a project's
65
- * own `class BaseModel(Base)` — needs imports resolved.
55
+ * Modules that make the framework certain if a base class came from one.
56
+ * Written in the import statement, needing no resolution — a model is
57
+ * recognisable at R0. Only the cross-file chain (`class BaseModel(Base)`) needs imports resolved.
66
58
  */
67
59
  export declare const ORM_BASE_MODULES: Readonly<Record<OrmFramework, ReadonlySet<string>>>;
68
60
  /**
69
- * Calls that *produce* a declarative base rather than being one.
70
- *
71
- * SQLAlchemy 1.x writes `Base = declarative_base()` at module level, so the base
72
- * class of a model is a name bound to a call result and not a class declaration
73
- * at all. Without this rule every 1.x model in existence is invisible.
61
+ * Calls that produce a declarative base rather than being one. SQLAlchemy
62
+ * 1.x writes `Base = declarative_base()` at module level, so the base is a
63
+ * name bound to a call result, not a class declaration — without this rule
64
+ * every 1.x model is invisible.
74
65
  */
75
66
  export declare const DECLARATIVE_BASE_FACTORIES: ReadonlySet<string>;
76
67
  /**
77
- * Is this attribute a mapped column, and by which framework's rule?
78
- *
79
- * Django's rule is shape-based rather than a name list: every field class in
80
- * `django.db.models` ends in `Field`, and new ones are added by Django and by
81
- * every third-party app. A closed list would go stale on each release and would
82
- * miss `JSONField`, `ArrayField` and every custom field a project writes. The
83
- * receiver still has to be the imported `models` module, so this is not a name
84
- * heuristic — the provenance is checked by the caller before this is consulted.
68
+ * Is this attribute a mapped column, and by which framework's rule? Django's
69
+ * rule is shape-based, not a name list — every field class in
70
+ * `django.db.models` ends in `Field`, and a closed list would go stale and
71
+ * miss `JSONField`/`ArrayField`/custom fields. Provenance is still checked
72
+ * by the caller first, so this isn't a name heuristic.
85
73
  */
86
74
  export declare function isColumnCall(attribute: PyAttribute, framework: OrmFramework): boolean;
87
75
  /** A base class name that is the framework's own, rather than a project's. */
88
76
  export declare function isFrameworkBaseName(name: string, framework: OrmFramework): boolean;
89
77
  /**
90
- * The mapped shape of a class already established to belong to `framework`.
91
- *
92
- * Returns `null` where the class declares no column at all. That guard is what
93
- * keeps a declarative base out of the graph as a model of its own: `class
94
- * Base(DeclarativeBase): pass` inherits the provenance and maps nothing, and a
95
- * `MODEL` with no fields is a claim about a table that does not exist.
78
+ * The mapped shape of a class already established to belong to `framework`,
79
+ * or `null` when it declares no column — keeps a bare declarative base
80
+ * (`class Base(DeclarativeBase): pass`) out of the graph as a model of its own.
96
81
  */
97
82
  export declare function ormShapeOf(input: {
98
83
  readonly framework: OrmFramework;
package/dist/orm.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"orm.d.ts","sourceRoot":"","sources":["../src/orm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,iFAAiF;IACjF,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,YAAY,EAAE,UAAU,GAAG,YAAY,GAAG,mBAAmB,CAAC;CACxE;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAQhF,CAAC;AAaF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,MAAM,CAIzD,CAAC;AA2CH;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAMrF;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAElF;AA8DD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;CACvC,GAAG,QAAQ,GAAG,IAAI,CA0ClB"}
1
+ {"version":3,"file":"orm.d.ts","sourceRoot":"","sources":["../src/orm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,iFAAiF;IACjF,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,YAAY,EAAE,UAAU,GAAG,YAAY,GAAG,mBAAmB,CAAC;CACxE;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAQhF,CAAC;AAWF;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,MAAM,CAIzD,CAAC;AAmCH;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAMrF;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,OAAO,CAElF;AAuDD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;CACvC,GAAG,QAAQ,GAAG,IAAI,CAoClB"}
package/dist/orm.js CHANGED
@@ -1,32 +1,26 @@
1
1
  /**
2
2
  * The ORM framework extractor for Python — SQLAlchemy and Django.
3
3
  *
4
- * **A `MODEL` is a framework claim, and this file is where the claim is earned.**
5
- * Golden pattern 07 states the constraint that produced it: in the conformance
6
- * corpus `Order` and `CreateOrderRequest` are structurally identical, so any
7
- * classification a *language* adapter made between them would be a name
8
- * heuristic — the one thing pattern 12 exists to punish. The evidence that
9
- * separates them is a persistence mapping: a declarative base, a table binding,
10
- * a column declaration. All three are written in the source, and this file reads
11
- * them rather than inferring them.
4
+ * A `MODEL` is a framework claim, earned here: golden pattern 07's
5
+ * conformance corpus has `Order` and `CreateOrderRequest` structurally
6
+ * identical, so classifying between them by name would be exactly what
7
+ * pattern 12 punishes. The evidence is a persistence mapping — declarative
8
+ * base, table binding, column declaration — all written in source and read,
9
+ * not inferred.
12
10
  *
13
- * Nothing here is a name rule. `isTestSuiteClass` in `extract.ts` deliberately
14
- * keeps one — a base whose name ends in `TestCase` — because the cost of being
15
- * wrong is a test attributed to the wrong suite. The cost of being wrong here is
16
- * a `MODEL` node that no database backs, which corrupts every data-propagation
17
- * traversal above it, so provenance or a chain to provenance is the only
18
- * admission. A class named `Model` proves nothing.
11
+ * Nothing here is a name rule (unlike `isTestSuiteClass` in `extract.ts`,
12
+ * which keeps one deliberately since misattributing a test costs little). A
13
+ * wrong `MODEL` corrupts every data-propagation traversal above it, so
14
+ * provenance or a chain to provenance is the only admission — a class named
15
+ * `Model` proves nothing.
19
16
  *
20
- * The split with `extract.py` is the same one the rest of this adapter uses: the
21
- * Python side records syntactic form and names no framework, and every decision
22
- * about what a form *means* is taken here.
17
+ * `extract.py` records syntactic form and names no framework; every
18
+ * "what does this form mean" decision is taken here.
23
19
  */
24
20
  /**
25
- * Modules whose names, if a base class came from one, make the framework certain.
26
- *
27
- * Provenance is written in the import statement and needs no resolution, which
28
- * is why a model is recognisable at R0. Only the cross-file *chain* — a project's
29
- * own `class BaseModel(Base)` — needs imports resolved.
21
+ * Modules that make the framework certain if a base class came from one.
22
+ * Written in the import statement, needing no resolution — a model is
23
+ * recognisable at R0. Only the cross-file chain (`class BaseModel(Base)`) needs imports resolved.
30
24
  */
31
25
  export const ORM_BASE_MODULES = {
32
26
  sqlalchemy: new Set([
@@ -39,20 +33,17 @@ export const ORM_BASE_MODULES = {
39
33
  };
40
34
  /** The framework's own base class names. A project's own base reaches these by chain. */
41
35
  const ORM_BASE_NAMES = {
42
- // `Base` is deliberately absent. It is what almost every SQLAlchemy project
43
- // calls its declarative base, and admitting it would be a name rule wearing a
44
- // framework's clothes — a project is free to call its base anything, and
45
- // something else is free to be called `Base`. The 1.x shape is reached through
46
- // `DECLARATIVE_BASE_FACTORIES` instead, which is provenance.
36
+ // `Base` is deliberately absent — almost every SQLAlchemy project calls its
37
+ // declarative base that, so admitting it would be a name rule in disguise.
38
+ // The 1.x shape is reached through `DECLARATIVE_BASE_FACTORIES` instead.
47
39
  sqlalchemy: new Set(["DeclarativeBase"]),
48
40
  django: new Set(["Model"]),
49
41
  };
50
42
  /**
51
- * Calls that *produce* a declarative base rather than being one.
52
- *
53
- * SQLAlchemy 1.x writes `Base = declarative_base()` at module level, so the base
54
- * class of a model is a name bound to a call result and not a class declaration
55
- * at all. Without this rule every 1.x model in existence is invisible.
43
+ * Calls that produce a declarative base rather than being one. SQLAlchemy
44
+ * 1.x writes `Base = declarative_base()` at module level, so the base is a
45
+ * name bound to a call result, not a class declaration — without this rule
46
+ * every 1.x model is invisible.
56
47
  */
57
48
  export const DECLARATIVE_BASE_FACTORIES = new Set([
58
49
  "declarative_base",
@@ -62,16 +53,10 @@ export const DECLARATIVE_BASE_FACTORIES = new Set([
62
53
  /** Column constructors, per framework. */
63
54
  const COLUMN_CALLS = {
64
55
  sqlalchemy: new Set(["Column", "mapped_column", "deferred", "synonym_for"]),
65
- /**
66
- * Django's relational fields, which are the exception to the `…Field` shape
67
- * below and were **not** guessed at — they were counted.
68
- *
69
- * Across django's own tree `ForeignKey` is the second most common field
70
- * constructor in existence, 914 uses against `CharField`'s 1,226, and the
71
- * shape rule alone missed every one of them because it is the one field class
72
- * Django did not suffix. `GenericForeignKey` and `GenericRelation` came out of
73
- * the same count at 59 and 46.
74
- */
56
+ // Django's relational fields, counted not guessed: `ForeignKey` is the
57
+ // second most common field constructor in django's own tree (914 uses vs
58
+ // `CharField`'s 1,226) and the one class Django didn't suffix `Field`, so
59
+ // the shape rule alone missed it (`GenericForeignKey`/`GenericRelation`: 59, 46).
75
60
  django: new Set([
76
61
  "ForeignKey",
77
62
  "OneToOneField",
@@ -81,11 +66,9 @@ const COLUMN_CALLS = {
81
66
  ]),
82
67
  };
83
68
  /**
84
- * Attribute names that are configuration rather than columns.
85
- *
86
- * `__tablename__` is the table binding and `__table_args__` its options; neither
87
- * is a field, and reporting them as fields would put two members in every model
88
- * that no query can select.
69
+ * Attribute names that are configuration, not columns — `__tablename__` is
70
+ * the table binding, `__table_args__` its options; reporting either as a
71
+ * field would put an unselectable member in every model.
89
72
  */
90
73
  const NOT_A_FIELD = new Set([
91
74
  "__tablename__",
@@ -97,14 +80,11 @@ const NOT_A_FIELD = new Set([
97
80
  ]);
98
81
  const leafOf = (dotted) => dotted === null ? "" : (dotted.split(".").pop() ?? "");
99
82
  /**
100
- * Is this attribute a mapped column, and by which framework's rule?
101
- *
102
- * Django's rule is shape-based rather than a name list: every field class in
103
- * `django.db.models` ends in `Field`, and new ones are added by Django and by
104
- * every third-party app. A closed list would go stale on each release and would
105
- * miss `JSONField`, `ArrayField` and every custom field a project writes. The
106
- * receiver still has to be the imported `models` module, so this is not a name
107
- * heuristic — the provenance is checked by the caller before this is consulted.
83
+ * Is this attribute a mapped column, and by which framework's rule? Django's
84
+ * rule is shape-based, not a name list — every field class in
85
+ * `django.db.models` ends in `Field`, and a closed list would go stale and
86
+ * miss `JSONField`/`ArrayField`/custom fields. Provenance is still checked
87
+ * by the caller first, so this isn't a name heuristic.
108
88
  */
109
89
  export function isColumnCall(attribute, framework) {
110
90
  if (attribute.callee === null)
@@ -121,13 +101,9 @@ export function isFrameworkBaseName(name, framework) {
121
101
  return ORM_BASE_NAMES[framework].has(leafOf(name));
122
102
  }
123
103
  /**
124
- * Nullability for one mapped column.
125
- *
126
- * Order is the framework's own, not this reader's preference. An explicit
127
- * keyword is the source's answer and wins outright. A primary key is not
128
- * nullable — that is SQL, not a convention. SQLAlchemy 2.0 then derives
129
- * nullability from the `Mapped[...]` annotation, and only when none of those
130
- * spoke does the framework default apply.
104
+ * Nullability for one mapped column. Order is the framework's own: explicit
105
+ * keyword wins, a primary key is never nullable (SQL, not convention), then
106
+ * SQLAlchemy 2.0's `Mapped[...]` annotation, and only then the framework default.
131
107
  */
132
108
  function nullabilityOf(attribute, framework) {
133
109
  const keyword = framework === "django" ? "null" : "nullable";
@@ -141,21 +117,18 @@ function nullabilityOf(attribute, framework) {
141
117
  return { name: attribute.name, nullable: false, nullableFrom: "declared" };
142
118
  }
143
119
  if (framework === "django") {
144
- // Django's documented default, and the only one it has: a field is NOT NULL
145
- // unless the model says otherwise.
120
+ // Django's only documented default: NOT NULL unless the model says otherwise.
146
121
  return { name: attribute.name, nullable: false, nullableFrom: "framework-default" };
147
122
  }
148
- // SQLAlchemy 2.0: `Mapped[str]` is NOT NULL, `Mapped[str | None]` is nullable.
149
- // The annotation is the declaration in this style, so it ranks above the
150
- // 1.x-era default rather than below it.
123
+ // SQLAlchemy 2.0: `Mapped[str]` is NOT NULL, `Mapped[str | None]` is
124
+ // nullable — the annotation IS the declaration here, ranking above the 1.x default.
151
125
  const annotation = attribute.annotation;
152
126
  if (annotation !== null && /\bMapped\s*\[/.test(annotation)) {
153
127
  const inner = annotation.slice(annotation.indexOf("[") + 1, annotation.lastIndexOf("]"));
154
128
  const nullable = /\bOptional\s*\[/.test(inner) || /\bNone\b/.test(inner);
155
129
  return { name: attribute.name, nullable, nullableFrom: "annotation" };
156
130
  }
157
- // SQLAlchemy 1.x: a column is nullable unless it says otherwise. The opposite
158
- // of Django's default, which is why neither is written once for both.
131
+ // SQLAlchemy 1.x: nullable unless it says otherwise — the opposite of Django's default.
159
132
  return { name: attribute.name, nullable: true, nullableFrom: "framework-default" };
160
133
  }
161
134
  /** The table a model binds to, where the source names one. */
@@ -169,12 +142,9 @@ function tableOf(attributes, meta, framework) {
169
142
  return null;
170
143
  }
171
144
  /**
172
- * The mapped shape of a class already established to belong to `framework`.
173
- *
174
- * Returns `null` where the class declares no column at all. That guard is what
175
- * keeps a declarative base out of the graph as a model of its own: `class
176
- * Base(DeclarativeBase): pass` inherits the provenance and maps nothing, and a
177
- * `MODEL` with no fields is a claim about a table that does not exist.
145
+ * The mapped shape of a class already established to belong to `framework`,
146
+ * or `null` when it declares no column — keeps a bare declarative base
147
+ * (`class Base(DeclarativeBase): pass`) out of the graph as a model of its own.
178
148
  */
179
149
  export function ormShapeOf(input) {
180
150
  const fields = [];
@@ -190,20 +160,14 @@ export function ormShapeOf(input) {
190
160
  else
191
161
  fields.push(read);
192
162
  }
193
- // **The column requirement is SQLAlchemy's alone, and the asymmetry is the
194
- // frameworks', not this reader's.**
195
- //
196
- // SQLAlchemy's declarative base is a class the *project* writes — `class
197
- // Base(DeclarativeBase): pass` — so it inherits the provenance that admits a
198
- // model and maps nothing. Without this guard the base itself becomes a `MODEL`
199
- // describing a table that does not exist.
200
- //
201
- // Django has no such class in the analysed set: `models.Model` is Django's own
202
- // and is never a subclass of itself. Inheriting it IS the declaration, and
203
- // `class Foo(models.Model): pass` is a complete model — Django gives it an
204
- // implicit primary key. Requiring a column here cost 317 real models on
205
- // django's own tree, which is how the asymmetry was found rather than reasoned
206
- // about.
163
+ // The column requirement is SQLAlchemy's alone — the asymmetry is the
164
+ // frameworks', not this reader's. SQLAlchemy's declarative base is a class
165
+ // the project writes (`class Base(DeclarativeBase): pass`), inheriting
166
+ // provenance while mapping nothing; without this guard it becomes a
167
+ // `MODEL` describing no table. Django has no such class in the analysed
168
+ // set — `class Foo(models.Model): pass` is a complete model with an
169
+ // implicit primary key, and requiring a column here cost 317 real models
170
+ // on django's own tree (found by measurement, not reasoned about).
207
171
  const table = tableOf(input.attributes, input.meta, input.framework);
208
172
  if (input.framework === "sqlalchemy" &&
209
173
  fields.length === 0 &&