@pexip-engage-public/plugin 1.1.17 → 1.1.19

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 (88) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/dist/configuration/PluginConfiguration.schema.d.ts +149 -149
  3. package/dist/configuration/PluginConfiguration.schema.d.ts.map +1 -1
  4. package/dist/configuration/PluginConfiguration.schema.js +55 -55
  5. package/dist/configuration/PluginConfiguration.schema.js.map +1 -1
  6. package/dist/configuration/migration.js +16 -16
  7. package/dist/configuration/migration.js.map +1 -1
  8. package/dist/configuration-parser/hash-parser.d.ts +1 -1
  9. package/dist/configuration-parser/hash-parser.d.ts.map +1 -1
  10. package/dist/configuration-parser/hash-parser.js +3 -3
  11. package/dist/configuration-parser/hash-parser.js.map +1 -1
  12. package/dist/configuration-parser/html-parser.d.ts +1 -1
  13. package/dist/configuration-parser/html-parser.d.ts.map +1 -1
  14. package/dist/configuration-parser/html-parser.js +3 -3
  15. package/dist/configuration-parser/html-parser.js.map +1 -1
  16. package/dist/configuration-parser/index.d.ts +6 -6
  17. package/dist/configuration-parser/index.js +2 -2
  18. package/dist/configuration-parser/index.js.map +1 -1
  19. package/dist/configuration-parser/js-parser.d.ts +1 -1
  20. package/dist/configuration-parser/js-parser.d.ts.map +1 -1
  21. package/dist/configuration-parser/js-parser.js +87 -87
  22. package/dist/configuration-parser/js-parser.js.map +1 -1
  23. package/dist/configuration-parser/migrate-legacy-configuration.js +3 -3
  24. package/dist/configuration-parser/migrate-legacy-configuration.js.map +1 -1
  25. package/dist/configuration-parser-legacy/LegacyParser.d.ts.map +1 -1
  26. package/dist/configuration-parser-legacy/LegacyParser.js +62 -62
  27. package/dist/configuration-parser-legacy/LegacyParser.js.map +1 -1
  28. package/dist/configuration-parser-legacy/LegacyParser.utils.js +23 -23
  29. package/dist/configuration-parser-legacy/LegacyParser.utils.js.map +1 -1
  30. package/dist/configuration-parser-legacy/ModernParser.js +8 -8
  31. package/dist/configuration-parser-legacy/ModernParser.js.map +1 -1
  32. package/dist/configuration-parser-legacy/Parser.js +1 -1
  33. package/dist/configuration-parser-legacy/Parser.js.map +1 -1
  34. package/dist/configuration-parser-legacy/tests/LegacyDomParser.test.js +20 -20
  35. package/dist/configuration-parser-legacy/tests/LegacyDomParser.test.js.map +1 -1
  36. package/dist/configuration-parser-legacy/tests/LegacyLocationHashParser.test.js +26 -26
  37. package/dist/configuration-parser-legacy/tests/LegacyLocationHashParser.test.js.map +1 -1
  38. package/dist/configuration-parser-legacy/tests/LegacyParser.test.js +4 -4
  39. package/dist/configuration-parser-legacy/tests/LegacyParser.test.js.map +1 -1
  40. package/dist/constants.d.ts +1 -1
  41. package/dist/constants.js +1 -1
  42. package/dist/encoding.d.ts +1 -1
  43. package/dist/encoding.d.ts.map +1 -1
  44. package/dist/encoding.js +5 -5
  45. package/dist/encoding.js.map +1 -1
  46. package/dist/events/event-types.d.ts +1 -1
  47. package/dist/events/event-types.d.ts.map +1 -1
  48. package/dist/instance/PluginInstance.d.ts +10 -10
  49. package/dist/instance/PluginInstance.d.ts.map +1 -1
  50. package/dist/instance/PluginInstance.js +29 -29
  51. package/dist/instance/PluginInstance.js.map +1 -1
  52. package/dist/instance/index.d.ts.map +1 -1
  53. package/dist/instance/index.js +3 -3
  54. package/dist/instance/index.js.map +1 -1
  55. package/dist/logger.d.ts +3 -3
  56. package/dist/logger.d.ts.map +1 -1
  57. package/dist/logger.js +9 -9
  58. package/dist/logger.js.map +1 -1
  59. package/dist/state/PluginState.schema.d.ts +451 -451
  60. package/dist/state/PluginState.schema.d.ts.map +1 -1
  61. package/dist/state/PluginState.schema.js +48 -48
  62. package/dist/state/PluginState.schema.js.map +1 -1
  63. package/dist/state/schemas.d.ts +13 -13
  64. package/dist/state/schemas.js +9 -9
  65. package/dist/state/schemas.js.map +1 -1
  66. package/package.json +6 -6
  67. package/src/configuration/PluginConfiguration.schema.ts +59 -60
  68. package/src/configuration/migration.ts +16 -16
  69. package/src/configuration-parser/hash-parser.ts +3 -3
  70. package/src/configuration-parser/html-parser.ts +3 -3
  71. package/src/configuration-parser/index.ts +2 -2
  72. package/src/configuration-parser/js-parser.ts +94 -94
  73. package/src/configuration-parser/migrate-legacy-configuration.ts +4 -4
  74. package/src/configuration-parser-legacy/LegacyParser.ts +63 -62
  75. package/src/configuration-parser-legacy/LegacyParser.utils.ts +24 -24
  76. package/src/configuration-parser-legacy/ModernParser.ts +8 -8
  77. package/src/configuration-parser-legacy/Parser.ts +1 -1
  78. package/src/configuration-parser-legacy/tests/LegacyDomParser.test.ts +20 -20
  79. package/src/configuration-parser-legacy/tests/LegacyLocationHashParser.test.ts +29 -29
  80. package/src/configuration-parser-legacy/tests/LegacyParser.test.ts +4 -4
  81. package/src/constants.ts +1 -1
  82. package/src/encoding.ts +6 -6
  83. package/src/events/event-types.ts +1 -2
  84. package/src/instance/PluginInstance.ts +30 -31
  85. package/src/instance/index.ts +3 -3
  86. package/src/logger.ts +9 -9
  87. package/src/state/PluginState.schema.ts +53 -53
  88. package/src/state/schemas.ts +9 -9
