@lilaquadrat/design-core 0.2.1 → 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 (80) hide show
  1. package/README.md +76 -3
  2. package/html/index.server.html +1 -8
  3. package/package.json +54 -54
  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 +132 -0
  74. package/tooling/ssr-test/index.mjs +205 -203
  75. package/tooling/vite.d.ts +36 -0
  76. package/tooling/vite.js +234 -0
  77. package/src/interfaces/EditorConfiguration.interface.ts +0 -15
  78. package/tooling/preview.plugin.ts +0 -134
  79. package/tooling/stylelint.config.mjs +0 -24
  80. package/tooling/vite.ts +0 -260
@@ -19,10 +19,10 @@ import { describe, it } from 'node:test';
19
19
  import assert from 'node:assert/strict';
20
20
 
21
21
  const DEFAULT_PATHS = {
22
- serverEntry : 'dist/server/server-entry.js',
23
- manifest : 'dist/server/.vite/ssr-manifest.json',
24
- template : 'dist/server/index.server.html',
25
- mailTemplate: 'dist/server/index.mail.html',
22
+ serverEntry: 'dist/server/server-entry.js',
23
+ manifest: 'dist/server/.vite/ssr-manifest.json',
24
+ template: 'dist/server/index.server.html',
25
+ mailTemplate: 'dist/server/index.mail.html',
26
26
  };
27
27
  /**
28
28
  * the app logs its startup through mixins/logger, which is console.log - only
@@ -34,21 +34,24 @@ const VUE_WARN = '[Vue warn]';
34
34
  * mirrors RenderClass.createGenericContext: the shape the STUDIO renderer hands
35
35
  * to render(), minus the parts that only matter for asset urls.
36
36
  */
