@gandalan/weblibs 1.5.27 → 1.5.29

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/JSDOC.md CHANGED
@@ -1,390 +1,159 @@
1
- # JSDoc Reference for WebLibs
1
+ # JSDoc Guide for WebLibs
2
2
 
3
- This document records the JSDoc stabilization work done in `WebLibs` and defines the rules that must be followed going forward.
3
+ This guide explains the small set of rules that keep IntelliSense working for consumers of `@gandalan/weblibs`.
4
4
 
5
- The goal is simple:
5
+ Use it when you add:
6
6
 
7
- - No API member should degrade to `any` because of broken JSDoc.
8
- - No DTO type should degrade to `any` because of missing exports, missing imports, or non-module files.
9
- - Type information must stay discoverable in VS Code IntelliSense through `import("...").Type` and local typedef aliases.
7
+ - DTO properties
8
+ - API methods
9
+ - root function exports
10
+ - classes or other public types
10
11
 
12
+ If you follow the patterns below, consumers get stable types in both JS and TS.
11
13
 
12
- ## What Was Changed
13
14
 
14
- The following classes of problems were fixed.
15
+ ## Goal
15
16
 
16
- ### 1. API typedef exports were completed
17
+ Public types must stay discoverable from:
17
18
 
18
- Several business API files did not export a stable API type alias, or exported it inconsistently.
19
+ - `import("@gandalan/weblibs").TypeName`
20
+ - `import { someFunction } from "@gandalan/weblibs"`
21
+ - generated `index.d.ts`
19
22
 
20
- The working pattern is:
23
+ The package relies on JSDoc as the source of truth, and `npm run generate:dts` builds the root declaration output.
21
24
 
22
- ```js
23
- /**
24
- * @typedef {ReturnType<typeof createProduktionApi>} ProduktionApi
25
- */
26
- ```
27
25
 
28
- This pattern was added or standardized for affected business API files.
26
+ ## The Short Version
29
27
 
28
+ 1. Every pure-type JS file must be an ES module.
29
+ 2. Always use `.js` in JSDoc import paths.
30
+ 3. Import cross-file DTO types locally.
31
+ 4. In API files, define short local typedef aliases at the top.
32
+ 5. Avoid circular typing like `@returns {XApi}` together with `@typedef {ReturnType<typeof createXApi>} XApi`.
33
+ 6. Regenerate declarations after public type changes.
30
34
 
31
- ### 2. Circular API typing was removed
32
35
 
33
- Some API factory functions used this pattern:
36
+ ## Basic Rules
34
37
 
35
- ```js
36
- /**
37
- * @returns {ProduktionApi}
38
- */
39
- export function createProduktionApi(fluentApi) {
40
- ```
38
+ ### 1. Make type-only files real modules
41
39
 
42
- while the same file also defined:
43
-
44
- ```js
45
- /**
46
- * @typedef {ReturnType<typeof createProduktionApi>} ProduktionApi
47
- */
48
- ```
49
-
50
- That is circular. The JS language service can collapse this to `any`.
51
-
52
- The `@returns {XApi}` annotation was removed from those files when `XApi` was defined via `ReturnType<typeof createXApi>`.
53
-
54
-
55
- ### 3. `idasFluentApi` member typing was stabilized
56
-
57
- `IDASFluentApi` was normalized so that business members are typed consistently through imported API aliases, for example:
58
-
59
- ```js
60
- /**
61
- * @typedef {import("./business/produktionApi.js").ProduktionApi} ProduktionApi
62
- */
63
-
64
- /**
65
- * @typedef {import("./fluentApi.js").FluentApi & {
66
- * produktion: ProduktionApi;
67
- * }} IDASFluentApi
68
- */
69
- ```
70
-
71
- This avoids ad hoc per-member typing strategies.
72
-
73
-
74
- ### 4. DTO script files were converted into actual ES modules
75
-
76
- Some DTO files only contained `@typedef` declarations and no export. In practice, that can make `import("./file.js").Type` unstable or unusable.
77
-
78
- These DTO files were converted into modules by adding:
40
+ If a file only contains typedefs, end it with:
79
41
 