@@ -162,16 +162,10 @@ export interface JSConfigV0 {
162
162
 
163
163
  function strictSanitize(config: PluginConfigurationV0) {
164
164
  return sanitize<PluginConfigurationV0>({
165
- version: undefined,
166
- flow: config.flow,
167
- intent: config.intent,
168
- language: config.language,
169
- "employee-ids": config["employee-ids"],
170
- "employee-type": config["employee-type"],
171
165
  "application-office_search": config["application-office_search"],
172
166
  "application-scroll": config["application-scroll"],
173
- "application-timezone_selection": config["application-timezone_selection"],
174
167
  "application-theme": config["application-theme"],
168
+ "application-timezone_selection": config["application-timezone_selection"],
175
169
  "browser-timezone": config["browser-timezone"],
176
170
  "customer-company": config["customer-company"],
177
171
  "customer-customer_number": config["customer-customer_number"],
@@ -194,6 +188,11 @@ function strictSanitize(config: PluginConfigurationV0) {
194
188
  "customer-preferred_contact_id": config["customer-preferred_contact_id"],
195
189
  "customer-preferred_office_id": config["customer-preferred_office_id"],
196
190
  "customer-timezone": config["customer-timezone"],
191
+ "employee-ids": config["employee-ids"],
192
+ "employee-type": config["employee-type"],
193
+ flow: config.flow,
194
+ intent: config.intent,
195
+ language: config.language,
197
196
  "lead_segment-id": config["lead_segment-id"],
198
197
  "lead_segment-type": config["lead_segment-type"],
199
198
  "listing-id": config["listing-id"],
@@ -208,8 +207,9 @@ function strictSanitize(config: PluginConfigurationV0) {
208
207
  "session-id": config["session-id"],
209
208
  "session-source_tags": config["session-source_tags"],
210
209
  "session-status": config["session-status"],
210
+ source_href: config.source_href,
211
211
  "subject-ids": config["subject-ids"],
212
212
  "subject-type": config["subject-type"],
213
- source_href: config.source_href,
213
+ version: undefined,
214
214
  });
215
215
  }
@@ -36,8 +36,8 @@ export function parsePluginConfigurationV1({
36
36
  ...domConfig,
37
37
  ...hashConfig,
38
38
  ...jsConfig,
39
- source_href: href,
40
39
  "browser-timezone": browserTimeZone,
40
+ source_href: href,
41
41
  };
42
42
 
43
43
  return { config, domConfig, hashConfig, jsConfig };
@@ -7,33 +7,33 @@ import { createFakeElement } from "./test-utils.js";
7
7
  describe("parseDOMParams", () => {
8
8
  it("should work", () => {
9
9
  const element = createFakeElement({
10
- "skedify:appointment.subject_id": "<subject-id here>",
10
+ "skedify:application.scroll": "disable_initial_scroll_on_schedule",
11
+ "skedify:application.timezone_selection": "enable_timezone_selection",
11
12
  "skedify:appointment.office_id": "<office-id here>",
12
- "skedify:language": "nl-BE",
13
- "skedify:meeting_types": "video,office",
14
- "skedify:flow": "S'TQC",
15
- "skedify:location.formatted_address": "Zuiderlaan 1, 9000 Ghent, Belgium",
16
- "skedify:location.geolocation": "123;456",
17
- "skedify:location.city": "Ghent",
18
- "skedify:location.country": "Belgium",
19
- "skedify:location.postal_code": "9000",
20
- "skedify:location.state": "Oost-Vlaanderen",
21
- "skedify:location.street_1": "Zuiderlaan 1",
22
- "skedify:customer.location.formatted_address": "Zuiderlaan 1, 9000 Ghent, Belgium",
23
- "skedify:customer.location.geolocation": "123;456",
13
+ "skedify:appointment.subject_id": "<subject-id here>",
24
14
  "skedify:customer.location.city": "Ghent",
25
15
  "skedify:customer.location.country": "Belgium",
16
+ "skedify:customer.location.formatted_address": "Zuiderlaan 1, 9000 Ghent, Belgium",
17
+ "skedify:customer.location.geolocation": "123;456",
26
18
  "skedify:customer.location.postal_code": "9000",
27
19
  "skedify:customer.location.state": "Oost-Vlaanderen",
28
20
  "skedify:customer.location.street_1": "Zuiderlaan 1",
29
- "skedify:application.scroll": "disable_initial_scroll_on_schedule",
30
- "skedify:listing_id": "<listing-id here>",
31
21
  "skedify:external_listing_id": "<external-listing-id here>",
32
- "skedify:application.timezone_selection": "enable_timezone_selection",
22
+ "skedify:flow": "S'TQC",
23
+ "skedify:language": "nl-BE",
24
+ "skedify:listing_id": "<listing-id here>",
25
+ "skedify:location.city": "Ghent",
26
+ "skedify:location.country": "Belgium",
27
+ "skedify:location.formatted_address": "Zuiderlaan 1, 9000 Ghent, Belgium",
28
+ "skedify:location.geolocation": "123;456",
29
+ "skedify:location.postal_code": "9000",
30
+ "skedify:location.state": "Oost-Vlaanderen",
31
+ "skedify:location.street_1": "Zuiderlaan 1",
32
+ "skedify:meeting_types": "video,office",
33
+ "skedify:search.country": "BE",
33
34
  "skedify:session.id": "269828b4-df32-42fe-80c7-4fb72b692f7e",
34
35
  "skedify:session.source_tags": "A;B;C",
35
36
  "skedify:session.status": "disabled",
36
- "skedify:search.country": "BE",
37
37
  });
38
38
 
39
39
  expect(legacyParse({ element })).toMatchInlineSnapshot(`
@@ -111,12 +111,12 @@ describe("parseDOMParams", () => {
111
111
 
112
112
  it("should work with prefilled customer values", () => {
113
113
  const element = createFakeElement({
114
- "skedify:customer.timezone": "Europe/Brussels",
114
+ "skedify:customer.customer_number": "123",
115
+ "skedify:customer.email": "ken@skedify.co",
115
116
  "skedify:customer.first_name": "Ken",
116
117
  "skedify:customer.last_name": "Depelchin",
117
- "skedify:customer.email": "ken@skedify.co",
118
118
  "skedify:customer.phone_number": "0478123123",
119
- "skedify:customer.customer_number": "123",
119
+ "skedify:customer.timezone": "Europe/Brussels",
120
120
  });
121
121
 
122
122
  expect(legacyParse({ element })).toMatchInlineSnapshot(`
@@ -7,52 +7,52 @@ import { createFakeHash } from "./test-utils.js";
7
7
  describe("parseSkedifyURIHashParams", () => {
8
8
  it("should create a valid object from the encoded values", () => {
9
9
  const hash = createFakeHash({
10
- rco: "example resource code",
11
- sub: "example subject id",
12
- off: "example office id",
13
- ctz: "example customer timezone",
14
- con: "contact_id_1,contact_id_2",
15
- sco: "BE",
16
- lng: "example language",
17
- flo: "example flow",
18
- cfn: "example customer first_name",
19
- cln: "example customer last_name",
20
- cem: "example customer email",
21
- cpn: "example customer phone number",
10
+ cci: "Ghent",
22
11
  ccn: "example customer customer number",
23
- mty: "example meeting_types",
24
-
25
- // Location
26
- lfa: "Zuiderlaan 1, 9000 Ghent, Belgium",
27
- lgl: "55.79086400000001;12.157552",
28
- lci: "Ghent",
29
- lco: "BE",
30
- lpc: "9000",
31
- lsa: "Oost-Vlaanderen",
32
- lst: "Zuiderlaan 1",
12
+ cco: "BE",
13
+ cem: "example customer email",
14
+ cfn: "example customer first_name",
33
15
 
34
16
  // Customer location
35
17
  cgl: "55.79086400000001;12.157552",
36
- cci: "Ghent",
37
- cco: "BE",
18
+ cln: "example customer last_name",
19
+ con: "contact_id_1,contact_id_2",
38
20
  cpc: "9000",
21
+ cpn: "example customer phone number",
39
22
  csa: "Oost-Vlaanderen",
40
23
  cst: "Zuiderlaan 1",
24
+ ctz: "example customer timezone",
41
25
 
42
- // Application
43
- scr: "default",
26
+ // hints
27
+ eco: ["4", "5", "6"],
28
+ eli: "ABC123",
44
29
  ets: "enable_timezone_selection",
30
+ flo: "example flow",
31
+ lci: "Ghent",
32
+ lco: "BE",
33
+
34
+ // Location
35
+ lfa: "Zuiderlaan 1, 9000 Ghent, Belgium",
36
+ lgl: "55.79086400000001;12.157552",
45
37
 
46
38
  // Listings
47
39
  lis: "1",
48
- eli: "ABC123",
40
+ lng: "example language",
41
+ lpc: "9000",
42
+ lsa: "Oost-Vlaanderen",
43
+ lst: "Zuiderlaan 1",
44
+ mty: "example meeting_types",
45
+ off: "example office id",
46
+ rco: "example resource code",
47
+ sco: "BE",
49
48
 
50
- // hints
51
- eco: ["4", "5", "6"],
49
+ // Application
50
+ scr: "default",
52
51
 
53
52
  // Session
54
53
  sid: "269828b4-df32-42fe-80c7-4fb72b692f7e",
55
54
  sst: "A;B;C",
55
+ sub: "example subject id",
56
56
  });
57
57
 
58
58
  expect(legacyParse({ hash })).toMatchInlineSnapshot(`
@@ -9,18 +9,18 @@ describe("LegacyConfigurationParser", () => {
9
9
  it("Should correctly cascade config options", () => {
10
10
  const config = legacyParse({
11
11
  element: createFakeElement({
12
- "skedify:searchCountry": "EN",
13
- "skedify:appointment.subject_id": "1",
14
12
  "skedify:appointment.office_id": "2000",
13
+ "skedify:appointment.subject_id": "1",
14
+ "skedify:searchCountry": "EN",
15
15
  }),
16
16
  hash: createFakeHash({
17
+ lis: "3000",
17
18
  sco: "DE,NB",
18
19
  sub: "2",
19
- lis: "3000",
20
20
  }),
21
21
  options: {
22
- searchCountry: "BE,NL",
23
22
  lead_segment_code: "CODE_123",
23
+ searchCountry: "BE,NL",
24
24
  },
25
25
  });
26
26
 
package/src/constants.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { Language } from "@pexip-engage-public/graphql";
2
2
 
3
3
  export const TOKEN = {
4
- EMPLOYEE: "E",
5
4
  CUSTOMER: "C",
5
+ EMPLOYEE: "E",
6
6
  LOCK: "*",
7
7
  MEETING_TYPE: "M",
8
8
  OFFICE: "O",
package/src/encoding.ts CHANGED
@@ -25,16 +25,16 @@ export function decodeURIParameters<T>(str: string): T {
25
25
  const CONFIGURATION_SEARCH_PARAM_KEY = "configuration.pexip";
26
26
 
27
27
  export const pluginSearchParams = {
28
- encode(config: PluginConfiguration): URLSearchParams {
29
- const searchParams = new URLSearchParams();
30
- searchParams.set(CONFIGURATION_SEARCH_PARAM_KEY, encodeURIParameters(config));
31
-
32
- return searchParams;
33
- },
34
28
  decode(searchParams: URLSearchParams) {
35
29
  const config = searchParams.get(CONFIGURATION_SEARCH_PARAM_KEY);
36
30
  if (!config) return null;
37
31
 
38
32
  return decodeURIParameters<PluginConfiguration>(config);
39
33
  },
34
+ encode(config: PluginConfiguration): URLSearchParams {
35
+ const searchParams = new URLSearchParams();
36
+ searchParams.set(CONFIGURATION_SEARCH_PARAM_KEY, encodeURIParameters(config));
37
+
38
+ return searchParams;
39
+ },
40
40
  };
@@ -1,6 +1,5 @@
1
- import type { InputType } from "@pexip-engage-public/graphql";
2
-
3
1
  import type { GeoPosition } from "@pexip-engage/utils/get-current-position";
2
+ import type { InputType } from "@pexip-engage-public/graphql";
4
3
  import type { PluginState } from "../state/index.js";
5
4
  export type IFrameMessage = PublicIFrameMessage | PrivateIFrameMessage;
6
5
  export type PublicIFrameMessage =
@@ -14,17 +14,16 @@ import type {
14
14
  } from "../events/index.js";
15
15
  import { logger } from "../logger.js";
16
16
  import type { PluginIntent } from "../state/index.js";
17
-
18
- import { getPexipEngagePluginFrame } from "./PexipEngagePluginFrame.js";
19
17
  import {
20
18
  type CustomEventPayload,
19
+ dispatchEvent,
21
20
  type InstanceEvent,
22
21
  PEXIP_ENGAGE_PLUGIN_EVENT,
23
22
  type PluginCustomEvent,
24
23
  type StaticEvent,
25
- dispatchEvent,
26
24
  } from "./dispatchEvent.js";
27
25
  import type { PluginHooks } from "./hooks.js";
26
+ import { getPexipEngagePluginFrame } from "./PexipEngagePluginFrame.js";
28
27
 
29
28
  type PluginEventListener = (event: PluginCustomEvent) => unknown;
30
29
 
@@ -44,14 +43,14 @@ export class PluginInstance {
44
43
  if (!isElement(target)) throw new Error("Invalid target passed, expected an element.");
45
44
  this.#target = target;
46
45
  this.#config = PluginInstance.#configurationParser({
47
- element: this.#target,
48
- options,
49
- hash: window.location.hash,
50
46
  browser: {
51
- legacyMode: PluginInstance.#legacyMode,
52
47
  href: window.location.href,
48
+ legacyMode: PluginInstance.#legacyMode,
53
49
  timeZone: new Intl.DateTimeFormat().resolvedOptions().timeZone,
54
50
  },
51
+ element: this.#target,
52
+ hash: window.location.hash,
53
+ options,
55
54
  });
56
55
 
57
56
  try {
@@ -69,10 +68,10 @@ export class PluginInstance {
69
68
  PluginInstance.#instances.push(this);
70
69
  queueMacroTask(() => {
71
70
  dispatchEvent({
72
- target: this.#target,
73
71
  bubbles: true,
74
72
  cancelable: true,
75
73
  detail: { instance: this, type: PluginInstance.EVENT_CREATION },
74
+ target: this.#target,
76
75
  });
77
76
  });
78
77
  }
@@ -102,22 +101,22 @@ export class PluginInstance {
102
101
  message.type === "MISCONFIGURED"
103
102
  ) {
104
103
  return dispatchEvent({
105
- target: this.#target,
106
104
  detail: { instance: self, ...message },
105
+ target: this.#target,
107
106
  });
108
107
  }
109
108
 
110
109
  if (message.type === "PRE_APPOINTMENT_REQUEST") {
111
110
  if (message.payload) {
112
111
  this.#hooks.beforeAppointmentCreate?.({
113
- data: message.payload,
114
112
  appointment: { meta: this.appointment.meta },
113
+ data: message.payload,
115
114
  });
116
115
  }
117
116
 
118
117
  this.#instance.iFrameResizer.sendMessage({
119
- type: "PRE_APPOINTMENT_REQUEST",
120
118
  payload: { meta: this.#meta },
119
+ type: "PRE_APPOINTMENT_REQUEST",
121
120
  });
122
121
 
123
122
  return;
@@ -125,8 +124,8 @@ export class PluginInstance {
125
124
 
126
125
  if (message.type === "REQUEST_ORIGIN_URL") {
127
126
  this.#instance.iFrameResizer.sendMessage({
128
- type: "REQUEST_ORIGIN_URL",
129
127
  payload: { href: window.location.href },
128
+ type: "REQUEST_ORIGIN_URL",
130
129
  });
131
130
 
132
131
  return;
@@ -136,10 +135,10 @@ export class PluginInstance {
136
135
  const geolocation = getCurrentPosition();
137
136
 
138
137
  this.#instance.iFrameResizer.sendMessage({
139
- type: "REQUEST_GEOLOCATION",
140
138
  payload: await geolocation.catch((error) =>
141
139
  typeof error === "string" ? { error } : { error: "Unknown error" },
142
140
  ),
141
+ type: "REQUEST_GEOLOCATION",
143
142
  });
144
143
 
145
144
  return;
@@ -186,20 +185,20 @@ export class PluginInstance {
186
185
  const self = this;
187
186
  const [instance] = resizer(
188
187
  {
189
- log: false,
190
188
  checkOrigin: false,
191
- onMessage: this.#handleMessage,
192
- resizeFrom: "child",
193
189
  heightCalculationMethod: "taggedElement",
190
+ log: false,
194
191
  onInit() {
195
192
  self.#status = "success";
196
193
  dispatchEvent({
197
- target: self.#target,
198
194
  bubbles: true,
199
195
  cancelable: true,
200
196
  detail: { instance: self, type: PluginInstance.EVENT_LOADED },
197
+ target: self.#target,
201
198
  });
202
199
  },
200
+ onMessage: this.#handleMessage,
201
+ resizeFrom: "child",
203
202
  },
204
203
  iframe,
205
204
  );
@@ -237,13 +236,13 @@ export class PluginInstance {
237
236
  // KEEP STABLE UNTIL February 2024
238
237
  /** @private internal API */
239
238
  setCSSVariable = (name: string, value: string) => {
240
- warnPrivate({ type: "function", name: "setCSSVariable" });
239
+ warnPrivate({ name: "setCSSVariable", type: "function" });
241
240
 
242
- this.#instance.iFrameResizer.sendMessage({ type: "CSS_VAR_UPDATE", payload: { name, value } });
241
+ this.#instance.iFrameResizer.sendMessage({ payload: { name, value }, type: "CSS_VAR_UPDATE" });
243
242
  };
244
243
 
245
244
  setCustomCSS = (css: string) => {
246
- this.#instance.iFrameResizer.sendMessage({ type: "CUSTOM_CSS_UPDATE", payload: { css } });
245
+ this.#instance.iFrameResizer.sendMessage({ payload: { css }, type: "CUSTOM_CSS_UPDATE" });
247
246
  };
248
247
 
249
248
  #listeners = new Set<EventListener>();
@@ -274,31 +273,31 @@ export class PluginInstance {
274
273
 
275
274
  get appointment() {
276
275
  return {
277
- intent: this.#state?.config.intent,
278
276
  appointmentId: this.#state?.appointmentId,
279
277
  callbackRequestId: this.#state?.callbackRequestId,
280
- officeId: this.#state?.officeId,
281
- meetingType: this.#state?.meetingType,
282
- subjectId: this.#state?.subjectId,
283
- subjectGroupId: this.#state?.subjectCategoryId,
284
- employeeId: this.#state?.employeeId,
285
278
  customer: this.#state?.customer,
279
+ employeeId: this.#state?.employeeId,
280
+ intent: this.#state?.config.intent,
281
+ meetingType: this.#state?.meetingType,
286
282
  meta: {
283
+ get: (key: string, defaultValue: unknown) => {
284
+ return this.#meta[key] ?? defaultValue;
285
+ },
287
286
  getAll: () => {
288
287
  return this.#meta;
289
288
  },
290
- get: (key: string, defaultValue: unknown) => {
291
- return this.#meta[key] ?? defaultValue;
289
+ remove: (key: string) => {
290
+ delete this.#meta[key];
292
291
  },
293
292
  set: (key: string, value: unknown) => {
294
293
  this.#meta[key] = value;
295
294
 
296
295
  return this.#meta;
297
296
  },
298
- remove: (key: string) => {
299
- delete this.#meta[key];
300
- },
301
297
  },
298
+ officeId: this.#state?.officeId,
299
+ subjectGroupId: this.#state?.subjectCategoryId,
300
+ subjectId: this.#state?.subjectId,
302
301
  };
303
302
  }
304
303
  static openDebugger() {
@@ -1,5 +1,5 @@
1
- import { PluginInstance as _PluginInstance } from "./PluginInstance.js";
2
1
  import { dispatchEvent } from "./dispatchEvent.js";
2
+ import { PluginInstance as _PluginInstance } from "./PluginInstance.js";
3
3
 
4
4
  export type { PexipEngagePluginEventID, PluginCustomEvent } from "./dispatchEvent.js";
5
5
  export { PEXIP_ENGAGE_PLUGIN_EVENT } from "./dispatchEvent.js";
@@ -54,10 +54,10 @@ export function installOnGlobal(options: { shouldWarn: boolean } = { shouldWarn:
54
54
  window.PexipEngage.q.push = (item) => processQueueItem(item);
55
55
 
56
56
  dispatchEvent({
57
- target: document,
58
- detail: { type: PluginStatic.EVENT_INIT },
59
57
  bubbles: true,
60
58
  cancelable: true,
59
+ detail: { type: PluginStatic.EVENT_INIT },
60
+ target: document,
61
61
  });
62
62
  }
63
63
 
package/src/logger.ts CHANGED
@@ -4,22 +4,22 @@ export const logger = {
4
4
  debug(arg: string, ...args: unknown[]) {
5
5
  console.debug(PREFIX + arg, ...args);
6
6
  },
7
- info(arg: string, ...args: unknown[]) {
8
- console.info(PREFIX + arg, ...args);
9
- },
10
- warn(arg: string, ...args: unknown[]) {
11
- console.warn(PREFIX + arg, ...args);
12
- },
13
7
  error(arg: string, ...args: unknown[]) {
14
8
  console.error(PREFIX + arg, ...args);
15
9
  },
16
- log(arg: string, ...args: unknown[]) {
17
- console.log(PREFIX + arg, ...args);
18
- },
19
10
  group(arg: string, ...args: unknown[]) {
20
11
  console.group(PREFIX + arg, ...args);
21
12
  },
22
13
  groupEnd() {
23
14
  console.groupEnd();
24
15
  },
16
+ info(arg: string, ...args: unknown[]) {
17
+ console.info(PREFIX + arg, ...args);
18
+ },
19
+ log(arg: string, ...args: unknown[]) {
20
+ console.log(PREFIX + arg, ...args);
21
+ },
22
+ warn(arg: string, ...args: unknown[]) {
23
+ console.warn(PREFIX + arg, ...args);
24
+ },
25
25
  };
@@ -6,12 +6,12 @@ import {
6
6
  } from "../configuration/PluginConfiguration.schema.js";
7
7
 
8
8
  import {
9
- util,
10
9
  CustomerFormSchema,
10
+ form,
11
11
  type IntentSchema,
12
12
  LocationSchema,
13
13
  MeetingTypeSchema,
14
- form,
14
+ util,
15
15
  } from "./schemas.js";
16
16
 
17
17
  export type PluginIntent = z.infer<typeof IntentSchema>;
@@ -19,27 +19,69 @@ export interface PluginState extends z.infer<typeof PluginStateSchema> {}
19
19
  export interface PluginStateInput extends z.input<typeof PluginStateSchema> {}
20
20
 
21
21
  export const PluginStateSchema = z.object({
22
- flow: FlowSchema,
23
- subjectId: z.string().optional(),
24
- officeId: z.string().optional(),
25
- employeeId: z.string().optional(),
26
22
  appointmentId: z.string().optional(),
27
23
  callbackRequestId: z.string().optional(),
28
- metadata: z.record(z.unknown()).optional(),
24
+
25
+ /** This object is the validated version `PluginConfiguration.current.ts` */
26
+ config: PluginConfigurationSchema,
27
+ customer: CustomerFormSchema.optional(),
28
+ employeeId: z.string().optional(),
29
+
30
+ // resolved values used for SRS
31
+ employees: z.string().array().optional(),
32
+ errors: z
33
+ .object({
34
+ /**
35
+ * Each step can have errors, in case of the timetable this currently only happens when
36
+ * a slot is booked by another customer between selecting the slot, and confirming the appointment
37
+ * (request).
38
+ */
39
+ timetable: z.literal(true).optional(),
40
+ })
41
+ .default({}),
42
+ fileUploads: z
43
+ .record(
44
+ z.object({ answerId: z.string(), fileName: z.string(), uploadUrl: z.string().nullable() }),
45
+ )
46
+ .optional(),
47
+ flow: FlowSchema,
48
+ leadSegmentId: z.string().optional(),
49
+ listingId: z.string().optional(),
50
+ /** The selected geolocation of the user */
51
+ location: LocationSchema.default({}),
29
52
  meetingType: MeetingTypeSchema.optional(),
53
+ meetingTypes: MeetingTypeSchema.array().optional(),
54
+ metadata: z.record(z.unknown()).optional(),
55
+ officeId: z.string().optional(),
56
+ offices: z.string().array().optional(),
57
+ questions: form.questionnaire,
58
+ schedulable: z.boolean().default(true),
59
+ /** Marking certain steps as (automatically) skipped or not. */
60
+ skipped: z
61
+ .object({
62
+ employee: z.literal(true).optional(),
63
+ meetingType: z.literal(true).optional(),
64
+ office: z.literal(true).optional(),
65
+ questions: z.literal(true).optional(),
66
+ subject: z.literal(true).optional(),
67
+ })
68
+ .default({}),
69
+ subjectGroups: z.string().array().optional(),
70
+ subjectId: z.string().optional(),
71
+ subjects: z.string().array().optional(),
30
72
  timetable: z
31
73
  .union([
32
74
  z.object({
75
+ employeeIds: z.undefined(),
76
+ end: z.undefined(),
33
77
  intent: z.literal("callback").optional(),
34
78
  start: z.undefined(),
35
- end: z.undefined(),
36
- employeeIds: z.undefined(),
37
79
  }),
38
80
  z.object({
81
+ employeeIds: util.array,
82
+ end: z.string().optional(),
39
83
  intent: z.literal("schedule").optional(),
40
84
  start: z.string().optional(),
41
- end: z.string().optional(),
42
- employeeIds: util.array,
43
85
  }),
44
86
  ])
45
87
  .and(
@@ -49,48 +91,6 @@ export const PluginStateSchema = z.object({
49
91
  }),
50
92
  )
51
93
  .default({}),
52
- customer: CustomerFormSchema.optional(),
53
- questions: form.questionnaire,
54
- fileUploads: z
55
- .record(
56
- z.object({ fileName: z.string(), answerId: z.string(), uploadUrl: z.string().nullable() }),
57
- )
58
- .optional(),
59
- /** The selected geolocation of the user */
60
- location: LocationSchema.default({}),
61
-
62
- // resolved values used for SRS
63
- employees: z.string().array().optional(),
64
- leadSegmentId: z.string().optional(),
65
- listingId: z.string().optional(),
66
- meetingTypes: MeetingTypeSchema.array().optional(),
67
- offices: z.string().array().optional(),
68
- subjectGroups: z.string().array().optional(),
69
- subjects: z.string().array().optional(),
70
- schedulable: z.boolean().default(true),
71
- /** Marking certain steps as (automatically) skipped or not. */
72
- skipped: z
73
- .object({
74
- subject: z.literal(true).optional(),
75
- office: z.literal(true).optional(),
76
- meetingType: z.literal(true).optional(),
77
- employee: z.literal(true).optional(),
78
- questions: z.literal(true).optional(),
79
- })
80
- .default({}),
81
- errors: z
82
- .object({
83
- /**
84
- * Each step can have errors, in case of the timetable this currently only happens when
85
- * a slot is booked by another customer between selecting the slot, and confirming the appointment
86
- * (request).
87
- */
88
- timetable: z.literal(true).optional(),
89
- })
90
- .default({}),
91
94
  /** Warnings that should be logged to the console */
92
95
  warning: z.string().optional(),
93
-
94
- /** This object is the validated version `PluginConfiguration.current.ts` */
95
- config: PluginConfigurationSchema,
96
96
  });