@momentco-ai/moment-sdk 0.1.2-dev.10 → 0.2.0-dev.12

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/README.md CHANGED
@@ -29,7 +29,7 @@ npm install @momentco-ai/moment-sdk
29
29
  <button
30
30
  class="moment-sync-trigger"
31
31
  data-moment-team-slug="your-team-slug"
32
- data-external-event-id="event-001"
32
+ data-moment-slug="event-001"
33
33
  data-moment-trigger-type="moment"
34
34
  >
35
35
  Add to Calendar
@@ -71,9 +71,9 @@ Place these on any element matching the trigger selector (default: `.moment-sync
71
71
  | Attribute | Required | Description |
72
72
  | -------------------------- | -------- | ------------------------------------------------------------ |
73
73
  | `data-moment-team-slug` | ✅ | Team/brand slug |
74
- | `data-external-event-id` | No | Specific event identifier (resolved to real ID by Moment) |
75
- | `data-moment-list-slug` | No | List slug (resolved to moment IDs by Moment) |
76
- | `data-moment-trigger-type` | No | `moment` (default), `list`, or `schedule` |
74
+ | `data-moment-slug` | No | Brand-level moment slug (resolved to real ID by Moment) |
75
+ | `data-moment-list-slug` | No | List slug (resolved to a list-level subscription by Moment) |
76
+ | `data-moment-trigger-type` | No | `moment` (default), `list`, or `team` |
77
77
  | `data-moment-ids` | No | Comma-separated moment IDs (fallback if slugs don't resolve) |
78
78
  | `data-moment-game-id` | No | Alias for `data-moment-ids` |
79
79
  | `data-moment-calendar` | No | Pre-select provider: `google` or `outlook` |
@@ -93,7 +93,7 @@ You can also open the modal programmatically instead of relying on data attribut
93
93
  // Open modal
94
94
  sdk.open({
95
95
  teamSlug: 'your-team-slug',
96
- externalEventId: 'event-123',
96
+ momentSlug: 'event-123',
97
97
  triggerType: 'moment',
98
98
  ids: ['moment-id-1'],
99
99
  calendar: 'google', // optional: skip provider selection
@@ -120,7 +120,7 @@ Programmatically create a styled trigger button:
120
120
  <script>
121
121
  const btn = createMomentButton({
122
122
  teamSlug: 'your-team-slug',
123
- externalEventId: 'event-001',
123
+ momentSlug: 'event-001',
124
124
  triggerType: 'moment',
125
125
  label: 'Add to Calendar',
126
126
  });
@@ -161,7 +161,7 @@ You can customize trigger button appearance in a few ways:
161
161
  <script>
162
162
  const primaryBtn = createMomentButton({
163
163
  teamSlug: 'your-team-slug',
164
- externalEventId: 'event-001',
164
+ momentSlug: 'event-001',
165
165
  triggerType: 'moment',
166
166
  label: 'Get Tickets + Calendar',
167
167
  className: 'my-calendar-btn',
@@ -177,7 +177,7 @@ You can also create plain HTML triggers and fully own styles/text:
177
177
  <button
178
178
  class="my-calendar-btn moment-sync-trigger"
179
179
  data-moment-team-slug="your-team-slug"
180
- data-external-event-id="event-001"
180
+ data-moment-slug="event-001"
181
181
  data-moment-trigger-type="moment"
182
182
  >
183
183
  Add This Match to My Calendar
@@ -221,7 +221,7 @@ All callbacks (`onSuccess`, `onError`, `onClose`) receive a result payload:
221
221
  "type": "moment.embed.result",
222
222
  "result": "success | error | cancelled",
223
223
  "provider": "google | outlook",
224
- "triggerType": "moment | list | schedule",
224
+ "triggerType": "moment | list | team",
225
225
  "momentIds": ["..."],
226
226
  "message": "optional details"
227
227
  }
@@ -1 +1 @@
1
- (function(u){"use strict";class g{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),s=Math.round(window.screenX+(window.outerWidth-500)/2),r=Math.round(window.screenY+(window.outerHeight-700)/2);if(this.popup=window.open(t,"moment-oauth-popup",`width=500,height=700,left=${s},top=${r},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=i=>{if(i.origin!==this.opts.liveOrigin||i.source!==this.popup)return;const o=i.data;!o||typeof o!="object"||o.source!=="moment-live-embed"||o.type!=="moment.embed.result"||(this.resultReceived=!0,this.sendStatusToIframe("completed"),this.opts.iframeWindow&&this.opts.iframeWindow.postMessage(o,this.opts.liveOrigin),this.opts.onResult(o),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,s=new URLSearchParams({provider:e.provider,teamSlug:e.teamSlug,ids:e.ids.join(","),triggerType:e.triggerType,returnOrigin:t});return`${this.opts.liveBaseUrl}/en/embed/oauth-popup?${s.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)}}const f=".moment-sync-trigger",v="https://live.dev.momentco.ai";class m{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:f,...e},this.liveBaseUrl=v;try{this.liveOrigin=new URL(this.liveBaseUrl).origin}catch{throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`)}this.bindTriggers(),this.emitAnalytics("embed.init")}open(e){this.emitAnalytics("embed.open",{teamSlug:e.teamSlug,triggerType:e.triggerType}),this.createModal(e)}close(){this.handleCancel()}rebind(){this.unbindTriggers(),this.bindTriggers()}destroy(){this.cleanup(),this.unbindTriggers()}bindTriggers(){document.querySelectorAll(this.opts.triggerSelector).forEach(t=>{const s=i=>{i.preventDefault(),this.handleTriggerClick(t)},r=this.boundClickHandlers.get(t);r&&t.removeEventListener("click",r),t.addEventListener("click",s),this.boundClickHandlers.set(t,s)})}unbindTriggers(){this.boundClickHandlers.forEach((e,t)=>{t.removeEventListener("click",e)}),this.boundClickHandlers.clear()}handleTriggerClick(e){const t=e.getAttribute("data-moment-team-slug")??"",s=e.getAttribute("data-external-event-id")??void 0,r=e.getAttribute("data-moment-list-slug")??void 0,i=e.getAttribute("data-moment-trigger-type");let o="moment";i!=null&&i!==""&&(i==="moment"||i==="list"||i==="schedule"?o=i:console.warn("[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",i));const l=e.getAttribute("data-moment-ids")??e.getAttribute("data-moment-game-id")??"",d=l?l.split(",").filter(Boolean):[],a=e.getAttribute("data-moment-calendar");let c;if(a!=null&&a!==""&&(a==="google"||a==="outlook"?c=a:console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:",a)),!t){console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");return}this.emitAnalytics("embed.trigger.click",{teamSlug:t,triggerType:o,momentIds:d}),this.open({teamSlug:t,externalEventId:s,listSlug:r,triggerType:o,ids:d,calendar:c??void 0})}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 s=l=>{l.key==="Escape"&&this.handleCancel()};document.addEventListener("keydown",s);const r=document.createElement("div");r.setAttribute("role","dialog"),r.setAttribute("aria-modal","true"),r.setAttribute("aria-label","Calendar sync modal"),r.tabIndex=-1,Object.assign(r.style,{position:"relative",width:"100%",maxWidth:"420px",maxHeight:"90vh",borderRadius:"16px",overflow:"hidden",backgroundColor:"#ffffff",boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)"});const i=document.createElement("button");i.type="button",i.textContent="ⓧ",i.setAttribute("aria-label","Close"),Object.assign(i.style,{position:"absolute",top:"8px",right:"8px",zIndex:"10",border:"none",backgroundColor:"transparent",color:"#999",fontSize:"20px",lineHeight:"1",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}),i.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"),Object.assign(this.iframe.style,{width:"100%",height:"480px",border:"none",display:"block"}),r.appendChild(i),r.appendChild(this.iframe),this.overlay.appendChild(r),document.body.appendChild(this.overlay);const o=l=>{if(l.key!=="Tab")return;const d=r.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(d.length===0){l.preventDefault(),r.focus();return}const a=d[0],c=d[d.length-1],h=document.activeElement;l.shiftKey&&h===a?(l.preventDefault(),c.focus()):!l.shiftKey&&h===c&&(l.preventDefault(),a.focus())};r.addEventListener("keydown",o),i.focus(),this.previousBodyOverflow=document.body.style.overflow,document.body.style.overflow="hidden",this.didManageBodyOverflow=!0,this.setupMessageListener(),this.overlay._escHandler=s,this.overlay._focusTrapHandler=o}buildIframeUrl(e){const t=new URLSearchParams;return t.set("teamSlug",e.teamSlug),e.externalEventId&&t.set("momentSlug",e.externalEventId),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),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 s=t;this.emitAnalytics("oauth.start",{provider:s.provider,teamSlug:s.teamSlug}),this.handleOAuthStart(s);return}if(t.source==="moment-live-embed"&&t.type==="moment.embed.result"){const s=t;this.handleResult(s)}}},window.addEventListener("message",this.messageHandler)}handleOAuthStart(e){this.popupBridge&&(this.popupBridge.cleanup(),this.popupBridge=null),this.popupBridge=new g({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 s=this.overlay.firstElementChild;s&&t&&s.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 p(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)}),Object.assign(e.style,{backgroundColor:"#1c1917",color:"#ffffff",border:"1px solid #292524",borderRadius:"4px",padding:"8px 16px",fontSize:"14px",fontWeight:"500",cursor:"pointer",lineHeight:"1.4"}),e.setAttribute("data-moment-team-slug",n.teamSlug),n.externalEventId&&e.setAttribute("data-external-event-id",n.externalEventId),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),e.textContent=n.label??"Add to Calendar",e}if(typeof window<"u"){const n=window;n.MomentSdk=m,n.createMomentButton=p}u.MomentSdk=m,u.createMomentButton=p,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})})(this.MomentSdk=this.MomentSdk||{});
1
+ (function(m){"use strict";class f{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)}}const v=".moment-sync-trigger",b="https://live.dev.momentco.ai";class p{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:v,...e},this.liveBaseUrl=b;try{this.liveOrigin=new URL(this.liveBaseUrl).origin}catch{throw new Error(`[MomentSdk] Invalid VITE_LIVE_BASE_URL: "${this.liveBaseUrl}"`)}this.bindTriggers(),this.emitAnalytics("embed.init")}open(e){this.emitAnalytics("embed.open",{teamSlug:e.teamSlug,triggerType:e.triggerType}),this.createModal(e)}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"?r=s:console.warn("[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",s));const l=e.getAttribute("data-moment-ids")??e.getAttribute("data-moment-game-id")??"",d=l?l.split(",").filter(Boolean):[],a=e.getAttribute("data-moment-calendar");let u;if(a!=null&&a!==""&&(a==="google"||a==="outlook"?u=a:console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:",a)),!t){console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");return}const c=r==="team"?void 0:i,y=r==="team"?void 0:o,g=r==="team"?[]:d;this.emitAnalytics("embed.trigger.click",{teamSlug:t,triggerType:r,momentIds:g}),this.open({teamSlug:t,momentSlug:c,listSlug:y,triggerType:r,ids:g,calendar:u??void 0})}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");o.setAttribute("role","dialog"),o.setAttribute("aria-modal","true"),o.setAttribute("aria-label","Calendar sync modal"),o.tabIndex=-1,Object.assign(o.style,{position:"relative",width:"100%",maxWidth:"420px",maxHeight:"90vh",borderRadius:"16px",overflow:"hidden",backgroundColor:"#ffffff",boxShadow:"0 25px 50px -12px rgba(0, 0, 0, 0.25)"});const s=document.createElement("button");s.type="button",s.textContent="ⓧ",s.setAttribute("aria-label","Close"),Object.assign(s.style,{position:"absolute",top:"8px",right:"8px",zIndex:"10",border:"none",backgroundColor:"transparent",color:"#999",fontSize:"20px",lineHeight:"1",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}),s.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"),Object.assign(this.iframe.style,{width:"100%",height:"480px",border:"none",display:"block"}),o.appendChild(s),o.appendChild(this.iframe),this.overlay.appendChild(o),document.body.appendChild(this.overlay);const r=l=>{if(l.key!=="Tab")return;const d=o.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(d.length===0){l.preventDefault(),o.focus();return}const a=d[0],u=d[d.length-1],c=document.activeElement;l.shiftKey&&c===a?(l.preventDefault(),u.focus()):!l.shiftKey&&c===u&&(l.preventDefault(),a.focus())};o.addEventListener("keydown",r),s.focus(),this.previousBodyOverflow=document.body.style.overflow,document.body.style.overflow="hidden",this.didManageBodyOverflow=!0,this.setupMessageListener(),this.overlay._escHandler=i,this.overlay._focusTrapHandler=r}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),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.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 f({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 h(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)}),Object.assign(e.style,{backgroundColor:"#1c1917",color:"#ffffff",border:"1px solid #292524",borderRadius:"4px",padding:"8px 16px",fontSize:"14px",fontWeight:"500",cursor:"pointer",lineHeight:"1.4"}),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),e.textContent=n.label??"Add to Calendar",e}if(typeof window<"u"){const n=window;n.MomentSdk=p,n.createMomentButton=h}m.MomentSdk=p,m.createMomentButton=h,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})})(this.MomentSdk=this.MomentSdk||{});
@@ -1,4 +1,4 @@
1
- class m {
1
+ class h {
2
2
  popup = null;
3
3
  pollTimer = null;
4
4
  messageHandler = null;
@@ -12,19 +12,19 @@ class m {
12
12
  */
13
13
  open(e) {
14
14
  this.cleanup(), this.resultReceived = !1;
15
- const t = this.buildPopupUrl(e), s = Math.round(window.screenX + (window.outerWidth - 500) / 2), r = Math.round(window.screenY + (window.outerHeight - 700) / 2);
15
+ const t = this.buildPopupUrl(e), i = Math.round(window.screenX + (window.outerWidth - 500) / 2), o = Math.round(window.screenY + (window.outerHeight - 700) / 2);
16
16
  if (this.popup = window.open(
17
17
  t,
18
18
  "moment-oauth-popup",
19
- `width=500,height=700,left=${s},top=${r},menubar=no,toolbar=no,location=yes,status=no`
19
+ `width=500,height=700,left=${i},top=${o},menubar=no,toolbar=no,location=yes,status=no`
20
20
  ), !this.popup || this.popup.closed) {
21
21
  this.sendStatusToIframe("popup-blocked"), this.opts.onPopupBlocked();
22
22
  return;
23
23
  }
24
- this.sendStatusToIframe("popup-opened"), this.startPolling(), this.messageHandler = (i) => {
25
- if (i.origin !== this.opts.liveOrigin || i.source !== this.popup) return;
26
- const o = i.data;
27
- !o || typeof o != "object" || o.source !== "moment-live-embed" || o.type !== "moment.embed.result" || (this.resultReceived = !0, this.sendStatusToIframe("completed"), this.opts.iframeWindow && this.opts.iframeWindow.postMessage(o, this.opts.liveOrigin), this.opts.onResult(o), this.cleanup());
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
+ !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
  }
30
30
  /**
@@ -39,14 +39,14 @@ class m {
39
39
  this.popup = null;
40
40
  }
41
41
  buildPopupUrl(e) {
42
- const t = window.location.origin, s = new URLSearchParams({
42
+ const t = window.location.origin, i = new URLSearchParams({
43
43
  provider: e.provider,
44
44
  teamSlug: e.teamSlug,
45
45
  ids: e.ids.join(","),
46
46
  triggerType: e.triggerType,
47
47
  returnOrigin: t
48
48
  });
49
- return `${this.opts.liveBaseUrl}/en/embed/oauth-popup?${s.toString()}`;
49
+ return e.subscriptionType && i.set("subscriptionType", e.subscriptionType), `${this.opts.liveBaseUrl}/en/embed/oauth-popup?${i.toString()}`;
50
50
  }
51
51
  startPolling() {
52
52
  this.pollTimer = setInterval(() => {
@@ -63,8 +63,8 @@ class m {
63
63
  this.opts.iframeWindow.postMessage(t, this.opts.liveOrigin);
64
64
  }
65
65
  }
66
- const p = ".moment-sync-trigger", h = "https://live.dev.momentco.ai";
67
- class g {
66
+ const g = ".moment-sync-trigger", f = "https://live.dev.momentco.ai";
67
+ class v {
68
68
  opts;
69
69
  liveBaseUrl;
70
70
  liveOrigin;
@@ -80,9 +80,9 @@ class g {
80
80
  closeTimer = null;
81
81
  constructor(e) {
82
82
  this.opts = {
83
- triggerSelector: p,
83
+ triggerSelector: g,
84
84
  ...e
85
- }, this.liveBaseUrl = h;
85
+ }, this.liveBaseUrl = f;
86
86
  try {
87
87
  this.liveOrigin = new URL(this.liveBaseUrl).origin;
88
88
  } catch {
@@ -120,10 +120,10 @@ class g {
120
120
  // ── Private: trigger binding ──────────────────────────────────────
121
121
  bindTriggers() {
122
122
  document.querySelectorAll(this.opts.triggerSelector).forEach((t) => {
123
- const s = (i) => {
124
- i.preventDefault(), this.handleTriggerClick(t);
125
- }, r = this.boundClickHandlers.get(t);
126
- r && t.removeEventListener("click", r), t.addEventListener("click", s), this.boundClickHandlers.set(t, s);
123
+ const i = (s) => {
124
+ s.preventDefault(), this.handleTriggerClick(t);
125
+ }, o = this.boundClickHandlers.get(t);
126
+ o && t.removeEventListener("click", o), t.addEventListener("click", i), this.boundClickHandlers.set(t, i);
127
127
  });
128
128
  }
129
129
  unbindTriggers() {
@@ -132,29 +132,30 @@ class g {
132
132
  }), this.boundClickHandlers.clear();
133
133
  }
134
134
  handleTriggerClick(e) {
135
- const t = e.getAttribute("data-moment-team-slug") ?? "", s = e.getAttribute("data-external-event-id") ?? void 0, r = e.getAttribute("data-moment-list-slug") ?? void 0, i = e.getAttribute("data-moment-trigger-type");
136
- let o = "moment";
137
- i != null && i !== "" && (i === "moment" || i === "list" || i === "schedule" ? o = i : console.warn(
135
+ 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");
136
+ let r = "moment";
137
+ s != null && s !== "" && (s === "moment" || s === "list" || s === "team" ? r = s : console.warn(
138
138
  "[MomentSdk] Invalid data-moment-trigger-type, falling back to 'moment':",
139
- i
139
+ s
140
140
  ));
141
141
  const l = e.getAttribute("data-moment-ids") ?? e.getAttribute("data-moment-game-id") ?? "", d = l ? l.split(",").filter(Boolean) : [], a = e.getAttribute("data-moment-calendar");
142
- let c;
143
- if (a != null && a !== "" && (a === "google" || a === "outlook" ? c = a : console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:", a)), !t) {
142
+ let u;
143
+ if (a != null && a !== "" && (a === "google" || a === "outlook" ? u = a : console.warn("[MomentSdk] Invalid data-moment-calendar, ignoring value:", a)), !t) {
144
144
  console.warn("[MomentSdk] Missing data-moment-team-slug on trigger element");
145
145
  return;
146
146
  }
147
+ const c = r === "team" ? void 0 : i, p = r === "team" ? void 0 : o, m = r === "team" ? [] : d;
147
148
  this.emitAnalytics("embed.trigger.click", {
148
149
  teamSlug: t,
149
- triggerType: o,
150
- momentIds: d
150
+ triggerType: r,
151
+ momentIds: m
151
152
  }), this.open({
152
153
  teamSlug: t,
153
- externalEventId: s,
154
- listSlug: r,
155
- triggerType: o,
156
- ids: d,
157
- calendar: c ?? void 0
154
+ momentSlug: c,
155
+ listSlug: p,
156
+ triggerType: r,
157
+ ids: m,
158
+ calendar: u ?? void 0
158
159
  });
159
160
  }
160
161
  // ── Private: modal creation ───────────────────────────────────────
@@ -174,12 +175,12 @@ class g {
174
175
  }), this.overlay.addEventListener("click", (l) => {
175
176
  l.target === this.overlay && this.handleCancel();
176
177
  });
177
- const s = (l) => {
178
+ const i = (l) => {
178
179
  l.key === "Escape" && this.handleCancel();
179
180
  };
180
- document.addEventListener("keydown", s);
181
- const r = document.createElement("div");
182
- r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "true"), r.setAttribute("aria-label", "Calendar sync modal"), r.tabIndex = -1, Object.assign(r.style, {
181
+ document.addEventListener("keydown", i);
182
+ const o = document.createElement("div");
183
+ o.setAttribute("role", "dialog"), o.setAttribute("aria-modal", "true"), o.setAttribute("aria-label", "Calendar sync modal"), o.tabIndex = -1, Object.assign(o.style, {
183
184
  position: "relative",
184
185
  width: "100%",
185
186
  maxWidth: "420px",
@@ -189,8 +190,8 @@ class g {
189
190
  backgroundColor: "#ffffff",
190
191
  boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
191
192
  });
192
- const i = document.createElement("button");
193
- i.type = "button", i.textContent = "ⓧ", i.setAttribute("aria-label", "Close"), Object.assign(i.style, {
193
+ const s = document.createElement("button");
194
+ s.type = "button", s.textContent = "ⓧ", s.setAttribute("aria-label", "Close"), Object.assign(s.style, {
194
195
  position: "absolute",
195
196
  top: "8px",
196
197
  right: "8px",
@@ -204,29 +205,29 @@ class g {
204
205
  display: "flex",
205
206
  alignItems: "center",
206
207
  justifyContent: "center"
207
- }), i.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"), Object.assign(this.iframe.style, {
208
+ }), s.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"), Object.assign(this.iframe.style, {
208
209
  width: "100%",
209
210
  height: "480px",
210
211
  border: "none",
211
212
  display: "block"
212
- }), r.appendChild(i), r.appendChild(this.iframe), this.overlay.appendChild(r), document.body.appendChild(this.overlay);
213
- const o = (l) => {
213
+ }), o.appendChild(s), o.appendChild(this.iframe), this.overlay.appendChild(o), document.body.appendChild(this.overlay);
214
+ const r = (l) => {
214
215
  if (l.key !== "Tab") return;
215
- const d = r.querySelectorAll(
216
+ const d = o.querySelectorAll(
216
217
  'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
217
218
  );
218
219
  if (d.length === 0) {
219
- l.preventDefault(), r.focus();
220
+ l.preventDefault(), o.focus();
220
221
  return;
221
222
  }
222
- const a = d[0], c = d[d.length - 1], u = document.activeElement;
223
- l.shiftKey && u === a ? (l.preventDefault(), c.focus()) : !l.shiftKey && u === c && (l.preventDefault(), a.focus());
223
+ const a = d[0], u = d[d.length - 1], c = document.activeElement;
224
+ l.shiftKey && c === a ? (l.preventDefault(), u.focus()) : !l.shiftKey && c === u && (l.preventDefault(), a.focus());
224
225
  };
225
- r.addEventListener("keydown", o), i.focus(), this.previousBodyOverflow = document.body.style.overflow, document.body.style.overflow = "hidden", this.didManageBodyOverflow = !0, this.setupMessageListener(), this.overlay._escHandler = s, this.overlay._focusTrapHandler = o;
226
+ o.addEventListener("keydown", r), s.focus(), this.previousBodyOverflow = document.body.style.overflow, document.body.style.overflow = "hidden", this.didManageBodyOverflow = !0, this.setupMessageListener(), this.overlay._escHandler = i, this.overlay._focusTrapHandler = r;
226
227
  }
227
228
  buildIframeUrl(e) {
228
229
  const t = new URLSearchParams();
229
- return t.set("teamSlug", e.teamSlug), e.externalEventId && t.set("momentSlug", e.externalEventId), 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), t.set("returnOrigin", window.location.origin), t.set("embed", "1"), `${this.liveBaseUrl}/en/embed/sync?${t.toString()}`;
230
+ 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), t.set("returnOrigin", window.location.origin), t.set("embed", "1"), `${this.liveBaseUrl}/en/embed/sync?${t.toString()}`;
230
231
  }
231
232
  // ── Private: message handling ─────────────────────────────────────
232
233
  setupMessageListener() {
@@ -235,22 +236,22 @@ class g {
235
236
  const t = e.data;
236
237
  if (!(!t || typeof t != "object")) {
237
238
  if (t.source === "moment-live-embed" && t.type === "moment.embed.oauth.start") {
238
- const s = t;
239
+ const i = t;
239
240
  this.emitAnalytics("oauth.start", {
240
- provider: s.provider,
241
- teamSlug: s.teamSlug
242
- }), this.handleOAuthStart(s);
241
+ provider: i.provider,
242
+ teamSlug: i.teamSlug
243
+ }), this.handleOAuthStart(i);
243
244
  return;
244
245
  }
245
246
  if (t.source === "moment-live-embed" && t.type === "moment.embed.result") {
246
- const s = t;
247
- this.handleResult(s);
247
+ const i = t;
248
+ this.handleResult(i);
248
249
  }
249
250
  }
250
251
  }, window.addEventListener("message", this.messageHandler);
251
252
  }
252
253
  handleOAuthStart(e) {
253
- this.popupBridge && (this.popupBridge.cleanup(), this.popupBridge = null), this.popupBridge = new m({
254
+ this.popupBridge && (this.popupBridge.cleanup(), this.popupBridge = null), this.popupBridge = new h({
254
255
  liveBaseUrl: this.liveBaseUrl,
255
256
  liveOrigin: this.liveOrigin,
256
257
  iframeWindow: this.iframe?.contentWindow ?? null,
@@ -302,8 +303,8 @@ class g {
302
303
  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) {
303
304
  const { _escHandler: e, _focusTrapHandler: t } = this.overlay;
304
305
  e && document.removeEventListener("keydown", e);
305
- const s = this.overlay.firstElementChild;
306
- s && t && s.removeEventListener("keydown", t), this.overlay.remove(), this.overlay = null;
306
+ const i = this.overlay.firstElementChild;
307
+ i && t && i.removeEventListener("keydown", t), this.overlay.remove(), this.overlay = null;
307
308
  }
308
309
  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;
309
310
  }
@@ -316,7 +317,7 @@ class g {
316
317
  });
317
318
  }
318
319
  }
319
- function f(n) {
320
+ function b(n) {
320
321
  const e = document.createElement("button");
321
322
  return e.type = "button", e.classList.add("moment-sync-trigger"), n.className && n.className.split(" ").forEach((t) => {
322
323
  t && e.classList.add(t);
@@ -330,13 +331,13 @@ function f(n) {
330
331
  fontWeight: "500",
331
332
  cursor: "pointer",
332
333
  lineHeight: "1.4"
333
- }), e.setAttribute("data-moment-team-slug", n.teamSlug), n.externalEventId && e.setAttribute("data-external-event-id", n.externalEventId), 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), e.textContent = n.label ?? "Add to Calendar", e;
334
+ }), 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), e.textContent = n.label ?? "Add to Calendar", e;
334
335
  }
335
336
  if (typeof window < "u") {
336
337
  const n = window;
337
- n.MomentSdk = g, n.createMomentButton = f;
338
+ n.MomentSdk = v, n.createMomentButton = b;
338
339
  }
339
340
  export {
340
- g as MomentSdk,
341
- f as createMomentButton
341
+ v as MomentSdk,
342
+ b as createMomentButton
342
343
  };
@@ -5,7 +5,8 @@ import type { MomentTriggerType, CalendarProvider } from './types';
5
5
  */
6
6
  export declare function createMomentButton(options: {
7
7
  teamSlug: string;
8
- externalEventId?: string;
8
+ /** Brand-level moment slug. */
9
+ momentSlug?: string;
9
10
  listSlug?: string;
10
11
  triggerType?: MomentTriggerType;
11
12
  ids?: string[];
@@ -1,4 +1,12 @@
1
- export type MomentTriggerType = 'moment' | 'list' | 'schedule';
1
+ /**
2
+ * Subscription target type forwarded to the Live embed and ultimately mapped
3
+ * to the backend `subscriptionType`.
4
+ *
5
+ * - `moment` → subscribe to one or more specific moments
6
+ * - `list` → subscribe to a curated list of moments
7
+ * - `team` → subscribe to a team / brand schedule (all published moments)
8
+ */
9
+ export type MomentTriggerType = 'moment' | 'list' | 'team';
2
10
  export type CalendarProvider = 'google' | 'outlook';
3
11
  export interface MomentSdkInitOptions {
4
12
  /** CSS selector for trigger elements. Default: ".moment-sync-trigger" */
@@ -12,14 +20,29 @@ export interface MomentSdkInitOptions {
12
20
  /** Optional analytics callback for tracking embed events. */
13
21
  onAnalytics?: (event: MomentAnalyticsEvent) => void;
14
22
  }
23
+ /**
24
+ * Payload accepted by `MomentSdk.open()` and parsed from trigger element
25
+ * `data-moment-*` attributes.
26
+ *
27
+ * Required fields by `triggerType`:
28
+ * - `moment` → `teamSlug` plus EITHER `momentSlug` (brand-level moment slug)
29
+ * OR `ids`
30
+ * - `list` → `teamSlug` plus `listSlug` (`ids` not required — list resolves
31
+ * to a single list-level subscription)
32
+ * - `team` → `teamSlug` only (resolves to the brand's team-level
33
+ * subscription; `listSlug`, `momentSlug`, and `ids` are ignored)
34
+ */
15
35
  export interface MomentSdkOpenPayload {
16
36
  teamSlug: string;
17
- externalEventId?: string;
37
+ /** Brand-level moment slug. */
38
+ momentSlug?: string;
18
39
  listSlug?: string;
19
40
  triggerType: MomentTriggerType;
20
41
  ids?: string[];
21
42
  calendar?: CalendarProvider;
22
43
  }
44
+ /** Backend subscription resource type that the embed will create */
45
+ export type MomentSubscriptionType = 'moment' | 'list' | 'team';
23
46
  /** Iframe → Parent: request to start OAuth via popup */
24
47
  export interface MomentOAuthStartPayload {
25
48
  source: 'moment-live-embed';
@@ -28,6 +51,14 @@ export interface MomentOAuthStartPayload {
28
51
  teamSlug: string;
29
52
  ids: string[];
30
53
  triggerType: MomentTriggerType;
54
+ /**
55
+ * Authoritative backend subscription type for `ids`.
56
+ * The iframe is the single source of truth: when present this should be
57
+ * forwarded verbatim to the popup so the popup does not need to re-derive
58
+ * it from `triggerType` (which would mis-handle cherry-picked moment IDs
59
+ * under a `list`/`team` trigger).
60
+ */
61
+ subscriptionType?: MomentSubscriptionType;
31
62
  returnOrigin: string;
32
63
  }
33
64
  /** Parent → Iframe: relay OAuth popup status */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momentco-ai/moment-sdk",
3
- "version": "0.1.2-dev.10",
3
+ "version": "0.2.0-dev.12",
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)",