@finsweet/webflow-apps-utils 1.0.18 → 1.0.20
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/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/ui/components/LoadingScreen.svelte +0 -1
- package/dist/ui/components/button/Button.svelte +0 -1
- package/dist/ui/components/color-picker/ColorPicker.svelte +0 -1
- package/dist/ui/components/color-picker/ColorSelect.svelte +0 -2
- package/dist/ui/components/copy-text/CopyText.svelte +0 -2
- package/dist/ui/components/input/Input.svelte +0 -1
- package/dist/ui/components/layout/Layout.svelte +1 -2
- package/dist/ui/components/layout/examples/ExampleLayout.svelte +3 -3
- package/dist/ui/components/modal/Modal.svelte +0 -1
- package/dist/ui/components/notification/Notification.svelte +2 -2
- package/dist/ui/components/select/Select.svelte +4 -4
- package/dist/ui/components/text/Text.svelte +1 -6
- package/dist/ui/components/tooltip/Tooltip.svelte +1 -1
- package/dist/ui/index.css +1 -0
- package/dist/ui/providers/GlobalProvider.svelte +0 -10
- package/dist/ui/providers/GlobalProviderDemo.svelte +1 -3
- package/dist/ui/router/examples/RouterExample.svelte +0 -1
- package/dist/ui/router/examples/pages/AboutPage.svelte +0 -2
- package/dist/ui/router/examples/pages/HomePage.svelte +0 -2
- package/dist/ui/router/examples/pages/NotFoundPage.svelte +0 -2
- package/dist/ui/router/providers/Link.svelte +0 -1
- package/dist/ui/stores/forms/FormDemo.svelte +1 -5
- package/dist/ui/stores/siteInfo.d.ts +2 -0
- package/dist/ui/utils/api/clipboard/handlePaste.js +1 -3
- package/dist/ui/utils/api/index.d.ts +0 -1
- package/dist/ui/utils/api/index.js +0 -1
- package/dist/ui/utils/diff-mapper/DiffMapperDemo.svelte +2 -3
- package/dist/ui/utils/index.d.ts +0 -1
- package/dist/ui/utils/index.js +0 -1
- package/dist/utils/api/clipboard/handlePaste.js +1 -3
- package/dist/utils/api/index.d.ts +0 -1
- package/dist/utils/api/index.js +0 -1
- package/dist/utils/browser-storage/sessionStorage.js +1 -3
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/webflow-canvas/attributes/getAllWebflowElementAttributes.js +1 -3
- package/dist/utils/webflow-canvas/attributes/getWebflowElementAttribute.js +1 -3
- package/dist/utils/webflow-canvas/attributes/removeWebflowElementAttribute.js +1 -3
- package/dist/utils/webflow-canvas/attributes/setWebflowElementAttribute.js +2 -4
- package/dist/utils/webflow-canvas/findInstanceElement.js +1 -3
- package/dist/utils/webflow-canvas/getAllPages.js +1 -3
- package/package.json +2 -2
- package/dist/types/auth.d.ts +0 -40
- package/dist/types/auth.js +0 -1
- package/dist/ui/utils/api/getFinsweetComponentsEnvironment.d.ts +0 -8
- package/dist/ui/utils/api/getFinsweetComponentsEnvironment.js +0 -66
- package/dist/ui/utils/auth/crossWindowLogin.d.ts +0 -5
- package/dist/ui/utils/auth/crossWindowLogin.js +0 -52
- package/dist/ui/utils/auth/index.d.ts +0 -45
- package/dist/ui/utils/auth/index.js +0 -178
- package/dist/utils/api/getFinsweetComponentsEnvironment.d.ts +0 -8
- package/dist/utils/api/getFinsweetComponentsEnvironment.js +0 -67
- package/dist/utils/logger/index.d.ts +0 -16
- package/dist/utils/logger/index.js +0 -39
package/dist/types/index.d.ts
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -1048,7 +1048,6 @@
|
|
|
1048
1048
|
border-radius: 4px;
|
|
1049
1049
|
color: var(--text1, #ebebeb);
|
|
1050
1050
|
font-size: 11px;
|
|
1051
|
-
font-family: Inter, sans-serif;
|
|
1052
1051
|
font-weight: 400;
|
|
1053
1052
|
line-height: 16px;
|
|
1054
1053
|
outline: none;
|
|
@@ -1068,7 +1067,6 @@
|
|
|
1068
1067
|
.label {
|
|
1069
1068
|
color: var(--text1, #ebebeb);
|
|
1070
1069
|
font-size: 11px;
|
|
1071
|
-
font-family: Inter, sans-serif;
|
|
1072
1070
|
font-weight: 400;
|
|
1073
1071
|
line-height: 16px;
|
|
1074
1072
|
text-align: center;
|
|
@@ -167,7 +167,6 @@
|
|
|
167
167
|
.copy-text__title {
|
|
168
168
|
margin: 0;
|
|
169
169
|
color: var(--text-color-primary, #ffffff);
|
|
170
|
-
font-family: Inter, sans-serif;
|
|
171
170
|
font-size: 12px;
|
|
172
171
|
font-weight: 500;
|
|
173
172
|
line-height: 16px;
|
|
@@ -181,7 +180,6 @@
|
|
|
181
180
|
align-items: flex-start;
|
|
182
181
|
align-self: stretch;
|
|
183
182
|
color: var(--text2);
|
|
184
|
-
font-family: Inter;
|
|
185
183
|
font-size: 12px;
|
|
186
184
|
font-style: normal;
|
|
187
185
|
font-weight: 500;
|
|
@@ -327,7 +327,6 @@
|
|
|
327
327
|
|
|
328
328
|
.tab-text {
|
|
329
329
|
color: inherit;
|
|
330
|
-
font-family: Inter;
|
|
331
330
|
font-size: 11.5px;
|
|
332
331
|
font-style: normal;
|
|
333
332
|
font-weight: 400;
|
|
@@ -402,7 +401,7 @@
|
|
|
402
401
|
|
|
403
402
|
.preview-bar-content span {
|
|
404
403
|
color: var(--actionPrimaryText);
|
|
405
|
-
|
|
404
|
+
|
|
406
405
|
font-size: 11.5px;
|
|
407
406
|
font-style: normal;
|
|
408
407
|
font-weight: 500;
|
|
@@ -462,7 +462,7 @@
|
|
|
462
462
|
font-weight: 500;
|
|
463
463
|
font-size: 11.5px;
|
|
464
464
|
color: var(--text1);
|
|
465
|
-
|
|
465
|
+
|
|
466
466
|
text-align: center;
|
|
467
467
|
}
|
|
468
468
|
|
|
@@ -474,7 +474,7 @@
|
|
|
474
474
|
background: var(--background1);
|
|
475
475
|
color: var(--text1);
|
|
476
476
|
font-size: 11.5px;
|
|
477
|
-
|
|
477
|
+
|
|
478
478
|
box-shadow: var(--boxShadows-input-inner);
|
|
479
479
|
transition: all 0.2s ease;
|
|
480
480
|
}
|
|
@@ -530,7 +530,7 @@
|
|
|
530
530
|
flex: 1;
|
|
531
531
|
font-size: 11.5px;
|
|
532
532
|
color: var(--text1);
|
|
533
|
-
|
|
533
|
+
|
|
534
534
|
line-height: 1.2;
|
|
535
535
|
}
|
|
536
536
|
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
|
|
238
238
|
.message {
|
|
239
239
|
color: var(--text-text-2, #bdbdbd);
|
|
240
|
-
|
|
240
|
+
|
|
241
241
|
font-size: 11px;
|
|
242
242
|
font-style: normal;
|
|
243
243
|
font-weight: 400;
|
|
@@ -252,7 +252,7 @@
|
|
|
252
252
|
|
|
253
253
|
.link {
|
|
254
254
|
color: var(--blue-blue-text, #8ac2ff);
|
|
255
|
-
|
|
255
|
+
|
|
256
256
|
font-size: 11px;
|
|
257
257
|
font-style: normal;
|
|
258
258
|
font-weight: 400;
|
|
@@ -553,7 +553,7 @@
|
|
|
553
553
|
}
|
|
554
554
|
.label .label-name {
|
|
555
555
|
color: var(--text1);
|
|
556
|
-
|
|
556
|
+
|
|
557
557
|
font-size: 11.5px;
|
|
558
558
|
font-style: normal;
|
|
559
559
|
font-weight: 400;
|
|
@@ -566,7 +566,7 @@
|
|
|
566
566
|
|
|
567
567
|
.label .label-description {
|
|
568
568
|
color: var(--text2, #bdbdbd);
|
|
569
|
-
|
|
569
|
+
|
|
570
570
|
font-size: 10px;
|
|
571
571
|
font-style: normal;
|
|
572
572
|
font-weight: 400;
|
|
@@ -645,7 +645,7 @@
|
|
|
645
645
|
gap: 4px;
|
|
646
646
|
align-self: stretch;
|
|
647
647
|
color: var(--text2, #bdbdbd);
|
|
648
|
-
|
|
648
|
+
|
|
649
649
|
font-size: 11px;
|
|
650
650
|
font-style: normal;
|
|
651
651
|
font-weight: 500;
|
|
@@ -679,7 +679,7 @@
|
|
|
679
679
|
gap: 4px;
|
|
680
680
|
align-self: stretch;
|
|
681
681
|
color: var(--text-text-1, #d9d9d9);
|
|
682
|
-
|
|
682
|
+
|
|
683
683
|
font-size: 11px;
|
|
684
684
|
font-style: normal;
|
|
685
685
|
font-weight: 400;
|
|
@@ -813,10 +813,6 @@
|
|
|
813
813
|
{/if}
|
|
814
814
|
|
|
815
815
|
<style>
|
|
816
|
-
.text {
|
|
817
|
-
font-family: inherit;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
816
|
.labels.link {
|
|
821
817
|
cursor: pointer;
|
|
822
818
|
padding: 4px;
|
|
@@ -882,7 +878,6 @@
|
|
|
882
878
|
}
|
|
883
879
|
|
|
884
880
|
* {
|
|
885
|
-
font-family: Inter;
|
|
886
881
|
font-style: normal;
|
|
887
882
|
line-height: 16px;
|
|
888
883
|
letter-spacing: -0.115px;
|
|
@@ -950,7 +945,7 @@
|
|
|
950
945
|
|
|
951
946
|
.popup-description span {
|
|
952
947
|
color: var(--text2, #bdbdbd);
|
|
953
|
-
|
|
948
|
+
|
|
954
949
|
font-size: 11px;
|
|
955
950
|
font-style: normal;
|
|
956
951
|
font-weight: 400;
|
package/dist/ui/index.css
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { getFinsweetComponentsEnvironment } from '../../utils/index.js';
|
|
3
|
-
|
|
4
2
|
import { createGlobalContext, setGlobalContext } from './globalContext.svelte';
|
|
5
3
|
import type { GlobalProviderProps } from './types';
|
|
6
4
|
|
|
@@ -41,14 +39,6 @@
|
|
|
41
39
|
// Create and set the global context
|
|
42
40
|
const globalContext = createGlobalContext(mergedContexts, debug);
|
|
43
41
|
setGlobalContext(globalContext);
|
|
44
|
-
const { development } = getFinsweetComponentsEnvironment();
|
|
45
|
-
|
|
46
|
-
// Development mode debugging
|
|
47
|
-
if (development && typeof window !== 'undefined') {
|
|
48
|
-
globalContext.subscribe((event) => {
|
|
49
|
-
console.log('🌍 Global Context Event:', event);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
42
|
</script>
|
|
53
43
|
|
|
54
44
|
{#if children}{@render children()}{/if}
|
|
@@ -161,7 +161,6 @@
|
|
|
161
161
|
margin: 0 auto;
|
|
162
162
|
background: var(--background1);
|
|
163
163
|
color: var(--text1);
|
|
164
|
-
font-family: var(--font-stack);
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
.start-demo {
|
|
@@ -211,7 +210,7 @@
|
|
|
211
210
|
cursor: pointer;
|
|
212
211
|
font-size: var(--font-size-small);
|
|
213
212
|
font-weight: var(--font-weight-normal);
|
|
214
|
-
|
|
213
|
+
|
|
215
214
|
transition: all 0.2s ease;
|
|
216
215
|
}
|
|
217
216
|
|
|
@@ -252,7 +251,6 @@
|
|
|
252
251
|
border: 1px solid var(--border2);
|
|
253
252
|
padding: var(--padding-tiny);
|
|
254
253
|
border-radius: var(--border-radius);
|
|
255
|
-
font-family: monospace;
|
|
256
254
|
font-size: var(--font-size-small);
|
|
257
255
|
color: var(--text2);
|
|
258
256
|
display: block;
|
|
@@ -290,7 +290,6 @@
|
|
|
290
290
|
cursor: pointer;
|
|
291
291
|
transition: all 0.3s ease;
|
|
292
292
|
width: 100%;
|
|
293
|
-
font-family: inherit;
|
|
294
293
|
font-size: inherit;
|
|
295
294
|
}
|
|
296
295
|
|
|
@@ -553,7 +552,6 @@
|
|
|
553
552
|
|
|
554
553
|
.debug-info p {
|
|
555
554
|
margin: 0.5rem 0;
|
|
556
|
-
font-family: 'SFMono-Regular', Consolas, monospace;
|
|
557
555
|
font-size: 0.875rem;
|
|
558
556
|
color: #495057;
|
|
559
557
|
}
|
|
@@ -169,7 +169,6 @@
|
|
|
169
169
|
background: #e9ecef;
|
|
170
170
|
padding: 0.2rem 0.4rem;
|
|
171
171
|
border-radius: 3px;
|
|
172
|
-
font-family: 'SFMono-Regular', Consolas, monospace;
|
|
173
172
|
font-size: 0.875rem;
|
|
174
173
|
color: #e83e8c;
|
|
175
174
|
}
|
|
@@ -189,7 +188,6 @@
|
|
|
189
188
|
|
|
190
189
|
.debug-info p {
|
|
191
190
|
margin: 0.5rem 0;
|
|
192
|
-
font-family: 'SFMono-Regular', Consolas, monospace;
|
|
193
191
|
font-size: 0.875rem;
|
|
194
192
|
color: #495057;
|
|
195
193
|
}
|
|
@@ -132,7 +132,6 @@
|
|
|
132
132
|
background: #e9ecef;
|
|
133
133
|
padding: 0.2rem 0.4rem;
|
|
134
134
|
border-radius: 3px;
|
|
135
|
-
font-family: 'SFMono-Regular', Consolas, monospace;
|
|
136
135
|
color: #e83e8c;
|
|
137
136
|
font-size: 0.875rem;
|
|
138
137
|
}
|
|
@@ -273,7 +272,6 @@
|
|
|
273
272
|
|
|
274
273
|
.debug-info p {
|
|
275
274
|
margin: 0.5rem 0;
|
|
276
|
-
font-family: 'SFMono-Regular', Consolas, monospace;
|
|
277
275
|
font-size: 0.875rem;
|
|
278
276
|
color: #495057;
|
|
279
277
|
}
|
|
@@ -296,7 +296,6 @@
|
|
|
296
296
|
margin: 0 auto;
|
|
297
297
|
background: var(--background1);
|
|
298
298
|
color: var(--text1);
|
|
299
|
-
font-family: var(--font-stack);
|
|
300
299
|
}
|
|
301
300
|
|
|
302
301
|
.demo-controls {
|
|
@@ -375,7 +374,6 @@
|
|
|
375
374
|
background: var(--background1);
|
|
376
375
|
color: var(--text1);
|
|
377
376
|
font-size: var(--font-size-small);
|
|
378
|
-
font-family: var(--font-stack);
|
|
379
377
|
}
|
|
380
378
|
|
|
381
379
|
input:focus {
|
|
@@ -413,7 +411,7 @@
|
|
|
413
411
|
cursor: pointer;
|
|
414
412
|
font-size: var(--font-size-small);
|
|
415
413
|
font-weight: var(--font-weight-normal);
|
|
416
|
-
|
|
414
|
+
|
|
417
415
|
transition: all 0.2s ease;
|
|
418
416
|
}
|
|
419
417
|
|
|
@@ -509,7 +507,6 @@
|
|
|
509
507
|
background: var(--background3);
|
|
510
508
|
border: 1px solid var(--border2);
|
|
511
509
|
border-radius: var(--border-radius);
|
|
512
|
-
font-family: monospace;
|
|
513
510
|
font-size: var(--font-size-tiny);
|
|
514
511
|
color: var(--text3);
|
|
515
512
|
}
|
|
@@ -519,7 +516,6 @@
|
|
|
519
516
|
border: 1px solid var(--border2);
|
|
520
517
|
padding: var(--padding-tiny);
|
|
521
518
|
border-radius: var(--border-radius);
|
|
522
|
-
font-family: monospace;
|
|
523
519
|
font-size: var(--font-size-tiny);
|
|
524
520
|
color: var(--text2);
|
|
525
521
|
display: block;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getLogger } from '../../../../utils/logger';
|
|
2
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
1
|
/**
|
|
4
2
|
* Processes pasted component data to validate Finsweet components.
|
|
5
3
|
*/
|
|
@@ -38,7 +36,7 @@ export const handlePasteXSCP = (e, component) => {
|
|
|
38
36
|
});
|
|
39
37
|
}
|
|
40
38
|
catch (error) {
|
|
41
|
-
|
|
39
|
+
console.error({}, 'handlePasteXSCP failed with error', error);
|
|
42
40
|
webflow.notify({
|
|
43
41
|
type: 'Error',
|
|
44
42
|
message: 'Invalid! You can only paste valid Finsweet Components.'
|
|
@@ -234,7 +234,7 @@ See console for the complete diff structure.
|
|
|
234
234
|
<style>
|
|
235
235
|
.demo-container {
|
|
236
236
|
padding: var(--spacing-24);
|
|
237
|
-
|
|
237
|
+
|
|
238
238
|
background: var(--background1);
|
|
239
239
|
color: var(--text1);
|
|
240
240
|
max-width: 800px;
|
|
@@ -261,7 +261,7 @@ See console for the complete diff structure.
|
|
|
261
261
|
cursor: pointer;
|
|
262
262
|
font-size: var(--font-size-small);
|
|
263
263
|
font-weight: var(--font-weight-normal);
|
|
264
|
-
|
|
264
|
+
|
|
265
265
|
transition: all 0.2s ease;
|
|
266
266
|
margin: var(--spacing-8) 0;
|
|
267
267
|
}
|
|
@@ -284,7 +284,6 @@ See console for the complete diff structure.
|
|
|
284
284
|
margin-top: var(--spacing-12);
|
|
285
285
|
white-space: pre-wrap;
|
|
286
286
|
border-radius: var(--border-radius);
|
|
287
|
-
font-family: monospace;
|
|
288
287
|
color: var(--text2);
|
|
289
288
|
font-size: var(--font-size-small);
|
|
290
289
|
}
|
package/dist/ui/utils/index.d.ts
CHANGED
package/dist/ui/utils/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getLogger } from '../../logger';
|
|
2
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
1
|
/**
|
|
4
2
|
* Processes pasted component data to validate Finsweet components.
|
|
5
3
|
*/
|
|
@@ -38,7 +36,7 @@ export const handlePasteXSCP = (e, component) => {
|
|
|
38
36
|
});
|
|
39
37
|
}
|
|
40
38
|
catch (error) {
|
|
41
|
-
|
|
39
|
+
console.error({}, 'handlePasteXSCP failed with error', error);
|
|
42
40
|
webflow.notify({
|
|
43
41
|
type: 'Error',
|
|
44
42
|
message: 'Invalid! You can only paste valid Finsweet Components.'
|
package/dist/utils/api/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Checks if sessionStorage is available in the current environment.
|
|
3
3
|
*/
|
|
4
|
-
import { getLogger } from '../logger';
|
|
5
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
6
4
|
export const isSessionStorageAvailable = () => {
|
|
7
5
|
try {
|
|
8
6
|
// Attempt to access sessionStorage
|
|
@@ -12,7 +10,7 @@ export const isSessionStorageAvailable = () => {
|
|
|
12
10
|
return true;
|
|
13
11
|
}
|
|
14
12
|
catch (e) {
|
|
15
|
-
|
|
13
|
+
console.error({}, 'Error! window.sessionStorage is not available your browser setting, please check if you have disabled third party cookies and/or site data.', e);
|
|
16
14
|
return false;
|
|
17
15
|
}
|
|
18
16
|
};
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getLogger } from '../../logger';
|
|
2
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
1
|
/**
|
|
4
2
|
* Gets all custom attributes from a Webflow element.
|
|
5
3
|
*/
|
|
@@ -11,7 +9,7 @@ export const getAllWebflowElementAttributes = async (element) => {
|
|
|
11
9
|
return null;
|
|
12
10
|
}
|
|
13
11
|
catch (error) {
|
|
14
|
-
|
|
12
|
+
console.error({}, 'Error in getAllWebflowElementAttributes:', error);
|
|
15
13
|
return null;
|
|
16
14
|
}
|
|
17
15
|
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getLogger } from '../../logger';
|
|
2
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
1
|
/**
|
|
4
2
|
* Gets the value of a custom attribute from a Webflow element.
|
|
5
3
|
*/
|
|
@@ -16,7 +14,7 @@ export const getWebflowElementAttribute = async (element, attributeName) => {
|
|
|
16
14
|
return null;
|
|
17
15
|
}
|
|
18
16
|
catch (error) {
|
|
19
|
-
|
|
17
|
+
console.error({}, 'Error in getWebflowElementAttribute:', error);
|
|
20
18
|
return null;
|
|
21
19
|
}
|
|
22
20
|
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getLogger } from '../../logger';
|
|
2
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
1
|
/**
|
|
4
2
|
* Removes a custom attribute from a Webflow element.
|
|
5
3
|
*/
|
|
@@ -28,7 +26,7 @@ export const removeWebflowElementAttribute = async (element, attributeName, noti
|
|
|
28
26
|
return;
|
|
29
27
|
}
|
|
30
28
|
catch (error) {
|
|
31
|
-
|
|
29
|
+
console.error('Error in removeWebflowElementAttribute:', error);
|
|
32
30
|
return null;
|
|
33
31
|
}
|
|
34
32
|
};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { getLogger } from '../../logger';
|
|
2
1
|
import { getWebflowElementAttribute } from './getWebflowElementAttribute';
|
|
3
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
4
2
|
/**
|
|
5
3
|
* Sets a custom attribute value on a Webflow element.
|
|
6
4
|
*/
|
|
@@ -8,7 +6,7 @@ export const setWebflowElementAttribute = async (element, attributeName, attribu
|
|
|
8
6
|
try {
|
|
9
7
|
const attributeExists = await checkAttribute(element, attributeName, attributeValue);
|
|
10
8
|
if (attributeExists) {
|
|
11
|
-
|
|
9
|
+
console.error(`Attribute ${attributeName}="${attributeValue}" already exists on the element. Exiting`);
|
|
12
10
|
return;
|
|
13
11
|
}
|
|
14
12
|
if (element?.customAttributes) {
|
|
@@ -34,7 +32,7 @@ export const setWebflowElementAttribute = async (element, attributeName, attribu
|
|
|
34
32
|
return;
|
|
35
33
|
}
|
|
36
34
|
catch (error) {
|
|
37
|
-
|
|
35
|
+
console.error('Error in setWebflowElementAttribute:', error);
|
|
38
36
|
return;
|
|
39
37
|
}
|
|
40
38
|
};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { noop } from '../helpers';
|
|
2
|
-
import { getLogger } from '../logger';
|
|
3
2
|
import { getWebflowElementAttribute } from './attributes';
|
|
4
|
-
const logger = getLogger('utils');
|
|
5
3
|
/**
|
|
6
4
|
* Exits the current component context.
|
|
7
5
|
*/
|
|
@@ -132,7 +130,7 @@ export const findInstanceElement = async ({ targetIndex, instance, component, al
|
|
|
132
130
|
return null;
|
|
133
131
|
}
|
|
134
132
|
catch (error) {
|
|
135
|
-
|
|
133
|
+
console.error({}, 'Error in findInstanceInsideOrOutsideComponent:', error);
|
|
136
134
|
throw error;
|
|
137
135
|
}
|
|
138
136
|
};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getLogger } from '../logger';
|
|
2
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
1
|
let pageStagingUrl;
|
|
4
2
|
/**
|
|
5
3
|
* Generates a slug for a page or folder.
|
|
@@ -80,7 +78,7 @@ export const getAllPages = async (pagesAndFolders, kind) => {
|
|
|
80
78
|
return pagesOnly;
|
|
81
79
|
}
|
|
82
80
|
catch (error) {
|
|
83
|
-
|
|
81
|
+
console.error({}, 'getAllPages failed with an error:', error);
|
|
84
82
|
return [];
|
|
85
83
|
}
|
|
86
84
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finsweet/webflow-apps-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"description": "Shared utilities for Webflow apps",
|
|
5
5
|
"homepage": "https://github.com/finsweet/webflow-apps-utils",
|
|
6
6
|
"repository": {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@types/node": "^22",
|
|
63
63
|
"@vitest/browser": "3.2.3",
|
|
64
64
|
"@vitest/coverage-v8": "3.2.3",
|
|
65
|
-
"@webflow/designer-extension-typings": "
|
|
65
|
+
"@webflow/designer-extension-typings": "latest",
|
|
66
66
|
"eslint": "^9.18.0",
|
|
67
67
|
"eslint-config-prettier": "^10.0.1",
|
|
68
68
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
package/dist/types/auth.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export interface Subscription {
|
|
2
|
-
id: string;
|
|
3
|
-
product_id: string;
|
|
4
|
-
price_id: string;
|
|
5
|
-
status: string;
|
|
6
|
-
canceled_at: number | null;
|
|
7
|
-
current_period_end: number | null;
|
|
8
|
-
current_period_start: number | null;
|
|
9
|
-
metadata: SubscriptionMetadata;
|
|
10
|
-
}
|
|
11
|
-
export interface SubscriptionMetadata {
|
|
12
|
-
siteId: string;
|
|
13
|
-
rewardful: string;
|
|
14
|
-
siteUrl: string;
|
|
15
|
-
siteHostname: string;
|
|
16
|
-
}
|
|
17
|
-
export interface FinsweetAuth {
|
|
18
|
-
access_token: string;
|
|
19
|
-
expires_in: number;
|
|
20
|
-
id_token: string;
|
|
21
|
-
refresh_token: string;
|
|
22
|
-
scope: string;
|
|
23
|
-
token_type: string;
|
|
24
|
-
expires: number;
|
|
25
|
-
user: {
|
|
26
|
-
userId: string;
|
|
27
|
-
firstname: string;
|
|
28
|
-
admin: boolean;
|
|
29
|
-
auth0Id: string;
|
|
30
|
-
premium: boolean;
|
|
31
|
-
role: string;
|
|
32
|
-
libraryAccess: ('canFavourite' | 'canManageLibrary')[] | null;
|
|
33
|
-
folders: {
|
|
34
|
-
favourites: number;
|
|
35
|
-
configs: number;
|
|
36
|
-
savedComponents: number;
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
subscriptions: Subscription[];
|
|
40
|
-
}
|
package/dist/types/auth.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { COMPONENTS_CORE_SCRIPT, COMPONENTS_CORE_SCRIPT_LOCAL, COMPONENTS_SERVER_DEV_ENDPOINT, COMPONENTS_SERVER_DEV_ENDPOINT_LOCAL, COMPONENTS_SERVER_PROD_ENDPOINT, getLocalStorage } from '../../../utils';
|
|
2
|
-
const DEV_MODE_KEY = 'fsComponentsDevMode';
|
|
3
|
-
const DEV_MODE_SCRIPT_KEY = 'fsComponentsDevModeScript';
|
|
4
|
-
const DEV_MODE_API_KEY = 'fsComponentsDevModeApi';
|
|
5
|
-
const URL_DEV_MODE_KEY = 'dev';
|
|
6
|
-
const URL_DEV_MODE_SCRIPT_KEY = 'script';
|
|
7
|
-
const URL_DEV_MODE_API_KEY = 'api';
|
|
8
|
-
let lastLogTime = 0;
|
|
9
|
-
const LOG_THROTTLE_MS = 3000;
|
|
10
|
-
/**
|
|
11
|
-
* Gets a parameter value from the URL search params.
|
|
12
|
-
*/
|
|
13
|
-
const getUrlParam = (key) => {
|
|
14
|
-
if (typeof window === 'undefined')
|
|
15
|
-
return null;
|
|
16
|
-
try {
|
|
17
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
18
|
-
return urlParams.get(key);
|
|
19
|
-
}
|
|
20
|
-
catch (e) {
|
|
21
|
-
console.error('Error getting URL parameter:', e);
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Throttled console log that only logs once within the throttle interval.
|
|
27
|
-
*/
|
|
28
|
-
const throttledLog = (message, data) => {
|
|
29
|
-
const now = Date.now();
|
|
30
|
-
if (now - lastLogTime >= LOG_THROTTLE_MS) {
|
|
31
|
-
console.log(message, data || '');
|
|
32
|
-
lastLogTime = now;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Gets the Finsweet components environment configuration.
|
|
37
|
-
*/
|
|
38
|
-
export const getFinsweetComponentsEnvironment = () => {
|
|
39
|
-
const devFromUrl = getUrlParam(URL_DEV_MODE_KEY);
|
|
40
|
-
const scriptFromUrl = getUrlParam(URL_DEV_MODE_SCRIPT_KEY);
|
|
41
|
-
const apiFromUrl = getUrlParam(URL_DEV_MODE_API_KEY);
|
|
42
|
-
const dev = devFromUrl !== null ? devFromUrl === 'true' : getLocalStorage(DEV_MODE_KEY) === 'true';
|
|
43
|
-
let script = scriptFromUrl || getLocalStorage(DEV_MODE_SCRIPT_KEY) || COMPONENTS_CORE_SCRIPT;
|
|
44
|
-
let api = dev
|
|
45
|
-
? apiFromUrl || getLocalStorage(DEV_MODE_API_KEY) || COMPONENTS_SERVER_DEV_ENDPOINT
|
|
46
|
-
: COMPONENTS_SERVER_PROD_ENDPOINT;
|
|
47
|
-
const isBrowser = typeof window !== 'undefined';
|
|
48
|
-
const isLocalhost = isBrowser && window?.location?.hostname?.includes('localhost');
|
|
49
|
-
//if localhost then use local scripts
|
|
50
|
-
if (isLocalhost) {
|
|
51
|
-
script = COMPONENTS_CORE_SCRIPT_LOCAL;
|
|
52
|
-
api = COMPONENTS_SERVER_DEV_ENDPOINT_LOCAL;
|
|
53
|
-
}
|
|
54
|
-
const development = !!dev || isLocalhost;
|
|
55
|
-
if (development) {
|
|
56
|
-
throttledLog(`\n\nFinsweet Components Environment:
|
|
57
|
-
- API: ${api}
|
|
58
|
-
- Core script: ${script}
|
|
59
|
-
- Development mode: ${development ? 'Yes' : 'No'}\n\n`);
|
|
60
|
-
}
|
|
61
|
-
return {
|
|
62
|
-
development,
|
|
63
|
-
coreScript: script,
|
|
64
|
-
api
|
|
65
|
-
};
|
|
66
|
-
};
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { AUTH0_AUDIENCE, AUTH0_CLIENT_ID, AUTH0_LOGIN_URL, AUTH0_REDIRECT_URL, AUTH0_SCOPE, PROD_FINSWEEET_ACCOUNTS_ORIGIN } from '../../../utils/constants';
|
|
2
|
-
/**
|
|
3
|
-
* Opens a popup window for cross-window authentication with Auth0.
|
|
4
|
-
*/
|
|
5
|
-
export const crossWindowLogin = () => {
|
|
6
|
-
return new Promise((resolve, reject) => {
|
|
7
|
-
const timeout = setTimeout(() => {
|
|
8
|
-
window.removeEventListener('message', handleMessage);
|
|
9
|
-
reject(new Error('Login timed out'));
|
|
10
|
-
}, 30000);
|
|
11
|
-
const handleMessage = (e) => {
|
|
12
|
-
if (e.origin !== PROD_FINSWEEET_ACCOUNTS_ORIGIN) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
clearTimeout(timeout);
|
|
16
|
-
window.removeEventListener('message', handleMessage);
|
|
17
|
-
if (e.data && e.data.access_token) {
|
|
18
|
-
resolve(e.data);
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
reject(new Error('Invalid data received'));
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
window.addEventListener('message', handleMessage);
|
|
25
|
-
// Open popup
|
|
26
|
-
const { outerWidth, outerHeight, screenX, screenY } = window;
|
|
27
|
-
const width = 512;
|
|
28
|
-
const height = outerHeight / 2;
|
|
29
|
-
const left = screenX + (outerWidth - width) / 2;
|
|
30
|
-
const top = screenY + (outerHeight - height) / 2;
|
|
31
|
-
const finsweetUrl = new URL(AUTH0_LOGIN_URL);
|
|
32
|
-
finsweetUrl.searchParams.set('response_type', 'code');
|
|
33
|
-
finsweetUrl.searchParams.set('client_id', AUTH0_CLIENT_ID);
|
|
34
|
-
finsweetUrl.searchParams.set('redirect_uri', AUTH0_REDIRECT_URL);
|
|
35
|
-
finsweetUrl.searchParams.set('scope', AUTH0_SCOPE);
|
|
36
|
-
finsweetUrl.searchParams.set('audience', AUTH0_AUDIENCE);
|
|
37
|
-
const popup = window.open(finsweetUrl.toString(), 'Finsweet Account', `width=${width},height=${height},left=${left},top=${top}`);
|
|
38
|
-
if (!popup) {
|
|
39
|
-
clearTimeout(timeout);
|
|
40
|
-
reject(new Error('Failed to open popup'));
|
|
41
|
-
}
|
|
42
|
-
// Check if popup is closed
|
|
43
|
-
const checkPopupClosed = setInterval(() => {
|
|
44
|
-
if (popup?.closed) {
|
|
45
|
-
clearInterval(checkPopupClosed);
|
|
46
|
-
clearTimeout(timeout);
|
|
47
|
-
window.removeEventListener('message', handleMessage);
|
|
48
|
-
reject(new Error('Login popup was closed'));
|
|
49
|
-
}
|
|
50
|
-
}, 1000);
|
|
51
|
-
});
|
|
52
|
-
};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { FinsweetAuth } from '../../../types';
|
|
2
|
-
/**
|
|
3
|
-
* Store for the Finsweet user data.
|
|
4
|
-
*/
|
|
5
|
-
export declare const finsweetUser: import("svelte/store").Writable<FinsweetAuth | null>;
|
|
6
|
-
export declare const isLoggingIn: import("svelte/store").Writable<boolean>;
|
|
7
|
-
/**
|
|
8
|
-
* Fetches user subscriptions from the server.
|
|
9
|
-
*/
|
|
10
|
-
export declare const getSubscriptions: (token: string) => Promise<any>;
|
|
11
|
-
/**
|
|
12
|
-
* Fetches user data from the authentication server.
|
|
13
|
-
*/
|
|
14
|
-
export declare const getUser: (token: string) => Promise<FinsweetAuth["user"]>;
|
|
15
|
-
/**
|
|
16
|
-
* Handles user login authentication flow.
|
|
17
|
-
*/
|
|
18
|
-
export declare const handleLogin: () => Promise<void>;
|
|
19
|
-
/**
|
|
20
|
-
* Handles user logout and cleanup.
|
|
21
|
-
*/
|
|
22
|
-
export declare const handleLogout: () => Promise<void>;
|
|
23
|
-
/**
|
|
24
|
-
* Checks if the user is logged in by validating stored session.
|
|
25
|
-
*/
|
|
26
|
-
export declare const checkInitialLoginState: () => Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* Sets a cookie with security options.
|
|
29
|
-
*/
|
|
30
|
-
export declare const setCookie: (name: string, value: string, options?: {}) => void;
|
|
31
|
-
/**
|
|
32
|
-
* Gets a cookie value by name.
|
|
33
|
-
*/
|
|
34
|
-
export declare const getCookie: (name: string) => string | undefined;
|
|
35
|
-
/**
|
|
36
|
-
* Deletes a cookie by name.
|
|
37
|
-
*/
|
|
38
|
-
export declare const deleteCookie: (name: string, options?: {}) => void;
|
|
39
|
-
/**
|
|
40
|
-
* Checks if the user has access to a specific feature.
|
|
41
|
-
*/
|
|
42
|
-
export declare const canAccessFeature: (loggedIn: boolean, access: FinsweetAuth["user"]["libraryAccess"] | null | undefined, required: FinsweetAuth["user"]["libraryAccess"]) => {
|
|
43
|
-
granted: boolean;
|
|
44
|
-
message: string;
|
|
45
|
-
};
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
import Cookies from 'js-cookie';
|
|
3
|
-
import { get, writable } from 'svelte/store';
|
|
4
|
-
import { getLocalStorage, removeLocalStorage, setLocalStorage } from '../../../utils';
|
|
5
|
-
import { FINSWEET_SUBSCRIPTIONS_ENDPOINT, FINSWEET_SUBSCRIPTIONS_ENDPOINT_STAGING } from '../../../utils/constants';
|
|
6
|
-
import { getFinsweetComponentsEnvironment } from '../api';
|
|
7
|
-
import { crossWindowLogin } from './crossWindowLogin';
|
|
8
|
-
/**
|
|
9
|
-
* Store for the Finsweet user data.
|
|
10
|
-
*/
|
|
11
|
-
export const finsweetUser = writable();
|
|
12
|
-
export const isLoggingIn = writable();
|
|
13
|
-
const checkLibraryAccess = (user, subscriptions) => {
|
|
14
|
-
// const fullAccess: FinsweetAuth['user']['libraryAccess'] = ['canFavourite', 'canManageLibrary'];
|
|
15
|
-
// if (user.admin || user.role === 'agency') {
|
|
16
|
-
// return fullAccess;
|
|
17
|
-
// }
|
|
18
|
-
// // cutoff date timestamp for June 5, 2024 00:00:00 UTC
|
|
19
|
-
// const JUNE_5_2025 = 1749081600000;
|
|
20
|
-
// if (subscriptions && subscriptions.length > 0) {
|
|
21
|
-
// const hasFullAccess = subscriptions.some((subscription) => {
|
|
22
|
-
// return (
|
|
23
|
-
// subscription.status === 'active' &&
|
|
24
|
-
// subscription.current_period_start &&
|
|
25
|
-
// // subscription started must be before June 5, 2025 for full access
|
|
26
|
-
// subscription.current_period_start * 1000 < JUNE_5_2025
|
|
27
|
-
// );
|
|
28
|
-
// });
|
|
29
|
-
// if (hasFullAccess) return fullAccess;
|
|
30
|
-
// }
|
|
31
|
-
//TODO: Enable when RBAC is ready
|
|
32
|
-
return ['canFavourite'];
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Fetches user subscriptions from the server.
|
|
36
|
-
*/
|
|
37
|
-
export const getSubscriptions = async (token) => {
|
|
38
|
-
try {
|
|
39
|
-
const { development } = getFinsweetComponentsEnvironment();
|
|
40
|
-
const endpoint = development
|
|
41
|
-
? FINSWEET_SUBSCRIPTIONS_ENDPOINT_STAGING
|
|
42
|
-
: FINSWEET_SUBSCRIPTIONS_ENDPOINT;
|
|
43
|
-
const response = await fetch(endpoint, {
|
|
44
|
-
headers: {
|
|
45
|
-
Authorization: `Bearer ${token}`
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
const data = await response.json();
|
|
49
|
-
return data;
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
console.error('Failed to fetch subscriptions', error);
|
|
53
|
-
return [];
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Fetches user data from the authentication server.
|
|
58
|
-
*/
|
|
59
|
-
export const getUser = async (token) => {
|
|
60
|
-
const response = await fetch('/auth0/verify', {
|
|
61
|
-
headers: {
|
|
62
|
-
Authorization: `Bearer ${token}`,
|
|
63
|
-
'Content-Type': 'application/json'
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
const data = await response.json();
|
|
67
|
-
return data;
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* Handles user login authentication flow.
|
|
71
|
-
*/
|
|
72
|
-
export const handleLogin = async () => {
|
|
73
|
-
if (get(isLoggingIn))
|
|
74
|
-
return;
|
|
75
|
-
try {
|
|
76
|
-
isLoggingIn.set(true);
|
|
77
|
-
const response = await crossWindowLogin();
|
|
78
|
-
const [user, subscriptions] = await Promise.all([
|
|
79
|
-
getUser(response.access_token),
|
|
80
|
-
getSubscriptions(response.access_token)
|
|
81
|
-
]);
|
|
82
|
-
if (user?.userId) {
|
|
83
|
-
const libraryAccess = checkLibraryAccess(user, subscriptions);
|
|
84
|
-
finsweetUser.set({ ...response, user: { ...user, libraryAccess }, subscriptions });
|
|
85
|
-
setLocalStorage('finsweetComponentsAuth', JSON.stringify(response));
|
|
86
|
-
setLocalStorage('finsweetComponentsAuthToken', response.access_token);
|
|
87
|
-
//dispatch login event
|
|
88
|
-
const event = new CustomEvent('finsweetLoginUpdate', { detail: { user } });
|
|
89
|
-
document.dispatchEvent(event);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
throw new Error('User data is invalid');
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
const err = error;
|
|
96
|
-
console.error('Login failed:', err.message);
|
|
97
|
-
finsweetUser.set(null);
|
|
98
|
-
webflow.notify({
|
|
99
|
-
type: 'Error',
|
|
100
|
-
message: 'Login failed. Please try again or contact support.'
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
finally {
|
|
104
|
-
isLoggingIn.set(false);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
/**
|
|
108
|
-
* Handles user logout and cleanup.
|
|
109
|
-
*/
|
|
110
|
-
export const handleLogout = async () => {
|
|
111
|
-
removeLocalStorage('finsweetComponentsAuth');
|
|
112
|
-
removeLocalStorage('finsweetComponentsAuthToken');
|
|
113
|
-
finsweetUser.set(null);
|
|
114
|
-
//dispatch login event
|
|
115
|
-
const event = new CustomEvent('finsweetLogoutUpdate', { detail: { user: null } });
|
|
116
|
-
document.dispatchEvent(event);
|
|
117
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
118
|
-
};
|
|
119
|
-
/**
|
|
120
|
-
* Checks if the user is logged in by validating stored session.
|
|
121
|
-
*/
|
|
122
|
-
export const checkInitialLoginState = async () => {
|
|
123
|
-
const session = getLocalStorage('finsweetComponentsAuth');
|
|
124
|
-
if (session) {
|
|
125
|
-
const parsedSession = JSON.parse(session);
|
|
126
|
-
// Check if the current time is greater than the expiration time
|
|
127
|
-
if (Date.now() > parsedSession.expires) {
|
|
128
|
-
await handleLogout();
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
const [user, subscriptions] = await Promise.all([
|
|
132
|
-
getUser(parsedSession.access_token),
|
|
133
|
-
getSubscriptions(parsedSession.access_token)
|
|
134
|
-
]);
|
|
135
|
-
if (user?.userId) {
|
|
136
|
-
const libraryAccess = checkLibraryAccess(user, subscriptions);
|
|
137
|
-
finsweetUser.set({ ...parsedSession, user: { ...user, libraryAccess }, subscriptions });
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
await handleLogout();
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
await handleLogout();
|
|
144
|
-
};
|
|
145
|
-
/**
|
|
146
|
-
* Sets a cookie with security options.
|
|
147
|
-
*/
|
|
148
|
-
export const setCookie = (name, value, options = {}) => {
|
|
149
|
-
Cookies.set(name, value, { sameSite: 'None', secure: true, ...options });
|
|
150
|
-
};
|
|
151
|
-
/**
|
|
152
|
-
* Gets a cookie value by name.
|
|
153
|
-
*/
|
|
154
|
-
export const getCookie = (name) => {
|
|
155
|
-
return Cookies.get(name);
|
|
156
|
-
};
|
|
157
|
-
/**
|
|
158
|
-
* Deletes a cookie by name.
|
|
159
|
-
*/
|
|
160
|
-
export const deleteCookie = (name, options = {}) => {
|
|
161
|
-
Cookies.remove(name, options);
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* Checks if the user has access to a specific feature.
|
|
165
|
-
*/
|
|
166
|
-
export const canAccessFeature = (loggedIn, access, required) => {
|
|
167
|
-
if (!loggedIn) {
|
|
168
|
-
return {
|
|
169
|
-
granted: false,
|
|
170
|
-
message: "This feature is available only when you're logged in."
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
if (required && required.every((r) => access?.includes(r))) {
|
|
174
|
-
return { granted: true, message: '' };
|
|
175
|
-
}
|
|
176
|
-
// no message for logged in users, so tooltips are not shown
|
|
177
|
-
return { granted: false, message: '' };
|
|
178
|
-
};
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { getLocalStorage } from '../browser-storage';
|
|
2
|
-
import { COMPONENTS_CORE_SCRIPT, COMPONENTS_CORE_SCRIPT_LOCAL, COMPONENTS_SERVER_DEV_ENDPOINT, COMPONENTS_SERVER_DEV_ENDPOINT_LOCAL, COMPONENTS_SERVER_PROD_ENDPOINT } from '../constants';
|
|
3
|
-
const DEV_MODE_KEY = 'fsComponentsDevMode';
|
|
4
|
-
const DEV_MODE_SCRIPT_KEY = 'fsComponentsDevModeScript';
|
|
5
|
-
const DEV_MODE_API_KEY = 'fsComponentsDevModeApi';
|
|
6
|
-
const URL_DEV_MODE_KEY = 'dev';
|
|
7
|
-
const URL_DEV_MODE_SCRIPT_KEY = 'script';
|
|
8
|
-
const URL_DEV_MODE_API_KEY = 'api';
|
|
9
|
-
let lastLogTime = 0;
|
|
10
|
-
const LOG_THROTTLE_MS = 3000;
|
|
11
|
-
/**
|
|
12
|
-
* Gets a parameter value from the URL search params.
|
|
13
|
-
*/
|
|
14
|
-
const getUrlParam = (key) => {
|
|
15
|
-
if (typeof window === 'undefined')
|
|
16
|
-
return null;
|
|
17
|
-
try {
|
|
18
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
19
|
-
return urlParams.get(key);
|
|
20
|
-
}
|
|
21
|
-
catch (e) {
|
|
22
|
-
console.error('Error getting URL parameter:', e);
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Throttled console log that only logs once within the throttle interval.
|
|
28
|
-
*/
|
|
29
|
-
const throttledLog = (message, data) => {
|
|
30
|
-
const now = Date.now();
|
|
31
|
-
if (now - lastLogTime >= LOG_THROTTLE_MS) {
|
|
32
|
-
console.log(message, data || '');
|
|
33
|
-
lastLogTime = now;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Gets the Finsweet components environment configuration.
|
|
38
|
-
*/
|
|
39
|
-
export const getFinsweetComponentsEnvironment = () => {
|
|
40
|
-
const devFromUrl = getUrlParam(URL_DEV_MODE_KEY);
|
|
41
|
-
const scriptFromUrl = getUrlParam(URL_DEV_MODE_SCRIPT_KEY);
|
|
42
|
-
const apiFromUrl = getUrlParam(URL_DEV_MODE_API_KEY);
|
|
43
|
-
const dev = devFromUrl !== null ? devFromUrl === 'true' : getLocalStorage(DEV_MODE_KEY) === 'true';
|
|
44
|
-
let script = scriptFromUrl || getLocalStorage(DEV_MODE_SCRIPT_KEY) || COMPONENTS_CORE_SCRIPT;
|
|
45
|
-
let api = dev
|
|
46
|
-
? apiFromUrl || getLocalStorage(DEV_MODE_API_KEY) || COMPONENTS_SERVER_DEV_ENDPOINT
|
|
47
|
-
: COMPONENTS_SERVER_PROD_ENDPOINT;
|
|
48
|
-
const isBrowser = typeof window !== 'undefined';
|
|
49
|
-
const isLocalhost = isBrowser && window?.location?.hostname?.includes('localhost');
|
|
50
|
-
//if localhost then use local scripts
|
|
51
|
-
if (isLocalhost) {
|
|
52
|
-
script = COMPONENTS_CORE_SCRIPT_LOCAL;
|
|
53
|
-
api = COMPONENTS_SERVER_DEV_ENDPOINT_LOCAL;
|
|
54
|
-
}
|
|
55
|
-
const development = !!dev || isLocalhost;
|
|
56
|
-
if (development) {
|
|
57
|
-
throttledLog(`\n\nFinsweet Components Environment:
|
|
58
|
-
- API: ${api}
|
|
59
|
-
- Core script: ${script}
|
|
60
|
-
- Development mode: ${development ? 'Yes' : 'No'}\n\n`);
|
|
61
|
-
}
|
|
62
|
-
return {
|
|
63
|
-
development,
|
|
64
|
-
coreScript: script,
|
|
65
|
-
api
|
|
66
|
-
};
|
|
67
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export type LoggerContext = string & Record<never, never>;
|
|
2
|
-
export interface LogData {
|
|
3
|
-
[key: string]: any;
|
|
4
|
-
}
|
|
5
|
-
export type LogLevel = 'error' | 'warn' | 'info' | 'log' | 'debug';
|
|
6
|
-
export interface Logger {
|
|
7
|
-
error: (context: LogData, message: string, ...args: any[]) => void;
|
|
8
|
-
warn: (context: LogData, message: string, ...args: any[]) => void;
|
|
9
|
-
info: (context: LogData, message: string, ...args: any[]) => void;
|
|
10
|
-
log: (context: LogData, message: string, ...args: any[]) => void;
|
|
11
|
-
debug: (context: LogData, message: string, ...args: any[]) => void;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Create a logger instance for the given context
|
|
15
|
-
*/
|
|
16
|
-
export declare function getLogger(context: LoggerContext): Logger;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { getFinsweetComponentsEnvironment } from '../api';
|
|
3
|
-
/**
|
|
4
|
-
* Create a logger instance for the given context
|
|
5
|
-
*/
|
|
6
|
-
export function getLogger(context) {
|
|
7
|
-
const createLogMethod = (level) => {
|
|
8
|
-
return (logContext, message, ...args) => {
|
|
9
|
-
const { development } = getFinsweetComponentsEnvironment();
|
|
10
|
-
if (development) {
|
|
11
|
-
const contextPrefix = `[${context}]`;
|
|
12
|
-
const consoleMethod = level === 'log' ? 'log' : level;
|
|
13
|
-
if (typeof console[consoleMethod] === 'function') {
|
|
14
|
-
console[consoleMethod](contextPrefix, message, logContext, ...args);
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
console.log(contextPrefix, message, logContext, ...args);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// In production, show warnings in console
|
|
21
|
-
if (!development && level === 'warn') {
|
|
22
|
-
const contextPrefix = `[${context}]`;
|
|
23
|
-
console.warn(contextPrefix, message, logContext, ...args);
|
|
24
|
-
}
|
|
25
|
-
// In production, only send errors to LogRocket
|
|
26
|
-
if (!development && level === 'error') {
|
|
27
|
-
const contextPrefix = `[${context}]`;
|
|
28
|
-
console.error(contextPrefix, message, logContext, ...args);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
return {
|
|
33
|
-
error: createLogMethod('error'),
|
|
34
|
-
warn: createLogMethod('warn'),
|
|
35
|
-
info: createLogMethod('info'),
|
|
36
|
-
log: createLogMethod('log'),
|
|
37
|
-
debug: createLogMethod('debug')
|
|
38
|
-
};
|
|
39
|
-
}
|