@gandalan/weblibs 2.0.2 → 2.0.5

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.
@@ -1,7 +1,31 @@
1
1
  /**
2
2
  * @typedef {import('../fluentApi.js').FluentApi} FluentApi
3
- * @typedef {Object & { AnpassungGuid?: string, anpassungGuid?: string }} AnpassungDTO
4
- * @typedef {Object & { AnpassungVorlageGuid?: string, anpassungVorlageGuid?: string }} AnpassungVorlageDTO
3
+ */
4
+
5
+ /**
6
+ * @typedef {Object} AnpassungDTO
7
+ * @property {string} AnpassungGuid
8
+ * @property {string} Art
9
+ * @property {boolean} GiltFuerBesitzer
10
+ * @property {boolean} GiltFuerAlleUntermandanten
11
+ * @property {boolean} GiltFuerZielMandant
12
+ * @property {string} ZielMandantGuid
13
+ * @property {string} Content
14
+ * @property {string} WarengruppeGuid
15
+ * @property {string} ArtikelGuid
16
+ * @property {number} Version
17
+ * @property {string} ChangedDate - ISO date string
18
+ */
19
+
20
+ /**
21
+ * @typedef {Object} AnpassungVorlageDTO
22
+ * @property {string} AnpassungVorlageGuid
23
+ * @property {string} Art
24
+ * @property {string} Name
25
+ * @property {string} Beschreibung
26
+ * @property {string} Content
27
+ * @property {number} Version
28
+ * @property {string} ChangedDate - ISO date string
5
29
  */
6
30
 
7
31
  /**
@@ -6,8 +6,7 @@
6
6
  * @typedef {import('../dtos/produktion.js').ProduktionsDatenDTO} ProduktionsDatenDTO
7
7
  * @typedef {import('../dtos/index.js').AVReserviertItemDTO} AVReserviertItemDTO
8
8
  * @typedef {import('../dtos/belege.js').CalculationInfoDTO} CalculationInfoDTO
9
- * @typedef {Object} AvReportVorgangRequestDto
10
- * @typedef {Object} AvReportVorgangDto
9
+ * @typedef {import('../dtos/index.js').BeleganschriftDTO} BeleganschriftDTO
11
10
  * @typedef {import('../dtos/produktion.js').SaegeDatenHistorieDTO} SaegeDatenHistorieDTO
12
11
  * @typedef {import('../dtos/produktion.js').SaegeDatenResultDTO} SaegeDatenResultDTO
13
12
  * @typedef {import('../dtos/index.js').MaterialBearbeitungsMethodeDTO} MaterialBearbeitungsMethodeDTO
@@ -16,6 +15,41 @@
16
15
  * @typedef {import('../dtos/av.js').SerienMaterialEditDTO} SerienMaterialEditDTO
17
16
  */
18
17
 
18
+ /**
19
+ * @typedef {Object} AvReportVorgangRequestDto
20
+ * @property {Array<string>} VorgangGuids
21
+ */
22
+
23
+ /**
24
+ * Minimalistic DTO for Vorgang in AV reports.
25
+ * @typedef {Object} AvReportVorgangDto
26
+ * @property {string} VorgangGuid
27
+ * @property {number} VorgangsNummer
28
+ * @property {string} Kommission
29
+ * @property {string} Kommission2
30
+ * @property {Array<AvReportBelegDto>} Belege
31
+ * @property {AvReportKontaktDto} Kunde
32
+ */
33
+
34
+ /**
35
+ * Minimalistic DTO for Beleg in AV reports.
36
+ * @typedef {Object} AvReportBelegDto
37
+ * @property {string} BelegGuid
38
+ * @property {BeleganschriftDTO} BelegAdresse
39
+ * @property {BeleganschriftDTO} VersandAdresse
40
+ * @property {boolean} VersandAdresseGleichBelegAdresse
41
+ * @property {string} BelegArt
42
+ * @property {string} Terminwunsch
43
+ * @property {boolean} IstSelbstabholer
44
+ */
45
+
46
+ /**
47
+ * Minimalistic DTO for Kontakt information in AvReportVorgangDto.
48
+ * @typedef {Object} AvReportKontaktDto
49
+ * @property {string} KundenNummer
50
+ * @property {string} Land
51
+ */
52
+
19
53
  /**
20
54
  * AV API - Arbeitsvorbereitung (work preparation) management
21
55
  * @param {FluentApi} fluentApi
@@ -1,6 +1,15 @@
1
1
  /**
2
2
  * @typedef {import('../fluentApi.js').FluentApi} FluentApi
3
+ */
4
+
5
+ /**
3
6
  * @typedef {Object} FileInfoDTO
7
+ * @property {string} FileName
8
+ * @property {number} FileSize
9
+ * @property {string} Modified - ISO date string
10
+ * @property {string} Created - ISO date string
11
+ * @property {string | null} GueltigBis - ISO date string
12
+ * @property {string | null} MandantGuid
4
13
  */