80
42
  ```js
81
43
  export {};
82
44
  ```
83
45
 
84
- This was required in plain typedef-only files such as:
85
-
86
- - `api/dtos/belege.js`
87
- - `api/dtos/kunden.js`
88
- - `api/dtos/produktion.js`
89
-
90
-
91
- ### 5. DTO cross-file dependencies were fixed
92
-
93
- Some DTOs referenced other DTOs from different files without importing them locally.
94
-
95
- Example of the broken pattern:
96
-
97
- ```js
98
- /**
99
- * @typedef {Object} BelegDTO
100
- * @property {BeleganschriftDTO} BelegAdresse
101
- */
102
- ```
103
-
104
- if `BeleganschriftDTO` lives in another file and is not imported locally.
46
+ Without this, `import("./file.js").TypeName` can degrade to `any`.
105
47
 
106
- That was fixed by either:
107
48
 
108
- - adding a local typedef alias, or
109
- - using an inline import in the property type.
49
+ ### 2. Always include `.js` in import paths
110
50
 
111
- Example:
51
+ Use:
112
52
 
113
53
  ```js
114
- /** @typedef {import('./kunden.js').BeleganschriftDTO} BeleganschriftDTO */
54
+ import("../dtos/belege.js").VorgangDTO
115
55
  ```
116
56
 
117
- or:
57
+ Not:
118
58
 
119
59
  ```js
120
- * @property {import('./kunden.js').BeleganschriftDTO} BelegAdresse
60
+ import("../dtos/belege").VorgangDTO
121
61
  ```
122
62
 
123
63
 
124
- ### 6. Missing DTO definitions in JSDoc were added
125
-
126
- Several DTO names used by the API surface existed in C# or were referenced in JS but were not actually modeled in JSDoc. Missing DTO definitions were added where source information was available.
127
-
128
- Examples added from source models:
64
+ ### 3. Import cross-file property types where they are used
129
65
 
130
- - `RechnungsNummer`
131
- - `ZusatztextDTO`
132
- - `BelegPositionSonderwunschDTO`
66
+ If a DTO property refers to a type from another file, add a local alias or use an inline import.
133
67
 
134
-
135
- ### 7. Business API method signatures were normalized
136
-
137
- Inline method-level types like this were reduced:
138
-
139
- ```js
140
- * @returns {Promise<import('../dtos/index.js').ProduktionsfreigabeItemDTO[]>}
141
- ```
142
-
143
- and replaced with local aliases at file top plus clean signatures:
68
+ Preferred:
144
69
 
145
70
  ```js
146
- /** @typedef {import('../dtos/produktion.js').ProduktionsfreigabeItemDTO} ProduktionsfreigabeItemDTO */
71
+ /** @typedef {import('./kunden.js').KontaktDTO} KontaktDTO */
147
72
 
148
73
  /**
149
- * @returns {Promise<ProduktionsfreigabeItemDTO[]>}
74
+ * @typedef {Object} VorgangDTO
75
+ * @property {KontaktDTO} Kunde
150
76
  */
151
- ```
152
-
153
- This is easier to read, easier to maintain, and resolves more reliably in IntelliSense.
154
-
155
-
156
- ### 8. `FluentApi` typedef usage was standardized
157
-
158
- Business API files must use:
159
77
 
