@stemy/ngx-utils 19.5.26 → 19.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  import 'zone.js';
2
2
  import 'reflect-metadata';
3
3
  import * as i0 from '@angular/core';
4
- import { InjectionToken, PLATFORM_ID, Inject, Injectable, Optional, Injector, untracked, computed, signal, inject, DestroyRef, EventEmitter, isDevMode, ErrorHandler, createComponent, NgZone, Pipe, input, output, ChangeDetectorRef, ElementRef, effect, HostListener, Directive, Input, HostBinding, Output, TemplateRef, ChangeDetectionStrategy, ViewEncapsulation, Component, ViewChild, forwardRef, ContentChild, ContentChildren, model, contentChildren, APP_INITIALIZER, makeEnvironmentProviders, NgModule } from '@angular/core';
4
+ import { InjectionToken, PLATFORM_ID, Inject, Injectable, Optional, Injector, untracked, computed, signal, inject, DestroyRef, isDevMode, ErrorHandler, EventEmitter, createComponent, NgZone, Pipe, input, output, ChangeDetectorRef, ElementRef, effect, HostListener, Directive, Input, HostBinding, Output, TemplateRef, ChangeDetectionStrategy, ViewEncapsulation, Component, ViewChild, forwardRef, ContentChild, ContentChildren, model, contentChildren, APP_INITIALIZER, makeEnvironmentProviders, NgModule } from '@angular/core';
5
5
  import * as i2 from '@angular/router';
6
6
  import { ActivatedRouteSnapshot, Scroll, NavigationEnd, Router, DefaultUrlSerializer, UrlTree, UrlSegmentGroup, UrlSegment, UrlSerializer, ROUTES } from '@angular/router';
7
- import { BehaviorSubject, Observable, firstValueFrom, Subject, Subscription, from, TimeoutError, combineLatest, lastValueFrom } from 'rxjs';
7
+ import { BehaviorSubject, Observable, firstValueFrom, Subject, Subscription, from, delay, timer, TimeoutError, combineLatest, lastValueFrom } from 'rxjs';
8
8
  import { skipWhile, debounceTime, distinctUntilChanged, map, filter, mergeMap, timeout } from 'rxjs/operators';
9
9
  import * as i1$3 from '@angular/common';
10
10
  import { isPlatformBrowser, isPlatformServer, DOCUMENT, APP_BASE_HREF, CommonModule } from '@angular/common';
@@ -13,7 +13,7 @@ import { DeviceDetectorService } from 'ngx-device-detector';
13
13
  import { DateTime } from 'luxon';
14
14
  import { Invokable } from 'invokable';
15
15
  import * as i1$1 from '@angular/common/http';
16
- import { HttpClient, HttpHeaders, HttpParams, HttpUrlEncodingCodec, HttpEventType } from '@angular/common/http';
16
+ import { HttpClient, HttpHeaders, HttpParams, HttpUrlEncodingCodec, HttpEventType, HttpResponse } from '@angular/common/http';
17
17
  import JSON5 from 'json5';
18
18
  import * as i1$2 from '@angular/platform-browser';
19
19
  import { ɵDomEventsPlugin as _DomEventsPlugin, EVENT_MANAGER_PLUGINS } from '@angular/platform-browser';
@@ -224,6 +224,9 @@ class ObjectUtils {
224
224
  static isString(value) {
225
225
  return typeof value === "string";
226
226
  }
227
+ static isStringWithValue(value) {
228
+ return ObjectUtils.isString(value) && value.length > 0;
229
+ }
227
230
  static isFunction(value) {
228
231
  return typeof value === "function";
229
232
  }
@@ -448,30 +451,6 @@ class PaginationItemContext {
448
451
  return false;
449
452
  }
450
453
  }
451
- class HttpPromise extends Promise {
452
- constructor(rejectHandler, executor) {
453
- super(executor);
454
- this.rejectHandler = rejectHandler;
455
- this.attachCount = 0;
456
- this.runCount = 0;
457
- }
458
- then(onFulfilled, onRejected) {
459
- this.attachCount++;
460
- return super.then(value => {
461
- this.runCount++;
462
- return onFulfilled ? onFulfilled(value) : null;
463
- }, (reason) => {
464
- const result = onRejected ? onRejected(reason) : null;
465
- this.hasRejectHandler = this.hasRejectHandler || (onRejected && result !== false);
466
- this.runCount++;
467
- this.rejectHandler(this.runCount == this.attachCount && !this.hasRejectHandler ? reason : null);
468
- return result;
469
- });
470
- }
471
- catch(onRejected) {
472
- return this.then(null, onRejected);
473
- }
474
- }
475
454
  // --- Resource if ---
476
455
  class ResourceIfContext {
477
456
  }
@@ -2038,6 +2017,21 @@ class MathUtils {
2038
2017
  function isBrowser() {
2039
2018
  return typeof window !== "undefined";
2040
2019
  }
2020
+ /**
2021
+ * Returns a hash code from anything
2022
+ * @param {string} obj The object to hash.
2023
+ * @return {number} A 32bit integer
2024
+ */
2025
+ function hashCode(obj) {
2026
+ const str = typeof obj === "string" ? obj : JSON.stringify(obj);
2027
+ let hash = 0;
2028
+ for (let i = 0, len = str.length; i < len; i++) {
2029
+ const chr = str.charCodeAt(i);
2030
+ hash = (hash << 5) - hash + chr;
2031
+ hash |= 0; // Convert to 32bit integer
2032
+ }
2033
+ return hash;
2034
+ }
2041
2035
  function switchClass(elem, className, status) {
2042
2036
  if (!elem?.classList)
2043
2037
  return;
@@ -2319,21 +2313,6 @@ class StringUtils {
2319
2313
  }
2320
2314
  }
2321
2315
  }