5
14
 
6
15
  /**
@@ -3,11 +3,24 @@
3
3
  * @typedef {import('../dtos/index.js').ChangeDTO} ChangeDTO
4
4
  * @typedef {import('../dtos/index.js').TagInfoDTO} TagInfoDTO
5
5
  * @typedef {import('../dtos/index.js').TagVorlageDTO} TagVorlageDTO
6
- * @typedef {Object} FilterItemDTO
7
6
  * @typedef {import('../dtos/index.js').ChangeInfoDTO} ChangeInfoDTO
8
7
  * @typedef {import('../dtos/index.js').UpdateInfoDTO} UpdateInfoDTO
9
8
  */
10
9
 
10
+ /**
11
+ * @typedef {Object} FilterItemDTO
12
+ * @property {string} FilterGuid
13
+ * @property {string} MandantGuid
14
+ * @property {string} BenutzerGuid
15
+ * @property {string} Title
16
+ * @property {string} Context
17
+ * @property {string} SerializedFilterSetting
18
+ * @property {number} Version
19
+ * @property {string} ChangedDate - ISO date string
20
+ * @property {boolean} IsDeleted
21
+ * @property {number} Reihenfolge
22
+ */
23
+
11
24
  /**
12
25
  * System API - System administration and configuration
13
26
  * @param {FluentApi} fluentApi
@@ -5,7 +5,7 @@
5
5
  * @typedef {import('../dtos/index.js').UIEingabeFeldInfoDTO} UIEingabeFeldInfoDTO
6
6
  * @typedef {import('../dtos/index.js').TagInfoDTO} TagInfoDTO
7
7
  * @typedef {import('../dtos/index.js').TagVorlageDTO} TagVorlageDTO
8
- * @typedef {Object} FilterItemDTO
8
+ * @typedef {import('./systemApi.js').FilterItemDTO} FilterItemDTO
9
9
  */
10
10
 
11
11
  /**
@@ -63,6 +63,7 @@
63
63
  * @property {string} [id] - Unique identifier for the menu item (auto-generated if not provided)
64
64
  * @property {boolean} [selected] - Indicates if the menu item is currently selected (managed by the menu system)
65
65
  * @property {string} [icon] - URL to an icon
66
+ * @property {boolean} [iconAdaptive] - If true, the icon adapts to the active theme (e.g. inverted in dark mode via the host's `icon-adaptive` styling).
66
67
  * @property {string | null} [url] - Relative URL to use for routes
67
68
  * @property {string} [text] - Display text (ignored for separator items)
68
69
  * @property {string | null} [parent] - Parent menu item (optional). If not set, the item will be added to the top level menu.
@@ -96,6 +97,74 @@
96
97
  * @property {NeherApp3ErfassungCache} erfassung
97
98
  */
98
99
 
