@ucm-kit/adapter-typescript 0.1.30 → 0.1.32

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/README.md CHANGED
@@ -6,7 +6,7 @@ two capabilities without making
6
6
  TypeScript compiler, a 23 MB dependency no other consumer should pay for.
7
7
 
8
8
  ```sh
9
- npm install --save-dev @ucm-kit/adapter-typescript@0.1.30 @ucm-kit/cli@0.1.37
9
+ npm install --save-dev @ucm-kit/adapter-typescript@0.1.32 @ucm-kit/cli@0.1.39
10
10
  npx ucm-typescript
11
11
  npx --no-install ucm check
12
12
  ```
@@ -28,6 +28,10 @@ reported:
28
28
 
29
29
  Parity requires a `tsconfig.json` at the root. Props are read with the
30
30
  TypeScript type checker; compositions are counted by their occurrences in JSX.
31
+ The props of `Button.tsx` come from an interface or a type alias named
32
+ `ButtonProps`. The component is the function named `Button`, or the file's
33
+ default export. A prop counts as read whether it is destructured in the
34
+ signature or from `props` in the body.
31
35
 
32
36
  Every one of these **warns without blocking**. The gap is in the code, so a
33
37
  developer closes it. No re-export helps.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ucm-kit/adapter-typescript",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "description": "Adaptateur TypeScript UCM : parité statique des composants et génération des types dérivés des contrats.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -35,7 +35,7 @@
35
35
  "test": "node scripts/run-tests.cjs"
36
36
  },
37
37
  "dependencies": {
38
- "@ucm-kit/core": "0.1.33",
38
+ "@ucm-kit/core": "0.1.35",
39
39
  "typescript": ">=5.5.0 <6"
40
40
  }
41
41
  }
package/src/parite.mjs CHANGED
@@ -45,6 +45,15 @@ function trouverFonctionComposant(source, nomComposant) {
45
45
  nommee = noeud;
46
46
  return;
47
47
  }
48
+ // `export default function (…)` n'est pas une affectation d'export : c'est
49
+ // une déclaration, anonyme ou nommée autrement que le fichier.
50
+ if (
51
+ ts.isFunctionDeclaration(noeud)
52
+ && noeud.modifiers?.some((modificateur) => modificateur.kind === ts.SyntaxKind.DefaultKeyword)
53
+ ) {
54
+ parDefaut = noeud;
55
+ return;
56
+ }
48
57
  if (ts.isExportAssignment(noeud) && !noeud.isExportEquals) {
49
58
  parDefaut = fonctionEmballee(noeud.expression);
50
59
  return;
@@ -65,7 +74,8 @@ function symboleLuDans(noeud, symbole, verificateur) {
65
74
  let lu = false;
66
75
  const visiter = (enfant) => {
67
76
  if (lu) return;
68
- if (ts.isIdentifier(enfant)) {
77
+ // Le nom d'une décomposition déclare le symbole, il ne le lit pas.
78
+ if (ts.isIdentifier(enfant) && !(ts.isBindingElement(enfant.parent) && enfant.parent.name === enfant)) {
69
79
  const symboleValeur = ts.isShorthandPropertyAssignment(enfant.parent)
70
80
  ? verificateur.getShorthandAssignmentValueSymbol(enfant.parent)
71
81
  : verificateur.getSymbolAtLocation(enfant);
@@ -121,6 +131,21 @@ function propsConsommees(fonction, nomsProps, verificateur) {
121
131
  && estLeParametre(noeud.expression)
122
132
  ) {
123
133
  for (const nom of nomsProps) consommees.add(nom);
134
+ } else if (
135
+ ts.isVariableDeclaration(noeud)
136
+ && ts.isObjectBindingPattern(noeud.name)
137
+ && noeud.initializer
138
+ && estLeParametre(noeud.initializer)
139
+ ) {
140
+ // `const { a } = props` : la prop compte si la variable locale est lue.
141
+ for (const element of noeud.name.elements) {
142
+ if (element.dotDotDotToken || !ts.isIdentifier(element.name)) continue;
143
+ const nom = nomDeBinding(element.propertyName ?? element.name);
144
+ const symbole = verificateur.getSymbolAtLocation(element.name);
145
+ if (nom && symbole && symboleLuDans(fonction.body, symbole, verificateur)) {
146
+ consommees.add(nom);
147
+ }
148
+ }
124
149
  }
125
150
  ts.forEachChild(noeud, visiter);
126
151
  };
@@ -267,7 +292,8 @@ export function lireApiPublique(fichiers, racine) {
267
292
  let props = null;
268
293
 
269
294
  ts.forEachChild(source, (noeud) => {
270
- if (!ts.isInterfaceDeclaration(noeud) || noeud.name.text !== attendue) return;
295
+ if (!(ts.isInterfaceDeclaration(noeud) || ts.isTypeAliasDeclaration(noeud))) return;
296
+ if (noeud.name.text !== attendue) return;
271
297
  const type = verificateur.getTypeAtLocation(noeud.name);
272
298
  const membres = verificateur.getPropertiesOfType(type);
273
299
  const consommees = propsConsommees(