2322
- /**
2323
- * Returns a hash code from a string
2324
- * @param {String} str The string to hash.
2325
- * @return {Number} A 32bit integer
2326
- * @see http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
2327
- */
2328
- function hashCode(str) {
2329
- let hash = 0;
2330
- for (let i = 0, len = str.length; i < len; i++) {
2331
- const chr = str.charCodeAt(i);
2332
- hash = (hash << 5) - hash + chr;
2333
- hash |= 0; // Convert to 32bit integer
2334
- }
2335
- return hash;
2336
- }
2337
2316
 
2338
2317
  class SetUtils {
2339
2318
  static equals(set, obj) {
@@ -2850,6 +2829,78 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
2850
2829
  type: Injectable
2851
2830
  }], ctorParameters: () => [{ type: UniversalService }] });
2852
2831
 
2832
+ class EventsService {
2833
+ get isSticky() {
2834
+ return this.sticky;
2835
+ }
2836
+ get isAuthenticated() {
2837
+ return !!this.user;
2838
+ }
2839
+ constructor() {
2840
+ this.eventForwarded = new Subject();
2841
+ this.stickyUpdated = new Subject();
2842
+ this.languageChanged = new Subject();
2843
+ this.translationsEnabled = new Subject();
2844
+ this.userChanged = new Subject();
2845
+ this.sticky = false;
2846
+ this.user = null;
2847
+ this.userChanged.subscribe(user => {
2848
+ this.user = user;
2849
+ });
2850
+ }
2851
+ event(e) {
2852
+ this.eventForwarded.next(e);
2853
+ }
2854
+ updateSticky(sticky) {
2855
+ this.sticky = sticky;
2856
+ this.stickyUpdated.next(sticky);
2857
+ }
2858
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EventsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2859
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EventsService }); }
2860
+ }
2861
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EventsService, decorators: [{
2862
+ type: Injectable
2863
+ }], ctorParameters: () => [] });
2864
+
2865
+ class CacheService {
2866
+ get userChanged() {
2867
+ return this.events.userChanged;
2868
+ }
2869
+ constructor(events) {
2870
+ this.events = events;
2871
+ this.ignore = new BehaviorSubject(null).pipe(delay(5));
2872
+ this.permanent = new Subject();
2873
+ this.caches = new Map();
2874
+ }
2875
+ expiresIn(amount = 10, unit = "seconds") {
2876
+ const when = DateTime.now().plus({ [unit]: amount }).toJSDate();
2877
+ return this.expiresAt(when);
2878
+ }
2879
+ expiresAt(when) {
2880
+ const now = new Date().getTime();
2881
+ // Prevent negative delay
2882
+ const delay = Math.max(when.getTime() - now, 5);
2883
+ return timer(delay);
2884
+ }
2885
+ use(key, valueCb, expires) {
2886
+ if (this.caches.has(key)) {
2887
+ return this.caches.get(key);
2888
+ }
2889
+ const value = valueCb();
2890
+ this.caches.set(key, value);
2891
+ const subscription = (expires || this.permanent).subscribe(() => {
2892
+ this.caches.delete(key);
2893
+ subscription.unsubscribe();
2894
+ });
2895
+ return value;
2896
+ }
2897
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CacheService, deps: [{ token: EventsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2898
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CacheService }); }
2899
+ }
2900
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CacheService, decorators: [{
2901
+ type: Injectable
2902
+ }], ctorParameters: () => [{ type: EventsService }] });
2903
+
2853
2904
  class BaseHttpService {
2854
2905
  static { this.failedRequests = []; }
2855
2906
  get name() {
@@ -2865,21 +2916,30 @@ class BaseHttpService {
2865
2916
  get universal() {
2866
2917
  return this.storage.universal;
2867
2918
  }
2868
- constructor(injector, client, storage, language, toaster, configs, request = null) {
2919
+ constructor(injector, client, storage, caches, language, toaster, configs, request = null) {
2869
2920
  this.injector = injector;
2870
2921
  this.client = client;
2871
2922
  this.storage = storage;
2923
+ this.caches = caches;
2872
2924
  this.language = language;
2873
2925
  this.toaster = toaster;
2874
2926
  this.configs = configs;
2875
2927
  this.request = request;
2876
2928
  this.requestHeaders = {};
2877
2929
  this.requestParams = {};
2878
- this.cache = {};
2879
2930
  this.initService();
2880
2931
  }
2881
2932
  initService() {
2882
2933
  }
2934
+ cached(mode) {
2935
+ if (mode === "auth") {
2936
+ return this.caches.userChanged;
2937
+ }
2938
+ if (mode instanceof Date) {
2939
+ return this.caches.expiresAt(mode);
2940
+ }
2941
+ return mode === false ? this.caches.ignore : this.caches.permanent;
2942
+ }
2883
2943
  url(url) {
2884
2944
  return url;
2885
2945
  }
@@ -2986,78 +3046,84 @@ class BaseHttpService {
2986
3046
  toastError(message, issueContext, reason, options) {
2987
3047
  this.toaster.warning(message, { issueContext, reason, options });
2988
3048
  }
2989
- toPromise(url, options, listener) {
2990
- const issueContext = { url: "" };
2991
- return new HttpPromise(response => {
2992
- if (!response) {
2993
- if (this.universal.isServer)
3049
+ toPromise(url, requestOptions, listener) {
3050
+ const { cache, read, ...options } = requestOptions;
3051
+ const absoluteUrl = this.absoluteUrl(url, options);
3052
+ const cacheKey = `request-${hashCode(absoluteUrl)}-${hashCode(options)}`;
3053
+ const issueContext = { url: absoluteUrl };
3054
+ return this.caches.use(`${cacheKey}-${read}`, async () => {
3055
+ const response = await this.caches.use(cacheKey, () => new HttpPromise(response => {
3056
+ if (!response) {
3057
+ if (this.universal.isServer)
3058
+ return;
3059
+ console.log("You may not need a reject Handler for this request!", this.name, url, options);
2994
3060
  return;
2995
- console.log("You may not need a reject Handler for this request!", this.name, url, options);
2996
- return;
2997
- }
2998
- const reason = response.error || {};
2999
- if (response.status == 0 || response.status == 301) {
3000
- this.toastWarning(`${url} endpoint is not implemented! Click here, to quickly create an issue.`, issueContext, reason, options);
3001
- return;
3002
- }
3003
- const regex = /((E11000 duplicate key error collection: (.)+\.)|(_1 dup key:(.)+))/g;
3004
- if (reason.message && regex.test(reason.message)) {
3005
- this.toastError("message.duplicate-key.error." + reason.message.replace(regex, "").replace(" index: ", "-"), issueContext, reason, options);
3006
- return;
3007
- }
3008
- this.toastWarning(`${url} endpoint error is not handled properly! Click here, to quickly create an issue.`, issueContext, reason, options);
3009
- }, (resolve, reject) => {
3010
- this.absoluteUrl(url, options).then(absoluteUrl => {
3011
- issueContext.url = absoluteUrl;
3061
+ }
3062
+ const reason = response.error || {};
3063
+ if (response.status == 0 || response.status == 301) {
3064
+ this.toastWarning(`${url} endpoint is not implemented! Click here, to quickly create an issue.`, issueContext, reason, options);
3065
+ return;
3066
+ }
3067
+ const regex = /((E11000 duplicate key error collection: (.)+\.)|(_1 dup key:(.)+))/g;
3068
+ if (reason.message && regex.test(reason.message)) {
3069
+ this.toastError("message.duplicate-key.error." + reason.message.replace(regex, "").replace(" index: ", "-"), issueContext, reason, options);
3070
+ return;
3071
+ }
3072
+ this.toastWarning(`${url} endpoint error is not handled properly! Click here, to quickly create an issue.`, issueContext, reason, options);
3073
+ }, (resolve, reject) => {
3012
3074
  const request = this.client.request(options.method, absoluteUrl, options);
3013
3075
  const finalRequest = ObjectUtils.isNumber(options.timeout) && options.timeout > 0
3014
3076
  ? request.pipe(timeout(options.timeout)) : request;
3015
- finalRequest.subscribe((event) => {
3016
- if (options.reportProgress && event?.type === HttpEventType.UploadProgress) {
3017
- const progress = {
3018
- percentage: MathUtils.round(event.loaded / event.total, 2, 0.01),
3019
- loaded: event.loaded,
3020
- total: event.total
3021
- };
3022
- if (listener) {
3023
- listener(progress);
3077
+ finalRequest.subscribe({
3078
+ next: event => {
3079
+ if (options.reportProgress && event?.type === HttpEventType.UploadProgress) {
3080
+ const progress = {
3081
+ percentage: MathUtils.round(event.loaded / event.total, 2, 0.01),
3082
+ loaded: event.loaded,
3083
+ total: event.total
3084
+ };
3085
+ if (listener) {
3086
+ listener(progress);
3087
+ }
3088
+ return;
3024
3089
  }
3025
- return;
3026
- }
3027
- resolve(this.parseResponse(event, url, options));
3028
- const headers = options.headers;
3029
- const authKey = "Authorization";
3030
- // If we use token auth
3031
- if (this.client.renewTokenFunc && headers.has(authKey)) {
3032
- const currentTime = Date.now() + 60_000;
3033
- const userTokenTime = this.getUserTokenTime() || currentTime;
3034
- // And the stored token expiration time is almost ended
3035
- if (currentTime >= userTokenTime) {
3036
- this.client.renewTokenFunc();
3090
+ resolve(event);
3091
+ const headers = options.headers;
3092
+ const authKey = "Authorization";
3093
+ // If we use token auth
3094
+ if (this.client.renewTokenFunc && headers.has(authKey)) {
3095
+ const currentTime = Date.now() + 60_000;
3096
+ const userTokenTime = this.getUserTokenTime() || currentTime;
3097
+ // And the stored token expiration time is almost ended
3098
+ if (currentTime >= userTokenTime) {
3099
+ this.client.renewTokenFunc();
3100
+ }
3037
3101
  }
3038
- }
3039
- }, (response) => {
3040
- if (response instanceof TimeoutError || response.status == 0 || response.status == 301) {
3041
- reject(response);
3042
- return;
3043
- }
3044
- const headers = options.headers;
3045
- const authKey = "Authorization";
3046
- // If an authorization header exists, and we still have an Unauthorized response prompt the user to log in again
3047
- if (headers.has(authKey) && response.status == 401) {
3048
- const pushed = this.pushFailedRequest(url, options, () => {
3049
- options.headers = this.makeHeaders(options.originalHeaders);
3050
- this.toPromise(url, options, listener).then(resolve, reject);
3051
- });
3052
- if (pushed) {
3053
- this.handleUnauthorizedError(absoluteUrl, options, () => reject(response));
3102
+ },
3103
+ error: (response) => {
3104
+ if (response instanceof TimeoutError || response.status == 0 || response.status == 301) {
3105
+ reject(response);
3054
3106
  return;
3055
3107
  }
3108
+ const headers = options.headers;
3109
+ const authKey = "Authorization";
3110
+ // If an authorization header exists, and we still have an Unauthorized response prompt the user to log in again
3111
+ if (headers.has(authKey) && response.status == 401) {
3112
+ const pushed = this.pushFailedRequest(url, options, () => {
3113
+ options.headers = this.makeHeaders(options.originalHeaders);
3114
+ this.toPromise(url, options, listener).then(resolve, reject);
3115
+ });
3116
+ if (pushed) {
3117
+ this.handleUnauthorizedError(absoluteUrl, options, () => reject(response));
3118
+ return;
3119
+ }
3120
+ }
3121
+ reject(response);
3056
3122
  }
3057
- reject(response);
3058
3123
  });
3059
- });
3060
- });
3124
+ }), cache);
3125
+ return this.parseResponse(response, url, options, read);
3126
+ }, cache);
3061
3127
  }
3062
3128
  getUserTokenTime() {
3063
3129
  return this.storage.get("userTokenTime");
@@ -3074,9 +3140,10 @@ class BaseHttpService {
3074
3140
  }
3075
3141
  return headers.referer.indexOf(headers.host) >= 0;
3076
3142
  }
3077
- makeOptions(options, method = "GET", body) {
3143
+ makeOptions(options, method = "GET", body, cache) {
3078
3144
  // Set base options
3079
3145
  options = options ? { ...options } : {};
3146
+ options.cache = options.cache || cache || this.caches.ignore;
3080
3147
  options.method = method;
3081
3148
  options.observe = options.observe || "body";
3082
3149
  options.originalHeaders = options.originalHeaders || options.headers || {};
@@ -3097,13 +3164,18 @@ class BaseHttpService {
3097
3164
  makeParams(options) {
3098
3165
  return this.client.makeParams(Object.assign({}, this.requestParams, options?.params || {}));
3099
3166
  }
3100
- parseResponse(response, url, options) {
3101
- return response;
3167
+ parseResponse(response, url, options, read) {
3168
+ if (!read)
3169
+ return response;
3170
+ if (response instanceof HttpResponse) {
3171
+ response = response.body;
3172
+ }
3173
+ return ObjectUtils.isObject(response) ? response[read] : response;
3102
3174
  }
3103
3175
  parseUrl(url) {
3104
3176
  return this.url(url).replace(/(?:((?!:).\/)\/)/g, "$1");
3105
3177
  }
3106
- async absoluteUrl(url, options) {
3178
+ absoluteUrl(url, options) {
3107
3179
  return this.parseUrl(url);
3108
3180
  }
3109
3181
  expressRequestUrl(url) {
@@ -3113,21 +3185,12 @@ class BaseHttpService {
3113
3185
  const separator = url.startsWith("/") ? "" : "/";
3114
3186
  return `${req.protocol}://${req.get("host")}${separator}${url}`;
3115
3187
  }
3116
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseHttpService, deps: [{ token: Injector }, { token: BaseHttpClient }, { token: StorageService }, { token: LANGUAGE_SERVICE }, { token: TOASTER_SERVICE }, { token: CONFIG_SERVICE }, { token: EXPRESS_REQUEST, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
3188
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseHttpService, deps: [{ token: i0.Injector }, { token: BaseHttpClient }, { token: StorageService }, { token: CacheService }, { token: LANGUAGE_SERVICE }, { token: TOASTER_SERVICE }, { token: CONFIG_SERVICE }, { token: EXPRESS_REQUEST, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
3117
3189
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseHttpService }); }
3118
3190
  }
3119
3191
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseHttpService, decorators: [{
3120
3192
  type: Injectable
3121
- }], ctorParameters: () => [{ type: i0.Injector, decorators: [{
3122
- type: Inject,
3123
- args: [Injector]
3124
- }] }, { type: BaseHttpClient, decorators: [{
3125
- type: Inject,
3126
- args: [BaseHttpClient]
3127
- }] }, { type: StorageService, decorators: [{
3128
- type: Inject,
3129
- args: [StorageService]
3130
- }] }, { type: undefined, decorators: [{
3193
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: BaseHttpClient }, { type: StorageService }, { type: CacheService }, { type: undefined, decorators: [{
3131
3194
  type: Inject,
3132
3195
  args: [LANGUAGE_SERVICE]
3133
3196
  }] }, { type: undefined, decorators: [{
@@ -3142,29 +3205,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3142
3205
  type: Inject,
3143
3206
  args: [EXPRESS_REQUEST]
3144
3207
  }] }] });
3208
+ class HttpPromise extends Promise {
3209
+ constructor(rejectHandler, executor) {
3210
+ super(executor);
3211
+ this.rejectHandler = rejectHandler;
3212
+ this.attachCount = 0;
3213
+ this.runCount = 0;
3214
+ }
3215
+ then(onFulfilled, onRejected) {
3216
+ this.attachCount++;
3217
+ return super.then(value => {
3218
+ this.runCount++;
3219
+ return onFulfilled ? onFulfilled(value) : null;
3220
+ }, (reason) => {
3221
+ const result = onRejected ? onRejected(reason) : null;
3222
+ this.hasRejectHandler = this.hasRejectHandler || (onRejected && result !== false);
3223
+ this.runCount++;
3224
+ this.rejectHandler(this.runCount == this.attachCount && !this.hasRejectHandler ? reason : null);
3225
+ return result;
3226
+ });
3227
+ }
3228
+ catch(onRejected) {
3229
+ return this.then(null, onRejected);
3230
+ }
3231
+ }
3145
3232
 
3146
3233
  class LocalHttpService extends BaseHttpService {
3147
3234
  get name() {
3148
3235
  return "local-http";
3149
3236
  }
3237
+ get config() {
3238
+ return this.configs.config;
3239
+ }
3150
3240
  get withCredentials() {
3151
3241
  return false;
3152
3242
  }
3153
3243
  initService() {
3244
+ super.initService();
3154
3245
  this.images = {};
3155
3246
  }
3156
3247
  url(url) {
3157
3248
  if (!url)
3158
3249
  return url;
3159
- const config = this.configs.config;
3250
+ const config = this.config;
3160
3251
  const baseUrl = config.cdnUrl || config.baseUrl || "";
3161
3252
  return url.startsWith("data:") || url.startsWith("http") || url.startsWith("//")
3162
3253
  ? url
3163
3254
  : `${baseUrl}${url}`;
3164
3255
  }
3165
- get(url, options) {
3166
- this.cache[url] = this.cache[url] || this.getPromise(url, options);
3167
- return this.cache[url];
3256
+ get(url, options, body) {
3257
+ options = this.makeOptions(options, "GET", body, this.caches.permanent);
3258
+ return this.toPromise(url, options);
3168
3259
  }
3169
3260
  getImage(url) {
3170
3261
  if (this.universal.isServer)
@@ -3227,12 +3318,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3227
3318
 
3228
3319
  const emptyGuards = [];
3229
3320
  class AclService {
3230
- constructor(injector, state, auth) {
3321
+ constructor(injector, state, events) {
3231
3322
  this.injector = injector;
3232
3323
  this.state = state;
3233
- this.auth = auth;
3324
+ this.events = events;
3234
3325
  this.components = [];
3235
- this.auth.userChanged.subscribe(() => {
3326
+ this.events.userChanged.subscribe(() => {
3236
3327
  this.components.forEach(t => t.dirty = true);
3237
3328
  const info = this.getStateInfo();
3238
3329
  const check = info && info.guard instanceof AuthGuard ? info.guard.checkRoute(info.route) : Promise.resolve(true);
@@ -3292,15 +3383,12 @@ class AclService {
3292
3383
  info.component = this.state.component;
3293
3384
  return info;
3294
3385
  }
3295
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AclService, deps: [{ token: i0.Injector }, { token: StateService }, { token: AUTH_SERVICE }], target: i0.ɵɵFactoryTarget.Injectable }); }
3386
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AclService, deps: [{ token: i0.Injector }, { token: StateService }, { token: EventsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3296
3387
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AclService }); }
3297
3388
  }
3298
3389
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AclService, decorators: [{
3299
3390
  type: Injectable
3300
- }], ctorParameters: () => [{ type: i0.Injector }, { type: StateService }, { type: undefined, decorators: [{
3301
- type: Inject,
3302
- args: [AUTH_SERVICE]
3303
- }] }] });
3391
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: StateService }, { type: EventsService }] });
3304
3392
 
3305
3393
  class ApiService extends BaseHttpService {
3306
3394
  get name() {
@@ -3346,16 +3434,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3346
3434
  }] });
3347
3435
 
3348
3436
  class StaticAuthService {
3349
- constructor() {
3350
- this.isAuthenticated = true;
3351
- this.userChanged = new EventEmitter();
3437
+ get isAuthenticated() {
3438
+ return false;
3352
3439
  }
3353
3440
  checkAuthenticated() {
3354
3441
  return Promise.resolve(this.isAuthenticated);
3355
3442
  }
3356
- getReturnState(route) {
3357
- return null;
3358
- }
3359
3443
  }
3360
3444
 
3361
3445
  class ConfigService {
@@ -3564,31 +3648,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3564
3648
  type: Injectable
3565
3649
  }], ctorParameters: () => [{ type: i0.Injector }] });
3566
3650
 
3567
- class EventsService {
3568
- get isSticky() {
3569
- return this.sticky;
3570
- }
3571
- constructor() {
3572
- this.eventForwarded = new EventEmitter();
3573
- this.stickyUpdated = new EventEmitter();
3574
- this.languageChanged = new EventEmitter();
3575
- this.translationsEnabled = new EventEmitter();
3576
- this.sticky = false;
3577
- }
3578
- event(e) {
3579
- this.eventForwarded.emit(e);
3580
- }
3581
- updateSticky(sticky) {
3582
- this.sticky = sticky;
3583
- this.stickyUpdated.emit(sticky);
3584
- }
3585
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EventsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3586
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EventsService }); }
3587
- }
3588
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EventsService, decorators: [{
3589
- type: Injectable
3590
- }], ctorParameters: () => [] });
3591
-
3592
3651
  class FormatterService {
3593
3652
  get defaultPrecision() {
3594
3653
  return 2;
@@ -3709,7 +3768,7 @@ class StaticLanguageService {
3709
3768
  }
3710
3769
  set currentLanguage(lang) {
3711
3770
  this.currentLang = lang;
3712
- this.events.languageChanged.emit(lang);
3771
+ this.events.languageChanged.next(lang);
3713
3772
  }
3714
3773
  get editLanguage() {
3715
3774
  return this.editLang || this.currentLanguage;
@@ -3722,7 +3781,7 @@ class StaticLanguageService {
3722
3781
  }
3723
3782
  set enableTranslations(value) {
3724
3783
  this.enableTrans = value;
3725
- this.events.translationsEnabled.emit(value);
3784
+ this.events.translationsEnabled.next(value);
3726
3785
  }
3727
3786
  get disableTranslations() {
3728
3787
  return !this.enableTranslations;
@@ -3878,7 +3937,7 @@ class LanguageService extends StaticLanguageService {
3878
3937
  }
3879
3938
  set currentLanguage(lang) {
3880
3939
  this.useLanguage(lang).then(() => {
3881
- this.events.languageChanged.emit(lang);
3940
+ this.events.languageChanged.next(lang);
3882
3941
  });
3883
3942
  }
3884
3943
  get settings() {
@@ -3923,7 +3982,7 @@ class LanguageService extends StaticLanguageService {
3923
3982
  }
3924
3983
  const lang = this.languages.indexOf(defaultLanguage) < 0 ? settings.defaultLanguage || this.languageList[0] : defaultLanguage;
3925
3984
  await this.useLanguage(lang);
3926
- this.events.languageChanged.emit(lang);
3985
+ this.events.languageChanged.next(lang);
3927
3986
  }
3928
3987
  async useLanguage(lang) {
3929
3988
  lang = this.languages.indexOf(lang) < 0 ? this.languages[0] : lang;
@@ -3977,27 +4036,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3977
4036
  class OpenApiService {
3978
4037
  constructor(api) {
3979
4038
  this.api = api;
4039
+ this.dynamicSchemas = {};
3980
4040
  }
3981
- getSchemas() {
3982
- this.schemasPromise = this.schemasPromise || new Promise((resolve => {
3983
- this.api.get("api-docs").then(res => {
3984
- const schemas = res.components?.schemas || res.definitions || {};
3985
- Object.values(schemas).forEach(schema => {
3986
- Object.keys(schema.properties || {}).forEach(p => {
3987
- schema.properties[p].id = p;
3988
- });
3989
- });
3990
- resolve(schemas);
3991
- }, () => {
3992
- resolve({});
3993
- });
4041
+ isDynamicSchema(value) {
4042
+ if (!ObjectUtils.isObject(value)) {
4043
+ return false;
4044
+ }
4045
+ const definition = value;
4046
+ return ObjectUtils.isStringWithValue(definition.dynamicSchema)
4047
+ || ObjectUtils.isStringWithValue(definition.dynamicSchemaUrl)
4048
+ || ObjectUtils.isStringWithValue(definition.dynamicSchemaName);
4049
+ }
4050
+ async getSchemas() {
4051
+ const cache = this.api.cached("auth");
4052
+ const apiDocs = this.api.get("api-docs", { cache });
4053
+ if (apiDocs !== this.apiDocs) {
4054
+ this.apiDocs = apiDocs;
4055
+ this.schemas = apiDocs.then(res => this.extractSchemas(res));
4056
+ }
4057
+ return this.schemas;
4058
+ }
4059
+ async getReferences(property, schema) {
4060
+ const props = !property.items ? [property] : [property, property.items];
4061
+ const references = [];
4062
+ for (const prop of props) {
4063
+ if (this.isDynamicSchema(prop) || ObjectUtils.isStringWithValue(prop.$ref)) {
4064
+ references.push(prop);
4065
+ continue;
4066
+ }
4067
+ if (ObjectUtils.isArray(prop.allOf)) {
4068
+ prop.allOf
4069
+ .filter(ref => ObjectUtils.isStringWithValue(ref.$ref))
4070
+ .forEach(ref => references.push(ref));
4071
+ }
4072
+ if (ObjectUtils.isArray(prop.oneOf)) {
4073
+ prop.oneOf
4074
+ .filter(ref => ObjectUtils.isStringWithValue(ref.$ref))
4075
+ .forEach(ref => references.push(ref));
4076
+ }
4077
+ }
4078
+ return Promise.all(references.map(ref => {
4079
+ if (this.isDynamicSchema(ref)) {
4080
+ return this.getDynamicSchema(ref);
4081
+ }
4082
+ return this.getSchema(ref.$ref.split("/").pop());
3994
4083
  }));
3995
- return this.schemasPromise;
3996
4084
  }
3997
4085
  async getSchema(name) {
3998
4086
  const schemas = await this.getSchemas();
3999
4087
  return schemas[name] || null;
4000
4088
  }
4089
+ async getDynamicSchema(definition) {
4090
+ const cache = this.api.cached("auth");
4091
+ const dynamicDocs = await this.api.get(definition.dynamicSchema || definition.dynamicSchemaUrl || "dynamic-schemas", { cache });
4092
+ const dynamicSchemas = this.extractSchemas(dynamicDocs);
4093
+ const dynamicSchema = dynamicSchemas[definition.dynamicSchemaName || "DTO"];
4094
+ delete dynamicSchemas[definition.dynamicSchemaName || "DTO"];
4095
+ Object.assign(this.dynamicSchemas, dynamicSchemas);
4096
+ return dynamicSchema;
4097
+ }
4098
+ extractSchemas(res) {
4099
+ const schemas = Object.assign({}, res.components?.schemas || res.definitions || {});
4100
+ Object.values(schemas).forEach(schema => {
4101
+ Object.keys(schema.properties || {}).forEach(p => {
4102
+ schema.properties[p].id = p;
4103
+ });
4104
+ });
4105
+ return schemas;
4106
+ }
4001
4107
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: OpenApiService, deps: [{ token: API_SERVICE }], target: i0.ɵɵFactoryTarget.Injectable }); }
4002
4108
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: OpenApiService }); }
4003
4109
  }
@@ -4332,10 +4438,10 @@ class SocketService {
4332
4438
  get id() {
4333
4439
  return this.client.id;
4334
4440
  }
4335
- constructor(auth, api, ioPath) {
4336
- this.auth = auth;
4441
+ constructor(api, ioPath, events) {
4337
4442
  this.api = api;
4338
4443
  this.ioPath = ioPath;
4444
+ this.events = events;
4339
4445
  const url = this.api.url(this.ioPath);
4340
4446
  this.client = new SocketClient(url, async () => {
4341
4447
  let script = null;
@@ -4350,23 +4456,23 @@ class SocketService {
4350
4456
  });
4351
4457
  }
4352
4458
  withAuth(extraHeaders = {}) {
4353
- this.authSub = this.auth.userChanged.subscribe(user => {
4459
+ this.userSub = this.events.userChanged.subscribe(user => {
4354
4460
  if (user) {
4355
4461
  this.connect(extraHeaders);
4356
4462
  return;
4357
4463
  }
4358
4464
  this.disconnect();
4359
4465
  });
4360
- if (this.auth.isAuthenticated) {
4466
+ if (this.events.isAuthenticated) {
4361
4467
  this.connect(extraHeaders);
4362
4468
  }
4363
4469
  }
4364
4470
  ngOnDestroy() {
4365
- this.authSub?.unsubscribe();
4471
+ this.userSub?.unsubscribe();
4366
4472
  this.disconnect();
4367
4473
  }
4368
4474
  connect(extraHeaders = {}) {
4369
- if (this.authSub && this.auth.isAuthenticated) {
4475
+ if (this.userSub && this.events.isAuthenticated) {
4370
4476
  extraHeaders = {
4371
4477
  ...(extraHeaders || {}),
4372
4478
  ...Object.entries(this.api.client.requestHeaders || {}).reduce((res, entry) => {
@@ -4389,21 +4495,18 @@ class SocketService {
4389
4495
  request(event, content) {
4390
4496
  return this.client.request(event, content);
4391
4497
  }
4392
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SocketService, deps: [{ token: AUTH_SERVICE }, { token: API_SERVICE }, { token: SOCKET_IO_PATH }], target: i0.ɵɵFactoryTarget.Injectable }); }
4498
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SocketService, deps: [{ token: API_SERVICE }, { token: SOCKET_IO_PATH }, { token: EventsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4393
4499
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SocketService }); }
4394
4500
  }
4395
4501
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SocketService, decorators: [{
4396
4502
  type: Injectable
4397
4503
  }], ctorParameters: () => [{ type: undefined, decorators: [{
4398
- type: Inject,
4399
- args: [AUTH_SERVICE]
4400
- }] }, { type: undefined, decorators: [{
4401
4504
  type: Inject,
4402
4505
  args: [API_SERVICE]
4403
4506
  }] }, { type: undefined, decorators: [{
4404
4507
  type: Inject,
4405
4508
  args: [SOCKET_IO_PATH]
4406
- }] }] });
4509
+ }] }, { type: EventsService }] });
4407
4510
 
4408
4511
  class DragDropHandler {
4409
4512
  static get(el) {
@@ -8391,6 +8494,7 @@ const providers = [
8391
8494
  StaticLanguageService,
8392
8495
  StorageService,
8393
8496
  BaseToasterService,
8497
+ CacheService,
8394
8498
  ComponentLoaderService,
8395
8499
  TranslatedUrlSerializer,
8396
8500
  UniversalService,
@@ -8780,5 +8884,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
8780
8884
  * Generated bundle index. Do not edit.
8781
8885
  */
8782
8886
 
8783
- export { API_SERVICE, APP_BASE_URL, AUTH_SERVICE, AclService, AjaxRequestHandler, ApiService, ArrayUtils, AsyncMethodBase, AsyncMethodDirective, AsyncMethodTargetDirective, AuthGuard, BASE_CONFIG, BUTTON_TYPE, BackgroundDirective, BaseDialogService, BaseHttpClient, BaseHttpService, BaseToasterService, BtnComponent, BtnDefaultComponent, CONFIG_SERVICE, CanvasColor, CanvasUtils, ChipsComponent, ChunkPipe, Circle, ComponentLoaderDirective, ComponentLoaderService, ConfigService, DIALOG_SERVICE, DateUtils, DragDropEventPlugin, DropListComponent, DropdownBoxComponent, DropdownContentDirective, DropdownDirective, DropdownToggleDirective, DynamicTableComponent, DynamicTableTemplateDirective, ERROR_HANDLER, EXPRESS_REQUEST, EntriesPipe, ErrorHandlerService, EventsService, ExtraItemPropertiesPipe, FactoryDependencies, FakeModuleComponent, FileSystemEntry, FileUtils, FilterPipe, FindPipe, ForbiddenZone, FormatNumberPipe, FormatterService, GenericValue, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplateDirective, GlobalTemplatePipe, GlobalTemplateService, GroupByPipe, HttpPromise, ICON_MAP, ICON_SERVICE, ICON_TYPE, IConfiguration, IconComponent, IconDefaultComponent, IconDirective, IconService, IncludesPipe, Initializer, InteractiveCanvasComponent, InteractiveCircleComponent, InteractiveItemComponent, InteractiveRectComponent, IsTypePipe, JSONfn, JoinPipe, KeysPipe, LANGUAGE_SERVICE, LanguageService, LoaderUtils, LocalHttpService, MapPipe, MathUtils, MaxPipe, MinPipe, NgxTemplateOutletDirective, NgxUtilsModule, OPTIONS_TOKEN, ObjectType, ObjectUtils, ObservableUtils, OpenApiService, PROMISE_SERVICE, PaginationDirective, PaginationItemContext, PaginationItemDirective, PaginationMenuComponent, Point, PopPipe, PromiseService, RESIZE_DELAY, RESIZE_STRATEGY, ROOT_ELEMENT, Rect, ReducePipe, ReflectUtils, RemapPipe, ReplacePipe, ResizeEventPlugin, ResourceIfContext, ResourceIfDirective, ReversePipe, RoundPipe, SCRIPT_PARAMS, SafeHtmlPipe, ScrollEventPlugin, SetUtils, ShiftPipe, SocketClient, SocketService, SplitPipe, StateService, StaticAuthService, StaticLanguageService, StickyClassDirective, StickyDirective, StorageMode, StorageService, StringUtils, TOASTER_SERVICE, TabsComponent, TabsItemDirective, TabsTemplateDirective, TimerUtils, TranslatePipe, TranslatedUrlSerializer, UniqueUtils, UniversalService, UnorderedListComponent, UnorderedListItemDirective, UnorderedListTemplateDirective, UploadComponent, ValuedPromise, ValuesPipe, Vector, WASI_IMPLEMENTATION, WasmService, cachedFactory, cancelablePromise, checkTransitions, computedPrevious, cssStyles, cssVariables, getComponentDef, getCssVariables, hashCode, impatientPromise, isBrowser, parseSelector, provideEntryComponents, provideWithOptions, selectorMatchesList, switchClass };
8887
+ export { API_SERVICE, APP_BASE_URL, AUTH_SERVICE, AclService, AjaxRequestHandler, ApiService, ArrayUtils, AsyncMethodBase, AsyncMethodDirective, AsyncMethodTargetDirective, AuthGuard, BASE_CONFIG, BUTTON_TYPE, BackgroundDirective, BaseDialogService, BaseHttpClient, BaseHttpService, BaseToasterService, BtnComponent, BtnDefaultComponent, CONFIG_SERVICE, CacheService, CanvasColor, CanvasUtils, ChipsComponent, ChunkPipe, Circle, ComponentLoaderDirective, ComponentLoaderService, ConfigService, DIALOG_SERVICE, DateUtils, DragDropEventPlugin, DropListComponent, DropdownBoxComponent, DropdownContentDirective, DropdownDirective, DropdownToggleDirective, DynamicTableComponent, DynamicTableTemplateDirective, ERROR_HANDLER, EXPRESS_REQUEST, EntriesPipe, ErrorHandlerService, EventsService, ExtraItemPropertiesPipe, FactoryDependencies, FakeModuleComponent, FileSystemEntry, FileUtils, FilterPipe, FindPipe, ForbiddenZone, FormatNumberPipe, FormatterService, GenericValue, GetOffsetPipe, GetTypePipe, GetValuePipe, GlobalTemplateDirective, GlobalTemplatePipe, GlobalTemplateService, GroupByPipe, ICON_MAP, ICON_SERVICE, ICON_TYPE, IConfiguration, IconComponent, IconDefaultComponent, IconDirective, IconService, IncludesPipe, Initializer, InteractiveCanvasComponent, InteractiveCircleComponent, InteractiveItemComponent, InteractiveRectComponent, IsTypePipe, JSONfn, JoinPipe, KeysPipe, LANGUAGE_SERVICE, LanguageService, LoaderUtils, LocalHttpService, MapPipe, MathUtils, MaxPipe, MinPipe, NgxTemplateOutletDirective, NgxUtilsModule, OPTIONS_TOKEN, ObjectType, ObjectUtils, ObservableUtils, OpenApiService, PROMISE_SERVICE, PaginationDirective, PaginationItemContext, PaginationItemDirective, PaginationMenuComponent, Point, PopPipe, PromiseService, RESIZE_DELAY, RESIZE_STRATEGY, ROOT_ELEMENT, Rect, ReducePipe, ReflectUtils, RemapPipe, ReplacePipe, ResizeEventPlugin, ResourceIfContext, ResourceIfDirective, ReversePipe, RoundPipe, SCRIPT_PARAMS, SafeHtmlPipe, ScrollEventPlugin, SetUtils, ShiftPipe, SocketClient, SocketService, SplitPipe, StateService, StaticAuthService, StaticLanguageService, StickyClassDirective, StickyDirective, StorageMode, StorageService, StringUtils, TOASTER_SERVICE, TabsComponent, TabsItemDirective, TabsTemplateDirective, TimerUtils, TranslatePipe, TranslatedUrlSerializer, UniqueUtils, UniversalService, UnorderedListComponent, UnorderedListItemDirective, UnorderedListTemplateDirective, UploadComponent, ValuedPromise, ValuesPipe, Vector, WASI_IMPLEMENTATION, WasmService, cachedFactory, cancelablePromise, checkTransitions, computedPrevious, cssStyles, cssVariables, getComponentDef, getCssVariables, hashCode, impatientPromise, isBrowser, parseSelector, provideEntryComponents, provideWithOptions, selectorMatchesList, switchClass };
8784
8888
  //# sourceMappingURL=stemy-ngx-utils.mjs.map