100
+ /**
101
+ * A single message envelope delivered to handlers.
102
+ * @typedef {Object} NeherMessage
103
+ * @property {string} id - Unique message id (`crypto.randomUUID`).
104
+ * @property {string} type - Message kind, e.g. `"artikel.selected"`.
105
+ * @property {string | null} to - Target module name (directed) or `null` (broadcast).
106
+ * @property {string | null} from - Sender module name (stamped by the endpoint) or `null`.
107
+ * @property {any} payload - Arbitrary payload.
108
+ * @property {number} ts - Timestamp (`Date.now`).
109
+ */
110
+
111
+ /**
112
+ * Handler invoked with the full message envelope.
113
+ * @callback MessageHandler
114
+ * @param {NeherMessage} message
115
+ * @returns {void}
116
+ */
117
+
118
+ /**
119
+ * Subscription type pattern: exact (`"a.b"`), prefix glob (`"a.*"`), all (`"*"`)
120
+ * or a list of patterns.
121
+ * @typedef {string | string[]} TypePattern
122
+ */
123
+
124
+ /**
125
+ * Options for `send`/`broadcast`.
126
+ * @typedef {Object} SendOptions
127
+ * @property {string} [from] - Sender module name (bus-level `send`/`broadcast` only; set automatically via an endpoint).
128
+ * @property {boolean} [retain] - Keep this `(to, type)` as a last value; subscribers that register later receive it immediately. Default `false`.
129
+ * @property {boolean} [requireRecipient] - If nobody received it, call `onUndeliverable` instead of silently dropping. Default `false`.
130
+ * @property {boolean} [deliverWhenAvailable] - If nobody is listening, buffer the directed message and deliver it when the target registers. Default `false`.
131
+ * @property {boolean} [echo] - For broadcast: also deliver to the sender itself. Default `false`.
132
+ * @property {number} [ttlMs] - Lifetime for buffered messages. Default `30000`.
133
+ * @property {(message: NeherMessage) => void} [onUndeliverable] - Callback invoked with the envelope when `requireRecipient` and no recipient.
134
+ */
135
+
136
+ /**
137
+ * Delivery information returned by `send`/`broadcast` — never the result of a handler.
138
+ * @typedef {Object} Delivery
139
+ * @property {boolean} delivered - At least one recipient was reached.
140
+ * @property {number} recipients - Number of distinct modules delivered to.
141
+ * @property {boolean} queued - Buffered for a later recipient.
142
+ */
143
+
144
+ /**
145
+ * A registered endpoint, returned by `messages.register`. `register` is
146
+ * idempotent; each handle's `dispose` only removes subscriptions made through it.
147
+ * @typedef {Object} Endpoint
148
+ * @property {string} name - The module name of this endpoint.
149
+ * @property {(type: TypePattern, handler: MessageHandler) => (() => void)} on - Subscribe; returns an unsubscribe function.
150
+ * @property {(to: string, type: string, payload?: any, options?: SendOptions) => Delivery} send - Directed message (`from` is stamped automatically).
151
+ * @property {(type: string, payload?: any, options?: SendOptions) => Delivery} broadcast - Broadcast (`from` is stamped automatically).
152
+ * @property {() => void} dispose - Remove all subscriptions created through this handle.
153
+ */
154
+
155
+ /**
156
+ * In-realm message bus for module-to-module communication, exposed at
157
+ * `neherapp3.messages`. Messaging, not RPC: `send`/`broadcast` return delivery
158
+ * information, never a handler's result.
159
+ * @typedef {Object} NeherApp3Messages
160
+ * @property {(moduleName: string) => Endpoint} register - Register a module as a reachable endpoint.
161
+ * @property {(to: string, type: string, payload?: any, options?: SendOptions) => Delivery} send - Directed message (`from` via `options.from`).
162
+ * @property {(type: string, payload?: any, options?: SendOptions) => Delivery} broadcast - Broadcast to all subscribers (`from` via `options.from`).
163
+ * @property {(moduleName: string) => boolean} isReachable - Does the module have at least one live handler?
164
+ * @property {(moduleName: string) => boolean} isKnown - Is the module registered (loaded via `addApp`)?
165
+ * @property {string[]} reachable - Reactive list of all currently reachable module names.
166
+ */
167
+
99
168
  /**
100
169
  * @typedef {Object} NeherApp3
101
170
  * @property {(menuItem: NeherApp3MenuItem) => void} addMenuItem - Adds a menu item. If an item with the same `id` already exists it is replaced.
@@ -105,6 +174,7 @@
105
174
  * @property {(message: string, type?: NeherApp3NotifyType, cb?: function) => void} notify - Shows a notification. Type defaults to 0 (info). Callback is optional.
106
175
  * @property {NeherApp3ApiCollection} api
107
176
  * @property {NeherApp3CacheCollection} cache
177
+ * @property {NeherApp3Messages} messages - In-realm message bus for module-to-module communication.
108
178
  * @property {boolean} isEmbedded - Indicates if the app is embedded inside i3
109
179
  */
110
180
 
package/index.d.ts CHANGED
@@ -93,6 +93,30 @@ export type AnpassungApi = {
93
93
  vorlage: { getAll: () => Promise<AnpassungVorlageDTO[]>; get: (guid: string) => Promise<AnpassungVorlageDTO>; save: (dto: AnpassungVorlageDTO) => Promise<void>; delete: (guid: string) => Promise<void> };
94
94
  };