160
- ```js
161
- /** @typedef {import('../fluentApi.js').FluentApi} FluentApi */
162
- ```
163
-
164
- and not:
165
-
166
- - a hand-written fake `FluentApi` object type
167
- - a missing typedef
168
- - an import path without `.js`
169
-
170
-
171
- ## Files Touched By This Work
172
-
173
- The exact set may evolve later, but the primary files changed during this stabilization were:
174
-
175
- ### API files
176
-
177
- - `api/idasFluentApi.js`
178
- - `api/business/benutzerApi.js`
179
- - `api/business/artikelApi.js`
180
- - `api/business/belegApi.js`
181
- - `api/business/produktionApi.js`
182
- - `api/business/fakturaApi.js`
183
- - `api/business/settingsApi.js`
184
- - `api/business/uiApi.js`
185
- - `api/business/utilityApi.js`
186
- - `api/business/serienApi.js`
187
- - `api/business/kontaktApi.js`
188
- - `api/business/belegPositionenApi.js`
189
- - `api/business/materialApi.js`
190
-
191
- ### DTO files
192
-
193
- - `api/dtos/index.js`
194
- - `api/dtos/belege.js`
195
- - `api/dtos/kunden.js`
196
- - `api/dtos/produktion.js`
197
- - `api/dtos/settings.js`
198
- - `api/dtos/ui.js`
199
- - `api/dtos/technik.js`
200
-
201
-
202
- ## The Rules
203
-
204
- These rules are mandatory if you want JSDoc discoverability to remain stable.
205
-
206
-
207
- ## Rule 1: Every DTO file must be an ES module
208
-
209
- If a DTO file only contains typedefs, still add:
210
-
211
- ```js
212
78
  export {};
213
79
  ```
214
80
 
215
- Why:
216
-
217
- - `import("./file.js").Type` is far more reliable when the target file is a real module.
218
- - Script files with only comments can cause type imports to degrade to `any`.
219
-
220
- Applies to:
221
-
222
- - DTO files
223
- - Any pure-type helper JS file used as a JSDoc import target
224
-
225
-
226
- ## Rule 2: Use `.js` in all JSDoc import paths
227
-
228
- Always write:
81
+ Also valid:
229
82
 
230
83
  ```js
231
- import("../dtos/belege.js").VorgangDTO
232
- ```
233
-
234
- Never write:
235
-
236
- ```js
237
- import("../dtos/belege").VorgangDTO
238
- ```
239
-
240
- Why:
241
-
242
- - The repo is ESM.
243
- - The JS language service resolves explicit file extensions more consistently.
244
-
245
-
246
- ## Rule 2a: Root DTO aliases must be generated, not hand-maintained
247
-
248
- The package root cannot rely on:
249
-
250
- ```js
251
- export * from "./api/dtos/index.js"
252
- ```
253
-
254
- to make JSDoc typedef aliases available through:
255
-
256
- ```js
257
- import("@gandalan/weblibs").VorgangDTO
258
- ```
259
-
260
- Why:
261
-
262
- - `export *` only forwards runtime exports.
263
- - JSDoc `@typedef` aliases are not runtime exports.
264
- - Root-level package imports therefore degrade to `any` unless the root module defines the aliases itself.
265
-
266
- The required pattern is:
267
-
268
- - keep `api/dtos/index.js` as the DTO alias source of truth
269
- - generate matching root typedef aliases into `index.js`
270
- - generate `index.d.ts` from the full package JSDoc source set for TypeScript consumers
271
-
272
- Do not edit the generated root DTO block manually. Regenerate it with:
273
-
274
- ```bash
275
- npm run generate:root-dto-typedefs
276
- ```
277
-
278
- The generator has two separate responsibilities:
279
-
280
- - `index.js`: generate the root DTO alias block for stable JSDoc imports from the package root
281
- - `index.d.ts`: generate root type exports for all non-trivial JSDoc-defined package types discovered in `index.js`, `api/**/*.js`, and `ui/**/*.js`
282
-
283
- For `index.d.ts`, simple local helper aliases like this are intentionally ignored:
284
-
285
- ```js
286
- /** @typedef {import('../fluentApi.js').FluentApi} FluentApi */
287
- ```
288
-
289
- because those are only local imports, not source type definitions. The declaration generator exports the canonical defining module instead.
290
-
291
-
292
- ## Rule 3: DTO files must import cross-file DTO dependencies locally
293
-
294
- If a DTO property references a type from another DTO file, that dependency must be represented in the file itself.
295
-
296
- Preferred forms:
297
-
298
- ```js
299
- /** @typedef {import('./kunden.js').BeleganschriftDTO} BeleganschriftDTO */
300
- ```
301
-
302
- or directly in the property:
84
+ /**
85
+ * @typedef {Object} VorgangDTO
86
+ * @property {import('./kunden.js').KontaktDTO} Kunde
87
+ */
303
88
 
