@lenne.tech/ng-base 13.6.3 → 13.6.6

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.
Files changed (165) hide show
  1. package/base-components/components/checkbox/checkbox.component.d.ts +1 -1
  2. package/base-prototype/base-prototype.module.d.ts +6 -5
  3. package/base-prototype/pages/forgot-password/forgot-password.component.d.ts +7 -2
  4. package/base-prototype/pages/login/login.component.d.ts +8 -2
  5. package/base-prototype/pages/register/register.component.d.ts +8 -2
  6. package/esm2020/base-components/components/checkbox/checkbox.component.mjs +3 -3
  7. package/esm2020/base-components/components/input/input.component.mjs +3 -3
  8. package/esm2020/base-prototype/base-prototype.module.mjs +5 -4
  9. package/esm2020/base-prototype/pages/forgot-password/forgot-password.component.mjs +30 -9
  10. package/esm2020/base-prototype/pages/login/login.component.mjs +46 -9
  11. package/esm2020/base-prototype/pages/register/register.component.mjs +45 -11
  12. package/esm2020/public-api.mjs +1 -42
  13. package/esm2020/shared/classes/auth.class.mjs +16 -0
  14. package/esm2020/shared/classes/basic-user.class.mjs +51 -0
  15. package/esm2020/shared/classes/graphql-enum.class.mjs +9 -0
  16. package/esm2020/shared/classes/graphql-meta.class.mjs +171 -0
  17. package/esm2020/shared/classes/graphql-type.class.mjs +13 -0
  18. package/esm2020/shared/classes/helper.class.mjs +304 -0
  19. package/esm2020/shared/classes/standard.class.mjs +40 -0
  20. package/esm2020/{src → shared}/enums/comparison-operator.enum.mjs +1 -1
  21. package/esm2020/shared/enums/graphql-request-type.enum.mjs +10 -0
  22. package/esm2020/shared/enums/logical-operator.enum.mjs +10 -0
  23. package/esm2020/shared/enums/sort-order.enum.mjs +6 -0
  24. package/esm2020/shared/functions/ws-client.function.mjs +39 -0
  25. package/esm2020/shared/interfaces/base-module-config.interface.mjs +3 -0
  26. package/esm2020/shared/interfaces/can-component-deactivate.interface.mjs +2 -0
  27. package/esm2020/shared/interfaces/combined-filter-input.interface.mjs +2 -0
  28. package/esm2020/shared/interfaces/field-object.interface.mjs +2 -0
  29. package/esm2020/shared/interfaces/field.interface.mjs +2 -0
  30. package/esm2020/shared/interfaces/filter-input.interface.mjs +2 -0
  31. package/esm2020/shared/interfaces/find-args.interface.mjs +2 -0
  32. package/esm2020/shared/interfaces/graphql-fields-object.interface.mjs +2 -0
  33. package/esm2020/shared/interfaces/graphql-options.interface.mjs +2 -0
  34. package/esm2020/shared/interfaces/graphql-plus-options.interfacen.mjs +2 -0
  35. package/esm2020/shared/interfaces/graphql-type-collection.interface.mjs +2 -0
  36. package/esm2020/shared/interfaces/single-filter-input.interface.mjs +2 -0
  37. package/esm2020/shared/interfaces/sort-input.interface.mjs +2 -0
  38. package/esm2020/shared/interfaces/time-components.interface.mjs +2 -0
  39. package/esm2020/shared/lenne.tech-ng-base-shared.mjs +5 -0
  40. package/esm2020/shared/public-api.mjs +51 -0
  41. package/esm2020/shared/services/auth.service.mjs +71 -0
  42. package/esm2020/shared/services/forms.service.mjs +25 -0
  43. package/esm2020/shared/services/graphql-meta.service.mjs +123 -0
  44. package/esm2020/shared/services/graphql-plus.service.mjs +84 -0
  45. package/esm2020/shared/services/graphql.service.mjs +441 -0
  46. package/esm2020/shared/services/image.service.mjs +102 -0
  47. package/esm2020/shared/services/loader.service.mjs +29 -0
  48. package/esm2020/shared/services/scroll.service.mjs +179 -0
  49. package/esm2020/shared/services/storage.service.mjs +132 -0
  50. package/esm2020/shared/services/user.service.mjs +82 -0
  51. package/esm2020/shared/services/ws.service.mjs +16 -0
  52. package/esm2020/shared/types/graphql-fields.type.mjs +2 -0
  53. package/esm2020/shared/types/storage.type.mjs +2 -0
  54. package/esm2020/shared/validators/match.validator.mjs +19 -0
  55. package/esm2020/src/base.module.mjs +14 -11
  56. package/esm2020/src/directives/match-height.directive.mjs +2 -2
  57. package/esm2020/src/factories/apollo-options.factory.mjs +14 -12
  58. package/esm2020/src/guards/auth.guard.mjs +3 -3
  59. package/esm2020/src/guards/can-deactivate.guard.mjs +1 -1
  60. package/esm2020/src/guards/logout.guard.mjs +2 -2
  61. package/esm2020/src/services/theme.service.mjs +2 -2
  62. package/fesm2015/lenne.tech-ng-base-base-components.mjs +4 -4
  63. package/fesm2015/lenne.tech-ng-base-base-components.mjs.map +1 -1
  64. package/fesm2015/lenne.tech-ng-base-base-prototype.mjs +113 -22
  65. package/fesm2015/lenne.tech-ng-base-base-prototype.mjs.map +1 -1
  66. package/fesm2015/lenne.tech-ng-base-shared.mjs +1878 -0
  67. package/fesm2015/lenne.tech-ng-base-shared.mjs.map +1 -0
  68. package/fesm2015/lenne.tech-ng-base.mjs +57 -1799
  69. package/fesm2015/lenne.tech-ng-base.mjs.map +1 -1
  70. package/fesm2020/lenne.tech-ng-base-base-components.mjs +4 -4
  71. package/fesm2020/lenne.tech-ng-base-base-components.mjs.map +1 -1
  72. package/fesm2020/lenne.tech-ng-base-base-prototype.mjs +111 -22
  73. package/fesm2020/lenne.tech-ng-base-base-prototype.mjs.map +1 -1
  74. package/fesm2020/lenne.tech-ng-base-shared.mjs +1939 -0
  75. package/fesm2020/lenne.tech-ng-base-shared.mjs.map +1 -0
  76. package/fesm2020/lenne.tech-ng-base.mjs +57 -1854
  77. package/fesm2020/lenne.tech-ng-base.mjs.map +1 -1
  78. package/package.json +10 -1
  79. package/public-api.d.ts +0 -36
  80. package/shared/classes/auth.class.d.ts +9 -0
  81. package/{src → shared}/classes/basic-user.class.d.ts +0 -0
  82. package/{src → shared}/classes/graphql-enum.class.d.ts +0 -0
  83. package/{src → shared}/classes/graphql-meta.class.d.ts +0 -0
  84. package/{src → shared}/classes/graphql-type.class.d.ts +0 -0
  85. package/{src → shared}/classes/helper.class.d.ts +0 -0
  86. package/{src → shared}/classes/standard.class.d.ts +0 -0
  87. package/{src → shared}/enums/comparison-operator.enum.d.ts +0 -0
  88. package/{src → shared}/enums/graphql-request-type.enum.d.ts +0 -0
  89. package/{src → shared}/enums/logical-operator.enum.d.ts +0 -0
  90. package/{src → shared}/enums/sort-order.enum.d.ts +0 -0
  91. package/shared/functions/ws-client.function.d.ts +5 -0
  92. package/{src → shared}/interfaces/base-module-config.interface.d.ts +1 -1
  93. package/{src → shared}/interfaces/can-component-deactivate.interface.d.ts +0 -0
  94. package/{src → shared}/interfaces/combined-filter-input.interface.d.ts +0 -0
  95. package/{src → shared}/interfaces/field-object.interface.d.ts +0 -0
  96. package/{src → shared}/interfaces/field.interface.d.ts +0 -0
  97. package/{src → shared}/interfaces/filter-input.interface.d.ts +0 -0
  98. package/{src → shared}/interfaces/find-args.interface.d.ts +0 -0
  99. package/{src → shared}/interfaces/graphql-fields-object.interface.d.ts +0 -0
  100. package/{src → shared}/interfaces/graphql-options.interface.d.ts +0 -0
  101. package/{src → shared}/interfaces/graphql-plus-options.interfacen.d.ts +0 -0
  102. package/{src → shared}/interfaces/graphql-type-collection.interface.d.ts +0 -0
  103. package/{src → shared}/interfaces/single-filter-input.interface.d.ts +0 -0
  104. package/{src → shared}/interfaces/sort-input.interface.d.ts +0 -0
  105. package/shared/interfaces/time-components.interface.d.ts +6 -0
  106. package/shared/lenne.tech-ng-base-shared.d.ts +5 -0
  107. package/shared/package.json +10 -0
  108. package/shared/public-api.d.ts +43 -0
  109. package/{src → shared}/services/auth.service.d.ts +0 -0
  110. package/{src → shared}/services/forms.service.d.ts +0 -1
  111. package/{src → shared}/services/graphql-meta.service.d.ts +0 -0
  112. package/{src → shared}/services/graphql-plus.service.d.ts +0 -0
  113. package/{src → shared}/services/graphql.service.d.ts +0 -0
  114. package/{src → shared}/services/image.service.d.ts +0 -0
  115. package/{src → shared}/services/loader.service.d.ts +0 -0
  116. package/{src → shared}/services/scroll.service.d.ts +0 -0
  117. package/{src → shared}/services/storage.service.d.ts +0 -0
  118. package/shared/services/user.service.d.ts +42 -0
  119. package/{src → shared}/services/ws.service.d.ts +2 -2
  120. package/{src → shared}/types/graphql-fields.type.d.ts +0 -0
  121. package/{src → shared}/types/storage.type.d.ts +0 -0
  122. package/shared/validators/match.validator.d.ts +4 -0
  123. package/src/base.module.d.ts +4 -2
  124. package/src/directives/match-height.directive.d.ts +1 -1
  125. package/src/factories/apollo-options.factory.d.ts +1 -3
  126. package/src/guards/auth.guard.d.ts +1 -2
  127. package/src/guards/can-deactivate.guard.d.ts +1 -1
  128. package/src/guards/logout.guard.d.ts +1 -1
  129. package/src/services/theme.service.d.ts +1 -1
  130. package/esm2020/src/classes/basic-user.class.mjs +0 -51
  131. package/esm2020/src/classes/graphql-enum.class.mjs +0 -9
  132. package/esm2020/src/classes/graphql-meta.class.mjs +0 -171
  133. package/esm2020/src/classes/graphql-type.class.mjs +0 -13
  134. package/esm2020/src/classes/helper.class.mjs +0 -304
  135. package/esm2020/src/classes/standard.class.mjs +0 -40
  136. package/esm2020/src/enums/graphql-request-type.enum.mjs +0 -10
  137. package/esm2020/src/enums/logical-operator.enum.mjs +0 -10
  138. package/esm2020/src/enums/sort-order.enum.mjs +0 -6
  139. package/esm2020/src/interfaces/base-module-config.interface.mjs +0 -3
  140. package/esm2020/src/interfaces/can-component-deactivate.interface.mjs +0 -2
  141. package/esm2020/src/interfaces/combined-filter-input.interface.mjs +0 -2
  142. package/esm2020/src/interfaces/field-object.interface.mjs +0 -2
  143. package/esm2020/src/interfaces/field.interface.mjs +0 -2
  144. package/esm2020/src/interfaces/filter-input.interface.mjs +0 -2
  145. package/esm2020/src/interfaces/find-args.interface.mjs +0 -2
  146. package/esm2020/src/interfaces/graphql-fields-object.interface.mjs +0 -2
  147. package/esm2020/src/interfaces/graphql-options.interface.mjs +0 -2
  148. package/esm2020/src/interfaces/graphql-plus-options.interfacen.mjs +0 -2
  149. package/esm2020/src/interfaces/graphql-type-collection.interface.mjs +0 -2
  150. package/esm2020/src/interfaces/single-filter-input.interface.mjs +0 -2
  151. package/esm2020/src/interfaces/sort-input.interface.mjs +0 -2
  152. package/esm2020/src/services/auth.service.mjs +0 -71
  153. package/esm2020/src/services/forms.service.mjs +0 -26
  154. package/esm2020/src/services/graphql-meta.service.mjs +0 -123
  155. package/esm2020/src/services/graphql-plus.service.mjs +0 -84
  156. package/esm2020/src/services/graphql.service.mjs +0 -441
  157. package/esm2020/src/services/image.service.mjs +0 -102
  158. package/esm2020/src/services/loader.service.mjs +0 -29
  159. package/esm2020/src/services/scroll.service.mjs +0 -179
  160. package/esm2020/src/services/storage.service.mjs +0 -132
  161. package/esm2020/src/services/ws.service.mjs +0 -17
  162. package/esm2020/src/types/graphql-fields.type.mjs +0 -2
  163. package/esm2020/src/types/storage.type.mjs +0 -2
  164. package/esm2020/src/validators/must-match.validator.mjs +0 -22
  165. package/src/validators/must-match.validator.d.ts +0 -6
