@servicetitan/web-components 30.2.1 → 30.3.1

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.
@@ -58,6 +58,8 @@ export declare class EventBus<EventTypes extends Serializable<EventTypes> = neve
58
58
  * @param data The data to pass to the event's handler.
59
59
  */
60
60
  emit: <T extends Serializable<T>, Event extends SymbolToken<T> | keyof EventTypes = any>(event: SymbolTokenEventType<T, Event>, ...data: Event extends SymbolToken<any> ? undefined extends T ? [T?] : [T] : [EventTypes] extends [never] ? [T?] : Event extends keyof EventTypes ? undefined extends EventTypes[Event] ? [EventTypes[Event]?] : [EventTypes[Event]] extends [never] ? [] : [EventTypes[Event]] : never) => void;
61
+ private validateEvent;
62
+ private getName;
61
63
  }
62
64
  export {};
63
65
  //# sourceMappingURL=event-bus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"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"}
package/dist/event-bus.js CHANGED
@@ -17,6 +17,7 @@ export class EventBus {
17
17
  * @param handler The handler to call when the event occurs. This handler is passed a `resolve` callback to return a successful result, and a `reject` callback to return an error.
18
18
  */
19
19
  on: (event, handler) => {
20
+ this.validateEvent(event);
20
21
  this.emitter.on(event, handler);
21
22
  },
22
23
  /**
@@ -33,6 +34,7 @@ export class EventBus {
33
34
  * @returns a Promise that resolves or rejects depending on whether the job completes successfully.
34
35
  */
35
36
  emit: (event) => {
37
+ this.validateEvent(event);
36
38
  return new Promise((resolve, reject) => {
37
39
  this.emitter.emit(event, {
38
40
  resolve,
@@ -65,6 +67,7 @@ export class EventBus {
65
67
  configurable: true,
66
68
  writable: true,
67
69
  value: (event, handler) => {
70
+ this.validateEvent(event);
68
71
  this.emitter.on(event, handler);
69
72
  }
70
73
  });
@@ -91,9 +94,77 @@ export class EventBus {
91
94
  configurable: true,
92
95
  writable: true,
93
96
  value: (event, ...data) => {
97
+ this.validateEvent(event);
94
98
  this.emitter.emit(event, data[0]);
95
99
  }
96
100
  });
97
101
  }
102
+ validateEvent(event) {
103
+ if (process.env.NODE_ENV === 'production') {
104
+ return;
105
+ }
106
+ const name = this.getName(event);
107
+ if (name === undefined || /^[^:]+:.+/.test(name) || allowListedEvents.has(name)) {
108
+ return;
109
+ }
110
+ throw new Error('event must have format {module}:{name}');
111
+ }
112
+ getName(event) {
113
+ var _a;
114
+ if (typeof event === 'string') {
115
+ return event;
116
+ }
117
+ if (typeof event === 'symbol') {
118
+ return (_a = Symbol.keyFor(event)) !== null && _a !== void 0 ? _a : '';
119
+ }
120
+ return undefined;
121
+ }
98
122
  }
123
+ const allowListedEvents = new Set([
124
+ '[EH] Module Link Clicked',
125
+ '[EH] Module Loaded',
126
+ '[internal] reset',
127
+ 'blink',
128
+ 'CLOSE_COMPONENT',
129
+ 'CLOSE_JOB_EDIT_FLYOUT',
130
+ 'company-profile-request-save',
131
+ 'company-profile-saved-error',
132
+ 'company-profile-saved',
133
+ 'dismiss-discrepancy-event',
134
+ 'dismiss-discrepancy-map-event',
135
+ 'dispatch-JobEditFlyout-fetchData',
136
+ 'dispatchpro-fetchStatus',
137
+ 'dispatchpro-open-issuereporter',
138
+ 'DRAWER_CREATED_CUSTOMER',
139
+ 'employees-emails-processed',
140
+ 'employees-request-save',
141
+ 'employees-saved-error',
142
+ 'employees-saved',
143
+ 'ium-ep-cancel-changes',
144
+ 'ium-ep-form-can-be-submitted-change',
145
+ 'ium-ep-save-changes',
146
+ 'loaded',
147
+ 'my-custom-event',
148
+ 'NEW_EVENT',
149
+ 'ON_WIDGET_INIT',
150
+ 'OPEN_ASSIST_SCREEN',
151
+ 'OPEN_CREATE_CUSTOMER_DRAWER',
152
+ 'OPEN_DC_SIDE_PANEL_COMPONENT',
153
+ 'open-troubleshooter',
154
+ 'resolve-discrepancy-map-event',
155
+ 'restore-discrepancy-event',
156
+ 'setLabel',
157
+ 'SHOW_POP_UP_MESSAGE',
158
+ 'TEAMS_SELECTED',
159
+ 'tech-is-dispatch-pro-change',
160
+ 'technicians-emails-processed',
161
+ 'technicians-request-save',
162
+ 'technicians-saved-error',
163
+ 'technicians-saved',
164
+ 'timesheet-activity-saved',
165
+ 'TOGGLE_DC_SIDE_PANEL_COMPONENT',
166
+ 'updateUserEmail',
167
+ 'visibility',
168
+ ':widgets:message',
169
+ ]);
99
170
  //# sourceMappingURL=event-bus.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AACnE,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAW,iBAAiB,CAAC,CAAC;AAExE,MAAM,UAAU,kBAAkB;IAC9B,OAAO,WAAW,CAAuB,iBAAiB,CAAC,CAAC;AAChE,CAAC;AAqCD,MAAM,OAAO,QAAQ;IAArB;QACI;;;;mBAAM;gBACF;;;;mBAIG;gBACH,EAAE,EAAE,CACA,KAAY,EACZ,OAA+B,EACjC,EAAE;oBACA,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBACpC,CAAC;gBAED;;;;mBAIG;gBACH,GAAG,EAAE,CACD,KAAY,EACZ,OAA+B,EACjC,EAAE;oBACA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBACrC,CAAC;gBAED;;;;mBAIG;gBACH,IAAI,EAAE,CAAoD,KAAY,EAAE,EAAE;oBACtE,OAAO,IAAI,OAAO,CAEhB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBAClB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE;4BACrB,OAAO;4BACP,MAAM,EAAE,CAAC,MAAuB,EAAE,EAAE;gCAChC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;oCACxD,MAAM,CAAC,MAAM,CAAC,CAAC;gCACnB,CAAC;qCAAM,CAAC;oCACJ,MAAM,EAAE,CAAC;gCACb,CAAC;4BACL,CAAC;yBACJ,CAAC,CAAC;oBACP,CAAC,CAAC,CAAC;gBACP,CAAC;aACJ;WAAC;QAEM;;;;mBAAU,IAAI,EAAO;WAAC;QAE9B;;;;WAIG;QACH;;;;mBAAK,CACD,KAAqC,EACrC,OAA2C,EAC7C,EAAE;gBACA,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,CAAC;WAAC;QAEF;;;;WAIG;QACH;;;;mBAAM,CAIF,KAAqC,EACrC,OAA2C,EAC7C,EAAE;gBACA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACrC,CAAC;WAAC;QAEF;;;;WAIG;QACH;;;;mBAAO,CACH,KAAqC,EACrC,GAAG,IAYY,EACjB,EAAE;gBACA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,CAAC;WAAC;IACN,CAAC;CAAA"}
1
+ {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/web-components",
3
- "version": "30.2.1",
3
+ "version": "30.3.1",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,17 +15,17 @@
15
15
  "src"
16
16
  ],
17
17
  "dependencies": {
18
- "@servicetitan/error-boundary": "30.2.1",
18
+ "@servicetitan/error-boundary": "30.3.1",
19
19
  "lodash.get": "~4.4.2",
20
20
  "mitt": "~3.0.1",
21
21
  "semver": "~7.7.2"
22
22
  },
23
23
  "devDependencies": {
24
- "@servicetitan/anvil2": "^1.33.1",
25
- "@servicetitan/design-system": "~14.5.2",
26
- "@servicetitan/launchdarkly-service": "30.2.1",
27
- "@servicetitan/log-service": "30.2.1",
28
- "@servicetitan/react-ioc": "30.2.1",
24
+ "@servicetitan/anvil2": "^1.34.0",
25
+ "@servicetitan/design-system": "~14.5.3",
26
+ "@servicetitan/launchdarkly-service": "30.3.1",
27
+ "@servicetitan/log-service": "30.3.1",
28
+ "@servicetitan/react-ioc": "30.3.1",
29
29
  "@testing-library/dom": "^10.4.0",
30
30
  "@testing-library/jest-dom": "^6.6.3",
31
31
  "@testing-library/react": "^16.3.0",
@@ -41,11 +41,11 @@
41
41
  "shadow-dom-testing-library": "^1.12.0"
42
42
  },
43
43
  "peerDependencies": {
44
- "@servicetitan/anvil2": ">=1.33.1",
45
- "@servicetitan/design-system": ">=14.5.2",
46
- "@servicetitan/launchdarkly-service": "30.2.1",
47
- "@servicetitan/log-service": "30.2.1",
48
- "@servicetitan/react-ioc": "30.2.1",
44
+ "@servicetitan/anvil2": ">=1.34.0",
45
+ "@servicetitan/design-system": ">=14.5.3",
46
+ "@servicetitan/launchdarkly-service": "30.3.1",
47
+ "@servicetitan/log-service": "30.3.1",
48
+ "@servicetitan/react-ioc": "30.3.1",
49
49
  "history": "~4.10.1",
50
50
  "react": ">=17.0.2",
51
51
  "react-dom": ">=17.0.2"
@@ -67,5 +67,5 @@
67
67
  "cli": {
68
68
  "webpack": false
69
69
  },
70
- "gitHead": "297a0bb448afa86cf35e80c5d9a7613d8f86b0a3"
70
+ "gitHead": "4d7f01d86d64fc00160d63a2e2a3448f28aa7a2d"
71
71
  }
@@ -3,9 +3,57 @@ import { EventBus, typedEventBusToken, EVENT_BUS_TOKEN } from '../event-bus';
3
3
 
4
4
  jest.mock('mitt', () => jest.fn());
5
5
 
6
+ const allowListedEvents = [
7
+ '[EH] Module Link Clicked',
8
+ '[EH] Module Loaded',
9
+ '[internal] reset',
10
+ 'blink',
11
+ 'CLOSE_COMPONENT',
12
+ 'CLOSE_JOB_EDIT_FLYOUT',
13
+ 'company-profile-request-save',
14
+ 'company-profile-saved-error',
15
+ 'company-profile-saved',
16
+ 'dismiss-discrepancy-event',
17
+ 'dismiss-discrepancy-map-event',
18
+ 'dispatch-JobEditFlyout-fetchData',
19
+ 'dispatchpro-fetchStatus',
20
+ 'dispatchpro-open-issuereporter',
21
+ 'DRAWER_CREATED_CUSTOMER',
22
+ 'employees-emails-processed',
23
+ 'employees-request-save',
24
+ 'employees-saved-error',
25
+ 'employees-saved',
26
+ 'ium-ep-cancel-changes',
27
+ 'ium-ep-form-can-be-submitted-change',
28
+ 'ium-ep-save-changes',
29
+ 'loaded',
30
+ 'my-custom-event',
31
+ 'NEW_EVENT',
32
+ 'ON_WIDGET_INIT',
33
+ 'OPEN_ASSIST_SCREEN',
34
+ 'OPEN_CREATE_CUSTOMER_DRAWER',
35
+ 'OPEN_DC_SIDE_PANEL_COMPONENT',
36
+ 'open-troubleshooter',
37
+ 'resolve-discrepancy-map-event',
38
+ 'restore-discrepancy-event',
39
+ 'setLabel',
40
+ 'SHOW_POP_UP_MESSAGE',
41
+ 'TEAMS_SELECTED',
42
+ 'tech-is-dispatch-pro-change',
43
+ 'technicians-emails-processed',
44
+ 'technicians-request-save',
45
+ 'technicians-saved-error',
46
+ 'technicians-saved',
47
+ 'timesheet-activity-saved',
48
+ 'TOGGLE_DC_SIDE_PANEL_COMPONENT',
49
+ 'updateUserEmail',
50
+ 'visibility',
51
+ ':widgets:message',
52
+ ];
53
+
6
54
  describe(`[web-components] ${EventBus.name}`, () => {
7
55
  let eventBus: EventBus;
8
- const type = 'event';
56
+ let event: string;
9
57
  const handler = jest.fn();
10
58
  const mittOn = jest.fn();
11
59
  const mittOff = jest.fn();
@@ -19,56 +67,110 @@ describe(`[web-components] ${EventBus.name}`, () => {
19
67
  }));
20
68
 
21
69
  eventBus = new EventBus();
70
+ event = 'example:event';
22
71
  });
23
72
 
24
- describe("when the 'on' method is called", () => {
25
- const subject = () => eventBus.on(type, handler);
73
+ function withInvalidEvent(test: () => void) {
74
+ describe('with invalid event', () => {
75
+ beforeEach(() => (event = 'foo'));
76
+
77
+ test();
78
+ });
79
+ }
80
+
81
+ function itRejectsInvalidEvent(subject: () => void) {
82
+ withInvalidEvent(() => {
83
+ test('throws error', () => {
84
+ expect(subject).toThrow();
85
+ });
86
+ });
87
+ }
88
+
89
+ describe('on', () => {
90
+ const subject = (testEvent?: string | symbol) => eventBus.on(testEvent ?? event, handler);
26
91
 
27
92
  test("calls the private mitt instance's 'on' method", () => {
28
93
  subject();
29
- expect(mittOn).toHaveBeenCalledWith(type, handler);
94
+ expect(mittOn).toHaveBeenCalledWith(event, handler);
95
+ });
96
+
97
+ itRejectsInvalidEvent(subject);
98
+
99
+ test.each([
100
+ '',
101
+ ':',
102
+ ':name',
103
+ 'module:',
104
+ Symbol(),
105
+ Symbol.for(':'),
106
+ Symbol.for(':name'),
107
+ Symbol.for('module:'),
108
+ ])('rejects "%s"', disallowed => {
109
+ expect(() => subject(disallowed)).toThrow();
110
+ });
111
+
112
+ test.each(allowListedEvents)('allows "%s" as string or Symbol', allowed => {
113
+ expect(() => subject(allowed)).not.toThrow();
114
+ expect(() => subject(Symbol.for(allowed))).not.toThrow();
115
+ });
116
+
117
+ withInvalidEvent(() => {
118
+ describe('when in production environment', () => {
119
+ const nodeEnv = process.env.NODE_ENV;
120
+
121
+ beforeEach(() => (process.env.NODE_ENV = 'production'));
122
+ afterEach(() => (process.env.NODE_ENV = nodeEnv));
123
+
124
+ test('accepts event', () => {
125
+ expect(subject).not.toThrow();
126
+ });
127
+ });
30
128
  });
31
129
  });
32
130
 
33
- describe("when the 'off' method is called", () => {
34
- const subject = () => eventBus.off(type, handler);
131
+ describe('off', () => {
132
+ const subject = () => eventBus.off(event, handler);
35
133
 
36
134
  test("calls the private mitt instance's 'off' method", () => {
37
135
  subject();
38
- expect(mittOff).toHaveBeenCalledWith(type, handler);
136
+ expect(mittOff).toHaveBeenCalledWith(event, handler);
39
137
  });
40
138
  });
41
139
 
42
- describe("when the 'emit' method is called", () => {
140
+ describe('emit', () => {
43
141
  const data = { foo: 'bar' };
44
- const subject = () => eventBus.emit(type, data);
142
+ const subject = () => eventBus.emit(event, data);
45
143
 
46
144
  test("calls the private mitt instance's 'emit' method", () => {
47
145
  subject();
48
- expect(mittEmit).toHaveBeenCalledWith(type, data);
146
+ expect(mittEmit).toHaveBeenCalledWith(event, data);
49
147
  });
148
+
149
+ itRejectsInvalidEvent(subject);
50
150
  });
51
151
 
52
- describe("when job's 'on' method is called", () => {
53
- const subject = () => eventBus.job.on(type, handler);
152
+ describe('job.on', () => {
153
+ const subject = () => eventBus.job.on(event, handler);
54
154
 
55
155
  test("calls the private mitt instance's 'on' method", () => {
56
156
  subject();
57
- expect(mittOn).toHaveBeenCalledWith(type, handler);
157
+ expect(mittOn).toHaveBeenCalledWith(event, handler);
58
158
  });
159
+
160
+ itRejectsInvalidEvent(subject);
59
161
  });
60
162
 
61
- describe("when job's 'off' method is called", () => {
62
- const subject = () => eventBus.job.off(type, handler);
163
+ describe('job.off', () => {
164
+ const subject = () => eventBus.job.off(event, handler);
63
165
 
64
166
  test("calls the private mitt instance's 'off' method", () => {
65
167
  subject();
66
- expect(mittOff).toHaveBeenCalledWith(type, handler);
168
+ expect(mittOff).toHaveBeenCalledWith(event, handler);
67
169
  });
68
170
  });
69
171
 
70
- describe("when job's 'emit' method is called", () => {
71
- const subject = () => eventBus.job.emit(type);
172
+ describe('job.emit', () => {
173
+ const subject = () => eventBus.job.emit(event);
72
174
 
73
175
  describe("when emit's 'emit' resolves", () => {
74
176
  beforeEach(() => {
@@ -122,6 +224,8 @@ describe(`[web-components] ${EventBus.name}`, () => {
122
224
  });
123
225
  });
124
226
  });
227
+
228
+ itRejectsInvalidEvent(subject);
125
229
  });
126
230
  });
127
231
 
package/src/event-bus.ts CHANGED
@@ -55,6 +55,7 @@ export class EventBus<EventTypes extends Serializable<EventTypes> = never> {
55
55
  event: Event,
56
56
  handler: JobEventHandler<Event>
57
57
  ) => {
58
+ this.validateEvent(event);
58
59
  this.emitter.on(event, handler);
59
60
  },
60
61
 
@@ -76,6 +77,7 @@ export class EventBus<EventTypes extends Serializable<EventTypes> = never> {
76
77
  * @returns a Promise that resolves or rejects depending on whether the job completes successfully.
77
78
  */
78
79
  emit: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event) => {
80
+ this.validateEvent(event);
79
81
  return new Promise<
80
82
  Event extends SymbolToken<infer ResultType> ? Serializable<ResultType> : JobPayload
81
83
  >((resolve, reject) => {
@@ -104,6 +106,7 @@ export class EventBus<EventTypes extends Serializable<EventTypes> = never> {
104
106
  event: SymbolTokenEventType<T, Event>,
105
107
  handler: EventHandler<EventTypes, Event, T>
106
108
  ) => {
109
+ this.validateEvent(event);
107
110
  this.emitter.on(event, handler);
108
111
  };
109
112
 
@@ -143,6 +146,78 @@ export class EventBus<EventTypes extends Serializable<EventTypes> = never> {
143
146
  : [EventTypes[Event]]
144
147
  : never
145
148
  ) => {
149
+ this.validateEvent(event);
146
150
  this.emitter.emit(event, data[0]);
147
151
  };
152
+
153
+ private validateEvent(event: any) {
154
+ if (process.env.NODE_ENV === 'production') {
155
+ return;
156
+ }
157
+
158
+ const name = this.getName(event);
159
+ if (name === undefined || /^[^:]+:.+/.test(name) || allowListedEvents.has(name)) {
160
+ return;
161
+ }
162
+
163
+ throw new Error('event must have format {module}:{name}');
164
+ }
165
+
166
+ private getName(event: any) {
167
+ if (typeof event === 'string') {
168
+ return event;
169
+ }
170
+ if (typeof event === 'symbol') {
171
+ return Symbol.keyFor(event) ?? '';
172
+ }
173
+ return undefined;
174
+ }
148
175
  }
176
+
177
+ const allowListedEvents = new Set([
178
+ '[EH] Module Link Clicked',
179
+ '[EH] Module Loaded',
180
+ '[internal] reset',
181
+ 'blink',
182
+ 'CLOSE_COMPONENT',
183
+ 'CLOSE_JOB_EDIT_FLYOUT',
184
+ 'company-profile-request-save',
185
+ 'company-profile-saved-error',
186
+ 'company-profile-saved',
187
+ 'dismiss-discrepancy-event',
188
+ 'dismiss-discrepancy-map-event',
189
+ 'dispatch-JobEditFlyout-fetchData',
190
+ 'dispatchpro-fetchStatus',
191
+ 'dispatchpro-open-issuereporter',
192
+ 'DRAWER_CREATED_CUSTOMER',
193
+ 'employees-emails-processed',
194
+ 'employees-request-save',
195
+ 'employees-saved-error',
196
+ 'employees-saved',
197
+ 'ium-ep-cancel-changes',
198
+ 'ium-ep-form-can-be-submitted-change',
199
+ 'ium-ep-save-changes',
200
+ 'loaded',
201
+ 'my-custom-event',
202
+ 'NEW_EVENT',
203
+ 'ON_WIDGET_INIT',
204
+ 'OPEN_ASSIST_SCREEN',
205
+ 'OPEN_CREATE_CUSTOMER_DRAWER',
206
+ 'OPEN_DC_SIDE_PANEL_COMPONENT',
207
+ 'open-troubleshooter',
208
+ 'resolve-discrepancy-map-event',
209
+ 'restore-discrepancy-event',
210
+ 'setLabel',
211
+ 'SHOW_POP_UP_MESSAGE',
212
+ 'TEAMS_SELECTED',
213
+ 'tech-is-dispatch-pro-change',
214
+ 'technicians-emails-processed',
215
+ 'technicians-request-save',
216
+ 'technicians-saved-error',
217
+ 'technicians-saved',
218
+ 'timesheet-activity-saved',
219
+ 'TOGGLE_DC_SIDE_PANEL_COMPONENT',
220
+ 'updateUserEmail',
221
+ 'visibility',
222
+ ':widgets:message',
223
+ ]);