@ave-id/embed 0.2.0 → 0.2.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.
- package/dist/embed.js +519 -0
- package/package.json +10 -2
package/dist/embed.js
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
const DEFAULT_THEME = "dark";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Mount Ave auth embed as an inline iframe
|
|
5
|
+
*/
|
|
6
|
+
export function mountAveEmbed({
|
|
7
|
+
container,
|
|
8
|
+
clientId,
|
|
9
|
+
redirectUri,
|
|
10
|
+
scope = "openid profile email",
|
|
11
|
+
issuer = "https://aveid.net",
|
|
12
|
+
theme = DEFAULT_THEME,
|
|
13
|
+
width = "100%",
|
|
14
|
+
height = 720,
|
|
15
|
+
onSuccess,
|
|
16
|
+
onError,
|
|
17
|
+
onClose,
|
|
18
|
+
}) {
|
|
19
|
+
if (!container) {
|
|
20
|
+
throw new Error("container is required");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const iframe = document.createElement("iframe");
|
|
24
|
+
const params = new URLSearchParams({
|
|
25
|
+
client_id: clientId,
|
|
26
|
+
redirect_uri: redirectUri,
|
|
27
|
+
scope,
|
|
28
|
+
embed: "1",
|
|
29
|
+
theme,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
iframe.src = `${issuer}/signin?${params.toString()}`;
|
|
33
|
+
iframe.style.width = width;
|
|
34
|
+
iframe.style.height = typeof height === "number" ? `${height}px` : height;
|
|
35
|
+
iframe.style.border = "0";
|
|
36
|
+
iframe.style.borderRadius = "24px";
|
|
37
|
+
iframe.style.background = "#090909";
|
|
38
|
+
iframe.allow = "publickey-credentials-get";
|
|
39
|
+
|
|
40
|
+
container.appendChild(iframe);
|
|
41
|
+
|
|
42
|
+
const messageHandler = (event) => {
|
|
43
|
+
if (event.origin !== issuer) return;
|
|
44
|
+
const data = event.data || {};
|
|
45
|
+
|
|
46
|
+
if (data.type === "ave:success") {
|
|
47
|
+
onSuccess?.(data.payload);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (data.type === "ave:error") {
|
|
51
|
+
onError?.(data.payload);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (data.type === "ave:close") {
|
|
55
|
+
onClose?.();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
window.addEventListener("message", messageHandler);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
iframe,
|
|
63
|
+
destroy() {
|
|
64
|
+
window.removeEventListener("message", messageHandler);
|
|
65
|
+
iframe.remove();
|
|
66
|
+
},
|
|
67
|
+
postMessage(payload) {
|
|
68
|
+
iframe.contentWindow?.postMessage(payload, issuer);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Open Ave auth as a modal sheet overlay
|
|
75
|
+
*/
|
|
76
|
+
export function openAveSheet({
|
|
77
|
+
clientId,
|
|
78
|
+
redirectUri,
|
|
79
|
+
scope = "openid profile email",
|
|
80
|
+
issuer = "https://aveid.net",
|
|
81
|
+
theme = DEFAULT_THEME,
|
|
82
|
+
onSuccess,
|
|
83
|
+
onError,
|
|
84
|
+
onClose,
|
|
85
|
+
}) {
|
|
86
|
+
// Create overlay backdrop
|
|
87
|
+
const overlay = document.createElement("div");
|
|
88
|
+
overlay.style.cssText = `
|
|
89
|
+
position: fixed;
|
|
90
|
+
inset: 0;
|
|
91
|
+
background: rgba(0, 0, 0, 0.7);
|
|
92
|
+
backdrop-filter: blur(4px);
|
|
93
|
+
z-index: 999999;
|
|
94
|
+
display: flex;
|
|
95
|
+
align-items: flex-end;
|
|
96
|
+
justify-content: center;
|
|
97
|
+
animation: aveSheetFadeIn 0.2s ease-out;
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
// Create sheet container
|
|
101
|
+
const sheet = document.createElement("div");
|
|
102
|
+
sheet.style.cssText = `
|
|
103
|
+
width: 100%;
|
|
104
|
+
max-width: 500px;
|
|
105
|
+
max-height: 90vh;
|
|
106
|
+
background: #090909;
|
|
107
|
+
border-radius: 24px 24px 0 0;
|
|
108
|
+
overflow: hidden;
|
|
109
|
+
animation: aveSheetSlideUp 0.3s ease-out;
|
|
110
|
+
position: relative;
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
// Add drag handle
|
|
114
|
+
const dragHandle = document.createElement("div");
|
|
115
|
+
dragHandle.style.cssText = `
|
|
116
|
+
width: 40px;
|
|
117
|
+
height: 4px;
|
|
118
|
+
background: #333;
|
|
119
|
+
border-radius: 2px;
|
|
120
|
+
margin: 12px auto;
|
|
121
|
+
`;
|
|
122
|
+
sheet.appendChild(dragHandle);
|
|
123
|
+
|
|
124
|
+
// Create close button
|
|
125
|
+
const closeBtn = document.createElement("button");
|
|
126
|
+
closeBtn.innerHTML = `
|
|
127
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#888" stroke-width="2">
|
|
128
|
+
<path d="M18 6L6 18M6 6l12 12"/>
|
|
129
|
+
</svg>
|
|
130
|
+
`;
|
|
131
|
+
closeBtn.style.cssText = `
|
|
132
|
+
position: absolute;
|
|
133
|
+
top: 8px;
|
|
134
|
+
right: 12px;
|
|
135
|
+
background: transparent;
|
|
136
|
+
border: none;
|
|
137
|
+
cursor: pointer;
|
|
138
|
+
padding: 8px;
|
|
139
|
+
z-index: 10;
|
|
140
|
+
`;
|
|
141
|
+
|
|
142
|
+
// Create iframe
|
|
143
|
+
const iframe = document.createElement("iframe");
|
|
144
|
+
const params = new URLSearchParams({
|
|
145
|
+
client_id: clientId,
|
|
146
|
+
redirect_uri: redirectUri,
|
|
147
|
+
scope,
|
|
148
|
+
embed: "1",
|
|
149
|
+
theme,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
iframe.src = `${issuer}/signin?${params.toString()}`;
|
|
153
|
+
iframe.style.cssText = `
|
|
154
|
+
width: 100%;
|
|
155
|
+
height: calc(90vh - 50px);
|
|
156
|
+
border: none;
|
|
157
|
+
background: #090909;
|
|
158
|
+
`;
|
|
159
|
+
iframe.allow = "publickey-credentials-get";
|
|
160
|
+
|
|
161
|
+
sheet.appendChild(closeBtn);
|
|
162
|
+
sheet.appendChild(iframe);
|
|
163
|
+
overlay.appendChild(sheet);
|
|
164
|
+
|
|
165
|
+
// Add animations
|
|
166
|
+
const style = document.createElement("style");
|
|
167
|
+
style.textContent = `
|
|
168
|
+
@keyframes aveSheetFadeIn {
|
|
169
|
+
from { opacity: 0; }
|
|
170
|
+
to { opacity: 1; }
|
|
171
|
+
}
|
|
172
|
+
@keyframes aveSheetSlideUp {
|
|
173
|
+
from { transform: translateY(100%); }
|
|
174
|
+
to { transform: translateY(0); }
|
|
175
|
+
}
|
|
176
|
+
@keyframes aveSheetSlideDown {
|
|
177
|
+
from { transform: translateY(0); }
|
|
178
|
+
to { transform: translateY(100%); }
|
|
179
|
+
}
|
|
180
|
+
@keyframes aveSheetFadeOut {
|
|
181
|
+
from { opacity: 1; }
|
|
182
|
+
to { opacity: 0; }
|
|
183
|
+
}
|
|
184
|
+
`;
|
|
185
|
+
document.head.appendChild(style);
|
|
186
|
+
|
|
187
|
+
// Close function
|
|
188
|
+
const close = () => {
|
|
189
|
+
sheet.style.animation = "aveSheetSlideDown 0.2s ease-in forwards";
|
|
190
|
+
overlay.style.animation = "aveSheetFadeOut 0.2s ease-in forwards";
|
|
191
|
+
setTimeout(() => {
|
|
192
|
+
overlay.remove();
|
|
193
|
+
style.remove();
|
|
194
|
+
window.removeEventListener("message", messageHandler);
|
|
195
|
+
onClose?.();
|
|
196
|
+
}, 200);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// Event handlers
|
|
200
|
+
closeBtn.onclick = close;
|
|
201
|
+
overlay.onclick = (e) => {
|
|
202
|
+
if (e.target === overlay) close();
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const messageHandler = (event) => {
|
|
206
|
+
if (event.origin !== issuer) return;
|
|
207
|
+
const data = event.data || {};
|
|
208
|
+
|
|
209
|
+
if (data.type === "ave:success") {
|
|
210
|
+
close();
|
|
211
|
+
onSuccess?.(data.payload);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (data.type === "ave:error") {
|
|
215
|
+
close();
|
|
216
|
+
onError?.(data.payload);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (data.type === "ave:close") {
|
|
220
|
+
close();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
window.addEventListener("message", messageHandler);
|
|
225
|
+
|
|
226
|
+
// Add to DOM
|
|
227
|
+
document.body.appendChild(overlay);
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
close,
|
|
231
|
+
iframe,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Open Ave auth as a popup window (for desktop)
|
|
237
|
+
*/
|
|
238
|
+
export function openAvePopup({
|
|
239
|
+
clientId,
|
|
240
|
+
redirectUri,
|
|
241
|
+
scope = "openid profile email",
|
|
242
|
+
issuer = "https://aveid.net",
|
|
243
|
+
width = 450,
|
|
244
|
+
height = 650,
|
|
245
|
+
onSuccess,
|
|
246
|
+
onError,
|
|
247
|
+
onClose,
|
|
248
|
+
}) {
|
|
249
|
+
const params = new URLSearchParams({
|
|
250
|
+
client_id: clientId,
|
|
251
|
+
redirect_uri: redirectUri,
|
|
252
|
+
scope,
|
|
253
|
+
embed: "1",
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const left = (window.innerWidth - width) / 2 + window.screenX;
|
|
257
|
+
const top = (window.innerHeight - height) / 2 + window.screenY;
|
|
258
|
+
|
|
259
|
+
const popup = window.open(
|
|
260
|
+
`${issuer}/signin?${params.toString()}`,
|
|
261
|
+
"ave_auth",
|
|
262
|
+
`width=${width},height=${height},left=${left},top=${top},menubar=no,toolbar=no,location=no,status=no`
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
if (!popup) {
|
|
266
|
+
onError?.({ error: "popup_blocked", message: "Popup was blocked by the browser" });
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const messageHandler = (event) => {
|
|
271
|
+
if (event.origin !== issuer) return;
|
|
272
|
+
const data = event.data || {};
|
|
273
|
+
|
|
274
|
+
if (data.type === "ave:success") {
|
|
275
|
+
popup.close();
|
|
276
|
+
window.removeEventListener("message", messageHandler);
|
|
277
|
+
onSuccess?.(data.payload);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (data.type === "ave:error") {
|
|
281
|
+
popup.close();
|
|
282
|
+
window.removeEventListener("message", messageHandler);
|
|
283
|
+
onError?.(data.payload);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (data.type === "ave:close") {
|
|
287
|
+
popup.close();
|
|
288
|
+
window.removeEventListener("message", messageHandler);
|
|
289
|
+
onClose?.();
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
window.addEventListener("message", messageHandler);
|
|
294
|
+
|
|
295
|
+
// Check if popup was closed
|
|
296
|
+
const pollTimer = setInterval(() => {
|
|
297
|
+
if (popup.closed) {
|
|
298
|
+
clearInterval(pollTimer);
|
|
299
|
+
window.removeEventListener("message", messageHandler);
|
|
300
|
+
onClose?.();
|
|
301
|
+
}
|
|
302
|
+
}, 500);
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
popup,
|
|
306
|
+
close() {
|
|
307
|
+
clearInterval(pollTimer);
|
|
308
|
+
popup.close();
|
|
309
|
+
window.removeEventListener("message", messageHandler);
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ============================================
|
|
315
|
+
// Ave Signing Embeds
|
|
316
|
+
// ============================================
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Open Ave signing as a modal sheet overlay
|
|
320
|
+
*/
|
|
321
|
+
export function openAveSigningSheet({
|
|
322
|
+
requestId,
|
|
323
|
+
issuer = "https://aveid.net",
|
|
324
|
+
onSigned,
|
|
325
|
+
onDenied,
|
|
326
|
+
onClose,
|
|
327
|
+
}) {
|
|
328
|
+
// Create overlay backdrop
|
|
329
|
+
const overlay = document.createElement("div");
|
|
330
|
+
overlay.style.cssText = `
|
|
331
|
+
position: fixed;
|
|
332
|
+
inset: 0;
|
|
333
|
+
background: rgba(0, 0, 0, 0.8);
|
|
334
|
+
backdrop-filter: blur(4px);
|
|
335
|
+
z-index: 999999;
|
|
336
|
+
display: flex;
|
|
337
|
+
align-items: flex-end;
|
|
338
|
+
justify-content: center;
|
|
339
|
+
animation: aveSheetFadeIn 0.2s ease-out;
|
|
340
|
+
`;
|
|
341
|
+
|
|
342
|
+
// Create sheet container
|
|
343
|
+
const sheet = document.createElement("div");
|
|
344
|
+
sheet.style.cssText = `
|
|
345
|
+
width: 100%;
|
|
346
|
+
max-width: 600px;
|
|
347
|
+
max-height: 90vh;
|
|
348
|
+
background: #111111;
|
|
349
|
+
border-radius: 32px 32px 0 0;
|
|
350
|
+
overflow: hidden;
|
|
351
|
+
animation: aveSheetSlideUp 0.3s ease-out;
|
|
352
|
+
position: relative;
|
|
353
|
+
`;
|
|
354
|
+
|
|
355
|
+
// Add drag handle
|
|
356
|
+
const dragHandle = document.createElement("div");
|
|
357
|
+
dragHandle.style.cssText = `
|
|
358
|
+
width: 40px;
|
|
359
|
+
height: 4px;
|
|
360
|
+
background: #333;
|
|
361
|
+
border-radius: 2px;
|
|
362
|
+
margin: 12px auto;
|
|
363
|
+
`;
|
|
364
|
+
sheet.appendChild(dragHandle);
|
|
365
|
+
|
|
366
|
+
// Create iframe
|
|
367
|
+
const iframe = document.createElement("iframe");
|
|
368
|
+
const params = new URLSearchParams({
|
|
369
|
+
requestId,
|
|
370
|
+
embed: "1",
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
iframe.src = `${issuer}/sign?${params.toString()}`;
|
|
374
|
+
iframe.style.cssText = `
|
|
375
|
+
width: 100%;
|
|
376
|
+
height: calc(90vh - 30px);
|
|
377
|
+
border: none;
|
|
378
|
+
background: transparent;
|
|
379
|
+
`;
|
|
380
|
+
iframe.allow = "publickey-credentials-get";
|
|
381
|
+
|
|
382
|
+
sheet.appendChild(iframe);
|
|
383
|
+
overlay.appendChild(sheet);
|
|
384
|
+
|
|
385
|
+
// Add animations (reuse if already present)
|
|
386
|
+
if (!document.getElementById("ave-sheet-styles")) {
|
|
387
|
+
const style = document.createElement("style");
|
|
388
|
+
style.id = "ave-sheet-styles";
|
|
389
|
+
style.textContent = `
|
|
390
|
+
@keyframes aveSheetFadeIn {
|
|
391
|
+
from { opacity: 0; }
|
|
392
|
+
to { opacity: 1; }
|
|
393
|
+
}
|
|
394
|
+
@keyframes aveSheetSlideUp {
|
|
395
|
+
from { transform: translateY(100%); }
|
|
396
|
+
to { transform: translateY(0); }
|
|
397
|
+
}
|
|
398
|
+
@keyframes aveSheetSlideDown {
|
|
399
|
+
from { transform: translateY(0); }
|
|
400
|
+
to { transform: translateY(100%); }
|
|
401
|
+
}
|
|
402
|
+
@keyframes aveSheetFadeOut {
|
|
403
|
+
from { opacity: 1; }
|
|
404
|
+
to { opacity: 0; }
|
|
405
|
+
}
|
|
406
|
+
`;
|
|
407
|
+
document.head.appendChild(style);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Close function
|
|
411
|
+
const close = () => {
|
|
412
|
+
sheet.style.animation = "aveSheetSlideDown 0.2s ease-in forwards";
|
|
413
|
+
overlay.style.animation = "aveSheetFadeOut 0.2s ease-in forwards";
|
|
414
|
+
setTimeout(() => {
|
|
415
|
+
overlay.remove();
|
|
416
|
+
window.removeEventListener("message", messageHandler);
|
|
417
|
+
onClose?.();
|
|
418
|
+
}, 200);
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// Click outside to close
|
|
422
|
+
overlay.onclick = (e) => {
|
|
423
|
+
if (e.target === overlay) close();
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
const messageHandler = (event) => {
|
|
427
|
+
if (event.origin !== issuer) return;
|
|
428
|
+
const data = event.data || {};
|
|
429
|
+
|
|
430
|
+
if (data.type === "ave:signed") {
|
|
431
|
+
close();
|
|
432
|
+
onSigned?.(data.payload);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (data.type === "ave:denied") {
|
|
436
|
+
close();
|
|
437
|
+
onDenied?.(data.payload);
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
window.addEventListener("message", messageHandler);
|
|
442
|
+
|
|
443
|
+
// Add to DOM
|
|
444
|
+
document.body.appendChild(overlay);
|
|
445
|
+
|
|
446
|
+
return {
|
|
447
|
+
close,
|
|
448
|
+
iframe,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Open Ave signing as a popup window
|
|
454
|
+
*/
|
|
455
|
+
export function openAveSigningPopup({
|
|
456
|
+
requestId,
|
|
457
|
+
issuer = "https://aveid.net",
|
|
458
|
+
width = 500,
|
|
459
|
+
height = 600,
|
|
460
|
+
onSigned,
|
|
461
|
+
onDenied,
|
|
462
|
+
onClose,
|
|
463
|
+
}) {
|
|
464
|
+
const params = new URLSearchParams({
|
|
465
|
+
requestId,
|
|
466
|
+
embed: "1",
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
const left = (window.innerWidth - width) / 2 + window.screenX;
|
|
470
|
+
const top = (window.innerHeight - height) / 2 + window.screenY;
|
|
471
|
+
|
|
472
|
+
const popup = window.open(
|
|
473
|
+
`${issuer}/sign?${params.toString()}`,
|
|
474
|
+
"ave_signing",
|
|
475
|
+
`width=${width},height=${height},left=${left},top=${top},menubar=no,toolbar=no,location=no,status=no`
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
if (!popup) {
|
|
479
|
+
onDenied?.({ error: "popup_blocked", message: "Popup was blocked by the browser" });
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const messageHandler = (event) => {
|
|
484
|
+
if (event.origin !== issuer) return;
|
|
485
|
+
const data = event.data || {};
|
|
486
|
+
|
|
487
|
+
if (data.type === "ave:signed") {
|
|
488
|
+
popup.close();
|
|
489
|
+
window.removeEventListener("message", messageHandler);
|
|
490
|
+
onSigned?.(data.payload);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (data.type === "ave:denied") {
|
|
494
|
+
popup.close();
|
|
495
|
+
window.removeEventListener("message", messageHandler);
|
|
496
|
+
onDenied?.(data.payload);
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
window.addEventListener("message", messageHandler);
|
|
501
|
+
|
|
502
|
+
// Check if popup was closed
|
|
503
|
+
const pollTimer = setInterval(() => {
|
|
504
|
+
if (popup.closed) {
|
|
505
|
+
clearInterval(pollTimer);
|
|
506
|
+
window.removeEventListener("message", messageHandler);
|
|
507
|
+
onClose?.();
|
|
508
|
+
}
|
|
509
|
+
}, 500);
|
|
510
|
+
|
|
511
|
+
return {
|
|
512
|
+
popup,
|
|
513
|
+
close() {
|
|
514
|
+
clearInterval(pollTimer);
|
|
515
|
+
popup.close();
|
|
516
|
+
window.removeEventListener("message", messageHandler);
|
|
517
|
+
},
|
|
518
|
+
};
|
|
519
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ave-id/embed",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/embed.js",
|
|
6
|
+
"module": "dist/embed.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/embed.js",
|
|
10
|
+
"default": "./dist/embed.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
6
13
|
"files": ["dist"],
|
|
7
14
|
"publishConfig": {
|
|
8
15
|
"access": "public"
|
|
9
16
|
},
|
|
10
17
|
"scripts": {
|
|
11
|
-
"build": "mkdir -p dist && cp src/embed.js dist/embed.js"
|
|
18
|
+
"build": "mkdir -p dist && cp src/embed.js dist/embed.js",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
12
20
|
}
|
|
13
21
|
}
|