304
- ```js
305
- * @property {import('./kunden.js').BeleganschriftDTO} BelegAdresse
89
+ export {};
306
90
  ```
307
91
 
308
- Never assume a type from another file is globally visible.
309
-
310
- Why:
311
-
312
- - Cross-file DTO references otherwise become weak links.
313
- - A top-level DTO may exist, but nested properties can still collapse to `any`.
314
92
 
93
+ ### 4. Keep API files readable with local aliases
315
94
 
316
- ## Rule 4: API files should define local type aliases at the top
317
-
318
- At the top of each API file, create short local aliases for every DTO used in that file.
319
-
320
- Example:
95
+ At the top of each API file, create short aliases for the types used in that file.
321
96
 
322
97
  ```js
323
98
  /**
324
99
  * @typedef {import('../fluentApi.js').FluentApi} FluentApi
325
100
  * @typedef {import('../dtos/produktion.js').ProduktionsfreigabeItemDTO} ProduktionsfreigabeItemDTO
326
- * @typedef {import('../dtos/produktion.js').ProduktionsInfoDTO} ProduktionsInfoDTO
327
101
  */
328
102
  ```
329
103
 
330
- Then use those aliases in method docs.
104
+ Then use those aliases in `@param` and `@returns`.
331
105
 
332
- Why:
333
106
 
334
- - Method signatures stay readable.
335
- - Repeated inline import expressions are error-prone.
336
- - VS Code resolves these aliases more reliably than repeated deep inline imports.
107
+ ## Common Tasks
337
108
 
109
+ ### Add a property to an existing DTO
338
110
 
339
- ## Rule 5: Prefer direct DTO source imports over aggregate imports when practical
111
+ 1. Open the concrete DTO owner file.
112
+ 2. Add the property with the exact runtime type.
113
+ 3. Import any cross-file type locally.
114
+ 4. Ensure the file ends with `export {};` if it is type-only.
340
115
 
341
- Preferred:
116
+ Example:
342
117
 
343
118
  ```js
344
- /** @typedef {import('../dtos/produktion.js').ProduktionsfreigabeItemDTO} ProduktionsfreigabeItemDTO */
345
- ```
119
+ /** @typedef {import('./kunden.js').BeleganschriftDTO} BeleganschriftDTO */
346
120
 
347
- Acceptable when the type truly belongs to the index layer:
121
+ /**
122
+ * @typedef {Object} BelegDTO
123
+ * @property {string} BelegGuid
124
+ * @property {BeleganschriftDTO} BelegAdresse
125
+ * @property {number | null} Total
126
+ */
348
127
 
349
- ```js
350
- /** @typedef {import('../dtos/index.js').LoginDTO} LoginDTO */
128
+ export {};
351
129
  ```
352
130
 
353
- Avoid defaulting everything to `dtos/index.js` when the concrete DTO source file is known.
354
-
355
- Why:
131
+ Rules:
356
132
 
357
- - Fewer resolution layers.
358
- - Easier debugging.
359
- - Better discoverability of the true type owner.
133
+ - Mark nullability explicitly.
134
+ - Match runtime names exactly.
135
+ - Mark optional properties only if they are actually optional.
360
136
 
361
137
 
362
- ## Rule 6: Do not use circular factory typedef patterns
138
+ ### Add a function to a business API
363
139
 
364
- Do not do this:
140
+ Use this pattern:
365
141
 
366
142
  ```js
367
143
  /**
368
- * @returns {ProduktionApi}
144
+ * @typedef {import('../fluentApi.js').FluentApi} FluentApi
145
+ * @typedef {import('../dtos/produktion.js').ProduktionsfreigabeItemDTO} ProduktionsfreigabeItemDTO
369
146
  */
370
- export function createProduktionApi(...) {}
371
147
 
372
- /**
373
- * @typedef {ReturnType<typeof createProduktionApi>} ProduktionApi
374
- */
375
- ```
376
-
377
- If the exported API type is defined through `ReturnType<typeof createXApi>`, then the factory should not also declare `@returns {XApi}`.
378
-
379
- Correct pattern:
380
-
381
- ```js
382
148
  /**
383
149
  * @param {FluentApi} fluentApi
384
150
  */
385
151
  export function createProduktionApi(fluentApi) {
386
152
  return {
387
- ...
153
+ /**
154
+ * @returns {Promise<ProduktionsfreigabeItemDTO[]>}
155
+ */
156
+ getAllProduktionsfreigabeItems: () => fluentApi.get("ProduktionsfreigabeListe")
388
157
  };
389
158
  }
390
159
 
@@ -393,315 +162,188 @@ export function createProduktionApi(fluentApi) {
393
162
  */
394
163
  ```
