@momentco-ai/moment-sdk 0.3.0 → 0.3.1-dev.20
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/CHANGELOG.md +6 -0
- package/README.md +24 -15
- package/dist/moment-sdk.js +2 -2
- package/dist/moment-sdk.mjs +60 -51
- package/dist/types/sdk/__tests__/sync-iframe-url.test.d.ts +1 -0
- package/dist/types/sdk/button.d.ts +3 -1
- package/dist/types/sdk/sync-iframe-url.d.ts +3 -0
- package/dist/types/sdk/types.d.ts +8 -0
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `externalEventIdPrefix` on `MomentSdkOpenPayload`, `createMomentButton()`, and `data-external-event-id-prefix` for event-level sync buttons. Live fetches all showings for the upstream event and prompts the user to pick one. Mutually exclusive with `externalEventId`.
|
|
13
|
+
|
|
8
14
|
## [0.3.0] - 2026-06-08
|
|
9
15
|
|
|
10
16
|
### Added
|
package/README.md
CHANGED
|
@@ -106,19 +106,20 @@ For `team` and `brand-playlist`, omit moment/list/ID and source-resolution attri
|
|
|
106
106
|
|
|
107
107
|
Place these on any element matching the trigger selector (default: `.moment-sync-trigger`):
|
|
108
108
|
|
|
109
|
-
| Attribute
|
|
110
|
-
|
|
|
111
|
-
| `data-moment-team-slug`
|
|
112
|
-
| `data-moment-slug`
|
|
113
|
-
| `data-moment-list-slug`
|
|
114
|
-
| `data-moment-trigger-type`
|
|
115
|
-
| `data-moment-ids`
|
|
116
|
-
| `data-moment-game-id`
|
|
117
|
-
| `data-moment-calendar`
|
|
118
|
-
| `data-api-source-id`
|
|
119
|
-
| `data-external-event-id`
|
|
120
|
-
|
|
121
|
-
|
|
109
|
+
| Attribute | Required | Description |
|
|
110
|
+
| ------------------------------- | ------------ | ----------------------------------------------------------------- |
|
|
111
|
+
| `data-moment-team-slug` | Yes | Team/brand slug provided by Moment |
|
|
112
|
+
| `data-moment-slug` | For `moment` | Brand-level moment slug (resolved server-side) |
|
|
113
|
+
| `data-moment-list-slug` | For `list` | List slug |
|
|
114
|
+
| `data-moment-trigger-type` | No | `moment` (default), `list`, `team`, or `brand-playlist` |
|
|
115
|
+
| `data-moment-ids` | No | Comma-separated moment IDs (fallback if slugs don't resolve) |
|
|
116
|
+
| `data-moment-game-id` | No | Alias for `data-moment-ids` |
|
|
117
|
+
| `data-moment-calendar` | No | Pre-select provider: `google` or `outlook` |
|
|
118
|
+
| `data-api-source-id` | No | Sync-subscription source ID (pairs with external id attributes) |
|
|
119
|
+
| `data-external-event-id` | No | Exact external id (`event_id:showing_id`) resolved against source |
|
|
120
|
+
| `data-external-event-id-prefix` | No | Upstream event id only — user picks a showing in the embed modal |
|
|
121
|
+
|
|
122
|
+
When `data-api-source-id` is set with either `data-external-event-id` (one showing) or `data-external-event-id-prefix` (all showings for an event), Live resolves moments server-side — useful when your CMS emits native event IDs instead of Moment slugs.
|
|
122
123
|
|
|
123
124
|
---
|
|
124
125
|
|
|
@@ -150,12 +151,20 @@ sdk.open({
|
|
|
150
151
|
triggerType: 'moment',
|
|
151
152
|
});
|
|
152
153
|
|
|
153
|
-
// Source-based resolution (CMS event ID)
|
|
154
|
+
// Source-based resolution (CMS event ID — single showing)
|
|
154
155
|
sdk.open({
|
|
155
156
|
teamSlug: 'your-team-slug',
|
|
156
157
|
triggerType: 'moment',
|
|
157
158
|
apiSourceId: 'your-sync-source-id',
|
|
158
|
-
externalEventId: '
|
|
159
|
+
externalEventId: '1420:2706',
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Source-based resolution (event with multiple showings — user picks date)
|
|
163
|
+
sdk.open({
|
|
164
|
+
teamSlug: 'your-team-slug',
|
|
165
|
+
triggerType: 'moment',
|
|
166
|
+
apiSourceId: 'your-sync-source-id',
|
|
167
|
+
externalEventIdPrefix: '1420',
|
|
159
168
|
});
|
|
160
169
|
|
|
161
170
|
// Follow full team schedule
|
package/dist/moment-sdk.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(g){"use strict";class w{popup=null;pollTimer=null;messageHandler=null;resultReceived=!1;opts;constructor(e){this.opts=e}open(e){this.cleanup(),this.resultReceived=!1;const t=this.buildPopupUrl(e),i=Math.round(window.screenX+(window.outerWidth-500)/2),o=Math.round(window.screenY+(window.outerHeight-700)/2);if(this.popup=window.open(t,"moment-oauth-popup",`width=500,height=700,left=${i},top=${o},menubar=no,toolbar=no,location=yes,status=no`),!this.popup||this.popup.closed){this.sendStatusToIframe("popup-blocked"),this.opts.onPopupBlocked();return}this.sendStatusToIframe("popup-opened"),this.startPolling(),this.messageHandler=s=>{if(s.origin!==this.opts.liveOrigin||s.source!==this.popup)return;const r=s.data;!r||typeof r!="object"||r.source!=="moment-live-embed"||r.type!=="moment.embed.result"||(this.resultReceived=!0,this.sendStatusToIframe("completed"),this.opts.iframeWindow&&this.opts.iframeWindow.postMessage(r,this.opts.liveOrigin),this.opts.onResult(r),this.cleanup())},window.addEventListener("message",this.messageHandler)}cleanup(){if(this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.popup&&!this.popup.closed)try{this.popup.close()}catch{}this.popup=null}buildPopupUrl(e){const t=window.location.origin,i=new URLSearchParams({provider:e.provider,teamSlug:e.teamSlug,ids:e.ids.join(","),triggerType:e.triggerType,returnOrigin:t});return e.subscriptionType&&i.set("subscriptionType",e.subscriptionType),`${this.opts.liveBaseUrl}/en/embed/oauth-popup?${i.toString()}`}startPolling(){this.pollTimer=setInterval(()=>{(!this.popup||this.popup.closed)&&(this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.resultReceived||(this.sendStatusToIframe("popup-closed"),this.opts.onPopupClosed()),this.cleanup())},500)}sendStatusToIframe(e){if(!this.opts.iframeWindow)return;const t={source:"moment-sdk",type:"moment.embed.oauth.status",status:e};this.opts.iframeWindow.postMessage(t,this.opts.liveOrigin)}}function x(n,e,t=typeof window<"u"?window.location.origin:""){const i=new URLSearchParams;return i.set("teamSlug",e.teamSlug),e.momentSlug&&i.set("momentSlug",e.momentSlug),e.listSlug&&i.set("listSlug",e.listSlug),i.set("triggerType",e.triggerType),e.ids?.length&&i.set("ids",e.ids.join(",")),e.calendar&&i.set("calendar",e.calendar),e.apiSourceId&&i.set("subscriptionId",e.apiSourceId),e.externalEventId&&i.set("externalId",e.externalEventId),e.externalEventIdPrefix&&!e.externalEventId&&i.set("externalIdPrefix",e.externalEventIdPrefix),i.set("returnOrigin",t),i.set("embed","1"),`${n}/en/embed/sync?${i.toString()}`}const f="moment-sdk-trigger-styles",E=`
|
|
2
2
|
:where(.moment-sync-trigger) {
|
|
3
3
|
background-color: #1c1917;
|
|
4
4
|
color: #ffffff;
|
|
@@ -22,4 +22,4 @@
|
|
|
22
22
|
outline: 2px solid #1c1917;
|
|
23
23
|
outline-offset: 2px;
|
|
24
24
|
}
|
|
25
|
-
`;function S(){if(typeof document>"u"||document.getElementById(g))return;const s=document.createElement("style");s.id=g,s.textContent=T,document.head.appendChild(s)}const E=".moment-sync-trigger",x="https://live.momentco.ai";class f{opts;liveBaseUrl;liveOrigin;overlay=null;iframe=null;popupBridge=null;messageHandler=null;boundClickHandlers=new Map;activePayload=null;previousFocusedElement=null;previousBodyOverflow="";didManageBodyOverflow=!1;closeTimer=null;constructor(e){this.opts={triggerSelector:E,...e},this.liveBaseUrl=x;try{this.liveOrigin=new URL(this.liveBaseUrl).origin}catch{throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`)}S(),this.bindTriggers(),this.emitAnalytics("embed.init")}open(e){const t=this.scopeOpenPayload(e);this.emitAnalytics("embed.open",{teamSlug:t.teamSlug,triggerType:t.triggerType}),this.createModal(t)}close(){this.handleCancel()}rebind(){this.unbindTriggers(),this.bindTriggers()}destroy(){this.cleanup(),this.unbindTriggers()}bindTriggers(){document.querySelectorAll(this.opts.triggerSelector).forEach(t=>{const i=n=>{n.preventDefault(),this.handleTriggerClick(t)},o=this.boundClickHandlers.get(t);o&&t.removeEventListener("click",o),t.addEventListener("click",i),this.boundClickHandlers.set(t,i)})}unbindTriggers(){this.boundClickHandlers.forEach((e,t)=>{t.removeEventListener("click",e)}),this.boundClickHandlers.clear()}handleTriggerClick(e){const t=e.getAttribute("data-moment-team-slug")??"",i=e.getAttribute("data-moment-slug")??void 0,o=e.getAttribute("data-moment-list-slug")??void 0,n=e.getAttribute("data-moment-trigger-type");let r="moment";n!=null&&n!==""&&(n==="moment"||n==="list"||n==="team"||n==="brand-playlist"?r=n:console.warn("[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",n));const d=e.getAttribute("data-moment-ids")??e.getAttribute("data-moment-game-id")??"",c=d?d.split(",").filter(Boolean):[],a=e.getAttribute("data-moment-calendar");let m;a!=null&&a!==""&&(a==="google"||a==="outlook"?m=a:console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:",a));const l=e.getAttribute("data-api-source-id")??void 0,u=e.getAttribute("data-external-event-id")??void 0;if(!t){console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");return}const p=r==="team"||r==="brand-playlist";this.emitAnalytics("embed.trigger.click",{teamSlug:t,triggerType:r,momentIds:p?[]:c}),this.open({teamSlug:t,momentSlug:i,listSlug:o,triggerType:r,ids:c,calendar:m??void 0,apiSourceId:l,externalEventId:u})}scopeOpenPayload(e){return e.triggerType==="team"||e.triggerType==="brand-playlist"?{teamSlug:e.teamSlug,triggerType:e.triggerType,calendar:e.calendar}:e}createModal(e){this.cleanup(),this.previousFocusedElement=document.activeElement||null,this.activePayload=e;const t=this.buildIframeUrl(e);this.overlay=document.createElement("div"),this.overlay.setAttribute("role","presentation"),Object.assign(this.overlay.style,{position:"fixed",inset:"0",zIndex:"999999",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0, 0, 0, 0.5)",backdropFilter:"blur(2px)",padding:"16px"}),this.overlay.addEventListener("click",l=>{l.target===this.overlay&&this.handleCancel()});const i=l=>{l.key==="Escape"&&this.handleCancel()};document.addEventListener("keydown",i);const o=document.createElement("div");Object.assign(o.style,{position:"relative",width:"100%",maxWidth:"380px",borderRadius:"16px",overflow:"hidden",backgroundColor:"#000000",boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)",display:"flex",flexDirection:"column"});const n=document.createElement("div");n.setAttribute("role","dialog"),n.setAttribute("aria-modal","true"),n.setAttribute("aria-label","Calendar sync modal"),n.tabIndex=-1,Object.assign(n.style,{position:"relative",width:"100%",maxHeight:"80vh",borderRadius:"12px",overflow:"auto",backgroundColor:"#ffffff"});const r=document.createElement("button");r.type="button",r.innerHTML='<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1l12 12M13 1L1 13" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',r.setAttribute("aria-label","Close"),Object.assign(r.style,{position:"absolute",top:"10px",right:"10px",zIndex:"10",border:"none",backgroundColor:"transparent",color:"#999",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",padding:"0"}),r.addEventListener("mouseenter",()=>{r.style.color="#666"}),r.addEventListener("mouseleave",()=>{r.style.color="#999"}),r.addEventListener("click",()=>this.handleCancel()),this.iframe=document.createElement("iframe"),this.iframe.src=t,this.iframe.setAttribute("allow",""),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-popups allow-forms"),this.iframe.setAttribute("scrolling","no"),Object.assign(this.iframe.style,{width:"100%",border:"none",display:"block",height:"420px",overflow:"hidden",transition:"height 0.15s ease"}),n.appendChild(r),n.appendChild(this.iframe);const d=document.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"12px 0"});const c=document.createElement("span");c.textContent="Powered by",Object.assign(c.style,{fontFamily:"Inter, system-ui, -apple-system, sans-serif",fontSize:"12px",lineHeight:"16px",color:"#ffffff"});const a=document.createElement("img");a.alt="Moment",a.src=`${this.liveBaseUrl}/brand/moment-text-white.png`,Object.assign(a.style,{height:"auto",width:"67px"}),d.appendChild(c),d.appendChild(a),o.appendChild(n),o.appendChild(d),this.overlay.appendChild(o),document.body.appendChild(this.overlay);const m=l=>{if(l.key!=="Tab")return;const u=n.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(u.length===0){l.preventDefault(),n.focus();return}const p=u[0],b=u[u.length-1],y=document.activeElement;l.shiftKey&&y===p?(l.preventDefault(),b.focus()):!l.shiftKey&&y===b&&(l.preventDefault(),p.focus())};n.addEventListener("keydown",m),r.focus(),this.previousBodyOverflow=document.body.style.overflow,document.body.style.overflow="hidden",this.didManageBodyOverflow=!0,this.setupMessageListener(),this.overlay._escHandler=i,this.overlay._focusTrapHandler=m}buildIframeUrl(e){const t=new URLSearchParams;return t.set("teamSlug",e.teamSlug),e.momentSlug&&t.set("momentSlug",e.momentSlug),e.listSlug&&t.set("listSlug",e.listSlug),t.set("triggerType",e.triggerType),e.ids?.length&&t.set("ids",e.ids.join(",")),e.calendar&&t.set("calendar",e.calendar),e.apiSourceId&&t.set("subscriptionId",e.apiSourceId),e.externalEventId&&t.set("externalId",e.externalEventId),t.set("returnOrigin",window.location.origin),t.set("embed","1"),`${this.liveBaseUrl}/en/embed/sync?${t.toString()}`}setupMessageListener(){this.messageHandler=e=>{if(e.origin!==this.liveOrigin||e.source!==this.iframe?.contentWindow)return;const t=e.data;if(!(!t||typeof t!="object")){if(t.source==="moment-live-embed"&&t.type==="moment.embed.oauth.start"){const i=t;this.emitAnalytics("oauth.start",{provider:i.provider,teamSlug:i.teamSlug}),this.handleOAuthStart(i);return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.resize"){const i=typeof t.height=="number"?t.height:0;if(i>0&&this.iframe){const o=Math.round(window.innerHeight*.8);this.iframe.style.height=`${Math.min(i,o)}px`}return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.open.url"){const{url:i}=t;i&&typeof i=="string"&&i.startsWith("webcal://")&&window.open(i,"_blank");return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.result"){const i=t;this.handleResult(i)}}},window.addEventListener("message",this.messageHandler)}handleOAuthStart(e){this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.popupBridge=new w({liveBaseUrl:this.liveBaseUrl,liveOrigin:this.liveOrigin,iframeWindow:this.iframe?.contentWindow??null,onResult:t=>{this.handleResult(t)},onPopupBlocked:()=>{this.emitAnalytics("oauth.popup.blocked",{provider:e.provider})},onPopupClosed:()=>{this.emitAnalytics("oauth.popup.closed",{provider:e.provider})}}),this.popupBridge.open(e)}handleResult(e){if(e.result==="success")this.emitAnalytics("subscribe.success",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onSuccess?.(e);else if(e.result==="error")this.emitAnalytics("subscribe.error",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onError?.(e);else if(e.result==="cancelled")return;this.opts.onClose?.(e),this.emitAnalytics("embed.close"),this.closeTimer=setTimeout(()=>this.cleanup(),1500)}handleCancel(){this.emitAnalytics("embed.close");const t={source:"moment-live-embed",type:"moment.embed.result",result:"cancelled",triggerType:this.activePayload?.triggerType??"moment",momentIds:this.activePayload?.ids??[]};this.opts.onClose?.(t),this.cleanup()}cleanup(){if(this.closeTimer&&(clearTimeout(this.closeTimer),this.closeTimer=null),this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.overlay){const{_escHandler:e,_focusTrapHandler:t}=this.overlay;e&&document.removeEventListener("keydown",e);const i=this.overlay.firstElementChild;i&&t&&i.removeEventListener("keydown",t),this.overlay.remove(),this.overlay=null}this.iframe=null,this.activePayload=null,this.didManageBodyOverflow&&(document.body.style.overflow=this.previousBodyOverflow,this.didManageBodyOverflow=!1),this.previousFocusedElement&&typeof this.previousFocusedElement.focus=="function"&&this.previousFocusedElement.focus(),this.previousFocusedElement=null}emitAnalytics(e,t){this.opts.onAnalytics?.({event:e,timestamp:Date.now(),...t})}}function v(s){const e=document.createElement("button");return e.type="button",e.classList.add("moment-sync-trigger"),s.className&&s.className.split(" ").forEach(t=>{t&&e.classList.add(t)}),e.setAttribute("data-moment-team-slug",s.teamSlug),s.momentSlug&&e.setAttribute("data-moment-slug",s.momentSlug),s.listSlug&&e.setAttribute("data-moment-list-slug",s.listSlug),s.triggerType&&e.setAttribute("data-moment-trigger-type",s.triggerType),s.ids?.length&&e.setAttribute("data-moment-ids",s.ids.join(",")),s.calendar&&e.setAttribute("data-moment-calendar",s.calendar),s.apiSourceId&&e.setAttribute("data-api-source-id",s.apiSourceId),s.externalEventId&&e.setAttribute("data-external-event-id",s.externalEventId),e.textContent=s.label??"Add to Calendar",e}if(typeof window<"u"){const s=window;s.MomentSdk=f,s.createMomentButton=v}h.MomentSdk=f,h.createMomentButton=v,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})})(this.MomentSdk=this.MomentSdk||{});
|
|
25
|
+
`;function T(){if(typeof document>"u"||document.getElementById(f))return;const n=document.createElement("style");n.id=f,n.textContent=E,document.head.appendChild(n)}const S=".moment-sync-trigger",I="https://live.dev.momentco.ai";class v{opts;liveBaseUrl;liveOrigin;overlay=null;iframe=null;popupBridge=null;messageHandler=null;boundClickHandlers=new Map;activePayload=null;previousFocusedElement=null;previousBodyOverflow="";didManageBodyOverflow=!1;closeTimer=null;constructor(e){this.opts={triggerSelector:S,...e},this.liveBaseUrl=I;try{this.liveOrigin=new URL(this.liveBaseUrl).origin}catch{throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`)}T(),this.bindTriggers(),this.emitAnalytics("embed.init")}open(e){e.externalEventId&&e.externalEventIdPrefix&&console.warn("[MomentSdk] Both externalEventId and externalEventIdPrefix provided; using externalEventId only.");const t=this.scopeOpenPayload(e);this.emitAnalytics("embed.open",{teamSlug:t.teamSlug,triggerType:t.triggerType}),this.createModal(t)}close(){this.handleCancel()}rebind(){this.unbindTriggers(),this.bindTriggers()}destroy(){this.cleanup(),this.unbindTriggers()}bindTriggers(){document.querySelectorAll(this.opts.triggerSelector).forEach(t=>{const i=s=>{s.preventDefault(),this.handleTriggerClick(t)},o=this.boundClickHandlers.get(t);o&&t.removeEventListener("click",o),t.addEventListener("click",i),this.boundClickHandlers.set(t,i)})}unbindTriggers(){this.boundClickHandlers.forEach((e,t)=>{t.removeEventListener("click",e)}),this.boundClickHandlers.clear()}handleTriggerClick(e){const t=e.getAttribute("data-moment-team-slug")??"",i=e.getAttribute("data-moment-slug")??void 0,o=e.getAttribute("data-moment-list-slug")??void 0,s=e.getAttribute("data-moment-trigger-type");let r="moment";s!=null&&s!==""&&(s==="moment"||s==="list"||s==="team"||s==="brand-playlist"?r=s:console.warn("[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",s));const c=e.getAttribute("data-moment-ids")??e.getAttribute("data-moment-game-id")??"",u=c?c.split(",").filter(Boolean):[],a=e.getAttribute("data-moment-calendar");let p;a!=null&&a!==""&&(a==="google"||a==="outlook"?p=a:console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:",a));const l=e.getAttribute("data-api-source-id")??void 0,d=e.getAttribute("data-external-event-id")??void 0,m=e.getAttribute("data-external-event-id-prefix")??void 0;if(d&&m&&console.warn("[MomentSdk] Both data-external-event-id and data-external-event-id-prefix are set; using data-external-event-id only."),!t){console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");return}const h=r==="team"||r==="brand-playlist";this.emitAnalytics("embed.trigger.click",{teamSlug:t,triggerType:r,momentIds:h?[]:u}),this.open({teamSlug:t,momentSlug:i,listSlug:o,triggerType:r,ids:u,calendar:p??void 0,apiSourceId:l,externalEventId:m&&!d?void 0:d,externalEventIdPrefix:d?void 0:m})}scopeOpenPayload(e){return e.triggerType==="team"||e.triggerType==="brand-playlist"?{teamSlug:e.teamSlug,triggerType:e.triggerType,calendar:e.calendar}:e}createModal(e){this.cleanup(),this.previousFocusedElement=document.activeElement||null,this.activePayload=e;const t=this.buildIframeUrl(e);this.overlay=document.createElement("div"),this.overlay.setAttribute("role","presentation"),Object.assign(this.overlay.style,{position:"fixed",inset:"0",zIndex:"999999",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0, 0, 0, 0.5)",backdropFilter:"blur(2px)",padding:"16px"}),this.overlay.addEventListener("click",l=>{l.target===this.overlay&&this.handleCancel()});const i=l=>{l.key==="Escape"&&this.handleCancel()};document.addEventListener("keydown",i);const o=document.createElement("div");Object.assign(o.style,{position:"relative",width:"100%",maxWidth:"380px",borderRadius:"16px",overflow:"hidden",backgroundColor:"#000000",boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)",display:"flex",flexDirection:"column"});const s=document.createElement("div");s.setAttribute("role","dialog"),s.setAttribute("aria-modal","true"),s.setAttribute("aria-label","Calendar sync modal"),s.tabIndex=-1,Object.assign(s.style,{position:"relative",width:"100%",maxHeight:"80vh",borderRadius:"12px",overflow:"auto",backgroundColor:"#ffffff"});const r=document.createElement("button");r.type="button",r.innerHTML='<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1l12 12M13 1L1 13" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg>',r.setAttribute("aria-label","Close"),Object.assign(r.style,{position:"absolute",top:"10px",right:"10px",zIndex:"10",border:"none",backgroundColor:"transparent",color:"#999",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",padding:"0"}),r.addEventListener("mouseenter",()=>{r.style.color="#666"}),r.addEventListener("mouseleave",()=>{r.style.color="#999"}),r.addEventListener("click",()=>this.handleCancel()),this.iframe=document.createElement("iframe"),this.iframe.src=t,this.iframe.setAttribute("allow",""),this.iframe.setAttribute("sandbox","allow-scripts allow-same-origin allow-popups allow-forms"),this.iframe.setAttribute("scrolling","no"),Object.assign(this.iframe.style,{width:"100%",border:"none",display:"block",height:"420px",overflow:"hidden",transition:"height 0.15s ease"}),s.appendChild(r),s.appendChild(this.iframe);const c=document.createElement("div");Object.assign(c.style,{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"12px 0"});const u=document.createElement("span");u.textContent="Powered by",Object.assign(u.style,{fontFamily:"Inter, system-ui, -apple-system, sans-serif",fontSize:"12px",lineHeight:"16px",color:"#ffffff"});const a=document.createElement("img");a.alt="Moment",a.src=`${this.liveBaseUrl}/brand/moment-text-white.png`,Object.assign(a.style,{height:"auto",width:"67px"}),c.appendChild(u),c.appendChild(a),o.appendChild(s),o.appendChild(c),this.overlay.appendChild(o),document.body.appendChild(this.overlay);const p=l=>{if(l.key!=="Tab")return;const d=s.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(d.length===0){l.preventDefault(),s.focus();return}const m=d[0],h=d[d.length-1],y=document.activeElement;l.shiftKey&&y===m?(l.preventDefault(),h.focus()):!l.shiftKey&&y===h&&(l.preventDefault(),m.focus())};s.addEventListener("keydown",p),r.focus(),this.previousBodyOverflow=document.body.style.overflow,document.body.style.overflow="hidden",this.didManageBodyOverflow=!0,this.setupMessageListener(),this.overlay._escHandler=i,this.overlay._focusTrapHandler=p}buildIframeUrl(e){return x(this.liveBaseUrl,e)}setupMessageListener(){this.messageHandler=e=>{if(e.origin!==this.liveOrigin||e.source!==this.iframe?.contentWindow)return;const t=e.data;if(!(!t||typeof t!="object")){if(t.source==="moment-live-embed"&&t.type==="moment.embed.oauth.start"){const i=t;this.emitAnalytics("oauth.start",{provider:i.provider,teamSlug:i.teamSlug}),this.handleOAuthStart(i);return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.resize"){const i=typeof t.height=="number"?t.height:0;if(i>0&&this.iframe){const o=Math.round(window.innerHeight*.8);this.iframe.style.height=`${Math.min(i,o)}px`}return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.open.url"){const{url:i}=t;i&&typeof i=="string"&&i.startsWith("webcal://")&&window.open(i,"_blank");return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.result"){const i=t;this.handleResult(i)}}},window.addEventListener("message",this.messageHandler)}handleOAuthStart(e){this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.popupBridge=new w({liveBaseUrl:this.liveBaseUrl,liveOrigin:this.liveOrigin,iframeWindow:this.iframe?.contentWindow??null,onResult:t=>{this.handleResult(t)},onPopupBlocked:()=>{this.emitAnalytics("oauth.popup.blocked",{provider:e.provider})},onPopupClosed:()=>{this.emitAnalytics("oauth.popup.closed",{provider:e.provider})}}),this.popupBridge.open(e)}handleResult(e){if(e.result==="success")this.emitAnalytics("subscribe.success",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onSuccess?.(e);else if(e.result==="error")this.emitAnalytics("subscribe.error",{provider:e.provider,triggerType:e.triggerType,momentIds:e.momentIds}),this.opts.onError?.(e);else if(e.result==="cancelled")return;this.opts.onClose?.(e),this.emitAnalytics("embed.close"),this.closeTimer=setTimeout(()=>this.cleanup(),1500)}handleCancel(){this.emitAnalytics("embed.close");const t={source:"moment-live-embed",type:"moment.embed.result",result:"cancelled",triggerType:this.activePayload?.triggerType??"moment",momentIds:this.activePayload?.ids??[]};this.opts.onClose?.(t),this.cleanup()}cleanup(){if(this.closeTimer&&(clearTimeout(this.closeTimer),this.closeTimer=null),this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.overlay){const{_escHandler:e,_focusTrapHandler:t}=this.overlay;e&&document.removeEventListener("keydown",e);const i=this.overlay.firstElementChild;i&&t&&i.removeEventListener("keydown",t),this.overlay.remove(),this.overlay=null}this.iframe=null,this.activePayload=null,this.didManageBodyOverflow&&(document.body.style.overflow=this.previousBodyOverflow,this.didManageBodyOverflow=!1),this.previousFocusedElement&&typeof this.previousFocusedElement.focus=="function"&&this.previousFocusedElement.focus(),this.previousFocusedElement=null}emitAnalytics(e,t){this.opts.onAnalytics?.({event:e,timestamp:Date.now(),...t})}}function b(n){const e=document.createElement("button");return e.type="button",e.classList.add("moment-sync-trigger"),n.className&&n.className.split(" ").forEach(t=>{t&&e.classList.add(t)}),e.setAttribute("data-moment-team-slug",n.teamSlug),n.momentSlug&&e.setAttribute("data-moment-slug",n.momentSlug),n.listSlug&&e.setAttribute("data-moment-list-slug",n.listSlug),n.triggerType&&e.setAttribute("data-moment-trigger-type",n.triggerType),n.ids?.length&&e.setAttribute("data-moment-ids",n.ids.join(",")),n.calendar&&e.setAttribute("data-moment-calendar",n.calendar),n.apiSourceId&&e.setAttribute("data-api-source-id",n.apiSourceId),n.externalEventId&&e.setAttribute("data-external-event-id",n.externalEventId),n.externalEventIdPrefix&&e.setAttribute("data-external-event-id-prefix",n.externalEventIdPrefix),e.textContent=n.label??"Add to Calendar",e}if(typeof window<"u"){const n=window;n.MomentSdk=v,n.createMomentButton=b}g.MomentSdk=v,g.createMomentButton=b,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})})(this.MomentSdk=this.MomentSdk||{});
|
package/dist/moment-sdk.mjs
CHANGED
|
@@ -21,9 +21,9 @@ class v {
|
|
|
21
21
|
this.sendStatusToIframe("popup-blocked"), this.opts.onPopupBlocked();
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
this.sendStatusToIframe("popup-opened"), this.startPolling(), this.messageHandler = (
|
|
25
|
-
if (
|
|
26
|
-
const r =
|
|
24
|
+
this.sendStatusToIframe("popup-opened"), this.startPolling(), this.messageHandler = (s) => {
|
|
25
|
+
if (s.origin !== this.opts.liveOrigin || s.source !== this.popup) return;
|
|
26
|
+
const r = s.data;
|
|
27
27
|
!r || typeof r != "object" || r.source !== "moment-live-embed" || r.type !== "moment.embed.result" || (this.resultReceived = !0, this.sendStatusToIframe("completed"), this.opts.iframeWindow && this.opts.iframeWindow.postMessage(r, this.opts.liveOrigin), this.opts.onResult(r), this.cleanup());
|
|
28
28
|
}, window.addEventListener("message", this.messageHandler);
|
|
29
29
|
}
|
|
@@ -63,7 +63,11 @@ class v {
|
|
|
63
63
|
this.opts.iframeWindow.postMessage(t, this.opts.liveOrigin);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
function b(n, e, t = typeof window < "u" ? window.location.origin : "") {
|
|
67
|
+
const i = new URLSearchParams();
|
|
68
|
+
return i.set("teamSlug", e.teamSlug), e.momentSlug && i.set("momentSlug", e.momentSlug), e.listSlug && i.set("listSlug", e.listSlug), i.set("triggerType", e.triggerType), e.ids?.length && i.set("ids", e.ids.join(",")), e.calendar && i.set("calendar", e.calendar), e.apiSourceId && i.set("subscriptionId", e.apiSourceId), e.externalEventId && i.set("externalId", e.externalEventId), e.externalEventIdPrefix && !e.externalEventId && i.set("externalIdPrefix", e.externalEventIdPrefix), i.set("returnOrigin", t), i.set("embed", "1"), `${n}/en/embed/sync?${i.toString()}`;
|
|
69
|
+
}
|
|
70
|
+
const f = "moment-sdk-trigger-styles", y = `
|
|
67
71
|
:where(.moment-sync-trigger) {
|
|
68
72
|
background-color: #1c1917;
|
|
69
73
|
color: #ffffff;
|
|
@@ -88,13 +92,13 @@ const f = "moment-sdk-trigger-styles", b = `
|
|
|
88
92
|
outline-offset: 2px;
|
|
89
93
|
}
|
|
90
94
|
`;
|
|
91
|
-
function
|
|
95
|
+
function w() {
|
|
92
96
|
if (typeof document > "u" || document.getElementById(f)) return;
|
|
93
|
-
const
|
|
94
|
-
|
|
97
|
+
const n = document.createElement("style");
|
|
98
|
+
n.id = f, n.textContent = y, document.head.appendChild(n);
|
|
95
99
|
}
|
|
96
|
-
const
|
|
97
|
-
class
|
|
100
|
+
const x = ".moment-sync-trigger", E = "https://live.dev.momentco.ai";
|
|
101
|
+
class T {
|
|
98
102
|
opts;
|
|
99
103
|
liveBaseUrl;
|
|
100
104
|
liveOrigin;
|
|
@@ -110,20 +114,23 @@ class E {
|
|
|
110
114
|
closeTimer = null;
|
|
111
115
|
constructor(e) {
|
|
112
116
|
this.opts = {
|
|
113
|
-
triggerSelector:
|
|
117
|
+
triggerSelector: x,
|
|
114
118
|
...e
|
|
115
|
-
}, this.liveBaseUrl =
|
|
119
|
+
}, this.liveBaseUrl = E;
|
|
116
120
|
try {
|
|
117
121
|
this.liveOrigin = new URL(this.liveBaseUrl).origin;
|
|
118
122
|
} catch {
|
|
119
123
|
throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`);
|
|
120
124
|
}
|
|
121
|
-
|
|
125
|
+
w(), this.bindTriggers(), this.emitAnalytics("embed.init");
|
|
122
126
|
}
|
|
123
127
|
/**
|
|
124
128
|
* Programmatically open the sync modal.
|
|
125
129
|
*/
|
|
126
130
|
open(e) {
|
|
131
|
+
e.externalEventId && e.externalEventIdPrefix && console.warn(
|
|
132
|
+
"[MomentSdk] Both externalEventId and externalEventIdPrefix provided; using externalEventId only."
|
|
133
|
+
);
|
|
127
134
|
const t = this.scopeOpenPayload(e);
|
|
128
135
|
this.emitAnalytics("embed.open", {
|
|
129
136
|
teamSlug: t.teamSlug,
|
|
@@ -151,8 +158,8 @@ class E {
|
|
|
151
158
|
// ── Private: trigger binding ──────────────────────────────────────
|
|
152
159
|
bindTriggers() {
|
|
153
160
|
document.querySelectorAll(this.opts.triggerSelector).forEach((t) => {
|
|
154
|
-
const i = (
|
|
155
|
-
|
|
161
|
+
const i = (s) => {
|
|
162
|
+
s.preventDefault(), this.handleTriggerClick(t);
|
|
156
163
|
}, o = this.boundClickHandlers.get(t);
|
|
157
164
|
o && t.removeEventListener("click", o), t.addEventListener("click", i), this.boundClickHandlers.set(t, i);
|
|
158
165
|
});
|
|
@@ -163,34 +170,37 @@ class E {
|
|
|
163
170
|
}), this.boundClickHandlers.clear();
|
|
164
171
|
}
|
|
165
172
|
handleTriggerClick(e) {
|
|
166
|
-
const t = e.getAttribute("data-moment-team-slug") ?? "", i = e.getAttribute("data-moment-slug") ?? void 0, o = e.getAttribute("data-moment-list-slug") ?? void 0,
|
|
173
|
+
const t = e.getAttribute("data-moment-team-slug") ?? "", i = e.getAttribute("data-moment-slug") ?? void 0, o = e.getAttribute("data-moment-list-slug") ?? void 0, s = e.getAttribute("data-moment-trigger-type");
|
|
167
174
|
let r = "moment";
|
|
168
|
-
|
|
175
|
+
s != null && s !== "" && (s === "moment" || s === "list" || s === "team" || s === "brand-playlist" ? r = s : console.warn(
|
|
169
176
|
"[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",
|
|
170
|
-
|
|
177
|
+
s
|
|
171
178
|
));
|
|
172
|
-
const
|
|
173
|
-
let
|
|
174
|
-
a != null && a !== "" && (a === "google" || a === "outlook" ?
|
|
175
|
-
const l = e.getAttribute("data-api-source-id") ?? void 0,
|
|
176
|
-
if (
|
|
179
|
+
const c = e.getAttribute("data-moment-ids") ?? e.getAttribute("data-moment-game-id") ?? "", u = c ? c.split(",").filter(Boolean) : [], a = e.getAttribute("data-moment-calendar");
|
|
180
|
+
let p;
|
|
181
|
+
a != null && a !== "" && (a === "google" || a === "outlook" ? p = a : console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:", a));
|
|
182
|
+
const l = e.getAttribute("data-api-source-id") ?? void 0, d = e.getAttribute("data-external-event-id") ?? void 0, m = e.getAttribute("data-external-event-id-prefix") ?? void 0;
|
|
183
|
+
if (d && m && console.warn(
|
|
184
|
+
"[MomentSdk] Both data-external-event-id and data-external-event-id-prefix are set; using data-external-event-id only."
|
|
185
|
+
), !t) {
|
|
177
186
|
console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");
|
|
178
187
|
return;
|
|
179
188
|
}
|
|
180
|
-
const
|
|
189
|
+
const h = r === "team" || r === "brand-playlist";
|
|
181
190
|
this.emitAnalytics("embed.trigger.click", {
|
|
182
191
|
teamSlug: t,
|
|
183
192
|
triggerType: r,
|
|
184
|
-
momentIds:
|
|
193
|
+
momentIds: h ? [] : u
|
|
185
194
|
}), this.open({
|
|
186
195
|
teamSlug: t,
|
|
187
196
|
momentSlug: i,
|
|
188
197
|
listSlug: o,
|
|
189
198
|
triggerType: r,
|
|
190
|
-
ids:
|
|
191
|
-
calendar:
|
|
199
|
+
ids: u,
|
|
200
|
+
calendar: p ?? void 0,
|
|
192
201
|
apiSourceId: l,
|
|
193
|
-
externalEventId:
|
|
202
|
+
externalEventId: m && !d ? void 0 : d,
|
|
203
|
+
externalEventIdPrefix: d ? void 0 : m
|
|
194
204
|
});
|
|
195
205
|
}
|
|
196
206
|
/** Drop moment/list/source scoping for brand-level subscription triggers. */
|
|
@@ -234,8 +244,8 @@ class E {
|
|
|
234
244
|
display: "flex",
|
|
235
245
|
flexDirection: "column"
|
|
236
246
|
});
|
|
237
|
-
const
|
|
238
|
-
|
|
247
|
+
const s = document.createElement("div");
|
|
248
|
+
s.setAttribute("role", "dialog"), s.setAttribute("aria-modal", "true"), s.setAttribute("aria-label", "Calendar sync modal"), s.tabIndex = -1, Object.assign(s.style, {
|
|
239
249
|
position: "relative",
|
|
240
250
|
width: "100%",
|
|
241
251
|
maxHeight: "80vh",
|
|
@@ -270,17 +280,17 @@ class E {
|
|
|
270
280
|
height: "420px",
|
|
271
281
|
overflow: "hidden",
|
|
272
282
|
transition: "height 0.15s ease"
|
|
273
|
-
}),
|
|
274
|
-
const
|
|
275
|
-
Object.assign(
|
|
283
|
+
}), s.appendChild(r), s.appendChild(this.iframe);
|
|
284
|
+
const c = document.createElement("div");
|
|
285
|
+
Object.assign(c.style, {
|
|
276
286
|
display: "flex",
|
|
277
287
|
alignItems: "center",
|
|
278
288
|
justifyContent: "center",
|
|
279
289
|
gap: "6px",
|
|
280
290
|
padding: "12px 0"
|
|
281
291
|
});
|
|
282
|
-
const
|
|
283
|
-
|
|
292
|
+
const u = document.createElement("span");
|
|
293
|
+
u.textContent = "Powered by", Object.assign(u.style, {
|
|
284
294
|
fontFamily: "Inter, system-ui, -apple-system, sans-serif",
|
|
285
295
|
fontSize: "12px",
|
|
286
296
|
lineHeight: "16px",
|
|
@@ -290,24 +300,23 @@ class E {
|
|
|
290
300
|
a.alt = "Moment", a.src = `${this.liveBaseUrl}/brand/moment-text-white.png`, Object.assign(a.style, {
|
|
291
301
|
height: "auto",
|
|
292
302
|
width: "67px"
|
|
293
|
-
}),
|
|
294
|
-
const
|
|
303
|
+
}), c.appendChild(u), c.appendChild(a), o.appendChild(s), o.appendChild(c), this.overlay.appendChild(o), document.body.appendChild(this.overlay);
|
|
304
|
+
const p = (l) => {
|
|
295
305
|
if (l.key !== "Tab") return;
|
|
296
|
-
const
|
|
306
|
+
const d = s.querySelectorAll(
|
|
297
307
|
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
298
308
|
);
|
|
299
|
-
if (
|
|
300
|
-
l.preventDefault(),
|
|
309
|
+
if (d.length === 0) {
|
|
310
|
+
l.preventDefault(), s.focus();
|
|
301
311
|
return;
|
|
302
312
|
}
|
|
303
|
-
const
|
|
304
|
-
l.shiftKey && g ===
|
|
313
|
+
const m = d[0], h = d[d.length - 1], g = document.activeElement;
|
|
314
|
+
l.shiftKey && g === m ? (l.preventDefault(), h.focus()) : !l.shiftKey && g === h && (l.preventDefault(), m.focus());
|
|
305
315
|
};
|
|
306
|
-
|
|
316
|
+
s.addEventListener("keydown", p), r.focus(), this.previousBodyOverflow = document.body.style.overflow, document.body.style.overflow = "hidden", this.didManageBodyOverflow = !0, this.setupMessageListener(), this.overlay._escHandler = i, this.overlay._focusTrapHandler = p;
|
|
307
317
|
}
|
|
308
318
|
buildIframeUrl(e) {
|
|
309
|
-
|
|
310
|
-
return t.set("teamSlug", e.teamSlug), e.momentSlug && t.set("momentSlug", e.momentSlug), e.listSlug && t.set("listSlug", e.listSlug), t.set("triggerType", e.triggerType), e.ids?.length && t.set("ids", e.ids.join(",")), e.calendar && t.set("calendar", e.calendar), e.apiSourceId && t.set("subscriptionId", e.apiSourceId), e.externalEventId && t.set("externalId", e.externalEventId), t.set("returnOrigin", window.location.origin), t.set("embed", "1"), `${this.liveBaseUrl}/en/embed/sync?${t.toString()}`;
|
|
319
|
+
return b(this.liveBaseUrl, e);
|
|
311
320
|
}
|
|
312
321
|
// ── Private: message handling ─────────────────────────────────────
|
|
313
322
|
setupMessageListener() {
|
|
@@ -410,17 +419,17 @@ class E {
|
|
|
410
419
|
});
|
|
411
420
|
}
|
|
412
421
|
}
|
|
413
|
-
function
|
|
422
|
+
function I(n) {
|
|
414
423
|
const e = document.createElement("button");
|
|
415
|
-
return e.type = "button", e.classList.add("moment-sync-trigger"),
|
|
424
|
+
return e.type = "button", e.classList.add("moment-sync-trigger"), n.className && n.className.split(" ").forEach((t) => {
|
|
416
425
|
t && e.classList.add(t);
|
|
417
|
-
}), e.setAttribute("data-moment-team-slug",
|
|
426
|
+
}), e.setAttribute("data-moment-team-slug", n.teamSlug), n.momentSlug && e.setAttribute("data-moment-slug", n.momentSlug), n.listSlug && e.setAttribute("data-moment-list-slug", n.listSlug), n.triggerType && e.setAttribute("data-moment-trigger-type", n.triggerType), n.ids?.length && e.setAttribute("data-moment-ids", n.ids.join(",")), n.calendar && e.setAttribute("data-moment-calendar", n.calendar), n.apiSourceId && e.setAttribute("data-api-source-id", n.apiSourceId), n.externalEventId && e.setAttribute("data-external-event-id", n.externalEventId), n.externalEventIdPrefix && e.setAttribute("data-external-event-id-prefix", n.externalEventIdPrefix), e.textContent = n.label ?? "Add to Calendar", e;
|
|
418
427
|
}
|
|
419
428
|
if (typeof window < "u") {
|
|
420
|
-
const
|
|
421
|
-
|
|
429
|
+
const n = window;
|
|
430
|
+
n.MomentSdk = T, n.createMomentButton = I;
|
|
422
431
|
}
|
|
423
432
|
export {
|
|
424
|
-
|
|
425
|
-
|
|
433
|
+
T as MomentSdk,
|
|
434
|
+
I as createMomentButton
|
|
426
435
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -13,8 +13,10 @@ export declare function createMomentButton(options: {
|
|
|
13
13
|
calendar?: CalendarProvider;
|
|
14
14
|
/** Sync subscription source id; pairs with `externalEventId` for server-side resolution. */
|
|
15
15
|
apiSourceId?: string;
|
|
16
|
-
/** External event identifier resolved against `apiSourceId
|
|
16
|
+
/** External event identifier resolved against `apiSourceId` (exact showing). */
|
|
17
17
|
externalEventId?: string;
|
|
18
|
+
/** Upstream event id — Live resolves all showings and prompts user to pick. */
|
|
19
|
+
externalEventIdPrefix?: string;
|
|
18
20
|
label?: string;
|
|
19
21
|
className?: string;
|
|
20
22
|
}): HTMLButtonElement;
|
|
@@ -54,9 +54,17 @@ export interface MomentSdkOpenPayload {
|
|
|
54
54
|
/**
|
|
55
55
|
* External event identifier emitted by the publisher's source feed (e.g. the
|
|
56
56
|
* provider's native event id). Resolved against `apiSourceId` to a moment.
|
|
57
|
+
* Use the composite `event_id:showing_id` format for a single showing.
|
|
57
58
|
* Forwarded to the Live embed as the `externalId` query param.
|
|
59
|
+
* Mutually exclusive with `externalEventIdPrefix`.
|
|
58
60
|
*/
|
|
59
61
|
externalEventId?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Upstream event id without showing suffix — Live fetches all showings for
|
|
64
|
+
* that event and prompts the user to pick one. Forwarded as `externalIdPrefix`.
|
|
65
|
+
* Mutually exclusive with `externalEventId`.
|
|
66
|
+
*/
|
|
67
|
+
externalEventIdPrefix?: string;
|
|
60
68
|
}
|
|
61
69
|
/** Backend subscription resource type that the embed will create */
|
|
62
70
|
export type MomentSubscriptionType = 'moment' | 'list' | 'team' | 'playlist';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momentco-ai/moment-sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1-dev.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Embeddable calendar sync widget for external team websites",
|
|
6
6
|
"author": "Moment Co. <support@momentco.ai> (https://momentco.ai)",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"format": "prettier --write .",
|
|
63
63
|
"format:check": "prettier --check .",
|
|
64
64
|
"quality": "pnpm run type-check && pnpm run lint && pnpm run format",
|
|
65
|
+
"test": "vitest run",
|
|
65
66
|
"examples": "pnpm build && node examples/serve.mjs",
|
|
66
67
|
"prepare": "husky"
|
|
67
68
|
},
|
|
@@ -72,6 +73,7 @@
|
|
|
72
73
|
"prettier": "^3.2.5",
|
|
73
74
|
"typescript": "^5.9.2",
|
|
74
75
|
"typescript-eslint": "^8.32.1",
|
|
75
|
-
"vite": "^7.1.5"
|
|
76
|
+
"vite": "^7.1.5",
|
|
77
|
+
"vitest": "^3.2.4"
|
|
76
78
|
}
|
|
77
79
|
}
|