@lenne.tech/ng-base 13.6.5 → 13.7.0

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