395
164
 
165
+ Important:
396
166
 
397
- ## Rule 7: `idasFluentApi` members must use imported API aliases consistently
167
+ - Do not also write `@returns {ProduktionApi}` on `createProduktionApi`.
168
+ - The generator expands `ReturnType<typeof createXApi>` into the root `index.d.ts`.
398
169
 
399
- Correct pattern:
400
-
401
- ```js
402
- /** @typedef {import('./business/produktionApi.js').ProduktionApi} ProduktionApi */
403
-
404
- /**
405
- * @typedef {import('./fluentApi.js').FluentApi & {
406
- * produktion: ProduktionApi;
407
- * }} IDASFluentApi
408
- */
409
- ```
410
-
411
- Do not mix:
412
-
413
- - imported alias types for some members
414
- - inline `ReturnType<typeof import(...).createXApi>` for others
415
- - unresolved local names for others
416
-
417
- One consistent member strategy must be used.
418
-
419
-
420
- ## Rule 8: Every API file must define `FluentApi` the same way
421
-
422
- Always:
423
-
424
- ```js
425
- /** @typedef {import('../fluentApi.js').FluentApi} FluentApi */
426
- ```
427
-
428
- Never:
429
-
430
- - hand-write a fake subset object
431
- - omit it and still write `@param {FluentApi}`
432
- - use extensionless import paths
433
170
 
171
+ ### Add an optional API parameter
434
172
 
435
- ## Rule 9: Optional parameters must be documented exactly
436
-
437
- If a parameter has a default value or is optional at call sites, mark it optional in JSDoc.
438
-
439
- Correct forms:
173
+ Document it exactly as the runtime behaves.
440
174
 
441
175
  ```js
176
+ /**
442
177
  * @param {boolean} [includeDetails=true]
443
- * @param {Date} [changedSince]
444
- * @param {string} [statusText='']
445
- ```
446
-
447
- Rules:
448
-
449
- - Use square brackets for optional parameters.
450
- - Include the default if the runtime defines one.
451
- - The JSDoc type must match the runtime type exactly.
452
- - If `null` is accepted, include it explicitly.
453
-
454
- Examples:
455
-
456
- ```js
457
178
  * @param {Date | null} [changedSince=null]
458
- * @param {boolean} [includeUIDefs=true]
459
- * @param {string[]} belegGuids
179
+ * @returns {Promise<AblageDTO[]>}
180
+ */
460
181
  ```
461
182
 
462
- Do not omit optionality when the implementation has a default value.
463
-
464
-
465
- ## Rule 10: Method names, parameter names, and types must match runtime code exactly
466
-
467
- JSDoc is not a sketch. It must match the code.
468
-
469
- That means:
470
-
471
- - parameter order must match the function signature
472
- - parameter names must match the implementation
473
- - optional/default markers must match runtime defaults
474
- - return types must match actual API responses, not assumptions
183
+ Use square brackets for optional parameters. Include default values when they exist.
475
184
 
476
- If the runtime returns a decoded JWT claims object, do not document it as a Swagger login DTO.
477
185
 
186
+ ### Add a root function export for consumers
478
187
 
479
- ## Rule 11: DTO property types must be concrete where possible
480
-
481
- Prefer:
188
+ If a function should be imported from the package root:
482
189
 
483
190
  ```js
484
- * @property {string} VorgangGuid
485
- * @property {number | null} VE_Menge
486
- * @property {Array<BelegPositionDTO>} PositionsObjekte
191
+ import { fluentApi } from "@gandalan/weblibs";
487
192
  ```
