@viasoftbr/shared-ui 0.0.4 → 0.0.6

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.
@@ -1,4 +1,5 @@
1
1
  import { ProtocolSettings } from '../types/protocol';
2
+ import { WebSocketSubscribeOptions } from '../types/websocket';
2
3
  export declare const api: import("axios").AxiosInstance;
3
4
  export declare const authApi: import("axios").AxiosInstance;
4
5
  export declare function getAccessToken(): string | null;
@@ -19,4 +20,4 @@ export declare const fetchApi: {
19
20
  export declare function buildWsUrl(path?: string): string;
20
21
  export declare function encodeFfurl(settings: ProtocolSettings): Promise<string>;
21
22
  export declare function decodeFfurl(ffurl: string): Promise<ProtocolSettings>;
22
- export declare function subscribeToWebsocket(url: string, onMessage: (data: any) => void): () => void;
23
+ export declare function subscribeToWebsocket(url: string, onMessage: (data: any) => void, options?: WebSocketSubscribeOptions): () => void;
@@ -1,7 +1,5 @@
1
1
  export * from './api';
2
2
  export * from './auth';
3
- export * from './loadRemoteModule';
4
- export * from './metadataLoader';
5
3
  export * from './registry';
6
4
  export * from './hostConfig';
7
5
  export * from './users';
package/dist/services.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
7
  var __export = (target, all3) => {
@@ -18,14 +16,6 @@ var __copyProps = (to, from, except, desc) => {
18
16
  }
19
17
  return to;
20
18
  };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
20
  var __publicField = (obj, key, value) => {
31
21
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -35,7 +25,6 @@ var __publicField = (obj, key, value) => {
35
25
  // src/services/index.ts
36
26
  var services_exports = {};
37
27
  __export(services_exports, {
38
- MetadataLoader: () => MetadataLoader,
39
28
  api: () => api,
40
29
  authApi: () => authApi,
41
30
  authService: () => authService,
@@ -50,8 +39,6 @@ __export(services_exports, {
50
39
  getRefreshToken: () => getRefreshToken,
51
40
  hostConfigLoader: () => hostConfigLoader,
52
41
  isFirstRun: () => isFirstRun,
53
- loadRemoteModule: () => loadRemoteModule,
54
- metadataLoader: () => metadataLoader,
55
42
  registry: () => registry,
56
43
  saveConfig: () => saveConfig,
57
44
  setAccessToken: () => setAccessToken,
@@ -2900,6 +2887,35 @@ function buildWsUrl(path = "/") {
2900
2887
  return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
2901
2888
  }
2902
2889
  }
2890
+ function extractBearerToken(headers, explicitToken) {
2891
+ if (explicitToken)
2892
+ return explicitToken;
2893
+ if (!headers)
2894
+ return null;
2895
+ const authHeader = headers.Authorization || headers.authorization;
2896
+ if (!authHeader)
2897
+ return null;
2898
+ const match = authHeader.match(/^Bearer\s+(.+)$/i);
2899
+ return match ? match[1] : null;
2900
+ }
2901
+ function appendWsQueryParam(url, key, value) {
2902
+ try {
2903
+ const parsed = new URL(
2904
+ url,
2905
+ typeof window !== "undefined" ? window.location.href : void 0
2906
+ );
2907
+ parsed.searchParams.set(key, value);
2908
+ return parsed.toString();
2909
+ } catch {
2910
+ const separator = url.includes("?") ? "&" : "?";
2911
+ return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
2912
+ }
2913
+ }
2914
+ function normalizeProtocols(protocols) {
2915
+ if (!protocols)
2916
+ return void 0;
2917
+ return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
2918
+ }
2903
2919
  async function encodeFfurl(settings) {
2904
2920
  const { ffurl } = await fetchApi.postJson("/auth/protocols/ffurl/encode", settings);
2905
2921
  return ffurl;
@@ -2908,8 +2924,28 @@ async function decodeFfurl(ffurl) {
2908
2924
  const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
2909
2925
  return settings;
2910
2926
  }
2911
- function subscribeToWebsocket(url, onMessage) {
2912
- const socket = new WebSocket(url);
2927
+ function subscribeToWebsocket(url, onMessage, options = {}) {
2928
+ const bearerToken = extractBearerToken(options.headers, options.bearerToken);
2929
+ const bearerStrategy = options.bearerStrategy ?? "query";
2930
+ let resolvedUrl = url;
2931
+ const protocols = normalizeProtocols(options.protocols) ?? [];
2932
+ if (options.headers && Object.keys(options.headers).length > 0) {
2933
+ console.warn(
2934
+ "WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
2935
+ );
2936
+ }
2937
+ if (bearerToken) {
2938
+ if (bearerStrategy === "protocol") {
2939
+ protocols.push("bearer", bearerToken);
2940
+ } else {
2941
+ resolvedUrl = appendWsQueryParam(
2942
+ url,
2943
+ options.bearerQueryParam ?? "access_token",
2944
+ bearerToken
2945
+ );
2946
+ }
2947
+ }
2948
+ const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
2913
2949
  socket.onmessage = (event) => {
2914
2950
  try {
2915
2951
  const data = JSON.parse(event.data);
@@ -2960,140 +2996,6 @@ var authService = {
2960
2996
  }
2961
2997
  };
2962
2998
 
2963
- // src/services/loadRemoteModule.ts
2964
- var React = __toESM(require("react"), 1);
2965
- var ReactDOM = __toESM(require("react-dom"), 1);
2966
- var sharedScopeInitialized = false;
2967
- function getSharedScope() {
2968
- if (!globalThis.__federation_shared__) {
2969
- globalThis.__federation_shared__ = {};
2970
- }
2971
- if (!sharedScopeInitialized) {
2972
- globalThis.__federation_shared__["react"] = {
2973
- "18.3.1": {
2974
- get: () => Promise.resolve(() => React),
2975
- loaded: true,
2976
- from: "core",
2977
- scope: "default"
2978
- }
2979
- };
2980
- globalThis.__federation_shared__["react-dom"] = {
2981
- "18.3.1": {
2982
- get: () => Promise.resolve(() => ReactDOM),
2983
- loaded: true,
2984
- from: "core",
2985
- scope: "default"
2986
- }
2987
- };
2988
- sharedScopeInitialized = true;
2989
- }
2990
- return globalThis.__federation_shared__;
2991
- }
2992
- var loadedContainers = /* @__PURE__ */ new Map();
2993
- var initializedContainers = /* @__PURE__ */ new Set();
2994
- async function loadContainer(url) {
2995
- if (loadedContainers.has(url)) {
2996
- return loadedContainers.get(url);
2997
- }
2998
- const loadPromise = (async () => {
2999
- try {
3000
- const container = await import(
3001
- /* @vite-ignore */
3002
- url
3003
- );
3004
- if (container.init && !initializedContainers.has(url)) {
3005
- await container.init(getSharedScope());
3006
- initializedContainers.add(url);
3007
- }
3008
- return container;
3009
- } catch (error) {
3010
- loadedContainers.delete(url);
3011
- initializedContainers.delete(url);
3012
- throw error;
3013
- }
3014
- })();
3015
- loadedContainers.set(url, loadPromise);
3016
- return loadPromise;
3017
- }
3018
- async function loadRemoteModule(config) {
3019
- const container = await loadContainer(config.url);
3020
- if (!container || typeof container.get !== "function") {
3021
- throw new Error(`Container inv\xE1lido ou sem m\xE9todo get: ${config.scope}`);
3022
- }
3023
- if (typeof container.dynamicLoadingCss === "function") {
3024
- try {
3025
- await container.dynamicLoadingCss([]);
3026
- } catch (err) {
3027
- console.warn(`Aviso: Falha ao carregar CSS global do remote ${config.scope}`, err);
3028
- }
3029
- }
3030
- const factory2 = await container.get(config.module);
3031
- const moduleExports = await factory2();
3032
- if (moduleExports && typeof moduleExports === "object" && "default" in moduleExports) {
3033
- return moduleExports.default;
3034
- }
3035
- return moduleExports;
3036
- }
3037
-
3038
- // src/services/metadataLoader.ts
3039
- var MetadataLoader = class {
3040
- constructor() {
3041
- __publicField(this, "metadataCache", /* @__PURE__ */ new Map());
3042
- }
3043
- async loadMetadata(metadataUrl) {
3044
- if (this.metadataCache.has(metadataUrl)) {
3045
- return this.metadataCache.get(metadataUrl) || [];
3046
- }
3047
- try {
3048
- const response = await fetch(metadataUrl);
3049
- console.log(response);
3050
- if (!response.ok) {
3051
- throw new Error(`Failed to fetch metadata: ${response.statusText}`);
3052
- }
3053
- const data = await response.json();
3054
- let metadata;
3055
- if (Array.isArray(data)) {
3056
- metadata = data;
3057
- } else if (data.pages && Array.isArray(data.pages)) {
3058
- metadata = data.pages;
3059
- } else {
3060
- throw new Error(
3061
- "Invalid metadata format: expected array or object with pages property"
3062
- );
3063
- }
3064
- metadata.forEach((page, index) => {
3065
- if (!page.id || !page.name || !page.path || !page.url) {
3066
- throw new Error(
3067
- `Invalid page metadata at index ${index}: missing required fields`
3068
- );
3069
- }
3070
- });
3071
- this.metadataCache.set(metadataUrl, metadata);
3072
- return metadata;
3073
- } catch (error) {
3074
- console.warn(`Failed to load metadata from ${metadataUrl}:`, error);
3075
- return [];
3076
- }
3077
- }
3078
- async loadFromDirectory(directoryUrl) {
3079
- try {
3080
- const manifestUrl = `${directoryUrl}/manifest.json`;
3081
- return await this.loadMetadata(manifestUrl);
3082
- } catch (error) {
3083
- throw new Error(
3084
- `Directory manifest not found at ${directoryUrl}/manifest.json: ${error}`
3085
- );
3086
- }
3087
- }
3088
- clearCache() {
3089
- this.metadataCache.clear();
3090
- }
3091
- getCachedMetadata(metadataUrl) {
3092
- return this.metadataCache.get(metadataUrl);
3093
- }
3094
- };
3095
- var metadataLoader = new MetadataLoader();
3096
-
3097
2999
  // src/services/registry.ts
3098
3000
  var PluginRegistryImpl = class {
3099
3001
  constructor() {
package/dist/services.js CHANGED
@@ -2847,6 +2847,35 @@ function buildWsUrl(path = "/") {
2847
2847
  return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
2848
2848
  }
2849
2849
  }
2850
+ function extractBearerToken(headers, explicitToken) {
2851
+ if (explicitToken)
2852
+ return explicitToken;
2853
+ if (!headers)
2854
+ return null;
2855
+ const authHeader = headers.Authorization || headers.authorization;
2856
+ if (!authHeader)
2857
+ return null;
2858
+ const match = authHeader.match(/^Bearer\s+(.+)$/i);
2859
+ return match ? match[1] : null;
2860
+ }
2861
+ function appendWsQueryParam(url, key, value) {
2862
+ try {
2863
+ const parsed = new URL(
2864
+ url,
2865
+ typeof window !== "undefined" ? window.location.href : void 0
2866
+ );
2867
+ parsed.searchParams.set(key, value);
2868
+ return parsed.toString();
2869
+ } catch {
2870
+ const separator = url.includes("?") ? "&" : "?";
2871
+ return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
2872
+ }
2873
+ }
2874
+ function normalizeProtocols(protocols) {
2875
+ if (!protocols)
2876
+ return void 0;
2877
+ return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
2878
+ }
2850
2879
  async function encodeFfurl(settings) {
2851
2880
  const { ffurl } = await fetchApi.postJson("/auth/protocols/ffurl/encode", settings);
2852
2881
  return ffurl;
@@ -2855,8 +2884,28 @@ async function decodeFfurl(ffurl) {
2855
2884
  const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
2856
2885
  return settings;
2857
2886
  }
2858
- function subscribeToWebsocket(url, onMessage) {
2859
- const socket = new WebSocket(url);
2887
+ function subscribeToWebsocket(url, onMessage, options = {}) {
2888
+ const bearerToken = extractBearerToken(options.headers, options.bearerToken);
2889
+ const bearerStrategy = options.bearerStrategy ?? "query";
2890
+ let resolvedUrl = url;
2891
+ const protocols = normalizeProtocols(options.protocols) ?? [];
2892
+ if (options.headers && Object.keys(options.headers).length > 0) {
2893
+ console.warn(
2894
+ "WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
2895
+ );
2896
+ }
2897
+ if (bearerToken) {
2898
+ if (bearerStrategy === "protocol") {
2899
+ protocols.push("bearer", bearerToken);
2900
+ } else {
2901
+ resolvedUrl = appendWsQueryParam(
2902
+ url,
2903
+ options.bearerQueryParam ?? "access_token",
2904
+ bearerToken
2905
+ );
2906
+ }
2907
+ }
2908
+ const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
2860
2909
  socket.onmessage = (event) => {
2861
2910
  try {
2862
2911
  const data = JSON.parse(event.data);
@@ -2907,140 +2956,6 @@ var authService = {
2907
2956
  }
2908
2957
  };
2909
2958
 
2910
- // src/services/loadRemoteModule.ts
2911
- import * as React from "react";
2912
- import * as ReactDOM from "react-dom";
2913
- var sharedScopeInitialized = false;
2914
- function getSharedScope() {
2915
- if (!globalThis.__federation_shared__) {
2916
- globalThis.__federation_shared__ = {};
2917
- }
2918
- if (!sharedScopeInitialized) {
2919
- globalThis.__federation_shared__["react"] = {
2920
- "18.3.1": {
2921
- get: () => Promise.resolve(() => React),
2922
- loaded: true,
2923
- from: "core",
2924
- scope: "default"
2925
- }
2926
- };
2927
- globalThis.__federation_shared__["react-dom"] = {
2928
- "18.3.1": {
2929
- get: () => Promise.resolve(() => ReactDOM),
2930
- loaded: true,
2931
- from: "core",
2932
- scope: "default"
2933
- }
2934
- };
2935
- sharedScopeInitialized = true;
2936
- }
2937
- return globalThis.__federation_shared__;
2938
- }
2939
- var loadedContainers = /* @__PURE__ */ new Map();
2940
- var initializedContainers = /* @__PURE__ */ new Set();
2941
- async function loadContainer(url) {
2942
- if (loadedContainers.has(url)) {
2943
- return loadedContainers.get(url);
2944
- }
2945
- const loadPromise = (async () => {
2946
- try {
2947
- const container = await import(
2948
- /* @vite-ignore */
2949
- url
2950
- );
2951
- if (container.init && !initializedContainers.has(url)) {
2952
- await container.init(getSharedScope());
2953
- initializedContainers.add(url);
2954
- }
2955
- return container;
2956
- } catch (error) {
2957
- loadedContainers.delete(url);
2958
- initializedContainers.delete(url);
2959
- throw error;
2960
- }
2961
- })();
2962
- loadedContainers.set(url, loadPromise);
2963
- return loadPromise;
2964
- }
2965
- async function loadRemoteModule(config) {
2966
- const container = await loadContainer(config.url);
2967
- if (!container || typeof container.get !== "function") {
2968
- throw new Error(`Container inv\xE1lido ou sem m\xE9todo get: ${config.scope}`);
2969
- }
2970
- if (typeof container.dynamicLoadingCss === "function") {
2971
- try {
2972
- await container.dynamicLoadingCss([]);
2973
- } catch (err) {
2974
- console.warn(`Aviso: Falha ao carregar CSS global do remote ${config.scope}`, err);
2975
- }
2976
- }
2977
- const factory2 = await container.get(config.module);
2978
- const moduleExports = await factory2();
2979
- if (moduleExports && typeof moduleExports === "object" && "default" in moduleExports) {
2980
- return moduleExports.default;
2981
- }
2982
- return moduleExports;
2983
- }
2984
-
2985
- // src/services/metadataLoader.ts
2986
- var MetadataLoader = class {
2987
- constructor() {
2988
- __publicField(this, "metadataCache", /* @__PURE__ */ new Map());
2989
- }
2990
- async loadMetadata(metadataUrl) {
2991
- if (this.metadataCache.has(metadataUrl)) {
2992
- return this.metadataCache.get(metadataUrl) || [];
2993
- }
2994
- try {
2995
- const response = await fetch(metadataUrl);
2996
- console.log(response);
2997
- if (!response.ok) {
2998
- throw new Error(`Failed to fetch metadata: ${response.statusText}`);
2999
- }
3000
- const data = await response.json();
3001
- let metadata;
3002
- if (Array.isArray(data)) {
3003
- metadata = data;
3004
- } else if (data.pages && Array.isArray(data.pages)) {
3005
- metadata = data.pages;
3006
- } else {
3007
- throw new Error(
3008
- "Invalid metadata format: expected array or object with pages property"
3009
- );
3010
- }
3011
- metadata.forEach((page, index) => {
3012
- if (!page.id || !page.name || !page.path || !page.url) {
3013
- throw new Error(
3014
- `Invalid page metadata at index ${index}: missing required fields`
3015
- );
3016
- }
3017
- });
3018
- this.metadataCache.set(metadataUrl, metadata);
3019
- return metadata;
3020
- } catch (error) {
3021
- console.warn(`Failed to load metadata from ${metadataUrl}:`, error);
3022
- return [];
3023
- }
3024
- }
3025
- async loadFromDirectory(directoryUrl) {
3026
- try {
3027
- const manifestUrl = `${directoryUrl}/manifest.json`;
3028
- return await this.loadMetadata(manifestUrl);
3029
- } catch (error) {
3030
- throw new Error(
3031
- `Directory manifest not found at ${directoryUrl}/manifest.json: ${error}`
3032
- );
3033
- }
3034
- }
3035
- clearCache() {
3036
- this.metadataCache.clear();
3037
- }
3038
- getCachedMetadata(metadataUrl) {
3039
- return this.metadataCache.get(metadataUrl);
3040
- }
3041
- };
3042
- var metadataLoader = new MetadataLoader();
3043
-
3044
2959
  // src/services/registry.ts
3045
2960
  var PluginRegistryImpl = class {
3046
2961
  constructor() {
@@ -3217,7 +3132,6 @@ var discoveryService = {
3217
3132
  }
3218
3133
  };
3219
3134
  export {
3220
- MetadataLoader,
3221
3135
  api,
3222
3136
  authApi,
3223
3137
  authService,
@@ -3232,8 +3146,6 @@ export {
3232
3146
  getRefreshToken,
3233
3147
  hostConfigLoader,
3234
3148
  isFirstRun,
3235
- loadRemoteModule,
3236
- metadataLoader,
3237
3149
  registry,
3238
3150
  saveConfig,
3239
3151
  setAccessToken,
@@ -1,6 +1,6 @@
1
- export * from './auth.ts';
2
- export * from './module.ts';
3
- export * from './plugin.types.ts';
4
- export * from './protocol.ts';
5
- export * from './websocket.ts';
6
- export * from './wizard.ts';
1
+ export * from './auth';
2
+ export * from './module';
3
+ export * from './plugin.types';
4
+ export * from './protocol';
5
+ export * from './websocket';
6
+ export * from './wizard';
@@ -25,3 +25,10 @@ export interface WebSocketData {
25
25
  };
26
26
  system: SystemInfo;
27
27
  }
28
+ export interface WebSocketSubscribeOptions {
29
+ headers?: Record<string, string>;
30
+ protocols?: string | string[];
31
+ bearerToken?: string | null;
32
+ bearerStrategy?: 'query' | 'protocol';
33
+ bearerQueryParam?: string;
34
+ }
package/package.json CHANGED
@@ -1,52 +1,32 @@
1
1
  {
2
2
  "name": "@viasoftbr/shared-ui",
3
- "description": "Shared frontend utilities, components and i18n for Viasoft plugins and micro-frontends",
4
- "type": "module",
5
- "main": "dist/index.js",
6
- "module": "./dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/types/index.d.ts",
9
6
  "exports": {
10
- ".": {
7
+ ".": {
11
8
  "import": "./dist/index.js",
12
- "require": "./dist/index.cjs",
13
- "types": "./dist/index.d.ts"
14
- },
15
- "./index": {
16
- "import": "./dist/index.js",
17
- "require": "./dist/index.cjs",
18
- "types": "./dist/index.d.ts"
19
- },
20
- "./context": {
21
- "import": "./dist/context.js",
22
- "require": "./dist/context.cjs",
23
- "types": "./dist/context/index.d.ts"
9
+ "types": "./dist/types/index.d.ts"
24
10
  },
25
11
  "./components": {
26
- "import": "./dist/components.js",
27
- "require": "./dist/components.cjs",
28
- "types": "./dist/components/index.d.ts"
29
- },
30
- "./services": {
31
- "import": "./dist/services.js",
32
- "require": "./dist/services.cjs",
33
- "types": "./dist/services/index.d.ts"
12
+ "import": "./dist/components/index.js",
13
+ "types": "./dist/types/components/index.d.ts"
34
14
  },
35
15
  "./types": {
36
- "import": "./dist/types.js",
37
- "require": "./dist/types.cjs",
38
- "types": "./dist/types/index.d.ts"
16
+ "import": "./dist/types-module/index.js",
17
+ "types": "./dist/types/types/index.d.ts"
39
18
  },
40
- "./i18n": {
41
- "import": "./dist/i18n.js",
42
- "require": "./dist/i18n.cjs",
43
- "types": "./dist/i18n.d.ts"
19
+ "./services": {
20
+ "import": "./dist/services/index.js",
21
+ "types": "./dist/types/services/index.d.ts"
44
22
  },
45
- "./jsmpeg": {
46
- "default": "./dist/jsmpeg.vu.min.js"
23
+ "./context": {
24
+ "import": "./dist/context/index.js",
25
+ "types": "./dist/types/context/index.d.ts"
47
26
  },
48
- "./locales/*": {
49
- "default": "./dist/locales/*"
27
+ "./hooks": {
28
+ "import": "./dist/hooks/index.js",
29
+ "types": "./dist/types/hooks/index.d.ts"
50
30
  }
51
31
  },
52
32
  "scripts": {