@rws-framework/client 2.22.0 → 2.23.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.
@@ -11,10 +11,17 @@ module.exports = async function(content) {
11
11
  let processedContent = content;
12
12
  const filePath = this.resourcePath;
13
13
  const isDev = this._compiler.options.mode === 'development';
14
- let isIgnored = false;
15
- let isDebugged = false;
16
14
  // timingStart('decorator_extraction');
17
- const decoratorExtract = LoadersHelper.extractRWSViewArgs(processedContent);
15
+ const decoratorExtract = await LoadersHelper.extractRWSViewArgsAsync(
16
+ processedContent,
17
+ false,
18
+ filePath,
19
+ this.addDependency,
20
+ this.query?.rwsWorkspaceDir,
21
+ this.query?.appRootDir,
22
+ isDev,
23
+ this.query?.publicDir
24
+ );
18
25
  const decoratorData = decoratorExtract ? decoratorExtract.viewDecoratorData : null;
19
26
 
20
27
  const cachedCode = processedContent;
@@ -34,19 +41,11 @@ module.exports = async function(content) {
34
41
  return content;
35
42
  }
36
43
 
37
- let templateName = null;
38
- let stylesPath = null;
44
+ let isIgnored = false;
45
+ let isDebugged = false;
39
46
 
40
47
  if(decoratorData.decoratorArgs){
41
48
  const decoratorArgs = decoratorData.decoratorArgs
42
-
43
- if(decoratorArgs.template){
44
- templateName = decoratorData.decoratorArgs.template || null;
45
- }
46
-
47
- if(decoratorArgs.styles){
48
- stylesPath = decoratorData.decoratorArgs.styles || null;
49
- }
50
49
 
51
50
  if(decoratorArgs.ignorePackaging){
52
51
  isIgnored = true;
@@ -64,19 +63,13 @@ module.exports = async function(content) {
64
63
 
65
64
  try {
66
65
  if(tagName){
67
- const [template, htmlFastImports, templateExists] = await LoadersHelper.getTemplate(filePath, this.addDependency, className, templateName, isDev);
68
-
69
- const styles = await LoadersHelper.getStyles(filePath, this.query?.rwsWorkspaceDir, this.query?.appRootDir,this.addDependency, templateExists, stylesPath, isDev, this.query?.publicDir);
70
-
71
66
  if(className){
72
- const replacedViewDecoratorContent = decoratorExtract.replacedDecorator;
67
+ const replacedViewDecoratorContent = decoratorExtract.replacedDecorator;
73
68
 
74
69
  if(replacedViewDecoratorContent){
75
- processedContent = `${template}\n${styles}\n${replacedViewDecoratorContent}`;
70
+ processedContent = replacedViewDecoratorContent;
76
71
  }
77
72
  }
78
-
79
- processedContent = `${htmlFastImports ? htmlFastImports + '\n' : ''}${processedContent}`;
80
73
  }
81
74
 
82
75
  const debugTsPath = filePath.replace('.ts','.debug.ts');
@@ -125,7 +125,115 @@ function _extractRWSViewDefs(fastOptions = {}, decoratorArgs = {})
125
125
  return [addedParamDefs, addedParams];
126
126
  }
127
127
 
128
- function extractRWSViewArgs(content, noReplace = false) {
128
+ function extractRWSViewArgs(content, noReplace = false, filePath = null, addDependency = null, rwsWorkspaceDir = null, appRootDir = null, isDev = false, publicDir = null) {
129
+ // If this is being called with only basic parameters (backward compatibility)
130
+ if (filePath === null || addDependency === null) {
131
+ return extractRWSViewArgsSync(content, noReplace);
132
+ }
133
+
134
+ // Otherwise, call the async version
135
+ return extractRWSViewArgsAsync(content, noReplace, filePath, addDependency, rwsWorkspaceDir, appRootDir, isDev, publicDir);
136
+ }
137
+
138
+ function extractRWSViewArgsSync(content, noReplace = false) {
139
+ const viewReg = /@RWSView\(\s*["']([^"']+)["'](?:\s*,\s*([\s\S]*?))?\s*\)\s*(.*?\s+)?class\s+([a-zA-Z0-9_-]+)\s+extends\s+RWSViewComponent/gm;
140
+
141
+ let m;
142
+ let tagName = null;
143
+ let className = null;
144
+ let classNamePrefix = null;
145
+ let decoratorArgs = null;
146
+
147
+ const _defaultRWSLoaderOptions = {
148
+ templatePath: 'template.html',
149
+ stylesPath: 'styles.scss',
150
+ fastOptions: { shadowOptions: { mode: 'open' } }
151
+ }
152
+
153
+ while ((m = viewReg.exec(content)) !== null) {
154
+ if (m.index === viewReg.lastIndex) {
155
+ viewReg.lastIndex++;
156
+ }
157
+
158
+ m.forEach((match, groupIndex) => {
159
+ if (groupIndex === 1) {
160
+ tagName = match;
161
+ }
162
+
163
+ if (groupIndex === 2) {
164
+ if (match) {
165
+ try {
166
+ decoratorArgs = JSON.parse(JSON.stringify(match));
167
+ } catch(e){
168
+ console.log(chalk.red('Decorator options parse error: ') + e.message + '\n Problematic line:');
169
+ console.log(`
170
+ @RWSView(${tagName}, ${match})
171
+ `);
172
+ console.log(chalk.yellowBright(`Decorator options failed to parse for "${tagName}" component.`) + ' { decoratorArgs } defaulting to null.');
173
+ console.log(match);
174
+
175
+ console.error(e);
176
+
177
+ throw new Error('Failed parsing @RWSView')
178
+ }
179
+ }
180
+ }
181
+
182
+ if (groupIndex === 3) {
183
+ if(match){
184
+ classNamePrefix = match;
185
+ }
186
+ }
187
+
188
+ if (groupIndex === 4) {
189
+ className = match;
190
+ }
191
+ });
192
+ }
193
+
194
+ if(!tagName){
195
+ return null;
196
+ }
197
+
198
+ let processedContent = content;
199
+ let fastOptions = _defaultRWSLoaderOptions.fastOptions;
200
+
201
+ if(decoratorArgs && decoratorArgs !== ''){
202
+ try {
203
+ decoratorArgs = json5.parse(decoratorArgs);
204
+ }catch(e){
205
+ // ignore parse errors for backward compatibility
206
+ }
207
+ }
208
+
209
+ if (decoratorArgs && decoratorArgs.fastElementOptions) {
210
+ fastOptions = decoratorArgs.fastElementOptions;
211
+ }
212
+
213
+ let replacedDecorator = null;
214
+
215
+ if(!noReplace){
216
+ const [addedParamDefs, addedParams] = _extractRWSViewDefs(fastOptions, decoratorArgs);
217
+ const replacedViewDecoratorContent = processedContent.replace(
218
+ viewReg,
219
+ `@RWSView('$1', null, { template: rwsTemplate, styles${addedParams.length ? ', options: {' + (addedParams.join(', ')) + '}' : ''} })\n$3class $4 extends RWSViewComponent `
220
+ );
221
+
222
+ replacedDecorator = `${addedParamDefs.join('\n')}\n${replacedViewDecoratorContent}`;
223
+ }
224
+
225
+ return {
226
+ viewDecoratorData: {
227
+ tagName,
228
+ className,
229
+ classNamePrefix,
230
+ decoratorArgs
231
+ },
232
+ replacedDecorator
233
+ }
234
+ }
235
+
236
+ async function extractRWSViewArgsAsync(content, noReplace = false, filePath = null, addDependency = null, rwsWorkspaceDir = null, appRootDir = null, isDev = false, publicDir = null) {
129
237
  const viewReg = /@RWSView\(\s*["']([^"']+)["'](?:\s*,\s*([\s\S]*?))?\s*\)\s*(.*?\s+)?class\s+([a-zA-Z0-9_-]+)\s+extends\s+RWSViewComponent/gm;
130
238
 
131
239
  let m;
@@ -206,16 +314,37 @@ function extractRWSViewArgs(content, noReplace = false) {
206
314
 
207
315
  let replacedDecorator = null;
208
316
 
209
- if(!noReplace){
210
- const [addedParamDefs, addedParams] = _extractRWSViewDefs(fastOptions, decoratorArgs);
211
- const replacedViewDecoratorContent = processedContent.replace(
317
+ if(!noReplace && filePath && addDependency){
318
+ const [addedParamDefs, addedParams] = _extractRWSViewDefs(fastOptions, decoratorArgs);
319
+
320
+ // Get template name and styles path from decorator args
321
+ let templateName = null;
322
+ let stylesPath = null;
323
+
324
+ if(decoratorArgs && decoratorArgs.template){
325
+ templateName = decoratorArgs.template;
326
+ }
327
+ if(decoratorArgs && decoratorArgs.styles){
328
+ stylesPath = decoratorArgs.styles;
329
+ }
330
+
331
+ // Generate template and styles
332
+ const [template, htmlFastImports, templateExists] = await getTemplate(filePath, addDependency, className, templateName, isDev);
333
+ const styles = await getStyles(filePath, rwsWorkspaceDir, appRootDir, addDependency, templateExists, stylesPath, isDev, publicDir);
334
+
335
+ // Extract original imports (everything before the @RWSView decorator)
336
+ const beforeDecorator = processedContent.substring(0, processedContent.search(/@RWSView/));
337
+ const afterDecoratorMatch = processedContent.match(/@RWSView[\s\S]*$/);
338
+ const afterDecorator = afterDecoratorMatch ? afterDecoratorMatch[0] : '';
339
+
340
+ const replacedViewDecoratorContent = afterDecorator.replace(
212
341
  viewReg,
213
- `@RWSView('$1', null, { template: rwsTemplate, styles${addedParams.length ? ', options: {' + (addedParams.join(', ')) + '}' : ''} })\n$3class $4 extends RWSViewComponent `
342
+ `${template}\n${styles}\n${addedParamDefs.join('\n')}\n@RWSView('$1', null, { template: rwsTemplate, styles${addedParams.length ? ', options: {' + (addedParams.join(', ')) + '}' : ''} })\n$3class $4 extends RWSViewComponent `
214
343
  );
215
344
 
216
345
  // console.log({replacedViewDecoratorContent});
217
346
 
218
- replacedDecorator = `${addedParamDefs.join('\n')}\n${replacedViewDecoratorContent}`;
347
+ replacedDecorator = `${htmlFastImports ? htmlFastImports + '\n' : ''}${beforeDecorator}${replacedViewDecoratorContent}`;
219
348
  }
220
349
 
221
350
  return {
@@ -290,4 +419,4 @@ let rwsTemplate: any = T.html<${className}>\`${templateContent}\`;
290
419
  return [template, htmlFastImports, templateExists];
291
420
  }
292
421
 
293
- module.exports = { getRWSLoaders, extractRWSViewArgs, getTemplate, getStyles }
422
+ module.exports = { getRWSLoaders, extractRWSViewArgs, extractRWSViewArgsAsync, getTemplate, getStyles }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rws-framework/client",
3
3
  "private": false,
4
- "version": "2.22.0",
4
+ "version": "2.23.0",
5
5
  "main": "src/index.ts",
6
6
  "scripts": {
7
7
  "docs": "typedoc --tsconfig ./tsconfig.json"
@@ -13,13 +13,15 @@ import TheRWSService from '../services/_service';
13
13
  import { handleExternalChange } from './_attrs/_external_handler';
14
14
  import { IFastDefinition, isDefined, defineComponent, getDefinition } from './_definitions';
15
15
  import { on, $emitDown, observe, sendEventToOutside } from './_event_handling';
16
+ import { domEvents } from '../events';
17
+ import CSSInjectionManager, { CSSInjectMode, ICSSInjectionOptions } from './_css_injection';
16
18
 
17
19
  type ComposeMethodType<
18
20
  T extends FoundationElementDefinition,
19
21
  K extends Constructable<RWSViewComponent>
20
22
  > = (this: K, elementDefinition: T) => (overrideDefinition?: OverrideFoundationElementDefinition<T>) => FoundationElementRegistry<FoundationElementDefinition, T>;
21
23
 
22
- type CSSInjectMode = 'adopted' | 'legacy' | 'both';
24
+ const _DEFAULT_INJECT_CSS_CACHE_LIMIT_DAYS = 1;
23
25
 
24
26
  export interface IWithCompose<T extends RWSViewComponent> {
25
27
  [key: string]: any
@@ -250,56 +252,39 @@ abstract class RWSViewComponent extends FoundationElement implements IRWSViewCom
250
252
  return RWSViewComponent.instances;
251
253
  }
252
254
 
253
- protected async injectStyles(styleLinks: string[], mode: CSSInjectMode = 'adopted') {
254
- const dbName = 'css-cache';
255
- const storeName = 'styles';
256
- const db = await this.indexedDBService.openDB(dbName, storeName);
257
-
258
- let adoptedSheets: CSSStyleSheet[] = [];
259
-
260
- for (const styleLink of styleLinks) {
261
- if (mode === 'legacy' || mode === 'both') {
262
- const link = document.createElement('link');
263
- link.rel = 'stylesheet';
264
- link.href = styleLink;
265
- this.getShadowRoot().appendChild(link);
266
- }
267
-
268
- if (mode === 'adopted' || mode === 'both') {
269
- const entry = await this.indexedDBService.getFromDB(db, storeName, styleLink);
270
- const maxAgeMs = 1000 * 60 * 60 * 24; // 24h
255
+ static getCachedStyles(styleLinks: string[]): CSSStyleSheet[] {
256
+ return CSSInjectionManager.getCachedStyles(styleLinks);
257
+ }
271
258
 
272
- let cssText: string | null = null;
259
+ static hasCachedStyles(styleLinks: string[]): boolean {
260
+ return CSSInjectionManager.hasCachedStyles(styleLinks);
261
+ }
273
262
 
274
- if (entry && typeof entry === 'object' && 'css' in entry && 'timestamp' in entry) {
275
- const expired = Date.now() - entry.timestamp > maxAgeMs;
276
- if (!expired) {
277
- cssText = entry.css;
278
- }
279
- }
263
+ static getStylesOwnerComponent(): any {
264
+ return CSSInjectionManager.getStylesOwnerComponent();
265
+ }
280
266
 
281
- if (!cssText) {
282
- cssText = await fetch(styleLink).then(res => res.text());
283
- await this.indexedDBService.saveToDB(db, storeName, styleLink, {
284
- css: cssText,
285
- timestamp: Date.now()
286
- });
287
- console.log(`System saved stylesheet: ${styleLink} to IndexedDB`)
288
- }
267
+ static clearCachedStyles(): void {
268
+ CSSInjectionManager.clearCachedStyles();
269
+ }
289
270
 
290
- const sheet = new CSSStyleSheet();
291
- await sheet.replace(cssText);
271
+ protected async injectStyles(styleLinks: string[], mode: CSSInjectMode = 'adopted', maxDaysExp?: number) {
272
+ // Create a bridge object that exposes the necessary properties
273
+ const componentBridge = {
274
+ shadowRoot: this.shadowRoot,
275
+ indexedDBService: this.indexedDBService,
276
+ $emit: this.$emit.bind(this)
277
+ };
278
+
279
+ return CSSInjectionManager.injectStyles(componentBridge, styleLinks, { mode, maxDaysExp });
280
+ }
292
281
 
293
- adoptedSheets.push(sheet);
294
- }
295
- }
282
+ protected getInjectedStyles(styleLinks: string[]): CSSStyleSheet[] {
283
+ return CSSInjectionManager.getCachedStyles(styleLinks);
284
+ }
296
285
 
297
- if(adoptedSheets.length){
298
- this.getShadowRoot().adoptedStyleSheets = [
299
- ...adoptedSheets,
300
- ...this.getShadowRoot().adoptedStyleSheets,
301
- ];
302
- }
286
+ protected hasInjectedStyles(styleLinks: string[]): boolean {
287
+ return CSSInjectionManager.hasCachedStyles(styleLinks);
303
288
  }
304
289
  }
305
290
 
@@ -0,0 +1,187 @@
1
+ import { domEvents } from '../events';
2
+ import IndexedDBService, { IndexedDBServiceInstance } from '../services/IndexedDBService';
3
+
4
+ type CSSInjectMode = 'adopted' | 'legacy' | 'both';
5
+
6
+ const _DEFAULT_INJECT_CSS_CACHE_LIMIT_DAYS = 1;
7
+
8
+ interface ICSSInjectionOptions {
9
+ mode?: CSSInjectMode;
10
+ maxDaysExp?: number;
11
+ }
12
+
13
+ interface ICSSInjectionComponent {
14
+ shadowRoot: ShadowRoot | null;
15
+ indexedDBService: IndexedDBServiceInstance;
16
+ $emit(eventName: string): void;
17
+ }
18
+
19
+ export class CSSInjectionManager {
20
+ private static CACHED_STYLES: Map<string, CSSStyleSheet> = new Map();
21
+ private static STYLES_OWNER_COMPONENT: ICSSInjectionComponent | null = null;
22
+
23
+ static getCachedStyles(styleLinks: string[]): CSSStyleSheet[] {
24
+ return styleLinks
25
+ .filter(link => CSSInjectionManager.CACHED_STYLES.has(link))
26
+ .map(link => CSSInjectionManager.CACHED_STYLES.get(link)!);
27
+ }
28
+
29
+ static hasCachedStyles(styleLinks: string[]): boolean {
30
+ return styleLinks.every(link => CSSInjectionManager.CACHED_STYLES.has(link));
31
+ }
32
+
33
+ static getStylesOwnerComponent(): ICSSInjectionComponent | null {
34
+ return CSSInjectionManager.STYLES_OWNER_COMPONENT;
35
+ }
36
+
37
+ static clearCachedStyles(): void {
38
+ CSSInjectionManager.CACHED_STYLES.clear();
39
+ CSSInjectionManager.STYLES_OWNER_COMPONENT = null;
40
+ }
41
+
42
+ static async injectStyles(
43
+ component: ICSSInjectionComponent,
44
+ styleLinks: string[],
45
+ options: ICSSInjectionOptions = {}
46
+ ): Promise<void> {
47
+ const { mode = 'adopted', maxDaysExp } = options;
48
+
49
+ if (!component.shadowRoot) {
50
+ throw new Error('Component must have a shadow root for CSS injection');
51
+ }
52
+
53
+ // Add initial transition styles to host element
54
+ const transitionSheet = new CSSStyleSheet();
55
+ await transitionSheet.replace(`
56
+ :host {
57
+ opacity: 0;
58
+ transition: opacity 0.3s ease-in-out;
59
+ }
60
+ `);
61
+ component.shadowRoot.adoptedStyleSheets = [
62
+ transitionSheet,
63
+ ...component.shadowRoot.adoptedStyleSheets,
64
+ ];
65
+
66
+ let adoptedSheets: CSSStyleSheet[] = [];
67
+ let doneAdded = false;
68
+
69
+ // Check if we already have cached styles from the owner component
70
+ const cachedSheets: CSSStyleSheet[] = [];
71
+ const uncachedLinks: string[] = [];
72
+
73
+ for (const styleLink of styleLinks) {
74
+ if (CSSInjectionManager.CACHED_STYLES.has(styleLink)) {
75
+ cachedSheets.push(CSSInjectionManager.CACHED_STYLES.get(styleLink)!);
76
+ } else {
77
+ uncachedLinks.push(styleLink);
78
+ }
79
+ }
80
+
81
+ // If we have cached styles, use them immediately
82
+ if (cachedSheets.length > 0) {
83
+ adoptedSheets.push(...cachedSheets);
84
+ doneAdded = true;
85
+ }
86
+
87
+ // Only process uncached styles
88
+ if (uncachedLinks.length > 0) {
89
+ // Set this component as the owner if no owner exists yet
90
+ if (!CSSInjectionManager.STYLES_OWNER_COMPONENT) {
91
+ CSSInjectionManager.STYLES_OWNER_COMPONENT = component;
92
+ }
93
+
94
+ const dbName = 'css-cache';
95
+ const storeName = 'styles';
96
+ const db = await component.indexedDBService.openDB(dbName, storeName);
97
+ const maxAgeMs = 1000 * 60 * 60 * 24; // 24h
98
+ const maxDaysAge = maxDaysExp ? maxDaysExp : _DEFAULT_INJECT_CSS_CACHE_LIMIT_DAYS;
99
+ const maxAgeDays = maxAgeMs * maxDaysAge;
100
+
101
+ for (const styleLink of uncachedLinks) {
102
+ const loadPromise = new Promise<void>(async (resolve, reject) => {
103
+ if (mode === 'legacy' || mode === 'both') {
104
+ const link = document.createElement('link');
105
+ link.rel = 'stylesheet';
106
+ link.href = styleLink;
107
+ component.shadowRoot!.appendChild(link);
108
+
109
+ link.onload = () => {
110
+ doneAdded = true;
111
+
112
+ if(mode === 'legacy'){
113
+ resolve();
114
+ }
115
+ };
116
+ }
117
+
118
+ if (mode === 'adopted' || mode === 'both') {
119
+ const entry = await component.indexedDBService.getFromDB(db, storeName, styleLink);
120
+
121
+ let cssText: string | null = null;
122
+
123
+ if (entry && typeof entry === 'object' && 'css' in entry && 'timestamp' in entry) {
124
+ const expired = Date.now() - entry.timestamp > maxAgeDays;
125
+ if (!expired) {
126
+ cssText = entry.css;
127
+ }
128
+ }
129
+
130
+ if (!cssText) {
131
+ cssText = await fetch(styleLink).then(res => res.text());
132
+ await component.indexedDBService.saveToDB(db, storeName, styleLink, {
133
+ css: cssText,
134
+ timestamp: Date.now()
135
+ });
136
+ console.log(`System saved stylesheet: ${styleLink} to IndexedDB`)
137
+ }
138
+
139
+ const sheet = new CSSStyleSheet();
140
+ await sheet.replace(cssText);
141
+
142
+ // Cache the stylesheet for future use
143
+ CSSInjectionManager.CACHED_STYLES.set(styleLink, sheet);
144
+
145
+ adoptedSheets.push(sheet);
146
+
147
+ if(mode === 'adopted' || mode === 'both'){
148
+ resolve();
149
+ }
150
+ }
151
+ });
152
+
153
+ await loadPromise;
154
+ }
155
+
156
+ doneAdded = true;
157
+ }
158
+
159
+ if (adoptedSheets.length) {
160
+ component.shadowRoot.adoptedStyleSheets = [
161
+ ...adoptedSheets,
162
+ ...component.shadowRoot.adoptedStyleSheets,
163
+ ];
164
+
165
+ doneAdded = true;
166
+ }
167
+
168
+ if (doneAdded) {
169
+ // Set opacity to 1 to fade in the component
170
+ const opacitySheet = new CSSStyleSheet();
171
+ await opacitySheet.replace(`
172
+ :host {
173
+ opacity: 1 !important;
174
+ }
175
+ `);
176
+ component.shadowRoot.adoptedStyleSheets = [
177
+ opacitySheet,
178
+ ...component.shadowRoot.adoptedStyleSheets,
179
+ ];
180
+
181
+ component.$emit(domEvents.loadedLinkedStyles);
182
+ }
183
+ }
184
+ }
185
+
186
+ export default CSSInjectionManager;
187
+ export { CSSInjectMode, ICSSInjectionOptions, ICSSInjectionComponent };
package/src/events.ts ADDED
@@ -0,0 +1,3 @@
1
+ export const domEvents = {
2
+ loadedLinkedStyles: 'loaded:linked'
3
+ }
package/src/index.ts CHANGED
@@ -22,14 +22,14 @@ import { RWSIgnore, RWSInject, RWSView } from './components/_decorator';
22
22
  import type { DefaultRWSPluginOptionsType } from './plugins/_plugin';
23
23
  import type { IRWSPlugin, IStaticRWSPlugin, IPluginSpawnOption } from './types/IRWSPlugin';
24
24
  import type IRWSUser from './types/IRWSUser';
25
- import type { IAssetShowOptions } from './components/_component';
25
+ import type { IAssetShowOptions, IRWSViewComponent } from './components/_component';
26
26
  import type { RWSDecoratorOptions } from './components/_decorator';
27
- import type { IKDBTypeInfo, IKDBTypesResponse } from './types/IBackendCore';
28
27
  import type { DOMOutputType, TagsProcessorType } from './services/DOMService';
29
28
  import type { IBackendRoute, IHTTProute, IPrefixedHTTProutes } from './services/ApiService';
30
29
  import type IRWSConfig from './types/IRWSConfig';
31
30
  import type RWSNotify from './types/RWSNotify';
32
31
  import type { NotifyUiType, NotifyLogType } from './types/RWSNotify';
32
+ import * as RWSEvents from './events';
33
33
 
34
34
  export default RWSClient;
35
35
 
@@ -70,11 +70,12 @@ export {
70
70
  RWSService,
71
71
  RWSViewComponent,
72
72
 
73
- RWSContainer
73
+ RWSContainer,
74
+
75
+ RWSEvents
74
76
  };
75
77
 
76
- export type {
77
- IKDBTypeInfo, IKDBTypesResponse,
78
+ export type {
78
79
  NotifyUiType,
79
80
  NotifyLogType,
80
81
  IBackendRoute as IRWSBackendRoute,
@@ -84,5 +85,6 @@ export type {
84
85
  IAssetShowOptions as IRWSAssetShowOptions,
85
86
  IRWSConfig,
86
87
  IRWSUser,
87
- TagsProcessorType
88
+ TagsProcessorType,
89
+ IRWSViewComponent
88
90
  }
@@ -1,4 +1,4 @@
1
- import { IKDBTypesResponse } from '../types/IBackendCore';
1
+ import { ITypesResponse } from '../../../components/src/types/IBackendCore';
2
2
  import TheService from './_service';
3
3
 
4
4
  //@4DI
@@ -20,11 +20,14 @@ interface IAPIOptions {
20
20
  routeParams?: {
21
21
  [key: string]: string
22
22
  },
23
+ queryParams?: {
24
+ [key: string]: string
25
+ }
23
26
  }
24
27
 
25
28
  interface IHTTProute<P = {[key: string]: any}> {
26
29
  name: string;
27
- path: string;
30
+ path: string | string[];
28
31
  method: string;
29
32
  noParams?: boolean;
30
33
  options?: any;
@@ -89,16 +92,16 @@ class ApiService extends TheService {
89
92
  public delete = calls.delete;
90
93
 
91
94
  public back = {
92
- get: async <T>(routeName: string, options?: IAPIOptions, token?: string): Promise<T> => calls.get.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams), options) as Promise<T>,
93
- post: async <T, P extends object = object>(routeName: string, payload?: P, options?: IAPIOptions): Promise<T> => calls.post.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams), payload, options) as Promise<T>,
94
- put: async <T, P extends object = object>(routeName: string, payload: P, options?: IAPIOptions): Promise<T> => calls.put.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams), payload, options) as Promise<T>,
95
- delete: async <T>(routeName: string, options?: IAPIOptions): Promise<T> => calls.delete.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams), options) as Promise<T>,
95
+ get: async <T>(routeName: string, options?: IAPIOptions, token?: string): Promise<T> => calls.get.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), options) as Promise<T>,
96
+ post: async <T, P extends object = object>(routeName: string, payload?: P, options?: IAPIOptions): Promise<T> => calls.post.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), payload, options) as Promise<T>,
97
+ put: async <T, P extends object = object>(routeName: string, payload: P, options?: IAPIOptions): Promise<T> => calls.put.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), payload, options) as Promise<T>,
98
+ delete: async <T>(routeName: string, options?: IAPIOptions): Promise<T> => calls.delete.bind(this)(backend.getBackendUrl.bind(this)(routeName, options?.routeParams, options?.queryParams), options) as Promise<T>,
96
99
  uploadFile: async (routeName: string, file: File, onProgress: (progress: number) => void, options: IAPIOptions = {}, payload: any = {}): Promise<UploadResponse> => this.uploadFile(backend.getBackendUrl.bind(this)(routeName, options?.routeParams), file, onProgress, payload),
97
100
  };
98
101
 
99
- async getResource(resourceName: string): Promise<IKDBTypesResponse>
102
+ async getResource(resourceName: string): Promise<ITypesResponse>
100
103
  {
101
- return calls.get.bind(this)(`${this.config.get('backendUrl')}${this.config.get('apiPrefix') || ''}/api/rws/resource/${resourceName}`) as Promise<IKDBTypesResponse>
104
+ return calls.get.bind(this)(`${this.config.get('backendUrl')}${this.config.get('apiPrefix') || ''}/api/rws/resource/${resourceName}`) as Promise<ITypesResponse>
102
105
  }
103
106
  }
104
107
 
@@ -83,7 +83,7 @@ class DOMService extends RWSService {
83
83
  sanitizeOptions: DOMPurify.Config = { })
84
84
  {
85
85
  const output: string = line.trim();
86
- const sanitized = DOMPurify.sanitize(output, { USE_PROFILES: { html: true }, ...sanitizeOptions});
86
+ const sanitized = DOMPurify.sanitize(output, { USE_PROFILES: { html: true }, ...sanitizeOptions}) as string;
87
87
  return sanitized;
88
88
  }
89
89
  }