488
193
 
489
- Avoid broad placeholders unless the source model is genuinely unknown.
490
-
491
- Use placeholders only when:
194
+ then both of these must be true:
492
195
 
493
- - no source model exists in the repo
494
- - the backend contract is genuinely unknown
495
- - the placeholder is temporary and explicitly marked as such
196
+ 1. The function is exported from `index.js`.
197
+ 2. The root declaration output includes a stable signature in `index.d.ts`.
496
198
 
199
+ In practice:
497
200
 
498
- ## Rule 12: Placeholders are allowed, but they must be obvious and deliberate
201
+ - add or keep the runtime export in `index.js`
202
+ - update the generator if the root declaration needs an explicit function signature
203
+ - run `npm run generate:dts`
499
204
 
500
- If a DTO cannot yet be modeled concretely, keep the placeholder explicit:
205
+ Example consumer-facing signature:
501
206
 
502
- ```js
503
- /** @typedef {Object} WebJobHistorieDTO */
207
+ ```ts
208
+ export function fluentApi(url: string, authManager: FluentAuthManager | null, serviceName: string): FluentApi;
504
209
  ```
505
210
 
506
- and keep it centralized in `api/dtos/index.js` with a note that it is a placeholder.
507
-
508
- Do not scatter placeholder definitions across business API files.
509
-
510
-
511
- ## Rule 13: Avoid duplicate semantic owners when possible
512
-
513
- There are two patterns in this repo:
514
-
515
- - concrete DTO file owns the actual shape
516
- - `dtos/index.js` re-exports or aliases it for convenience
211
+ Rule of thumb:
517
212
 
518
- The concrete source file should remain the semantic owner of the shape.
213
+ - runtime export alone is not enough
214
+ - consumers need the root declaration too
519
215
 
520
- Examples:
521
216
 
522
- - `belege.js` owns `VorgangDTO`
523
- - `produktion.js` owns `ProduktionsfreigabeItemDTO`
524
- - `kunden.js` owns `KontaktDTO`
217
+ ### Add a public class for consumption
525
218
 
526
- `dtos/index.js` may alias them, but should not silently replace a concrete definition with a weaker one.
527
-
528
-
529
- ## Rule 14: If a DTO file references types from C# sources, keep the JSDoc aligned to the source names
530
-
531
- If you add or fix a DTO from C#:
532
-
533
- - preserve the original name
534
- - preserve nullability where clear
535
- - preserve enum value meaning where clear
536
- - preserve nested object types when known
537
-
538
- Example fixes performed in this work came from C# source classes and enums.
539
-
540
-
541
- ## Rule 15: Use clean method-level JSDoc, not deep import expressions
542
-
543
- Preferred:
219
+ If you add a class that consumers should import directly:
544
220
 
545
221
  ```js
546
- /** @typedef {import('../dtos/produktion.js').ProduktionsfreigabeItemDTO} ProduktionsfreigabeItemDTO */
547
-
548
- /**
549
- * @returns {Promise<ProduktionsfreigabeItemDTO[]>}
550
- */
551
- getAllProduktionsfreigabeItems: () => fluentApi.get("ProduktionsfreigabeListe"),
222
+ import { MyClient } from "@gandalan/weblibs";
552
223
  ```
553
224
 
554
- Avoid:
225
+ follow this pattern:
555
226
 
556
227
  ```js
557
228
  /**
558
- * @returns {Promise<import('../dtos/index.js').ProduktionsfreigabeItemDTO[]>}
229
+ * Client for example operations.
559
230
  */
