@equinor/fusion-framework-dev-server 1.0.0-next.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/CHANGELOG.md +82 -0
- package/LICENSE +21 -0
- package/READDME.md +108 -0
- package/package.json +48 -0
- package/src/create-dev-server-config.ts +94 -0
- package/src/create-dev-server.ts +18 -0
- package/src/index.ts +11 -0
- package/src/process-services.ts +87 -0
- package/src/types.ts +48 -0
- package/src/version.ts +2 -0
- package/tsconfig.json +19 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @equinor/fusion-framework-dev-server
|
|
2
|
+
|
|
3
|
+
## 1.0.0-next.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#3074](https://github.com/equinor/fusion-framework/pull/3074) [`6b034e5`](https://github.com/equinor/fusion-framework/commit/6b034e5459094cea0c0f2490335eef3092390a13) Thanks [@odinr](https://github.com/odinr)! - Introduced a new package, `@equinor/fusion-framework-dev-server`, designed to provide a development server tailored for Fusion Framework applications. Built on top of Vite, it seamlessly integrates Vite and Fusion Framework configurations.
|
|
8
|
+
|
|
9
|
+
**Features**
|
|
10
|
+
|
|
11
|
+
- _`createDevServer` Function_: Simplifies the creation of a development server using a configuration object.
|
|
12
|
+
- _`createDevServerConfig` Function_: Generates a Vite-compatible configuration for the development server.
|
|
13
|
+
- _SPA Support_: Includes `spa.templateEnv` for defining environment variables specific to Single Page Applications.
|
|
14
|
+
- _API Service Discovery_: Enables proxying and route mapping for API services via `api.serviceDiscoveryUrl`.
|
|
15
|
+
- _Dynamic Proxy Routes_: Introduced the `processServices` function to remap Fusion services' URIs and dynamically generate proxy routes.
|
|
16
|
+
- _Logging_: Integrated `@equinor/fusion-log` for customizable logging, with dedicated sub-loggers for SPA and API services.
|
|
17
|
+
|
|
18
|
+
**Dependencies**
|
|
19
|
+
|
|
20
|
+
The following dependencies were added to support the new package:
|
|
21
|
+
|
|
22
|
+
- `@equinor/fusion-framework-vite-plugin-api-service`
|
|
23
|
+
- `@equinor/fusion-framework-vite-plugin-spa`
|
|
24
|
+
- `@equinor/fusion-log`
|
|
25
|
+
|
|
26
|
+
**Examples**
|
|
27
|
+
|
|
28
|
+
_Using `createDevServer`_
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { createDevServer } from "@equinor/fusion-framework-dev-server";
|
|
32
|
+
|
|
33
|
+
const devServer = await createDevServer({
|
|
34
|
+
spa: {
|
|
35
|
+
templateEnv: {
|
|
36
|
+
portal: {
|
|
37
|
+
id: "dev-portal",
|
|
38
|
+
},
|
|
39
|
+
title: "My Test Dev Server",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
api: {
|
|
43
|
+
serviceDiscoveryUrl: "https://location.of.your.service.discovery",
|
|
44
|
+
processServices: (data, route) => {
|
|
45
|
+
return {
|
|
46
|
+
data: data.concat({
|
|
47
|
+
key: "mock-service",
|
|
48
|
+
name: "Mock Service",
|
|
49
|
+
uri: "/mock-api",
|
|
50
|
+
}),
|
|
51
|
+
routes: [],
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
_Using `createDevServerConfig`_
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { createDevServerConfig } from "@equinor/fusion-framework-dev-server";
|
|
62
|
+
|
|
63
|
+
const config = createDevServerConfig({
|
|
64
|
+
spa: {
|
|
65
|
+
templateEnv: { API_URL: "https://api.example.com" },
|
|
66
|
+
},
|
|
67
|
+
api: {
|
|
68
|
+
serviceDiscoveryUrl: "https://discovery.example.com",
|
|
69
|
+
routes: ["/api"],
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Patch Changes
|
|
75
|
+
|
|
76
|
+
- [#3074](https://github.com/equinor/fusion-framework/pull/3074) [`6b034e5`](https://github.com/equinor/fusion-framework/commit/6b034e5459094cea0c0f2490335eef3092390a13) Thanks [@odinr](https://github.com/odinr)! - update Vite to 6.3.5
|
|
77
|
+
|
|
78
|
+
- [#3074](https://github.com/equinor/fusion-framework/pull/3074) [`6b034e5`](https://github.com/equinor/fusion-framework/commit/6b034e5459094cea0c0f2490335eef3092390a13) Thanks [@odinr](https://github.com/odinr)! - exported UserConfig interface from vite
|
|
79
|
+
|
|
80
|
+
- Updated dependencies [[`6b034e5`](https://github.com/equinor/fusion-framework/commit/6b034e5459094cea0c0f2490335eef3092390a13), [`6b034e5`](https://github.com/equinor/fusion-framework/commit/6b034e5459094cea0c0f2490335eef3092390a13), [`6b034e5`](https://github.com/equinor/fusion-framework/commit/6b034e5459094cea0c0f2490335eef3092390a13), [`6b034e5`](https://github.com/equinor/fusion-framework/commit/6b034e5459094cea0c0f2490335eef3092390a13)]:
|
|
81
|
+
- @equinor/fusion-framework-vite-plugin-spa@1.0.0-next.0
|
|
82
|
+
- @equinor/fusion-framework-vite-plugin-api-service@1.0.0-next.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Equinor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/READDME.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Fusion Framework Dev Server
|
|
2
|
+
|
|
3
|
+
This package provides a development server for Fusion Framework applications.
|
|
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.
|
|
11
|
+
|
|
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.
|
|
14
|
+
|
|
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.
|
|
18
|
+
|
|
19
|
+
### Basic Configuration
|
|
20
|
+
|
|
21
|
+
The dev server requires a basic configuration object to be passed to it.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
const devServer = await createDevServer({
|
|
25
|
+
spa: {
|
|
26
|
+
templateEnv: {
|
|
27
|
+
portal: {
|
|
28
|
+
id: '@equinor/fusion-framework-dev-portal',
|
|
29
|
+
}
|
|
30
|
+
title: 'My Test Dev Server',
|
|
31
|
+
serviceDiscovery: {
|
|
32
|
+
url: 'https://location.of.your.service.discovery',
|
|
33
|
+
scopes: ['scope_required'],
|
|
34
|
+
},
|
|
35
|
+
msal: {
|
|
36
|
+
clientId: 'dev-client-id',
|
|
37
|
+
tenantId: 'dev-tenant-id',
|
|
38
|
+
redirectUri: '/authentication/login-callback',
|
|
39
|
+
requiresAuth: 'true',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Adding Service Discovery
|
|
47
|
+
|
|
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.
|
|
49
|
+
|
|
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
|
+
};
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
routes: [ /** add proxy and middleware routes */]
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## Proxying API Requests
|
|
77
|
+
|
|
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.
|
|
79
|
+
|
|
80
|
+
see [Vite server Proxy](https://vite.dev/config/server-options#server-proxy) for more details for setting up the proxy.
|
|
81
|
+
|
|
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'],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
proxy: {
|
|
100
|
+
'/api': {
|
|
101
|
+
target: 'https://api.example.com',
|
|
102
|
+
changeOrigin: true,
|
|
103
|
+
pathRewrite: { '^/api': '' },
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@equinor/fusion-framework-dev-server",
|
|
3
|
+
"version": "1.0.0-next.0",
|
|
4
|
+
"description": "Package for running a development server for fusion-framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/esm/index.js",
|
|
9
|
+
"types": "./dist/types/index.d.ts"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"types": "dist/types/index.d.ts",
|
|
13
|
+
"directories": {
|
|
14
|
+
"dist": "dist"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/equinor/fusion-framework.git",
|
|
19
|
+
"directory": "packages/dev-server"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"dev-server",
|
|
23
|
+
"fusion-framework",
|
|
24
|
+
"vite",
|
|
25
|
+
"typescript"
|
|
26
|
+
],
|
|
27
|
+
"license": "ISC",
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@equinor/fusion-framework-vite-plugin-api-service": "^1.0.0-next.0",
|
|
33
|
+
"@equinor/fusion-framework-vite-plugin-spa": "^1.0.0-next.0",
|
|
34
|
+
"@equinor/fusion-log": "^1.1.4"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"typescript": "^5.5.4",
|
|
38
|
+
"vite": "^6.3.5",
|
|
39
|
+
"vitest": "^2.0.5"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"vite": "^6.0.7"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -b",
|
|
46
|
+
"test": "vitest"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { defineConfig, mergeConfig, type UserConfig } from 'vite';
|
|
2
|
+
import apiServicePlugin, {
|
|
3
|
+
createProxyHandler,
|
|
4
|
+
} from '@equinor/fusion-framework-vite-plugin-api-service';
|
|
5
|
+
|
|
6
|
+
import fusionSpaPlugin from '@equinor/fusion-framework-vite-plugin-spa';
|
|
7
|
+
import { ConsoleLogger, LogLevel } from '@equinor/fusion-log';
|
|
8
|
+
|
|
9
|
+
import defaultProcessServices from './process-services.js';
|
|
10
|
+
|
|
11
|
+
import type { DevServerOptions, TemplateEnv, TemplateEnvFn } from './types.js';
|
|
12
|
+
|
|
13
|
+
const createDefaultLogger = (lvl: LogLevel = LogLevel.Info, title = 'dev-server') => {
|
|
14
|
+
const logger = new ConsoleLogger(title);
|
|
15
|
+
logger.level = lvl;
|
|
16
|
+
return logger;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a development server configuration for a Fusion Framework application.
|
|
21
|
+
*
|
|
22
|
+
* @template TEnv - A type extending `Partial<TemplateEnv>` that represents the environment variables for the template.
|
|
23
|
+
* @param options - The options for configuring the development server.
|
|
24
|
+
* @param options.spa - Configuration for the Single Page Application (SPA), including template environment settings.
|
|
25
|
+
* @param options.api - Configuration for the API, including service discovery URL, routes, and service processing logic.
|
|
26
|
+
*
|
|
27
|
+
* @returns A `UserConfig` object that defines the Vite development server configuration.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* - The `spa.templateEnv` can either be a function or a partial object of type `TEnv`.
|
|
31
|
+
* - The `api.processServices` defaults to `defaultProcessServices` if not provided.
|
|
32
|
+
* - The server is configured to run on port 3000.
|
|
33
|
+
* - Includes plugins for API service handling and SPA template environment generation.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const config = createDevServerConfig({
|
|
38
|
+
* spa: {
|
|
39
|
+
* templateEnv: { API_URL: 'https://api.example.com' },
|
|
40
|
+
* },
|
|
41
|
+
* api: {
|
|
42
|
+
* serviceDiscoveryUrl: 'https://discovery.example.com',
|
|
43
|
+
* routes: ['/api'],
|
|
44
|
+
* },
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export const createDevServerConfig = <TEnv extends Partial<TemplateEnv>>(
|
|
49
|
+
options: DevServerOptions<TEnv>,
|
|
50
|
+
overrides?: UserConfig,
|
|
51
|
+
): UserConfig => {
|
|
52
|
+
const { spa, api, log, server } = options;
|
|
53
|
+
const processServices = api.processServices ?? defaultProcessServices;
|
|
54
|
+
const generateTemplateEnv: TemplateEnvFn<TEnv> =
|
|
55
|
+
// ensure that the templateEnv is a function
|
|
56
|
+
typeof spa?.templateEnv === 'function'
|
|
57
|
+
? spa.templateEnv
|
|
58
|
+
: () => spa?.templateEnv as Partial<TEnv>;
|
|
59
|
+
|
|
60
|
+
// setup log instance
|
|
61
|
+
const logger = log?.logger ?? createDefaultLogger(log?.level);
|
|
62
|
+
|
|
63
|
+
const apiServiceLogger = logger.createSubLogger('api-service');
|
|
64
|
+
const spaLogger = logger.createSubLogger('spa');
|
|
65
|
+
|
|
66
|
+
const baseConfig = defineConfig({
|
|
67
|
+
appType: 'custom',
|
|
68
|
+
define: {
|
|
69
|
+
'process.env': JSON.stringify({
|
|
70
|
+
FUSION_LOG_LEVEL: String(logger.level),
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
server: {
|
|
74
|
+
...server,
|
|
75
|
+
},
|
|
76
|
+
plugins: [
|
|
77
|
+
apiServicePlugin(
|
|
78
|
+
{
|
|
79
|
+
proxyHandler: createProxyHandler(api.serviceDiscoveryUrl, processServices, {
|
|
80
|
+
logger: apiServiceLogger,
|
|
81
|
+
}),
|
|
82
|
+
routes: api.routes,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
logger: apiServiceLogger,
|
|
86
|
+
},
|
|
87
|
+
),
|
|
88
|
+
fusionSpaPlugin({ generateTemplateEnv, logger: spaLogger }),
|
|
89
|
+
],
|
|
90
|
+
});
|
|
91
|
+
return mergeConfig(baseConfig, overrides ?? {});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default createDevServerConfig;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createServer, type UserConfig } from 'vite';
|
|
2
|
+
import createDevServerConfig from './create-dev-server-config.js';
|
|
3
|
+
|
|
4
|
+
import type { DevServerOptions } from './types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Asynchronously creates and configures a development server instance.
|
|
8
|
+
*
|
|
9
|
+
* @param options - The options used to configure the development server.
|
|
10
|
+
* @returns A promise that resolves to the created development server instance.
|
|
11
|
+
*/
|
|
12
|
+
export const createDevServer = async (options: DevServerOptions, overrides?: UserConfig) => {
|
|
13
|
+
const config = createDevServerConfig(options, overrides);
|
|
14
|
+
const server = await createServer(config);
|
|
15
|
+
return server;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default createDevServer;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { UserConfig } from 'vite';
|
|
2
|
+
|
|
3
|
+
export { processServices } from './process-services.js';
|
|
4
|
+
|
|
5
|
+
export { default, createDevServer } from './create-dev-server.js';
|
|
6
|
+
|
|
7
|
+
export { createDevServerConfig } from './create-dev-server-config.js';
|
|
8
|
+
|
|
9
|
+
export type { FusionTemplateEnv } from '@equinor/fusion-framework-vite-plugin-spa';
|
|
10
|
+
|
|
11
|
+
export * from './types.js';
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { ApiDataProcessor, ApiRoute } from '@equinor/fusion-framework-vite-plugin-api-service';
|
|
2
|
+
import type { FusionService } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Processes an array of Fusion services, remapping their URIs to proxy through the development server
|
|
6
|
+
* and generating corresponding proxy routes.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of the input data, expected to be an array of `FusionService`.
|
|
9
|
+
* @param data - The input array of Fusion services to process.
|
|
10
|
+
* @param args - Additional arguments containing the route and request information.
|
|
11
|
+
* @param args.route - The base route used to construct the proxy paths.
|
|
12
|
+
* @param args.request - The HTTP request object, used to extract the referer header.
|
|
13
|
+
* @returns An object containing the processed services and the generated proxy routes.
|
|
14
|
+
* @throws {Error} If the input data is not an array.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const services = [
|
|
19
|
+
* { key: 'service1', uri: 'http://example.com/api', name: 'Service 1' },
|
|
20
|
+
* { key: 'service2', uri: 'http://example.org/api', name: 'Service 2' },
|
|
21
|
+
* ];
|
|
22
|
+
* const args = {
|
|
23
|
+
* route: '/proxy',
|
|
24
|
+
* request: { headers: { referer: 'http://localhost:3000' } },
|
|
25
|
+
* };
|
|
26
|
+
* const result = processServices(services, args);
|
|
27
|
+
* console.log(result.data); // Processed services with updated URIs
|
|
28
|
+
*
|
|
29
|
+
* // Expected output:
|
|
30
|
+
* // result.data:
|
|
31
|
+
* // [
|
|
32
|
+
* // { key: 'service1', uri: 'http://localhost:3000/proxy/service1', name: 'Service 1' },
|
|
33
|
+
* // { key: 'service2', uri: 'http://localhost:3000/proxy/service2', name: 'Service 2' },
|
|
34
|
+
* // ]
|
|
35
|
+
*
|
|
36
|
+
* console.log(result.routes); // Generated proxy routes
|
|
37
|
+
*
|
|
38
|
+
* // result.routes:
|
|
39
|
+
* // [
|
|
40
|
+
* // {
|
|
41
|
+
* // match: '/service1/api*sub',
|
|
42
|
+
* // proxy: {
|
|
43
|
+
* // target: 'http://example.com',
|
|
44
|
+
* // rewrite: (path) => path.replace('/service1', ''),
|
|
45
|
+
* // },
|
|
46
|
+
* // },
|
|
47
|
+
* // {
|
|
48
|
+
* // match: '/service2/api*sub',
|
|
49
|
+
* // proxy: {
|
|
50
|
+
* // target: 'http://example.org',
|
|
51
|
+
* // rewrite: (path) => path.replace('/service2', ''),
|
|
52
|
+
* // },
|
|
53
|
+
* // },
|
|
54
|
+
* // ]
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export const processServices: ApiDataProcessor<FusionService[]> = (data, args) => {
|
|
58
|
+
const { route, request } = args;
|
|
59
|
+
const apiRoutes = [] as ApiRoute[];
|
|
60
|
+
const apiServices = [] as FusionService[];
|
|
61
|
+
|
|
62
|
+
if (!Array.isArray(data)) {
|
|
63
|
+
throw new Error('Invalid data format');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// remap all services to proxy though the dev server
|
|
67
|
+
// and generate the proxy routes
|
|
68
|
+
for (const service of data as FusionService[]) {
|
|
69
|
+
// append host, port and protocol to the service uri
|
|
70
|
+
// and replace the path with the local proxy path
|
|
71
|
+
const serviceUrl = new URL(`${route}/${service.key}`, request.headers.referer);
|
|
72
|
+
apiServices.push({ ...service, uri: String(serviceUrl) });
|
|
73
|
+
|
|
74
|
+
// add the proxy route
|
|
75
|
+
const url = new URL(service.uri);
|
|
76
|
+
apiRoutes.push({
|
|
77
|
+
match: `/${service.key}${url.pathname}*sub`,
|
|
78
|
+
proxy: {
|
|
79
|
+
target: url.origin,
|
|
80
|
+
rewrite: (path) => path.replace(`/${service.key}`, ''),
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return { data: apiServices, routes: apiRoutes };
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default processServices;
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ApiDataProcessor, ApiRoute } from '@equinor/fusion-framework-vite-plugin-api-service';
|
|
2
|
+
import type { FusionTemplateEnv, TemplateEnvFn } from '@equinor/fusion-framework-vite-plugin-spa';
|
|
3
|
+
import type { ConsoleLogger } from '@equinor/fusion-log';
|
|
4
|
+
|
|
5
|
+
export type FusionService = {
|
|
6
|
+
key: string;
|
|
7
|
+
uri: string;
|
|
8
|
+
name: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
FusionTemplateEnv as TemplateEnv,
|
|
13
|
+
TemplateEnvFn,
|
|
14
|
+
} from '@equinor/fusion-framework-vite-plugin-spa';
|
|
15
|
+
|
|
16
|
+
export { UserConfig as DevServerOverrides } from 'vite';
|
|
17
|
+
|
|
18
|
+
export type DevServerOptions<TEnv extends Partial<FusionTemplateEnv> = Partial<FusionTemplateEnv>> =
|
|
19
|
+
{
|
|
20
|
+
spa?: {
|
|
21
|
+
templateEnv: TEnv | TemplateEnvFn<TEnv>;
|
|
22
|
+
};
|
|
23
|
+
api: {
|
|
24
|
+
/**
|
|
25
|
+
* The URL of the service discovery proxy endpoint.
|
|
26
|
+
*/
|
|
27
|
+
serviceDiscoveryUrl: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Route mapper for processing service discovery data.
|
|
31
|
+
*/
|
|
32
|
+
processServices?: ApiDataProcessor<FusionService[]>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Additional routes to be added to the API service proxy.
|
|
36
|
+
* @note used for overriding proxy responses and mocking services.
|
|
37
|
+
*/
|
|
38
|
+
routes?: ApiRoute[];
|
|
39
|
+
};
|
|
40
|
+
log?: {
|
|
41
|
+
level?: number;
|
|
42
|
+
logger?: ConsoleLogger;
|
|
43
|
+
};
|
|
44
|
+
server?: {
|
|
45
|
+
port?: number;
|
|
46
|
+
host?: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
package/src/version.ts
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": "src",
|
|
5
|
+
"outDir": "dist/esm",
|
|
6
|
+
"declarationDir": "./dist/types",
|
|
7
|
+
"baseUrl": "."
|
|
8
|
+
},
|
|
9
|
+
"references": [
|
|
10
|
+
{
|
|
11
|
+
"path": "../vite-plugins/api-service"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"path": "../vite-plugins/spa"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"include": ["src/**/*", "tests/*"],
|
|
18
|
+
"exclude": ["node_modules", "tests"]
|
|
19
|
+
}
|