37
- function createContext (content, options = {}) {
38
-
39
- return {
40
- data : content,
41
- layout : options.layout,
42
- settings : {
43
- name : content.company ? `${content.company}-${content.project}` : 'preflight',
44
- company: content.company ?? 'preflight',
45
- project: content.project ?? 'preflight',
46
- mode : content.settings?.mode ?? 'presentation',
47
- },
48
- tags : content.tags,
49
- cdn : '',
50
- renderTarget: options.renderTarget ?? 'web',
51
- };
37
+ function createContext(content, options = {}) {
38
+
39
+ return {
40
+ content: content,
41
+ layout: options.layout,
42
+ contextContent: options.contextContent,
43
+ recipient: options.recipient,
44
+ list: options.list,
45
+ editor: {
46
+ name: content.company ? `${content.company}-${content.project}` : 'preflight',
47
+ company: content.company ?? 'preflight',
48
+ project: content.project ?? 'preflight',
49
+ mode: content.settings?.mode ?? 'presentation',
50
+ },
51
+ tags: content.tags,
52
+ cdn: '',
53
+ renderTarget: options.renderTarget ?? 'web',
54
+ };
52
55
 
53
56
  }
54
57
 
@@ -56,26 +59,27 @@ function createContext (content, options = {}) {
56
59
  * turns a fixture into a site the renderer can address: a filename to look up
57
60
  * and a url that resolves to it, exactly as Publish.action stores one.
58
61
  */
59
- function createSite (name, content, options = {}) {
60
- const target = options.target ?? content.target;
61
- const filename = target === 'mail'
62
- ? ['mail']
63
- : content.settings?.filename ?? [name];
64
- const site = {
65
- ...content,
66
- id : content.id ?? name,
67
- state : content.state ?? 'publish',
68
- settings: {
69
- mode : 'presentation',
70
- title: name,
71
- ...content.settings,
72
- filename,
73
- },
74
- };
75
-
76
- if (target) site.target = target;
77
-
78
- return { name, site, url: site.settings.url || filename[0] };
62
+ function createSite(name, content, options = {}) {
63
+
64
+ const target = options.target ?? content.target;
65
+ const filename = target === 'mail'
66
+ ? ['mail']
67
+ : content.settings?.filename ?? [name];
68
+ const site = {
69
+ ...content,
70
+ id: content.id ?? name,
71
+ state: content.state ?? 'publish',
72
+ settings: {
73
+ mode: 'presentation',
74
+ title: name,
75
+ ...content.settings,
76
+ filename,
77
+ },
78
+ };
79
+
80
+ if (target) site.target = target;
81
+
82
+ return { name, site, url: site.settings.url || filename[0] };
79
83
 
80
84
  }
81
85
 
@@ -83,53 +87,54 @@ function createSite (name, content, options = {}) {
83
87
  * vue reports a failed serverPrefetch and an unresolved component through the
84
88
  * console rather than by rejecting, so the console is part of the assertion.
85
89
  */
86
- async function captureConsole (run) {
90
+ async function captureConsole(run) {
87
91
 
88
- const captured = { errors: [], warnings: [] };
89
- const originalError = console.error;
90
- const originalWarn = console.warn;
92
+ const captured = { errors: [], warnings: [] };
93
+ const originalError = console.error;
94
+ const originalWarn = console.warn;
91
95
 
92
- console.error = (...args) => captured.errors.push(args.map(stringify).join(' '));
93
- console.warn = (...args) => captured.warnings.push(args.map(stringify).join(' '));
96
+ console.error = (...args) => captured.errors.push(args.map(stringify).join(' '));
97
+ console.warn = (...args) => captured.warnings.push(args.map(stringify).join(' '));
94
98
 
95
- try {
99
+ try {
96
100
 
97
- const result = await run();
101
+ const result = await run();
98
102
 
99
- return { result, captured };
103
+ return { result, captured };
100
104
 
101
- } finally {
105
+ } finally {
102
106
 
103
- console.error = originalError;
104
- console.warn = originalWarn;
107
+ console.error = originalError;
108
+ console.warn = originalWarn;
105
109
 
106
- }
110
+ }
107
111
 
108
112
  }
109
113
 
110
- function stringify (value) {
114
+ function stringify(value) {
111
115
 
112
- if (value instanceof Error) return `${value.message}\n${value.stack}`;
113
- if (typeof value === 'string') return value;
116
+ if (value instanceof Error) return `${value.message}\n${value.stack}`;
117
+ if (typeof value === 'string') return value;
114
118
 
115
- try {
119
+ try {
116
120
 
117
- return JSON.stringify(value);
121
+ return JSON.stringify(value);
118
122
 
119
- } catch {
123
+ } catch {
120
124
 
121
- return String(value);
125
+ return String(value);
122
126
 
123
- }
127
+ }
124
128
 
125
129
  }
126
130
 
127
- function assembleDocument (template, rendered) {
131
+ function assembleDocument(template, rendered) {
128
132
 
129
- return template
130
- .replace('<!--preload-links-->', rendered.preloadLinks)
131
- .replace('<!--ssr-outlet-->', rendered.html)
132
- .replace('<!--pinia-state-->', `<script>window.__INITIAL_STATE__ = ${rendered.initialState}</script>`);
133
+ return template
134
+ .replace('<!--preload-links-->', rendered.preloadLinks)
135
+ .replace('<!--ssr-outlet-->', rendered.html)
136
+ .replace('<!--pinia-state-->', `<script>window.__INITIAL_STATE__ = ${rendered.initialState}</script>`)
137
+ .replace('</head>', `${rendered.head ?? ''}</head>`);
133
138
 
134
139
  }
135
140
 
@@ -138,13 +143,13 @@ function assembleDocument (template, rendered) {
138
143
  * convention, not a contract - a handful of modules render no wrapper at all -
139
144
  * so a miss is reported, never asserted.
140
145
  */
141
- function moduleMarkers (type, overrides = {}) {
146
+ function moduleMarkers(type, overrides = {}) {
142
147
 
143
- if (overrides[type]) return overrides[type];
148
+ if (overrides[type]) return overrides[type];
144
149
 
145
- const base = type.replace(/-module$/, '');
150
+ const base = type.replace(/-module$/, '');
146
151
 
147
- return [`lila-${base}-module`, `${base}-module`, `lila-${base}`];
152
+ return [`lila-${base}-module`, `${base}-module`, `lila-${base}`];
148
153
 
149
154
  }
150
155
 
@@ -154,89 +159,89 @@ function moduleMarkers (type, overrides = {}) {
154
159
  * has (a structure declaration, a payment provider) complains offline, and that
155
160
  * complaint is not a regression.
156
161
  */
157
- function splitAllowed (messages, allowed) {
162
+ function splitAllowed(messages, allowed) {
158
163
 
159
- const unexpected = [];
160
- const expected = [];
164
+ const unexpected = [];
165
+ const expected = [];
161
166
 
162
- messages.forEach((single) => {
167
+ messages.forEach((single) => {
163
168
 
164
- if (allowed.some((pattern) => pattern.test(single))) {
169
+ if (allowed.some((pattern) => pattern.test(single))) {
165
170
 
166
- expected.push(single);
171
+ expected.push(single);
167
172
 
168
- } else {
173
+ } else {
169
174
 
170
- unexpected.push(single);
175
+ unexpected.push(single);
171
176
 
172
- }
177
+ }
173
178
 
174
- });
179
+ });
175
180
 
176
- return { unexpected, expected };
181
+ return { unexpected, expected };
177
182
 
178
183
  }
179
184
 
180
- function assertRendered (name, rendered, captured, options = {}) {
185
+ function assertRendered(name, rendered, captured, options = {}) {
181
186
 
182
- const allowed = options.allowedConsole ?? [];
183
- const errors = splitAllowed(captured.errors, allowed);
184
- const warnings = splitAllowed(
185
- captured.warnings.filter((single) => single.includes(VUE_WARN)),
186
- allowed,
187
- );
187
+ const allowed = options.allowedConsole ?? [];
188
+ const errors = splitAllowed(captured.errors, allowed);
189
+ const warnings = splitAllowed(
190
+ captured.warnings.filter((single) => single.includes(VUE_WARN)),
191
+ allowed,
192
+ );
188
193
 
189
- assert.ok(rendered, `${name}: render returned nothing`);
190
- assert.equal(
191
- errors.unexpected.length,
192
- 0,
193
- `${name}: console.error during render\n${errors.unexpected.join('\n')}`,
194
- );
195
- assert.equal(
196
- warnings.unexpected.length,
197
- 0,
198
- `${name}: vue warnings during render\n${warnings.unexpected.join('\n')}`,
199
- );
194
+ assert.ok(rendered, `${name}: render returned nothing`);
195
+ assert.equal(
196
+ errors.unexpected.length,
197
+ 0,
198
+ `${name}: console.error during render\n${errors.unexpected.join('\n')}`,
199
+ );
200
+ assert.equal(
201
+ warnings.unexpected.length,
202
+ 0,
203
+ `${name}: vue warnings during render\n${warnings.unexpected.join('\n')}`,
204
+ );
200
205
 
201
- if (options.onExpected && (errors.expected.length || warnings.expected.length)) {
206
+ if (options.onExpected && (errors.expected.length || warnings.expected.length)) {
202
207
 
203
- options.onExpected([...errors.expected, ...warnings.expected]);
208
+ options.onExpected([...errors.expected, ...warnings.expected]);
204
209
 
205
- }
206
- assert.equal(typeof rendered.html, 'string', `${name}: html is not a string`);
210
+ }
211
+ assert.equal(typeof rendered.html, 'string', `${name}: html is not a string`);
207
212
 
208
- const contentMarker = options.contentMarker ?? 'lila-content-module';
213
+ const contentMarker = options.contentMarker ?? 'lila-content-module';
209
214
 
210
- if (contentMarker) {
215
+ if (contentMarker) {
211
216
 
212
- assert.ok(
213
- rendered.html.includes(contentMarker),
214
- `${name}: ${contentMarker} did not render - the page would publish as an empty shell`,
215
- );
217
+ assert.ok(
218
+ rendered.html.includes(contentMarker),
219
+ `${name}: ${contentMarker} did not render - the page would publish as an empty shell`,
220
+ );
216
221
 
217
- }
222
+ }
218
223
 
219
- assert.doesNotThrow(
220
- () => JSON.parse(rendered.initialState),
221
- `${name}: initialState is not valid json, hydration would fail`,
222
- );
224
+ assert.doesNotThrow(
225
+ () => JSON.parse(rendered.initialState),
226
+ `${name}: initialState is not valid json, hydration would fail`,
227
+ );
223
228
 
224
229
  }
225
230
 
226
- async function loadRenderer (root, paths) {
231
+ async function loadRenderer(root, paths) {
227
232
 
228
- const serverEntry = resolve(root, paths.serverEntry);
229
- const renderer = await import(serverEntry);
233
+ const serverEntry = resolve(root, paths.serverEntry);
234
+ const renderer = await import(serverEntry);
230
235
 
231
- assert.equal(typeof renderer.render, 'function', `${paths.serverEntry} does not export render()`);
236
+ assert.equal(typeof renderer.render, 'function', `${paths.serverEntry} does not export render()`);
232
237
 
233
- return renderer;
238
+ return renderer;
234
239
 
235
240
  }
236
241
 
237
- async function loadJson (root, path) {
242
+ async function loadJson(root, path) {
238
243
 
239
- return JSON.parse(await readFile(resolve(root, path), 'utf-8'));
244
+ return JSON.parse(await readFile(resolve(root, path), 'utf-8'));
240
245
 
241
246
  }
242
247
 
@@ -251,140 +256,137 @@ async function loadJson (root, path) {
251
256
  * @param {RegExp[]} [options.allowedConsole] console output the project expects offline, reported instead of failed
252
257
  * @param {Record<string, string[]>} [options.markers] root markers for modules whose class does not follow from their type
253
258
  */
254
- export async function runSsrSuite (options) {
259
+ export async function runSsrSuite(options) {
260
+
261
+ const root = options.root ?? process.cwd();
262
+ const paths = { ...DEFAULT_PATHS, ...options.paths };
263
+ const fixtures = options.fixtures;
264
+ const withVariants = options.variants !== false;
265
+ const allowedConsole = options.allowedConsole ?? [];
266
+ const markers = options.markers ?? {};
267
+ const renderer = await loadRenderer(root, paths);
268
+ const manifest = await loadJson(root, paths.manifest);
269
+ const template = await readFile(resolve(root, paths.template), 'utf-8');
270
+
271
+ async function render(entry, renderOptions = {}) {
272
+
273
+ return captureConsole(() => renderer.render({
274
+ url: entry.url,
275
+ context: createContext(entry.site, renderOptions),
276
+ manifest,
277
+ cdnUrl: '',
278
+ }));
255
279
 
256
- const root = options.root ?? process.cwd();
257
- const paths = { ...DEFAULT_PATHS, ...options.paths };
258
- const fixtures = options.fixtures;
259
- const withVariants = options.variants !== false;
260
- const allowedConsole = options.allowedConsole ?? [];
261
- const markers = options.markers ?? {};
262
- const renderer = await loadRenderer(root, paths);
263
- const manifest = await loadJson(root, paths.manifest);
264
- const template = await readFile(resolve(root, paths.template), 'utf-8');
280
+ }
265
281
 
266
- async function render (entry, renderOptions = {}) {
282
+ describe('ssr: viewData renders as its own site', () => {
267
283
 
268
- return captureConsole(() => renderer.render(
269
- entry.url,
270
- createContext(entry.site, renderOptions),
271
- renderOptions.contextData ?? null,
272
- renderOptions.recipient ?? null,
273
- renderOptions.list ?? null,
274
- manifest,
275
- { cdnUrl: '' },
276
- ));
284
+ Object.entries(fixtures.viewData ?? {}).forEach(([name, content]) => {
277
285
 
278
- }
286
+ it(name, async (t) => {
279
287
 
280
- describe('ssr: viewData renders as its own site', () => {
288
+ if (!Array.isArray(content?.modules)) {
281
289
 
282
- Object.entries(fixtures.viewData ?? {}).forEach(([name, content]) => {
290
+ t.diagnostic(`${name} is not page content (no modules array) - skipped`);
291
+ return;
283
292
 
284
- it(name, async (t) => {
293
+ }
285
294
 
286
- if (!Array.isArray(content?.modules)) {
295
+ const entry = createSite(name, content);
296
+ const { result, captured } = await render(entry);
287
297
 
288
- t.diagnostic(`${name} is not page content (no modules array) - skipped`);
289
- return;
298
+ assertRendered(name, result, captured, {
299
+ allowedConsole,
300
+ onExpected: (messages) => t.diagnostic(`${name}: expected offline complaints\n${messages.join('\n')}`),
301
+ });
290
302
 
291
- }
303
+ const document = assembleDocument(template, result);
292
304
 
293
- const entry = createSite(name, content);
294
- const { result, captured } = await render(entry);
305
+ assert.ok(
306
+ !document.includes('<!--ssr-outlet-->'),
307
+ `${name}: the html template still holds its placeholder`,
308
+ );
295
309
 
296
- assertRendered(name, result, captured, {
297
- allowedConsole,
298
- onExpected: (messages) => t.diagnostic(`${name}: expected offline complaints\n${messages.join('\n')}`),
299
- });
310
+ content.modules.forEach((single) => {
300
311
 
301
- const document = assembleDocument(template, result);
302
-
303
- assert.ok(
304
- !document.includes('<!--ssr-outlet-->'),
305
- `${name}: the html template still holds its placeholder`,
306
- );
312
+ if (!single?.type) return;
307
313
 
308
- content.modules.forEach((single) => {
314
+ const found = moduleMarkers(single.type, markers).some((marker) => result.html.includes(marker));
309
315
 
310
- if (!single?.type) return;
316
+ if (!found) t.diagnostic(`${name}: no root marker found for ${single.type}`);
311
317
 
312
- const found = moduleMarkers(single.type, markers).some((marker) => result.html.includes(marker));
318
+ });
313
319
 
314
- if (!found) t.diagnostic(`${name}: no root marker found for ${single.type}`);
320
+ });
315
321
 
316
322
  });
317
323
 
318
- });
319
-
320
324
  });
321
325
 
322
- });
326
+ describe('ssr: every module renders with no data at all', () => {
323
327
 
324
- describe('ssr: every module renders with no data at all', () => {
328
+ (fixtures.modules ?? []).forEach((single) => {
325
329
 
326
- (fixtures.modules ?? []).forEach((single) => {
330
+ const type = `${single.name}-module`;
327
331
 
328
- const type = `${single.name}-module`;
332
+ it(type, async () => {
329
333
 
330
- it(type, async () => {
334
+ const entry = createSite(`empty-${single.name}`, {
335
+ modules: [{ type, uuid: `empty-${single.name}` }],
336
+ });
337
+ const { result, captured } = await render(entry);
331
338
 
332
- const entry = createSite(`empty-${single.name}`, {
333
- modules: [{ type, uuid: `empty-${single.name}` }],
334
- });
335
- const { result, captured } = await render(entry);
339
+ assertRendered(type, result, captured, { allowedConsole });
336
340
 
337
- assertRendered(type, result, captured, { allowedConsole });
341
+ });
338
342
 
339
- });
343
+ if (!withVariants) return;
340
344
 
341
- if (!withVariants) return;
345
+ (single.variants ?? []).forEach((variant) => {
342
346
 
343
- (single.variants ?? []).forEach((variant) => {
347
+ if (!variant?.key) return;
344
348
 
345
- if (!variant?.key) return;
349
+ it(`${type} [${variant.key}]`, async () => {
346
350
 
347
- it(`${type} [${variant.key}]`, async () => {
351
+ const entry = createSite(`empty-${single.name}-${variant.key}`, {
352
+ modules: [{ type, uuid: `empty-${single.name}-${variant.key}`, variant: [variant.key] }],
353
+ });
354
+ const { result, captured } = await render(entry);
348
355
 
349
- const entry = createSite(`empty-${single.name}-${variant.key}`, {
350
- modules: [{ type, uuid: `empty-${single.name}-${variant.key}`, variant: [variant.key] }],
351
- });
352
- const { result, captured } = await render(entry);
356
+ assertRendered(`${type} [${variant.key}]`, result, captured, { allowedConsole });
353
357
 
354
- assertRendered(`${type} [${variant.key}]`, result, captured, { allowedConsole });
358
+ });
355
359
 
356
- });
360
+ });
357
361
 
358
- });
362
+ });
359
363
 
360
364
  });
361
365
 
362
- });
366
+ if (!fixtures.mailModules?.length) return;
363
367
 
364
- if (!fixtures.mailModules?.length) return;
368
+ describe('ssr: every mail module renders with no data at all', () => {
365
369
 
366
- describe('ssr: every mail module renders with no data at all', () => {
370
+ fixtures.mailModules.forEach((single) => {
367
371
 
368
- fixtures.mailModules.forEach((single) => {
372
+ const type = `${single.name}-module`;
369
373
 
370
- const type = `${single.name}-module`;
374
+ it(type, async () => {
371
375
 
372
- it(type, async () => {
376
+ const entry = createSite(`empty-mail-${single.name}`, {
377
+ target: 'mail',
378
+ modules: [{ type, uuid: `empty-mail-${single.name}` }],
379
+ }, { target: 'mail' });
380
+ const { result, captured } = await render(entry);
373
381
 
374
- const entry = createSite(`empty-mail-${single.name}`, {
375
- target : 'mail',
376
- modules: [{ type, uuid: `empty-mail-${single.name}` }],
377
- }, { target: 'mail' });
378
- const { result, captured } = await render(entry);
382
+ assertRendered(type, result, captured, { allowedConsole });
379
383
 
380
- assertRendered(type, result, captured, { allowedConsole });
384
+ });
381
385
 
382
- });
386
+ });
383
387
 
384
388
  });
385
389
 
386
- });
387
-
388
390
  }
389
391
 
390
392
  export default runSsrSuite;
@@ -0,0 +1,36 @@
1
+ import type { Plugin, UserConfig, UserConfigFnObject } from 'vite';
2
+
3
+ export type Target = 'local' | 'next' | 'live';
4
+
5
+ export interface ViteFactoryOptions {
6
+ /**
7
+ * absolute path to the project root (the folder holding index.html)
8
+ */
9
+ root: string
10
+ /**
11
+ * project relative path to the less folder holding variables, mixins and
12
+ * fonts - these are the design and never ship with the package
13
+ */
14
+ lessDir?: string
15
+ /**
16
+ * project relative entry for the ssr build
17
+ */
18
+ ssrEntry?: string
19
+ /**
20
+ * project relative entry for the ssr preflight fixtures (mode ssr-test).
21
+ * it exports the design's viewData and module registries so the test suite
22
+ * can read them without a bundler of its own
23
+ */
24
+ ssrFixturesEntry?: string
25
+ /**
26
+ * additional defines merged over the framework ones
27
+ */
28
+ define?: Record<string, string>
29
+ }
30
+
31
+ export function createViteConfig (options: ViteFactoryOptions): UserConfigFnObject;
32
+ export default createViteConfig;
33
+
34
+ export function previewBundle (): Plugin;
35
+ export function dropPreviewAssets (): Plugin;
36
+ export function previewBuildOptions (base: UserConfig['build']): UserConfig['build'];