@getdraft/plugin 1.17.0 → 1.19.0-alpha.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.
package/src/plugin.ts CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  HandlerParams,
15
15
  MessageData,
16
16
  ExportAsFileParams,
17
+ RenderSectionPersonalizationGroupInput,
17
18
  } from './types';
18
19
  import {
19
20
  getImageParamsFromFileUrl,
@@ -22,6 +23,8 @@ import {
22
23
  } from './utils';
23
24
  import pkg from '../package.json';
24
25
 
26
+ const UNKNOWN_ERROR_MESSAGE = 'Unknown error';
27
+
25
28
  const getDeployLink = () => {
26
29
  const regex = new RegExp(`(^| )seplugin-dev=([^;]+)`);
27
30
  const match = document.cookie.match(regex);
@@ -170,7 +173,7 @@ export class PluginInstance {
170
173
  reject(
171
174
  new DraftError(
172
175
  code || 'unknown_error',
173
- message || 'Unknown error',
176
+ message || UNKNOWN_ERROR_MESSAGE,
174
177
  ),
175
178
  );
176
179
  } else {
@@ -221,7 +224,7 @@ export class PluginInstance {
221
224
  }
222
225
  };
223
226
 
224
- private onLoadPersonalization = async () => {
227
+ private onLoadPersonalization = async (requestId?: string) => {
225
228
  try {
226
229
  if (!this.config.on.loadPersonalization) {
227
230
  throw new Error('No personalization loader provided');
@@ -232,9 +235,62 @@ export class PluginInstance {
232
235
 
233
236
  this.postEvent('loadPersonalization', {
234
237
  items: personalizationDictionary,
238
+ requestId,
235
239
  });
236
240
  } catch (e) {
237
- this.postEvent('loadPersonalization', {});
241
+ this.postEvent('loadPersonalization', { requestId });
242
+ }
243
+ };
244
+
245
+ private onLoadSectionPersonalizationCatalog = async (requestId?: string) => {
246
+ try {
247
+ const handler = this.config.on.loadSectionPersonalizationCatalog;
248
+
249
+ if (!handler) {
250
+ throw new Error('No section personalization catalog loader provided');
251
+ }
252
+
253
+ const catalog = await handler();
254
+
255
+ this.postEvent('loadSectionPersonalizationCatalog', {
256
+ ok: true,
257
+ requestId,
258
+ catalog,
259
+ });
260
+ } catch (error) {
261
+ this.postEvent('loadSectionPersonalizationCatalog', {
262
+ ok: false,
263
+ requestId,
264
+ message: error instanceof Error ? error.message : UNKNOWN_ERROR_MESSAGE,
265
+ });
266
+ }
267
+ };
268
+
269
+ private onRenderSectionPersonalizationGroup = async (
270
+ data: RenderSectionPersonalizationGroupInput & { requestId?: string },
271
+ ) => {
272
+ const { requestId, ...input } = data;
273
+
274
+ try {
275
+ const handler = this.config.on.renderSectionPersonalizationGroup;
276
+
277
+ if (!handler) {
278
+ throw new Error('No section personalization renderer provided');
279
+ }
280
+
281
+ const renderedHtml = await handler(input);
282
+
283
+ this.postEvent('renderSectionPersonalizationGroup', {
284
+ ok: true,
285
+ requestId,
286
+ html: renderedHtml,
287
+ });
288
+ } catch (error) {
289
+ this.postEvent('renderSectionPersonalizationGroup', {
290
+ ok: false,
291
+ requestId,
292
+ message: error instanceof Error ? error.message : UNKNOWN_ERROR_MESSAGE,
293
+ });
238
294
  }
239
295
  };
240
296
 
@@ -284,7 +340,17 @@ export class PluginInstance {
284
340
  } else if (event === 'uploadImage') {
285
341
  this.onImageUpload(data as UploadImageParams & { id: string });
286
342
  } else if (event === 'loadPersonalization') {
287
- this.onLoadPersonalization();
343
+ this.onLoadPersonalization((data as { requestId?: string }).requestId);
344
+ } else if (event === 'loadSectionPersonalizationCatalog') {
345
+ this.onLoadSectionPersonalizationCatalog(
346
+ (data as { requestId?: string }).requestId,
347
+ );
348
+ } else if (event === 'renderSectionPersonalizationGroup') {
349
+ this.onRenderSectionPersonalizationGroup(
350
+ data as RenderSectionPersonalizationGroupInput & {
351
+ requestId?: string;
352
+ },
353
+ );
288
354
  } else {
289
355
  this.triggerEvent(
290
356
  this.config.on[event],
@@ -326,12 +392,21 @@ export class PluginInstance {
326
392
  apiUrl,
327
393
  pluginId,
328
394
  authData,
395
+ sectionPersonalization,
329
396
  __config,
330
397
  } = this.config;
331
398
 
332
399
  verifyConfig(this.config);
333
400
 
334
401
  if (this.iframe && this.iframe.contentWindow) {
402
+ const resolvedSectionPersonalization = {
403
+ ...sectionPersonalization,
404
+ enabled:
405
+ sectionPersonalization?.enabled === true &&
406
+ !!on.loadSectionPersonalizationCatalog &&
407
+ !!on.renderSectionPersonalizationGroup,
408
+ };
409
+
335
410
  this.postEvent('init', {
336
411
  container,
337
412
  locale,
@@ -340,6 +415,7 @@ export class PluginInstance {
340
415
  token,
341
416
  pluginId,
342
417
  authData,
418
+ sectionPersonalization: resolvedSectionPersonalization,
343
419
  apiUrl,
344
420
  __config,
345
421
  enabledListeners: Object.keys(on),
@@ -393,6 +469,14 @@ export class PluginInstance {
393
469
  this.postEvent('toggleInvisibleCharacters', { state });
394
470
  }
395
471
 
472
+ async isInvisibleCharactersVisible() {
473
+ const { state } = await this.promisedIframeMethod<{ state: boolean }>(
474
+ 'getInvisibleCharactersVisibility',
475
+ );
476
+
477
+ return state;
478
+ }
479
+
396
480
  togglePreview(state?: boolean) {
397
481
  this.postEvent('togglePreview', { state });
398
482
  }
package/src/types.ts CHANGED
@@ -23,6 +23,56 @@ type PersonalizationDictionaryEntry =
23
23
 
24
24
  export type PersonalizationDictionaryItems = PersonalizationDictionaryEntry[];
25
25
 
26
+ export type SectionPersonalizationValue = string | number | boolean | null;
27
+
28
+ export interface SectionPersonalizationField {
29
+ id: string;
30
+ operatorId: 'equals';
31
+ }
32
+
33
+ export interface SectionPersonalizationCatalogOption {
34
+ label: string;
35
+ value: Exclude<SectionPersonalizationValue, null>;
36
+ }
37
+
38
+ export interface SectionPersonalizationCatalogGroup {
39
+ type: 'group';
40
+ id: string;
41
+ label: string;
42
+ children: SectionPersonalizationCatalogNode[];
43
+ }
44
+
45
+ export interface SectionPersonalizationCatalogField {
46
+ type: 'field';
47
+ id: string;
48
+ label: string;
49
+ valueType?: 'string' | 'number' | 'boolean' | 'date';
50
+ options?: SectionPersonalizationCatalogOption[];
51
+ }
52
+
53
+ export type SectionPersonalizationCatalogNode =
54
+ | SectionPersonalizationCatalogGroup
55
+ | SectionPersonalizationCatalogField;
56
+
57
+ export interface SectionPersonalizationConfig {
58
+ enabled: boolean;
59
+ aboutUrl?: string;
60
+ }
61
+
62
+ export interface RenderSectionPersonalizationGroupInput {
63
+ groupId: string;
64
+ fields: SectionPersonalizationField[];
65
+ variants: Array<{
66
+ id: string;
67
+ values: Record<string, SectionPersonalizationValue>;
68
+ html: string;
69
+ }>;
70
+ fallback?: {
71
+ id: string;
72
+ html: string;
73
+ };
74
+ }
75
+
26
76
  export interface SerializedTemplate {
27
77
  [key: string]: unknown;
28
78
  parentId: string | null;
@@ -55,6 +105,7 @@ export type MessageData = {
55
105
  code?: string;
56
106
  message?: string;
57
107
  action?: string;
108
+ requestId?: string;
58
109
  };
59
110
 
60
111
  export interface ExportAsFileParams {
@@ -266,6 +317,14 @@ export interface Handlers {
266
317
  openGallery: EventHandler<(url?: string) => Promise<void>>;
267
318
  uploadImage: AsyncEventHandler<UploadImageParams, string>;
268
319
  loadPersonalization: AsyncEventHandler<void, PersonalizationDictionary>;
320
+ loadSectionPersonalizationCatalog: AsyncEventHandler<
321
+ void,
322
+ SectionPersonalizationCatalogNode[]
323
+ >;
324
+ renderSectionPersonalizationGroup: AsyncEventHandler<
325
+ RenderSectionPersonalizationGroupInput,
326
+ string
327
+ >;
269
328
  }
270
329
 
271
330
  export type HandlerParams<H> = H extends
@@ -290,6 +349,7 @@ export interface PluginConfig {
290
349
  pluginId: string;
291
350
  apiUrl: string;
292
351
  disableHotkeysPassing?: boolean;
352
+ sectionPersonalization?: SectionPersonalizationConfig;
293
353
  __config?: object;
294
354
  on: Partial<Handlers>;
295
355
  }