231
+ export class MyClient {
232
+ /**
233
+ * @param {string} baseUrl
234
+ */
235
+ constructor(baseUrl) {
236
+ this.baseUrl = baseUrl;
237
+ }
238
+
239
+ /**
240
+ * @param {string} id
241
+ * @returns {Promise<string>}
242
+ */
243
+ async load(id) {
244
+ return `${this.baseUrl}/${id}`;
245
+ }
246
+ }
560
247
  ```
561
248
 
249
+ To make it consumable:
562
250
 
563
- ## Rule 16: Keep JSDoc formatting strict
564
-
565
- Formatting affects readability and can affect tooling robustness.
566
-
567
- Rules:
251
+ 1. Export the class from its source file.
252
+ 2. Re-export it from `index.js` if it belongs at the package root.
253
+ 3. Run `npm run generate:dts`.
254
+ 4. Verify the class shape appears in `index.d.ts`.
568
255
 
569
- - keep indentation consistent with the file
570
- - keep comment stars aligned
571
- - do not leave malformed comment lines
572
- - do not mix single-quote and double-quote styles against repo lint rules
573
- - run lint fix after large edits in `WebLibs`
256
+ For helper-only local classes that are not part of the public API, do not expose them at the root.
574
257
 
575
258
 
576
- ## Recommended Patterns
259
+ ### Add a new standalone public type
577
260
 
578
- ### Pattern A: DTO-only module
261
+ If you add a new manual type file such as `api/someTypes.js`, keep it simple:
579
262
 
580
263
  ```js
581
264
  /**
582
- * @typedef {Object} ExampleDTO
583
- * @property {string} Guid
584
- * @property {number | null} Version
265
+ * @typedef {Object} ExampleOptions
266
+ * @property {string} id
267
+ * @property {boolean} [enabled=true]
585
268
  */
586
269
 
587
270
  export {};
588
271
  ```
589
272
 
273
+ If that type must be visible to consumers, make sure the file is part of the generator input and regenerate declarations.
590
274
 
591
- ### Pattern B: DTO with cross-file dependency
592
275
 
593
- ```js
594
- /** @typedef {import('./kunden.js').KontaktDTO} KontaktDTO */
276
+ ## Root Consumption Model
595
277
 
596
- /**
597
- * @typedef {Object} VorgangDTO
598
- * @property {KontaktDTO} Kunde
599
- */
278
+ There are two public surfaces:
600
279
 
601
- export {};
602
- ```
280
+ - `index.js` for runtime exports and root JSDoc aliases
281
+ - `index.d.ts` for consumer TypeScript declarations
603
282
 
283
+ `npm run generate:dts` updates both.
604
284
 
605
- ### Pattern C: Business API file
285
+ Do not hand-edit generated root blocks unless you are changing the generator itself.
606
286
 
607
- ```js
608
- /**
609
- * @typedef {import('../fluentApi.js').FluentApi} FluentApi
610
- * @typedef {import('../dtos/produktion.js').ProduktionsfreigabeItemDTO} ProduktionsfreigabeItemDTO
611
- */
612
287
 
613
- /**
614
- * @param {FluentApi} fluentApi
615
- */
616
- export function createProduktionApi(fluentApi) {
617
- return {
618
- /**
619
- * @returns {Promise<ProduktionsfreigabeItemDTO[]>}
620
- */
621
- getAllProduktionsfreigabeItems: () => fluentApi.get("ProduktionsfreigabeListe")
622
- };
623
- }
288
+ ## What to Prefer
624
289
 
625
- /**
626
- * @typedef {ReturnType<typeof createProduktionApi>} ProduktionApi
627
- */
628
- ```
290
+ Prefer:
629
291
 
292
+ ```js
293
+ /** @typedef {import('../dtos/produktion.js').ProduktionsfreigabeItemDTO} ProduktionsfreigabeItemDTO */
294
+ ```
630
295
 
631
- ### Pattern D: Optional parameter with default
296
+ Over:
632
297
 
633
298
  ```js
634
299
  /**
635
- * @param {boolean} [includeDetails=true]
636
- * @param {Date | null} [changedSince=null]
637
- * @returns {Promise<AblageDTO[]>}
300
+ * @returns {Promise<import('../dtos/index.js').ProduktionsfreigabeItemDTO[]>}
638
301
  */