@@ -0,0 +1,1939 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Injectable, Inject } from '@angular/core';
3
+ import { BehaviorSubject, of, throwError, Observable, map as map$1 } from 'rxjs';
4
+ import * as i1 from 'apollo-angular';
5
+ import { gql } from 'apollo-angular';
6
+ import { buildClientSchema, getIntrospectionQuery } from 'graphql';
7
+ import { map } from 'rxjs/operators';
8
+ import { FormControl, FormGroup } from '@angular/forms';
9
+ import * as i1$1 from '@angular/router';
10
+ import { createClient } from 'graphql-ws';
11
+
12
+ /**
13
+ * Helper class
14
+ */
15
+ class Helper {
16
+ /**
17
+ * Simple filter function for plain objects
18
+ */
19
+ static filter(objects, filter) {
20
+ return (objects?.filter((element) => {
21
+ for (const [key, value] of Object.entries(filter)) {
22
+ if (Array.isArray(element[key])) {
23
+ for (const item of element[key]) {
24
+ if (!element[key].includs(value)) {
25
+ return false;
26
+ }
27
+ }
28
+ }
29
+ else if (element[key] !== value) {
30
+ return false;
31
+ }
32
+ }
33
+ return true;
34
+ }) || []);
35
+ }
36
+ /**
37
+ * Convert to a url/uri conform string
38
+ * Only:
39
+ * - lower case
40
+ * - chars, numbers and hyphens
41
+ */
42
+ static urlString(str, options = {}) {
43
+ // Config
44
+ const config = {
45
+ allowAll: false,
46
+ ...options,
47
+ };
48
+ // To string
49
+ str = str + '';
50
+ // Trim
51
+ str = str.trim();
52
+ // Lower case
53
+ str = str.toLowerCase();
54
+ if (!config.allowAll) {
55
+ // Replace spaces
56
+ str = str.trim().replace(/\s+/g, '-');
57
+ // Replace some special chars
58
+ str = str.replace('ä', 'ae');
59
+ str = str.replace('ö', 'oe');
60
+ str = str.replace('ü', 'ue');
61
+ str = str.replace('ß', 'ss');
62
+ // Remove other special chars
63
+ str = str.replace(/[^a-zA-Z0-9-]/g, '');
64
+ }
65
+ // Return url conform string
66
+ return encodeURI(str);
67
+ }
68
+ /**
69
+ * Simple map function
70
+ */
71
+ static map(source, target, options = {}) {
72
+ // Set config
73
+ const config = {
74
+ funcAllowed: false,
75
+ dateStringToDate: true,
76
+ ...options,
77
+ };
78
+ // Check source
79
+ if (!source || typeof source !== 'object' || Array.isArray(source)) {
80
+ return target;
81
+ }
82
+ // Update properties
83
+ for (const key of Object.keys(target)) {
84
+ if (source[key] !== undefined && (config.funcAllowed || typeof (source[key] !== 'function'))) {
85
+ if (typeof source[key] === 'string' && config.dateStringToDate) {
86
+ if (Array.isArray(config.dateStringToDate)) {
87
+ if (config.dateStringToDate.includes(key)) {
88
+ target[key] = Helper.parseDate(source[key]);
89
+ }
90
+ }
91
+ else {
92
+ target[key] = Helper.parseDate(source[key]);
93
+ }
94
+ }
95
+ else {
96
+ target[key] = source[key];
97
+ }
98
+ }
99
+ }
100
+ // Return target
101
+ return target;
102
+ }
103
+ /**
104
+ * Create Object or Objects of specified type with specified data
105
+ */
106
+ static maps(data, targetClass) {
107
+ // Check data
108
+ if (!data || typeof data !== 'object') {
109
+ return undefined;
110
+ }
111
+ // Check array
112
+ if (!Array.isArray(data)) {
113
+ data = [data];
114
+ }
115
+ // Map
116
+ return data.map((item) => {
117
+ return targetClass.map(item);
118
+ });
119
+ }
120
+ /**
121
+ * Get plain parameter
122
+ */
123
+ static getPlainParameter(parameter) {
124
+ if (!parameter) {
125
+ return parameter;
126
+ }
127
+ return parameter?.split('?')?.shift()?.split('#')?.shift();
128
+ }
129
+ /**
130
+ * Get ID of an url parameter
131
+ */
132
+ static getParameterId(parameter) {
133
+ if (!parameter) {
134
+ return parameter;
135
+ }
136
+ return Helper.getPlainParameter(parameter)?.split('-').pop();
137
+ }
138
+ /**
139
+ * Delay
140
+ */
141
+ static delay(ms) {
142
+ const promise = new Promise((resolve) => setTimeout(resolve, ms));
143
+ return promise;
144
+ }
145
+ /**
146
+ * Deep freeze
147
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze
148
+ */
149
+ static deepFreeze(object, preparedObjects = []) {
150
+ // Prevent infinit regress
151
+ if (preparedObjects.includes(object)) {
152
+ return object;
153
+ }
154
+ preparedObjects.push(object);
155
+ // Retrieve the property names defined on object
156
+ const propNames = Object.getOwnPropertyNames(object);
157
+ // Freeze properties before freezing self
158
+ for (const name of propNames) {
159
+ const value = object[name];
160
+ if (value && typeof value === 'object') {
161
+ Helper.deepFreeze(value, preparedObjects);
162
+ }
163
+ }
164
+ return Object.freeze(object);
165
+ }
166
+ /**
167
+ * Generates an unique identifier with 24 characters
168
+ */
169
+ static getUID() {
170
+ let dt = new Date().getTime();
171
+ const uuid = 'xxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
172
+ // eslint-disable-next-line no-bitwise
173
+ const r = (dt + Math.random() * 16) % 16 | 0;
174
+ dt = Math.floor(dt / 16);
175
+ // eslint-disable-next-line no-bitwise
176
+ return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
177
+ });
178
+ return uuid;
179
+ }
180
+ /**
181
+ * Parse date string to date object
182
+ */
183
+ static parseDate(dateString) {
184
+ const reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
185
+ const reMsAjax = /^\/Date\((d|-|.*)\)[\/|\\]$/;
186
+ if (typeof dateString === 'string') {
187
+ const isoExec = reISO.exec(dateString);
188
+ if (isoExec) {
189
+ return new Date(dateString);
190
+ }
191
+ const msAjaxExec = reMsAjax.exec(dateString);
192
+ if (msAjaxExec) {
193
+ const cleaned = msAjaxExec[1].split(/[-+,.]/);
194
+ return new Date(cleaned[0] ? +cleaned[0] : 0 - +cleaned[1]);
195
+ }
196
+ }
197
+ return dateString;
198
+ }
199
+ /**
200
+ * Get browser name and version
201
+ */
202
+ static getBrowser() {
203
+ const userAgent = navigator.userAgent;
204
+ let data = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
205
+ let version;
206
+ if (/trident/i.test(data[1])) {
207
+ version = /\brv[ :]+(\d+)/g.exec(userAgent) || [];
208
+ return { name: 'IE', version: version[1] || '' };
209
+ }
210
+ if (data[1] === 'Chrome') {
211
+ version = userAgent.match(/\bOPR|Edge\/(\d+)/);
212
+ if (version != null) {
213
+ return { name: 'Opera', version: version[1] };
214
+ }
215
+ }
216
+ data = data[2] ? [data[1], data[2]] : [navigator.appName, navigator.appVersion, '-?'];
217
+ version = userAgent.match(/version\/(\d+)/i);
218
+ if (version !== null) {
219
+ data.splice(1, 1, version[1]);
220
+ }
221
+ return {
222
+ name: data[0],
223
+ version: data[1],
224
+ };
225
+ }
226
+ /**
227
+ * Whether first parameter is a deep subset of second parameter
228
+ * Hint: functions will be ignored
229
+ */
230
+ static isSubset(a, b) {
231
+ // Equal
232
+ if (a === b) {
233
+ return true;
234
+ }
235
+ // Different type
236
+ if (typeof a !== typeof b) {
237
+ return false;
238
+ }
239
+ // Process array
240
+ if (Array.isArray(a)) {
241
+ for (const [key, value] of Object.entries(a)) {
242
+ if (Helper.isSubset(value, b[key])) {
243
+ return false;
244
+ }
245
+ }
246
+ return true;
247
+ }
248
+ // Process object
249
+ if (typeof a === 'object') {
250
+ const plain = JSON.parse(JSON.stringify(a));
251
+ for (const [key, value] of Object.entries(plain)) {
252
+ if (Helper.isSubset(value, b[key])) {
253
+ return false;
254
+ }
255
+ }
256
+ return true;
257
+ }
258
+ // Else
259
+ return true;
260
+ }
261
+ /**
262
+ * Whether parameters are equal (have equal properties)
263
+ * Hint: functions will be ignored
264
+ */
265
+ static isEqual(a, b) {
266
+ return Helper.isSubset(a, b) && Helper.isSubset(b, a);
267
+ }
268
+ /**
269
+ * First level difference of two objects
270
+ * Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
271
+ *
272
+ * @returns Record<string, any> Object with properties from first object
273
+ */
274
+ static getDiff(a, b, clone = true) {
275
+ const result = {};
276
+ let firstObject = a;
277
+ if (clone) {
278
+ firstObject = JSON.parse(JSON.stringify(a));
279
+ }
280
+ for (const [key, value] of Object.entries(firstObject)) {
281
+ if (!Helper.isSubset(value, b[key])) {
282
+ result[key] = value;
283
+ }
284
+ }
285
+ return result;
286
+ }
287
+ /**
288
+ * Check if propertie is type of HTMLCollection or NodeList
289
+ * See https://stackoverflow.com/a/7238344
290
+ *
291
+ * @param nodes
292
+ */
293
+ static isNodeList(nodes) {
294
+ try {
295
+ const stringRepr = Object.prototype.toString.call(nodes);
296
+ return (typeof nodes === 'object' &&
297
+ /^\[object (HTMLCollection|NodeList|Object)\]$/.test(stringRepr) &&
298
+ typeof nodes.length === 'number' &&
299
+ (nodes.length === 0 || (typeof nodes[0] === 'object' && nodes[0].nodeType > 0)));
300
+ }
301
+ catch (e) {
302
+ return false;
303
+ }
304
+ }
305
+ static arrayBufferToBase64(buffer) {
306
+ let binary = '';
307
+ const bytes = new Uint8Array(buffer);
308
+ const len = bytes.byteLength;
309
+ for (let i = 0; i < len; i++) {
310
+ binary += String.fromCharCode(bytes[i]);
311
+ }
312
+ return `data:image/*;base64, ${window.btoa(binary)}`;
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Standard class
318
+ * Other classes should extend the Standard class, if they offer own functions
319
+ * If the extended class uses object properties with own map functions, it should implement its own map function
320
+ */
321
+ class Standard {
322
+ /**
323
+ * Static map method
324
+ */
325
+ static map(data, item = new this()) {
326
+ return item.map(data);
327
+ }
328
+ /**
329
+ * Map data into an object
330
+ */
331
+ map(data) {
332
+ return Helper.map(data, this);
333
+ }
334
+ /**
335
+ * Clone object (and map additional data)
336
+ */
337
+ clone(mapData) {
338
+ const current = JSON.parse(JSON.stringify(this));
339
+ if (mapData) {
340
+ Object.assign(current, mapData);
341
+ }
342
+ return new this.constructor().map(current);
343
+ }
344
+ /**
345
+ * Compare this with another object
346
+ * Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
347
+ *
348
+ * @return Record<string, any> with properties of this object which are different
349
+ */
350
+ getDiff(compare, clone = true) {
351
+ return Helper.getDiff(this, compare, clone);
352
+ }
353
+ }
354
+
355
+ /**
356
+ * User class
357
+ */
358
+ class BasicUser extends Standard {
359
+ constructor() {
360
+ super(...arguments);
361
+ this.id = undefined;
362
+ this.email = undefined;
363
+ this.firstName = undefined;
364
+ this.lastName = undefined;
365
+ this.roles = [];
366
+ this.username = undefined;
367
+ }
368
+ // ===================================================================================================================
369
+ // Methods
370
+ // ===================================================================================================================
371
+ /**
372
+ * Mapping
373
+ */
374
+ map(data) {
375
+ Helper.map(data, this);
376
+ return this;
377
+ }
378
+ /**
379
+ * Checks whether the user has at least one of the required roles
380
+ */
381
+ hasRole(roles) {
382
+ if (typeof roles === 'string') {
383
+ roles = [roles];
384
+ }
385
+ if (!this.roles || this.roles.length < 1) {
386
+ return false;
387
+ }
388
+ return !roles || roles.length < 1 ? true : this.roles.some((role) => roles.includes(role));
389
+ }
390
+ /**
391
+ * Checks whether the user has all required roles
392
+ */
393
+ hasAllRoles(roles) {
394
+ if (typeof roles === 'string') {
395
+ roles = [roles];
396
+ }
397
+ if (!this.roles || this.roles.length < 1) {
398
+ return false;
399
+ }
400
+ return !roles ? true : roles.every((role) => this.roles.includes(role));
401
+ }
402
+ }
403
+
404
+ /**
405
+ * GraphQL enum
406
+ */
407
+ class GraphQLEnum {
408
+ constructor(value) {
409
+ this.value = value;
410
+ }
411
+ }
412
+
413
+ /**
414
+ * GraphQL type
415
+ */
416
+ class GraphQLType extends Standard {
417
+ constructor() {
418
+ super(...arguments);
419
+ this.type = '';
420
+ this.isEnum = false;
421
+ this.validEnums = [];
422
+ }
423
+ }
424
+
425
+ /**
426
+ * GraphQL meta
427
+ */
428
+ class GraphQLMeta {
429
+ /**
430
+ * Integrate schema
431
+ */
432
+ constructor(schema) {
433
+ this.schema = schema;
434
+ // Frozen caches
435
+ this.args = {};
436
+ this.fields = {};
437
+ if (!schema) {
438
+ throw Error('Missing schema');
439
+ }
440
+ }
441
+ /**
442
+ * Get arguments of GraphQL function
443
+ */
444
+ getArgs(functionName, options = {}) {
445
+ const { cache, freeze, type } = {
446
+ cache: true,
447
+ freeze: true,
448
+ type: undefined,
449
+ ...options,
450
+ };
451
+ // Get cache
452
+ if (cache && freeze) {
453
+ const args = this.args[functionName + type];
454
+ if (args) {
455
+ return args;
456
+ }
457
+ }
458
+ const func = this.getFunction(functionName, { type });
459
+ const result = {};
460
+ if (func?.args) {
461
+ func.args.forEach((item) => {
462
+ result[item.name] = this.getDeepType(item.type);
463
+ });
464
+ }
465
+ // Set cache
466
+ if (freeze) {
467
+ this.args[functionName + type] = Helper.deepFreeze(result);
468
+ }
469
+ return result;
470
+ }
471
+ /**
472
+ * Get fields of GraphQL function
473
+ */
474
+ getFields(functionName, options = {}) {
475
+ const { cache, freeze, type } = {
476
+ cache: true,
477
+ freeze: true,
478
+ type: undefined,
479
+ ...options,
480
+ };
481
+ // Get cache
482
+ if (cache && freeze) {
483
+ const args = this.fields[functionName + type];
484
+ if (args) {
485
+ return args;
486
+ }
487
+ }
488
+ const func = this.getFunction(functionName, options);
489
+ const result = this.getDeepType(func.type);
490
+ // Set cache
491
+ if (freeze) {
492
+ this.fields[functionName + type] = Helper.deepFreeze(result);
493
+ }
494
+ return result;
495
+ }
496
+ /**
497
+ * Get GraphQL function
498
+ */
499
+ getFunction(name, options = {}) {
500
+ // Set config
501
+ const config = {
502
+ ...options,
503
+ };
504
+ // Init possible functions
505
+ let functions = {};
506
+ // If function type is set
507
+ if (config.type) {
508
+ const graphQLType = config.type.charAt(0).toUpperCase() + config.type.slice(1);
509
+ const type = this.schema.getType(graphQLType);
510
+ if (type) {
511
+ functions = type.getFields();
512
+ }
513
+ }
514
+ // If function type is not set
515
+ else {
516
+ ['Subscription', 'Mutation', 'Query'].forEach((item) => {
517
+ const type = this.schema.getType(item);
518
+ if (type) {
519
+ functions = {
520
+ ...functions,
521
+ ...(type.getFields() || {}),
522
+ };
523
+ }
524
+ });
525
+ }
526
+ // Get function via name
527
+ return functions[name];
528
+ }
529
+ /**
530
+ * Get type
531
+ */
532
+ getType(name) {
533
+ return this.schema.getType(name);
534
+ }
535
+ /**
536
+ * Get deep type data
537
+ */
538
+ getDeepType(type, prepared = new WeakMap()) {
539
+ // Check type
540
+ if (!type) {
541
+ return type;
542
+ }
543
+ // Infinite regress protection
544
+ const preparedObject = {};
545
+ // Check prepared
546
+ if (typeof type === 'object') {
547
+ const preparedType = prepared.get(type);
548
+ if (preparedType) {
549
+ return preparedType;
550
+ }
551
+ // Set prepared
552
+ prepared.set(type, preparedObject);
553
+ }
554
+ // Search deeper
555
+ if (type.ofType) {
556
+ const ofTypeResult = this.getDeepType(type.ofType, prepared);
557
+ Object.assign(preparedObject, ofTypeResult);
558
+ return ofTypeResult;
559
+ }
560
+ // Process fields
561
+ if (type._fields) {
562
+ const result = {};
563
+ for (const [key, value] of Object.entries(type._fields)) {
564
+ result[key] = this.getDeepType(value, prepared);
565
+ }
566
+ Object.assign(preparedObject, result);
567
+ return result;
568
+ }
569
+ // Get type name
570
+ if (type.type) {
571
+ const typeResult = this.getDeepType(type.type, prepared);
572
+ Object.assign(preparedObject, typeResult);
573
+ return typeResult;
574
+ }
575
+ // Initialize GraphQLType
576
+ const graphqlType = GraphQLType.map({
577
+ type: type.name,
578
+ });
579
+ // Set enum values
580
+ if (!!type._values) {
581
+ graphqlType.isEnum = true;
582
+ for (const [key, value] of Object.entries(type._nameLookup)) {
583
+ if (!value.isDeprecated) {
584
+ graphqlType.validEnums.push(key);
585
+ }
586
+ }
587
+ }
588
+ // Finish
589
+ prepared.set(type, graphqlType);
590
+ return graphqlType;
591
+ }
592
+ }
593
+
594
+ class Auth extends Standard {
595
+ constructor() {
596
+ super(...arguments);
597
+ this.token = undefined;
598
+ this.user = undefined;
599
+ }
600
+ map(data) {
601
+ Helper.map(data, this);
602
+ this.user = data?.user ? BasicUser.map(data.user) : this.user;
603
+ return this;
604
+ }
605
+ }
606
+
607
+ const BASE_MODULE_CONFIG = new InjectionToken('BASE_MODULE_CONFIG');
608
+
609
+ /**
610
+ * Storage service for local data storage
611
+ */
612
+ class StorageService {
613
+ /**
614
+ * Initializations
615
+ */
616
+ constructor(moduleConfig) {
617
+ this.moduleConfig = moduleConfig;
618
+ /**
619
+ * Storage
620
+ */
621
+ this.storage = null;
622
+ /**
623
+ * Prefix for storage keys
624
+ */
625
+ this.prefix = '';
626
+ // Set storage
627
+ const type = moduleConfig.storageType ? moduleConfig.storageType : 'local';
628
+ if (window[type + 'Storage']) {
629
+ this.storage = window[type + 'Storage'];
630
+ }
631
+ // Set prefix
632
+ this.prefix = '';
633
+ if (moduleConfig.prefix) {
634
+ this.prefix += moduleConfig.prefix + '_';
635
+ }
636
+ if (moduleConfig.version) {
637
+ this.prefix += moduleConfig.version + '_';
638
+ }
639
+ }
640
+ /**
641
+ * Save itemKeys
642
+ *
643
+ * If you want to save one item, use itemKeys and value parameters like these:
644
+ * save('KEY_OF_THE_ITEM', ITEM)
645
+ *
646
+ * If you want to save multiple items, use itemKeys only (value parameter will be ignored):
647
+ * save({'KEY_OF_ITEM_1': ITEM_1, 'KEY_OF_ITEM_2': ITEM_2, ...})
648
+ */
649
+ save(itemKeys, value) {
650
+ // Check local storage
651
+ if (!this.storage) {
652
+ return false;
653
+ }
654
+ // Check item keys and value
655
+ if (!itemKeys ||
656
+ (typeof itemKeys === 'object' && !Object.keys(itemKeys).length) ||
657
+ (typeof itemKeys === 'string' && value === undefined)) {
658
+ return false;
659
+ }
660
+ if (typeof itemKeys === 'object') {
661
+ for (const [itemKey, itemValue] of Object.entries(itemKeys)) {
662
+ this.storage.setItem(this.prefix + itemKey, JSON.stringify(itemValue));
663
+ }
664
+ return true;
665
+ }
666
+ this.storage.setItem(this.prefix + itemKeys, JSON.stringify(value));
667
+ return true;
668
+ }
669
+ /**
670
+ * Load items via key(s)
671
+ */
672
+ load(itemKeys) {
673
+ // Check local storage
674
+ if (!this.storage) {
675
+ return;
676
+ }
677
+ // Check item keys
678
+ if (!itemKeys || (Array.isArray(itemKeys) && !itemKeys.length)) {
679
+ return null;
680
+ }
681
+ if (Array.isArray(itemKeys)) {
682
+ const back = {};
683
+ itemKeys.forEach((itemKey) => {
684
+ const loadedItem = this.storage.getItem(this.prefix + itemKey);
685
+ if (loadedItem) {
686
+ back[itemKey] = JSON.parse(loadedItem);
687
+ }
688
+ else {
689
+ back[itemKey] = null;
690
+ }
691
+ });
692
+ return back;
693
+ }
694
+ let value = this.storage.getItem(this.prefix + itemKeys);
695
+ if (value) {
696
+ value = JSON.parse(value);
697
+ }
698
+ return value;
699
+ }
700
+ /**
701
+ * Remove item from storage
702
+ *
703
+ * @param itemKeys keys or key to remove
704
+ */
705
+ remove(itemKeys) {
706
+ // Check local storage
707
+ if (!this.storage) {
708
+ return false;
709
+ }
710
+ if (Array.isArray(itemKeys)) {
711
+ itemKeys.forEach((key) => {
712
+ this.storage.removeItem(this.prefix + key);
713
+ });
714
+ return true;
715
+ }
716
+ this.storage.removeItem(this.prefix + itemKeys);
717
+ return true;
718
+ }
719
+ /**
720
+ * Clear local storage
721
+ */
722
+ reset() {
723
+ this.storage.clear();
724
+ }
725
+ }
726
+ StorageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: StorageService, deps: [{ token: BASE_MODULE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
727
+ StorageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: StorageService, providedIn: 'root' });
728
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: StorageService, decorators: [{
729
+ type: Injectable,
730
+ args: [{
731
+ providedIn: 'root',
732
+ }]
733
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
734
+ type: Inject,
735
+ args: [BASE_MODULE_CONFIG]
736
+ }] }]; } });
737
+
738
+ class WsService {
739
+ reconnect() {
740
+ this.client?.restart();
741
+ }
742
+ }
743
+ WsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: WsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
744
+ WsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: WsService, providedIn: 'root' });
745
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: WsService, decorators: [{
746
+ type: Injectable,
747
+ args: [{
748
+ providedIn: 'root',
749
+ }]
750
+ }] });
751
+
752
+ /**
753
+ * Authentication service
754
+ */
755
+ class AuthService {
756
+ /**
757
+ * Constructor
758
+ */
759
+ constructor(moduleConfig, storageService, wsService) {
760
+ this.moduleConfig = moduleConfig;
761
+ this.storageService = storageService;
762
+ this.wsService = wsService;
763
+ // Subjects
764
+ this._currentUser = new BehaviorSubject(null);
765
+ this._token = new BehaviorSubject(null);
766
+ this.token = this.storageService.load('token');
767
+ this.currentUser = this.storageService.load('currentUser');
768
+ }
769
+ /**
770
+ * Logout
771
+ */
772
+ logout() {
773
+ this.storageService.remove(['token', 'currentUser']);
774
+ this.currentUser = null;
775
+ this.token = null;
776
+ }
777
+ // #################################################################
778
+ // Current User
779
+ // #################################################################
780
+ get currentUser() {
781
+ return this._currentUser.value;
782
+ }
783
+ set currentUser(user) {
784
+ this._currentUser.next(user);
785
+ this.storageService.save('currentUser', user);
786
+ }
787
+ get currentUserObservable() {
788
+ return this._currentUser.asObservable();
789
+ }
790
+ // #################################################################
791
+ // Token
792
+ // #################################################################
793
+ get token() {
794
+ return this._token.value;
795
+ }
796
+ set token(token) {
797
+ this._token.next(token);
798
+ this.storageService.save('token', token);
799
+ this.wsService.reconnect();
800
+ }
801
+ get tokenObservable() {
802
+ return this._token.asObservable();
803
+ }
804
+ }
805
+ AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthService, deps: [{ token: BASE_MODULE_CONFIG }, { token: StorageService }, { token: WsService }], target: i0.ɵɵFactoryTarget.Injectable });
806
+ AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthService, providedIn: 'root' });
807
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthService, decorators: [{
808
+ type: Injectable,
809
+ args: [{
810
+ providedIn: 'root',
811
+ }]
812
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
813
+ type: Inject,
814
+ args: [BASE_MODULE_CONFIG]
815
+ }] }, { type: StorageService }, { type: WsService }]; } });
816
+
817
+ /**
818
+ * GraphQL request type enum
819
+ */
820
+ var GraphQLRequestType;
821
+ (function (GraphQLRequestType) {
822
+ GraphQLRequestType["QUERY"] = "query";
823
+ GraphQLRequestType["MUTATION"] = "mutation";
824
+ GraphQLRequestType["SUBSCRIPTION"] = "subscription";
825
+ })(GraphQLRequestType || (GraphQLRequestType = {}));
826
+
827
+ /**
828
+ * GraphQL meta service
829
+ *
830
+ * For collecting meta information of the GraphQL API
831
+ */
832
+ class GraphQLMetaService {
833
+ /**
834
+ * Include services
835
+ */
836
+ constructor(apollo) {
837
+ this.apollo = apollo;
838
+ }
839
+ /**
840
+ * Getter of introspectionQuery
841
+ */
842
+ get introspectionQuery() {
843
+ return JSON.parse(JSON.stringify(this._introspectionQuery));
844
+ }
845
+ /**
846
+ * Get schema for API
847
+ * See https://www.apollographql.com/blog/three-ways-to-represent-your-graphql-schema-a41f4175100d
848
+ */
849
+ getSchema(options = {}) {
850
+ // Get configurations
851
+ const config = {
852
+ cache: true,
853
+ freeze: true,
854
+ ...options,
855
+ };
856
+ // Use caching
857
+ if (config.cache) {
858
+ if (config.freeze && this._frozenSchema) {
859
+ return of(this._frozenSchema);
860
+ }
861
+ if (this._introspectionQuery) {
862
+ return of(buildClientSchema(this.introspectionQuery));
863
+ }
864
+ if (config.freeze && this._frozenSchemaObservable) {
865
+ return this._frozenSchemaObservable;
866
+ }
867
+ else if (!config.freeze && this._schemaObservable) {
868
+ return this._schemaObservable;
869
+ }
870
+ }
871
+ // Request schema from server
872
+ const observable = this.apollo
873
+ .query({
874
+ query: gql(getIntrospectionQuery({ descriptions: false })),
875
+ })
876
+ .pipe(map((schema) => {
877
+ // Cache introspectionQuery
878
+ this._introspectionQuery = schema.data;
879
+ // Convert schema to GraphQLSchema
880
+ this._frozenSchema = Helper.deepFreeze(buildClientSchema(this.introspectionQuery));
881
+ // Return GraphQLSchema
882
+ if (config.freeze) {
883
+ return this._frozenSchema;
884
+ }
885
+ return buildClientSchema(schema.data);
886
+ }));
887
+ // Set observables
888
+ if (config.freeze) {
889
+ this._frozenSchemaObservable = observable;
890
+ }
891
+ else {
892
+ this._schemaObservable = observable;
893
+ }
894
+ // Return result
895
+ return observable;
896
+ }
897
+ /**
898
+ * Get meta for API
899
+ * See https://www.apollographql.com/blog/three-ways-to-represent-your-graphql-schema-a41f4175100d
900
+ */
901
+ getMeta(options = {}) {
902
+ // Get configurations
903
+ const config = {
904
+ cache: true,
905
+ log: false,
906
+ ...options,
907
+ };
908
+ // Use caching
909
+ if (config.cache) {
910
+ if (this._meta) {
911
+ return of(this._meta);
912
+ }
913
+ else if (this._metaObservable) {
914
+ return this._metaObservable;
915
+ }
916
+ }
917
+ // Request schema from server
918
+ const observable = this.getSchema(options).pipe(map((schema) => {
919
+ // Log
920
+ if (config.log) {
921
+ console.log({ schema });
922
+ }
923
+ this._meta = new GraphQLMeta(schema);
924
+ return this._meta;
925
+ }));
926
+ // Set observables
927
+ this._metaObservable = observable;
928
+ // Return result
929
+ return observable;
930
+ }
931
+ }
932
+ GraphQLMetaService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLMetaService, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
933
+ GraphQLMetaService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLMetaService, providedIn: 'root' });
934
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLMetaService, decorators: [{
935
+ type: Injectable,
936
+ args: [{
937
+ providedIn: 'root',
938
+ }]
939
+ }], ctorParameters: function () { return [{ type: i1.Apollo }]; } });
940
+
941
+ /**
942
+ * GraphQL service
943
+ */
944
+ class GraphQLService {
945
+ /**
946
+ * Include services
947
+ */
948
+ constructor(apollo, graphQLMetaService) {
949
+ this.apollo = apollo;
950
+ this.graphQLMetaService = graphQLMetaService;
951
+ }
952
+ /**
953
+ * GraphQL request
954
+ */
955
+ graphQl(graphql, options = {}) {
956
+ // Check arguments
957
+ if (!graphql) {
958
+ throwError('Missing graphql argument');
959
+ }
960
+ // Get config
961
+ const config = {
962
+ arguments: null,
963
+ fields: null,
964
+ log: false,
965
+ model: null,
966
+ type: GraphQLRequestType.QUERY,
967
+ ...options,
968
+ };
969
+ // Convert class to Object for arguments
970
+ if (typeof config.arguments === 'function') {
971
+ config.arguments = new config.arguments();
972
+ }
973
+ // Convert class to Object for fields
974
+ if (typeof config.fields === 'function') {
975
+ config.fields = new config.fields();
976
+ }
977
+ // Log
978
+ if (config.log) {
979
+ console.log({ config });
980
+ }
981
+ // Send request
982
+ return new Observable((subscriber) => {
983
+ // Get meta
984
+ this.graphQLMetaService.getMeta({ log: config.log }).subscribe((meta) => {
985
+ // Prepare fields
986
+ let fields;
987
+ let allowedFields;
988
+ // Log meta
989
+ if (config.log) {
990
+ console.log({ meta });
991
+ }
992
+ if (config.fields) {
993
+ allowedFields = meta.getFields(graphql, { type: config.type });
994
+ // Log meta
995
+ if (config.log) {
996
+ console.log({ allowedFields });
997
+ }
998
+ const fieldsData = this.prepareFields(config.fields, {
999
+ allowed: allowedFields,
1000
+ });
1001
+ // Log fields data
1002
+ if (config.log) {
1003
+ fieldsData.usedFields.sort();
1004
+ fieldsData.schemaFields.sort();
1005
+ const filtered = fieldsData.schemaFields.filter((field) => !fieldsData.usedFields.includes(field));
1006
+ const unused = this.graphQLTypeCollectionToStringArray(allowedFields).filter((field) => !fieldsData.usedFields.includes(field));
1007
+ console.log({ fieldsData, filtered, unused });
1008
+ }
1009
+ fields = fieldsData.fieldsString;
1010
+ }
1011
+ if (fields && !fields.startsWith('{')) {
1012
+ fields = '{' + fields + '\n}';
1013
+ }
1014
+ // Log fields
1015
+ if (config.log) {
1016
+ console.log({ fields });
1017
+ }
1018
+ // Get allowed args
1019
+ const allowedArgs = meta.getArgs(graphql, { type: config.type });
1020
+ // Log allowed args
1021
+ if (config.log) {
1022
+ console.log({ allowedArgs });
1023
+ }
1024
+ const argsData = this.prepareArguments(config.arguments, {
1025
+ allowed: allowedArgs,
1026
+ });
1027
+ // Log args data
1028
+ if (config.log) {
1029
+ argsData.usedArgs.sort();
1030
+ argsData.schemaArgs.sort();
1031
+ const filtered = argsData.schemaArgs.filter((field) => !argsData.usedArgs.includes(field));
1032
+ const unused = this.graphQLTypeCollectionToStringArray(allowedArgs)
1033
+ .sort()
1034
+ .filter((field) => !argsData.usedArgs.includes(field));
1035
+ console.log({ argsData, filtered, unused });
1036
+ }
1037
+ const args = argsData?.argsString || '';
1038
+ // Log
1039
+ if (config.log) {
1040
+ console.log({ graphQL: graphql, args, fields, type: config.type });
1041
+ }
1042
+ // Prepare request
1043
+ const documentNode = fields
1044
+ ? gql(config.type + '{\n' + graphql + args + fields + '\n}')
1045
+ : gql(config.type + '{\n' + graphql + args + '\n}');
1046
+ // Log
1047
+ if (config.log) {
1048
+ console.log({ documentNode });
1049
+ }
1050
+ const request = {};
1051
+ request[config.type] = documentNode;
1052
+ // Log
1053
+ if (config.log) {
1054
+ console.log({ request });
1055
+ }
1056
+ let func;
1057
+ if (config.type === GraphQLRequestType.MUTATION) {
1058
+ func = 'mutate';
1059
+ request[config.type] = documentNode;
1060
+ }
1061
+ else if (config.type === GraphQLRequestType.SUBSCRIPTION) {
1062
+ func = 'subscribe';
1063
+ request.query = documentNode;
1064
+ }
1065
+ else {
1066
+ func = config.type;
1067
+ request[config.type] = documentNode;
1068
+ }
1069
+ this.apollo[func](request).subscribe((result) => {
1070
+ const data = result?.data?.[graphql] !== undefined ? result.data[graphql] : result;
1071
+ // Direct data
1072
+ if (!config.model) {
1073
+ subscriber.next(data);
1074
+ }
1075
+ // Map data as array
1076
+ else if (Array.isArray(data)) {
1077
+ subscriber.next(data.map((item) => {
1078
+ return config.model.map(item);
1079
+ }));
1080
+ }
1081
+ // Map data
1082
+ else {
1083
+ subscriber.next(config.model.map(data));
1084
+ }
1085
+ if (config.type !== GraphQLRequestType.SUBSCRIPTION) {
1086
+ // Done
1087
+ subscriber.complete();
1088
+ }
1089
+ }, (error) => {
1090
+ subscriber.error(error);
1091
+ subscriber.complete();
1092
+ });
1093
+ });
1094
+ });
1095
+ }
1096
+ /**
1097
+ * Get fields / args from IGraphQLTypeCollection
1098
+ */
1099
+ graphQLTypeCollectionToStringArray(collection, current = '', result = [], cacheNode = []) {
1100
+ if (collection) {
1101
+ if (collection instanceof GraphQLType) {
1102
+ result.push(current);
1103
+ }
1104
+ else {
1105
+ if (current?.includes('.')) {
1106
+ cacheNode.push(current.split('.')[1]);
1107
+ }
1108
+ else if (current) {
1109
+ cacheNode.push(current);
1110
+ }
1111
+ for (const key of Object.keys(collection)) {
1112
+ if (current === key || cacheNode.includes(key)) {
1113
+ continue;
1114
+ }
1115
+ this.graphQLTypeCollectionToStringArray(collection[key], current ? current + '.' + key : key, result, cacheNode);
1116
+ }
1117
+ }
1118
+ }
1119
+ return result;
1120
+ }
1121
+ /**
1122
+ * Prepare arguments for GraphQL request
1123
+ */
1124
+ prepareArguments(args, options = {}) {
1125
+ // Init config variables
1126
+ const { allowed, level, parent, schemaArgs, usedArgs } = {
1127
+ allowed: null,
1128
+ level: 1,
1129
+ parent: '',
1130
+ schemaArgs: [],
1131
+ usedArgs: [],
1132
+ ...options,
1133
+ };
1134
+ // Check args
1135
+ if (args === undefined || args === null) {
1136
+ return { argsString: '', schemaArgs, usedArgs };
1137
+ }
1138
+ // Init args
1139
+ const result = [];
1140
+ // Process array
1141
+ if (Array.isArray(args)) {
1142
+ const allowedKeys = allowed ? Object.keys(allowed) : null;
1143
+ for (const item of args) {
1144
+ let key = null;
1145
+ if (allowed) {
1146
+ if (allowed.length < 1) {
1147
+ break;
1148
+ }
1149
+ key = allowedKeys?.shift();
1150
+ }
1151
+ // Process value
1152
+ result.push(this.prepareArguments(item, {
1153
+ allowed: key ? allowed[key] : null,
1154
+ level: level + 1,
1155
+ parent: parent + key + '.',
1156
+ schemaArgs,
1157
+ usedArgs,
1158
+ }).argsString);
1159
+ }
1160
+ // Encapsulation of the array result
1161
+ if (result.length) {
1162
+ // Complete result, encapsulated via round brackets
1163
+ if (level === 1) {
1164
+ return { argsString: '(' + result.join(', ') + ')', schemaArgs, usedArgs };
1165
+ }
1166
+ // Deeper result part, encapsulated via square brackets
1167
+ else {
1168
+ return { argsString: '[' + result.join(', ') + ']', schemaArgs, usedArgs };
1169
+ }
1170
+ }
1171
+ }
1172
+ // Process object
1173
+ else if (typeof args === 'object') {
1174
+ // Check object is empty
1175
+ if (args && Object.keys(args).length === 0 && Object.getPrototypeOf(args) === Object.prototype) {
1176
+ return { argsString: '{}', schemaArgs, usedArgs };
1177
+ }
1178
+ // Process all object entries
1179
+ for (const [key, value] of Object.entries(args)) {
1180
+ // Init data for current entry
1181
+ const currentKey = parent + key;
1182
+ schemaArgs.push(currentKey);
1183
+ // If the allowed key handling is enabled and the current key is not included in the list of allowed keys,
1184
+ // the current key will be skipped
1185
+ if (allowed && !allowed[key]) {
1186
+ continue;
1187
+ }
1188
+ // Skip value if not exists
1189
+ if (value === undefined || value === null) {
1190
+ continue;
1191
+ }
1192
+ // Add current key to metadata
1193
+ usedArgs.push(currentKey);
1194
+ // Process GraphQLEnum
1195
+ if (value instanceof GraphQLEnum) {
1196
+ result.push(key + ':' + value.value);
1197
+ continue;
1198
+ }
1199
+ // Process array
1200
+ else if (Array.isArray(value)) {
1201
+ result.push(key +
1202
+ ': [' +
1203
+ value.map((item) => this.prepareArguments(item, {
1204
+ allowed: allowed[key],
1205
+ level: level + 1,
1206
+ parent: currentKey + '.',
1207
+ schemaArgs,
1208
+ usedArgs,
1209
+ }).argsString) +
1210
+ ']');
1211
+ continue;
1212
+ }
1213
+ // Prepare additional result string
1214
+ let additionalResult = key + ': ';
1215
+ // Value is a date object
1216
+ if (typeof value === 'object' && Object.prototype.toString.call(value) === '[object Date]') {
1217
+ additionalResult += `"""${value.toString()}"""`;
1218
+ }
1219
+ // Value is a string
1220
+ else if (typeof value === 'string') {
1221
+ // Enum (doesn't need quotation marks)
1222
+ if (allowed[key].isEnum) {
1223
+ additionalResult += value;
1224
+ }
1225
+ // String
1226
+ else {
1227
+ additionalResult += `"""${value.replace(/"/g, '\\"')}"""`;
1228
+ }
1229
+ }
1230
+ // Value is a simple boolean or a number
1231
+ else if (typeof value === 'boolean' || typeof value === 'number') {
1232
+ additionalResult += value;
1233
+ }
1234
+ // Others
1235
+ else {
1236
+ additionalResult += this.prepareArguments(value, {
1237
+ allowed: allowed[key],
1238
+ level: level + 1,
1239
+ parent: currentKey + '.',
1240
+ schemaArgs,
1241
+ usedArgs,
1242
+ }).argsString;
1243
+ }
1244
+ // Push deeper part into result array
1245
+ result.push(additionalResult);
1246
+ }
1247
+ // Encapsulation of the object result
1248
+ if (result.length) {
1249
+ // Complete result, encapsulated via round brackets
1250
+ if (level === 1) {
1251
+ return { argsString: '(' + result.join(', ') + ')', schemaArgs, usedArgs };
1252
+ }
1253
+ // Deeper result part, encapsulated via curly brackets
1254
+ else {
1255
+ return { argsString: '{' + result.join(', ') + '}', schemaArgs, usedArgs };
1256
+ }
1257
+ }
1258
+ }
1259
+ // Prepare and process other / unknown values as JSON
1260
+ else {
1261
+ return { argsString: JSON.stringify(args), schemaArgs, usedArgs };
1262
+ }
1263
+ }
1264
+ /**
1265
+ * Prepare fields for GraphQL request
1266
+ */
1267
+ prepareFields(fields, options = {}) {
1268
+ // Config
1269
+ const { allowed, parent, schemaFields, spaces, tab, usedFields } = {
1270
+ allowed: null,
1271
+ parent: '',
1272
+ schemaFields: [],
1273
+ spaces: 2,
1274
+ tab: 1,
1275
+ usedFields: [],
1276
+ ...options,
1277
+ };
1278
+ // Init fields string
1279
+ let fieldsString = '';
1280
+ // Check fields
1281
+ if (!fields) {
1282
+ return { fieldsString, schemaFields, usedFields };
1283
+ }
1284
+ // Process string
1285
+ if (typeof fields === 'string') {
1286
+ if (allowed &&
1287
+ ((typeof allowed === 'string' && allowed !== fields) || (typeof allowed === 'object' && !allowed[fields]))) {
1288
+ return { fieldsString, schemaFields, usedFields };
1289
+ }
1290
+ return { fieldsString: '\n' + ' '.repeat(spaces).repeat(tab) + fields, schemaFields, usedFields };
1291
+ }
1292
+ // Process array
1293
+ else if (Array.isArray(fields)) {
1294
+ for (const item of fields) {
1295
+ if (typeof item === 'object') {
1296
+ fieldsString =
1297
+ fieldsString +
1298
+ this.prepareFields(item, {
1299
+ allowed,
1300
+ parent,
1301
+ spaces,
1302
+ schemaFields,
1303
+ tab: tab + 1,
1304
+ usedFields,
1305
+ }).fieldsString;
1306
+ continue;
1307
+ }
1308
+ const currentPath = parent + item;
1309
+ schemaFields.push(currentPath);
1310
+ if (allowed && !allowed?.[item]) {
1311
+ continue;
1312
+ }
1313
+ usedFields.push(currentPath);
1314
+ fieldsString =
1315
+ fieldsString +
1316
+ this.prepareFields(item, {
1317
+ allowed: typeof allowed?.[item] === 'object' && !(allowed?.[item] instanceof GraphQLType) ? allowed?.[item] : item,
1318
+ parent: currentPath + '.',
1319
+ spaces,
1320
+ schemaFields,
1321
+ tab: tab + 1,
1322
+ usedFields,
1323
+ }).fieldsString;
1324
+ }
1325
+ }
1326
+ // Process object
1327
+ else if (typeof fields === 'object') {
1328
+ for (const [key, val] of Object.entries(fields)) {
1329
+ const currentPath = parent + key;
1330
+ schemaFields.push(currentPath);
1331
+ if (allowed && !allowed[key]) {
1332
+ continue;
1333
+ }
1334
+ usedFields.push(currentPath);
1335
+ if (typeof val !== 'object' || !Object.keys(val).length) {
1336
+ fieldsString = fieldsString + '\n' + ' '.repeat(spaces).repeat(tab) + key;
1337
+ }
1338
+ else {
1339
+ fieldsString =
1340
+ fieldsString +
1341
+ '\n' +
1342
+ ' '.repeat(spaces).repeat(tab) +
1343
+ key +
1344
+ ' ' +
1345
+ '{' +
1346
+ this.prepareFields(val, {
1347
+ allowed: typeof allowed?.[key] === 'object' && !(allowed?.[key] instanceof GraphQLType) ? allowed?.[key] : key,
1348
+ parent: currentPath + '.',
1349
+ spaces,
1350
+ schemaFields,
1351
+ tab: tab + 1,
1352
+ usedFields,
1353
+ }).fieldsString +
1354
+ '\n' +
1355
+ ' '.repeat(spaces).repeat(tab) +
1356
+ '}';
1357
+ }
1358
+ }
1359
+ }
1360
+ // Return result
1361
+ return { fieldsString, schemaFields, usedFields };
1362
+ }
1363
+ }
1364
+ GraphQLService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLService, deps: [{ token: i1.Apollo }, { token: GraphQLMetaService }], target: i0.ɵɵFactoryTarget.Injectable });
1365
+ GraphQLService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLService, providedIn: 'root' });
1366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLService, decorators: [{
1367
+ type: Injectable,
1368
+ args: [{
1369
+ providedIn: 'root',
1370
+ }]
1371
+ }], ctorParameters: function () { return [{ type: i1.Apollo }, { type: GraphQLMetaService }]; } });
1372
+
1373
+ /**
1374
+ * Loader service for loading indication
1375
+ */
1376
+ class LoaderService {
1377
+ constructor() {
1378
+ this.isLoading = new BehaviorSubject(false);
1379
+ }
1380
+ start() {
1381
+ this.isLoading.next(true);
1382
+ }
1383
+ stop() {
1384
+ this.isLoading.next(false);
1385
+ }
1386
+ getAsObservable() {
1387
+ return this.isLoading.asObservable();
1388
+ }
1389
+ }
1390
+ LoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1391
+ LoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LoaderService, providedIn: 'root' });
1392
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LoaderService, decorators: [{
1393
+ type: Injectable,
1394
+ args: [{
1395
+ providedIn: 'root',
1396
+ }]
1397
+ }] });
1398
+
1399
+ /**
1400
+ * GraphQL plus service, for extra error handling and loading indication
1401
+ */
1402
+ class GraphQLPlusService extends GraphQLService {
1403
+ /**
1404
+ * Include services
1405
+ */
1406
+ constructor(apollo, graphqlMetaService, loaderService) {
1407
+ super(apollo, graphqlMetaService);
1408
+ this.apollo = apollo;
1409
+ this.graphqlMetaService = graphqlMetaService;
1410
+ this.loaderService = loaderService;
1411
+ }
1412
+ graphQl(graphql, options = {}) {
1413
+ this.handleLoader('start', options);
1414
+ return new Observable((subscriber) => {
1415
+ super.graphQl(graphql, options).subscribe((response) => {
1416
+ if (response && response.errors) {
1417
+ this.handleError(response.errors, options.excludedErrors);
1418
+ subscriber.error(response);
1419
+ this.handleLoader('stop', options);
1420
+ subscriber.complete();
1421
+ }
1422
+ subscriber.next(response);
1423
+ this.handleLoader('stop', options);
1424
+ if (options.type !== GraphQLRequestType.SUBSCRIPTION) {
1425
+ subscriber.complete();
1426
+ }
1427
+ }, (error) => {
1428
+ if (!options.ignoreErrors) {
1429
+ this.handleError(error, options.excludedErrors);
1430
+ }
1431
+ subscriber.error(error);
1432
+ this.handleLoader('stop', options);
1433
+ subscriber.complete();
1434
+ });
1435
+ });
1436
+ }
1437
+ handleLoader(state, options) {
1438
+ if (options.loading) {
1439
+ if (state === 'start') {
1440
+ this.loaderService.start();
1441
+ }
1442
+ else if (state === 'stop') {
1443
+ this.loaderService.stop();
1444
+ }
1445
+ }
1446
+ }
1447
+ handleError(error, excludedErrors = null) {
1448
+ if (excludedErrors) {
1449
+ if (Array.isArray(excludedErrors)) {
1450
+ excludedErrors.forEach((excludedError) => {
1451
+ if (error.message.includes(excludedError.toLowerCase())) {
1452
+ return;
1453
+ }
1454
+ });
1455
+ }
1456
+ else if (error.message.toLowerCase().includes(excludedErrors?.toLowerCase())) {
1457
+ return;
1458
+ }
1459
+ }
1460
+ this.displayError(error);
1461
+ }
1462
+ displayError(error) {
1463
+ console.error(error);
1464
+ }
1465
+ }
1466
+ GraphQLPlusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLPlusService, deps: [{ token: i1.Apollo }, { token: GraphQLMetaService }, { token: LoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
1467
+ GraphQLPlusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLPlusService, providedIn: 'root' });
1468
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLPlusService, decorators: [{
1469
+ type: Injectable,
1470
+ args: [{
1471
+ providedIn: 'root',
1472
+ }]
1473
+ }], ctorParameters: function () { return [{ type: i1.Apollo }, { type: GraphQLMetaService }, { type: LoaderService }]; } });
1474
+
1475
+ class FormsService {
1476
+ validateAllFormFields(formGroup) {
1477
+ Object.keys(formGroup.controls).forEach((field) => {
1478
+ const control = formGroup.get(field);
1479
+ if (control instanceof FormControl) {
1480
+ control.markAsTouched({ onlySelf: true });
1481
+ }
1482
+ else if (control instanceof FormGroup) {
1483
+ this.validateAllFormFields(control);
1484
+ }
1485
+ });
1486
+ }
1487
+ }
1488
+ FormsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: FormsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1489
+ FormsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: FormsService, providedIn: 'root' });
1490
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: FormsService, decorators: [{
1491
+ type: Injectable,
1492
+ args: [{
1493
+ providedIn: 'root',
1494
+ }]
1495
+ }] });
1496
+
1497
+ class UserService extends GraphQLPlusService {
1498
+ constructor(apollo, graphqlMetaService, loaderService, authService) {
1499
+ super(apollo, graphqlMetaService, loaderService);
1500
+ this.apollo = apollo;
1501
+ this.graphqlMetaService = graphqlMetaService;
1502
+ this.loaderService = loaderService;
1503
+ this.authService = authService;
1504
+ }
1505
+ /**
1506
+ * Login
1507
+ *
1508
+ * @param input
1509
+ */
1510
+ login(input) {
1511
+ return this.graphQl('signIn', {
1512
+ arguments: { input },
1513
+ fields: ['token', { user: ['id', 'firstName', 'lastName', 'email', 'roles'] }],
1514
+ type: GraphQLRequestType.QUERY,
1515
+ loading: true,
1516
+ }).pipe(map$1((response) => {
1517
+ this.authService.token = response.token;
1518
+ this.authService.currentUser = BasicUser.map(response.user);
1519
+ return Auth.map({
1520
+ token: response.token,
1521
+ user: BasicUser.map(response.user),
1522
+ });
1523
+ }));
1524
+ }
1525
+ /**
1526
+ * Register
1527
+ *
1528
+ * @param input
1529
+ */
1530
+ register(input) {
1531
+ return this.graphQl('signUp', {
1532
+ arguments: { input },
1533
+ fields: ['token', { user: ['id', 'firstName', 'lastName', 'email', 'roles'] }],
1534
+ type: GraphQLRequestType.MUTATION,
1535
+ loading: true,
1536
+ }).pipe(map$1((response) => {
1537
+ this.authService.token = response.token;
1538
+ this.authService.currentUser = BasicUser.map(response.user);
1539
+ return Auth.map({
1540
+ token: response.token,
1541
+ user: BasicUser.map(response.user),
1542
+ });
1543
+ }));
1544
+ }
1545
+ /**
1546
+ * Request password reset mail
1547
+ *
1548
+ * @param email
1549
+ */
1550
+ requestPasswordResetMail(email) {
1551
+ return this.graphQl('requestPasswordResetMail', {
1552
+ arguments: { email },
1553
+ fields: [],
1554
+ type: GraphQLRequestType.QUERY,
1555
+ loading: true,
1556
+ });
1557
+ }
1558
+ }
1559
+ UserService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: UserService, deps: [{ token: i1.Apollo }, { token: GraphQLMetaService }, { token: LoaderService }, { token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
1560
+ UserService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: UserService, providedIn: 'root' });
1561
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: UserService, decorators: [{
1562
+ type: Injectable,
1563
+ args: [{
1564
+ providedIn: 'root',
1565
+ }]
1566
+ }], ctorParameters: function () { return [{ type: i1.Apollo }, { type: GraphQLMetaService }, { type: LoaderService }, { type: AuthService }]; } });
1567
+
1568
+ /**
1569
+ * Image service
1570
+ */
1571
+ class ImageService {
1572
+ /**
1573
+ * Preaload images (for lazy handling)
1574
+ *
1575
+ * @param options
1576
+ * @protected
1577
+ */
1578
+ preLoadImages(options) {
1579
+ // Init configuration
1580
+ const config = {
1581
+ doneFunnction: undefined,
1582
+ elements: document,
1583
+ regExp: undefined,
1584
+ ...options,
1585
+ };
1586
+ return new Promise((resolve) => {
1587
+ // Convert element(s) into array
1588
+ if (!Array.isArray(config.elements)) {
1589
+ // NodeList or HTMLCollection
1590
+ if (Helper.isNodeList(config.elements)) {
1591
+ config.elements = Array.from(config.elements);
1592
+ }
1593
+ // Single element
1594
+ else {
1595
+ config.elements = [config.elements];
1596
+ }
1597
+ }
1598
+ // Init loading
1599
+ const promises = [];
1600
+ // Get all images
1601
+ let images = [];
1602
+ config.elements.forEach((element) => {
1603
+ images = images.concat(Array.from(element.getElementsByTagName('img')));
1604
+ });
1605
+ // Prepare images
1606
+ for (let image of images) {
1607
+ const src = image.getAttribute('src');
1608
+ // Check if changes are necessary and possible
1609
+ if ((image.complete && image.naturalHeight !== 0) || // already laoded
1610
+ !src || // Image has no src
1611
+ config.regExp?.test(src) // Test if src matches regular expression
1612
+ ) {
1613
+ continue;
1614
+ }
1615
+ // Replace lazy loading image with immediately loading image
1616
+ if (image.getAttribute('loading') === 'lazy') {
1617
+ const newImage = document.createElement('img');
1618
+ Array.from(image.attributes).forEach((attr) => {
1619
+ if (attr.name !== 'loading' && attr.name !== 'src') {
1620
+ newImage.setAttribute(attr.name, attr.value);
1621
+ }
1622
+ });
1623
+ image.replaceWith(newImage);
1624
+ image = newImage;
1625
+ }
1626
+ // Wait for laoding
1627
+ promises.push(this.loadImage(image, src));
1628
+ }
1629
+ // Wait until all images loaded
1630
+ Promise.all(promises)
1631
+ .catch((e) => console.error('Error during image loading', e))
1632
+ .finally(async () => {
1633
+ // Return result
1634
+ let result;
1635
+ if (config.doneFunnction) {
1636
+ result = await config.doneFunction();
1637
+ }
1638
+ resolve(result);
1639
+ });
1640
+ });
1641
+ }
1642
+ /**
1643
+ * Load image for image element
1644
+ *
1645
+ * @param imageElement
1646
+ * @param src
1647
+ * @protected
1648
+ */
1649
+ async loadImage(imageElement, src) {
1650
+ src = src || imageElement.src;
1651
+ return new Promise((resolve, reject) => {
1652
+ imageElement.onload = () => resolve(imageElement);
1653
+ imageElement.onerror = reject;
1654
+ imageElement.src = src;
1655
+ });
1656
+ }
1657
+ }
1658
+ ImageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ImageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1659
+ ImageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ImageService, providedIn: 'root' });
1660
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ImageService, decorators: [{
1661
+ type: Injectable,
1662
+ args: [{
1663
+ providedIn: 'root',
1664
+ }]
1665
+ }] });
1666
+
1667
+ /**
1668
+ * Scroll service for autoscroll to specific fragments
1669
+ */
1670
+ class ScrollService {
1671
+ /**
1672
+ * Initializer
1673
+ */
1674
+ constructor(router, moduleConfig, imageService) {
1675
+ this.router = router;
1676
+ this.moduleConfig = moduleConfig;
1677
+ this.imageService = imageService;
1678
+ /**
1679
+ * Is a scroll listener set
1680
+ *
1681
+ * @protected
1682
+ */
1683
+ this.scrollListener = false;
1684
+ /**
1685
+ * Current scroll timer;
1686
+ *
1687
+ * @protected
1688
+ */
1689
+ this.scrollTimer = -1;
1690
+ const config = {
1691
+ scrollDetectionOffset: 200,
1692
+ scrollOffset: 100,
1693
+ scrollSamplingRate: 100,
1694
+ ...moduleConfig,
1695
+ };
1696
+ this.detectionOffset = config.scrollDetectionOffset;
1697
+ this.scrollOffset = config.scrollOffset;
1698
+ this.scrollSamplingRate = config.scrollSamplingRate;
1699
+ }
1700
+ /**
1701
+ * Scroll to structureElement with specific ID
1702
+ */
1703
+ async scrollTo(id, options = {}) {
1704
+ // Prepare config
1705
+ const config = {
1706
+ checkUrl: false,
1707
+ loadImagesBefore: true,
1708
+ resetStyles: false,
1709
+ setOverflow: true,
1710
+ stopPropagation: true,
1711
+ ...options,
1712
+ };
1713
+ // Check current URL
1714
+ if (config.checkUrl && this.router.url !== '/' && !this.router.url.startsWith('/#')) {
1715
+ await this.router.navigate(['/'], { fragment: id });
1716
+ return !config.stopPropagation;
1717
+ }
1718
+ // Check if target element exits
1719
+ const el = document.getElementById(id);
1720
+ if (!el) {
1721
+ console.error('Missing scroll element with ID:', id);
1722
+ return !config.stopPropagation;
1723
+ }
1724
+ // Check if body overflow is visible
1725
+ // This is necessary for scroll handling
1726
+ const body = document.querySelector('body');
1727
+ let undoOverflowChanges = false;
1728
+ const scrollBodyStyles = JSON.parse(JSON.stringify(window.getComputedStyle(body)));
1729
+ if (config.setOverflow && (scrollBodyStyles.overflowX !== 'visible' || scrollBodyStyles.overflowY !== 'visible')) {
1730
+ // Set body overflow to visible
1731
+ console.warn('Style of body element for overflowX and overflowY will be set to "visible" for scrolling!');
1732
+ body.style.overflowX = 'visible';
1733
+ body.style.overflowY = 'visible';
1734
+ undoOverflowChanges = true;
1735
+ }
1736
+ // Load images before scrolling (once)
1737
+ if (config.loadImagesBefore) {
1738
+ await this.imageService.preLoadImages();
1739
+ }
1740
+ // Get get bounding rect of target element
1741
+ const cords = el.getBoundingClientRect();
1742
+ // Scroll to element
1743
+ window.scrollBy({ top: cords.top - this.scrollOffset, behavior: 'smooth' });
1744
+ await this.scrollDone({
1745
+ doneFunction: () => {
1746
+ // Undo changes
1747
+ if (undoOverflowChanges && config.resetStyles) {
1748
+ body.style.overflowX = scrollBodyStyles.overflowX;
1749
+ body.style.overflowY = scrollBodyStyles.overflowY;
1750
+ console.warn('Original style of body element for overflowX and overflowY is set.');
1751
+ }
1752
+ },
1753
+ });
1754
+ // Return stop propagation configuration
1755
+ return !config.stopPropagation;
1756
+ }
1757
+ /**
1758
+ * Get last active structureElement
1759
+ */
1760
+ getLastActiveElement(list) {
1761
+ const currentScrollPosition = window.scrollY;
1762
+ const elementsWithId = document.querySelectorAll('[id]');
1763
+ let lastId = null;
1764
+ let lastPosition = 0 - this.detectionOffset - 1;
1765
+ elementsWithId.forEach((element) => {
1766
+ const cords = element.getBoundingClientRect();
1767
+ const top = cords.top + window.pageYOffset - this.detectionOffset;
1768
+ if ((!list || !list.length || list.includes(element.id)) && // In list
1769
+ top < currentScrollPosition && // In active area
1770
+ lastPosition < top // Higher than the last one
1771
+ ) {
1772
+ lastId = element.id;
1773
+ lastPosition = top;
1774
+ }
1775
+ });
1776
+ return lastId;
1777
+ }
1778
+ /**
1779
+ * Check if ID is active
1780
+ */
1781
+ isActive(id, list, isFirst) {
1782
+ const lastActiveElement = this.getLastActiveElement(list);
1783
+ return id === lastActiveElement || (lastActiveElement === null && isFirst);
1784
+ }
1785
+ /**
1786
+ * Scroll done promise
1787
+ */
1788
+ async scrollDone(options = {}) {
1789
+ // Init configuration
1790
+ const config = {
1791
+ doneFunction: undefined,
1792
+ ...options,
1793
+ };
1794
+ // Wait for scroll done
1795
+ await this.scrollDoneDetection();
1796
+ // Get result
1797
+ if (config.doneFunction) {
1798
+ return config.doneFunction();
1799
+ }
1800
+ }
1801
+ /**
1802
+ * Scroll done detecton
1803
+ *
1804
+ * @protected
1805
+ */
1806
+ scrollDoneDetection() {
1807
+ // Return current scroll promise (Singelton)
1808
+ if (this.scrollPromise) {
1809
+ return this.scrollPromise;
1810
+ }
1811
+ // Create current scroll promise
1812
+ this.scrollPromise = new Promise((resolve) => {
1813
+ this.scrollPromiseResolve = resolve;
1814
+ if (this.scrollTimer !== -1) {
1815
+ window.clearTimeout(this.scrollTimer);
1816
+ }
1817
+ this.scrollTimer = window.setTimeout(() => {
1818
+ window.removeEventListener('scroll', this.scrollDoneDetection.bind(this));
1819
+ this.scrollPromise = undefined;
1820
+ resolve();
1821
+ }, this.scrollSamplingRate);
1822
+ });
1823
+ // Lisitening to scroll event;
1824
+ window.addEventListener('scroll', this.scrollDoneDetection.bind(this));
1825
+ // Return promise
1826
+ return this.scrollPromise;
1827
+ }
1828
+ }
1829
+ ScrollService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ScrollService, deps: [{ token: i1$1.Router }, { token: BASE_MODULE_CONFIG }, { token: ImageService }], target: i0.ɵɵFactoryTarget.Injectable });
1830
+ ScrollService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ScrollService, providedIn: 'root' });
1831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ScrollService, decorators: [{
1832
+ type: Injectable,
1833
+ args: [{
1834
+ providedIn: 'root',
1835
+ }]
1836
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: undefined, decorators: [{
1837
+ type: Inject,
1838
+ args: [BASE_MODULE_CONFIG]
1839
+ }] }, { type: ImageService }]; } });
1840
+
1841
+ /**
1842
+ * Comparison operator enum
1843
+ */
1844
+ var ComparisonOperatorEnum;
1845
+ (function (ComparisonOperatorEnum) {
1846
+ ComparisonOperatorEnum["EQ"] = "EQ";
1847
+ ComparisonOperatorEnum["GT"] = "GT";
1848
+ ComparisonOperatorEnum["GTE"] = "GTE";
1849
+ ComparisonOperatorEnum["IN"] = "IN";
1850
+ ComparisonOperatorEnum["LT"] = "LT";
1851
+ ComparisonOperatorEnum["LTE"] = "LTE";
1852
+ ComparisonOperatorEnum["NE"] = "NE";
1853
+ ComparisonOperatorEnum["NIN"] = "NIN";
1854
+ ComparisonOperatorEnum["REGEX"] = "REGEX";
1855
+ })(ComparisonOperatorEnum || (ComparisonOperatorEnum = {}));
1856
+
1857
+ /**
1858
+ * Logical operator enum
1859
+ */
1860
+ var LogicalOperatorEnum;
1861
+ (function (LogicalOperatorEnum) {
1862
+ LogicalOperatorEnum["AND"] = "AND";
1863
+ LogicalOperatorEnum["NOR"] = "NOR";
1864
+ LogicalOperatorEnum["OR"] = "OR";
1865
+ })(LogicalOperatorEnum || (LogicalOperatorEnum = {}));
1866
+
1867
+ var SortOrderEnum;
1868
+ (function (SortOrderEnum) {
1869
+ SortOrderEnum["ASC"] = "ASC";
1870
+ SortOrderEnum["DESC"] = "DESC";
1871
+ })(SortOrderEnum || (SortOrderEnum = {}));
1872
+
1873
+ class Validation {
1874
+ static match(controlName, checkControlName) {
1875
+ return (controls) => {
1876
+ const control = controls.get(controlName);
1877
+ const checkControl = controls.get(checkControlName);
1878
+ if (checkControl?.errors && !checkControl.errors?.matching) {
1879
+ return null;
1880
+ }
1881
+ if (control?.value !== checkControl?.value) {
1882
+ controls.get(checkControlName)?.setErrors({ matching: true });
1883
+ return { matching: true };
1884
+ }
1885
+ else {
1886
+ return null;
1887
+ }
1888
+ };
1889
+ }
1890
+ }
1891
+
1892
+ function createRestartableClient(options) {
1893
+ let restartRequested = false;
1894
+ let restart = () => {
1895
+ restartRequested = true;
1896
+ };
1897
+ const { on = undefined } = options;
1898
+ const client = createClient({
1899
+ ...options,
1900
+ on: {
1901
+ ...on,
1902
+ connected: (socket) => {
1903
+ // @ts-ignore
1904
+ on?.connected?.(socket);
1905
+ restart = () => {
1906
+ if (socket.readyState === WebSocket.OPEN) {
1907
+ // if the socket is still open for the restart, do the restart
1908
+ socket.close(4205, 'Client Restart');
1909
+ }
1910
+ else {
1911
+ // otherwise the socket might've closed, indicate that you want
1912
+ // a restart on the next connected event
1913
+ restartRequested = true;
1914
+ }
1915
+ };
1916
+ // just in case you were eager to restart
1917
+ if (restartRequested) {
1918
+ restartRequested = false;
1919
+ restart();
1920
+ }
1921
+ },
1922
+ },
1923
+ });
1924
+ return {
1925
+ ...client,
1926
+ restart: () => restart(),
1927
+ };
1928
+ }
1929
+
1930
+ /**
1931
+ * Exports for public API
1932
+ */
1933
+
1934
+ /**
1935
+ * Generated bundle index. Do not edit.
1936
+ */
1937
+
1938
+ export { Auth, AuthService, BASE_MODULE_CONFIG, BasicUser, ComparisonOperatorEnum, FormsService, GraphQLEnum, GraphQLMeta, GraphQLMetaService, GraphQLPlusService, GraphQLRequestType, GraphQLService, GraphQLType, Helper, ImageService, LoaderService, LogicalOperatorEnum, ScrollService, SortOrderEnum, Standard, StorageService, UserService, Validation, WsService, createRestartableClient };
1939
+ //# sourceMappingURL=lenne.tech-ng-base-shared.mjs.map