@rws-framework/client 2.5.4 → 2.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.
package/src/client.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import IRWSConfig from './interfaces/IRWSConfig';
2
- import startClient from './run';
2
+
3
3
  import RWSNotify from './types/RWSNotify';
4
4
 
5
5
  import ConfigService, { ConfigServiceInstance } from './services/ConfigService';
@@ -14,7 +14,7 @@ import { IBackendRoute } from './services/ApiService';
14
14
  import IRWSUser from './interfaces/IRWSUser';
15
15
  import RWSWindow, { RWSWindowComponentRegister, loadRWSRichWindow } from './interfaces/RWSWindow';
16
16
 
17
- import { DI, Container } from '@microsoft/fast-foundation';
17
+ import { DI, Container, Registration } from '@microsoft/fast-foundation';
18
18
 
19
19
  import {
20
20
  IFrontRoutes
@@ -22,6 +22,11 @@ import {
22
22
 
23
23
  import RWSViewComponent, { IWithCompose } from './components/_component';
24
24
  import RWSContainer from './components/_container';
25
+ import TheRWSService from './services/_service';
26
+
27
+ import ComponentHelper, { ComponentHelperStatic } from './client/components';
28
+ import ServicesHelper from './client/services';
29
+ import ConfigHelper from './client/config';
25
30
 
26
31
  interface IHotModule extends NodeModule {
27
32
  hot?: {
@@ -32,23 +37,24 @@ interface IHotModule extends NodeModule {
32
37
  }
33
38
  }
34
39
 
35
-
40
+ type RWSInfoType = { components: string[] };
36
41
  type RWSEventListener = (event: CustomEvent) => void;
37
42
 
38
43
  class RWSClient {
39
- private _container: Container;
40
- private user: IRWSUser = null;
41
-
42
- private config: IRWSConfig = {};
43
- protected initCallback: () => Promise<void> = async () => { };
44
+ protected _container: Container;
45
+ protected user: IRWSUser = null;
46
+
47
+ protected config: IRWSConfig = {};
48
+ protected isSetup = false;
49
+ protected devStorage: { [key: string]: any } = {};
50
+ protected customServices: { [serviceName: string]: TheRWSService} = {};
51
+ protected defaultServices: { [serviceName: string]: TheRWSService} = {};
44
52
 
45
- private isSetup = false;
46
- protected devStorage: { [key: string]: any } = {};
53
+ private componentHelper = ComponentHelper.bind(this)();
54
+ private servicesHelper = ServicesHelper.bind(this)();
55
+ private configHelper = ConfigHelper.bind(this)();
47
56
 
48
- private cfgSetupListener: RWSEventListener = (event: CustomEvent<{ callId: string }>) => {
49
- console.log('Received custom event from web component:', event.detail);
50
- // this.broadcastConfigForViewComponents();
51
- };
57
+ protected initCallback: () => Promise<void> = async () => { };
52
58
 
53
59
  constructor(
54
60
  @ConfigService public appConfig: ConfigServiceInstance,
@@ -61,62 +67,32 @@ class RWSClient {
61
67
  @NotifyService public notifyService: NotifyServiceInstance
62
68
  ) {
63
69
  this._container = RWSContainer();
64
- this.user = this.getUser();
70
+ this.user = this.getUser();
71
+
72
+ this.loadServices();
65
73
 
66
74
  this.pushDataToServiceWorker('SET_WS_URL', { url: this.appConfig.get('wsUrl') }, 'ws_url');
67
75
 
68
76
  if (this.user) {
69
77
  this.pushUserToServiceWorker({ ...this.user, instructor: false });
70
- }
78
+ }
71
79
  }
72
80
 
73
81
  async setup(config: IRWSConfig = {}): Promise<IRWSConfig> {
74
- if (this.isSetup) {
75
- return this.config;
76
- }
77
-
78
- this.config = { ...this.config, ...config };
79
- this.appConfig.mergeConfig(this.config);
80
-
81
- // this.on<IRWSConfig>('rws_cfg_call', this.cfgSetupListener);
82
-
83
- const hotModule: IHotModule = (module as IHotModule);
84
-
85
- if (hotModule.hot) {
86
- hotModule.hot.accept('./print.js', function () {
87
- console.log('Accepting the updated module!');
88
- });
89
- }
90
-
91
- if (this.appConfig.get('parted')) {
92
- await this.loadPartedComponents();
93
- }
94
-
95
-
96
- this.isSetup = true;
97
- return this.config;
82
+ return this.configHelper.setup(config);
98
83
  }
99
84
 
100
85
  async start(config: IRWSConfig = {}): Promise<RWSClient> {
101
- this.config = { ...this.config, ...config };
102
-
103
- if (!this.isSetup) {
104
- this.config = await this.setup(this.config);
105
- }
106
-
107
- if (Object.keys(config).length) {
108
- this.appConfig.mergeConfig(this.config);
109
- }
110
-
111
- if (this.config.user && !this.config.dontPushToSW) {
112
- this.pushUserToServiceWorker(this.user);
113
- }
114
-
115
- await startClient(this.appConfig, this.wsService, this.notifyService, this.routingService);
86
+ return this.configHelper.start(config);
87
+ }
116
88
 
117
- await this.initCallback();
89
+ private loadServices(){
90
+ return this.servicesHelper.loadServices();
91
+ }
118
92
 
119
- return this;
93
+ get(key: string): any | null
94
+ {
95
+ return this.configHelper.get(key);
120
96
  }
121
97
 
122
98
  addRoutes(routes: IFrontRoutes) {
@@ -146,53 +122,20 @@ class RWSClient {
146
122
  }
147
123
 
148
124
  pushDataToServiceWorker(type: string, data: any, asset_type: string = 'data_push'): void {
149
- let tries = 0;
150
-
151
- const doIt: () => void = () => {
152
- try {
153
- this.swService.sendDataToServiceWorker(type, data, asset_type);
154
- } catch (e) {
155
- if (tries < 3) {
156
- setTimeout(() => { doIt(); }, 300);
157
- tries++;
158
- }
159
- }
160
- };
161
-
162
- doIt();
125
+ this.configHelper.pushDataToServiceWorker(type, data, asset_type);
126
+
163
127
  }
164
128
 
165
129
  pushUserToServiceWorker(userData: any) {
166
- this.setUser(userData);
167
- this.pushDataToServiceWorker('SET_USER', userData, 'logged_user');
130
+ this.configHelper.pushUserToServiceWorker(userData);
168
131
  }
169
132
 
170
133
  getUser(): IRWSUser {
171
-
172
- const localSaved = localStorage.getItem('the_rws_user');
173
-
174
- if (localSaved) {
175
- this.setUser(JSON.parse(localSaved) as IRWSUser);
176
- }
177
-
178
- return this.user;
134
+ return this.configHelper.getUser();
179
135
  }
180
136
 
181
137
  setUser(user: IRWSUser): RWSClient {
182
- if (!user || !user?.jwt_token) {
183
- console.warn('[RWS Client Warning]', 'Passed user is not valid', user);
184
- return this;
185
- }
186
-
187
- this.user = user;
188
-
189
- this.apiService.setToken(this.user.jwt_token);
190
- this.wsService.setUser(this.user);
191
-
192
- localStorage.setItem('the_rws_user', JSON.stringify(this.user));
193
-
194
-
195
- return this;
138
+ return this.configHelper.setUser(user);
196
139
  }
197
140
 
198
141
  getConfig(): ConfigServiceInstance {
@@ -219,29 +162,11 @@ class RWSClient {
219
162
  }
220
163
 
221
164
  async loadPartedComponents(): Promise<void> {
222
- this.assignClientToBrowser();
223
-
224
- const componentParts: string[] = await this.apiService.get<string[]>(this.appConfig.get('partedDirUrlPrefix') + '/rws_chunks_info.json');
225
-
226
- componentParts.forEach((componentName: string, key: number) => {
227
- const partUrl = `${this.appConfig.get('partedDirUrlPrefix')}/${this.appConfig.get('partedPrefix')}.${componentName}.js`;
228
-
229
- const script: HTMLScriptElement = document.createElement('script');
230
- script.src = partUrl;
231
- script.async = true;
232
- script.type = 'text/javascript';
233
- document.body.appendChild(script);
234
-
235
- console.log(`Appended ${componentParts[key]} component (${partUrl})`);
236
- });
165
+ return this.componentHelper.loadPartedComponents();
237
166
  }
238
167
 
239
168
  async onDOMLoad(): Promise<void> {
240
- return new Promise<void>((resolve) => {
241
- document.addEventListener('DOMContentLoaded', () => {
242
- resolve();
243
- });
244
- });
169
+ return this.domService.onDOMLoad()
245
170
  }
246
171
 
247
172
  assignClientToBrowser(): void {
@@ -261,30 +186,17 @@ class RWSClient {
261
186
  return window;
262
187
  }
263
188
 
264
-
265
- private broadcastConfigForViewComponents(): void {
266
- document.dispatchEvent(new CustomEvent<{ config: IRWSConfig }>('rws_cfg_broadcast', { detail: { config: this.appConfig.getData() } }));
267
- }
268
-
269
189
  static getDI(): typeof DI {
270
190
  return DI;
271
191
  }
272
192
 
273
193
  static defineAllComponents() {
274
- const richWindowComponents: RWSWindowComponentRegister = (window as Window & RWSWindow).RWS.components;
275
-
276
- Object.keys(richWindowComponents).map(key => richWindowComponents[key].component).forEach((el: IWithCompose<RWSViewComponent>) => {
277
- el.define(el as any, el.definition);
278
- });
194
+ ComponentHelperStatic.defineAllComponents();
279
195
  }
280
196
 
281
197
 
282
198
  defineComponents(){
283
- const richWindowComponents: RWSWindowComponentRegister = (window as Window & RWSWindow).RWS.components;
284
-
285
- Object.keys(richWindowComponents).map(key => richWindowComponents[key].component).forEach((el: IWithCompose<RWSViewComponent>) => {
286
- el.define(el as any, el.definition);
287
- });
199
+ ComponentHelperStatic.defineAllComponents();
288
200
  }
289
201
  }
290
202
 
@@ -82,7 +82,7 @@ abstract class RWSViewComponent extends FoundationElement implements IRWSViewCom
82
82
  if (this.fileAssets[file]) {
83
83
  return;
84
84
  }
85
- this.utilsService.getFileContents(this.config.get('pubUrlFilePrefix') + file).then((response: string) => {
85
+ this.apiService.pureGet(this.config.get('pubUrlFilePrefix') + file).then((response: string) => {
86
86
  this.fileAssets = { ...this.fileAssets, [file]: html`${response}` };
87
87
  });
88
88
  });
@@ -7,7 +7,8 @@ interface RWSDecoratorOptions {
7
7
  template?: string,
8
8
  styles?: string,
9
9
  fastElementOptions?: any,
10
- ignorePackaging?: boolean
10
+ ignorePackaging?: boolean,
11
+ oreoMode?: boolean
11
12
  }
12
13
 
13
14
  //const _PARAMTYPES_METADATA_KEY = 'design:paramtypes';
@@ -2,6 +2,7 @@ import { IFrontRoutes } from '../services/RoutingService';
2
2
  import RWSViewComponent from '../components/_component';
3
3
 
4
4
  export default interface IRWSConfig {
5
+ dev?: boolean
5
6
  defaultLayout?: typeof RWSViewComponent
6
7
  backendUrl?: string
7
8
  wsUrl?: string
@@ -35,7 +35,8 @@ type IBackendRoute = IHTTProute | IPrefixedHTTProutes;
35
35
 
36
36
  const _DEFAULT_CONTENT_TYPE = 'application/json';
37
37
 
38
- class ApiServiceInstance extends TheService {
38
+ class ApiService extends TheService {
39
+ static _DEFAULT: boolean = true;
39
40
  private token?: string;
40
41
 
41
42
  constructor(@ConfigService private config: ConfigServiceInstance) {
@@ -238,5 +239,5 @@ class ApiServiceInstance extends TheService {
238
239
  }
239
240
  }
240
241
 
241
- export default ApiServiceInstance.getSingleton();
242
- export { IBackendRoute, RequestOptions, ApiServiceInstance, IHTTProute, IPrefixedHTTProutes };
242
+ export default ApiService.getSingleton();
243
+ export { IBackendRoute, RequestOptions, ApiService as ApiServiceInstance, IHTTProute, IPrefixedHTTProutes };
@@ -9,6 +9,7 @@ const __SENT_TO_COMPONENTS: string[] = [];
9
9
 
10
10
  @RWSFillBuild()
11
11
  class ConfigService extends TheService {
12
+ static _DEFAULT: boolean = false;
12
13
  static isLoaded: boolean = false;
13
14
 
14
15
  _DEFAULTS: Partial<IRWSConfig> = {};
@@ -32,24 +33,33 @@ class ConfigService extends TheService {
32
33
  const isInData: boolean = Object.keys(this.data).includes(key);
33
34
  const isInBuildVars: boolean = Object.keys(this._BUILD_OVERRIDE).includes(key);
34
35
 
36
+ let isDev = false;
37
+
38
+ if((Object.keys(this._BUILD_OVERRIDE).includes('dev'))){
39
+ isDev = Object.keys(this._BUILD_OVERRIDE).includes('dev') && this._BUILD_OVERRIDE.dev;
40
+ }
41
+
35
42
  if(!isInData){
36
43
  let defaultVal = null;
37
44
 
38
45
  if(isInDefaults){
39
46
  defaultVal = this._DEFAULTS[key];
40
- }
41
-
42
- if(isInBuildVars && !!this._BUILD_OVERRIDE[key]){
43
- defaultVal = this._BUILD_OVERRIDE[key];
44
- }
47
+ }
45
48
 
46
49
  if(defaultVal && defaultVal[0] === '@'){
47
50
  defaultVal = this.data[((defaultVal as string).slice(1)) as keyof IRWSConfig];
48
51
  }
49
-
52
+
53
+ if(isInBuildVars && Object.keys(this._BUILD_OVERRIDE).includes(key)){
54
+ if(isDev){
55
+ console.warn(`.rws.json override [${key}]:`), this._BUILD_OVERRIDE[key];
56
+ }
57
+
58
+ defaultVal = this._BUILD_OVERRIDE[key];
59
+ }
60
+
50
61
  return defaultVal;
51
- }
52
-
62
+ }
53
63
 
54
64
  return this.data[key as keyof IRWSConfig];
55
65
  }
@@ -9,7 +9,8 @@ type DOMOutputType<T extends Element> = NodeListOf<T> | T | null;
9
9
  declare let trustedTypes: TrustedTypePolicyFactory;
10
10
 
11
11
 
12
- class DOMServiceInstance extends RWSService {
12
+ class DOMService extends RWSService {
13
+ static _DEFAULT: boolean = true;
13
14
  parse$<T extends Element>(input: NodeListOf<T>, directReturn: boolean = false): DOMOutputType<T> {
14
15
  if(input.length > 1 || directReturn) {
15
16
  return input;
@@ -83,9 +84,18 @@ class DOMServiceInstance extends RWSService {
83
84
 
84
85
  return sanitized;
85
86
  }
87
+
88
+ async onDOMLoad(): Promise<void>
89
+ {
90
+ return new Promise<void>((resolve) => {
91
+ document.addEventListener('DOMContentLoaded', () => {
92
+ resolve();
93
+ });
94
+ });
95
+ }
86
96
  }
87
97
 
88
- const DOMService = DOMServiceInstance.getSingleton();
89
98
 
90
- export default DOMService;
91
- export { DOMOutputType, DOMServiceInstance, TagsProcessorType };
99
+
100
+ export default DOMService.getSingleton();
101
+ export { DOMOutputType, DOMService, TagsProcessorType, DOMService as DOMServiceInstance };
@@ -4,7 +4,8 @@ import TheService from './_service';
4
4
  * @class
5
5
  * @extends TheService
6
6
  */
7
- class NotifyServiceInstance extends TheService {
7
+ class NotifyService extends TheService {
8
+ static _DEFAULT: boolean = true;
8
9
  private notifier: RWSNotify;
9
10
 
10
11
  public setNotifier(notifier: RWSNotify)
@@ -43,7 +44,5 @@ class NotifyServiceInstance extends TheService {
43
44
  }
44
45
  }
45
46
 
46
- const NotifyService = NotifyServiceInstance.getSingleton();
47
-
48
- export default NotifyService;
49
- export { NotifyServiceInstance };
47
+ export default NotifyService.getSingleton();
48
+ export { NotifyService as NotifyServiceInstance };
@@ -9,6 +9,7 @@ import ConfigService, { ConfigServiceInstance } from './ConfigService';
9
9
  type IFrontRoutes = Record<string, unknown>;
10
10
 
11
11
  class RoutingService extends TheService {
12
+ static _DEFAULT: boolean = true;
12
13
  private router: Router<any>;
13
14
  private routes: IFrontRoutes;
14
15
 
@@ -2,6 +2,7 @@ import RWSService from '@rws-framework/client/src/services/_service';
2
2
 
3
3
 
4
4
  class ServiceWorkerService extends RWSService {
5
+ static _DEFAULT: boolean = true;
5
6
  async registerServiceWorker(): Promise<void>
6
7
  {
7
8
  await ServiceWorkerService.registerServiceWorker();
@@ -3,19 +3,8 @@ import ApiService, {ApiServiceInstance} from './ApiService';
3
3
 
4
4
  import { RawSourceMap } from 'source-map';
5
5
 
6
- class UtilsService extends TheService {
7
- private apiService: ApiServiceInstance;
8
-
9
- constructor(@ApiService apiService: ApiServiceInstance){
10
- super();
11
- this.apiService = apiService;
12
- }
13
-
14
- async getFileContents(filePath: string): Promise<string>
15
- {
16
- return this.apiService.pureGet(filePath);
17
- }
18
-
6
+ class UtilsService extends TheService {
7
+ static _DEFAULT: boolean = true;
19
8
  mergeDeep<T>(target: T | any, source: T | any): T
20
9
  {
21
10
  const isObject = (obj: any) => obj && typeof obj === 'object';
@@ -22,6 +22,7 @@ const wsLog = async (fakeError: Error, text: any, socketId: string = null, isEr
22
22
  };
23
23
 
24
24
  class WSService extends TheService {
25
+ static _DEFAULT: boolean = true;
25
26
  static websocket_instance: Socket;
26
27
  private _ws: Socket | null = null;
27
28
 
@@ -10,6 +10,8 @@ export interface IWithDI<T> {
10
10
 
11
11
  export default abstract class TheRWSService {
12
12
  _RELOADABLE: boolean = false;
13
+ static _IN_CLIENT: boolean = false;
14
+ static _DEFAULT: boolean = false;
13
15
 
14
16
  constructor() {
15
17
  }
@@ -47,4 +49,14 @@ export default abstract class TheRWSService {
47
49
 
48
50
  return interf;
49
51
  }
52
+
53
+ isDefault(): boolean
54
+ {
55
+ return (this as any).constructor._DEFAULT;
56
+ }
57
+
58
+ isInClient(): boolean
59
+ {
60
+ return (this as any).constructor._IN_CLIENT;
61
+ }
50
62
  }
package/webpack/index.js CHANGED
@@ -1,10 +1,8 @@
1
- const cssLoader = require('./rws_fast_css_loader');
2
- const scssLoader = require('./rws_fast_scss_loader');
3
- const htmlLoader = require('./rws_fast_html_loader');
4
- const tsLoader = require('./rws_fast_ts_loader');
1
+ const scssLoader = require('./loaders/rws_fast_scss_loader');
2
+ const htmlLoader = require('./loaders/rws_fast_html_loader');
3
+ const tsLoader = require('./loaders/rws_fast_ts_loader');
5
4
 
6
- module.exports = {
7
- cssLoader,
5
+ module.exports = {
8
6
  scssLoader,
9
7
  htmlLoader,
10
8
  tsLoader
@@ -1,10 +1,10 @@
1
- const RWSPlugin = require("./rws_plugin");
1
+ const RWSCssPlugin = require("../rws_scss_plugin");
2
2
  const path = require('path');
3
3
  const cssLoader = require('css-loader');
4
4
 
5
5
  module.exports = function(content) {
6
6
  const callback = this.async();
7
- const plugin = new RWSPlugin();
7
+ const plugin = new RWSCssPlugin();
8
8
  const filePath = this.resourcePath;
9
9
 
10
10
  const options = this.getOptions() || { minify: false };
@@ -2,8 +2,8 @@
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
4
  const ts = require('typescript');
5
- const tools = require('../_tools');
6
- const RWSPlugin = require("./rws_plugin");
5
+ const tools = require('../../_tools');
6
+
7
7
 
8
8
  const _defaultRWSLoaderOptions = {
9
9
  templatePath: 'template.html',
@@ -11,23 +11,6 @@ const _defaultRWSLoaderOptions = {
11
11
  fastOptions: { shadowOptions: { mode: 'open' } }
12
12
  }
13
13
 
14
- function toJsonString(str) {
15
- // Replace single quotes with double quotes
16
- str = str.replace(/'/g, '"');
17
-
18
- // Add double quotes around keys
19
- str = str.replace(/([a-zA-Z0-9_]+)(?=\s*:)/g, '"$1"');
20
-
21
- try {
22
- // Parse the string as JSON and then stringify it to get a JSON string
23
- const jsonObj = JSON.parse(str);
24
- return JSON.stringify(jsonObj);
25
- } catch (error) {
26
- console.error("Error in parsing:", error);
27
- return null;
28
- }
29
- }
30
-
31
14
  module.exports = async function(content) {
32
15
  let processedContent = content;
33
16
  const filePath = this.resourcePath;
@@ -95,7 +78,7 @@ module.exports = async function(content) {
95
78
 
96
79
  replaced = modifiedContent;
97
80
  replaced = replaced.replace(`@RWSView('${tagName}')`, '');
98
- const plugin = new RWSPlugin();
81
+
99
82
  let styles = 'const styles: null = null;'
100
83
 
101
84
  if(fs.existsSync(path.dirname(filePath) + '/styles')){
@@ -112,13 +95,9 @@ module.exports = async function(content) {
112
95
 
113
96
  let htmlContent = fs.readFileSync(templatePath, 'utf-8');
114
97
 
115
- // try {
116
- // htmlContent = await htmlMinify(htmlContent, {
117
- // collapseWhitespace: true,
118
- // });
119
- // } catch(e){
120
- // console.error(e);
121
- // }
98
+ if(!isDev){
99
+ htmlContent = htmlContent.replace(/\n/g, '');
100
+ }
122
101
 
123
102
  template = `import './${templateName}.html';
124
103
  //@ts-ignore
@@ -0,0 +1,35 @@
1
+
2
+
3
+ const path = require('path');
4
+ const Terser = require('terser');
5
+
6
+ async function removeCommentsFromFile(code, inputSourceMap) {
7
+ const callback = this.async();
8
+ const sourceMap = this.sourceMap;
9
+ // Configure Terser to remove comments
10
+ try {
11
+ const minifyOptions = {
12
+ format: {
13
+ comments: false // Remove all comments
14
+ },
15
+ sourceMap: sourceMap
16
+ ? {
17
+ content: inputSourceMap || false,
18
+ url: 'out.js.map'
19
+ }
20
+ : false
21
+ };
22
+
23
+ // Minify source code
24
+ const result = await Terser.minify(code, minifyOptions);
25
+
26
+ // Pass along the source map if enabled
27
+ callback(null, result.code, result.map || inputSourceMap);
28
+ } catch (err) {
29
+ callback(err);
30
+ }
31
+ }
32
+
33
+ module.exports = async function (source, inputSourceMap) {
34
+ return await removeCommentsFromFile.bind(this)(source, inputSourceMap);
35
+ };
@@ -15,7 +15,7 @@ const log = (args) => {
15
15
  console.log(args);
16
16
  }
17
17
  }
18
- class RWSPlugin {
18
+ class RWSScssPlugin {
19
19
  autoCompile = [];
20
20
 
21
21
  constructor(params){
@@ -326,4 +326,4 @@ class RWSPlugin {
326
326
  }
327
327
  }
328
328
 
329
- module.exports = RWSPlugin;
329
+ module.exports = RWSScssPlugin;
@@ -1,16 +0,0 @@
1
- // custom-css-loader.js
2
- const RWSPlugin = require("./rws_plugin");
3
- const plugin = new RWSPlugin();
4
-
5
- module.exports = function(content) {
6
-
7
- if(this.resourcePath == '/app/frontend/src/styles/main.scss'){
8
- console.log('zzzzz',content, plugin.checkForImporterType(this._module, 'ts'));
9
- }
10
-
11
- if(!plugin.checkForImporterType(this._module, 'ts')){
12
- return content;
13
- }
14
-
15
- return `import { css } from '@microsoft/fast-element';\nexport default css\`${content}\`;`;
16
- };