@stemy/ngx-utils 19.5.25 → 19.6.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.
@@ -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() {
@@ -3348,7 +3436,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3348
3436
  class StaticAuthService {
3349
3437
  constructor() {
3350
3438
  this.isAuthenticated = true;
3351
- this.userChanged = new EventEmitter();
3352
3439
  }
3353
3440
  checkAuthenticated() {
3354
3441
  return Promise.resolve(this.isAuthenticated);
@@ -3564,31 +3651,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3564
3651
  type: Injectable
3565
3652
  }], ctorParameters: () => [{ type: i0.Injector }] });
3566
3653
 
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
3654
  class FormatterService {
3593
3655
  get defaultPrecision() {
3594
3656
  return 2;
@@ -3709,7 +3771,7 @@ class StaticLanguageService {
3709
3771
  }
3710
3772
  set currentLanguage(lang) {
3711
3773
  this.currentLang = lang;
3712
- this.events.languageChanged.emit(lang);
3774
+ this.events.languageChanged.next(lang);
3713
3775
  }
3714
3776
  get editLanguage() {
3715
3777
  return this.editLang || this.currentLanguage;
@@ -3722,7 +3784,7 @@ class StaticLanguageService {
3722
3784
  }
3723
3785
  set enableTranslations(value) {
3724
3786
  this.enableTrans = value;
3725
- this.events.translationsEnabled.emit(value);
3787
+ this.events.translationsEnabled.next(value);
3726
3788
  }
3727
3789
  get disableTranslations() {
3728
3790
  return !this.enableTranslations;
@@ -3878,7 +3940,7 @@ class LanguageService extends StaticLanguageService {
3878
3940
  }
3879
3941
  set currentLanguage(lang) {
3880
3942
  this.useLanguage(lang).then(() => {
3881
- this.events.languageChanged.emit(lang);
3943
+ this.events.languageChanged.next(lang);
3882
3944
  });
3883
3945
  }
3884
3946
  get settings() {
@@ -3923,7 +3985,7 @@ class LanguageService extends StaticLanguageService {
3923
3985
  }
3924
3986
  const lang = this.languages.indexOf(defaultLanguage) < 0 ? settings.defaultLanguage || this.languageList[0] : defaultLanguage;
3925
3987
  await this.useLanguage(lang);
3926
- this.events.languageChanged.emit(lang);
3988
+ this.events.languageChanged.next(lang);
3927
3989
  }
3928
3990
  async useLanguage(lang) {
3929
3991
  lang = this.languages.indexOf(lang) < 0 ? this.languages[0] : lang;
@@ -3977,27 +4039,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3977
4039
  class OpenApiService {
3978
4040
  constructor(api) {
3979
4041
  this.api = api;
4042
+ this.dynamicSchemas = {};
3980
4043
  }
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
- });
4044
+ isDynamicSchema(value) {
4045
+ if (!ObjectUtils.isObject(value)) {
4046
+ return false;
4047
+ }
4048
+ const definition = value;
4049
+ return ObjectUtils.isStringWithValue(definition.dynamicSchema)
4050
+ || ObjectUtils.isStringWithValue(definition.dynamicSchemaUrl)
4051
+ || ObjectUtils.isStringWithValue(definition.dynamicSchemaName);
4052
+ }
4053
+ async getSchemas() {
4054
+ const cache = this.api.cached("auth");
4055
+ const apiDocs = this.api.get("api-docs", { cache });
4056
+ if (apiDocs !== this.apiDocs) {
4057
+ this.apiDocs = apiDocs;
4058
+ this.schemas = apiDocs.then(res => this.extractSchemas(res));
4059
+ }
4060
+ return this.schemas;
4061
+ }
4062
+ async getReferences(property, schema) {
4063
+ const props = !property.items ? [property] : [property, property.items];
4064
+ const references = [];
4065
+ for (const prop of props) {
4066
+ if (this.isDynamicSchema(prop)) {
4067
+ references.push(prop);
4068
+ continue;
4069
+ }
4070
+ if (ObjectUtils.isArray(prop.allOf)) {
4071
+ prop.allOf
4072
+ .filter(ref => ObjectUtils.isStringWithValue(ref.$ref))
4073
+ .forEach(ref => references.push(ref));
4074
+ }
4075
+ if (ObjectUtils.isArray(prop.oneOf)) {
4076
+ prop.oneOf
4077
+ .filter(ref => ObjectUtils.isStringWithValue(ref.$ref))
4078
+ .forEach(ref => references.push(ref));
4079
+ }
4080
+ }
4081
+ return Promise.all(references.map(ref => {
4082
+ if (this.isDynamicSchema(ref)) {
4083
+ return this.getDynamicSchema(ref);
4084
+ }
4085
+ return this.getSchema(ref.$ref.split("/").pop());
3994
4086
  }));
3995
- return this.schemasPromise;
3996
4087
  }
3997
4088
  async getSchema(name) {
3998
4089
  const schemas = await this.getSchemas();
3999
4090
  return schemas[name] || null;
4000
4091
  }
4092
+ async getDynamicSchema(definition) {
4093
+ const cache = this.api.cached("auth");
4094
+ const dynamicDocs = await this.api.get(definition.dynamicSchema || definition.dynamicSchemaUrl || "dynamic-schemas", { cache });
4095
+ const dynamicSchemas = this.extractSchemas(dynamicDocs);
4096
+ const dynamicSchema = dynamicSchemas[definition.dynamicSchemaName || "DTO"];
4097
+ delete dynamicSchemas[definition.dynamicSchemaName || "DTO"];
4098
+ Object.assign(this.dynamicSchemas, dynamicSchemas);
4099
+ return dynamicSchema;
4100
+ }
4101
+ extractSchemas(res) {
4102
+ const schemas = Object.assign({}, res.components?.schemas || res.definitions || {});
4103
+ Object.values(schemas).forEach(schema => {
4104
+ Object.keys(schema.properties || {}).forEach(p => {
4105
+ schema.properties[p].id = p;
4106
+ });
4107
+ });
4108
+ return schemas;
4109
+ }
4001
4110
  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
4111
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: OpenApiService }); }
4003
4112
  }
