@descope/sdk-mixins 0.25.0 → 0.26.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.
Files changed (51) hide show
  1. package/dist/cjs/index.js +5 -0
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/mixins/componentsConditionsMixin/applier.js +71 -0
  4. package/dist/cjs/mixins/componentsConditionsMixin/applier.js.map +1 -0
  5. package/dist/cjs/mixins/componentsConditionsMixin/componentsConditionsMixin.js +103 -0
  6. package/dist/cjs/mixins/componentsConditionsMixin/componentsConditionsMixin.js.map +1 -0
  7. package/dist/cjs/mixins/telemetryMixin/telemetryMixin.js +34 -8
  8. package/dist/cjs/mixins/telemetryMixin/telemetryMixin.js.map +1 -1
  9. package/dist/esm/index.js +2 -0
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/mixins/componentsConditionsMixin/applier.js +68 -0
  12. package/dist/esm/mixins/componentsConditionsMixin/applier.js.map +1 -0
  13. package/dist/esm/mixins/componentsConditionsMixin/componentsConditionsMixin.js +101 -0
  14. package/dist/esm/mixins/componentsConditionsMixin/componentsConditionsMixin.js.map +1 -0
  15. package/dist/esm/mixins/telemetryMixin/telemetryMixin.js +34 -8
  16. package/dist/esm/mixins/telemetryMixin/telemetryMixin.js.map +1 -1
  17. package/dist/index.d.ts +664 -280
  18. package/dist/types/index.d.ts +1 -0
  19. package/dist/types/mixins/componentsConditionsMixin/applier.d.ts +4 -0
  20. package/dist/types/mixins/componentsConditionsMixin/applier.test.d.ts +1 -0
  21. package/dist/types/mixins/componentsConditionsMixin/componentsConditionsMixin.d.ts +379 -0
  22. package/dist/types/mixins/componentsConditionsMixin/componentsConditionsMixin.test.d.ts +1 -0
  23. package/dist/types/mixins/componentsConditionsMixin/index.d.ts +2 -0
  24. package/dist/types/mixins/configMixin/configMixin.d.ts +14 -14
  25. package/dist/types/mixins/createStateManagementMixin.d.ts +2 -2
  26. package/dist/types/mixins/createValidateAttributesMixin/createValidateAttributesMixin.d.ts +5 -5
  27. package/dist/types/mixins/cspNonceMixin.d.ts +5 -5
  28. package/dist/types/mixins/debuggerMixin/debugger-wc.d.ts +5 -5
  29. package/dist/types/mixins/debuggerMixin/debuggerMixin.d.ts +8 -8
  30. package/dist/types/mixins/descopeUiMixin/descopeUiMixin.d.ts +19 -19
  31. package/dist/types/mixins/fetchWidgetPagesMixin/createFetchWidgetPagesMixin.d.ts +15 -15
  32. package/dist/types/mixins/flowIdMixin.d.ts +5 -5
  33. package/dist/types/mixins/flowInputMixin/flowInputMixin.d.ts +41 -41
  34. package/dist/types/mixins/formMixin.d.ts +2 -2
  35. package/dist/types/mixins/initElementMixin.d.ts +5 -5
  36. package/dist/types/mixins/initLifecycleMixin.d.ts +1 -1
  37. package/dist/types/mixins/injectNpmLibMixin/injectNpmLibMixin.d.ts +2 -2
  38. package/dist/types/mixins/injectStyleMixin.d.ts +5 -5
  39. package/dist/types/mixins/loggerMixin/loggerMixin.d.ts +2 -2
  40. package/dist/types/mixins/modalMixin/modalMixin.d.ts +23 -23
  41. package/dist/types/mixins/notificationsMixin/notificationsMixin.d.ts +23 -23
  42. package/dist/types/mixins/observeAttributesMixin/observeAttributesMixin.d.ts +4 -4
  43. package/dist/types/mixins/projectIdMixin.d.ts +5 -5
  44. package/dist/types/mixins/resetMixin.d.ts +6 -6
  45. package/dist/types/mixins/staticResourcesMixin/staticResourcesMixin.d.ts +10 -10
  46. package/dist/types/mixins/telemetryMixin/telemetryMixin.d.ts +24 -24
  47. package/dist/types/mixins/tenantIdMixin.d.ts +5 -5
  48. package/dist/types/mixins/themeMixin/themeMixin.d.ts +40 -40
  49. package/dist/types/mixins/widgetConfigMixin/widgetConfigMixin.d.ts +14 -14
  50. package/dist/types/mixins/widgetIdMixin.d.ts +5 -5
  51. package/package.json +1 -1
package/dist/cjs/index.js CHANGED
@@ -28,6 +28,8 @@ var injectStyleMixin = require('./mixins/injectStyleMixin.js');
28
28
  var cspNonceMixin = require('./mixins/cspNonceMixin.js');
29
29
  var telemetryMixin = require('./mixins/telemetryMixin/telemetryMixin.js');
30
30
  var flowInputMixin = require('./mixins/flowInputMixin/flowInputMixin.js');
31
+ var componentsConditionsMixin = require('./mixins/componentsConditionsMixin/componentsConditionsMixin.js');
32
+ var applier = require('./mixins/componentsConditionsMixin/applier.js');
31
33
 
32
34
 
33
35
 
@@ -60,4 +62,7 @@ exports.injectStyleMixin = injectStyleMixin.injectStyleMixin;
60
62
  exports.cspNonceMixin = cspNonceMixin.cspNonceMixin;
61
63
  exports.telemetryMixin = telemetryMixin.telemetryMixin;
62
64
  exports.flowInputMixin = flowInputMixin.flowInputMixin;
