@equinor/fusion-framework-vite-plugin-spa 3.1.12-next.0 → 4.0.1
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 +46 -8
- package/README.md +145 -138
- package/dist/esm/html/index.js +9 -0
- package/dist/esm/html/index.js.map +1 -1
- package/dist/esm/html/register-service-worker.js +30 -0
- package/dist/esm/html/register-service-worker.js.map +1 -1
- package/dist/esm/index.js +31 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/plugin.js +36 -1
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/util/load-env.js +14 -8
- package/dist/esm/util/load-env.js.map +1 -1
- package/dist/esm/util/object-to-env.js +19 -25
- package/dist/esm/util/object-to-env.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/html/bootstrap.js +834 -389
- package/dist/html/bootstrap.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/html/index.d.ts +9 -0
- package/dist/types/html/index.html.d.ts +1 -1
- package/dist/types/html/register-service-worker.d.ts +30 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/plugin.d.ts +75 -7
- package/dist/types/types.d.ts +98 -11
- package/dist/types/util/load-env.d.ts +14 -8
- package/dist/types/util/object-to-env.d.ts +19 -25
- package/dist/types/version.d.ts +1 -1
- package/package.json +9 -9
- package/src/html/index.ts +9 -0
- package/src/html/register-service-worker.ts +30 -0
- package/src/index.ts +31 -0
- package/src/plugin.ts +80 -8
- package/src/types.ts +100 -11
- package/src/util/load-env.ts +14 -8
- package/src/util/object-to-env.ts +19 -25
- package/src/version.ts +1 -1
|
@@ -1 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API surface of the `@equinor/fusion-framework-vite-plugin-spa/html`
|
|
3
|
+
* sub-path export.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Re-exports the {@link registerServiceWorker} function so that custom
|
|
7
|
+
* bootstrap files can register the SPA service worker without importing
|
|
8
|
+
* internal paths.
|
|
9
|
+
*/
|
|
1
10
|
export { registerServiceWorker } from './register-service-worker.js';
|
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
* @constant
|
|
16
16
|
* @type {string}
|
|
17
17
|
*/
|
|
18
|
-
export declare const html = "\n <!DOCTYPE html>\n <html>\n <head>\n <title>%FUSION_SPA_TITLE%</title>\n <meta name=\"mode\" content=\"%MODE%\">\n <meta name=\"fusion-spa-plugin-version\" content=\"
|
|
18
|
+
export declare const html = "\n <!DOCTYPE html>\n <html>\n <head>\n <title>%FUSION_SPA_TITLE%</title>\n <meta name=\"mode\" content=\"%MODE%\">\n <meta name=\"fusion-spa-plugin-version\" content=\"4.0.1\">\n <link rel=\"stylesheet\" href=\"https://cdn.eds.equinor.com/font/equinor-font.css\" />\n <script type=\"module\" src=\"%FUSION_SPA_BOOTSTRAP%\"></script>\n <script>\n // Set AG Grid license key globally if provided\n window.FUSION_AG_GRID_KEY = '%FUSION_SPA_AG_GRID_KEY%';\n \n // suppress console error for custom elements already defined. \n // WebComponents should be added by the portal, but not removed from application\n const _customElementsDefine = window.customElements.define;\n window.customElements.define = (name, cl, conf) => {\n if (!customElements.get(name)) {\n _customElementsDefine.call(window.customElements, name, cl, conf);\n }\n };\n </script>\n <style>\n html, body {\n margin: 0;\n padding: 0;\n height: 100%;\n font-family: 'EquinorFont', sans-serif;\n }\n </style>\n </head>\n <body></body>\n </html>\n";
|
|
19
19
|
export default html;
|
|
@@ -1,4 +1,34 @@
|
|
|
1
1
|
import type { ModulesInstance } from '@equinor/fusion-framework-module';
|
|
2
2
|
import type { MsalModule } from '@equinor/fusion-framework-module-msal';
|
|
3
3
|
import { type TelemetryModule } from '@equinor/fusion-framework-module-telemetry';
|
|
4
|
+
/**
|
|
5
|
+
* Registers the Fusion SPA service worker and wires token acquisition.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* The service worker intercepts outgoing fetch requests that match
|
|
9
|
+
* the configured {@link ResourceConfiguration | resource patterns},
|
|
10
|
+
* rewrites URLs, and injects Bearer tokens obtained from the MSAL
|
|
11
|
+
* module. This function:
|
|
12
|
+
*
|
|
13
|
+
* 1. Registers `/@fusion-spa-sw.js` as a module service worker.
|
|
14
|
+
* 2. Listens for `GET_TOKEN` messages from the worker and responds
|
|
15
|
+
* with MSAL access tokens.
|
|
16
|
+
* 3. Sends the `INIT_CONFIG` message containing resource configurations
|
|
17
|
+
* to the active worker once it is ready and controlling the page.
|
|
18
|
+
*
|
|
19
|
+
* @param framework - An initialized Fusion Framework instance that
|
|
20
|
+
* includes the {@link MsalModule} (for token acquisition) and
|
|
21
|
+
* {@link TelemetryModule} (for structured logging).
|
|
22
|
+
* @throws {Error} When service workers are not supported by the browser.
|
|
23
|
+
* @throws {Error} When the `FUSION_SPA_SERVICE_WORKER_RESOURCES`
|
|
24
|
+
* environment variable is not defined.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { registerServiceWorker } from '@equinor/fusion-framework-vite-plugin-spa/html';
|
|
29
|
+
*
|
|
30
|
+
* const framework = await configurator.initialize();
|
|
31
|
+
* await registerServiceWorker(framework);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
4
34
|
export declare function registerServiceWorker(framework: ModulesInstance<[MsalModule, TelemetryModule]>): Promise<void>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,2 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @equinor/fusion-framework-vite-plugin-spa
|
|
3
|
+
*
|
|
4
|
+
* Vite plugin for building Fusion Framework Single Page Applications (SPAs).
|
|
5
|
+
*
|
|
6
|
+
* Provides HTML template generation, MSAL authentication bootstrapping,
|
|
7
|
+
* service discovery wiring, portal loading, and authenticated API proxying
|
|
8
|
+
* via a service worker.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* This plugin is intended for non-production development environments and
|
|
12
|
+
* is designed for use with `@equinor/fusion-framework-cli`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { fusionSpaPlugin } from '@equinor/fusion-framework-vite-plugin-spa';
|
|
17
|
+
*
|
|
18
|
+
* export default defineConfig({
|
|
19
|
+
* plugins: [
|
|
20
|
+
* fusionSpaPlugin({
|
|
21
|
+
* generateTemplateEnv: () => ({
|
|
22
|
+
* title: 'My App',
|
|
23
|
+
* portal: { id: 'my-portal' },
|
|
24
|
+
* serviceDiscovery: { url: 'https://...', scopes: ['api://...'] },
|
|
25
|
+
* msal: { tenantId: '...', clientId: '...', redirectUri: '...' },
|
|
26
|
+
* }),
|
|
27
|
+
* }),
|
|
28
|
+
* ],
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
1
32
|
export { default, plugin as fusionSpaPlugin, type PluginOptions } from './plugin.js';
|
|
2
33
|
export * from './types.js';
|
package/dist/types/plugin.d.ts
CHANGED
|
@@ -1,21 +1,89 @@
|
|
|
1
1
|
import { type Plugin } from 'vite';
|
|
2
2
|
import type { TemplateEnv, TemplateEnvFn } from './types.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Options accepted by the Fusion SPA Vite plugin.
|
|
5
5
|
*
|
|
6
|
-
* @
|
|
6
|
+
* @remarks
|
|
7
|
+
* Controls HTML template generation, environment variable prefixing,
|
|
8
|
+
* and the factory that produces template environment values from the
|
|
9
|
+
* current Vite build/serve context.
|
|
7
10
|
*
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
* @
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* @template TEnv - Shape of the template environment. Defaults to {@link TemplateEnv}.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const opts: PluginOptions<FusionTemplateEnv> = {
|
|
16
|
+
* templateEnvPrefix: 'FUSION_SPA_',
|
|
17
|
+
* generateTemplateEnv: (env) => ({
|
|
18
|
+
* title: 'My App',
|
|
19
|
+
* portal: { id: 'my-portal' },
|
|
20
|
+
* serviceDiscovery: { url: '...', scopes: ['...'] },
|
|
21
|
+
* msal: { tenantId: '...', clientId: '...', redirectUri: '...' },
|
|
22
|
+
* }),
|
|
23
|
+
* };
|
|
24
|
+
* ```
|
|
13
25
|
*/
|
|
14
26
|
export type PluginOptions<TEnv extends TemplateEnv = TemplateEnv> = {
|
|
27
|
+
/**
|
|
28
|
+
* Custom HTML template string.
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* When omitted the plugin uses a built-in template that loads the
|
|
32
|
+
* bootstrap script, sets the page title, and includes the Equinor font.
|
|
33
|
+
*/
|
|
15
34
|
template?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Prefix used when reading environment variables from `.env` files.
|
|
37
|
+
*
|
|
38
|
+
* @defaultValue `'FUSION_SPA_'`
|
|
39
|
+
*/
|
|
16
40
|
templateEnvPrefix?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Factory that returns partial environment values merged with defaults
|
|
43
|
+
* and flattened into `{templateEnvPrefix}*` variables.
|
|
44
|
+
*
|
|
45
|
+
* @see {@link TemplateEnvFn}
|
|
46
|
+
*/
|
|
17
47
|
generateTemplateEnv?: TemplateEnvFn<TEnv>;
|
|
48
|
+
/**
|
|
49
|
+
* Optional logger used for plugin diagnostics during Vite config
|
|
50
|
+
* resolution.
|
|
51
|
+
*/
|
|
18
52
|
logger?: Pick<Console, 'debug' | 'info' | 'warn' | 'error'>;
|
|
19
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Creates the Fusion SPA Vite plugin.
|
|
56
|
+
*
|
|
57
|
+
* @remarks
|
|
58
|
+
* The plugin hooks into Vite's `config`, `resolveId`, and `configureServer`
|
|
59
|
+
* lifecycle to:
|
|
60
|
+
*
|
|
61
|
+
* 1. Flatten {@link PluginOptions.generateTemplateEnv | template env} values
|
|
62
|
+
* and `.env` overrides into `import.meta.env.FUSION_SPA_*` defines.
|
|
63
|
+
* 2. Resolve virtual module IDs (`/@fusion-spa-bootstrap.js`,
|
|
64
|
+
* `/@fusion-spa-sw.js`) to the package's pre-built HTML assets.
|
|
65
|
+
* 3. Serve the SPA HTML template for every `text/html` GET request
|
|
66
|
+
* (SPA fallback).
|
|
67
|
+
*
|
|
68
|
+
* @template TEnv - Shape of the template environment.
|
|
69
|
+
* @param options - Plugin configuration. See {@link PluginOptions}.
|
|
70
|
+
* @returns A Vite {@link Plugin} instance named `fusion-framework-plugin-spa`.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { plugin as fusionSpaPlugin } from '@equinor/fusion-framework-vite-plugin-spa';
|
|
75
|
+
*
|
|
76
|
+
* export default defineConfig({
|
|
77
|
+
* plugins: [
|
|
78
|
+
* fusionSpaPlugin({
|
|
79
|
+
* generateTemplateEnv: () => ({
|
|
80
|
+
* title: 'My App',
|
|
81
|
+
* portal: { id: 'my-portal' },
|
|
82
|
+
* }),
|
|
83
|
+
* }),
|
|
84
|
+
* ],
|
|
85
|
+
* });
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
20
88
|
export declare const plugin: <TEnv extends TemplateEnv = TemplateEnv>(options?: PluginOptions<TEnv>) => Plugin;
|
|
21
89
|
export default plugin;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,49 +1,136 @@
|
|
|
1
1
|
import type { ConfigEnv } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* Base type for template environment variables.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* A loose record that can hold any key-value pairs later flattened into
|
|
7
|
+
* `FUSION_SPA_*` environment variables by {@link objectToEnv}.
|
|
8
|
+
* Extend this type (or use {@link FusionTemplateEnv}) when you need a
|
|
9
|
+
* strongly-typed environment shape.
|
|
10
|
+
*/
|
|
2
11
|
export type TemplateEnv = Record<string, unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* Describes a single resource that the SPA service worker should intercept.
|
|
14
|
+
*
|
|
15
|
+
* When the service worker sees a fetch request whose URL starts with {@link url},
|
|
16
|
+
* it optionally rewrites the path and attaches an OAuth Bearer token obtained
|
|
17
|
+
* from the MSAL module for the specified {@link scopes}.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const resource: ResourceConfiguration = {
|
|
22
|
+
* url: '/app-proxy',
|
|
23
|
+
* rewrite: '/@fusion-api/app',
|
|
24
|
+
* scopes: ['api://backend/.default'],
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
3
28
|
export type ResourceConfiguration = {
|
|
29
|
+
/** URL path prefix to match against outgoing fetch requests. */
|
|
4
30
|
url: string;
|
|
31
|
+
/** OAuth scopes used to acquire a Bearer token for matched requests. */
|
|
5
32
|
scopes?: string[];
|
|
33
|
+
/** Replacement path prefix; the matched {@link url} segment is swapped for this value. */
|
|
6
34
|
rewrite?: string;
|
|
7
35
|
};
|
|
8
36
|
/**
|
|
9
|
-
*
|
|
37
|
+
* Strongly-typed environment configuration consumed by the default SPA
|
|
38
|
+
* HTML template and bootstrap script.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* Values are flattened to `FUSION_SPA_*` environment variables at build time
|
|
42
|
+
* and injected into the HTML template via Vite's
|
|
43
|
+
* {@link https://vite.dev/guide/env-and-mode.html#html-constant-replacement | constant replacement}.
|
|
44
|
+
* They can also be overridden through a `.env` file.
|
|
45
|
+
*
|
|
46
|
+
* @see {@link PluginOptions.generateTemplateEnv} for how to supply these values.
|
|
10
47
|
*/
|
|
11
48
|
export type FusionTemplateEnv = {
|
|
12
|
-
/**
|
|
49
|
+
/** HTML `<title>` for the generated page. */
|
|
13
50
|
title: string;
|
|
14
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Path to the bootstrap module loaded by the HTML template.
|
|
53
|
+
*
|
|
54
|
+
* @defaultValue `'/@fusion-spa-bootstrap.js'`
|
|
55
|
+
*/
|
|
15
56
|
bootstrap: string;
|
|
57
|
+
/** Optional telemetry configuration. */
|
|
16
58
|
telemetry?: {
|
|
59
|
+
/**
|
|
60
|
+
* Minimum severity level for console telemetry output.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* Maps to `TelemetryLevel` values: Debug (0), Information (1),
|
|
64
|
+
* Warning (2), Error (3), Critical (4).
|
|
65
|
+
*
|
|
66
|
+
* @defaultValue `1` (Information)
|
|
67
|
+
*/
|
|
17
68
|
consoleLevel?: number;
|
|
18
69
|
};
|
|
19
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Portal to load and render inside the SPA shell.
|
|
72
|
+
*
|
|
73
|
+
* @remarks
|
|
74
|
+
* The `id` can reference:
|
|
75
|
+
* - A local npm package (e.g. `@equinor/fusion-framework-dev-portal`)
|
|
76
|
+
* - A portal identifier from the Fusion Portal Service
|
|
77
|
+
* - Any custom portal implementation
|
|
78
|
+
*/
|
|
20
79
|
portal: {
|
|
80
|
+
/** Portal identifier used to fetch the portal manifest. */
|
|
21
81
|
id: string;
|
|
82
|
+
/**
|
|
83
|
+
* Version tag for the portal manifest.
|
|
84
|
+
* @defaultValue `'latest'`
|
|
85
|
+
*/
|
|
22
86
|
tag?: string;
|
|
87
|
+
/**
|
|
88
|
+
* When `true`, portal entry point requests are prefixed with `/portal-proxy`
|
|
89
|
+
* so they can be intercepted by a proxy server.
|
|
90
|
+
* @defaultValue `false`
|
|
91
|
+
*/
|
|
23
92
|
proxy?: boolean;
|
|
24
93
|
};
|
|
25
|
-
/** Service discovery
|
|
94
|
+
/** Service discovery endpoint and authentication scopes. */
|
|
26
95
|
serviceDiscovery: {
|
|
96
|
+
/** URL of the Fusion service discovery endpoint. */
|
|
27
97
|
url: string;
|
|
98
|
+
/** OAuth scopes required to authenticate service discovery requests. */
|
|
28
99
|
scopes: string[];
|
|
29
100
|
};
|
|
30
|
-
/** MSAL configuration */
|
|
101
|
+
/** Microsoft Authentication Library (MSAL) configuration for Azure AD. */
|
|
31
102
|
msal: {
|
|
103
|
+
/** Azure AD tenant identifier. */
|
|
32
104
|
tenantId: string;
|
|
105
|
+
/** Application (client) identifier registered in Azure AD. */
|
|
33
106
|
clientId: string;
|
|
107
|
+
/** Redirect URI for the authentication callback. */
|
|
34
108
|
redirectUri: string;
|
|
109
|
+
/**
|
|
110
|
+
* When `'true'`, the application automatically prompts for login
|
|
111
|
+
* on initial load.
|
|
112
|
+
*/
|
|
35
113
|
requiresAuth: string;
|
|
36
114
|
};
|
|
37
|
-
/** Service worker configuration */
|
|
115
|
+
/** Service worker resource interception configuration. */
|
|
38
116
|
serviceWorker: {
|
|
117
|
+
/**
|
|
118
|
+
* Array of resource configurations the service worker will manage.
|
|
119
|
+
* @see {@link ResourceConfiguration}
|
|
120
|
+
*/
|
|
39
121
|
resources: ResourceConfiguration[];
|
|
40
122
|
};
|
|
41
123
|
};
|
|
42
124
|
/**
|
|
43
|
-
*
|
|
125
|
+
* Factory function that produces a partial template environment from the
|
|
126
|
+
* current Vite {@link ConfigEnv} (mode, command, etc.).
|
|
127
|
+
*
|
|
128
|
+
* @remarks
|
|
129
|
+
* Returned values are merged with defaults and flattened into
|
|
130
|
+
* `FUSION_SPA_*` environment variables.
|
|
44
131
|
*
|
|
45
|
-
* @template TEnv -
|
|
46
|
-
* @param configEnv -
|
|
47
|
-
* @returns A partial environment
|
|
132
|
+
* @template TEnv - Shape of the environment configuration. Defaults to {@link TemplateEnv}.
|
|
133
|
+
* @param configEnv - Vite configuration environment containing `mode` and `command`.
|
|
134
|
+
* @returns A partial environment object, or `undefined` to use defaults only.
|
|
48
135
|
*/
|
|
49
136
|
export type TemplateEnvFn<TEnv extends TemplateEnv> = (configEnv: ConfigEnv) => Partial<TEnv> | undefined;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { type ConfigEnv, type UserConfig } from 'vite';
|
|
2
2
|
/**
|
|
3
|
-
* Loads environment variables
|
|
3
|
+
* Loads environment variables from `.env` files for the Fusion SPA plugin.
|
|
4
4
|
*
|
|
5
|
-
* @
|
|
5
|
+
* @remarks
|
|
6
|
+
* Delegates to Vite's {@link https://vite.dev/guide/env-and-mode.html#env-files | loadEnv}
|
|
7
|
+
* using the resolved project root and env directory. Only variables whose
|
|
8
|
+
* name starts with {@link namespace} are returned.
|
|
6
9
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @param
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
10
|
+
* Values loaded here override any matching keys produced by
|
|
11
|
+
* {@link PluginOptions.generateTemplateEnv}.
|
|
12
|
+
*
|
|
13
|
+
* @param config - Vite user configuration (`root`, `envDir`).
|
|
14
|
+
* @param env - Vite configuration environment containing the current `mode`.
|
|
15
|
+
* @param namespace - Variable name prefix to filter on.
|
|
16
|
+
* @returns A flat record of matching environment variable names to their string values.
|
|
17
|
+
*
|
|
18
|
+
* @defaultValue namespace — `'FUSION_SPA_'`
|
|
13
19
|
*/
|
|
14
20
|
export declare function loadEnvironment(config: UserConfig, env: ConfigEnv, namespace?: string): Record<string, string>;
|
|
15
21
|
export default loadEnvironment;
|
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Non-object values are stringified.
|
|
2
|
+
* Flattens a nested object into a single-level record with
|
|
3
|
+
* `UPPER_SNAKE_CASE` keys suitable for Vite's `config.define`.
|
|
5
4
|
*
|
|
6
|
-
* @
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Used internally by the Fusion SPA plugin to convert the object
|
|
7
|
+
* returned by {@link PluginOptions.generateTemplateEnv} into
|
|
8
|
+
* `import.meta.env.*` defines.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* finalKey: true
|
|
18
|
-
* }
|
|
19
|
-
* }
|
|
20
|
-
* };
|
|
10
|
+
* - camelCase keys are converted to UPPER_SNAKE_CASE.
|
|
11
|
+
* - Nested objects are recursively flattened with `_` separators.
|
|
12
|
+
* - Arrays and primitives are JSON-stringified.
|
|
13
|
+
*
|
|
14
|
+
* @param obj - The object to flatten.
|
|
15
|
+
* @param prefix - Key prefix prepended to every output key.
|
|
16
|
+
* @returns A flat record mapping `PREFIX_KEY` strings to JSON-stringified values.
|
|
21
17
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* //
|
|
28
|
-
* // NESTED_OBJECT_DEEP_NESTED_FINAL_KEY: "true"
|
|
29
|
-
* // }
|
|
18
|
+
* @defaultValue prefix — `'FUSION_SPA'`
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* objectToEnv({ portal: { id: 'my-portal' } }, 'FUSION_SPA');
|
|
23
|
+
* // => { FUSION_SPA_PORTAL_ID: '"my-portal"' }
|
|
30
24
|
* ```
|
|
31
25
|
*/
|
|
32
26
|
export declare function objectToEnv(obj: object, prefix?: string): Record<string, string>;
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "
|
|
1
|
+
export declare const version = "4.0.1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-vite-plugin-spa",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Vite plugin for SPA development",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -37,19 +37,19 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@equinor/fusion-framework-module": "
|
|
41
|
-
"@equinor/fusion-framework-module-http": "
|
|
42
|
-
"@equinor/fusion-framework-module-
|
|
43
|
-
"@equinor/fusion-framework-module-
|
|
44
|
-
"@equinor/fusion-framework-module-telemetry": "
|
|
40
|
+
"@equinor/fusion-framework-module": "6.0.0",
|
|
41
|
+
"@equinor/fusion-framework-module-http": "8.0.0",
|
|
42
|
+
"@equinor/fusion-framework-module-msal": "8.0.1",
|
|
43
|
+
"@equinor/fusion-framework-module-service-discovery": "10.0.0",
|
|
44
|
+
"@equinor/fusion-framework-module-telemetry": "5.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
48
48
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
49
49
|
"@rollup/plugin-typescript": "^12.1.2",
|
|
50
|
-
"rollup": "^4.
|
|
51
|
-
"typescript": "^5.
|
|
52
|
-
"vite": "^
|
|
50
|
+
"rollup": "^4.59.0",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vite": "^8.0.0"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsc -b",
|
package/src/html/index.ts
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API surface of the `@equinor/fusion-framework-vite-plugin-spa/html`
|
|
3
|
+
* sub-path export.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Re-exports the {@link registerServiceWorker} function so that custom
|
|
7
|
+
* bootstrap files can register the SPA service worker without importing
|
|
8
|
+
* internal paths.
|
|
9
|
+
*/
|
|
1
10
|
export { registerServiceWorker } from './register-service-worker.js';
|
|
@@ -2,6 +2,36 @@ import type { ModulesInstance } from '@equinor/fusion-framework-module';
|
|
|
2
2
|
import type { MsalModule } from '@equinor/fusion-framework-module-msal';
|
|
3
3
|
import { TelemetryLevel, type TelemetryModule } from '@equinor/fusion-framework-module-telemetry';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Registers the Fusion SPA service worker and wires token acquisition.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* The service worker intercepts outgoing fetch requests that match
|
|
10
|
+
* the configured {@link ResourceConfiguration | resource patterns},
|
|
11
|
+
* rewrites URLs, and injects Bearer tokens obtained from the MSAL
|
|
12
|
+
* module. This function:
|
|
13
|
+
*
|
|
14
|
+
* 1. Registers `/@fusion-spa-sw.js` as a module service worker.
|
|
15
|
+
* 2. Listens for `GET_TOKEN` messages from the worker and responds
|
|
16
|
+
* with MSAL access tokens.
|
|
17
|
+
* 3. Sends the `INIT_CONFIG` message containing resource configurations
|
|
18
|
+
* to the active worker once it is ready and controlling the page.
|
|
19
|
+
*
|
|
20
|
+
* @param framework - An initialized Fusion Framework instance that
|
|
21
|
+
* includes the {@link MsalModule} (for token acquisition) and
|
|
22
|
+
* {@link TelemetryModule} (for structured logging).
|
|
23
|
+
* @throws {Error} When service workers are not supported by the browser.
|
|
24
|
+
* @throws {Error} When the `FUSION_SPA_SERVICE_WORKER_RESOURCES`
|
|
25
|
+
* environment variable is not defined.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { registerServiceWorker } from '@equinor/fusion-framework-vite-plugin-spa/html';
|
|
30
|
+
*
|
|
31
|
+
* const framework = await configurator.initialize();
|
|
32
|
+
* await registerServiceWorker(framework);
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
5
35
|
export async function registerServiceWorker(
|
|
6
36
|
framework: ModulesInstance<[MsalModule, TelemetryModule]>,
|
|
7
37
|
) {
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @equinor/fusion-framework-vite-plugin-spa
|
|
3
|
+
*
|
|
4
|
+
* Vite plugin for building Fusion Framework Single Page Applications (SPAs).
|
|
5
|
+
*
|
|
6
|
+
* Provides HTML template generation, MSAL authentication bootstrapping,
|
|
7
|
+
* service discovery wiring, portal loading, and authenticated API proxying
|
|
8
|
+
* via a service worker.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* This plugin is intended for non-production development environments and
|
|
12
|
+
* is designed for use with `@equinor/fusion-framework-cli`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { fusionSpaPlugin } from '@equinor/fusion-framework-vite-plugin-spa';
|
|
17
|
+
*
|
|
18
|
+
* export default defineConfig({
|
|
19
|
+
* plugins: [
|
|
20
|
+
* fusionSpaPlugin({
|
|
21
|
+
* generateTemplateEnv: () => ({
|
|
22
|
+
* title: 'My App',
|
|
23
|
+
* portal: { id: 'my-portal' },
|
|
24
|
+
* serviceDiscovery: { url: 'https://...', scopes: ['api://...'] },
|
|
25
|
+
* msal: { tenantId: '...', clientId: '...', redirectUri: '...' },
|
|
26
|
+
* }),
|
|
27
|
+
* }),
|
|
28
|
+
* ],
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
1
32
|
export { default, plugin as fusionSpaPlugin, type PluginOptions } from './plugin.js';
|
|
2
33
|
|
|
3
34
|
export * from './types.js';
|
package/src/plugin.ts
CHANGED
|
@@ -10,31 +10,103 @@ import { loadEnvironment } from './util/load-env.js';
|
|
|
10
10
|
import type { TemplateEnv, TemplateEnvFn } from './types.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Options accepted by the Fusion SPA Vite plugin.
|
|
14
14
|
*
|
|
15
|
-
* @
|
|
15
|
+
* @remarks
|
|
16
|
+
* Controls HTML template generation, environment variable prefixing,
|
|
17
|
+
* and the factory that produces template environment values from the
|
|
18
|
+
* current Vite build/serve context.
|
|
16
19
|
*
|
|
17
|
-
* @
|
|
18
|
-
*
|
|
19
|
-
* @
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* @template TEnv - Shape of the template environment. Defaults to {@link TemplateEnv}.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const opts: PluginOptions<FusionTemplateEnv> = {
|
|
25
|
+
* templateEnvPrefix: 'FUSION_SPA_',
|
|
26
|
+
* generateTemplateEnv: (env) => ({
|
|
27
|
+
* title: 'My App',
|
|
28
|
+
* portal: { id: 'my-portal' },
|
|
29
|
+
* serviceDiscovery: { url: '...', scopes: ['...'] },
|
|
30
|
+
* msal: { tenantId: '...', clientId: '...', redirectUri: '...' },
|
|
31
|
+
* }),
|
|
32
|
+
* };
|
|
33
|
+
* ```
|
|
22
34
|
*/
|
|
23
35
|
export type PluginOptions<TEnv extends TemplateEnv = TemplateEnv> = {
|
|
36
|
+
/**
|
|
37
|
+
* Custom HTML template string.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* When omitted the plugin uses a built-in template that loads the
|
|
41
|
+
* bootstrap script, sets the page title, and includes the Equinor font.
|
|
42
|
+
*/
|
|
24
43
|
template?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Prefix used when reading environment variables from `.env` files.
|
|
47
|
+
*
|
|
48
|
+
* @defaultValue `'FUSION_SPA_'`
|
|
49
|
+
*/
|
|
25
50
|
templateEnvPrefix?: string;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Factory that returns partial environment values merged with defaults
|
|
54
|
+
* and flattened into `{templateEnvPrefix}*` variables.
|
|
55
|
+
*
|
|
56
|
+
* @see {@link TemplateEnvFn}
|
|
57
|
+
*/
|
|
26
58
|
generateTemplateEnv?: TemplateEnvFn<TEnv>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Optional logger used for plugin diagnostics during Vite config
|
|
62
|
+
* resolution.
|
|
63
|
+
*/
|
|
27
64
|
logger?: Pick<Console, 'debug' | 'info' | 'warn' | 'error'>;
|
|
28
65
|
};
|
|
29
66
|
|
|
30
67
|
/**
|
|
31
|
-
*
|
|
68
|
+
* Built-in defaults applied when no matching value is provided by
|
|
69
|
+
* {@link PluginOptions.generateTemplateEnv} or `.env` files.
|
|
32
70
|
*/
|
|
33
71
|
const defaultEnv: Partial<TemplateEnv> = {
|
|
34
72
|
title: 'Fusion SPA',
|
|
35
73
|
bootstrap: '/@fusion-spa-bootstrap.js',
|
|
36
74
|
};
|
|
37
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Creates the Fusion SPA Vite plugin.
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* The plugin hooks into Vite's `config`, `resolveId`, and `configureServer`
|
|
81
|
+
* lifecycle to:
|
|
82
|
+
*
|
|
83
|
+
* 1. Flatten {@link PluginOptions.generateTemplateEnv | template env} values
|
|
84
|
+
* and `.env` overrides into `import.meta.env.FUSION_SPA_*` defines.
|
|
85
|
+
* 2. Resolve virtual module IDs (`/@fusion-spa-bootstrap.js`,
|
|
86
|
+
* `/@fusion-spa-sw.js`) to the package's pre-built HTML assets.
|
|
87
|
+
* 3. Serve the SPA HTML template for every `text/html` GET request
|
|
88
|
+
* (SPA fallback).
|
|
89
|
+
*
|
|
90
|
+
* @template TEnv - Shape of the template environment.
|
|
91
|
+
* @param options - Plugin configuration. See {@link PluginOptions}.
|
|
92
|
+
* @returns A Vite {@link Plugin} instance named `fusion-framework-plugin-spa`.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* import { plugin as fusionSpaPlugin } from '@equinor/fusion-framework-vite-plugin-spa';
|
|
97
|
+
*
|
|
98
|
+
* export default defineConfig({
|
|
99
|
+
* plugins: [
|
|
100
|
+
* fusionSpaPlugin({
|
|
101
|
+
* generateTemplateEnv: () => ({
|
|
102
|
+
* title: 'My App',
|
|
103
|
+
* portal: { id: 'my-portal' },
|
|
104
|
+
* }),
|
|
105
|
+
* }),
|
|
106
|
+
* ],
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
38
110
|
export const plugin = <TEnv extends TemplateEnv = TemplateEnv>(
|
|
39
111
|
options?: PluginOptions<TEnv>,
|
|
40
112
|
): Plugin => {
|