@lilaquadrat/design-core 0.2.2 → 0.3.0

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 (78) hide show
  1. package/README.md +71 -3
  2. package/html/index.server.html +1 -8
  3. package/package.json +53 -53
  4. package/src/client-entry.ts +8 -8
  5. package/src/components/partials/error.partial.vue +19 -19
  6. package/src/components/partials/main-components.partial.vue +75 -70
  7. package/src/components/partials/qrcode.partial.vue +8 -8
  8. package/src/functions/AuthProviderFactory.ts +30 -0
  9. package/src/functions/PaymenyProviderFactory.ts +11 -11
  10. package/src/functions/auth0.provider.ts +75 -0
  11. package/src/functions/keycloak.provider.ts +228 -0
  12. package/src/functions/lila-dom.ts +50 -50
  13. package/src/functions/shopify.provider.ts +176 -154
  14. package/src/functions/stripe.provider.ts +120 -108
  15. package/src/globals.d.ts +1 -2
  16. package/src/index.ts +9 -7
  17. package/src/interfaces/AuthCallbackResult.interface.ts +5 -0
  18. package/src/interfaces/AuthConfig.interface.ts +13 -0
  19. package/src/interfaces/AuthProvider.interface.ts +15 -0
  20. package/src/interfaces/FrontendConfig.interface.ts +11 -40
  21. package/src/interfaces/GenericEvents.interface.ts +1 -1
  22. package/src/interfaces/IdTokenExtended.interface.ts +13 -4
  23. package/src/interfaces/PaymentProvider.interface.ts +2 -2
  24. package/src/interfaces/RenderOptions.interface.ts +12 -0
  25. package/src/libs/ActionNotice.ts +125 -125
  26. package/src/libs/Models.class.ts +219 -221
  27. package/src/main.ts +41 -36
  28. package/src/mixins/createCookieString.ts +50 -36
  29. package/src/mixins/createModelDeclaration.ts +22 -19
  30. package/src/mixins/createRouter.ts +12 -12
  31. package/src/mixins/date.ts +4 -2
  32. package/src/mixins/formatSize.ts +5 -5
  33. package/src/mixins/getAnchor.ts +1 -1
  34. package/src/mixins/getRoutes.ts +13 -25
  35. package/src/mixins/hasSlotContent.ts +22 -16
  36. package/src/mixins/hooks.ts +101 -60
  37. package/src/mixins/loadComponents.ts +60 -58
  38. package/src/mixins/logger.ts +17 -13
  39. package/src/mixins/replaceVariables.ts +10 -8
  40. package/src/mixins/scroll.ts +61 -45
  41. package/src/models/Address.model.ts +7 -7
  42. package/src/models/Contact.model.ts +14 -14
  43. package/src/plugins/analytics.ts +198 -0
  44. package/src/plugins/auth.ts +74 -60
  45. package/src/plugins/currency.ts +10 -10
  46. package/src/plugins/events.ts +101 -97
  47. package/src/plugins/filters.ts +21 -18
  48. package/src/plugins/replacer.ts +7 -6
  49. package/src/plugins/signupFlow.ts +45 -43
  50. package/src/plugins/traceable.ts +28 -26
  51. package/src/plugins/translations.ts +9 -9
  52. package/src/plugins/youtube.ts +39 -34
  53. package/src/routes.ts +108 -108
  54. package/src/server-entry.ts +75 -77
  55. package/src/stores/calls.store.ts +14 -14
  56. package/src/stores/cart.store.ts +116 -107
  57. package/src/stores/content.store.ts +87 -45
  58. package/src/stores/editor.store.ts +16 -16
  59. package/src/stores/files.store.ts +72 -72
  60. package/src/stores/main.store.ts +155 -109
  61. package/src/stores/user.store.ts +72 -68
  62. package/src/translations/de.ts +127 -127
  63. package/src/views/content.view.vue +81 -143
  64. package/src/views/download.view.vue +25 -23
  65. package/src/views/editor.view.vue +150 -125
  66. package/src/views/login.view.vue +35 -36
  67. package/src/views/signup-account.view.vue +14 -14
  68. package/tooling/cypress/config.ts +68 -54
  69. package/tooling/cypress/manifest-utils.mjs +34 -22
  70. package/tooling/cypress/run-parallel.mjs +41 -35
  71. package/tooling/cypress/support/commands.ts +458 -300
  72. package/tooling/eslint.config.js +1 -223
  73. package/tooling/preview.plugin.js +68 -68
  74. package/tooling/ssr-test/index.mjs +205 -203
  75. package/tooling/vite.d.ts +0 -6
  76. package/tooling/vite.js +170 -162
  77. package/src/interfaces/EditorConfiguration.interface.ts +0 -15
  78. package/tooling/stylelint.config.mjs +0 -24
