@gandalan/weblibs 1.5.28 → 1.5.30
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 +170 -528
- package/api/neherApp3Types.js +1 -0
- package/index.d.ts +1 -0
- package/index.js +4 -23
- package/package.json +2 -2
- package/scripts/{generate-root-dto-typedefs.mjs → generate-dts.mjs} +1 -286
- package/api/neherApp3Types.d.ts +0 -85
package/JSDOC.md
CHANGED
|
@@ -1,390 +1,159 @@
|
|
|
1
|
-
# JSDoc
|
|
1
|
+
# JSDoc Guide for WebLibs
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This guide explains the small set of rules that keep IntelliSense working for consumers of `@gandalan/weblibs`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Use it when you add:
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
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
|
-
|
|
15
|
+
## Goal
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
Public types must stay discoverable from:
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
- `import("@gandalan/weblibs").TypeName`
|
|
20
|
+
- `import { someFunction } from "@gandalan/weblibs"`
|
|
21
|
+
- generated `index.d.ts`
|
|
19
22
|
|
|
20
|
-
The
|
|
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
|
-
|
|
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
|
-
|
|
36
|
+
## Basic Rules
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @returns {ProduktionApi}
|
|
38
|
-
*/
|
|
39
|
-
export function createProduktionApi(fluentApi) {
|
|
40
|
-
```
|
|
38
|
+
### 1. Make type-only files real modules
|
|
41
39
|
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
109
|
-
- using an inline import in the property type.
|
|
49
|
+
### 2. Always include `.js` in import paths
|
|
110
50
|
|
|
111
|
-
|
|
51
|
+
Use:
|
|
112
52
|
|
|
113
53
|
```js
|
|
114
|
-
|
|
54
|
+
import("../dtos/belege.js").VorgangDTO
|
|
115
55
|
```
|
|
116
56
|
|
|
117
|
-
|
|
57
|
+
Not:
|
|
118
58
|
|
|
119
59
|
```js
|
|
120
|
-
|
|
60
|
+
import("../dtos/belege").VorgangDTO
|
|
121
61
|
```
|
|
122
62
|
|
|
123
63
|
|
|
124
|
-
###
|
|
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
|
-
|
|
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('
|
|
71
|
+
/** @typedef {import('./kunden.js').KontaktDTO} KontaktDTO */
|
|
147
72
|
|
|
148
73
|
/**
|
|
149
|
-
* @
|
|
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
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
104
|
+
Then use those aliases in `@param` and `@returns`.
|
|
331
105
|
|
|
332
|
-
Why:
|
|
333
106
|
|
|
334
|
-
|
|
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
|
-
|
|
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
|
-
|
|
116
|
+
Example:
|
|
342
117
|
|
|
343
118
|
```js
|
|
344
|
-
/** @typedef {import('
|
|
345
|
-
```
|
|
119
|
+
/** @typedef {import('./kunden.js').BeleganschriftDTO} BeleganschriftDTO */
|
|
346
120
|
|
|
347
|
-
|
|
121
|
+
/**
|
|
122
|
+
* @typedef {Object} BelegDTO
|
|
123
|
+
* @property {string} BelegGuid
|
|
124
|
+
* @property {BeleganschriftDTO} BelegAdresse
|
|
125
|
+
* @property {number | null} Total
|
|
126
|
+
*/
|
|
348
127
|
|
|
349
|
-
|
|
350
|
-
/** @typedef {import('../dtos/index.js').LoginDTO} LoginDTO */
|
|
128
|
+
export {};
|
|
351
129
|
```
|
|
352
130
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
Why:
|
|
131
|
+
Rules:
|
|
356
132
|
|
|
357
|
-
-
|
|
358
|
-
-
|
|
359
|
-
-
|
|
133
|
+
- Mark nullability explicitly.
|
|
134
|
+
- Match runtime names exactly.
|
|
135
|
+
- Mark optional properties only if they are actually optional.
|
|
360
136
|
|
|
361
137
|
|
|
362
|
-
|
|
138
|
+
### Add a function to a business API
|
|
363
139
|
|
|
364
|
-
|
|
140
|
+
Use this pattern:
|
|
365
141
|
|
|
366
142
|
```js
|
|
367
143
|
/**
|
|
368
|
-
* @
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
* @
|
|
459
|
-
|
|
179
|
+
* @returns {Promise<AblageDTO[]>}
|
|
180
|
+
*/
|
|
460
181
|
```
|
|
461
182
|
|
|
462
|
-
|
|
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
|
-
|
|
480
|
-
|
|
481
|
-
Prefer:
|
|
188
|
+
If a function should be imported from the package root:
|
|
482
189
|
|
|
483
190
|
```js
|
|
484
|
-
|
|
485
|
-
* @property {number | null} VE_Menge
|
|
486
|
-
* @property {Array<BelegPositionDTO>} PositionsObjekte
|
|
191
|
+
import { fluentApi } from "@gandalan/weblibs";
|
|
487
192
|
```
|
|
488
193
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
Use placeholders only when:
|
|
194
|
+
then both of these must be true:
|
|
492
195
|
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
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
|
-
|
|
205
|
+
Example consumer-facing signature:
|
|
501
206
|
|
|
502
|
-
```
|
|
503
|
-
|
|
207
|
+
```ts
|
|
208
|
+
export function fluentApi(url: string, authManager: FluentAuthManager | null, serviceName: string): FluentApi;
|
|
504
209
|
```
|
|
505
210
|
|
|
506
|
-
|
|
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
|
-
|
|
213
|
+
- runtime export alone is not enough
|
|
214
|
+
- consumers need the root declaration too
|
|
519
215
|
|
|
520
|
-
Examples:
|
|
521
216
|
|
|
522
|
-
|
|
523
|
-
- `produktion.js` owns `ProduktionsfreigabeItemDTO`
|
|
524
|
-
- `kunden.js` owns `KontaktDTO`
|
|
217
|
+
### Add a public class for consumption
|
|
525
218
|
|
|
526
|
-
|
|
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
|
-
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* @returns {Promise<ProduktionsfreigabeItemDTO[]>}
|
|
550
|
-
*/
|
|
551
|
-
getAllProduktionsfreigabeItems: () => fluentApi.get("ProduktionsfreigabeListe"),
|
|
222
|
+
import { MyClient } from "@gandalan/weblibs";
|
|
552
223
|
```
|
|
553
224
|
|
|
554
|
-
|
|
225
|
+
follow this pattern:
|
|
555
226
|
|
|
556
227
|
```js
|
|
557
228
|
/**
|
|
558
|
-
*
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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
|
-
-
|
|
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
|
-
|
|
259
|
+
### Add a new standalone public type
|
|
577
260
|
|
|
578
|
-
|
|
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}
|
|
583
|
-
* @property {string}
|
|
584
|
-
* @property {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
296
|
+
Over:
|
|
632
297
|
|
|
633
298
|
```js
|
|
634
299
|
/**
|
|
635
|
-
* @
|
|
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
|
-
|
|
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
|
-
|
|
309
|
+
Avoid these patterns:
|
|
657
310
|
|
|
658
|
-
-
|
|
659
|
-
-
|
|
660
|
-
-
|
|
661
|
-
-
|
|
662
|
-
-
|
|
663
|
-
-
|
|
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
|
-
|
|
321
|
+
When you change public JSDoc or exports:
|
|
676
322
|
|
|
677
|
-
1. Fix
|
|
678
|
-
2.
|
|
679
|
-
3.
|
|
680
|
-
4.
|
|
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
|
-
##
|
|
329
|
+
## Quick Checklist
|
|
687
330
|
|
|
688
|
-
|
|
331
|
+
Before you finish, confirm:
|
|
689
332
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
-
|
|
693
|
-
-
|
|
694
|
-
-
|
|
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
|
|
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.
|
|
704
|
-
2.
|
|
705
|
-
3.
|
|
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
|
-
|
|
349
|
+
That is the whole system.
|