@descope/sdk-mixins 0.15.1 → 0.16.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/dist/cjs/mixins/descopeUiMixin/descopeUiMixin.js +13 -2
- package/dist/cjs/mixins/descopeUiMixin/descopeUiMixin.js.map +1 -1
- package/dist/cjs/mixins/injectNpmLibMixin/helpers.js +29 -17
- package/dist/cjs/mixins/injectNpmLibMixin/helpers.js.map +1 -1
- package/dist/cjs/mixins/injectNpmLibMixin/injectNpmLibMixin.js +3 -3
- package/dist/cjs/mixins/injectNpmLibMixin/injectNpmLibMixin.js.map +1 -1
- package/dist/esm/mixins/descopeUiMixin/descopeUiMixin.js +13 -2
- package/dist/esm/mixins/descopeUiMixin/descopeUiMixin.js.map +1 -1
- package/dist/esm/mixins/injectNpmLibMixin/helpers.js +29 -17
- package/dist/esm/mixins/injectNpmLibMixin/helpers.js.map +1 -1
- package/dist/esm/mixins/injectNpmLibMixin/injectNpmLibMixin.js +3 -3
- package/dist/esm/mixins/injectNpmLibMixin/injectNpmLibMixin.js.map +1 -1
- package/dist/index.d.ts +179 -183
- package/dist/types/mixins/configMixin/configMixin.d.ts +14 -14
- package/dist/types/mixins/configMixin/types.d.ts +1 -0
- package/dist/types/mixins/createStateManagementMixin.d.ts +2 -2
- package/dist/types/mixins/createValidateAttributesMixin/createValidateAttributesMixin.d.ts +5 -5
- package/dist/types/mixins/cspNonceMixin.d.ts +5 -5
- package/dist/types/mixins/debuggerMixin/debugger-wc.d.ts +5 -5
- package/dist/types/mixins/debuggerMixin/debuggerMixin.d.ts +8 -8
- package/dist/types/mixins/descopeUiMixin/descopeUiMixin.d.ts +20 -22
- package/dist/types/mixins/formMixin.d.ts +2 -2
- package/dist/types/mixins/initElementMixin.d.ts +5 -5
- package/dist/types/mixins/initLifecycleMixin.d.ts +1 -1
- package/dist/types/mixins/injectNpmLibMixin/helpers.d.ts +3 -3
- package/dist/types/mixins/injectNpmLibMixin/injectNpmLibMixin.d.ts +3 -6
- package/dist/types/mixins/injectStyleMixin.d.ts +5 -5
- package/dist/types/mixins/loggerMixin/loggerMixin.d.ts +2 -2
- package/dist/types/mixins/modalMixin/modalMixin.d.ts +24 -26
- package/dist/types/mixins/notificationsMixin/notificationsMixin.d.ts +24 -26
- package/dist/types/mixins/observeAttributesMixin/observeAttributesMixin.d.ts +4 -4
- package/dist/types/mixins/projectIdMixin.d.ts +5 -5
- package/dist/types/mixins/resetMixin.d.ts +6 -6
- package/dist/types/mixins/staticResourcesMixin/staticResourcesMixin.d.ts +10 -10
- package/dist/types/mixins/themeMixin/themeMixin.d.ts +33 -35
- package/package.json +3 -3
|
@@ -9,7 +9,7 @@ var helpers = require('./helpers.js');
|
|
|
9
9
|
var constants = require('./constants.js');
|
|
10
10
|
|
|
11
11
|
const descopeUiMixin = sdkHelpers.createSingletonMixin((superclass) => {
|
|
12
|
-
var _DescopeUiMixinClass_instances, _DescopeUiMixinClass_getComponentsVersion, _DescopeUiMixinClass_descopeUi, _DescopeUiMixinClass_loadDescopeUiComponent, _DescopeUiMixinClass_getDescopeUi, _a;
|
|
12
|
+
var _DescopeUiMixinClass_instances, _DescopeUiMixinClass_getComponentsVersion, _DescopeUiMixinClass_getComponentsVersionSri, _DescopeUiMixinClass_descopeUi, _DescopeUiMixinClass_loadDescopeUiComponent, _DescopeUiMixinClass_getDescopeUi, _a;
|
|
13
13
|
const BaseClass = sdkHelpers.compose(loggerMixin.loggerMixin, configMixin.configMixin, injectNpmLibMixin.injectNpmLibMixin)(superclass);
|
|
14
14
|
return _a = class DescopeUiMixinClass extends BaseClass {
|
|
15
15
|
constructor() {
|
|
@@ -46,6 +46,15 @@ const descopeUiMixin = sdkHelpers.createSingletonMixin((superclass) => {
|
|
|
46
46
|
}
|
|
47
47
|
return componentsVersion;
|
|
48
48
|
},
|
|
49
|
+
_DescopeUiMixinClass_getComponentsVersionSri = async function _DescopeUiMixinClass_getComponentsVersionSri() {
|
|
50
|
+
var _b;
|
|
51
|
+
const config = await this.config;
|
|
52
|
+
const componentsVersionSri = (_b = config === null || config === void 0 ? void 0 : config.projectConfig) === null || _b === void 0 ? void 0 : _b.componentsVersionSri;
|
|
53
|
+
if (componentsVersionSri) {
|
|
54
|
+
this.logger.debug('SRI hash available for components');
|
|
55
|
+
}
|
|
56
|
+
return componentsVersionSri;
|
|
57
|
+
},
|
|
49
58
|
_DescopeUiMixinClass_loadDescopeUiComponent = async function _DescopeUiMixinClass_loadDescopeUiComponent(componentName) {
|
|
50
59
|
const isComponentAlreadyDefined = !!customElements.get(componentName);
|
|
51
60
|
if (isComponentAlreadyDefined) {
|
|
@@ -80,7 +89,9 @@ const descopeUiMixin = sdkHelpers.createSingletonMixin((superclass) => {
|
|
|
80
89
|
return globalThis.DescopeUI;
|
|
81
90
|
}
|
|
82
91
|
try {
|
|
83
|
-
|
|
92
|
+
const componentsVersion = await tslib.__classPrivateFieldGet(this, _DescopeUiMixinClass_instances, "m", _DescopeUiMixinClass_getComponentsVersion).call(this);
|
|
93
|
+
const componentsVersionSri = await tslib.__classPrivateFieldGet(this, _DescopeUiMixinClass_instances, "m", _DescopeUiMixinClass_getComponentsVersionSri).call(this);
|
|
94
|
+
await this.injectNpmLib(constants.WEB_COMPONENTS_UI_LIB_NAME, componentsVersion, constants.JS_FILE_PATH, [constants.LOCAL_STORAGE_OVERRIDE], componentsVersionSri);
|
|
84
95
|
this.logger.debug('DescopeUI was loaded');
|
|
85
96
|
return globalThis.DescopeUI;
|
|
86
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"descopeUiMixin.js","sources":["../../../../src/mixins/descopeUiMixin/descopeUiMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { configMixin } from '../configMixin';\nimport { injectNpmLibMixin } from '../injectNpmLibMixin';\nimport { loggerMixin } from '../loggerMixin';\nimport { getDescopeUiComponentsList } from './helpers';\nimport {\n JS_FILE_PATH,\n LOCAL_STORAGE_OVERRIDE,\n WEB_COMPONENTS_UI_LIB_NAME,\n} from './constants';\n\nexport const descopeUiMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n configMixin,\n injectNpmLibMixin,\n )(superclass);\n\n return class DescopeUiMixinClass extends BaseClass {\n // eslint-disable-next-line class-methods-use-this\n async #getComponentsVersion() {\n const config = await this.config;\n const componentsVersion = config?.projectConfig?.componentsVersion;\n\n if (!componentsVersion) {\n this.logger.error('Could not get components version');\n } else {\n this.logger.debug(`Got component version \"${componentsVersion}\"`);\n }\n\n return componentsVersion;\n }\n\n #descopeUi: Promise<any>;\n\n get descopeUi() {\n if (!this.#descopeUi) {\n this.#descopeUi = this.#getDescopeUi();\n }\n\n return this.#descopeUi;\n }\n\n async #loadDescopeUiComponent(componentName: string) {\n const isComponentAlreadyDefined = !!customElements.get(componentName);\n\n if (isComponentAlreadyDefined) {\n this.logger.debug(\n `Loading component \"${componentName}\" is skipped as it is already defined`,\n );\n return undefined;\n }\n\n const descopeUI = await this.descopeUi;\n\n if (!descopeUI[componentName]) {\n this.logger.error(\n `Cannot load UI component \"${componentName}\"`,\n `Descope UI does not have a component named \"${componentName}\", available components are: \"${Object.keys(\n descopeUI,\n ).join(', ')}\"`,\n );\n return undefined;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/return-await\n return await descopeUI[componentName]();\n } catch (e) {\n // this error is thrown when trying to register a component which is already registered\n // when running 2 flows on the same page, it might happen that the register fn is called twice\n // in case it happens, we are silently ignore the error\n if (e.name === 'NotSupportedError') {\n // eslint-disable-next-line no-console\n console.debug(\n `Encountered an error while attempting to define the \"${componentName}\" component, it is likely that this component is already defined`,\n );\n } else {\n throw e;\n }\n }\n\n return undefined;\n }\n\n async #getDescopeUi() {\n if (globalThis.DescopeUI) {\n return globalThis.DescopeUI;\n }\n\n try {\n await this.injectNpmLib(\n WEB_COMPONENTS_UI_LIB_NAME,\n
|
|
1
|
+
{"version":3,"file":"descopeUiMixin.js","sources":["../../../../src/mixins/descopeUiMixin/descopeUiMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { configMixin } from '../configMixin';\nimport { injectNpmLibMixin } from '../injectNpmLibMixin';\nimport { loggerMixin } from '../loggerMixin';\nimport { getDescopeUiComponentsList } from './helpers';\nimport {\n JS_FILE_PATH,\n LOCAL_STORAGE_OVERRIDE,\n WEB_COMPONENTS_UI_LIB_NAME,\n} from './constants';\n\nexport const descopeUiMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n configMixin,\n injectNpmLibMixin,\n )(superclass);\n\n return class DescopeUiMixinClass extends BaseClass {\n // eslint-disable-next-line class-methods-use-this\n async #getComponentsVersion() {\n const config = await this.config;\n const componentsVersion = config?.projectConfig?.componentsVersion;\n\n if (!componentsVersion) {\n this.logger.error('Could not get components version');\n } else {\n this.logger.debug(`Got component version \"${componentsVersion}\"`);\n }\n\n return componentsVersion;\n }\n\n async #getComponentsVersionSri() {\n const config = await this.config;\n const componentsVersionSri =\n config?.projectConfig?.componentsVersionSri;\n\n if (componentsVersionSri) {\n this.logger.debug('SRI hash available for components');\n }\n\n return componentsVersionSri;\n }\n\n #descopeUi: Promise<any>;\n\n get descopeUi() {\n if (!this.#descopeUi) {\n this.#descopeUi = this.#getDescopeUi();\n }\n\n return this.#descopeUi;\n }\n\n async #loadDescopeUiComponent(componentName: string) {\n const isComponentAlreadyDefined = !!customElements.get(componentName);\n\n if (isComponentAlreadyDefined) {\n this.logger.debug(\n `Loading component \"${componentName}\" is skipped as it is already defined`,\n );\n return undefined;\n }\n\n const descopeUI = await this.descopeUi;\n\n if (!descopeUI[componentName]) {\n this.logger.error(\n `Cannot load UI component \"${componentName}\"`,\n `Descope UI does not have a component named \"${componentName}\", available components are: \"${Object.keys(\n descopeUI,\n ).join(', ')}\"`,\n );\n return undefined;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/return-await\n return await descopeUI[componentName]();\n } catch (e) {\n // this error is thrown when trying to register a component which is already registered\n // when running 2 flows on the same page, it might happen that the register fn is called twice\n // in case it happens, we are silently ignore the error\n if (e.name === 'NotSupportedError') {\n // eslint-disable-next-line no-console\n console.debug(\n `Encountered an error while attempting to define the \"${componentName}\" component, it is likely that this component is already defined`,\n );\n } else {\n throw e;\n }\n }\n\n return undefined;\n }\n\n async #getDescopeUi() {\n if (globalThis.DescopeUI) {\n return globalThis.DescopeUI;\n }\n\n try {\n const componentsVersion = await this.#getComponentsVersion();\n const componentsVersionSri = await this.#getComponentsVersionSri();\n\n await this.injectNpmLib(\n WEB_COMPONENTS_UI_LIB_NAME,\n componentsVersion,\n JS_FILE_PATH,\n [LOCAL_STORAGE_OVERRIDE],\n componentsVersionSri,\n );\n this.logger.debug('DescopeUI was loaded');\n return globalThis.DescopeUI;\n } catch (error) {\n this.logger.error(error);\n throw new Error('DescopeUI was not loaded');\n }\n }\n\n async loadDescopeUiComponents(\n templateOrComponentNames: HTMLTemplateElement | string[],\n ) {\n const descopeUiComponentsList = Array.isArray(templateOrComponentNames)\n ? templateOrComponentNames\n : getDescopeUiComponentsList(templateOrComponentNames);\n\n return Promise.all(\n descopeUiComponentsList.map((componentName: string) =>\n this.#loadDescopeUiComponent(componentName),\n ),\n );\n }\n };\n },\n);\n"],"names":["createSingletonMixin","compose","loggerMixin","configMixin","injectNpmLibMixin","__classPrivateFieldGet","__classPrivateFieldSet","getDescopeUiComponentsList","WEB_COMPONENTS_UI_LIB_NAME","JS_FILE_PATH","LOCAL_STORAGE_OVERRIDE"],"mappings":"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"}
|
|
@@ -19,14 +19,21 @@ const hashUrl = (url) => {
|
|
|
19
19
|
}
|
|
20
20
|
return `${Math.abs(hash).toString()}`;
|
|
21
21
|
};
|
|
22
|
-
const setupScript = (id) => {
|
|
22
|
+
const setupScript = (id, integrity) => {
|
|
23
23
|
const scriptEle = document.createElement('script');
|
|
24
24
|
scriptEle.id = id;
|
|
25
|
+
if (integrity) {
|
|
26
|
+
scriptEle.integrity = integrity;
|
|
27
|
+
scriptEle.crossOrigin = 'anonymous';
|
|
28
|
+
}
|
|
29
|
+
if (window.DESCOPE_NONCE) {
|
|
30
|
+
scriptEle.setAttribute('nonce', window.DESCOPE_NONCE);
|
|
31
|
+
}
|
|
25
32
|
return scriptEle;
|
|
26
33
|
};
|
|
27
|
-
const injectScript = (scriptId, url) => {
|
|
34
|
+
const injectScript = (scriptId, url, integrity) => {
|
|
28
35
|
return new Promise((res, rej) => {
|
|
29
|
-
const scriptEle = setupScript(scriptId);
|
|
36
|
+
const scriptEle = setupScript(scriptId, integrity);
|
|
30
37
|
scriptEle.onerror = (error) => {
|
|
31
38
|
scriptEle.setAttribute('status', 'error');
|
|
32
39
|
rej(error);
|
|
@@ -39,7 +46,13 @@ const injectScript = (scriptId, url) => {
|
|
|
39
46
|
document.body.appendChild(scriptEle);
|
|
40
47
|
});
|
|
41
48
|
};
|
|
42
|
-
const handleExistingScript = (existingScript) => {
|
|
49
|
+
const handleExistingScript = (existingScript, expectedIntegrity) => {
|
|
50
|
+
if (expectedIntegrity) {
|
|
51
|
+
const actualIntegrity = existingScript.integrity;
|
|
52
|
+
if (actualIntegrity !== expectedIntegrity) {
|
|
53
|
+
return Promise.reject(new Error(`Integrity mismatch: expected ${expectedIntegrity}, found ${actualIntegrity}`));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
43
56
|
if (isScriptLoaded(existingScript)) {
|
|
44
57
|
return Promise.resolve(existingScript);
|
|
45
58
|
}
|
|
@@ -57,11 +70,11 @@ const handleExistingScript = (existingScript) => {
|
|
|
57
70
|
};
|
|
58
71
|
const injectScriptWithFallbacks = async (scriptsData, onError) => {
|
|
59
72
|
for (const scriptData of scriptsData) {
|
|
60
|
-
const { id, url } = scriptData;
|
|
73
|
+
const { id, url, integrity } = scriptData;
|
|
61
74
|
const existingScript = getExistingScript(id);
|
|
62
75
|
if (existingScript) {
|
|
63
76
|
try {
|
|
64
|
-
await handleExistingScript(existingScript);
|
|
77
|
+
await handleExistingScript(existingScript, integrity);
|
|
65
78
|
return scriptData;
|
|
66
79
|
}
|
|
67
80
|
catch (e) {
|
|
@@ -70,7 +83,7 @@ const injectScriptWithFallbacks = async (scriptsData, onError) => {
|
|
|
70
83
|
}
|
|
71
84
|
else {
|
|
72
85
|
try {
|
|
73
|
-
await injectScript(id, url);
|
|
86
|
+
await injectScript(id, url, integrity);
|
|
74
87
|
return scriptData;
|
|
75
88
|
}
|
|
76
89
|
catch (e) {
|
|
@@ -80,7 +93,7 @@ const injectScriptWithFallbacks = async (scriptsData, onError) => {
|
|
|
80
93
|
}
|
|
81
94
|
throw new Error('All scripts failed to load');
|
|
82
95
|
};
|
|
83
|
-
const generateLibUrls = (baseUrls, libName, version, path = '') => baseUrls.reduce((prev, curr) => {
|
|
96
|
+
const generateLibUrls = (baseUrls, libName, version, path = '', integrity) => baseUrls.reduce((prev, curr) => {
|
|
84
97
|
const baseUrl = curr;
|
|
85
98
|
if (!baseUrl) {
|
|
86
99
|
return prev;
|
|
@@ -96,15 +109,14 @@ const generateLibUrls = (baseUrls, libName, version, path = '') => baseUrls.redu
|
|
|
96
109
|
if (!isUrlIncludesPath) {
|
|
97
110
|
url.pathname = `/npm/${libName}@${version}/${path}`;
|
|
98
111
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
];
|
|
112
|
+
const scriptData = {
|
|
113
|
+
url: url,
|
|
114
|
+
id: `npmlib-${libName.replaceAll('@', '').replaceAll('/', '_')}-${hashUrl(url)}`,
|
|
115
|
+
};
|
|
116
|
+
if (integrity) {
|
|
117
|
+
scriptData.integrity = integrity;
|
|
118
|
+
}
|
|
119
|
+
return [...prev, scriptData];
|
|
108
120
|
}, []);
|
|
109
121
|
|
|
110
122
|
exports.generateLibUrls = generateLibUrls;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sources":["../../../../src/mixins/injectNpmLibMixin/helpers.ts"],"sourcesContent":["const getExistingScript = (scriptId: string): HTMLScriptElement => {\n return document.querySelector(`script#${scriptId}`);\n};\n\nconst isScriptLoaded = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'loaded';\n};\n\nconst isScriptError = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'error';\n};\n\nconst hashUrl = (url: URL) => {\n let hash = 0;\n const urlStr = url.toString();\n\n for (let i = 0; i < urlStr.length; i++) {\n const char = urlStr.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n\n return `${Math.abs(hash).toString()}`;\n};\n\nconst setupScript = (id: string) => {\n const scriptEle = document.createElement('script');\n scriptEle.id = id;\n\n
|
|
1
|
+
{"version":3,"file":"helpers.js","sources":["../../../../src/mixins/injectNpmLibMixin/helpers.ts"],"sourcesContent":["const getExistingScript = (scriptId: string): HTMLScriptElement => {\n return document.querySelector(`script#${scriptId}`);\n};\n\nconst isScriptLoaded = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'loaded';\n};\n\nconst isScriptError = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'error';\n};\n\nconst hashUrl = (url: URL) => {\n let hash = 0;\n const urlStr = url.toString();\n\n for (let i = 0; i < urlStr.length; i++) {\n const char = urlStr.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n\n return `${Math.abs(hash).toString()}`;\n};\n\nconst setupScript = (id: string, integrity?: string) => {\n const scriptEle = document.createElement('script');\n scriptEle.id = id;\n\n if (integrity) {\n scriptEle.integrity = integrity;\n scriptEle.crossOrigin = 'anonymous';\n }\n\n if ((window as any).DESCOPE_NONCE) {\n scriptEle.setAttribute('nonce', (window as any).DESCOPE_NONCE);\n }\n\n return scriptEle;\n};\n\nconst injectScript = (scriptId: string, url: URL, integrity?: string) => {\n return new Promise((res, rej) => {\n const scriptEle = setupScript(scriptId, integrity);\n\n scriptEle.onerror = (error) => {\n scriptEle.setAttribute('status', 'error');\n rej(error);\n };\n scriptEle.onload = () => {\n scriptEle.setAttribute('status', 'loaded');\n res(scriptEle);\n };\n\n scriptEle.src = url.toString();\n\n document.body.appendChild(scriptEle);\n });\n};\n\nconst handleExistingScript = (\n existingScript: HTMLScriptElement,\n expectedIntegrity?: string,\n) => {\n if (expectedIntegrity) {\n const actualIntegrity = existingScript.integrity;\n if (actualIntegrity !== expectedIntegrity) {\n return Promise.reject(\n new Error(\n `Integrity mismatch: expected ${expectedIntegrity}, found ${actualIntegrity}`,\n ),\n );\n }\n }\n\n if (isScriptLoaded(existingScript)) {\n return Promise.resolve(existingScript);\n }\n\n if (isScriptError(existingScript)) {\n return Promise.reject();\n }\n\n return new Promise((res, rej) => {\n existingScript.addEventListener('load', () => {\n res(existingScript);\n });\n\n existingScript.addEventListener('error', (error) => {\n rej(error);\n });\n });\n};\n\nexport type ScriptData = {\n id: string;\n url: URL;\n integrity?: string;\n};\n\nexport const injectScriptWithFallbacks = async (\n scriptsData: ScriptData[],\n onError: (scriptData: ScriptData, existingScript: boolean) => void,\n) => {\n for (const scriptData of scriptsData) {\n const { id, url, integrity } = scriptData;\n const existingScript = getExistingScript(id);\n if (existingScript) {\n try {\n await handleExistingScript(existingScript, integrity);\n return scriptData;\n } catch (e) {\n onError(scriptData, true);\n }\n } else {\n try {\n await injectScript(id, url, integrity);\n return scriptData;\n } catch (e) {\n onError(scriptData, false);\n }\n }\n }\n throw new Error('All scripts failed to load');\n};\n\nexport const generateLibUrls = (\n baseUrls: string[],\n libName: string,\n version: string,\n path = '',\n integrity?: string,\n) =>\n baseUrls.reduce((prev, curr) => {\n const baseUrl = curr;\n if (!baseUrl) {\n return prev;\n }\n\n let url: URL;\n try {\n url = new URL(baseUrl);\n } catch (e) {\n throw new Error(`Invalid URL: ${baseUrl}`);\n }\n\n const isUrlIncludesPath = url.pathname !== '/';\n\n if (!isUrlIncludesPath) {\n url.pathname = `/npm/${libName}@${version}/${path}`;\n }\n\n const scriptData: ScriptData = {\n url: url,\n id: `npmlib-${libName.replaceAll('@', '').replaceAll('/', '_')}-${hashUrl(\n url,\n )}`,\n };\n\n if (integrity) {\n scriptData.integrity = integrity;\n }\n\n return [...prev, scriptData];\n }, []);\n"],"names":[],"mappings":"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"}
|
|
@@ -11,9 +11,9 @@ const injectNpmLibMixin = sdkHelpers.createSingletonMixin((superclass) => {
|
|
|
11
11
|
get baseCdnUrl() {
|
|
12
12
|
return this.getAttribute('base-cdn-url') || '';
|
|
13
13
|
}
|
|
14
|
-
injectNpmLib(libName, version, filePath = '', overrides = []) {
|
|
15
|
-
this.logger.debug(`Injecting npm lib: "${libName}" with version: "${version}"`);
|
|
16
|
-
return helpers.injectScriptWithFallbacks(helpers.generateLibUrls([...overrides, this.baseCdnUrl, ...constants.BASE_URLS], libName, version, filePath), (scriptData, existingScript) => {
|
|
14
|
+
injectNpmLib(libName, version, filePath = '', overrides = [], integrity) {
|
|
15
|
+
this.logger.debug(`Injecting npm lib: "${libName}" with version: "${version}"${integrity ? ' with SRI integrity check' : ''}`);
|
|
16
|
+
return helpers.injectScriptWithFallbacks(helpers.generateLibUrls([...overrides, this.baseCdnUrl, ...constants.BASE_URLS], libName, version, filePath, integrity), (scriptData, existingScript) => {
|
|
17
17
|
if (existingScript) {
|
|
18
18
|
this.logger.error(`Existing script cannot be loaded: "${scriptData.url}"`);
|
|
19
19
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectNpmLibMixin.js","sources":["../../../../src/mixins/injectNpmLibMixin/injectNpmLibMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport { BASE_URLS } from './constants';\nimport { generateLibUrls, injectScriptWithFallbacks } from './helpers';\n\n// scripts load to window under descope object\ndeclare global {\n var descope: any;\n}\n\nexport const injectNpmLibMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(loggerMixin)(superclass);\n\n return class InjectNpmLibMixinClass extends BaseClass {\n get baseCdnUrl() {\n return this.getAttribute('base-cdn-url') || '';\n }\n\n injectNpmLib(\n libName: string,\n version: string,\n filePath = '',\n overrides: string[] = [],\n ) {\n this.logger.debug(\n `Injecting npm lib: \"${libName}\" with version: \"${version}\"`,\n );\n return injectScriptWithFallbacks(\n generateLibUrls(\n [...overrides, this.baseCdnUrl, ...BASE_URLS],\n libName,\n version,\n filePath,\n ),\n (scriptData, existingScript) => {\n if (existingScript) {\n this.logger.error(\n `Existing script cannot be loaded: \"${scriptData.url}\"`,\n );\n return;\n }\n this.logger.error(\n `Cannot load script from URL, Make sure this URL is valid and return the correct script: \"${scriptData.url}\"`,\n );\n },\n );\n }\n };\n },\n);\n"],"names":["createSingletonMixin","compose","loggerMixin","injectScriptWithFallbacks","generateLibUrls","BASE_URLS"],"mappings":";;;;;;;MAUa,iBAAiB,GAAGA,+BAAoB,CACnD,CAAqC,UAAa,KAAI;IACpD,MAAM,SAAS,GAAGC,kBAAO,CAACC,uBAAW,CAAC,CAAC,UAAU,CAAC,CAAC;IAEnD,OAAO,MAAM,sBAAuB,SAAQ,SAAS,CAAA;AACnD,QAAA,IAAI,UAAU,GAAA;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;SAChD;
|
|
1
|
+
{"version":3,"file":"injectNpmLibMixin.js","sources":["../../../../src/mixins/injectNpmLibMixin/injectNpmLibMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport { BASE_URLS } from './constants';\nimport { generateLibUrls, injectScriptWithFallbacks } from './helpers';\n\n// scripts load to window under descope object\ndeclare global {\n var descope: any;\n}\n\nexport const injectNpmLibMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(loggerMixin)(superclass);\n\n return class InjectNpmLibMixinClass extends BaseClass {\n get baseCdnUrl() {\n return this.getAttribute('base-cdn-url') || '';\n }\n\n injectNpmLib(\n libName: string,\n version: string,\n filePath = '',\n overrides: string[] = [],\n integrity?: string,\n ) {\n this.logger.debug(\n `Injecting npm lib: \"${libName}\" with version: \"${version}\"${\n integrity ? ' with SRI integrity check' : ''\n }`,\n );\n return injectScriptWithFallbacks(\n generateLibUrls(\n [...overrides, this.baseCdnUrl, ...BASE_URLS],\n libName,\n version,\n filePath,\n integrity,\n ),\n (scriptData, existingScript) => {\n if (existingScript) {\n this.logger.error(\n `Existing script cannot be loaded: \"${scriptData.url}\"`,\n );\n return;\n }\n this.logger.error(\n `Cannot load script from URL, Make sure this URL is valid and return the correct script: \"${scriptData.url}\"`,\n );\n },\n );\n }\n };\n },\n);\n"],"names":["createSingletonMixin","compose","loggerMixin","injectScriptWithFallbacks","generateLibUrls","BASE_URLS"],"mappings":";;;;;;;MAUa,iBAAiB,GAAGA,+BAAoB,CACnD,CAAqC,UAAa,KAAI;IACpD,MAAM,SAAS,GAAGC,kBAAO,CAACC,uBAAW,CAAC,CAAC,UAAU,CAAC,CAAC;IAEnD,OAAO,MAAM,sBAAuB,SAAQ,SAAS,CAAA;AACnD,QAAA,IAAI,UAAU,GAAA;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;SAChD;AAED,QAAA,YAAY,CACV,OAAe,EACf,OAAe,EACf,QAAQ,GAAG,EAAE,EACb,SAAA,GAAsB,EAAE,EACxB,SAAkB,EAAA;YAElB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,CAAuB,oBAAA,EAAA,OAAO,oBAAoB,OAAO,CAAA,CAAA,EACvD,SAAS,GAAG,2BAA2B,GAAG,EAC5C,CAAE,CAAA,CACH,CAAC;AACF,YAAA,OAAOC,iCAAyB,CAC9BC,uBAAe,CACb,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,GAAGC,mBAAS,CAAC,EAC7C,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,CACV,EACD,CAAC,UAAU,EAAE,cAAc,KAAI;gBAC7B,IAAI,cAAc,EAAE;oBAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,CAAsC,mCAAA,EAAA,UAAU,CAAC,GAAG,CAAG,CAAA,CAAA,CACxD,CAAC;oBACF,OAAO;iBACR;gBACD,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,CAA4F,yFAAA,EAAA,UAAU,CAAC,GAAG,CAAG,CAAA,CAAA,CAC9G,CAAC;AACJ,aAAC,CACF,CAAC;SACH;KACF,CAAC;AACJ,CAAC;;;;"}
|
|
@@ -7,7 +7,7 @@ import { getDescopeUiComponentsList } from './helpers.js';
|
|
|
7
7
|
import { WEB_COMPONENTS_UI_LIB_NAME, JS_FILE_PATH, LOCAL_STORAGE_OVERRIDE } from './constants.js';
|
|
8
8
|
|
|
9
9
|
const descopeUiMixin = createSingletonMixin((superclass) => {
|
|
10
|
-
var _DescopeUiMixinClass_instances, _DescopeUiMixinClass_getComponentsVersion, _DescopeUiMixinClass_descopeUi, _DescopeUiMixinClass_loadDescopeUiComponent, _DescopeUiMixinClass_getDescopeUi, _a;
|
|
10
|
+
var _DescopeUiMixinClass_instances, _DescopeUiMixinClass_getComponentsVersion, _DescopeUiMixinClass_getComponentsVersionSri, _DescopeUiMixinClass_descopeUi, _DescopeUiMixinClass_loadDescopeUiComponent, _DescopeUiMixinClass_getDescopeUi, _a;
|
|
11
11
|
const BaseClass = compose(loggerMixin, configMixin, injectNpmLibMixin)(superclass);
|
|
12
12
|
return _a = class DescopeUiMixinClass extends BaseClass {
|
|
13
13
|
constructor() {
|
|
@@ -44,6 +44,15 @@ const descopeUiMixin = createSingletonMixin((superclass) => {
|
|
|
44
44
|
}
|
|
45
45
|
return componentsVersion;
|
|
46
46
|
},
|
|
47
|
+
_DescopeUiMixinClass_getComponentsVersionSri = async function _DescopeUiMixinClass_getComponentsVersionSri() {
|
|
48
|
+
var _b;
|
|
49
|
+
const config = await this.config;
|
|
50
|
+
const componentsVersionSri = (_b = config === null || config === void 0 ? void 0 : config.projectConfig) === null || _b === void 0 ? void 0 : _b.componentsVersionSri;
|
|
51
|
+
if (componentsVersionSri) {
|
|
52
|
+
this.logger.debug('SRI hash available for components');
|
|
53
|
+
}
|
|
54
|
+
return componentsVersionSri;
|
|
55
|
+
},
|
|
47
56
|
_DescopeUiMixinClass_loadDescopeUiComponent = async function _DescopeUiMixinClass_loadDescopeUiComponent(componentName) {
|
|
48
57
|
const isComponentAlreadyDefined = !!customElements.get(componentName);
|
|
49
58
|
if (isComponentAlreadyDefined) {
|
|
@@ -78,7 +87,9 @@ const descopeUiMixin = createSingletonMixin((superclass) => {
|
|
|
78
87
|
return globalThis.DescopeUI;
|
|
79
88
|
}
|
|
80
89
|
try {
|
|
81
|
-
|
|
90
|
+
const componentsVersion = await __classPrivateFieldGet(this, _DescopeUiMixinClass_instances, "m", _DescopeUiMixinClass_getComponentsVersion).call(this);
|
|
91
|
+
const componentsVersionSri = await __classPrivateFieldGet(this, _DescopeUiMixinClass_instances, "m", _DescopeUiMixinClass_getComponentsVersionSri).call(this);
|
|
92
|
+
await this.injectNpmLib(WEB_COMPONENTS_UI_LIB_NAME, componentsVersion, JS_FILE_PATH, [LOCAL_STORAGE_OVERRIDE], componentsVersionSri);
|
|
82
93
|
this.logger.debug('DescopeUI was loaded');
|
|
83
94
|
return globalThis.DescopeUI;
|
|
84
95
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"descopeUiMixin.js","sources":["../../../../src/mixins/descopeUiMixin/descopeUiMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { configMixin } from '../configMixin';\nimport { injectNpmLibMixin } from '../injectNpmLibMixin';\nimport { loggerMixin } from '../loggerMixin';\nimport { getDescopeUiComponentsList } from './helpers';\nimport {\n JS_FILE_PATH,\n LOCAL_STORAGE_OVERRIDE,\n WEB_COMPONENTS_UI_LIB_NAME,\n} from './constants';\n\nexport const descopeUiMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n configMixin,\n injectNpmLibMixin,\n )(superclass);\n\n return class DescopeUiMixinClass extends BaseClass {\n // eslint-disable-next-line class-methods-use-this\n async #getComponentsVersion() {\n const config = await this.config;\n const componentsVersion = config?.projectConfig?.componentsVersion;\n\n if (!componentsVersion) {\n this.logger.error('Could not get components version');\n } else {\n this.logger.debug(`Got component version \"${componentsVersion}\"`);\n }\n\n return componentsVersion;\n }\n\n #descopeUi: Promise<any>;\n\n get descopeUi() {\n if (!this.#descopeUi) {\n this.#descopeUi = this.#getDescopeUi();\n }\n\n return this.#descopeUi;\n }\n\n async #loadDescopeUiComponent(componentName: string) {\n const isComponentAlreadyDefined = !!customElements.get(componentName);\n\n if (isComponentAlreadyDefined) {\n this.logger.debug(\n `Loading component \"${componentName}\" is skipped as it is already defined`,\n );\n return undefined;\n }\n\n const descopeUI = await this.descopeUi;\n\n if (!descopeUI[componentName]) {\n this.logger.error(\n `Cannot load UI component \"${componentName}\"`,\n `Descope UI does not have a component named \"${componentName}\", available components are: \"${Object.keys(\n descopeUI,\n ).join(', ')}\"`,\n );\n return undefined;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/return-await\n return await descopeUI[componentName]();\n } catch (e) {\n // this error is thrown when trying to register a component which is already registered\n // when running 2 flows on the same page, it might happen that the register fn is called twice\n // in case it happens, we are silently ignore the error\n if (e.name === 'NotSupportedError') {\n // eslint-disable-next-line no-console\n console.debug(\n `Encountered an error while attempting to define the \"${componentName}\" component, it is likely that this component is already defined`,\n );\n } else {\n throw e;\n }\n }\n\n return undefined;\n }\n\n async #getDescopeUi() {\n if (globalThis.DescopeUI) {\n return globalThis.DescopeUI;\n }\n\n try {\n await this.injectNpmLib(\n WEB_COMPONENTS_UI_LIB_NAME,\n
|
|
1
|
+
{"version":3,"file":"descopeUiMixin.js","sources":["../../../../src/mixins/descopeUiMixin/descopeUiMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { configMixin } from '../configMixin';\nimport { injectNpmLibMixin } from '../injectNpmLibMixin';\nimport { loggerMixin } from '../loggerMixin';\nimport { getDescopeUiComponentsList } from './helpers';\nimport {\n JS_FILE_PATH,\n LOCAL_STORAGE_OVERRIDE,\n WEB_COMPONENTS_UI_LIB_NAME,\n} from './constants';\n\nexport const descopeUiMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n configMixin,\n injectNpmLibMixin,\n )(superclass);\n\n return class DescopeUiMixinClass extends BaseClass {\n // eslint-disable-next-line class-methods-use-this\n async #getComponentsVersion() {\n const config = await this.config;\n const componentsVersion = config?.projectConfig?.componentsVersion;\n\n if (!componentsVersion) {\n this.logger.error('Could not get components version');\n } else {\n this.logger.debug(`Got component version \"${componentsVersion}\"`);\n }\n\n return componentsVersion;\n }\n\n async #getComponentsVersionSri() {\n const config = await this.config;\n const componentsVersionSri =\n config?.projectConfig?.componentsVersionSri;\n\n if (componentsVersionSri) {\n this.logger.debug('SRI hash available for components');\n }\n\n return componentsVersionSri;\n }\n\n #descopeUi: Promise<any>;\n\n get descopeUi() {\n if (!this.#descopeUi) {\n this.#descopeUi = this.#getDescopeUi();\n }\n\n return this.#descopeUi;\n }\n\n async #loadDescopeUiComponent(componentName: string) {\n const isComponentAlreadyDefined = !!customElements.get(componentName);\n\n if (isComponentAlreadyDefined) {\n this.logger.debug(\n `Loading component \"${componentName}\" is skipped as it is already defined`,\n );\n return undefined;\n }\n\n const descopeUI = await this.descopeUi;\n\n if (!descopeUI[componentName]) {\n this.logger.error(\n `Cannot load UI component \"${componentName}\"`,\n `Descope UI does not have a component named \"${componentName}\", available components are: \"${Object.keys(\n descopeUI,\n ).join(', ')}\"`,\n );\n return undefined;\n }\n\n try {\n // eslint-disable-next-line @typescript-eslint/return-await\n return await descopeUI[componentName]();\n } catch (e) {\n // this error is thrown when trying to register a component which is already registered\n // when running 2 flows on the same page, it might happen that the register fn is called twice\n // in case it happens, we are silently ignore the error\n if (e.name === 'NotSupportedError') {\n // eslint-disable-next-line no-console\n console.debug(\n `Encountered an error while attempting to define the \"${componentName}\" component, it is likely that this component is already defined`,\n );\n } else {\n throw e;\n }\n }\n\n return undefined;\n }\n\n async #getDescopeUi() {\n if (globalThis.DescopeUI) {\n return globalThis.DescopeUI;\n }\n\n try {\n const componentsVersion = await this.#getComponentsVersion();\n const componentsVersionSri = await this.#getComponentsVersionSri();\n\n await this.injectNpmLib(\n WEB_COMPONENTS_UI_LIB_NAME,\n componentsVersion,\n JS_FILE_PATH,\n [LOCAL_STORAGE_OVERRIDE],\n componentsVersionSri,\n );\n this.logger.debug('DescopeUI was loaded');\n return globalThis.DescopeUI;\n } catch (error) {\n this.logger.error(error);\n throw new Error('DescopeUI was not loaded');\n }\n }\n\n async loadDescopeUiComponents(\n templateOrComponentNames: HTMLTemplateElement | string[],\n ) {\n const descopeUiComponentsList = Array.isArray(templateOrComponentNames)\n ? templateOrComponentNames\n : getDescopeUiComponentsList(templateOrComponentNames);\n\n return Promise.all(\n descopeUiComponentsList.map((componentName: string) =>\n this.#loadDescopeUiComponent(componentName),\n ),\n );\n }\n };\n },\n);\n"],"names":[],"mappings":"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"}
|
|
@@ -17,14 +17,21 @@ const hashUrl = (url) => {
|
|
|
17
17
|
}
|
|
18
18
|
return `${Math.abs(hash).toString()}`;
|
|
19
19
|
};
|
|
20
|
-
const setupScript = (id) => {
|
|
20
|
+
const setupScript = (id, integrity) => {
|
|
21
21
|
const scriptEle = document.createElement('script');
|
|
22
22
|
scriptEle.id = id;
|
|
23
|
+
if (integrity) {
|
|
24
|
+
scriptEle.integrity = integrity;
|
|
25
|
+
scriptEle.crossOrigin = 'anonymous';
|
|
26
|
+
}
|
|
27
|
+
if (window.DESCOPE_NONCE) {
|
|
28
|
+
scriptEle.setAttribute('nonce', window.DESCOPE_NONCE);
|
|
29
|
+
}
|
|
23
30
|
return scriptEle;
|
|
24
31
|
};
|
|
25
|
-
const injectScript = (scriptId, url) => {
|
|
32
|
+
const injectScript = (scriptId, url, integrity) => {
|
|
26
33
|
return new Promise((res, rej) => {
|
|
27
|
-
const scriptEle = setupScript(scriptId);
|
|
34
|
+
const scriptEle = setupScript(scriptId, integrity);
|
|
28
35
|
scriptEle.onerror = (error) => {
|
|
29
36
|
scriptEle.setAttribute('status', 'error');
|
|
30
37
|
rej(error);
|
|
@@ -37,7 +44,13 @@ const injectScript = (scriptId, url) => {
|
|
|
37
44
|
document.body.appendChild(scriptEle);
|
|
38
45
|
});
|
|
39
46
|
};
|
|
40
|
-
const handleExistingScript = (existingScript) => {
|
|
47
|
+
const handleExistingScript = (existingScript, expectedIntegrity) => {
|
|
48
|
+
if (expectedIntegrity) {
|
|
49
|
+
const actualIntegrity = existingScript.integrity;
|
|
50
|
+
if (actualIntegrity !== expectedIntegrity) {
|
|
51
|
+
return Promise.reject(new Error(`Integrity mismatch: expected ${expectedIntegrity}, found ${actualIntegrity}`));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
41
54
|
if (isScriptLoaded(existingScript)) {
|
|
42
55
|
return Promise.resolve(existingScript);
|
|
43
56
|
}
|
|
@@ -55,11 +68,11 @@ const handleExistingScript = (existingScript) => {
|
|
|
55
68
|
};
|
|
56
69
|
const injectScriptWithFallbacks = async (scriptsData, onError) => {
|
|
57
70
|
for (const scriptData of scriptsData) {
|
|
58
|
-
const { id, url } = scriptData;
|
|
71
|
+
const { id, url, integrity } = scriptData;
|
|
59
72
|
const existingScript = getExistingScript(id);
|
|
60
73
|
if (existingScript) {
|
|
61
74
|
try {
|
|
62
|
-
await handleExistingScript(existingScript);
|
|
75
|
+
await handleExistingScript(existingScript, integrity);
|
|
63
76
|
return scriptData;
|
|
64
77
|
}
|
|
65
78
|
catch (e) {
|
|
@@ -68,7 +81,7 @@ const injectScriptWithFallbacks = async (scriptsData, onError) => {
|
|
|
68
81
|
}
|
|
69
82
|
else {
|
|
70
83
|
try {
|
|
71
|
-
await injectScript(id, url);
|
|
84
|
+
await injectScript(id, url, integrity);
|
|
72
85
|
return scriptData;
|
|
73
86
|
}
|
|
74
87
|
catch (e) {
|
|
@@ -78,7 +91,7 @@ const injectScriptWithFallbacks = async (scriptsData, onError) => {
|
|
|
78
91
|
}
|
|
79
92
|
throw new Error('All scripts failed to load');
|
|
80
93
|
};
|
|
81
|
-
const generateLibUrls = (baseUrls, libName, version, path = '') => baseUrls.reduce((prev, curr) => {
|
|
94
|
+
const generateLibUrls = (baseUrls, libName, version, path = '', integrity) => baseUrls.reduce((prev, curr) => {
|
|
82
95
|
const baseUrl = curr;
|
|
83
96
|
if (!baseUrl) {
|
|
84
97
|
return prev;
|
|
@@ -94,15 +107,14 @@ const generateLibUrls = (baseUrls, libName, version, path = '') => baseUrls.redu
|
|
|
94
107
|
if (!isUrlIncludesPath) {
|
|
95
108
|
url.pathname = `/npm/${libName}@${version}/${path}`;
|
|
96
109
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
{
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
];
|
|
110
|
+
const scriptData = {
|
|
111
|
+
url: url,
|
|
112
|
+
id: `npmlib-${libName.replaceAll('@', '').replaceAll('/', '_')}-${hashUrl(url)}`,
|
|
113
|
+
};
|
|
114
|
+
if (integrity) {
|
|
115
|
+
scriptData.integrity = integrity;
|
|
116
|
+
}
|
|
117
|
+
return [...prev, scriptData];
|
|
106
118
|
}, []);
|
|
107
119
|
|
|
108
120
|
export { generateLibUrls, injectScriptWithFallbacks };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sources":["../../../../src/mixins/injectNpmLibMixin/helpers.ts"],"sourcesContent":["const getExistingScript = (scriptId: string): HTMLScriptElement => {\n return document.querySelector(`script#${scriptId}`);\n};\n\nconst isScriptLoaded = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'loaded';\n};\n\nconst isScriptError = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'error';\n};\n\nconst hashUrl = (url: URL) => {\n let hash = 0;\n const urlStr = url.toString();\n\n for (let i = 0; i < urlStr.length; i++) {\n const char = urlStr.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n\n return `${Math.abs(hash).toString()}`;\n};\n\nconst setupScript = (id: string) => {\n const scriptEle = document.createElement('script');\n scriptEle.id = id;\n\n
|
|
1
|
+
{"version":3,"file":"helpers.js","sources":["../../../../src/mixins/injectNpmLibMixin/helpers.ts"],"sourcesContent":["const getExistingScript = (scriptId: string): HTMLScriptElement => {\n return document.querySelector(`script#${scriptId}`);\n};\n\nconst isScriptLoaded = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'loaded';\n};\n\nconst isScriptError = (script: HTMLScriptElement) => {\n return script.getAttribute('status') === 'error';\n};\n\nconst hashUrl = (url: URL) => {\n let hash = 0;\n const urlStr = url.toString();\n\n for (let i = 0; i < urlStr.length; i++) {\n const char = urlStr.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n\n return `${Math.abs(hash).toString()}`;\n};\n\nconst setupScript = (id: string, integrity?: string) => {\n const scriptEle = document.createElement('script');\n scriptEle.id = id;\n\n if (integrity) {\n scriptEle.integrity = integrity;\n scriptEle.crossOrigin = 'anonymous';\n }\n\n if ((window as any).DESCOPE_NONCE) {\n scriptEle.setAttribute('nonce', (window as any).DESCOPE_NONCE);\n }\n\n return scriptEle;\n};\n\nconst injectScript = (scriptId: string, url: URL, integrity?: string) => {\n return new Promise((res, rej) => {\n const scriptEle = setupScript(scriptId, integrity);\n\n scriptEle.onerror = (error) => {\n scriptEle.setAttribute('status', 'error');\n rej(error);\n };\n scriptEle.onload = () => {\n scriptEle.setAttribute('status', 'loaded');\n res(scriptEle);\n };\n\n scriptEle.src = url.toString();\n\n document.body.appendChild(scriptEle);\n });\n};\n\nconst handleExistingScript = (\n existingScript: HTMLScriptElement,\n expectedIntegrity?: string,\n) => {\n if (expectedIntegrity) {\n const actualIntegrity = existingScript.integrity;\n if (actualIntegrity !== expectedIntegrity) {\n return Promise.reject(\n new Error(\n `Integrity mismatch: expected ${expectedIntegrity}, found ${actualIntegrity}`,\n ),\n );\n }\n }\n\n if (isScriptLoaded(existingScript)) {\n return Promise.resolve(existingScript);\n }\n\n if (isScriptError(existingScript)) {\n return Promise.reject();\n }\n\n return new Promise((res, rej) => {\n existingScript.addEventListener('load', () => {\n res(existingScript);\n });\n\n existingScript.addEventListener('error', (error) => {\n rej(error);\n });\n });\n};\n\nexport type ScriptData = {\n id: string;\n url: URL;\n integrity?: string;\n};\n\nexport const injectScriptWithFallbacks = async (\n scriptsData: ScriptData[],\n onError: (scriptData: ScriptData, existingScript: boolean) => void,\n) => {\n for (const scriptData of scriptsData) {\n const { id, url, integrity } = scriptData;\n const existingScript = getExistingScript(id);\n if (existingScript) {\n try {\n await handleExistingScript(existingScript, integrity);\n return scriptData;\n } catch (e) {\n onError(scriptData, true);\n }\n } else {\n try {\n await injectScript(id, url, integrity);\n return scriptData;\n } catch (e) {\n onError(scriptData, false);\n }\n }\n }\n throw new Error('All scripts failed to load');\n};\n\nexport const generateLibUrls = (\n baseUrls: string[],\n libName: string,\n version: string,\n path = '',\n integrity?: string,\n) =>\n baseUrls.reduce((prev, curr) => {\n const baseUrl = curr;\n if (!baseUrl) {\n return prev;\n }\n\n let url: URL;\n try {\n url = new URL(baseUrl);\n } catch (e) {\n throw new Error(`Invalid URL: ${baseUrl}`);\n }\n\n const isUrlIncludesPath = url.pathname !== '/';\n\n if (!isUrlIncludesPath) {\n url.pathname = `/npm/${libName}@${version}/${path}`;\n }\n\n const scriptData: ScriptData = {\n url: url,\n id: `npmlib-${libName.replaceAll('@', '').replaceAll('/', '_')}-${hashUrl(\n url,\n )}`,\n };\n\n if (integrity) {\n scriptData.integrity = integrity;\n }\n\n return [...prev, scriptData];\n }, []);\n"],"names":[],"mappings":"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"}
|
|
@@ -9,9 +9,9 @@ const injectNpmLibMixin = createSingletonMixin((superclass) => {
|
|
|
9
9
|
get baseCdnUrl() {
|
|
10
10
|
return this.getAttribute('base-cdn-url') || '';
|
|
11
11
|
}
|
|
12
|
-
injectNpmLib(libName, version, filePath = '', overrides = []) {
|
|
13
|
-
this.logger.debug(`Injecting npm lib: "${libName}" with version: "${version}"`);
|
|
14
|
-
return injectScriptWithFallbacks(generateLibUrls([...overrides, this.baseCdnUrl, ...BASE_URLS], libName, version, filePath), (scriptData, existingScript) => {
|
|
12
|
+
injectNpmLib(libName, version, filePath = '', overrides = [], integrity) {
|
|
13
|
+
this.logger.debug(`Injecting npm lib: "${libName}" with version: "${version}"${integrity ? ' with SRI integrity check' : ''}`);
|
|
14
|
+
return injectScriptWithFallbacks(generateLibUrls([...overrides, this.baseCdnUrl, ...BASE_URLS], libName, version, filePath, integrity), (scriptData, existingScript) => {
|
|
15
15
|
if (existingScript) {
|
|
16
16
|
this.logger.error(`Existing script cannot be loaded: "${scriptData.url}"`);
|
|
17
17
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectNpmLibMixin.js","sources":["../../../../src/mixins/injectNpmLibMixin/injectNpmLibMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport { BASE_URLS } from './constants';\nimport { generateLibUrls, injectScriptWithFallbacks } from './helpers';\n\n// scripts load to window under descope object\ndeclare global {\n var descope: any;\n}\n\nexport const injectNpmLibMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(loggerMixin)(superclass);\n\n return class InjectNpmLibMixinClass extends BaseClass {\n get baseCdnUrl() {\n return this.getAttribute('base-cdn-url') || '';\n }\n\n injectNpmLib(\n libName: string,\n version: string,\n filePath = '',\n overrides: string[] = [],\n ) {\n this.logger.debug(\n `Injecting npm lib: \"${libName}\" with version: \"${version}\"`,\n );\n return injectScriptWithFallbacks(\n generateLibUrls(\n [...overrides, this.baseCdnUrl, ...BASE_URLS],\n libName,\n version,\n filePath,\n ),\n (scriptData, existingScript) => {\n if (existingScript) {\n this.logger.error(\n `Existing script cannot be loaded: \"${scriptData.url}\"`,\n );\n return;\n }\n this.logger.error(\n `Cannot load script from URL, Make sure this URL is valid and return the correct script: \"${scriptData.url}\"`,\n );\n },\n );\n }\n };\n },\n);\n"],"names":[],"mappings":";;;;;MAUa,iBAAiB,GAAG,oBAAoB,CACnD,CAAqC,UAAa,KAAI;IACpD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC;IAEnD,OAAO,MAAM,sBAAuB,SAAQ,SAAS,CAAA;AACnD,QAAA,IAAI,UAAU,GAAA;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;SAChD;
|
|
1
|
+
{"version":3,"file":"injectNpmLibMixin.js","sources":["../../../../src/mixins/injectNpmLibMixin/injectNpmLibMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport { BASE_URLS } from './constants';\nimport { generateLibUrls, injectScriptWithFallbacks } from './helpers';\n\n// scripts load to window under descope object\ndeclare global {\n var descope: any;\n}\n\nexport const injectNpmLibMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(loggerMixin)(superclass);\n\n return class InjectNpmLibMixinClass extends BaseClass {\n get baseCdnUrl() {\n return this.getAttribute('base-cdn-url') || '';\n }\n\n injectNpmLib(\n libName: string,\n version: string,\n filePath = '',\n overrides: string[] = [],\n integrity?: string,\n ) {\n this.logger.debug(\n `Injecting npm lib: \"${libName}\" with version: \"${version}\"${\n integrity ? ' with SRI integrity check' : ''\n }`,\n );\n return injectScriptWithFallbacks(\n generateLibUrls(\n [...overrides, this.baseCdnUrl, ...BASE_URLS],\n libName,\n version,\n filePath,\n integrity,\n ),\n (scriptData, existingScript) => {\n if (existingScript) {\n this.logger.error(\n `Existing script cannot be loaded: \"${scriptData.url}\"`,\n );\n return;\n }\n this.logger.error(\n `Cannot load script from URL, Make sure this URL is valid and return the correct script: \"${scriptData.url}\"`,\n );\n },\n );\n }\n };\n },\n);\n"],"names":[],"mappings":";;;;;MAUa,iBAAiB,GAAG,oBAAoB,CACnD,CAAqC,UAAa,KAAI;IACpD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC;IAEnD,OAAO,MAAM,sBAAuB,SAAQ,SAAS,CAAA;AACnD,QAAA,IAAI,UAAU,GAAA;YACZ,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;SAChD;AAED,QAAA,YAAY,CACV,OAAe,EACf,OAAe,EACf,QAAQ,GAAG,EAAE,EACb,SAAA,GAAsB,EAAE,EACxB,SAAkB,EAAA;YAElB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,CAAuB,oBAAA,EAAA,OAAO,oBAAoB,OAAO,CAAA,CAAA,EACvD,SAAS,GAAG,2BAA2B,GAAG,EAC5C,CAAE,CAAA,CACH,CAAC;AACF,YAAA,OAAO,yBAAyB,CAC9B,eAAe,CACb,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC,EAC7C,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,CACV,EACD,CAAC,UAAU,EAAE,cAAc,KAAI;gBAC7B,IAAI,cAAc,EAAE;oBAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,CAAsC,mCAAA,EAAA,UAAU,CAAC,GAAG,CAAG,CAAA,CAAA,CACxD,CAAC;oBACF,OAAO;iBACR;gBACD,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,CAA4F,yFAAA,EAAA,UAAU,CAAC,GAAG,CAAG,CAAA,CAAA,CAC9G,CAAC;AACJ,aAAC,CACF,CAAC;SACH;KACF,CAAC;AACJ,CAAC;;;;"}
|