@vouchfor/embeds 0.0.0-experiment.a913709 → 0.0.0-experiment.a91d11e

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vouchfor/embeds",
3
- "version": "0.0.0-experiment.a913709",
3
+ "version": "0.0.0-experiment.a91d11e",
4
4
  "license": "MIT",
5
5
  "author": "Aaron Williams",
6
6
  "main": "dist/es/embeds.js",
@@ -26,7 +26,7 @@
26
26
  "lint:staged": "lint-staged",
27
27
  "prepublishOnly": "yarn build",
28
28
  "size": "size-limit",
29
- "storybook": "yarn prebuild && storybook dev -p 6006",
29
+ "storybook": "yarn prebuild && storybook dev -p 6007",
30
30
  "prebuild": "yarn build:deps && yarn generate:manifest",
31
31
  "test": "true"
32
32
  },
@@ -35,12 +35,12 @@
35
35
  "**/*.{md,json,yml}": "prettier --write"
36
36
  },
37
37
  "dependencies": {
38
- "@lit/task": "1.0.0",
39
- "@vouchfor/media-player": "0.0.0-experiment.a913709",
38
+ "@lit/task": "^1.0.0",
39
+ "@vouchfor/media-player": "0.0.0-experiment.a91d11e",
40
40
  "uuid": "^9.0.1"
41
41
  },