95
95
 
96
+ export type AnpassungDTO = {
97
+ AnpassungGuid: string;
98
+ Art: string;
99
+ GiltFuerBesitzer: boolean;
100
+ GiltFuerAlleUntermandanten: boolean;
101
+ GiltFuerZielMandant: boolean;
102
+ ZielMandantGuid: string;
103
+ Content: string;
104
+ WarengruppeGuid: string;
105
+ ArtikelGuid: string;
106
+ Version: number;
107
+ ChangedDate: string;
108
+ };
109
+
110
+ export type AnpassungVorlageDTO = {
111
+ AnpassungVorlageGuid: string;
112
+ Art: string;
113
+ Name: string;
114
+ Beschreibung: string;
115
+ Content: string;
116
+ Version: number;
117
+ ChangedDate: string;
118
+ };
119
+
96
120
  export type ApiVersionDTO = {
97
121
  Version: string;
98
122
  Environment: string;
@@ -212,6 +236,34 @@ export type AvApi = {
212
236
  material: { serieBerechnen: (serieGuid: string) => Promise<void>; getForSerie: (serieGuid: string) => Promise<MaterialbedarfDTO[]>; getOffenerBedarfV2: (serieGuid: string, filterCsvExportedMaterial?: boolean) => Promise<MaterialbedarfDTO[]>; getOffenerBedarf: (serieGuid: string) => Promise<MaterialbedarfDTO[]>; resetForSerie: (serieGuid: string) => Promise<void>; berechnenForFunction: (serieGuid: string, mandantId: number) => Promise<string[]>; resetFromAvPosForFunction: (avPosGuid: string, mandantId: number) => Promise<string[]>; addOrUpdate: (dto: MaterialbedarfDTO) => Promise<SerienMaterialEditDTO>; delete: (materialbedarfGuid: string) => Promise<void> };
213
237
  };
214
238
 
239
+ export type AvReportBelegDto = {
240
+ BelegGuid: string;
241
+ BelegAdresse: BeleganschriftDTO;
242
+ VersandAdresse: BeleganschriftDTO;
243
+ VersandAdresseGleichBelegAdresse: boolean;
244
+ BelegArt: string;
245
+ Terminwunsch: string;
246
+ IstSelbstabholer: boolean;
247
+ };
248
+
249
+ export type AvReportKontaktDto = {
250
+ KundenNummer: string;
251
+ Land: string;
252
+ };
253
+
254
+ export type AvReportVorgangDto = {
255
+ VorgangGuid: string;
256
+ VorgangsNummer: number;
257
+ Kommission: string;
258
+ Kommission2: string;
259
+ Belege: Array<AvReportBelegDto>;
260
+ Kunde: AvReportKontaktDto;
261
+ };
262
+
263
+ export type AvReportVorgangRequestDto = {
264
+ VorgangGuids: Array<string>;
265
+ };
266
+
215
267
  export type AVReserviertItemDTO = {
216
268
  Variante: string;
217
269
  ArtikelNummer: string;
@@ -853,6 +905,12 @@ export type CsvExportCombinationDTO = {
853
905
  ExportFarbArten: ExportFarbArt[];
854
906
  };
855
907
 
908
+ export type Delivery = {
909
+ delivered: boolean;
910
+ recipients: number;
911
+ queued: boolean;
912
+ };
913
+
856
914
  export type DevOpsStatusDTO = {
857
915
  Env: string;
858
916
  DbInfo: string;
@@ -860,6 +918,14 @@ export type DevOpsStatusDTO = {
860
918
  PendingMigrations: string[];
861
919
  };
862
920
 
921
+ export type Endpoint = {
922
+ name: string;
923
+ on: (type: TypePattern, handler: MessageHandler) => (() => void);
924
+ send: (to: string, type: string, payload?: any, options?: SendOptions) => Delivery;
925
+ broadcast: (type: string, payload?: any, options?: SendOptions) => Delivery;
926
+ dispose: () => void;
927
+ };
928
+
863
929
  export type EnvironmentConfig = {
864
930
  name: string;
865
931
  version: string;
@@ -1018,6 +1084,28 @@ export type FileApi = {
1018
1084
  data: { get: (filename: string) => Promise<Uint8Array>; getList: (directory?: string) => Promise<FileInfoDTO[]>; save: (fileName: string, data: Uint8Array) => Promise<void>; delete: (filename: string) => Promise<void> };
1019
1085
  };
1020
1086
 
1087
+ export type FileInfoDTO = {
1088
+ FileName: string;
1089
+ FileSize: number;
1090
+ Modified: string;
1091
+ Created: string;
1092
+ GueltigBis: string | null;
1093
+ MandantGuid: string | null;
1094
+ };
1095
+
1096
+ export type FilterItemDTO = {
1097
+ FilterGuid: string;
1098
+ MandantGuid: string;
1099
+ BenutzerGuid: string;
1100
+ Title: string;
1101
+ Context: string;
1102
+ SerializedFilterSetting: string;
1103
+ Version: number;
1104
+ ChangedDate: string;
1105
+ IsDeleted: boolean;
1106
+ Reihenfolge: number;
1107
+ };
1108
+
1021
1109
  export type FluentApi = {
1022
1110
  baseUrl: string;
1023
1111
  authManager: FluentAuthManager|null;
@@ -1841,7 +1929,7 @@ export type MaterialBearbeitungsMethodeDTO = {
1841
1929
  ChangedDate: string;
1842
1930
  };
1843
1931
 
1844
- export type MaterialbedarfCutOptimization = object.<string, any>;
1932
+ export type MaterialbedarfCutOptimization = Record<string, any>;
1845
1933
 
1846
1934
  export type MaterialbedarfDTO = {
1847
1935
  MaterialBedarfGuid: string;
@@ -1942,6 +2030,8 @@ export type MaterialDTO = {
1942
2030
  MoeglicheBearbeitungsMethoden: Array<string>;
1943
2031
  };
1944
2032
 
2033
+ export type MessageHandler = (message: NeherMessage) => void;
2034
+
1945
2035
  export type NachrichtenDTO = {
1946
2036
  NachrichtGuid: string;
1947
2037
  MandantGuid: string;
@@ -1961,6 +2051,7 @@ export type NeherApp3 = {
1961
2051
  notify: (message: string, type?: NeherApp3NotifyType, cb?: Function) => void;
1962
2052
  api: NeherApp3ApiCollection;
1963
2053
  cache: NeherApp3CacheCollection;
2054
+ messages: NeherApp3Messages;
1964
2055
  isEmbedded: boolean;
1965
2056
  };
1966
2057
 
@@ -1994,6 +2085,7 @@ export type NeherApp3MenuItem = {
1994
2085
  id?: string;
1995
2086
  selected?: boolean;
1996
2087
  icon?: string;
2088
+ iconAdaptive?: boolean;
1997
2089
  url?: string | null;
1998
2090
  text?: string;
1999
2091
  parent?: string | null;
@@ -2001,6 +2093,15 @@ export type NeherApp3MenuItem = {
2001
2093
  separator?: boolean;
2002
2094
  };
2003
2095
 
2096
+ export type NeherApp3Messages = {
2097
+ register: (moduleName: string) => Endpoint;
2098
+ send: (to: string, type: string, payload?: any, options?: SendOptions) => Delivery;
2099
+ broadcast: (type: string, payload?: any, options?: SendOptions) => Delivery;
2100
+ isReachable: (moduleName: string) => boolean;
2101
+ isKnown: (moduleName: string) => boolean;
2102
+ reachable: string[];
2103
+ };
2104
+
2004
2105
  export type NeherApp3Module = {
2005
2106
  moduleName: string;
2006
2107
  setup?: (context: NeherApp3SetupContext) => void | Promise<void>;
@@ -2021,6 +2122,15 @@ export type NeherApp3Props = {
2021
2122
 
2022
2123
  export type NeherApp3SetupContext = NeherApp3Props & { neherapp3: NeherApp3 };
2023
2124
 
2125
+ export type NeherMessage = {
2126
+ id: string;
2127
+ type: string;
2128
+ to: string | null;
2129
+ from: string | null;
2130
+ payload: any;
2131
+ ts: number;
2132
+ };
2133
+
2024
2134
  export type OberflaecheDTO = {
2025
2135
  OberflaecheGuid: string;
2026
2136
  Bezeichnung: string;
@@ -2095,11 +2205,11 @@ export type PreisermittlungsEinstellungenDTO = {
2095
2205
  EndpreisRundungsModus: string;
2096
2206
  SonderfarbZuschlaege: string;
2097
2207
  BruttoPreisErmitteln: boolean;
2098
- AufpreisAnpassungen: object.<string, AufpreisAnpassungDTO[]>;
2099
- PreisfaktorAnpassungen: object.<string, number>;
2100
- ZuschnittpreisfaktorAnpassungen: object.<string, number>;
2101
- AufpreisfaktorAnpassungen: object.<string, number>;
2102
- GrenzfreigabeAnpassungen: object.<string, boolean>;
2208
+ AufpreisAnpassungen: Record<string, AufpreisAnpassungDTO[]>;
2209
+ PreisfaktorAnpassungen: Record<string, number>;
2210
+ ZuschnittpreisfaktorAnpassungen: Record<string, number>;
2211
+ AufpreisfaktorAnpassungen: Record<string, number>;
2212
+ GrenzfreigabeAnpassungen: Record<string, boolean>;
2103
2213
  MbAufpreis: number;
2104
2214
  Mb_v_Fix_Aufpreis: number|null;
2105
2215
  Mb_Klebeband_Aufpreis: number|null;
@@ -2548,6 +2658,16 @@ export type SchnittKonturOperationDTO = {
2548
2658
 
2549
2659
  export type SchnittoptimierungsOptionen = ('Keine'|'Lieferdatum'|'Serie'|'FarbeOberflaeche');
2550
2660
 
2661
+ export type SendOptions = {
2662
+ from?: string;
2663
+ retain?: boolean;
2664
+ requireRecipient?: boolean;
2665
+ deliverWhenAvailable?: boolean;
2666
+ echo?: boolean;
2667
+ ttlMs?: number;
2668
+ onUndeliverable?: (message: NeherMessage) => void;
2669
+ };
2670
+
2551
2671
  export type SerieAuslastungDTO = {
2552
2672
  IstSumme: boolean;
2553
2673
  Produktfamilie: string;
@@ -2727,6 +2847,8 @@ export type TemplateDTO = {
2727
2847
  Benutzer: string;
2728
2848
  };
2729
2849
 
2850
+ export type TypePattern = string | string[];
2851
+
2730
2852
  export type UiApi = {
2731
2853
  getAllUiDefinitions: () => Promise<UIDefinitionDTO[]>;
2732
2854
  getUiDefinition: (guid: string) => Promise<UIDefinitionDTO>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gandalan/weblibs",
3
- "version": "2.0.2",
3
+ "version": "2.0.5",
4
4
  "description": "WebLibs for Gandalan JS/TS projects",
5
5
  "keywords": [
6
6
  "gandalan"
@@ -23,14 +23,14 @@
23
23
  "dependencies": {
24
24
  "@mdi/js": "^7.4.47",
25
25
  "jwt-decode": "^4.0.0",
26
- "validator": "^13.12.0"
26
+ "validator": "^13.15.35"
27
27
  },
28
28
  "devDependencies": {
29
- "@babel/core": "^7.26.9",
30
- "@babel/eslint-parser": "^7.26.8",
31
- "@eslint/js": "^9.21.0",
32
- "eslint": "^9.21.0",
33
- "globals": "^15.15.0"
29
+ "@babel/core": "^8.0.1",
30
+ "@babel/eslint-parser": "^8.0.1",
31
+ "@eslint/js": "^10.0.1",
32
+ "eslint": "^10.5.0",
33
+ "globals": "^17.7.0"
34
34
  },
35
35
  "publishConfig": {
36
36
  "access": "public",
@@ -429,7 +429,7 @@ function parseObjectLiteralProperties(objectSource, scopeTypeMap) {
429
429
 
430
430
  index = skipWhitespaceAndComments(objectSource, index);
431
431
 
432
- let typeExpression = "any";
432
+ let typeExpression;
433
433
  let optional = false;
434
434
 
435
435
  if (objectSource[index] === ":") {
@@ -858,35 +858,56 @@ function isSimpleImportAlias(typeExpression) {
858
858
  return simpleImportTypePattern.test(typeExpression.replace(/\s+/g, ""));
859
859
  }
860
860
 
861
+ function splitBlockByTagBoundaries(normalizedBlock) {
862
+ const tagPattern = /@(?:typedef|callback)\b/g;
863
+ const startIndices = [];
864
+ let match;
865
+
866
+ while ((match = tagPattern.exec(normalizedBlock)) !== null) {
867
+ startIndices.push(match.index);
868
+ }
869
+
870
+ if (startIndices.length <= 1) {
871
+ return [normalizedBlock];
872
+ }
873
+
874
+ return startIndices.map((startIndex, position) => {
875
+ const endIndex = position + 1 < startIndices.length ? startIndices[position + 1] : normalizedBlock.length;
876
+ return normalizedBlock.slice(startIndex, endIndex);
877
+ });
878
+ }
879
+
861
880
  function extractPublicTypeEntries(source, filePath) {
862
881
  const entries = [];
863
882
 
864
883
  for (const block of getJSDocBlocks(source).map(normalizeJSDocBlock)) {
865
- const typedefEntry = extractTypedefEntry(block);
884
+ for (const segment of splitBlockByTagBoundaries(block)) {
885
+ const typedefEntry = extractTypedefEntry(segment);
866
886
 
867
- if (typedefEntry) {
868
- const inferredCreateApiName = typedefEntry.typeExpression.match(returnTypeOfCreateApiPattern)?.[1] ?? null;
887
+ if (typedefEntry) {
888
+ const inferredCreateApiName = typedefEntry.typeExpression.match(returnTypeOfCreateApiPattern)?.[1] ?? null;
869
889
 
870
- if (inferredCreateApiName) {
871
- const inferredObjectEntry = inferReturnTypeObjectEntry(source, filePath, typedefEntry.name, inferredCreateApiName);
890
+ if (inferredCreateApiName) {
891
+ const inferredObjectEntry = inferReturnTypeObjectEntry(source, filePath, typedefEntry.name, inferredCreateApiName);
872
892
 
873
- if (inferredObjectEntry) {
874
- entries.push(inferredObjectEntry);
875
- continue;
893
+ if (inferredObjectEntry) {
894
+ entries.push(inferredObjectEntry);
895
+ continue;
896
+ }
876
897
  }
877
- }
878
898
 
879
- if (!isSimpleImportAlias(typedefEntry.typeExpression)) {
880
- entries.push({ ...typedefEntry, filePath });
881
- }
899
+ if (!isSimpleImportAlias(typedefEntry.typeExpression)) {
900
+ entries.push({ ...typedefEntry, filePath });
901
+ }
882
902
 
883
- continue;
884
- }
903
+ continue;
904
+ }
885
905
 
886
- const callbackEntry = extractCallbackEntry(block);
906
+ const callbackEntry = extractCallbackEntry(segment);
887
907
 
888
- if (callbackEntry) {
889
- entries.push({ ...callbackEntry, filePath });
908
+ if (callbackEntry) {
909
+ entries.push({ ...callbackEntry, filePath });
910
+ }
890
911
  }
891
912
  }
892
913
 
@@ -940,15 +961,20 @@ function replaceObjectGenerics(typeExpression, transformTypeExpression) {
940
961
  let result = "";
941
962
 
942
963
  for (let index = 0; index < typeExpression.length; index += 1) {
943
- if (!typeExpression.startsWith("Object<", index)) {
964
+ // Support both the TypeScript form (Object<...>) and the dotted JSDoc form (Object.<...>).
965
+ const isDottedForm = typeExpression.startsWith("Object.<", index);
966
+ const isPlainForm = typeExpression.startsWith("Object<", index);
967
+
968
+ if (!isDottedForm && !isPlainForm) {
944
969
  result += typeExpression[index];
945
970
  continue;
946
971
  }
947
972
 
973
+ const openAngleIndex = index + (isDottedForm ? "Object.".length : "Object".length);
948
974
  let angleDepth = 0;
949
975
  let closingIndex = -1;
950
976
 
951
- for (let cursor = index + "Object".length; cursor < typeExpression.length; cursor += 1) {
977
+ for (let cursor = openAngleIndex; cursor < typeExpression.length; cursor += 1) {
952
978
  const character = typeExpression[cursor];
953
979
 
954
980
  if (character === "<") {
@@ -968,7 +994,7 @@ function replaceObjectGenerics(typeExpression, transformTypeExpression) {
968
994
  continue;
969
995
  }
970
996
 
971
- const genericContent = typeExpression.slice(index + "Object<".length, closingIndex);
997
+ const genericContent = typeExpression.slice(openAngleIndex + 1, closingIndex);
972
998
  const genericParts = splitTopLevel(genericContent, ",");
973
999
 
974
1000
  if (genericParts.length === 2) {