65
+ exports.componentsConditionsMixin = componentsConditionsMixin.componentsConditionsMixin;
66
+ exports.applyComponentsState = applier.applyComponentsState;
67
+ exports.clearComponentsState = applier.clearComponentsState;
63
68
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ // Applies server-computed component conditions (hide / disable / read-only) to a
4
+ // widget's DOM. Mirrors the flow web-component applier, but targets widget
5
+ // components by their `data-id` (widgets address components that way) and hides
6
+ // via inline style + the `hidden` attribute rather than a `.hidden` class, which
7
+ // widgets do not inject into their shadow DOM.
8
+ const ATTR_SELECTOR_ESCAPE_PATTERN = /(["\\])/g;
9
+ // CSS.escape with a narrow fallback for environments that lack it.
10
+ function escapeSelector(value) {
11
+ if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {
12
+ return CSS.escape(value);
13
+ }
14
+ return value.replace(ATTR_SELECTOR_ESCAPE_PATTERN, '\\$1');
15
+ }
16
+ // IDs can repeat, so match all.
17
+ function findComponents(root, id) {
18
+ return Array.from(root.querySelectorAll(`[data-id="${escapeSelector(id)}"]`));
19
+ }
20
+ function applyAction(el, action) {
21
+ var _a;
22
+ switch (action) {
23
+ case 'hide':
24
+ el.setAttribute('hidden', '');
25
+ (_a = el.style) === null || _a === void 0 ? void 0 : _a.setProperty('display', 'none', 'important');
26
+ break;
27
+ case 'disable':
28
+ el.setAttribute('disabled', 'true');
29
+ break;
30
+ case 'read-only':
31
+ el.setAttribute('readonly', 'true');
32
+ break;
33
+ // Unknown action - ignore. A bad action shouldn't make it past the server.
34
+ }
35
+ }
36
+ function clearAction(el, action) {
37
+ var _a;
38
+ switch (action) {
39
+ case 'hide':
40
+ el.removeAttribute('hidden');
41
+ (_a = el.style) === null || _a === void 0 ? void 0 : _a.removeProperty('display');
42
+ break;
43
+ case 'disable':
44
+ el.removeAttribute('disabled');
45
+ break;
46
+ case 'read-only':
47
+ el.removeAttribute('readonly');
48
+ break;
49
+ // no-op
50
+ }
51
+ }
52
+ /** Applies the componentId -> action map to the matching elements under root. */
53
+ function applyComponentsState(root, componentsState) {
54
+ if (!root || !componentsState)
55
+ return;
56
+ Object.entries(componentsState).forEach(([id, action]) => {
57
+ findComponents(root, id).forEach((el) => applyAction(el, action));
58
+ });
59
+ }
60
+ /** Reverts a previously-applied componentId -> action map. */
61
+ function clearComponentsState(root, componentsState) {
62
+ if (!root || !componentsState)
63
+ return;
64
+ Object.entries(componentsState).forEach(([id, action]) => {
65
+ findComponents(root, id).forEach((el) => clearAction(el, action));
66
+ });
67
+ }
68
+
69
+ exports.applyComponentsState = applyComponentsState;
70
+ exports.clearComponentsState = clearComponentsState;
71
+ //# sourceMappingURL=applier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applier.js","sources":["../../../../src/mixins/componentsConditionsMixin/applier.ts"],"sourcesContent":["// Applies server-computed component conditions (hide / disable / read-only) to a\n// widget's DOM. Mirrors the flow web-component applier, but targets widget\n// components by their `data-id` (widgets address components that way) and hides\n// via inline style + the `hidden` attribute rather than a `.hidden` class, which\n// widgets do not inject into their shadow DOM.\n\nconst ATTR_SELECTOR_ESCAPE_PATTERN = /([\"\\\\])/g;\n\n// CSS.escape with a narrow fallback for environments that lack it.\nfunction escapeSelector(value: string): string {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value);\n }\n return value.replace(ATTR_SELECTOR_ESCAPE_PATTERN, '\\\\$1');\n}\n\n// IDs can repeat, so match all.\nfunction findComponents(root: ParentNode, id: string): Element[] {\n return Array.from(root.querySelectorAll(`[data-id=\"${escapeSelector(id)}\"]`));\n}\n\nfunction applyAction(el: Element, action: string): void {\n switch (action) {\n case 'hide':\n el.setAttribute('hidden', '');\n (el as HTMLElement).style?.setProperty('display', 'none', 'important');\n break;\n case 'disable':\n el.setAttribute('disabled', 'true');\n break;\n case 'read-only':\n el.setAttribute('readonly', 'true');\n break;\n default:\n // Unknown action - ignore. A bad action shouldn't make it past the server.\n }\n}\n\nfunction clearAction(el: Element, action: string): void {\n switch (action) {\n case 'hide':\n el.removeAttribute('hidden');\n (el as HTMLElement).style?.removeProperty('display');\n break;\n case 'disable':\n el.removeAttribute('disabled');\n break;\n case 'read-only':\n el.removeAttribute('readonly');\n break;\n default:\n // no-op\n }\n}\n\n/** Applies the componentId -> action map to the matching elements under root. */\nexport function applyComponentsState(\n root: ParentNode | null | undefined,\n componentsState: Record<string, string> | undefined,\n): void {\n if (!root || !componentsState) return;\n Object.entries(componentsState).forEach(([id, action]) => {\n findComponents(root, id).forEach((el) => applyAction(el, action));\n });\n}\n\n/** Reverts a previously-applied componentId -> action map. */\nexport function clearComponentsState(\n root: ParentNode | null | undefined,\n componentsState: Record<string, string> | undefined,\n): void {\n if (!root || !componentsState) return;\n Object.entries(componentsState).forEach(([id, action]) => {\n findComponents(root, id).forEach((el) => clearAction(el, action));\n });\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ 'use strict';
2
+
3
+ var tslib = require('tslib');
4
+ var sdkHelpers = require('@descope/sdk-helpers');
5
+ var loggerMixin = require('../loggerMixin/loggerMixin.js');
6
+ var initElementMixin = require('../initElementMixin.js');
7
+ var applier = require('./applier.js');
8
+
9
+ const COMPONENTS_STATE_PATH = '/v1/mgmt/widget/components-state';
10
+ /**
11
+ * Shared widget mixin that fetches the server-computed component conditions
12
+ * verdict for the current user and applies hide/disable/read-only to the widget
13
+ * DOM. Server-side only - no client-side re-evaluation. Compose it LAST in a
14
+ * widget's initMixin so its init wraps the widget's render.
15
+ *
16
+ * It reuses the widget's existing web-js-sdk httpClient (`this.api.httpClient`),
17
+ * so `apiMixin` must be composed and `createSdk` must return `httpClient`. A
18
+ * missing client is a wiring mistake, surfaced loudly (throw) rather than
19
+ * silently rendering everything; a runtime fetch failure fails open instead.
20
+ */
21
+ const componentsConditionsMixin = sdkHelpers.createSingletonMixin((superclass) => {
22
+ var _ComponentsConditionsMixinClass_instances, _ComponentsConditionsMixinClass_statePromise, _ComponentsConditionsMixinClass_appliedState, _ComponentsConditionsMixinClass_requireHttpClient, _ComponentsConditionsMixinClass_fetchComponentsState, _a;
23
+ // NB: do not compose initLifecycleMixin here - its empty init() has no
24
+ // super.init() call and would shadow the widget's render init.
25
+ const BaseClass = sdkHelpers.compose(loggerMixin.loggerMixin, initElementMixin.initElementMixin)(superclass);
26
+ return _a = class ComponentsConditionsMixinClass extends BaseClass {
27
+ constructor() {
28
+ super(...arguments);
29
+ _ComponentsConditionsMixinClass_instances.add(this);
30
+ _ComponentsConditionsMixinClass_statePromise.set(this, void 0);
31
+ _ComponentsConditionsMixinClass_appliedState.set(this, {});
32
+ }
33
+ async init() {
34
+ var _b, _c;
35
+ if (this.getAttribute('mock') === 'true') {
36
+ // Mock mode (demos / e2e) has no backend - skip the fetch, hide nothing.
37
+ tslib.__classPrivateFieldSet(this, _ComponentsConditionsMixinClass_statePromise, Promise.resolve({}), "f");
38
+ await ((_b = super.init) === null || _b === void 0 ? void 0 : _b.call(this));
39
+ return;
40
+ }
41
+ // Resolve the client up front so a wiring mistake throws before the
42
+ // fetch's fail-open path can swallow it.
43
+ const httpClient = tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_requireHttpClient).call(this);
44
+ // Fire immediately so it overlaps the page/data fetch super.init runs.
45
+ tslib.__classPrivateFieldSet(this, _ComponentsConditionsMixinClass_statePromise, tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_fetchComponentsState).call(this, httpClient), "f");
46
+ await ((_c = super.init) === null || _c === void 0 ? void 0 : _c.call(this));
47
+ }
48
+ async onWidgetRootReady() {
49
+ var _b, _c;
50
+ // @ts-expect-error onWidgetRootReady is provided by the widget's initWidgetRootMixin
51
+ await ((_b = super.onWidgetRootReady) === null || _b === void 0 ? void 0 : _b.call(this));
52
+ // Apply once the DOM exists and component values are populated, before the
53
+ // widget dispatches 'ready'. Awaiting here bounds any added latency to
54
+ // max(0, conditionsFetch - pageFetch).
55
+ tslib.__classPrivateFieldSet(this, _ComponentsConditionsMixinClass_appliedState, (_c = (await tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_statePromise, "f"))) !== null && _c !== void 0 ? _c : {}, "f");
56
+ applier.applyComponentsState(this.contentRootElement, tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_appliedState, "f"));
57
+ }
58
+ /**
59
+ * Re-fetch and re-apply after the widget mutates data the conditions read
60
+ * (e.g. a profile save). Public hook for the upcoming re-evaluate-on-mutation
61
+ * work - no widget wires it to its mutating flows yet.
62
+ */
63
+ async reevaluateComponentsState() {
64
+ const httpClient = tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_requireHttpClient).call(this);
65
+ applier.clearComponentsState(this.contentRootElement, tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_appliedState, "f"));
66
+ tslib.__classPrivateFieldSet(this, _ComponentsConditionsMixinClass_appliedState, await tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_fetchComponentsState).call(this, httpClient), "f");
67
+ applier.applyComponentsState(this.contentRootElement, tslib.__classPrivateFieldGet(this, _ComponentsConditionsMixinClass_appliedState, "f"));
68
+ }
69
+ },
70
+ _ComponentsConditionsMixinClass_statePromise = new WeakMap(),
71
+ _ComponentsConditionsMixinClass_appliedState = new WeakMap(),
72
+ _ComponentsConditionsMixinClass_instances = new WeakSet(),
73
+ _ComponentsConditionsMixinClass_requireHttpClient = function _ComponentsConditionsMixinClass_requireHttpClient() {
74
+ var _b;
75
+ const httpClient = (_b = this.api) === null || _b === void 0 ? void 0 : _b.httpClient;
76
+ if (!httpClient) {
77
+ // Developer misconfiguration (apiMixin not composed, or createSdk does
78
+ // not expose httpClient) - fail loud so it is caught in development.
79
+ throw new Error('componentsConditionsMixin: the widget sdk must expose `httpClient`. Compose apiMixin and return `webSdk.httpClient` from createSdk.');
80
+ }
81
+ return httpClient;
82
+ },
83
+ _ComponentsConditionsMixinClass_fetchComponentsState = async function _ComponentsConditionsMixinClass_fetchComponentsState(httpClient) {
84
+ var _b;
85
+ try {
86
+ const res = await httpClient.get(COMPONENTS_STATE_PATH);
87
+ if (!(res === null || res === void 0 ? void 0 : res.ok))
88
+ return {};
89
+ const body = await res.json();
90
+ return (_b = body === null || body === void 0 ? void 0 : body.componentsState) !== null && _b !== void 0 ? _b : {};
91
+ }
92
+ catch (e) {
93
+ // Fail open: render everything. UI hiding is presentation, not access
94
+ // control - sensitive data stays gated by the widget's data API.
95
+ this.logger.debug('components-conditions: failed to fetch, showing all components', e === null || e === void 0 ? void 0 : e.message);
96
+ return {};
97
+ }
98
+ },
99
+ _a;
100
+ });
101
+
102
+ exports.componentsConditionsMixin = componentsConditionsMixin;
103
+ //# sourceMappingURL=componentsConditionsMixin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentsConditionsMixin.js","sources":["../../../../src/mixins/componentsConditionsMixin/componentsConditionsMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport { initElementMixin } from '../initElementMixin';\nimport { applyComponentsState, clearComponentsState } from './applier';\n\ntype ComponentsState = Record<string, string>;\n\nconst COMPONENTS_STATE_PATH = '/v1/mgmt/widget/components-state';\n\n// The widget's sdk (built by apiMixin) is expected to expose the client here.\ninterface ComponentsConditionsHost {\n api?: { httpClient?: ConditionsHttpClient };\n}\n\n// Minimal client contract the mixin needs. Widgets expose their existing\n// web-js-sdk httpClient (the same instance used for every other API call),\n// narrowed to this so no web-js-sdk/core-js-sdk type leaks into the widget's\n// public sdk surface. Declared last (with the mixin) to satisfy import/exports-last.\nexport interface ConditionsHttpClient {\n get: (path: string) => Promise<Response>;\n}\n\n/**\n * Shared widget mixin that fetches the server-computed component conditions\n * verdict for the current user and applies hide/disable/read-only to the widget\n * DOM. Server-side only - no client-side re-evaluation. Compose it LAST in a\n * widget's initMixin so its init wraps the widget's render.\n *\n * It reuses the widget's existing web-js-sdk httpClient (`this.api.httpClient`),\n * so `apiMixin` must be composed and `createSdk` must return `httpClient`. A\n * missing client is a wiring mistake, surfaced loudly (throw) rather than\n * silently rendering everything; a runtime fetch failure fails open instead.\n */\nexport const componentsConditionsMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n // NB: do not compose initLifecycleMixin here - its empty init() has no\n // super.init() call and would shadow the widget's render init.\n const BaseClass = compose(loggerMixin, initElementMixin)(superclass);\n\n return class ComponentsConditionsMixinClass extends BaseClass {\n #statePromise?: Promise<ComponentsState>;\n\n #appliedState: ComponentsState = {};\n\n #requireHttpClient(): ConditionsHttpClient {\n const httpClient = (this as unknown as ComponentsConditionsHost).api\n ?.httpClient;\n if (!httpClient) {\n // Developer misconfiguration (apiMixin not composed, or createSdk does\n // not expose httpClient) - fail loud so it is caught in development.\n throw new Error(\n 'componentsConditionsMixin: the widget sdk must expose `httpClient`. Compose apiMixin and return `webSdk.httpClient` from createSdk.',\n );\n }\n return httpClient;\n }\n\n async #fetchComponentsState(\n httpClient: ConditionsHttpClient,\n ): Promise<ComponentsState> {\n try {\n const res = await httpClient.get(COMPONENTS_STATE_PATH);\n if (!res?.ok) return {};\n const body = await res.json();\n return body?.componentsState ?? {};\n } catch (e) {\n // Fail open: render everything. UI hiding is presentation, not access\n // control - sensitive data stays gated by the widget's data API.\n this.logger.debug(\n 'components-conditions: failed to fetch, showing all components',\n (e as Error)?.message,\n );\n return {};\n }\n }\n\n async init() {\n if (this.getAttribute('mock') === 'true') {\n // Mock mode (demos / e2e) has no backend - skip the fetch, hide nothing.\n this.#statePromise = Promise.resolve({});\n await super.init?.();\n return;\n }\n // Resolve the client up front so a wiring mistake throws before the\n // fetch's fail-open path can swallow it.\n const httpClient = this.#requireHttpClient();\n // Fire immediately so it overlaps the page/data fetch super.init runs.\n this.#statePromise = this.#fetchComponentsState(httpClient);\n await super.init?.();\n }\n\n async onWidgetRootReady() {\n // @ts-expect-error onWidgetRootReady is provided by the widget's initWidgetRootMixin\n await super.onWidgetRootReady?.();\n // Apply once the DOM exists and component values are populated, before the\n // widget dispatches 'ready'. Awaiting here bounds any added latency to\n // max(0, conditionsFetch - pageFetch).\n this.#appliedState = (await this.#statePromise) ?? {};\n applyComponentsState(this.contentRootElement, this.#appliedState);\n }\n\n /**\n * Re-fetch and re-apply after the widget mutates data the conditions read\n * (e.g. a profile save). Public hook for the upcoming re-evaluate-on-mutation\n * work - no widget wires it to its mutating flows yet.\n */\n async reevaluateComponentsState() {\n const httpClient = this.#requireHttpClient();\n clearComponentsState(this.contentRootElement, this.#appliedState);\n this.#appliedState = await this.#fetchComponentsState(httpClient);\n applyComponentsState(this.contentRootElement, this.#appliedState);\n }\n };\n },\n);\n"],"names":["createSingletonMixin","compose","loggerMixin","initElementMixin","__classPrivateFieldSet","__classPrivateFieldGet","applyComponentsState","clearComponentsState"],"mappings":"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"}
@@ -200,14 +200,40 @@ const telemetryMixin = sdkHelpers.createSingletonMixin((superclass) => {
200
200
  // The backend ships telemetry nested under `projectConfig` in config.json.
201
201
  const resolvedConfig = await this.config;
202
202
  const beTelemetry = (_b = resolvedConfig === null || resolvedConfig === void 0 ? void 0 : resolvedConfig.projectConfig) === null || _b === void 0 ? void 0 : _b.telemetry;
203
- const sampleRate = Number(process.env.DESCOPE_TELEMETRY_SESSION_SAMPLE_RATE);
204
- const fallback = {
205
- enabled: (process.env.DESCOPE_TELEMETRY_ENABLED || '').toLowerCase() ===
206
- 'true',
207
- rumConfig: Object.assign({ applicationId: process.env.DESCOPE_TELEMETRY_APPLICATION_ID || '', identityPoolId: process.env.DESCOPE_TELEMETRY_IDENTITY_POOL_ID || '', region: process.env.DESCOPE_TELEMETRY_REGION || '', sessionSampleRate: Number.isFinite(sampleRate) && sampleRate > 0 ? sampleRate : 1 }, (process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN && {
208
- guestRoleArn: process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN,
209
- })),
210
- };
203
+ // The DESCOPE_TELEMETRY_* reads below are build-time env tokens: the WC
204
+ // app build substitutes them from .env (rollup.config.app.mjs) and the
205
+ // WC lib build strips them to "" (stubEnvInProd). But @descope/sdk-mixins
206
+ // ships its own dist with these tokens RAW, so a non-WC consumer that
207
+ // bundles this file for the browser hits a bare `process`, which is
208
+ // undefined there -> "ReferenceError: process is not defined".
209
+ // Wrap the reads in try/catch: this keeps the literal `process.env.*`
210
+ // tokens intact (so the WC build-time replace/strip still match them),
211
+ // while falling back to an empty config wherever `process` doesn't
212
+ // exist. Real config comes from the backend (projectConfig.telemetry).
213
+ let fallback;
214
+ try {
215
+ const sampleRate = Number(process.env.DESCOPE_TELEMETRY_SESSION_SAMPLE_RATE);
216
+ fallback = {
217
+ enabled: (process.env.DESCOPE_TELEMETRY_ENABLED || '').toLowerCase() ===
218
+ 'true',
219
+ rumConfig: Object.assign({ applicationId: process.env.DESCOPE_TELEMETRY_APPLICATION_ID || '', identityPoolId: process.env.DESCOPE_TELEMETRY_IDENTITY_POOL_ID || '', region: process.env.DESCOPE_TELEMETRY_REGION || '', sessionSampleRate: Number.isFinite(sampleRate) && sampleRate > 0 ? sampleRate : 1 }, (process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN && {
220
+ guestRoleArn: process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN,
221
+ })),
222
+ };
223
+ }
224
+ catch (_c) {
225
+ // `process` is not defined (browser, no build-time replacement).
226
+ // No .env fallback here - rely on the backend telemetry config.
227
+ fallback = {
228
+ enabled: false,
229
+ rumConfig: {
230
+ applicationId: '',
231
+ identityPoolId: '',
232
+ region: '',
233
+ sessionSampleRate: 1,
234
+ },
235
+ };
236
+ }
211
237
  const cfg = Object.assign(Object.assign(Object.assign({}, fallback), beTelemetry), { rumConfig: Object.assign(Object.assign({}, fallback.rumConfig), beTelemetry === null || beTelemetry === void 0 ? void 0 : beTelemetry.rumConfig), capture: tslib.__classPrivateFieldGet(this, _TelemetryMixinClass_instances, "m", _TelemetryMixinClass_resolveCapture).call(this, beTelemetry === null || beTelemetry === void 0 ? void 0 : beTelemetry.capture) });
212
238
  // If enabled but a required RUM credential is missing (empty from both
213
239
  // the BE block and the .env fallback), disable rather than hand AwsRum
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryMixin.js","sources":["../../../../src/mixins/telemetryMixin/telemetryMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { injectNpmLibMixin } from '../injectNpmLibMixin';\nimport { loggerMixin } from '../loggerMixin';\nimport { TelemetryConfig } from '../configMixin/types';\nimport {\n DEBUG_LOGS_LIB_NAME,\n JS_FILE_PATH,\n LOCAL_STORAGE_OVERRIDE,\n} from './constants';\nimport { initLifecycleMixin } from '../initLifecycleMixin';\nimport { configMixin } from '../configMixin';\nimport { projectIdMixin } from '../projectIdMixin';\nimport { flowIdMixin } from '../flowIdMixin';\n\n// Human-readable delay formatter. Picks the largest unit that fits so logs\n// read as \"30 minutes\" / \"2 days\" instead of \"1800 seconds\" / \"172800 seconds\".\nfunction formatDelay(ms: number): string {\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s} seconds`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m} minutes`;\n const h = Math.floor(m / 60);\n if (h < 24) return `${h} hours`;\n return `${Math.floor(h / 24)} days`;\n}\n\n// Extend global window to include DescopeDebugLogs (UMD global)\ndeclare global {\n interface Window {\n DescopeDebugLogs?: new (config: any, context: any, logger?: any) => any;\n }\n}\n\nexport const telemetryMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n injectNpmLibMixin,\n loggerMixin,\n initLifecycleMixin,\n configMixin,\n projectIdMixin,\n flowIdMixin,\n )(superclass);\n\n return class TelemetryMixinClass extends BaseClass {\n #telemetryManager: any = null;\n #telemetryInitialized = false;\n #expirationTimeoutId: NodeJS.Timeout | null = null;\n\n async #initializeTelemetry(\n config: TelemetryConfig,\n context: {\n projectId: string;\n flowId?: string;\n sdkVersion?: string;\n },\n ) {\n if (!config?.enabled) {\n this.logger.debug('Telemetry is disabled, skipping initialization');\n return;\n }\n\n if (this.#telemetryInitialized) {\n this.logger.debug('Telemetry already initialized');\n return;\n }\n\n if (config.expiration && Date.now() >= config.expiration) {\n this.logger.info(\n `Telemetry expiration time has passed (${new Date(\n config.expiration,\n ).toISOString()}), skipping initialization`,\n );\n return;\n }\n\n try {\n this.logger.debug('Initializing telemetry...');\n const version = config.version || 'latest';\n\n await this.injectNpmLib(DEBUG_LOGS_LIB_NAME, version, JS_FILE_PATH, [\n LOCAL_STORAGE_OVERRIDE,\n ]);\n\n const TelemetryManager = window.DescopeDebugLogs;\n if (!TelemetryManager) {\n throw new Error(\n 'DescopeDebugLogs not found after loading @descope/debug-logs. ' +\n 'This likely means the UMD build failed to load from CDN.',\n );\n }\n\n this.#telemetryManager = new TelemetryManager(\n {\n enabled: true,\n rumConfig: config.rumConfig,\n capture: config.capture,\n },\n {\n projectId: context.projectId,\n flowId: context.flowId,\n version: context.sdkVersion || '1.0.0',\n },\n this.logger,\n );\n\n // The TelemetryManager constructor swallows RUM-client init errors\n // (it sets an internal failure flag instead of throwing). Confirm it\n // actually came up before flagging success - otherwise we'd log\n // \"initialized\" and, because #initializeTelemetry early-returns once\n // #telemetryInitialized is true, permanently block any retry.\n if (!this.#telemetryManager.isReady()) {\n this.logger.error(\n 'Telemetry manager failed to initialize (RUM client not ready)',\n );\n this.#telemetryManager = null;\n return;\n }\n\n this.#telemetryInitialized = true;\n\n this.logger.info('Telemetry initialized successfully');\n\n if (config.expiration) {\n this.#scheduleExpirationShutdown(config.expiration);\n }\n } catch (error) {\n this.logger.error('Failed to initialize telemetry:', error);\n this.#telemetryInitialized = false;\n }\n }\n\n /**\n * Schedule automatic telemetry shutdown at expiration time\n * @param expirationMs - Unix timestamp in milliseconds when telemetry should expire\n */\n #scheduleExpirationShutdown(expirationMs: number) {\n const now = Date.now();\n const timeUntilExpiration = expirationMs - now;\n\n if (timeUntilExpiration <= 0) {\n this.logger.info('Telemetry expiration time reached, shutting down');\n this.#shutdownTelemetry();\n return;\n }\n\n // setTimeout's max safe delay is ~24.8 days; cap at 1 day so a\n // mis-set expiration far in the future doesn't underflow to 0.\n const MAX_TIMEOUT = 86400000;\n const delay = Math.min(timeUntilExpiration, MAX_TIMEOUT);\n\n if (timeUntilExpiration > MAX_TIMEOUT) {\n this.logger.warn(\n `Telemetry expiration is beyond maximum timeout (${formatDelay(\n timeUntilExpiration,\n )}). Setting to maximum.`,\n );\n }\n\n this.logger.info(\n `Telemetry will expire at ${new Date(\n expirationMs,\n ).toISOString()} (in ${formatDelay(delay)})`,\n );\n\n this.#expirationTimeoutId = setTimeout(() => {\n this.logger.info('Telemetry expiration time reached, shutting down');\n this.#shutdownTelemetry();\n }, delay);\n }\n\n #shutdownTelemetry() {\n if (this.#expirationTimeoutId) {\n clearTimeout(this.#expirationTimeoutId);\n this.#expirationTimeoutId = null;\n }\n\n if (this.#telemetryManager) {\n try {\n this.logger.debug('Shutting down telemetry...');\n this.#telemetryManager.shutdown();\n this.#telemetryManager = null;\n this.#telemetryInitialized = false;\n this.logger.info('Telemetry shutdown complete');\n } catch (error) {\n this.logger.error('Error shutting down telemetry:', error);\n }\n }\n }\n\n /**\n * Get the telemetry manager instance (for advanced usage)\n */\n get telemetryManager() {\n return this.#telemetryManager;\n }\n\n // A RUM client needs applicationId, identityPoolId and region. If any is\n // missing, AwsRum either throws at construction or silently records\n // nothing, so we treat the config as unusable.\n #isRumConfigComplete(rumConfig?: TelemetryConfig['rumConfig']): boolean {\n return Boolean(\n rumConfig?.applicationId &&\n rumConfig?.identityPoolId &&\n rumConfig?.region,\n );\n }\n\n async #getTelemetryConfig(): Promise<TelemetryConfig> {\n // Prefer telemetry config shipped by the backend in the project's\n // config.json. Otherwise, fall back to values from\n // packages/sdks/web-component/.env (DESCOPE_TELEMETRY_* — substituted\n // at WC build time via rollup.config.app.mjs). We MERGE rather than\n // replace so the backend can override individual fields (e.g. just\n // expiration) without re-stating every credential.\n // The backend ships telemetry nested under `projectConfig` in config.json.\n const resolvedConfig = await this.config;\n const beTelemetry = resolvedConfig?.projectConfig?.telemetry;\n\n const sampleRate = Number(\n process.env.DESCOPE_TELEMETRY_SESSION_SAMPLE_RATE,\n );\n\n const fallback: NonNullable<TelemetryConfig> = {\n enabled:\n (process.env.DESCOPE_TELEMETRY_ENABLED || '').toLowerCase() ===\n 'true',\n rumConfig: {\n applicationId: process.env.DESCOPE_TELEMETRY_APPLICATION_ID || '',\n identityPoolId:\n process.env.DESCOPE_TELEMETRY_IDENTITY_POOL_ID || '',\n region: process.env.DESCOPE_TELEMETRY_REGION || '',\n sessionSampleRate:\n Number.isFinite(sampleRate) && sampleRate > 0 ? sampleRate : 1,\n ...(process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN && {\n guestRoleArn: process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN,\n }),\n },\n };\n\n const cfg: NonNullable<TelemetryConfig> = {\n ...fallback,\n ...beTelemetry,\n rumConfig: {\n ...fallback.rumConfig,\n ...beTelemetry?.rumConfig,\n },\n capture: this.#resolveCapture(beTelemetry?.capture),\n };\n\n // If enabled but a required RUM credential is missing (empty from both\n // the BE block and the .env fallback), disable rather than hand AwsRum\n // an empty applicationId/identityPoolId/region — that would either\n // throw at construction or silently no-op with no session recorded.\n if (cfg.enabled && !this.#isRumConfigComplete(cfg.rumConfig)) {\n this.logger.warn(\n 'Telemetry enabled but rumConfig is incomplete (applicationId/identityPoolId/region required). Skipping initialization.',\n );\n cfg.enabled = false;\n }\n\n // Safety cap: when no backend telemetry config is present at all,\n // end the session after 5 minutes so dev sessions don't leak. Once\n // the backend owns the config it controls expiration explicitly.\n if (!beTelemetry) {\n cfg.expiration = Date.now() + 5 * 60 * 1000;\n this.logger.debug(\n 'No backend telemetry config present; applying a 5-minute safety cap on the session.',\n );\n }\n\n return cfg;\n }\n\n /**\n * The backend can't serialize a DOM element reference, so we always\n * inject this.shadowRoot here. Respect an explicit `dom: false`.\n */\n #resolveCapture(\n beCapture: NonNullable<TelemetryConfig>['capture'],\n ): NonNullable<TelemetryConfig>['capture'] {\n // `network: true` = capture ALL network traffic. We used to default to\n // `{ urlFilter: [] }` but the two network paths had inverted semantics\n // for the empty array: the custom NetworkPlugin treated it as\n // \"capture everything\", while AWS RUM's built-in HTTP telemetry\n // treated it as \"capture nothing\". `true` is consistent — both paths\n // capture all by default. BE can override with a narrow filter later.\n const domSetting = beCapture?.dom;\n if (domSetting === false) {\n return {\n console: true,\n network: true,\n navigation: true,\n ...beCapture,\n dom: false,\n };\n }\n return {\n console: true,\n network: true,\n navigation: true,\n ...beCapture,\n dom: {\n throttleMs: 2000,\n ...(typeof domSetting === 'object' ? domSetting : {}),\n rootElement: this.shadowRoot as any,\n },\n };\n }\n\n updateTelemetryContext(context: Record<string, any>) {\n if (this.#telemetryManager) {\n try {\n this.#telemetryManager.updateContext(context);\n } catch (error) {\n // Fail silently - telemetry errors should never break the web-component\n this.logger.error('Error updating telemetry context:', error);\n }\n }\n }\n\n #telemetryReady: Promise<void> | null = null;\n\n async init() {\n // super.init() FIRST so downstream mixins finish setup and the\n // SDK's user-facing paint isn't blocked on our CDN load or the\n // `this.config` fetch. Kick off telemetry as its OWN promise chain\n // stored on the instance. NOT awaited here — tests using\n // jest.useFakeTimers can't advance the fetch chain, and blocking on\n // it would freeze the render. Failures are caught so telemetry\n // errors can never break the SDK's boot.\n await super.init?.();\n const sdkVersion = (this as any).sdkVersion || '1.0.0';\n this.#telemetryReady = this.#getTelemetryConfig()\n .then((config) =>\n this.#initializeTelemetry(config as any, {\n projectId: this.projectId,\n flowId: this.flowId,\n sdkVersion,\n }),\n )\n .catch((error) => {\n this.logger.error('Failed to start telemetry:', error);\n });\n }\n\n // Test hook: resolves once telemetry init has settled (success or\n // caught error). Not part of the public SDK contract.\n get telemetryReady(): Promise<void> {\n return this.#telemetryReady ?? Promise.resolve();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback?.();\n this.#shutdownTelemetry();\n }\n };\n },\n);\n"],"names":["createSingletonMixin","compose","injectNpmLibMixin","loggerMixin","initLifecycleMixin","configMixin","projectIdMixin","flowIdMixin","__classPrivateFieldGet","__classPrivateFieldSet","DEBUG_LOGS_LIB_NAME","JS_FILE_PATH","LOCAL_STORAGE_OVERRIDE"],"mappings":"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"}
1
+ {"version":3,"file":"telemetryMixin.js","sources":["../../../../src/mixins/telemetryMixin/telemetryMixin.ts"],"sourcesContent":["import { compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { injectNpmLibMixin } from '../injectNpmLibMixin';\nimport { loggerMixin } from '../loggerMixin';\nimport { TelemetryConfig } from '../configMixin/types';\nimport {\n DEBUG_LOGS_LIB_NAME,\n JS_FILE_PATH,\n LOCAL_STORAGE_OVERRIDE,\n} from './constants';\nimport { initLifecycleMixin } from '../initLifecycleMixin';\nimport { configMixin } from '../configMixin';\nimport { projectIdMixin } from '../projectIdMixin';\nimport { flowIdMixin } from '../flowIdMixin';\n\n// Human-readable delay formatter. Picks the largest unit that fits so logs\n// read as \"30 minutes\" / \"2 days\" instead of \"1800 seconds\" / \"172800 seconds\".\nfunction formatDelay(ms: number): string {\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s} seconds`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m} minutes`;\n const h = Math.floor(m / 60);\n if (h < 24) return `${h} hours`;\n return `${Math.floor(h / 24)} days`;\n}\n\n// Extend global window to include DescopeDebugLogs (UMD global)\ndeclare global {\n interface Window {\n DescopeDebugLogs?: new (config: any, context: any, logger?: any) => any;\n }\n}\n\nexport const telemetryMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n injectNpmLibMixin,\n loggerMixin,\n initLifecycleMixin,\n configMixin,\n projectIdMixin,\n flowIdMixin,\n )(superclass);\n\n return class TelemetryMixinClass extends BaseClass {\n #telemetryManager: any = null;\n #telemetryInitialized = false;\n #expirationTimeoutId: NodeJS.Timeout | null = null;\n\n async #initializeTelemetry(\n config: TelemetryConfig,\n context: {\n projectId: string;\n flowId?: string;\n sdkVersion?: string;\n },\n ) {\n if (!config?.enabled) {\n this.logger.debug('Telemetry is disabled, skipping initialization');\n return;\n }\n\n if (this.#telemetryInitialized) {\n this.logger.debug('Telemetry already initialized');\n return;\n }\n\n if (config.expiration && Date.now() >= config.expiration) {\n this.logger.info(\n `Telemetry expiration time has passed (${new Date(\n config.expiration,\n ).toISOString()}), skipping initialization`,\n );\n return;\n }\n\n try {\n this.logger.debug('Initializing telemetry...');\n const version = config.version || 'latest';\n\n await this.injectNpmLib(DEBUG_LOGS_LIB_NAME, version, JS_FILE_PATH, [\n LOCAL_STORAGE_OVERRIDE,\n ]);\n\n const TelemetryManager = window.DescopeDebugLogs;\n if (!TelemetryManager) {\n throw new Error(\n 'DescopeDebugLogs not found after loading @descope/debug-logs. ' +\n 'This likely means the UMD build failed to load from CDN.',\n );\n }\n\n this.#telemetryManager = new TelemetryManager(\n {\n enabled: true,\n rumConfig: config.rumConfig,\n capture: config.capture,\n },\n {\n projectId: context.projectId,\n flowId: context.flowId,\n version: context.sdkVersion || '1.0.0',\n },\n this.logger,\n );\n\n // The TelemetryManager constructor swallows RUM-client init errors\n // (it sets an internal failure flag instead of throwing). Confirm it\n // actually came up before flagging success - otherwise we'd log\n // \"initialized\" and, because #initializeTelemetry early-returns once\n // #telemetryInitialized is true, permanently block any retry.\n if (!this.#telemetryManager.isReady()) {\n this.logger.error(\n 'Telemetry manager failed to initialize (RUM client not ready)',\n );\n this.#telemetryManager = null;\n return;\n }\n\n this.#telemetryInitialized = true;\n\n this.logger.info('Telemetry initialized successfully');\n\n if (config.expiration) {\n this.#scheduleExpirationShutdown(config.expiration);\n }\n } catch (error) {\n this.logger.error('Failed to initialize telemetry:', error);\n this.#telemetryInitialized = false;\n }\n }\n\n /**\n * Schedule automatic telemetry shutdown at expiration time\n * @param expirationMs - Unix timestamp in milliseconds when telemetry should expire\n */\n #scheduleExpirationShutdown(expirationMs: number) {\n const now = Date.now();\n const timeUntilExpiration = expirationMs - now;\n\n if (timeUntilExpiration <= 0) {\n this.logger.info('Telemetry expiration time reached, shutting down');\n this.#shutdownTelemetry();\n return;\n }\n\n // setTimeout's max safe delay is ~24.8 days; cap at 1 day so a\n // mis-set expiration far in the future doesn't underflow to 0.\n const MAX_TIMEOUT = 86400000;\n const delay = Math.min(timeUntilExpiration, MAX_TIMEOUT);\n\n if (timeUntilExpiration > MAX_TIMEOUT) {\n this.logger.warn(\n `Telemetry expiration is beyond maximum timeout (${formatDelay(\n timeUntilExpiration,\n )}). Setting to maximum.`,\n );\n }\n\n this.logger.info(\n `Telemetry will expire at ${new Date(\n expirationMs,\n ).toISOString()} (in ${formatDelay(delay)})`,\n );\n\n this.#expirationTimeoutId = setTimeout(() => {\n this.logger.info('Telemetry expiration time reached, shutting down');\n this.#shutdownTelemetry();\n }, delay);\n }\n\n #shutdownTelemetry() {\n if (this.#expirationTimeoutId) {\n clearTimeout(this.#expirationTimeoutId);\n this.#expirationTimeoutId = null;\n }\n\n if (this.#telemetryManager) {\n try {\n this.logger.debug('Shutting down telemetry...');\n this.#telemetryManager.shutdown();\n this.#telemetryManager = null;\n this.#telemetryInitialized = false;\n this.logger.info('Telemetry shutdown complete');\n } catch (error) {\n this.logger.error('Error shutting down telemetry:', error);\n }\n }\n }\n\n /**\n * Get the telemetry manager instance (for advanced usage)\n */\n get telemetryManager() {\n return this.#telemetryManager;\n }\n\n // A RUM client needs applicationId, identityPoolId and region. If any is\n // missing, AwsRum either throws at construction or silently records\n // nothing, so we treat the config as unusable.\n #isRumConfigComplete(rumConfig?: TelemetryConfig['rumConfig']): boolean {\n return Boolean(\n rumConfig?.applicationId &&\n rumConfig?.identityPoolId &&\n rumConfig?.region,\n );\n }\n\n async #getTelemetryConfig(): Promise<TelemetryConfig> {\n // Prefer telemetry config shipped by the backend in the project's\n // config.json. Otherwise, fall back to values from\n // packages/sdks/web-component/.env (DESCOPE_TELEMETRY_* — substituted\n // at WC build time via rollup.config.app.mjs). We MERGE rather than\n // replace so the backend can override individual fields (e.g. just\n // expiration) without re-stating every credential.\n // The backend ships telemetry nested under `projectConfig` in config.json.\n const resolvedConfig = await this.config;\n const beTelemetry = resolvedConfig?.projectConfig?.telemetry;\n\n // The DESCOPE_TELEMETRY_* reads below are build-time env tokens: the WC\n // app build substitutes them from .env (rollup.config.app.mjs) and the\n // WC lib build strips them to \"\" (stubEnvInProd). But @descope/sdk-mixins\n // ships its own dist with these tokens RAW, so a non-WC consumer that\n // bundles this file for the browser hits a bare `process`, which is\n // undefined there -> \"ReferenceError: process is not defined\".\n // Wrap the reads in try/catch: this keeps the literal `process.env.*`\n // tokens intact (so the WC build-time replace/strip still match them),\n // while falling back to an empty config wherever `process` doesn't\n // exist. Real config comes from the backend (projectConfig.telemetry).\n let fallback: NonNullable<TelemetryConfig>;\n try {\n const sampleRate = Number(\n process.env.DESCOPE_TELEMETRY_SESSION_SAMPLE_RATE,\n );\n\n fallback = {\n enabled:\n (process.env.DESCOPE_TELEMETRY_ENABLED || '').toLowerCase() ===\n 'true',\n rumConfig: {\n applicationId: process.env.DESCOPE_TELEMETRY_APPLICATION_ID || '',\n identityPoolId:\n process.env.DESCOPE_TELEMETRY_IDENTITY_POOL_ID || '',\n region: process.env.DESCOPE_TELEMETRY_REGION || '',\n sessionSampleRate:\n Number.isFinite(sampleRate) && sampleRate > 0 ? sampleRate : 1,\n ...(process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN && {\n guestRoleArn: process.env.DESCOPE_TELEMETRY_GUEST_ROLE_ARN,\n }),\n },\n };\n } catch {\n // `process` is not defined (browser, no build-time replacement).\n // No .env fallback here - rely on the backend telemetry config.\n fallback = {\n enabled: false,\n rumConfig: {\n applicationId: '',\n identityPoolId: '',\n region: '',\n sessionSampleRate: 1,\n },\n };\n }\n\n const cfg: NonNullable<TelemetryConfig> = {\n ...fallback,\n ...beTelemetry,\n rumConfig: {\n ...fallback.rumConfig,\n ...beTelemetry?.rumConfig,\n },\n capture: this.#resolveCapture(beTelemetry?.capture),\n };\n\n // If enabled but a required RUM credential is missing (empty from both\n // the BE block and the .env fallback), disable rather than hand AwsRum\n // an empty applicationId/identityPoolId/region — that would either\n // throw at construction or silently no-op with no session recorded.\n if (cfg.enabled && !this.#isRumConfigComplete(cfg.rumConfig)) {\n this.logger.warn(\n 'Telemetry enabled but rumConfig is incomplete (applicationId/identityPoolId/region required). Skipping initialization.',\n );\n cfg.enabled = false;\n }\n\n // Safety cap: when no backend telemetry config is present at all,\n // end the session after 5 minutes so dev sessions don't leak. Once\n // the backend owns the config it controls expiration explicitly.\n if (!beTelemetry) {\n cfg.expiration = Date.now() + 5 * 60 * 1000;\n this.logger.debug(\n 'No backend telemetry config present; applying a 5-minute safety cap on the session.',\n );\n }\n\n return cfg;\n }\n\n /**\n * The backend can't serialize a DOM element reference, so we always\n * inject this.shadowRoot here. Respect an explicit `dom: false`.\n */\n #resolveCapture(\n beCapture: NonNullable<TelemetryConfig>['capture'],\n ): NonNullable<TelemetryConfig>['capture'] {\n // `network: true` = capture ALL network traffic. We used to default to\n // `{ urlFilter: [] }` but the two network paths had inverted semantics\n // for the empty array: the custom NetworkPlugin treated it as\n // \"capture everything\", while AWS RUM's built-in HTTP telemetry\n // treated it as \"capture nothing\". `true` is consistent — both paths\n // capture all by default. BE can override with a narrow filter later.\n const domSetting = beCapture?.dom;\n if (domSetting === false) {\n return {\n console: true,\n network: true,\n navigation: true,\n ...beCapture,\n dom: false,\n };\n }\n return {\n console: true,\n network: true,\n navigation: true,\n ...beCapture,\n dom: {\n throttleMs: 2000,\n ...(typeof domSetting === 'object' ? domSetting : {}),\n rootElement: this.shadowRoot as any,\n },\n };\n }\n\n updateTelemetryContext(context: Record<string, any>) {\n if (this.#telemetryManager) {\n try {\n this.#telemetryManager.updateContext(context);\n } catch (error) {\n // Fail silently - telemetry errors should never break the web-component\n this.logger.error('Error updating telemetry context:', error);\n }\n }\n }\n\n #telemetryReady: Promise<void> | null = null;\n\n async init() {\n // super.init() FIRST so downstream mixins finish setup and the\n // SDK's user-facing paint isn't blocked on our CDN load or the\n // `this.config` fetch. Kick off telemetry as its OWN promise chain\n // stored on the instance. NOT awaited here — tests using\n // jest.useFakeTimers can't advance the fetch chain, and blocking on\n // it would freeze the render. Failures are caught so telemetry\n // errors can never break the SDK's boot.\n await super.init?.();\n const sdkVersion = (this as any).sdkVersion || '1.0.0';\n this.#telemetryReady = this.#getTelemetryConfig()\n .then((config) =>\n this.#initializeTelemetry(config as any, {\n projectId: this.projectId,\n flowId: this.flowId,\n sdkVersion,\n }),\n )\n .catch((error) => {\n this.logger.error('Failed to start telemetry:', error);\n });\n }\n\n // Test hook: resolves once telemetry init has settled (success or\n // caught error). Not part of the public SDK contract.\n get telemetryReady(): Promise<void> {\n return this.#telemetryReady ?? Promise.resolve();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback?.();\n this.#shutdownTelemetry();\n }\n };\n },\n);\n"],"names":["createSingletonMixin","compose","injectNpmLibMixin","loggerMixin","initLifecycleMixin","configMixin","projectIdMixin","flowIdMixin","__classPrivateFieldGet","__classPrivateFieldSet","DEBUG_LOGS_LIB_NAME","JS_FILE_PATH","LOCAL_STORAGE_OVERRIDE"],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -26,4 +26,6 @@ export { injectStyleMixin } from './mixins/injectStyleMixin.js';
26
26
  export { cspNonceMixin } from './mixins/cspNonceMixin.js';
27
27
  export { telemetryMixin } from './mixins/telemetryMixin/telemetryMixin.js';
28
28
  export { flowInputMixin } from './mixins/flowInputMixin/flowInputMixin.js';
29
+ export { componentsConditionsMixin } from './mixins/componentsConditionsMixin/componentsConditionsMixin.js';
30
+ export { applyComponentsState, clearComponentsState } from './mixins/componentsConditionsMixin/applier.js';
29
31
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,68 @@
1
+ // Applies server-computed component conditions (hide / disable / read-only) to a
2
+ // widget's DOM. Mirrors the flow web-component applier, but targets widget
3
+ // components by their `data-id` (widgets address components that way) and hides
4
+ // via inline style + the `hidden` attribute rather than a `.hidden` class, which
5
+ // widgets do not inject into their shadow DOM.
6
+ const ATTR_SELECTOR_ESCAPE_PATTERN = /(["\\])/g;
7
+ // CSS.escape with a narrow fallback for environments that lack it.
8
+ function escapeSelector(value) {
9
+ if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {
10
+ return CSS.escape(value);
11
+ }
12
+ return value.replace(ATTR_SELECTOR_ESCAPE_PATTERN, '\\$1');
13
+ }
14
+ // IDs can repeat, so match all.
15
+ function findComponents(root, id) {
16
+ return Array.from(root.querySelectorAll(`[data-id="${escapeSelector(id)}"]`));
17
+ }
18
+ function applyAction(el, action) {
19
+ var _a;
20
+ switch (action) {
21
+ case 'hide':
22
+ el.setAttribute('hidden', '');
23
+ (_a = el.style) === null || _a === void 0 ? void 0 : _a.setProperty('display', 'none', 'important');
24
+ break;
25
+ case 'disable':
26
+ el.setAttribute('disabled', 'true');
27
+ break;
28
+ case 'read-only':
29
+ el.setAttribute('readonly', 'true');
30
+ break;
31
+ // Unknown action - ignore. A bad action shouldn't make it past the server.
32
+ }
33
+ }
34
+ function clearAction(el, action) {
35
+ var _a;
36
+ switch (action) {
37
+ case 'hide':
38
+ el.removeAttribute('hidden');
39
+ (_a = el.style) === null || _a === void 0 ? void 0 : _a.removeProperty('display');
40
+ break;
41
+ case 'disable':
42
+ el.removeAttribute('disabled');
43
+ break;
44
+ case 'read-only':
45
+ el.removeAttribute('readonly');
46
+ break;
47
+ // no-op
48
+ }
49
+ }
50
+ /** Applies the componentId -> action map to the matching elements under root. */
51
+ function applyComponentsState(root, componentsState) {
52
+ if (!root || !componentsState)
53
+ return;
54
+ Object.entries(componentsState).forEach(([id, action]) => {
55
+ findComponents(root, id).forEach((el) => applyAction(el, action));
56
+ });
57
+ }
58
+ /** Reverts a previously-applied componentId -> action map. */
59
+ function clearComponentsState(root, componentsState) {
60
+ if (!root || !componentsState)
61
+ return;
62
+ Object.entries(componentsState).forEach(([id, action]) => {
63
+ findComponents(root, id).forEach((el) => clearAction(el, action));
64
+ });
65
+ }
66
+
67
+ export { applyComponentsState, clearComponentsState };
68
+ //# sourceMappingURL=applier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applier.js","sources":["../../../../src/mixins/componentsConditionsMixin/applier.ts"],"sourcesContent":["// Applies server-computed component conditions (hide / disable / read-only) to a\n// widget's DOM. Mirrors the flow web-component applier, but targets widget\n// components by their `data-id` (widgets address components that way) and hides\n// via inline style + the `hidden` attribute rather than a `.hidden` class, which\n// widgets do not inject into their shadow DOM.\n\nconst ATTR_SELECTOR_ESCAPE_PATTERN = /([\"\\\\])/g;\n\n// CSS.escape with a narrow fallback for environments that lack it.\nfunction escapeSelector(value: string): string {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value);\n }\n return value.replace(ATTR_SELECTOR_ESCAPE_PATTERN, '\\\\$1');\n}\n\n// IDs can repeat, so match all.\nfunction findComponents(root: ParentNode, id: string): Element[] {\n return Array.from(root.querySelectorAll(`[data-id=\"${escapeSelector(id)}\"]`));\n}\n\nfunction applyAction(el: Element, action: string): void {\n switch (action) {\n case 'hide':\n el.setAttribute('hidden', '');\n (el as HTMLElement).style?.setProperty('display', 'none', 'important');\n break;\n case 'disable':\n el.setAttribute('disabled', 'true');\n break;\n case 'read-only':\n el.setAttribute('readonly', 'true');\n break;\n default:\n // Unknown action - ignore. A bad action shouldn't make it past the server.\n }\n}\n\nfunction clearAction(el: Element, action: string): void {\n switch (action) {\n case 'hide':\n el.removeAttribute('hidden');\n (el as HTMLElement).style?.removeProperty('display');\n break;\n case 'disable':\n el.removeAttribute('disabled');\n break;\n case 'read-only':\n el.removeAttribute('readonly');\n break;\n default:\n // no-op\n }\n}\n\n/** Applies the componentId -> action map to the matching elements under root. */\nexport function applyComponentsState(\n root: ParentNode | null | undefined,\n componentsState: Record<string, string> | undefined,\n): void {\n if (!root || !componentsState) return;\n Object.entries(componentsState).forEach(([id, action]) => {\n findComponents(root, id).forEach((el) => applyAction(el, action));\n });\n}\n\n/** Reverts a previously-applied componentId -> action map. */\nexport function clearComponentsState(\n root: ParentNode | null | undefined,\n componentsState: Record<string, string> | undefined,\n): void {\n if (!root || !componentsState) return;\n Object.entries(componentsState).forEach(([id, action]) => {\n findComponents(root, id).forEach((el) => clearAction(el, action));\n });\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { __classPrivateFieldSet, __classPrivateFieldGet } from 'tslib';
2
+ import { createSingletonMixin, compose } from '@descope/sdk-helpers';
3
+ import { loggerMixin } from '../loggerMixin/loggerMixin.js';
4
+ import { initElementMixin } from '../initElementMixin.js';
5
+ import { applyComponentsState, clearComponentsState } from './applier.js';
6
+
7
+ const COMPONENTS_STATE_PATH = '/v1/mgmt/widget/components-state';
8
+ /**
9
+ * Shared widget mixin that fetches the server-computed component conditions
10
+ * verdict for the current user and applies hide/disable/read-only to the widget
11
+ * DOM. Server-side only - no client-side re-evaluation. Compose it LAST in a
12
+ * widget's initMixin so its init wraps the widget's render.
13
+ *
14
+ * It reuses the widget's existing web-js-sdk httpClient (`this.api.httpClient`),
15
+ * so `apiMixin` must be composed and `createSdk` must return `httpClient`. A
16
+ * missing client is a wiring mistake, surfaced loudly (throw) rather than
17
+ * silently rendering everything; a runtime fetch failure fails open instead.
18
+ */
19
+ const componentsConditionsMixin = createSingletonMixin((superclass) => {
20
+ var _ComponentsConditionsMixinClass_instances, _ComponentsConditionsMixinClass_statePromise, _ComponentsConditionsMixinClass_appliedState, _ComponentsConditionsMixinClass_requireHttpClient, _ComponentsConditionsMixinClass_fetchComponentsState, _a;
21
+ // NB: do not compose initLifecycleMixin here - its empty init() has no
22
+ // super.init() call and would shadow the widget's render init.
23
+ const BaseClass = compose(loggerMixin, initElementMixin)(superclass);
24
+ return _a = class ComponentsConditionsMixinClass extends BaseClass {
25
+ constructor() {
26
+ super(...arguments);
27
+ _ComponentsConditionsMixinClass_instances.add(this);
28
+ _ComponentsConditionsMixinClass_statePromise.set(this, void 0);
29
+ _ComponentsConditionsMixinClass_appliedState.set(this, {});
30
+ }
31
+ async init() {
32
+ var _b, _c;
33
+ if (this.getAttribute('mock') === 'true') {
34
+ // Mock mode (demos / e2e) has no backend - skip the fetch, hide nothing.
35
+ __classPrivateFieldSet(this, _ComponentsConditionsMixinClass_statePromise, Promise.resolve({}), "f");
36
+ await ((_b = super.init) === null || _b === void 0 ? void 0 : _b.call(this));
37
+ return;
38
+ }
39
+ // Resolve the client up front so a wiring mistake throws before the
40
+ // fetch's fail-open path can swallow it.
41
+ const httpClient = __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_requireHttpClient).call(this);
42
+ // Fire immediately so it overlaps the page/data fetch super.init runs.
43
+ __classPrivateFieldSet(this, _ComponentsConditionsMixinClass_statePromise, __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_fetchComponentsState).call(this, httpClient), "f");
44
+ await ((_c = super.init) === null || _c === void 0 ? void 0 : _c.call(this));
45
+ }
46
+ async onWidgetRootReady() {
47
+ var _b, _c;
48
+ // @ts-expect-error onWidgetRootReady is provided by the widget's initWidgetRootMixin
49
+ await ((_b = super.onWidgetRootReady) === null || _b === void 0 ? void 0 : _b.call(this));
50
+ // Apply once the DOM exists and component values are populated, before the
51
+ // widget dispatches 'ready'. Awaiting here bounds any added latency to
52
+ // max(0, conditionsFetch - pageFetch).
53
+ __classPrivateFieldSet(this, _ComponentsConditionsMixinClass_appliedState, (_c = (await __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_statePromise, "f"))) !== null && _c !== void 0 ? _c : {}, "f");
54
+ applyComponentsState(this.contentRootElement, __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_appliedState, "f"));
55
+ }
56
+ /**
57
+ * Re-fetch and re-apply after the widget mutates data the conditions read
58
+ * (e.g. a profile save). Public hook for the upcoming re-evaluate-on-mutation
59
+ * work - no widget wires it to its mutating flows yet.
60
+ */
61
+ async reevaluateComponentsState() {
62
+ const httpClient = __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_requireHttpClient).call(this);
63
+ clearComponentsState(this.contentRootElement, __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_appliedState, "f"));
64
+ __classPrivateFieldSet(this, _ComponentsConditionsMixinClass_appliedState, await __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_instances, "m", _ComponentsConditionsMixinClass_fetchComponentsState).call(this, httpClient), "f");
65
+ applyComponentsState(this.contentRootElement, __classPrivateFieldGet(this, _ComponentsConditionsMixinClass_appliedState, "f"));
66
+ }
67
+ },
68
+ _ComponentsConditionsMixinClass_statePromise = new WeakMap(),
69
+ _ComponentsConditionsMixinClass_appliedState = new WeakMap(),
70
+ _ComponentsConditionsMixinClass_instances = new WeakSet(),
71
+ _ComponentsConditionsMixinClass_requireHttpClient = function _ComponentsConditionsMixinClass_requireHttpClient() {
72
+ var _b;
73
+ const httpClient = (_b = this.api) === null || _b === void 0 ? void 0 : _b.httpClient;
74
+ if (!httpClient) {
75
+ // Developer misconfiguration (apiMixin not composed, or createSdk does
76
+ // not expose httpClient) - fail loud so it is caught in development.
77
+ throw new Error('componentsConditionsMixin: the widget sdk must expose `httpClient`. Compose apiMixin and return `webSdk.httpClient` from createSdk.');
78
+ }
79
+ return httpClient;
80
+ },
81
+ _ComponentsConditionsMixinClass_fetchComponentsState = async function _ComponentsConditionsMixinClass_fetchComponentsState(httpClient) {
82
+ var _b;
83
+ try {
84
+ const res = await httpClient.get(COMPONENTS_STATE_PATH);
85
+ if (!(res === null || res === void 0 ? void 0 : res.ok))
86
+ return {};
87
+ const body = await res.json();
88
+ return (_b = body === null || body === void 0 ? void 0 : body.componentsState) !== null && _b !== void 0 ? _b : {};
89
+ }
90
+ catch (e) {
91
+ // Fail open: render everything. UI hiding is presentation, not access
92
+ // control - sensitive data stays gated by the widget's data API.
93
+ this.logger.debug('components-conditions: failed to fetch, showing all components', e === null || e === void 0 ? void 0 : e.message);
94
+ return {};
95
+ }
96
+ },
97
+ _a;
98
+ });
99
+
100
+ export { componentsConditionsMixin };
101
+ //# sourceMappingURL=componentsConditionsMixin.js.map