@webority/web-core 0.80.4 → 0.80.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.
- package/dist/config/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/initSDK.js +1 -1
- package/dist/types/config/index.d.ts +11 -0
- package/dist/types/initSDK.d.ts +6 -0
- package/dist/types/versionCheck/deployedBuild.d.ts +9 -0
- package/dist/types/versionCheck/index.d.ts +12 -9
- package/dist/versionCheck/deployedBuild.js +1 -0
- package/dist/versionCheck/index.js +1 -1
- package/package.json +1 -1
package/dist/config/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=`warn`,t=3e4,n=3,r=`X-Correlation-Id`,i={baseUrl:null,loggingEnabled:!0,logLevel:e,environment:`Development`,appVersion:null,commit:null,appBuild:null,timeoutMs:t,retries:3,correlationIdHeader:r,staticAssets:null},
|
|
1
|
+
var e=`warn`,t=3e4,n=3,r=`X-Correlation-Id`,i=`/version.json`,a=3e5,o={baseUrl:null,loggingEnabled:!0,logLevel:e,environment:`Development`,appVersion:null,commit:null,appBuild:null,buildId:null,versionUrl:i,buildCheckIntervalMs:a,timeoutMs:t,retries:3,correlationIdHeader:r,staticAssets:null},s={...o},c=e=>{s={...s,...e}},l=()=>s;function u(e,t){let n=s[e];return n===null?t:n}var d=()=>{s={...o}};export{a as DEFAULT_BUILD_CHECK_INTERVAL_MS,r as DEFAULT_CORRELATION_ID_HEADER,e as DEFAULT_LOG_LEVEL,n as DEFAULT_RETRIES,t as DEFAULT_TIMEOUT_MS,i as DEFAULT_VERSION_URL,l as getConfig,u as getConfigValue,d as resetConfig,c as setConfig};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{DEFAULT_BUILD_CHECK_INTERVAL_MS as e,DEFAULT_CORRELATION_ID_HEADER as t,DEFAULT_LOG_LEVEL as n,DEFAULT_RETRIES as r,DEFAULT_TIMEOUT_MS as i,DEFAULT_VERSION_URL as a,getConfig as o,getConfigValue as s,resetConfig as c,setConfig as l}from"./config/index.js";import{Logger as u,configureLogger as d,getDeviceContext as f,setDeviceContext as p,setRemoteLogger as m}from"./logger/logger.js";import{decodeJWT as h,getJWTExpiry as g,isJWTExpired as _}from"./auth/jwt.js";import{ACCESS_TOKEN_KEY as v,LEGACY_REFRESH_TOKEN_LIFETIME_MS as y,REFRESH_TOKEN_KEY as b,SESSION_USER_KEY as x,addSessionEndedListener as S,clearSession as C,getKeepSignedIn as w,getSessionUser as T,getToken as E,hasSession as D,hasSessionEndedInTab as O,removeSessionUser as k,removeToken as A,setKeepSignedIn as j,setLegacyTokenKeys as M,storeSessionUser as N,storeToken as P}from"./auth/authStore.js";import{addNetworkStatusListener as F,getNetworkStatus as I,setNetworkStatusImplementation as L,useNetworkStatus as R}from"./network/networkStatus.js";import{ACCOUNT_ID_HEADER as z,CLIENT_BUILD_HEADER as B,CLIENT_KIND as V,CLIENT_KIND_HEADER as H,getClientBuild as U}from"./api/clientHeaders.js";import{MIN_APP_VERSION_HEADER as W,addMinAppVersionListener as G,getMinAppVersion as K}from"./api/minAppVersion.js";import{applyRequestDefaults as q,newCorrelationId as J}from"./api/requestDefaults.js";import{WORKSPACE_CHANGED_CODE as Y,WorkspaceChangedError as X,isWorkspaceChangedError as Z}from"./api/workspaceChanged.js";import{IDEMPOTENCY_KEY_HEADER as Q,attachRetry as $,isNeverSentError as ee,isRetryableFailure as te,isRetryableStatus as ne,retryAfterMs as re}from"./api/retry.js";import{REFRESH_LOCK_NAME as ie,withCrossTabRefreshLock as ae}from"./api/crossTabRefreshLock.js";import oe from"./api/publicClient.js";import{SIGN_OUT_REASON_HEADER as se,injectStore as ce,injectUserAuth as le,refreshAccessToken as ue,resetRefreshState as de}from"./api/tokenRefresh.js";import fe,{RequestOfflineError as pe,SESSION_TERMINATION_CODES as me}from"./api/userClient.js";import{initUserAuth as he}from"./initUserAuth.js";import{CONTRACT_ERROR_CODE as ge,NETWORK_CODE as _e,OFFLINE_CODE as ve,OFFLINE_MESSAGE as ye,REQUEST_CANCELED_CODE as be,SERVER_FAILURE_MESSAGE as xe,TIMEOUT_CODE as Se,TIMEOUT_MESSAGE as Ce,UNEXPECTED_MESSAGE as we,UNREACHABLE_MESSAGE as Te,apiErrorMessage as Ee,extractApiError as De,isApiError as Oe,isNoResponse as ke,toFieldPath as Ae}from"./errors/extractApiError.js";import{configureFormatters as je,getFormatterConfig as Me}from"./formatters/formatConfig.js";import{formatCurrency as Ne}from"./formatters/currency.js";import{addDays as Pe}from"./formatters/dateMath.js";import{formatDate as Fe,formatDateTime as Ie,formatMinor as Le,formatNumber as Re,formatPercent as ze,formatRelative as Be,formatTime as Ve}from"./formatters/house.js";import{initWebority as He}from"./initSDK.js";import{createApiBaseQuery as Ue}from"./query/apiBaseQuery.js";import{APP_API_DEFAULTS as We,createAppApi as Ge}from"./query/createAppApi.js";import{setupApiListeners as Ke}from"./query/listeners.js";import{buildListQuery as qe,getNextPageParam as Je,getPreviousPageParam as Ye,hasNextPage as Xe,hasPreviousPage as Ze}from"./query/paging.js";import{LIST_TAG_ID as Qe,itemTag as $e,listTag as et,providesList as tt,providesPagedList as nt}from"./query/tags.js";import{errorToastMiddleware as rt,isSilentRejection as it}from"./redux/errorToastMiddleware.js";import{createRootReducer as at,resetState as ot}from"./redux/rootReducer.js";import{SERIALIZABLE_IGNORED_ACTION_PATHS as st}from"./redux/serializableCheck.js";import{hasRecentlyReloaded as ct,importWithReload as lt,isChunkLoadError as ut,lazyWithReload as dt,markReloaded as ft}from"./router/chunkReload.js";import{hasPermission as pt}from"./router/permissions.js";import{RETURN_TO_PARAM as mt,buildLoginPath as ht,getReturnTo as gt,toSafeReturnTo as _t}from"./router/returnTo.js";import{PublicOnly as vt,RequireAuth as yt,RequirePermission as bt}from"./router/guards.js";import{publicOnly as xt,requireAuth as St,requirePermission as Ct,withGuards as wt}from"./router/loaders.js";import{classifyRouteError as Tt,useRouteErrorReport as Et}from"./router/routeError.js";import{staticUrl as Dt}from"./static/index.js";import{Storage as Ot,isStorageAvailable as kt,setStorageImplementation as At,syncStorage as jt}from"./storage/index.js";import{isBuildBelowMinimum as Mt,parseBuildNumber as Nt}from"./versionCheck/buildNumber.js";import{addDeployedBuildListener as Pt,getNewerDeployedBuild as Ft,startDeployedBuildCheck as It}from"./versionCheck/deployedBuild.js";import{installReloadOnNavigate as Lt,isUpdateAvailable as Rt,useVersionCheck as zt}from"./versionCheck/index.js";export{v as ACCESS_TOKEN_KEY,z as ACCOUNT_ID_HEADER,We as APP_API_DEFAULTS,B as CLIENT_BUILD_HEADER,V as CLIENT_KIND,H as CLIENT_KIND_HEADER,ge as CONTRACT_ERROR_CODE,e as DEFAULT_BUILD_CHECK_INTERVAL_MS,t as DEFAULT_CORRELATION_ID_HEADER,n as DEFAULT_LOG_LEVEL,r as DEFAULT_RETRIES,i as DEFAULT_TIMEOUT_MS,a as DEFAULT_VERSION_URL,Q as IDEMPOTENCY_KEY_HEADER,y as LEGACY_REFRESH_TOKEN_LIFETIME_MS,Qe as LIST_TAG_ID,u as Logger,W as MIN_APP_VERSION_HEADER,_e as NETWORK_CODE,ve as OFFLINE_CODE,ye as OFFLINE_MESSAGE,vt as PublicOnly,ie as REFRESH_LOCK_NAME,b as REFRESH_TOKEN_KEY,be as REQUEST_CANCELED_CODE,mt as RETURN_TO_PARAM,pe as RequestOfflineError,yt as RequireAuth,bt as RequirePermission,st as SERIALIZABLE_IGNORED_ACTION_PATHS,xe as SERVER_FAILURE_MESSAGE,me as SESSION_TERMINATION_CODES,x as SESSION_USER_KEY,se as SIGN_OUT_REASON_HEADER,Ot as Storage,Se as TIMEOUT_CODE,Ce as TIMEOUT_MESSAGE,we as UNEXPECTED_MESSAGE,Te as UNREACHABLE_MESSAGE,Y as WORKSPACE_CHANGED_CODE,X as WorkspaceChangedError,Pe as addDays,Pt as addDeployedBuildListener,G as addMinAppVersionListener,F as addNetworkStatusListener,S as addSessionEndedListener,Ee as apiErrorMessage,q as applyRequestDefaults,$ as attachRetry,qe as buildListQuery,ht as buildLoginPath,Tt as classifyRouteError,C as clearSession,je as configureFormatters,d as configureLogger,Ue as createApiBaseQuery,Ge as createAppApi,at as createRootReducer,h as decodeJWT,rt as errorToastMiddleware,De as extractApiError,Ne as formatCurrency,Fe as formatDate,Ie as formatDateTime,Le as formatMinor,Re as formatNumber,ze as formatPercent,Be as formatRelative,Ve as formatTime,U as getClientBuild,o as getConfig,s as getConfigValue,f as getDeviceContext,Me as getFormatterConfig,g as getJWTExpiry,w as getKeepSignedIn,K as getMinAppVersion,I as getNetworkStatus,Ft as getNewerDeployedBuild,Je as getNextPageParam,Ye as getPreviousPageParam,gt as getReturnTo,T as getSessionUser,E as getToken,Xe as hasNextPage,pt as hasPermission,Ze as hasPreviousPage,ct as hasRecentlyReloaded,D as hasSession,O as hasSessionEndedInTab,lt as importWithReload,he as initUserAuth,He as initWebority,ce as injectStore,le as injectUserAuth,Lt as installReloadOnNavigate,Oe as isApiError,Mt as isBuildBelowMinimum,ut as isChunkLoadError,_ as isJWTExpired,ee as isNeverSentError,ke as isNoResponse,te as isRetryableFailure,ne as isRetryableStatus,it as isSilentRejection,kt as isStorageAvailable,Rt as isUpdateAvailable,Z as isWorkspaceChangedError,$e as itemTag,dt as lazyWithReload,et as listTag,ft as markReloaded,J as newCorrelationId,Nt as parseBuildNumber,tt as providesList,nt as providesPagedList,oe as publicClient,xt as publicOnly,ue as refreshAccessToken,k as removeSessionUser,A as removeToken,St as requireAuth,Ct as requirePermission,c as resetConfig,de as resetRefreshState,ot as resetState,re as retryAfterMs,l as setConfig,p as setDeviceContext,j as setKeepSignedIn,M as setLegacyTokenKeys,L as setNetworkStatusImplementation,m as setRemoteLogger,At as setStorageImplementation,Ke as setupApiListeners,It as startDeployedBuildCheck,Dt as staticUrl,N as storeSessionUser,P as storeToken,jt as syncStorage,Ae as toFieldPath,_t as toSafeReturnTo,R as useNetworkStatus,Et as useRouteErrorReport,zt as useVersionCheck,fe as userClient,ae as withCrossTabRefreshLock,wt as withGuards};
|
package/dist/initSDK.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DEFAULT_CORRELATION_ID_HEADER as e,setConfig as t}from"./config/index.js";import{Logger as n}from"./logger/logger.js";var r=r=>{if(typeof r.baseUrl!=`string`)throw Error(`baseUrl is required for Webority packages initialization`);t({baseUrl:r.baseUrl,loggingEnabled:r.loggingEnabled??!0,logLevel:r.logLevel??`warn`,environment:r.environment??`Development`,appVersion:r.appVersion??null,commit:r.commit??null,appBuild:r.appBuild??null,timeoutMs:r.timeoutMs??3e4,retries:r.retries??3,correlationIdHeader:r.correlationIdHeader===void 0?e:r.correlationIdHeader,staticAssets:r.staticAssets??null}),n.info(`[@webority/web-core] initialized`)};export{r as initWebority};
|
|
1
|
+
import{DEFAULT_CORRELATION_ID_HEADER as e,setConfig as t}from"./config/index.js";import{Logger as n}from"./logger/logger.js";var r=r=>{if(typeof r.baseUrl!=`string`)throw Error(`baseUrl is required for Webority packages initialization`);t({baseUrl:r.baseUrl,loggingEnabled:r.loggingEnabled??!0,logLevel:r.logLevel??`warn`,environment:r.environment??`Development`,appVersion:r.appVersion??null,commit:r.commit??null,appBuild:r.appBuild??null,buildId:r.buildId??null,versionUrl:r.versionUrl??`/version.json`,buildCheckIntervalMs:r.buildCheckIntervalMs??3e5,timeoutMs:r.timeoutMs??3e4,retries:r.retries??3,correlationIdHeader:r.correlationIdHeader===void 0?e:r.correlationIdHeader,staticAssets:r.staticAssets??null}),n.info(`[@webority/web-core] initialized`)};export{r as initWebority};
|
|
@@ -26,6 +26,15 @@ export interface Config {
|
|
|
26
26
|
* compares it with the API's `X-Min-App-Version`.
|
|
27
27
|
*/
|
|
28
28
|
appBuild: number | null;
|
|
29
|
+
/**
|
|
30
|
+
* The deploy marker stamped into the bundle (`<sha>-<epochMs>-<app>`, the `version` the build writes
|
|
31
|
+
* to `version.json`). The deployed-build check compares it with the live `version.json`.
|
|
32
|
+
*/
|
|
33
|
+
buildId: string | null;
|
|
34
|
+
/** Where the live build marker is served. */
|
|
35
|
+
versionUrl: string;
|
|
36
|
+
/** How often an open tab checks `versionUrl`, in milliseconds. */
|
|
37
|
+
buildCheckIntervalMs: number;
|
|
29
38
|
/**
|
|
30
39
|
* Request timeout for both clients, in milliseconds. A request overrides it with its own
|
|
31
40
|
* axios `timeout`. Default 30000.
|
|
@@ -53,6 +62,8 @@ export declare const DEFAULT_LOG_LEVEL: LogLevel;
|
|
|
53
62
|
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
54
63
|
export declare const DEFAULT_RETRIES = 3;
|
|
55
64
|
export declare const DEFAULT_CORRELATION_ID_HEADER = "X-Correlation-Id";
|
|
65
|
+
export declare const DEFAULT_VERSION_URL = "/version.json";
|
|
66
|
+
export declare const DEFAULT_BUILD_CHECK_INTERVAL_MS = 300000;
|
|
56
67
|
/** Set global configuration for all Webority packages. */
|
|
57
68
|
export declare const setConfig: (config: Partial<Config>) => void;
|
|
58
69
|
/** Get the current configuration. */
|
package/dist/types/initSDK.d.ts
CHANGED
|
@@ -18,6 +18,12 @@ export interface InitConfig {
|
|
|
18
18
|
commit?: string;
|
|
19
19
|
/** The integer build number the deploy stamps; the version check compares it with the API's minimum. */
|
|
20
20
|
appBuild?: number;
|
|
21
|
+
/** The deploy marker the build writes to `version.json`; an open tab compares it with the live file. Defaults to `null` (no check). */
|
|
22
|
+
buildId?: string | null;
|
|
23
|
+
/** Where the live build marker is served. Defaults to `'/version.json'`. */
|
|
24
|
+
versionUrl?: string;
|
|
25
|
+
/** How often an open tab checks `versionUrl`, in milliseconds. Defaults to 300000. */
|
|
26
|
+
buildCheckIntervalMs?: number;
|
|
21
27
|
/** Request timeout in milliseconds. Defaults to 30000; 0 means no timeout. A request's own `timeout` wins. */
|
|
22
28
|
timeoutMs?: number;
|
|
23
29
|
/** Retries under the retry rule. Defaults to 3; 0 turns retrying off. */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** The live build marker when it differs from this bundle's `buildId`, or `null` while the bundle is current. */
|
|
2
|
+
export declare const getNewerDeployedBuild: () => string | null;
|
|
3
|
+
/** Called once when a newer deployed build is found. Returns the remover. */
|
|
4
|
+
export declare const addDeployedBuildListener: (listener: () => void) => (() => void);
|
|
5
|
+
/**
|
|
6
|
+
* Polls `versionUrl` while the tab is open and stops at the first marker that differs from `buildId`.
|
|
7
|
+
* A second call returns the same stop function, so a remount never starts a second timer.
|
|
8
|
+
*/
|
|
9
|
+
export declare const startDeployedBuildCheck: () => (() => void);
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Whether the running bundle is below the API minimum or a newer build is deployed.
|
|
3
|
+
*/
|
|
2
4
|
export declare const isUpdateAvailable: () => boolean;
|
|
3
5
|
export interface VersionCheckState {
|
|
4
|
-
/** The running bundle is older than the API supports; a reload fetches the new one. */
|
|
6
|
+
/** The running bundle is older than the API supports or than the deployed build; a reload fetches the new one. */
|
|
5
7
|
updateAvailable: boolean;
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
|
-
* Whether a newer build must be loaded
|
|
9
|
-
* `
|
|
10
|
-
* "new version" bar that reads this lives in `@webority/ui-react`.
|
|
10
|
+
* Whether a newer build must be loaded: the minimum the API sends in `X-Min-App-Version`, or a
|
|
11
|
+
* newer deployed build found by `startDeployedBuildCheck`. Re-renders the moment either changes.
|
|
12
|
+
* The "new version" bar that reads this lives in `@webority/ui-react`.
|
|
11
13
|
*/
|
|
12
14
|
export declare const useVersionCheck: () => VersionCheckState;
|
|
13
15
|
/**
|
|
@@ -31,12 +33,13 @@ export interface ReloadOnNavigateOptions {
|
|
|
31
33
|
reload?: () => void;
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
|
-
* Once an update is flagged, the
|
|
35
|
-
*
|
|
36
|
-
* mid-task. Returns the unsubscribe.
|
|
36
|
+
* Once an update is flagged, by the API minimum or by a newer deployed build,
|
|
37
|
+
* the next route change reloads the page, so the user lands on the new route
|
|
38
|
+
* in the new build instead of being interrupted mid-task. Returns the unsubscribe.
|
|
37
39
|
*
|
|
38
|
-
* One reload per
|
|
40
|
+
* One reload per trigger per tab: if a stale cache keeps serving the old
|
|
39
41
|
* bundle, navigation is not turned into a reload on every click.
|
|
40
42
|
*/
|
|
41
43
|
export declare const installReloadOnNavigate: (router: NavigationRouter, { reload }?: ReloadOnNavigateOptions) => (() => void);
|
|
42
44
|
export { isBuildBelowMinimum, parseBuildNumber } from "./buildNumber";
|
|
45
|
+
export { addDeployedBuildListener, getNewerDeployedBuild, startDeployedBuildCheck } from "./deployedBuild";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getConfigValue as e}from"../config/index.js";import{Logger as t}from"../logger/logger.js";var n=null,r=new Set,i=null,a=()=>void 0,o=()=>n,s=e=>(r.add(e),()=>{r.delete(e)}),c=()=>{for(let e of[...r])try{e()}catch(e){t.error(`[VersionCheck] a deployed-build listener threw`,e)}},l=()=>{if(typeof window>`u`)return a;if(i!==null)return i;let r=e(`buildId`);if(!r)return t.warn(`[VersionCheck] buildId is not configured; call setConfig({ buildId }) with the marker the build stamps`),i=a,a;let o=e(`versionUrl`),s=e(`buildCheckIntervalMs`),l=!1,u=async()=>{if(!l){l=!0;try{let e=await fetch(o,{cache:`no-store`});if(!e.ok)return;let t=(await e.json())?.version,i=typeof t==`string`?t.trim():``;i!==``&&i!==r&&(n=i,c(),p())}catch(e){t.debug(`[VersionCheck] the deployed-build check failed`,e)}finally{l=!1}}},d=()=>{document.visibilityState===`visible`&&u()},f=setInterval(()=>void u(),s),p=()=>{clearInterval(f),document.removeEventListener(`visibilitychange`,d)};return document.addEventListener(`visibilitychange`,d),i=p,p};export{s as addDeployedBuildListener,o as getNewerDeployedBuild,l as startDeployedBuildCheck};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getConfigValue as e}from"../config/index.js";import{Logger as t}from"../logger/logger.js";import{addMinAppVersionListener as n,getMinAppVersion as r}from"../api/minAppVersion.js";import{isBuildBelowMinimum as i,parseBuildNumber as a}from"./buildNumber.js";import{
|
|
1
|
+
import{getConfigValue as e}from"../config/index.js";import{Logger as t}from"../logger/logger.js";import{addMinAppVersionListener as n,getMinAppVersion as r}from"../api/minAppVersion.js";import{isBuildBelowMinimum as i,parseBuildNumber as a}from"./buildNumber.js";import{addDeployedBuildListener as o,getNewerDeployedBuild as s,startDeployedBuildCheck as c}from"./deployedBuild.js";import{useMemo as l,useSyncExternalStore as u}from"react";var d=e=>{let t=n(()=>e()),r=o(e);return()=>{t(),r()}},f=()=>`${r()??``}|${s()??``}`,p=n=>{if(n===null)return!1;let r=a(e(`appBuild`));return r===null?(t.error(`[VersionCheck] the build number is not configured. Call setConfig({ appBuild: <integer> }) at startup with the build number the deploy stamps into the bundle.`),!1):i(r,n)},m=()=>p(r())||s()!==null,h=()=>l(()=>({updateAvailable:p(r())||s()!==null}),[u(d,f,f)]),g=`webority.versionCheck.reloadedFor`,_=e=>{try{return window.sessionStorage.getItem(e)}catch{return null}},v=(e,t)=>{try{window.sessionStorage.setItem(e,t)}catch{}},y=(e,{reload:n=()=>window.location.reload()}={})=>{let i=e.state.location.key;return e.subscribe(e=>{let a=e.location.key;if(a===i)return;i=a;let o=r(),c=s(),l;if(p(o))l=String(o);else if(c!==null)l=`build:${c}`;else return;if(_(g)===l){t.warn(`[VersionCheck] still on the old bundle after a reload for ${l}`);return}v(g,l),n()})};export{o as addDeployedBuildListener,s as getNewerDeployedBuild,y as installReloadOnNavigate,i as isBuildBelowMinimum,m as isUpdateAvailable,a as parseBuildNumber,c as startDeployedBuildCheck,h as useVersionCheck};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/web-core",
|
|
3
|
-
"version": "0.80.
|
|
3
|
+
"version": "0.80.6",
|
|
4
4
|
"description": "Platform layer for Webority React web portals: HTTP clients with single-flight token refresh, auth store, API error extraction, RTK Query base query, logger, formatters, storage, version check and route guards. No UI.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|