@equinor/fusion-framework-dev-server 1.1.3 → 1.1.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @equinor/fusion-framework-dev-server
2
2
 
3
+ ## 1.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`99a3c26`](https://github.com/equinor/fusion-framework/commit/99a3c26275c2089c3708124f5819ce383d8dc3dc)]:
8
+ - @equinor/fusion-framework-vite-plugin-spa@1.2.0
9
+
10
+ ## 1.1.4
11
+
12
+ ### Patch Changes
13
+
14
+ - [#3532](https://github.com/equinor/fusion-framework/pull/3532) [`63ecde5`](https://github.com/equinor/fusion-framework/commit/63ecde5c29e775b341c3fac0c1eeb7123db5e2db) Thanks [@dependabot](https://github.com/apps/dependabot)! - Bump vite from 7.1.8 to 7.1.9 across development tools and plugins.
15
+
16
+ This patch update fixes bugs and improves stability in the vite dependency.
17
+
18
+ - Updated dependencies [[`45954e5`](https://github.com/equinor/fusion-framework/commit/45954e5db471a2faa24e88e41fc6d6c18817d6d1), [`63ecde5`](https://github.com/equinor/fusion-framework/commit/63ecde5c29e775b341c3fac0c1eeb7123db5e2db), [`d1098f7`](https://github.com/equinor/fusion-framework/commit/d1098f7eeff04380c9e05e4a7a7d6b16e1d95884)]:
19
+ - @equinor/fusion-framework-vite-plugin-spa@1.1.4
20
+ - @equinor/fusion-framework-vite-plugin-api-service@1.2.2
21
+
3
22
  ## 1.1.3
4
23
 
5
24
  ### Patch Changes
package/README.md CHANGED
@@ -1,108 +1,488 @@
1
1
  # Fusion Framework Dev Server
2
2
 
3
- This package provides a development server for Fusion Framework applications.
3
+ A powerful development server for Fusion Framework applications, built on Vite with integrated service discovery, API proxying, and portal support.
4
4
 
5
- ## Configuration
6
-
7
- This dev server is focused on Fusion Framework, but under the hood it uses Vite. The configuration is a mix of Vite and Fusion Framework.
8
- The dev server is created using the `createDevServer` function, which takes a configuration object as an argument.
9
-
10
- The first argument is the generic fusion framework configuration, which simplifies the configuration for the dev server.
5
+ ## Features
11
6
 
12
- The second argument is the Vite configuration object, which is optional and overrides the default Vite configuration.
13
- see [Vite options](https://vite.dev/config/) for more details.
7
+ - 🚀 **Fast Development**: Powered by Vite for lightning-fast HMR and builds
8
+ - 🔗 **Service Discovery**: Automatic API service discovery and proxying
9
+ - 🏠 **Portal Support**: Built-in portal development with manifest loading
10
+ - 🔧 **API Mocking**: Easy mocking and overriding of API responses
11
+ - 📊 **Telemetry**: Integrated logging and debugging capabilities
12
+ - ⚙️ **Flexible Configuration**: Extensive customization options
14
13
 
15
- > [!TIP]
16
- const devServer = await createDevServer({
17
- > You can use the `createDevServerConfig` to generate fusion configuration, then `Vite.mergeConfig` to merge with additional Vite configuration. Then create the dev server with `Vite.createServer`. The `createDevServer` function is a wrapper around this.
14
+ ## Quick Start
18
15
 
19
- ### Basic Configuration
16
+ Here's the minimal setup to get a Fusion Framework dev server running:
20
17
 
21
- The dev server requires a basic configuration object to be passed to it.
18
+ ```typescript
19
+ import { createDevServer } from '@equinor/fusion-framework-dev-server';
22
20
 
23
- ```ts
24
21
  const devServer = await createDevServer({
25
22
  spa: {
26
23
  templateEnv: {
27
24
  portal: {
28
25
  id: '@equinor/fusion-framework-dev-portal',
29
- }
30
- title: 'My Test Dev Server',
26
+ },
27
+ title: 'My Fusion App',
31
28
  serviceDiscovery: {
32
- url: 'https://location.of.your.service.discovery',
33
- scopes: ['scope_required'],
29
+ url: 'https://service-discovery.example.com',
30
+ scopes: ['api://example.com/user_impersonation'],
34
31
  },
35
32
  msal: {
36
- clientId: 'dev-client-id',
37
- tenantId: 'dev-tenant-id',
33
+ clientId: 'your-client-id',
34
+ tenantId: 'your-tenant-id',
38
35
  redirectUri: '/authentication/login-callback',
39
36
  requiresAuth: 'true',
40
37
  },
41
38
  },
42
39
  },
40
+ api: {
41
+ serviceDiscoveryUrl: 'https://service-discovery.example.com',
42
+ },
43
43
  });
44
+
45
+ await devServer.listen();
46
+ devServer.printUrls();
44
47
  ```
45
48
 
46
- ### Adding Service Discovery
49
+ ## Configuration
47
50
 
48
- By adding configuration to the `api` object, you can add service discovery to your dev server. This is useful for mocking API requests and setting up routes. see [@equinor/fusion-framework-vite-plugin-api-service](../vite-plugins/api-service/README.md) for more details.
51
+ The dev server accepts a configuration object with the following structure:
49
52
 
50
- ```ts
51
- createDevServer(
52
- {
53
- // Adding proxying for service discovery
54
- api: {
55
- // proxy target for service discovery
56
- serviceDiscoveryUrl: 'https://location.of.your/service/discovery',
57
- // method for modifying the service discovery response and setting up routes
58
- processServices: (dataResponse, route) => {
59
- const { data, routes } = processServices(dataResponse, route);
60
- return {
61
- data: data.concat({
62
- key: 'portals',
63
- name: 'Portal Service - MOCK',
64
- uri: '/@fusion-api/portals',
65
- }),
66
- routes,
67
- };
53
+ ### SPA Configuration
54
+
55
+ Configure the Single Page Application environment and template generation:
56
+
57
+ ```typescript
58
+ {
59
+ spa: {
60
+ templateEnv: {
61
+ // Portal configuration
62
+ portal: {
63
+ id: 'your-portal-id', // Portal identifier
64
+ },
65
+
66
+ // Application title
67
+ title: 'My Application',
68
+
69
+ // Service discovery settings
70
+ serviceDiscovery: {
71
+ url: 'https://service-discovery.example.com',
72
+ scopes: ['scope1', 'scope2'],
73
+ },
74
+
75
+ // Authentication configuration
76
+ msal: {
77
+ clientId: 'your-client-id',
78
+ tenantId: 'your-tenant-id',
79
+ redirectUri: '/authentication/login-callback',
80
+ requiresAuth: 'true', // or 'false'
81
+ },
82
+
83
+ // Optional telemetry configuration (browser console logging)
84
+ telemetry: {
85
+ consoleLevel: 1, // 0=Debug, 1=Information, 2=Warning, 3=Error, 4=Critical
86
+ },
87
+
88
+ // Optional service worker configuration
89
+ serviceWorker: {
90
+ resources: [
91
+ {
92
+ url: '/api',
93
+ rewrite: '/api-v1',
94
+ scopes: ['api://example.com/user_impersonation'],
95
+ },
96
+ ],
68
97
  },
69
98
  },
70
- routes: [ /** add proxy and middleware routes */]
71
- }
72
- );
99
+ },
100
+ }
73
101
  ```
74
102
 
103
+ ### API Configuration
75
104
 
76
- ## Proxying API Requests
105
+ Configure API proxying and service discovery:
77
106
 
78
- Sometimes proxy requests need authentication tokens, or need to be rewritten to a different path. The dev server can handle this by using the `serviceWorker` configuration.
107
+ ```typescript
108
+ {
109
+ api: {
110
+ // Required: Service discovery endpoint
111
+ serviceDiscoveryUrl: 'https://service-discovery.example.com',
79
112
 
80
- see [Vite server Proxy](https://vite.dev/config/server-options#server-proxy) for more details for setting up the proxy.
113
+ // Optional: Custom service processing
114
+ processServices: (services, route) => {
115
+ // Process and return services with routes
116
+ return processServices(services, route);
117
+ },
81
118
 
82
- ```ts
83
- createDevServer(
84
- {
85
- ... // add basic configuration here
86
-
87
- // intercepting requests to /api and rewriting them to /api-v1 and adding auth token
88
- serviceWorker: {
89
- resources: [
90
- {
91
- url: '/api',
92
- rewrite: '/api-v1',
93
- scopes: ['scope1', 'scope2'],
119
+ // Optional: Additional API routes
120
+ routes: [
121
+ {
122
+ match: '/api/custom/*',
123
+ middleware: (req, res) => {
124
+ // Custom middleware logic
125
+ res.end(JSON.stringify({ custom: 'response' }));
94
126
  },
95
- ],
96
- }
97
- },
98
- {
99
- proxy: {
100
- '/api': {
101
- target: 'https://api.example.com',
102
- changeOrigin: true,
103
- pathRewrite: { '^/api': '' },
127
+ },
128
+ ],
129
+ },
130
+ }
131
+ ```
132
+
133
+ ### Logging Configuration
134
+
135
+ Configure CLI/server-side logging levels and custom loggers:
136
+
137
+ ```typescript
138
+ {
139
+ log: {
140
+ // Optional: CLI log level (0=None, 1=Error, 2=Warning, 3=Info, 4=Debug)
141
+ level: 3, // Default is Info level
142
+
143
+ // Optional: Custom logger instance
144
+ logger: new ConsoleLogger('my-dev-server'),
145
+ },
146
+ }
147
+ ```
148
+
149
+ > [!NOTE]
150
+ > **Telemetry vs CLI Logging**: The `telemetry.consoleLevel` controls logging output in the browser console (visible to end users), while `log.level` controls server-side logging in the terminal/command line (visible to developers). These use different logging systems with different level mappings.
151
+
152
+ ### Main Functions
153
+
154
+ #### `createDevServer(options, overrides?)`
155
+
156
+ Creates and configures a development server instance.
157
+
158
+ **Parameters:**
159
+ - `options` (`DevServerOptions`): Configuration object for the dev server
160
+ - `overrides` (`UserConfig`): Optional Vite configuration overrides
161
+
162
+ **Returns:** `Promise<ViteDevServer>` - Configured Vite development server
163
+
164
+ **Example:**
165
+ ```typescript
166
+ const devServer = await createDevServer(config);
167
+ await devServer.listen();
168
+ ```
169
+
170
+ #### `createDevServerConfig(options, overrides?)`
171
+
172
+ Creates a Vite configuration object for the dev server.
173
+
174
+ **Parameters:**
175
+ - `options` (`DevServerOptions`): Configuration object for the dev server
176
+ - `overrides` (`UserConfig`): Optional Vite configuration overrides
177
+
178
+ **Returns:** `UserConfig` - Vite configuration object
179
+
180
+ ### Utility Functions
181
+
182
+ #### `processServices(data, args)`
183
+
184
+ Processes service discovery data and generates proxy routes.
185
+
186
+ **Parameters:**
187
+ - `data` (`FusionService[]`): Array of services from service discovery
188
+ - `args.route` (`string`): Base route for proxying
189
+ - `args.request` (`IncomingMessage`): HTTP request object
190
+
191
+ **Returns:** Object with processed services and routes
192
+
193
+ ### Types
194
+
195
+ #### `DevServerOptions<TEnv>`
196
+
197
+ Configuration options for the development server.
198
+
199
+ ```typescript
200
+ type DevServerOptions<TEnv extends Partial<FusionTemplateEnv>> = {
201
+ spa?: {
202
+ templateEnv: TEnv | TemplateEnvFn<TEnv>;
203
+ };
204
+ api: {
205
+ serviceDiscoveryUrl: string;
206
+ processServices?: ApiDataProcessor<FusionService[]>;
207
+ routes?: ApiRoute[];
208
+ };
209
+ log?: {
210
+ level?: number;
211
+ logger?: ConsoleLogger;
212
+ };
213
+ };
214
+ ```
215
+
216
+ #### `FusionService`
217
+
218
+ Represents a service in the Fusion ecosystem.
219
+
220
+ ```typescript
221
+ type FusionService = {
222
+ key: string; // Service identifier
223
+ uri: string; // Service endpoint URL
224
+ name: string; // Human-readable service name
225
+ };
226
+ ```
227
+
228
+ ## Examples
229
+
230
+ ### Basic Portal Development
231
+
232
+ ```typescript
233
+ import { createDevServer } from '@equinor/fusion-framework-dev-server';
234
+
235
+ const devServer = await createDevServer({
236
+ spa: {
237
+ templateEnv: {
238
+ portal: { id: 'my-portal' },
239
+ title: 'My Portal',
240
+ serviceDiscovery: {
241
+ url: 'https://service-discovery.example.com',
242
+ scopes: ['api://example.com/user_impersonation'],
243
+ },
244
+ msal: {
245
+ clientId: process.env.CLIENT_ID!,
246
+ tenantId: process.env.TENANT_ID!,
247
+ redirectUri: '/authentication/login-callback',
248
+ requiresAuth: 'true',
104
249
  },
105
250
  },
251
+ },
252
+ api: {
253
+ serviceDiscoveryUrl: 'https://service-discovery.example.com',
254
+ },
255
+ });
256
+
257
+ await devServer.listen();
258
+ ```
259
+
260
+ ### Adding Mock Services
261
+
262
+ ```typescript
263
+ import { createDevServer, processServices } from '@equinor/fusion-framework-dev-server';
264
+
265
+ const devServer = await createDevServer({
266
+ spa: { /* ... spa config ... */ },
267
+ api: {
268
+ serviceDiscoveryUrl: 'https://service-discovery.example.com',
269
+ processServices: (data, route) => {
270
+ const { data: services, routes } = processServices(data, route);
271
+
272
+ // Add mock services
273
+ return {
274
+ data: services.concat({
275
+ key: 'mock-api',
276
+ name: 'Mock API Service',
277
+ uri: '/mock-api',
278
+ }),
279
+ routes: routes.concat({
280
+ match: '/mock-api/*',
281
+ middleware: (req, res) => {
282
+ res.setHeader('Content-Type', 'application/json');
283
+ res.end(JSON.stringify({ mock: 'data' }));
284
+ },
285
+ }),
286
+ };
287
+ },
288
+ },
289
+ });
290
+ ```
291
+
292
+ ### Custom Vite Configuration
293
+
294
+ ```typescript
295
+ import { createDevServer } from '@equinor/fusion-framework-dev-server';
296
+ import { defineConfig } from 'vite';
297
+
298
+ const devServer = await createDevServer(
299
+ { /* ... dev server config ... */ },
300
+ defineConfig({
301
+ server: {
302
+ port: 3001,
303
+ host: '0.0.0.0',
304
+ },
305
+ define: {
306
+ __DEV__: true,
307
+ },
308
+ })
309
+ );
310
+ ```
311
+
312
+
313
+ ## Troubleshooting
314
+
315
+ ### Common Issues
316
+
317
+ #### "Cannot find module '@equinor/fusion-framework-dev-server'"
318
+
319
+ **Solution:** Make sure the package is installed and you're using the correct import path.
320
+
321
+ ```bash
322
+ pnpm add -D @equinor/fusion-framework-dev-server
323
+ ```
324
+
325
+ #### Service Discovery Connection Failed
326
+
327
+ **Problem:** The dev server can't connect to the service discovery endpoint.
328
+
329
+ **Solutions:**
330
+ 1. Check that `serviceDiscoveryUrl` is correct and accessible
331
+ 2. Verify network connectivity to the service discovery endpoint
332
+ 3. Check for authentication requirements
333
+
334
+ #### Portal Manifest Not Loading
335
+
336
+ **Problem:** Portal configuration isn't loading properly.
337
+
338
+ **Solutions:**
339
+ 1. Verify the portal ID is correct in the `spa.templateEnv.portal.id` field
340
+ 2. Check that the portal service is available and responding
341
+ 3. Ensure proper authentication is configured
342
+
343
+ #### API Routes Not Working
344
+
345
+ **Problem:** Custom API routes or service proxying isn't functioning.
346
+
347
+ **Solutions:**
348
+ 1. Check the `routes` configuration in the `api` section
349
+ 2. Verify route patterns match the expected request paths
350
+ 3. Ensure middleware functions are properly implemented
351
+ 4. Check for conflicts with existing routes
352
+
353
+ #### Authentication Issues
354
+
355
+ **Problem:** MSAL authentication isn't working.
356
+
357
+ **Solutions:**
358
+ 1. Verify `clientId` and `tenantId` are correct
359
+ 2. Check that `redirectUri` matches your application configuration
360
+ 3. Ensure the required scopes are properly configured
361
+ 4. Check browser console for authentication errors
362
+
363
+ ### Debug Logging
364
+
365
+ Enable debug logging to troubleshoot issues:
366
+
367
+ #### CLI/Server-Side Debug Logging
368
+ ```typescript
369
+ const devServer = await createDevServer({
370
+ // ... config
371
+ log: {
372
+ level: 4, // Debug level (0=None, 1=Error, 2=Warning, 3=Info, 4=Debug)
373
+ },
374
+ });
375
+ ```
376
+
377
+ #### Browser Console Telemetry Logging
378
+ ```typescript
379
+ {
380
+ spa: {
381
+ templateEnv: {
382
+ // ... other config
383
+ telemetry: {
384
+ consoleLevel: 0, // Debug level (0=Debug, 1=Information, 2=Warning, 3=Error, 4=Critical)
385
+ },
386
+ },
387
+ },
388
+ }
389
+ ```
390
+
391
+ ## Advanced Usage
392
+
393
+ ### Custom Service Processing
394
+
395
+ For advanced service discovery manipulation:
396
+
397
+ ```typescript
398
+ import { createDevServer, processServices } from '@equinor/fusion-framework-dev-server';
399
+
400
+ const devServer = await createDevServer({
401
+ api: {
402
+ serviceDiscoveryUrl: 'https://service-discovery.example.com',
403
+ processServices: (services, route) => {
404
+ const { data, routes } = processServices(services, route);
405
+
406
+ // Filter out development-only services in production
407
+ const filteredData = data.filter(service =>
408
+ process.env.NODE_ENV !== 'production' || !service.key.includes('dev')
409
+ );
410
+
411
+ // Add custom routes for specific services
412
+ const customRoutes = routes.map(route => ({
413
+ ...route,
414
+ // Add custom headers or modify proxy behavior
415
+ }));
416
+
417
+ return { data: filteredData, routes: customRoutes };
418
+ },
419
+ },
420
+ });
421
+ ```
422
+
423
+ ### Integration with Build Tools
424
+
425
+ The dev server works seamlessly with the Fusion Framework CLI:
426
+
427
+ ```bash
428
+ # Use with CLI for automatic configuration
429
+ npx @equinor/fusion-framework-cli app dev
430
+
431
+ # Or portal development
432
+ npx @equinor/fusion-framework-cli portal dev
433
+ ```
434
+
435
+ ### Custom Plugins
436
+
437
+ Extend the dev server with custom Vite plugins:
438
+
439
+ ```typescript
440
+ import { createDevServer } from '@equinor/fusion-framework-dev-server';
441
+ import myCustomPlugin from 'my-custom-vite-plugin';
442
+
443
+ const devServer = await createDevServer(
444
+ { /* ... config ... */ },
445
+ {
446
+ plugins: [myCustomPlugin()],
106
447
  }
107
448
  );
108
449
  ```
450
+
451
+ ## Migration Guide
452
+
453
+ ### From Direct Vite Usage
454
+
455
+ If you're migrating from a direct Vite setup:
456
+
457
+ 1. Replace your Vite configuration with the dev server configuration
458
+ 2. Move service discovery logic to the `api.processServices` function
459
+ 3. Configure portal settings in `spa.templateEnv`
460
+ 4. Update your start script to use `createDevServer`
461
+
462
+ **Before:**
463
+ ```typescript
464
+ // vite.config.ts
465
+ export default defineConfig({
466
+ plugins: [react(), /* other plugins */],
467
+ server: {
468
+ proxy: { /* proxy config */ },
469
+ },
470
+ });
471
+ ```
472
+
473
+ **After:**
474
+ ```typescript
475
+ import { createDevServer } from '@equinor/fusion-framework-dev-server';
476
+
477
+ const devServer = await createDevServer({
478
+ // Move your config here
479
+ });
480
+ ```
481
+
482
+ ## Contributing
483
+
484
+ This package is part of the Fusion Framework monorepo. See the main [contributing guide](../../CONTRIBUTING.md) for details.
485
+
486
+ ## License
487
+
488
+ ISC
@@ -14,7 +14,7 @@ const createDefaultLogger = (lvl = LogLevel.Info, title = 'dev-server') => {
14
14
  *
15
15
  * @template TEnv - A type extending `Partial<TemplateEnv>` that represents the environment variables for the template.
16
16
  * @param options - The options for configuring the development server.
17
- * @param options.spa - Configuration for the Single Page Application (SPA), including template environment settings.
17
+ * @param options.spa - Optional configuration for the Single Page Application (SPA), including template environment settings.
18
18
  * @param options.api - Configuration for the API, including service discovery URL, routes, and service processing logic.
19
19
  *
20
20
  * @returns A `UserConfig` object that defines the Vite development server configuration.
@@ -1,3 +1,3 @@
1
1
  // Generated by genversion.
2
- export const version = '1.1.3';
2
+ export const version = '1.1.5';
3
3
  //# sourceMappingURL=version.js.map