@@ -4332,10 +4441,10 @@ class SocketService {
4332
4441
  get id() {
4333
4442
  return this.client.id;
4334
4443
  }
4335
- constructor(auth, api, ioPath) {
4336
- this.auth = auth;
4444
+ constructor(api, ioPath, events) {
4337
4445
  this.api = api;
4338
4446
  this.ioPath = ioPath;
4447
+ this.events = events;
4339
4448
  const url = this.api.url(this.ioPath);
4340
4449
  this.client = new SocketClient(url, async () => {
4341
4450
  let script = null;
@@ -4350,23 +4459,23 @@ class SocketService {
4350
4459
  });
4351
4460
  }
4352
4461
  withAuth(extraHeaders = {}) {
4353
- this.authSub = this.auth.userChanged.subscribe(user => {
4462
+ this.userSub = this.events.userChanged.subscribe(user => {
4354
4463
  if (user) {
4355
4464
  this.connect(extraHeaders);
4356
4465
  return;
4357
4466
  }
4358
4467
  this.disconnect();
4359
4468
  });
4360
- if (this.auth.isAuthenticated) {
4469
+ if (this.events.isAuthenticated) {
4361
4470
  this.connect(extraHeaders);
4362
4471
  }
4363
4472
  }
4364
4473
  ngOnDestroy() {
4365
- this.authSub?.unsubscribe();
4474
+ this.userSub?.unsubscribe();
4366
4475
  this.disconnect();
4367
4476
  }
4368
4477
  connect(extraHeaders = {}) {
4369
- if (this.authSub && this.auth.isAuthenticated) {
4478
+ if (this.userSub && this.events.isAuthenticated) {
4370
4479
  extraHeaders = {
4371
4480
  ...(extraHeaders || {}),
4372
4481
  ...Object.entries(this.api.client.requestHeaders || {}).reduce((res, entry) => {
@@ -4389,21 +4498,18 @@ class SocketService {
4389
4498
  request(event, content) {
4390
4499
  return this.client.request(event, content);
4391
4500
  }
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 }); }
4501
+ 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
4502
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SocketService }); }
4394
4503
  }
4395
4504
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SocketService, decorators: [{
4396
4505
  type: Injectable
4397
4506
  }], ctorParameters: () => [{ type: undefined, decorators: [{
4398
- type: Inject,
4399
- args: [AUTH_SERVICE]
4400
- }] }, { type: undefined, decorators: [{
4401
4507
  type: Inject,
4402
4508
  args: [API_SERVICE]
4403
4509
  }] }, { type: undefined, decorators: [{
4404
4510
  type: Inject,
4405
4511
  args: [SOCKET_IO_PATH]
4406
- }] }] });
4512
+ }] }, { type: EventsService }] });
4407
4513
 
4408
4514
  class DragDropHandler {
4409
4515
  static get(el) {
@@ -7943,7 +8049,7 @@ class TabsComponent {
7943
8049
  const current = this.value();
7944
8050
  this.tabItems().forEach(item => {
7945
8051
  const value = item.value();
7946
- switchClass(item.element?.nativeElement, "hidden-tab", current === value);
8052
+ switchClass(item.element?.nativeElement, "hidden-tab", current !== value);
7947
8053
  if (options.some(o => o.value === value))
7948
8054
  return;
7949
8055
  const label = item.label();
@@ -8391,6 +8497,7 @@ const providers = [
8391
8497
  StaticLanguageService,
8392
8498
  StorageService,
8393
8499
  BaseToasterService,
8500
+ CacheService,
8394
8501
  ComponentLoaderService,
8395
8502
  TranslatedUrlSerializer,
8396
8503
  UniversalService,
@@ -8780,5 +8887,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
8780
8887
  * Generated bundle index. Do not edit.
8781
8888
  */
8782
8889
 
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 };
8890
+ 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
8891
  //# sourceMappingURL=stemy-ngx-utils.mjs.map