@@ -1,182 +1,228 @@
1
- import { ref } from 'vue'
1
+ import { ref, computed } from 'vue'
2
2
  import { defineStore } from 'pinia'
3
- import type { BasicData, Content, CustomModule } from '@lilaquadrat/interfaces';
4
- import type EditorConfiguration from '../interfaces/EditorConfiguration.interface';
3
+ import type { BasicData, Content, DesignCustomModule, WorkingContext } from '@lilaquadrat/interfaces';
5
4
  import StudioSDK, { type SDKResponse } from '@lilaquadrat/sdk';
6
5
  import { useAuth } from '../plugins/auth';
7
- import type FrontendConfig from '../interfaces/FrontendConfig.interface';
8
6
  import type { AxiosError } from 'axios';
9
- import { computed } from 'vue';
10
7
  import { hardCopy } from '@lilaquadrat/frontend/content';
8
+ import useContentStore from './content.store';
9
+
10
+ /**
11
+ * a failed request resolves with a status and no data, instead of throwing
12
+ */
13
+ type ContentResponse = SDKResponse<BasicData<Content>> | SDKResponse<undefined>;
11
14
 
12
15
  export const useMainStore = defineStore('main', () => {
13
16
 
14
- const startupDone = ref<boolean>(false);
15
- const clientOnlyStartupDone = ref<boolean>(false);
16
- const data = ref<BasicData<Content>>();
17
- const layout = ref<BasicData<Content>>();
18
- const editorConfiguration = ref<EditorConfiguration>({});
19
- const fullscreen = ref<boolean>(false);
20
- const config = ref<FrontendConfig>();
21
- const isEditor = ref<boolean>(typeof window !== 'undefined' && window !== window.top);
22
- /**
17
+ const startupDone = ref<boolean>(false);
18
+ const clientOnlyStartupDone = ref<boolean>(false);
19
+ const fullscreen = ref<boolean>(false);
20
+ const isEditor = ref<boolean>(typeof window !== 'undefined' && window !== window.top);
21
+ /**
23
22
  * there are case where the content should not update if the lock state changed
24
23
  * e.g. the user is connected after using register-main
25
24
  * this state will be set to false by the next navigation
26
25
  */
27
- const disabledLockUpdate = ref<boolean>(false);
28
- const staticData = ref<Record<string, Partial<BasicData<Content>>>>();
29
- const customModulesBrowser = ref<CustomModule[]>();
30
- const customModulesMail = ref<CustomModule[]>();
31
- const target = ref<'browser'|'mail'>();
26
+ const disabledLockUpdate = ref<boolean>(false);
27
+ const staticData = ref<Record<string, Partial<BasicData<Content>>>>();
28
+ const customModulesBrowser = ref<DesignCustomModule[]>();
29
+ const customModulesMail = ref<DesignCustomModule[]>();
30
+
31
+ /**
32
+ * the flattened WorkingContext: the static environment and project settings,
33
+ * mirrored key for key. the rendered content itself lives in the content store.
34
+ */
35
+ const project = ref<WorkingContext['project']>();
36
+ const company = ref<WorkingContext['company']>();
37
+ const dynamic = ref<WorkingContext['dynamic']>();
38
+ const installable = ref<WorkingContext['installable']>();
39
+ const pwa = ref<WorkingContext['pwa']>();
40
+ const login = ref<WorkingContext['login']>();
41
+ const analytics = ref<WorkingContext['analytics']>();
42
+ const paymentProvider = ref<WorkingContext['paymentProvider']>();
43
+ const endpoints = ref<WorkingContext['endpoints']>();
44
+ const auth = ref<WorkingContext['auth']>();
45
+ const editor = ref<WorkingContext['editor']>();
46
+ const tags = ref<WorkingContext['tags']>();
47
+ const app = ref<WorkingContext['app']>();
48
+ const css = ref<WorkingContext['css']>();
49
+ const cdn = ref<WorkingContext['cdn']>();
50
+ const renderTarget = ref<WorkingContext['renderTarget']>();
51
+
52
+ function setContext(value: Partial<WorkingContext>) {
53
+
54
+ project.value = value.project;
55
+ company.value = value.company;
56
+ dynamic.value = value.dynamic;
57
+ installable.value = value.installable;
58
+ pwa.value = value.pwa;
59
+ login.value = value.login;
60
+ analytics.value = value.analytics;
61
+ paymentProvider.value = value.paymentProvider;
62
+ endpoints.value = value.endpoints;
63
+ auth.value = value.auth;
64
+ editor.value = value.editor;
65
+ tags.value = value.tags;
66
+ app.value = value.app;
67
+ css.value = value.css;
68
+ cdn.value = value.cdn;
69
+ renderTarget.value = value.renderTarget;
32
70
 
33
- function setData (value: BasicData<Content>) {
71
+ }
34
72
 
35
- data.value = value;
73
+ function setFullscreen(value: boolean) {
36
74
 
37
- }
75
+ fullscreen.value = value;
38
76
 
39
- function setFullscreen (value: boolean) {
77
+ if (!document) return;
40
78
 
41
- fullscreen.value = value;
79
+ const { body } = document;
42
80
 
43
- if (!document) return;
81
+ if (value) {
44
82
 
45
- const { body } = document;
83
+ body.classList.add('fullscreen');
46
84
 
47
- if (value) {
85
+ } else {
48
86
 
49
- body.classList.add('fullscreen');
87
+ if (body.classList.contains('fullscreen')) {
50
88
 
51
- } else {
89
+ body.classList.remove('fullscreen');
90
+
91
+ }
52
92
 
53
- if (body.classList.contains('fullscreen')) {
54
- body.classList.remove('fullscreen');
55
- }
93
+ }
56
94
 
57
95
  }
58
96
 
59
- }
97
+ function checkFullscreen() {
60
98
 
61
- function checkFullscreen () {
99
+ const elements = document.querySelectorAll('.overlay-background:not(.inactive)');
62
100
 
63
- const elements = document.querySelectorAll('.overlay-background:not(.inactive)');
101
+ if (!elements.length) setFullscreen(false);
64
102
 
65
- if (!elements.length) setFullscreen(false);
66
-
67
- }
68
-
69
- function setConfiguration (value: EditorConfiguration) {
70
-
71
- editorConfiguration.value = value;
103
+ }
72
104
 
73
- }
105
+ const apiConfig = computed(() => {
74
106
 
75
- const apiConfig = computed(() => {
107
+ const { authToken } = useAuth();
76
108
 
77
- const { authToken } = useAuth();
109
+ return {
110
+ authToken,
111
+ mode: 'custom' as const,
112
+ customEndpoints: {
113
+ api: endpoints.value?.api ?? '',
114
+ media: endpoints.value?.media ?? ''
115
+ },
116
+ company: company.value,
117
+ project: project.value,
118
+ // the sdk identifies the calling app as `<company>-<project>`
119
+ app: company.value && project.value ? `${company.value}-${project.value}` : ''
120
+ }
78
121
 
79
- return {
80
- authToken,
81
- ...config.value?.api,
82
- company: config.value?.company,
83
- project: config.value?.project,
84
- app : config.value?.name as string
85
- }
122
+ });
86
123
 
87
- });
124
+ async function getContent(params: { filename: string }, type: 'public' | 'members'): Promise<ContentResponse>
125
+ async function getContent(params: { id: string }, type: 'public' | 'members'): Promise<ContentResponse>
126
+ async function getContent(params: { internalId: string }, type: 'public' | 'members'): Promise<ContentResponse>
127
+ async function getContent(params: { latest?: boolean, predefined?: boolean, categories?: string[] }, type: 'public' | 'members'): Promise<ContentResponse>
128
+ async function getContent(params: { predefined?: boolean, filename?: string, latest?: boolean, id?: string, internalId?: string, categories?: string[] }, type: 'public' | 'members'): Promise<ContentResponse> {
88
129
 
89
- async function getContent(params: { filename: string }, type: 'public' | 'members'): Promise<SDKResponse<BasicData<Content>|undefined>>
90
- async function getContent(params: { id: string }, type: 'public' | 'members'): Promise<SDKResponse<BasicData<Content>|undefined>>
91
- async function getContent(params: { internalId: string }, type: 'public' | 'members'): Promise<SDKResponse<BasicData<Content>|undefined>>
92
- async function getContent(params: { latest?: boolean, predefined?: boolean, categories?: string[] }, type: 'public' | 'members'): Promise<SDKResponse<BasicData<Content>|undefined>>
93
- async function getContent (params: { predefined?: boolean, filename?: string, latest?: boolean, id?: string, internalId?: string, categories?: string[] }, type: 'public' | 'members'): Promise<SDKResponse<BasicData<Content>|undefined>> {
130
+ const sdk = new StudioSDK(apiConfig.value);
131
+ const targetWithType = sdk[type === 'members' ? 'members' : 'public'];
132
+ const current = useContentStore().content;
94
133
 
95
- const sdk = new StudioSDK(apiConfig.value);
96
- const targetWithType = sdk[type === 'members' ? 'members' : 'public'];
134
+ if(params.filename && current?.settings?.filename?.includes(params.filename)) {
97
135
 
98
- if(params.filename && data.value?.settings?.filename?.includes(params.filename)) {
136
+ return hardCopy<SDKResponse<BasicData<Content>>>({ data: current, status: 200 });
99
137
 
100
- return hardCopy<SDKResponse<BasicData<Content>>>({ data: data.value, status: 200 });
138
+ }
101
139
 
102
- }
140
+ if (params.id && current?.id === params.id) {
103
141
 
104
- if (params.id && data.value?.id === params.id) {
142
+ return hardCopy<SDKResponse<BasicData<Content>>>({ data: current, status: 200 });
105
143
 
106
- return hardCopy<SDKResponse<BasicData<Content>>>({ data: data.value, status: 200 });
144
+ }
107
145
 
108
- }
146
+ if (params.internalId && current?._id?.toString() === params.internalId) {
109
147
 
110
- if (params.internalId && data.value?._id?.toString() === params.internalId) {
148
+ return hardCopy<SDKResponse<BasicData<Content>>>({ data: current, status: 200 });
111
149
 
112
- return hardCopy<SDKResponse<BasicData<Content>>>({ data: data.value, status: 200 });
150
+ }
113
151
 
114
- }
152
+ try {
115
153
 
116
- try {
154
+ if (params.predefined && !params.latest && params.id && type === 'public') {
117
155
 
118
- if (params.predefined && !params.latest && params.id && type === 'public') {
156
+ return sdk.public.content.predefined(params.id);
119
157
 
120
- return sdk.public.content.predefined(params.id);
158
+ } else if (params.predefined && params.latest && params.categories && type === 'public') {
121
159
 
122
- } else if (params.predefined && params.latest && params.categories && type === 'public') {
160
+ return sdk.public.content.predefinedLatest(params.categories);
123
161
 
124
- return sdk.public.content.predefinedLatest(params.categories);
162
+ } else if (params.internalId) {
125
163
 
126
- } else if (params.internalId) {
164
+ return targetWithType.content.getByInternalId(params.internalId);
127
165
 
128
- return targetWithType.content.getByInternalId(params.internalId);
166
+ } else if (params.id) {
129
167
 
130
- } else if (params.id) {
168
+ return targetWithType.content.getById(params.id);
131
169
 
132
- return targetWithType.content.getById(params.id);
170
+ } else if (params.filename) {
133
171
 
134
- } else if (params.filename) {
172
+ return targetWithType.content.getByFilename(params.filename);
135
173
 
136
- return targetWithType.content.getByFilename(params.filename);
174
+ }
137
175
 
138
- }
176
+ } catch (e) {
139
177
 
140
- } catch (e) {
178
+ const error = e as AxiosError;
141
179
 
142
- const error = e as AxiosError;
180
+ if (!error.response?.status) {
143
181
 
144
- if (!error.response?.status) {
182
+ return { status: 400, data: undefined}
145
183
 
146
- return { status: 400, data: undefined}
184
+ } else {
147
185
 
148
- } else {
186
+ return { status: error?.response?.status, data: undefined };
149
187
 
150
- return { status: error?.response?.status, data: undefined };
188
+ }
151
189
 
152
190
  }
153
191
 
154
- }
155
-
156
- return { status: 400, data: undefined};
192
+ return { status: 400, data: undefined};
157
193
 
158
194
  }
159
195
 
160
196
  return {
161
- setData,
162
- data,
163
- layout,
164
- fullscreen,
165
- setFullscreen,
166
- checkFullscreen,
167
- setConfiguration,
168
- configuration: editorConfiguration,
169
- getContent,
170
- startupDone,
171
- clientOnlyStartupDone,
172
- config,
173
- staticData,
174
- apiConfig,
175
- customModulesBrowser,
176
- customModulesMail,
177
- target,
178
- disabledLockUpdate,
179
- isEditor
197
+ setContext,
198
+ setFullscreen,
199
+ checkFullscreen,
200
+ getContent,
201
+ startupDone,
202
+ clientOnlyStartupDone,
203
+ staticData,
204
+ apiConfig,
205
+ customModulesBrowser,
206
+ customModulesMail,
207
+ disabledLockUpdate,
208
+ isEditor,
209
+ fullscreen,
210
+ project,
211
+ company,
212
+ dynamic,
213
+ installable,
214
+ pwa,
215
+ login,
216
+ analytics,
217
+ paymentProvider,
218
+ endpoints,
219
+ auth,
220
+ editor,
221
+ tags,
222
+ app,
223
+ css,
224
+ cdn,
225
+ renderTarget
180
226
  }
181
227
 
182
228
  });
@@ -8,116 +8,120 @@ import { type CustomerPerson } from '@lilaquadrat/interfaces';
8
8
 
9
9
  export const useUserStore = defineStore('user', () => {
10
10
 
11
- const locked = ref<string>();
12
- const customer = ref<{_id: string, id?: string}>();
13
- const emailConfirmationCode = ref<string>();
14
- const userData = ref<CustomerPerson>();
15
- const isUser = ref<boolean>(false);
16
- const isFullUser = ref<boolean>(false);
11
+ const locked = ref<string>();
12
+ const customer = ref<{_id: string, id?: string}>();
13
+ const emailConfirmationCode = ref<string>();
14
+ const userData = ref<CustomerPerson>();
15
+ const isUser = ref<boolean>(false);
16
+ const isFullUser = ref<boolean>(false);
17
17
 
18
- function setCustomer (customerData: {_id: string, id?: string}) {
18
+ function setCustomer(customerData: {_id: string, id?: string}) {
19
19
 
20
- customer.value = customerData;
21
- localStorage.setItem('lila-customer', JSON.stringify(customerData));
20
+ customer.value = customerData;
21
+ localStorage.setItem('lila-customer', JSON.stringify(customerData));
22
22
 
23
- }
23
+ }
24
24
 
25
- async function initCustomer () {
25
+ async function initCustomer() {
26
26
 
27
- const customerData = localStorage.getItem('lila-customer');
27
+ const customerData = localStorage.getItem('lila-customer');
28
28
 
29
- logger.userstore('init');
29
+ logger.userstore('init');
30
30
 
31
- if(customerData) {
31
+ if(customerData) {
32
32
 
33
- customer.value = JSON.parse(customerData);
33
+ customer.value = JSON.parse(customerData);
34
34
 
35
- }
35
+ }
36
36
 
37
- if(auth.isAuth.value) {
37
+ if(auth.isAuth.value) {
38
38
 
39
- await updateLock();
40
- isUser.value = true;
39
+ await updateLock();
40
+ isUser.value = true;
41
41
 
42
- if(locked.value === 'user-connect') {
43
- isFullUser.value = false;
44
- } else {
45
- isFullUser.value = true;
46
- }
42
+ if(locked.value === 'user-connect') {
47
43
 
48
- }
44
+ isFullUser.value = false;
45
+
46
+ } else {
47
+
48
+ isFullUser.value = true;
49
+
50
+ }
51
+
52
+ }
49
53
 
50
- logger.userstore('done');
54
+ logger.userstore('done');
51
55
 
52
- }
56
+ }
53
57
 
54
- async function updateLock () {
58
+ async function updateLock() {
55
59
 
56
- if(auth.isAuth.value) {
60
+ if(auth.isAuth.value) {
57
61
 
58
- await getUser();
62
+ await getUser();
59
63
 
60
- if(!userData.value) {
64
+ if(!userData.value) {
61
65
 
62
- console.error('LOCK THE USE FOR MISSING CONNECTION');
63
- locked.value = 'user-connect';
66
+ console.error('LOCK THE USE FOR MISSING CONNECTION');
67
+ locked.value = 'user-connect';
64
68
 
65
- return;
69
+ return;
66
70
 
67
- }
71
+ }
68
72
 
69
- /**
73
+ /**
70
74
  * check if a customerId is given and user is not connected
71
75
  */
72
- if (!userData.value?.emailConfirmed) {
76
+ if (!userData.value?.emailConfirmed) {
73
77
 
74
- console.error('LOCK THE USE FOR EMAIL VERIFICATION');
75
- locked.value = 'email-verified';
78
+ console.error('LOCK THE USE FOR EMAIL VERIFICATION');
79
+ locked.value = 'email-verified';
76
80
 
77
- return;
81
+ return;
78
82
 
79
- }
83
+ }
80
84
 
81
- locked.value = undefined;
82
- isFullUser.value = true;
85
+ locked.value = undefined;
86
+ isFullUser.value = true;
83
87
 
84
- }
88
+ }
85
89
 
86
- }
90
+ }
87
91
 
88
- async function getUser () {
92
+ async function getUser() {
89
93
 
90
- const mainStore = useMainStore();
91
- const sdk = new StudioSDK(mainStore.apiConfig);
94
+ const mainStore = useMainStore();
95
+ const sdk = new StudioSDK(mainStore.apiConfig);
92
96
 
93
- try {
97
+ try {
94
98
 
95
- StudioSDK.flushCache('me');
99
+ StudioSDK.flushCache('me');
96
100
 
97
- const me = await sdk.members.me.get();
101
+ const me = await sdk.members.me.get();
98
102
 
99
- userData.value = me.data;
103
+ userData.value = me.data;
100
104
 
101
- } catch (error) {
105
+ } catch (error) {
102
106
 
103
- console.error(error);
107
+ console.error(error);
104
108
 
109
+ }
110
+
105
111
  }
106
112
 
107
- }
108
-
109
- return {
110
- locked,
111
- setCustomer,
112
- initCustomer,
113
- updateLock,
114
- customer,
115
- userData,
116
- isUser,
117
- isFullUser,
118
- getUser,
119
- emailConfirmationCode
120
- }
113
+ return {
114
+ locked,
115
+ setCustomer,
116
+ initCustomer,
117
+ updateLock,
118
+ customer,
119
+ userData,
120
+ isUser,
121
+ isFullUser,
122
+ getUser,
123
+ emailConfirmationCode
124
+ }
121
125
 
122
126
  })
123
127