639
302
  ```
640
303
 
304
+ Prefer concrete DTO owner files over `dtos/index.js` when the owning file is known.
641
305
 
642
- ## Edge Cases Checklist
643
-
644
- Before finishing any JSDoc work, verify all of the following.
645
-
646
- ### DTO checklist
647
306
 
648
- - The DTO file is an ES module.
649
- - Every cross-file DTO property type is imported locally or written as an inline import.
650
- - Every enum-like type is documented with the correct primitive union or numeric union.
651
- - Nullability is explicit.
652
- - Arrays use `Type[]` or `Array<Type>` consistently.
653
- - No referenced type name exists only in C# while missing from JSDoc.
654
- - If a placeholder remains, it is explicit and centralized.
307
+ ## What to Avoid
655
308
 
656
- ### API checklist
309
+ Avoid these patterns:
657
310
 
658
- - `FluentApi` is imported with `.js`.
659
- - DTOs used in method docs have top-of-file aliases.
660
- - No inline `import('../dtos/index.js').Type` remains in `@param` or `@returns` unless there is a deliberate reason.
661
- - Optional parameters use square-bracket syntax.
662
- - Default values in code are reflected in JSDoc.
663
- - There is no circular `@returns {XApi}` with `ReturnType<typeof createXApi>`.
664
- - The exported `XApi` typedef exists at the end of the file.
665
-
666
- ### `idasFluentApi` checklist
667
-
668
- - Every business member type is imported explicitly.
669
- - All member properties use one consistent typing strategy.
670
- - The `userInfo` type matches the runtime object shape, not a guessed backend DTO.
311
+ - extensionless JSDoc imports
312
+ - DTO files without `export {}`
313
+ - cross-file DTO references with no local import
314
+ - repeating deep inline imports in every method signature
315
+ - circular API return typing
316
+ - exposing a runtime export without making sure it is declared at the root
671
317
 
672
318
 
673
319
  ## Validation Workflow
674
320
 
675
- Whenever you touch JSDoc in `WebLibs`, validate in this order.
321
+ When you change public JSDoc or exports:
676
322
 
677
- 1. Fix local file diagnostics.
678
- 2. Ensure DTO files are ES modules.
679
- 3. Ensure DTO cross-file property references are imported locally.
680
- 4. Ensure API files use local DTO aliases.
681
- 5. Ensure no circular API `ReturnType` patterns remain.
682
- 6. Run ESLint fix on changed files.
683
- 7. Restart the TS server if IntelliSense still shows stale `any`.
323
+ 1. Fix diagnostics in the file you changed.
324
+ 2. Run `npm run generate:dts`.
325
+ 3. Check that `index.js` and `index.d.ts` reflect the new public shape.
326
+ 4. Verify IntelliSense from the package root.
684
327
 
685
328
 
686
- ## Known Remaining Risk
329
+ ## Quick Checklist
687
330
 
688
- `api/dtos/index.js` still contains some placeholder DTOs that were kept intentionally because no complete JSDoc source model was fully introduced in this pass.
331
+ Before you finish, confirm:
689
332
 
690
- That is acceptable for now as long as:
691
-
692
- - they remain explicit placeholders
693
- - they do not replace stronger concrete definitions
694
- - they are upgraded when the source DTO shape becomes available
333
+ - the file uses `.js` JSDoc imports
334
+ - type-only files end with `export {}`
335
+ - DTO property types are imported locally when needed
336
+ - public API methods use local aliases
337
+ - new root exports are present in both runtime and declarations
338
+ - `npm run generate:dts` has been run
695
339
 
696
340
 
697
341
  ## Bottom Line
698
342
 
699
- If you follow these rules, JSDoc discoverability in this repo stays stable.
700
-
701
- The three most important requirements are:
343
+ If you want a property, function, or class to be easy for consumers to use, do three things:
702
344
 
703
- 1. DTO files must be ES modules.
704
- 2. DTO cross-file property types must be imported locally.
705
- 3. API files must use local typedef aliases and avoid circular or overly indirect typing.
345
+ 1. Define the type clearly in the owning file.
346
+ 2. Export it through the correct public surface.
347
+ 3. Regenerate the root declarations.
706
348
 
707
- If one of those three is violated, IntelliSense will often fall back to `any` even though the comments look valid at first glance.
349
+ That is the whole system.