42
42
  "peerDependencies": {
43
- "lit": "^3.0.2"
43
+ "lit": "^3.1.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@esm-bundle/chai": "^4.3.4-fix.0",
@@ -62,7 +62,7 @@
62
62
  "eslint": "^8.50.0",
63
63
  "eslint-plugin-import": "^2.28.1",
64
64
  "lint-staged": "^14.0.1",
65
- "lit": "^2.8.0",
65
+ "lit": "^3.1.0",
66
66
  "prettier": "^3.0.3",
67
67
  "react": "^18.2.0",
68
68
  "react-dom": "^18.2.0",
@@ -10,30 +10,18 @@ type EmbedArgs = EmbedProps & {
10
10
  showVouch?: boolean;
11
11
  };
12
12
 
13
- const _Embed = ({
14
- vouchId,
15
- templateId,
16
- preload,
17
- autoplay,
18
- env,
19
- apiKey,
20
- controls,
21
-
22
- resolution,
23
- aspectRatio
24
- }: EmbedArgs) => {
13
+ const _Embed = ({ vouchId, templateId, preload, autoplay, env, apiKey, controls, aspectRatio }: EmbedArgs) => {
25
14
  return html`
26
15
  <div style="height: 100vh">
27
16
  <vouch-embed
28
17
  env=${ifDefined(env)}
29
18
  apiKey=${ifDefined(apiKey)}
30
- ?autoplay=${autoplay}
31
19
  vouchId=${ifDefined(vouchId)}
32
20
  templateId=${ifDefined(templateId)}
33
- resolution=${ifDefined(resolution)}
34
- aspectRatio=${ifDefined(aspectRatio)}
35
- preload=${ifDefined(preload)}
36
21
  .controls=${controls}
22
+ ?autoplay=${autoplay}
23
+ preload=${ifDefined(preload)}
24
+ aspectRatio=${ifDefined(aspectRatio)}
37
25
  ></vouch-embed>
38
26
  </div>
39
27
  `;
@@ -51,11 +39,10 @@ type Story = StoryObj<EmbedArgs>;
51
39
 
52
40
  const Embed: Story = {
53
41
  args: {
54
- env: 'dev',
42
+ env: 'local',
55
43
  apiKey: 'TVik9uTMgE-PD25UTHIS6gyl0hMBWC7AT4dkpdlLBT4VIfDWZJrQiCk6Ak7m1',
56
44
  vouchId: '6JQEIPeStt',
57
- templateId: '7d0113f7-3f9a-4bdd-97e3-07ee6eec5730',
58
- resolution: 1080,
45
+ templateId: '357fc118-e179-4171-9446-ff2b8e9d1b29',
59
46
  aspectRatio: 0,
60
47
  preload: 'none',
61
48
  autoplay: false
@@ -63,7 +50,7 @@ const Embed: Story = {
63
50
  argTypes: {
64
51
  env: {
65
52
  control: 'radio',
66
- options: ['prod', 'staging', 'dev']
53
+ options: ['local', 'dev', 'staging', 'prod']
67
54
  },
68
55
  preload: {
69
56
  control: 'radio',
@@ -1,7 +1,7 @@
1
1
  import { Task } from '@lit/task';
2
+ import { v4 as uuidv4 } from 'uuid';
2
3
 
3
4
  import type { Embed, EmbedProps } from '..';
4
- import type { TemplateInstance } from '@vouchfor/canvas-video';
5
5
  import type { ReactiveControllerHost } from 'lit';
6
6
  import type { Environment } from '~/utils/env';
7
7
 
@@ -21,8 +21,6 @@ class FetcherController {
21
21
  host: EmbedHost;
22
22
 
23
23
  private _fetching = false;
24
- private _vouch: EmbedProps['data'] | null = null;
25
- private _template: TemplateInstance | null = null;
26
24
 
27
25
  set fetching(value) {
28
26
  if (this._fetching !== value) {
@@ -34,51 +32,67 @@ class FetcherController {
34
32
  return this._fetching;
35
33
  }
36
34
 
37
- set vouch(value) {
38
- if (this._vouch !== value) {
39
- this._vouch = value;
40
- this.host.requestUpdate();
41
- }
42
- }
43
- get vouch() {
44
- return this._vouch;
45
- }
46
-
47
- set template(value) {
48
- if (this._template !== value) {
49
- this._template = value;
50
- this.host.requestUpdate();
51
- }
52
- }
53
- get template() {
54
- return this._template;
55
- }
56
-
57
- private async getVouch(env: Environment, apiKey: string, vouchId?: string) {
35
+ private getVouch = async (env: Environment, apiKey: string, vouchId: string) => {
58
36
  const { embedApiUrl } = getEnvUrls(env);
59
37
 
60
- if (vouchId) {
61
- return fetch(`${embedApiUrl}/vouches/${vouchId}`, {
38
+ const cacheCheck = uuidv4();
39
+ const res = await fetch(`${embedApiUrl}/vouches/${vouchId}`, {
40
+ method: 'GET',
41
+ headers: [
42
+ ['X-Api-Key', apiKey],
43
+ ['X-Cache-Check', cacheCheck]
44
+ ]
45
+ });
46
+
47
+ const vouch = await res.json();
48
+ this.host.dispatchEvent(new CustomEvent('vouch:loaded', { detail: vouchId }));
49
+
50
+ // HACK: we're currently using API Gateway caching on the embed API without any invalidation logic,
51
+ // so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
52
+ // API call with the `Cache-Control` header which will re-fill the cache
53
+ const resCacheCheck = res?.headers?.get('X-Cache-Check');
54
+ if (resCacheCheck && resCacheCheck !== cacheCheck) {
55
+ fetch(`${embedApiUrl}/vouches/${vouchId}`, {
62
56
  method: 'GET',
63
- headers: [['X-Api-Key', apiKey]]
64
- }).then((response) => response.json());
57
+ headers: [
58
+ ['X-Api-Key', apiKey],
59
+ ['Cache-Control', 'max-age=0']
60
+ ]
61
+ });
65
62
  }
66
63
 
67
- return null;
68
- }
64
+ return vouch;
65
+ };
69
66
 
70
- private async getTemplate(env: Environment, apiKey: string, templateId?: string) {
67
+ private getTemplate = async (env: Environment, apiKey: string, templateId: string) => {
71
68
  const { embedApiUrl } = getEnvUrls(env);
72
69
 
73
- if (templateId) {
74
- return fetch(`${embedApiUrl}/templates/${templateId}`, {
70
+ const cacheCheck = uuidv4();
71
+ const res = await fetch(`${embedApiUrl}/templates/${templateId}`, {
72
+ method: 'GET',
73
+ headers: [
74
+ ['X-Api-Key', apiKey],
75
+ ['X-Cache-Check', cacheCheck]
76
+ ]
77
+ });
78
+ const template = await res.json();
79
+
80
+ // HACK: we're currently using API Gateway caching on the embed API without any invalidation logic,
81
+ // so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
82
+ // API call with the `Cache-Control` header which will re-fill the cache
83
+ const resCacheCheck = res?.headers?.get('X-Cache-Check');
84
+ if (resCacheCheck && resCacheCheck !== cacheCheck) {
85
+ fetch(`${embedApiUrl}/templates/${templateId}`, {
75
86
  method: 'GET',
76
- headers: [['X-Api-Key', apiKey]]
77
- }).then((response) => response.json());
87
+ headers: [
88
+ ['X-Api-Key', apiKey],
89
+ ['Cache-Control', 'max-age=0']
90
+ ]
91
+ });
78
92
  }
79
93
 
80
- return null;
81
- }
94
+ return template;
95
+ };
82
96
 
83
97
  constructor(host: EmbedHost) {
84
98
  this.host = host;
@@ -86,22 +100,26 @@ class FetcherController {
86
100
  this.host,
87
101
  async ([env, apiKey, data, vouchId, templateId]: TaskDeps) => {
88
102
  try {
89
- this.vouch = null;
90
- this.template = null;
103
+ host.vouch = undefined;
104
+ host.template = undefined;
91
105
 
92
106
  if (data) {
93
- const template = await this.getTemplate(env, apiKey, templateId);
94
- this.vouch = data;
95
- this.template = data?.settings?.template?.instance ?? template;
107
+ let template;
108
+ if (templateId) {
109
+ this.fetching = true;
110
+ template = await this.getTemplate(env, apiKey, templateId);
111
+ }
112
+ host.vouch = data;
113
+ host.template = template ?? data?.settings?.template?.instance;
96
114
  } else if (vouchId) {
97
115
  this.fetching = true;
98
116
 
99
117
  const [vouch, template] = await Promise.all([
100
118
  this.getVouch(env, apiKey, vouchId),
101
- this.getTemplate(env, apiKey, templateId)
119
+ templateId ? this.getTemplate(env, apiKey, templateId) : null
102
120
  ]);
103
- this.vouch = vouch;
104
- this.template = vouch?.settings?.template?.instance ?? template;
121
+ host.vouch = vouch;
122
+ host.template = template ?? vouch?.settings?.template?.instance;
105
123
  }
106
124
  } finally {
107
125
  this.fetching = false;
@@ -6,13 +6,13 @@ import type { ReactiveController, ReactiveControllerHost } from 'lit';
6
6
 
7
7
  import { getEnvUrls } from '~/utils/env';
8
8
 
9
- const STREAMED_THROTTLE = 2000;
9
+ // In seconds due to checking against node.currentTime
10
+ const STREAMED_THROTTLE = 10;
10
11
 
11
12
  type EmbedHost = ReactiveControllerHost & Embed;
12
13
 
13
14
  type TrackingEvent = 'VOUCH_LOADED' | 'VOUCH_RESPONSE_VIEWED' | 'VIDEO_PLAYED' | 'VIDEO_STREAMED';
14
15
  type TrackingPayload = {
15
- vouchId: string;
16
16
  answerId?: string;
17
17
  streamStart?: number;
18
18
  streamEnd?: number;
@@ -36,8 +36,9 @@ class TrackingController implements ReactiveController {
36
36
  private _hasPlayed = false;
37
37
  private _hasLoaded: BooleanMap = {};
38
38
  private _answersViewed: BooleanMap = {};
39
- private _streamedTime: TimeMap = {};
40
- private _streamedPrevTimestamp: TimeMap = {};
39
+ private _streamStartTime: TimeMap = {};
40
+ private _streamLatestTime: TimeMap = {};
41
+ private _currentlyPlayingVideo: VideoEventDetail | null = null;
41
42
 
42
43
  constructor(host: EmbedHost) {
43
44
  this.host = host;
@@ -45,11 +46,11 @@ class TrackingController implements ReactiveController {
45
46
  }
46
47
 
47
48
  private _findVouchId() {
48
- if (this.host.data) {
49
- if ('uuid' in this.host.data) {
50
- return this.host.data.uuid;
49
+ if (this.host.vouch) {
50
+ if ('uuid' in this.host.vouch) {
51
+ return this.host.vouch.uuid;
51
52
  }
52
- return this.host.data.id;
53
+ return this.host.vouch.id;
53
54
  }
54
55
  }
55
56
 
@@ -116,7 +117,7 @@ class TrackingController implements ReactiveController {
116
117
  });
117
118
 
118
119
  return {
119
- source: 'media_player',
120
+ source: this.host.trackingSource,
120
121
  time: new Date(),
121
122
  region,
122
123
  country,
@@ -128,11 +129,16 @@ class TrackingController implements ReactiveController {
128
129
  };
129
130
  };
130
131
 
131
- private _sendTrackingEvent = (event: TrackingEvent, payload: TrackingPayload) => {
132
+ private _sendTrackingEvent = (event: TrackingEvent, payload?: TrackingPayload) => {
133
+ const vouchId = this._findVouchId();
134
+
135
+ if (!vouchId || this.host.disableTracking) {
136
+ return;
137
+ }
138
+
132
139
  const { publicApiUrl } = getEnvUrls(this.host.env);
133
140
  const { client, tab, request, visitor } = this._getUids();
134
141
 
135
- // Don't send tracking if we don't have a source
136
142
  navigator.sendBeacon(
137
143
  `${publicApiUrl}/api/events`,
138
144
  JSON.stringify({
@@ -156,87 +162,74 @@ class TrackingController implements ReactiveController {
156
162
 
157
163
  // Only send loaded event once per session
158
164
  if (!this._hasLoaded[vouchId]) {
159
- this._sendTrackingEvent('VOUCH_LOADED', {
160
- vouchId
161
- });
165
+ this._sendTrackingEvent('VOUCH_LOADED');
162
166
  this._hasLoaded[vouchId] = true;
163
167
  }
164
168
  };
165
169
 
166
170
  private _handlePlay = () => {
167
- const vouchId = this._findVouchId();
168
-
169
- if (!vouchId) {
170
- return;
171
- }
172
-
173
171
  // Only send the video played event once per session
174
172
  if (!this._hasPlayed) {
175
173
  this._sendTrackingEvent('VIDEO_PLAYED', {
176
- vouchId,
177
174
  streamStart: this.host.currentTime
178
175
  });
179
176
  this._hasPlayed = true;
180
177
  }
181
178
  };
182
179
 
183
- private _handleVideoPlay = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
184
- const vouchId = this._findVouchId();
185
- if (!vouchId) {
186
- return;
187
- }
180
+ private _handleVideoPlay = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
188
181
  // Only increment play count once per session
189
- if (!this._answersViewed[id]) {
182
+ if (!this._answersViewed[key]) {
190
183
  this._sendTrackingEvent('VOUCH_RESPONSE_VIEWED', {
191
- vouchId,
192
184
  answerId: id
193
185
  });
194
- this._answersViewed[id] = true;
186
+ this._answersViewed[key] = true;
195
187
  }
196
- this._streamedTime[id] = node.currentTime;
197
- this._streamedPrevTimestamp[id] = Date.now();
188
+
189
+ this._streamStartTime[key] = node.currentTime;
190
+ this._streamLatestTime[key] = node.currentTime;
198
191
  };
199
192
 
200
- private _handleVideoTimeUpdate = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
201
- const vouchId = this._findVouchId();
202
- if (!vouchId) {
203
- return;
193
+ private _handleVideoTimeUpdate = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
194
+ // We only want to count any time that the video is actually playing
195
+ if (!this.host.paused) {
196
+ this._currentlyPlayingVideo = { id, key, node };
197
+ this._streamLatestTime[key] = node.currentTime;
204
198
  }
205
- const currentTimestamp = Date.now();
199
+
206
200
  if (
201
+ !node.paused &&
207
202
  !this.host.paused &&
208
203
  // Only fire the video seeked event when this video is the active one
209
204
  id === this.host.scene?.video?.id &&
210
205
  // Throttle the frequency that we send streamed events while playing
211
- currentTimestamp - this._streamedPrevTimestamp[id] > STREAMED_THROTTLE
206
+ this._streamLatestTime[key] - this._streamStartTime[key] > STREAMED_THROTTLE
212
207
  ) {
213
208
  this._sendTrackingEvent('VIDEO_STREAMED', {
214
- vouchId,
215
209
  answerId: id,
216
- streamStart: this._streamedTime[id],
217
- streamEnd: node.currentTime
210
+ streamStart: this._streamStartTime[key],
211
+ streamEnd: this._streamLatestTime[key]
218
212
  });
219
- this._streamedTime[id] = node.currentTime;
220
- this._streamedPrevTimestamp[id] = currentTimestamp;
213
+
214
+ this._streamStartTime[key] = node.currentTime;
221
215
  }
222
216
  };
223
217
 
224
- private _handleVideoPause = ({ detail: { id, node } }: CustomEvent<VideoEventDetail>) => {
225
- const vouchId = this._findVouchId();
226
- if (!vouchId) {
227
- return;
218
+ private _handleVideoPause = ({ detail: { id, key } }: CustomEvent<VideoEventDetail>) => {
219
+ // Don't send a tracking event when seeking backwards
220
+ if (this._streamLatestTime[key] > this._streamStartTime[key]) {
221
+ // Send a video streamed event any time the video pauses then reset the streamed state
222
+ // We do this to capture the last bit of time that the video was played between the previous
223
+ // stream event and the video being paused manually or stopping because it ended
224
+ this._sendTrackingEvent('VIDEO_STREAMED', {
225
+ answerId: id,
226
+ streamStart: this._streamStartTime[key],
227
+ streamEnd: this._streamLatestTime[key]
228
+ });
228
229
  }
229
- // Send a video streamed event any time the video pauses then reset the streamed state
230
- // We do this to capture the last bit of time that the video was played between the previous
231
- // stream event and the video being paused manually or stopping because it ended
232
- this._sendTrackingEvent('VIDEO_STREAMED', {
233
- vouchId,
234
- answerId: id,
235
- streamStart: this._streamedTime[id],
236
- streamEnd: node.currentTime
237
- });
238
- delete this._streamedTime[id];
239
- delete this._streamedPrevTimestamp[id];
230
+ this._currentlyPlayingVideo = null;
231
+ delete this._streamStartTime[key];
232
+ delete this._streamLatestTime[key];
240
233
  };
241
234
 
242
235
  hostConnected() {
@@ -250,6 +243,20 @@ class TrackingController implements ReactiveController {
250
243
  }
251
244
 
252
245
  hostDisconnected() {
246
+ if (this._currentlyPlayingVideo) {
247
+ const { id, key } = this._currentlyPlayingVideo;
248
+ if (this._streamLatestTime[key] > this._streamStartTime[key]) {
249
+ // Send a video streamed event any time the video pauses then reset the streamed state
250
+ // We do this to capture the last bit of time that the video was played between the previous
251
+ // stream event and the video being paused manually or stopping because it ended
252
+ this._sendTrackingEvent('VIDEO_STREAMED', {
253
+ answerId: id,
254
+ streamStart: this._streamStartTime[key],
255
+ streamEnd: this._streamLatestTime[key]
256
+ });
257
+ }
258
+ }
259
+
253
260
  this.host.removeEventListener('vouch:loaded', this._handleVouchLoaded);
254
261
  this.host.mediaPlayer?.removeEventListener('play', this._handlePlay);
255
262
  this.host.mediaPlayer?.removeEventListener('video:play', this._handleVideoPlay);
@@ -1,5 +1,5 @@
1
1
  import { html, LitElement } from 'lit';
2
- import { customElement, property } from 'lit/decorators.js';
2
+ import { customElement, property, state } from 'lit/decorators.js';
3
3
  import { ifDefined } from 'lit/directives/if-defined.js';
4
4
  import { createRef, ref } from 'lit/directives/ref.js';
5
5
 
@@ -14,12 +14,11 @@ import { TrackingController } from './controllers/tracking';
14
14
 
15
15
  import '@vouchfor/media-player';
16
16
 
17
- type EmbedProps = Pick<
18
- MediaPlayerProps,
19
- 'data' | 'resolution' | 'aspectRatio' | 'preload' | 'autoplay' | 'controls'
20
- > & {
17
+ type EmbedProps = Pick<MediaPlayerProps, 'data' | 'aspectRatio' | 'preload' | 'autoplay' | 'controls'> & {
21
18
  env: Environment;
22
19
  apiKey: string;
20
+ disableTracking?: boolean;
21
+ trackingSource?: string;
23
22
  vouchId?: string;
24
23
  templateId?: string;
25
24
  };
@@ -34,13 +33,13 @@ class Embed extends LitElement {
34
33
 
35
34
  @property({ type: String }) env: EmbedProps['env'] = 'prod';
36
35
  @property({ type: String }) apiKey: EmbedProps['apiKey'] = '';
36
+ @property({ type: Boolean }) disableTracking: EmbedProps['disableTracking'] = false;
37
+ @property({ type: String }) trackingSource: EmbedProps['trackingSource'] = 'embed';
37
38
 
39
+ @property({ type: Array }) controls: EmbedProps['controls'];
38
40
  @property({ type: String }) preload: EmbedProps['preload'] = 'auto';
39
41
  @property({ type: Boolean }) autoplay: EmbedProps['autoplay'] = false;
40
-
41
- @property({ type: Number }) resolution: EmbedProps['resolution'] = 1080;
42
42
  @property({ type: Number }) aspectRatio: EmbedProps['aspectRatio'] = 0;
43
- @property({ type: Array }) controls: EmbedProps['controls'];
44
43
 
45
44
  private eventController = new EventForwardController(this, [
46
45
  'durationchange',
@@ -60,6 +59,7 @@ class Embed extends LitElement {
60
59
  'waiting',
61
60
 
62
61
  'video:loadeddata',
62
+ 'video:seeking',
63
63
  'video:seeked',
64
64
  'video:play',
65
65
  'video:playing',
@@ -74,13 +74,8 @@ class Embed extends LitElement {
74
74
  // @ts-ignore
75
75
  private _trackingController = new TrackingController(this);
76
76
 
77
- get vouch() {
78
- return this._fetcherController.vouch;
79
- }
80
-
81
- get template(): TemplateInstance | null {
82
- return this._fetcherController.template;
83
- }
77
+ @state() vouch: EmbedProps['data'];
78
+ @state() template: TemplateInstance | undefined;
84
79
 
85
80
  get fetching() {
86
81
  return this._fetcherController.fetching;
@@ -176,18 +171,17 @@ class Embed extends LitElement {
176
171
 
177
172
  render() {
178
173
  return html`
179
- <vmp-media-player
174
+ <vmp-new-media-player
180
175
  ${ref(this._mediaPlayerRef)}
181
176
  ${this.eventController.register()}
182
177
  ?autoplay=${this.autoplay}
183
178
  ?loading=${this.fetching}
184
179
  .data=${this.vouch}
185
180
  .template=${this.template}
186
- resolution=${ifDefined(this.resolution)}
187
181
  aspectRatio=${ifDefined(this.aspectRatio)}
188
182
  preload=${ifDefined(this.preload)}
189
183
  .controls=${this.controls}
190
- ></vmp-media-player>
184
+ ></vmp-new-media-player>
191
185
  `;
192
186
  }
193
187
  }
package/src/utils/env.ts CHANGED
@@ -1,15 +1,11 @@
1
- type Environment = 'dev' | 'staging' | 'prod';
1
+ type Environment = 'local' | 'dev' | 'staging' | 'prod';
2
2
 
3
3
  type GetEnvUrlsReturn = {
4
- marketingUrl: string;
5
4
  videoUrl: string;
6
5
  publicApiUrl: string;
7
6
  embedApiUrl: string;
8
- publicRecorderUrl: string;
9
7
  };
10
8
 
11
- const marketingUrl = 'https://vouchfor.com';
12
-
13
9
  const devVideoUrl = 'https://d2rxhdlm2q91uk.cloudfront.net';
14
10
  const stagingVideoUrl = 'https://d1ix11aj5kfygl.cloudfront.net';
15
11
  const prodVideoUrl = 'https://d157jlwnudd93d.cloudfront.net';
@@ -18,61 +14,51 @@ const devPublicApiUrl = 'https://bshyfw4h5a.execute-api.ap-southeast-2.amazonaws
18
14
  const stagingPublicApiUrl = 'https://gyzw7rpbq3.execute-api.ap-southeast-2.amazonaws.com/staging';
19
15
  const prodPublicApiUrl = 'https://vfcjuim1l3.execute-api.ap-southeast-2.amazonaws.com/prod';
20
16
 
21
- const devEmbedApiUrl = 'http://localhost:6060/v1';
22
- const stagingEmbedApiUrl = 'https://embed-staging.vouchfor.com/v1';
23
- const prodEmbedApiUrl = 'https://embed.vouchfor.com/v1';
24
-
25
- const devPublicRecorderUrl = 'https://dev.vouchfor.com';
26
- const stagingPublicRecorderUrl = 'https://staging.vouchfor.com';
27
- const prodPublicRecorderUrl = 'https://app.vouchfor.com';
17
+ const localEmbedApiUrl = 'http://localhost:6060/v2';
18
+ const devEmbedApiUrl = 'https://embed-dev.vouchfor.com/v2';
19
+ const stagingEmbedApiUrl = 'https://embed-staging.vouchfor.com/v2';
20
+ const prodEmbedApiUrl = 'https://embed.vouchfor.com/v2';
28
21
 
29
22
  // We are handling the case where env is an unknown string so the ts error is a lie
30
23
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
31
24
  // @ts-ignore
32
25
  function getEnvUrls(env: Environment): GetEnvUrlsReturn {
33
- if (!['dev', 'staging', 'prod'].includes(env)) {
26
+ if (!['local', 'dev', 'staging', 'prod'].includes(env)) {
34
27
  throw new Error(`Unknown environment: ${env}`);
35
28
  }
36
29
 
30
+ if (env === 'local') {
31
+ return {
32
+ videoUrl: devVideoUrl,
33
+ publicApiUrl: devPublicApiUrl,
34
+ embedApiUrl: localEmbedApiUrl
35
+ };
36
+ }
37
+
37
38
  if (env === 'dev') {
38
39
  return {
39
- marketingUrl,
40
40
  videoUrl: devVideoUrl,
41
41
  publicApiUrl: devPublicApiUrl,
42
- embedApiUrl: devEmbedApiUrl,
43
- publicRecorderUrl: devPublicRecorderUrl
42
+ embedApiUrl: devEmbedApiUrl
44
43
  };
45
44
  }
46
45
 
47
46
  if (env === 'staging') {
48
47
  return {
49
- marketingUrl,
50
48
  videoUrl: stagingVideoUrl,
51
49
  publicApiUrl: stagingPublicApiUrl,
52
- embedApiUrl: stagingEmbedApiUrl,
53
- publicRecorderUrl: stagingPublicRecorderUrl
50
+ embedApiUrl: stagingEmbedApiUrl
54
51
  };
55
52
  }
56
53
 
57
54
  if (env === 'prod') {
58
55
  return {
59
- marketingUrl,
60
56
  videoUrl: prodVideoUrl,
61
57
  publicApiUrl: prodPublicApiUrl,
62
- embedApiUrl: prodEmbedApiUrl,
63
- publicRecorderUrl: prodPublicRecorderUrl
58
+ embedApiUrl: prodEmbedApiUrl
64
59
  };
65
60
  }
66
61
  }
67
62
 
68
- export {
69
- marketingUrl,
70
- devEmbedApiUrl,
71
- stagingEmbedApiUrl,
72
- prodEmbedApiUrl,
73
- devPublicRecorderUrl,
74
- stagingPublicRecorderUrl,
75
- prodPublicRecorderUrl,
76
- getEnvUrls
77
- };
63
+ export { devEmbedApiUrl, stagingEmbedApiUrl, prodEmbedApiUrl, getEnvUrls };
78
64
  export type { Environment };
@@ -1,14 +0,0 @@
1
- import type { Embed } from '..';
2
- import type { ReactiveController, ReactiveControllerHost } from 'lit';
3
- type EmbedHost = ReactiveControllerHost & Embed;
4
- declare class EventForwardController implements ReactiveController {
5
- host: EmbedHost;
6
- private _events;
7
- private _cleanup;
8
- private _forwardElementRef;
9
- constructor(host: EmbedHost, events: string[]);
10
- register(): import("lit-html/directive.js").DirectiveResult<typeof import("lit-html/directives/ref.js").RefDirective>;
11
- hostConnected(): void;
12
- hostDisconnected(): void;
13
- }
14
- export { EventForwardController };