UNPKG

tsdav

Version:

WebDAV, CALDAV, and CARDDAV client for Nodejs and the Browser

2 lines (1 loc) 37.5 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("cross-fetch/polyfill");var e,t=require("debug"),r=require("xml-js"),a=require("base-64");exports.DAVNamespace=void 0,(e=exports.DAVNamespace||(exports.DAVNamespace={})).CALENDAR_SERVER="http://calendarserver.org/ns/",e.CALDAV_APPLE="http://apple.com/ns/ical/",e.CALDAV="urn:ietf:params:xml:ns:caldav",e.CARDDAV="urn:ietf:params:xml:ns:carddav",e.DAV="DAV:";const s={[exports.DAVNamespace.CALDAV]:"xmlns:c",[exports.DAVNamespace.CARDDAV]:"xmlns:card",[exports.DAVNamespace.CALENDAR_SERVER]:"xmlns:cs",[exports.DAVNamespace.CALDAV_APPLE]:"xmlns:ca",[exports.DAVNamespace.DAV]:"xmlns:d"};var o,n;exports.DAVNamespaceShort=void 0,(o=exports.DAVNamespaceShort||(exports.DAVNamespaceShort={})).CALDAV="c",o.CARDDAV="card",o.CALENDAR_SERVER="cs",o.CALDAV_APPLE="ca",o.DAV="d",function(e){e.VEVENT="VEVENT",e.VTODO="VTODO",e.VJOURNAL="VJOURNAL",e.VFREEBUSY="VFREEBUSY",e.VTIMEZONE="VTIMEZONE",e.VALARM="VALARM"}(n||(n={}));const c=e=>{const t=Number(e);if(!Number.isNaN(t))return t;const r=e.toLowerCase();return"true"===r||"false"!==r&&e},d=(e,t)=>{if(!e&&!t)return!0;if(!e||!t)return!1;const r=e.trim(),a=t.trim();if(Math.abs(r.length-a.length)>1)return!1;const s="/"===r.slice(-1)?r.slice(0,-1):r,o="/"===a.slice(-1)?a.slice(0,-1):a;return e.includes(o)||t.includes(s)},i=(e,t)=>{if(!e&&!t)return!0;if(!e||!t)return!1;const r=e.trim(),a=t.trim(),s="/"===r.slice(-1)?r.slice(0,-1):r,o="/"===a.slice(-1)?a.slice(0,-1):a;return e.includes(o)||t.includes(s)},l=e=>e.reduce(((e,t)=>({...e,[s[t]]:t})),{}),p=e=>Object.entries(e).reduce(((e,[t,r])=>r?{...e,[t]:r}:e),{}),h=(e,t)=>t?{[e]:t}:{},u=(e,t)=>e?t&&0!==t.length?Object.fromEntries(Object.entries(e).filter((([e])=>!t.includes(e)))):e:{};var f=Object.freeze({__proto__:null,cleanupFalsy:p,conditionalParam:h,excludeHeaders:u,getDAVAttribute:l,urlContains:i,urlEquals:d});const m=t("tsdav:request"),A=async e=>{var t;const{url:a,init:s,convertIncoming:o=!0,parseOutgoing:n=!0,fetchOptions:d={}}=e,{headers:i={},body:l,namespace:h,method:u,attributes:f}=s,A=o?r.js2xml({_declaration:{_attributes:{version:"1.0",encoding:"utf-8"}},...l,_attributes:f},{compact:!0,spaces:2,elementNameFn:e=>h&&!/^.+:.+/.test(e)?`${h}:${e}`:e}):l,v=await fetch(a,{headers:{"Content-Type":"text/xml;charset=UTF-8",...p(i)},body:A,method:u,...d}),D=await v.text();if(!v.ok||!(null===(t=v.headers.get("content-type"))||void 0===t?void 0:t.includes("xml"))||!n)return[{href:v.url,ok:v.ok,status:v.status,statusText:v.statusText,raw:D}];const y=r.xml2js(D,{compact:!0,trim:!0,textFn:(e,t)=>{try{const r=t._parent,a=Object.keys(r),s=a[a.length-1],o=r[s];if(o.length>0){o[o.length-1]=c(e)}else r[s]=c(e)}catch(e){m(e.stack)}},elementNameFn:e=>e.replace(/^.+:/,"").replace(/([-_]\w)/g,(e=>e[1].toUpperCase())),attributesFn:e=>{const t={...e};return delete t.xmlns,t},ignoreDeclaration:!0});return(Array.isArray(y.multistatus.response)?y.multistatus.response:[y.multistatus.response]).map((e=>{var t,r;if(!e)return{status:v.status,statusText:v.statusText,ok:v.ok};const a=/^\S+\s(?<status>\d+)\s(?<statusText>.+)$/.exec(e.status);return{raw:y,href:e.href,status:(null==a?void 0:a.groups)?Number.parseInt(null==a?void 0:a.groups.status,10):v.status,statusText:null!==(r=null===(t=null==a?void 0:a.groups)||void 0===t?void 0:t.statusText)&&void 0!==r?r:v.statusText,ok:!e.error,error:e.error,responsedescription:e.responsedescription,props:(Array.isArray(e.propstat)?e.propstat:[e.propstat]).reduce(((e,t)=>({...e,...null==t?void 0:t.prop})),{})}}))},v=async e=>{const{url:t,props:r,depth:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e;return A({url:t,init:{method:"PROPFIND",headers:u(p({depth:a,...s}),o),namespace:exports.DAVNamespaceShort.DAV,body:{propfind:{_attributes:l([exports.DAVNamespace.CALDAV,exports.DAVNamespace.CALDAV_APPLE,exports.DAVNamespace.CALENDAR_SERVER,exports.DAVNamespace.CARDDAV,exports.DAVNamespace.DAV]),prop:r}}},fetchOptions:n})},D=async e=>{const{url:t,data:r,headers:a,headersToExclude:s,fetchOptions:o={}}=e;return fetch(t,{method:"PUT",body:r,headers:u(a,s),...o})},y=async e=>{const{url:t,data:r,etag:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e;return fetch(t,{method:"PUT",body:r,headers:u(p({"If-Match":a,...s}),o),...n})},O=async e=>{const{url:t,headers:r,etag:a,headersToExclude:s,fetchOptions:o={}}=e;return fetch(t,{method:"DELETE",headers:u(p({"If-Match":a,...r}),s),...o})};var V=Object.freeze({__proto__:null,createObject:D,davRequest:A,deleteObject:O,propfind:v,updateObject:y});function x(e,t){const r=e=>t.every((t=>e[t]));return Array.isArray(e)?e.every((e=>r(e))):r(e)}const C=(e,t)=>t.reduce(((t,r)=>e[r]?t:`${t.length?`${t},`:""}${r.toString()}`),""),g=t("tsdav:collection"),b=async e=>{const{url:t,body:r,depth:a,defaultNamespace:s=exports.DAVNamespaceShort.DAV,headers:o,headersToExclude:n,fetchOptions:c={}}=e,d=await A({url:t,init:{method:"REPORT",headers:u(p({depth:a,...o}),n),namespace:s,body:r},fetchOptions:c});return 1!==d.length||d[0].raw?d:[]},w=async e=>{const{url:t,props:r,depth:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e;return A({url:t,init:{method:"MKCOL",headers:u(p({depth:a,...s}),o),namespace:exports.DAVNamespaceShort.DAV,body:r?{mkcol:{set:{prop:r}}}:void 0},fetchOptions:n})},S=async e=>{var t,r,a,s,o;const{collection:n,headers:c,headersToExclude:d,fetchOptions:i={}}=e;return null!==(o=null===(s=null===(a=null===(r=null===(t=(await v({url:n.url,props:{[`${exports.DAVNamespaceShort.DAV}:supported-report-set`]:{}},depth:"0",headers:u(c,d),fetchOptions:i}))[0])||void 0===t?void 0:t.props)||void 0===r?void 0:r.supportedReportSet)||void 0===a?void 0:a.supportedReport)||void 0===s?void 0:s.map((e=>Object.keys(e.report)[0])))&&void 0!==o?o:[]},N=async e=>{var t,r,a;const{collection:s,headers:o,headersToExclude:n,fetchOptions:c={}}=e,d=(await v({url:s.url,props:{[`${exports.DAVNamespaceShort.CALENDAR_SERVER}:getctag`]:{}},depth:"0",headers:u(o,n),fetchOptions:c})).filter((e=>i(s.url,e.href)))[0];if(!d)throw new Error("Collection does not exist on server");return{isDirty:`${s.ctag}`!=`${null===(t=d.props)||void 0===t?void 0:t.getctag}`,newCtag:null===(a=null===(r=d.props)||void 0===r?void 0:r.getctag)||void 0===a?void 0:a.toString()}},$=e=>{const{url:t,props:r,headers:a,syncLevel:s,syncToken:o,headersToExclude:n,fetchOptions:c}=e;return A({url:t,init:{method:"REPORT",namespace:exports.DAVNamespaceShort.DAV,headers:u({...a},n),body:{"sync-collection":{_attributes:l([exports.DAVNamespace.CALDAV,exports.DAVNamespace.CARDDAV,exports.DAVNamespace.DAV]),"sync-level":s,"sync-token":o,[`${exports.DAVNamespaceShort.DAV}:prop`]:r}}},fetchOptions:c})},E=async e=>{var t,r,a,s,o,n,c,d,l,p,h;const{collection:f,method:m,headers:A,headersToExclude:v,account:D,detailedResult:y,fetchOptions:O={}}=e,V=["accountType","homeUrl"];if(!D||!x(D,V)){if(!D)throw new Error("no account for smartCollectionSync");throw new Error(`account must have ${C(D,V)} before smartCollectionSync`)}const b=null!=m?m:(null===(t=f.reports)||void 0===t?void 0:t.includes("syncCollection"))?"webdav":"basic";if(g(`smart collection sync with type ${D.accountType} and method ${b}`),"webdav"===b){const e=await $({url:f.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{},[`${"caldav"===D.accountType?exports.DAVNamespaceShort.CALDAV:exports.DAVNamespaceShort.CARDDAV}:${"caldav"===D.accountType?"calendar-data":"address-data"}`]:{},[`${exports.DAVNamespaceShort.DAV}:displayname`]:{}},syncLevel:1,syncToken:f.syncToken,headers:u(A,v),fetchOptions:O}),t=e.filter((e=>{var t;const r="caldav"===D.accountType?".ics":".vcf";return(null===(t=e.href)||void 0===t?void 0:t.slice(-4))===r})),l=t.filter((e=>404!==e.status)).map((e=>e.href)),p=t.filter((e=>404===e.status)).map((e=>e.href)),h=(l.length&&null!==(a=await(null===(r=null==f?void 0:f.objectMultiGet)||void 0===r?void 0:r.call(f,{url:f.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{},[`${"caldav"===D.accountType?exports.DAVNamespaceShort.CALDAV:exports.DAVNamespaceShort.CARDDAV}:${"caldav"===D.accountType?"calendar-data":"address-data"}`]:{}},objectUrls:l,depth:"1",headers:u(A,v),fetchOptions:O})))&&void 0!==a?a:[]).map((e=>{var t,r,a,s,o,n,c,d,i,l;return{url:null!==(t=e.href)&&void 0!==t?t:"",etag:null===(r=e.props)||void 0===r?void 0:r.getetag,data:"caldav"===(null==D?void 0:D.accountType)?null!==(o=null===(s=null===(a=e.props)||void 0===a?void 0:a.calendarData)||void 0===s?void 0:s._cdata)&&void 0!==o?o:null===(n=e.props)||void 0===n?void 0:n.calendarData:null!==(i=null===(d=null===(c=e.props)||void 0===c?void 0:c.addressData)||void 0===d?void 0:d._cdata)&&void 0!==i?i:null===(l=e.props)||void 0===l?void 0:l.addressData}})),m=null!==(s=f.objects)&&void 0!==s?s:[],V=h.filter((e=>m.every((t=>!i(t.url,e.url))))),x=m.reduce(((e,t)=>{const r=h.find((e=>i(e.url,t.url)));return r&&r.etag&&r.etag!==t.etag?[...e,r]:e}),[]),C=p.map((e=>({url:e,etag:""}))),g=m.filter((e=>h.some((t=>i(e.url,t.url)&&t.etag===e.etag))));return{...f,objects:y?{created:V,updated:x,deleted:C}:[...g,...V,...x],syncToken:null!==(d=null===(c=null===(n=null===(o=e[0])||void 0===o?void 0:o.raw)||void 0===n?void 0:n.multistatus)||void 0===c?void 0:c.syncToken)&&void 0!==d?d:f.syncToken}}if("basic"===b){const{isDirty:e,newCtag:t}=await N({collection:f,headers:u(A,v),fetchOptions:O}),r=null!==(l=f.objects)&&void 0!==l?l:[],a=null!==(h=await(null===(p=f.fetchObjects)||void 0===p?void 0:p.call(f,{collection:f,headers:u(A,v),fetchOptions:O})))&&void 0!==h?h:[],s=a.filter((e=>r.every((t=>!i(t.url,e.url))))),o=r.reduce(((e,t)=>{const r=a.find((e=>i(e.url,t.url)));return r&&r.etag&&r.etag!==t.etag?[...e,r]:e}),[]),n=r.filter((e=>a.every((t=>!i(t.url,e.url))))),c=r.filter((e=>a.some((t=>i(e.url,t.url)&&t.etag===e.etag))));if(e)return{...f,objects:y?{created:s,updated:o,deleted:n}:[...c,...s,...o],ctag:t}}return y?{...f,objects:{created:[],updated:[],deleted:[]}}:f};var T=Object.freeze({__proto__:null,collectionQuery:b,isCollectionDirty:N,makeCollection:w,smartCollectionSync:E,supportedReportSet:S,syncCollection:$});const k=t("tsdav:addressBook"),U=async e=>{const{url:t,props:r,filters:a,depth:s,headers:o,headersToExclude:n,fetchOptions:c={}}=e;return b({url:t,body:{"addressbook-query":p({_attributes:l([exports.DAVNamespace.CARDDAV,exports.DAVNamespace.DAV]),[`${exports.DAVNamespaceShort.DAV}:prop`]:r,filter:null!=a?a:{"prop-filter":{_attributes:{name:"FN"}}}})},defaultNamespace:exports.DAVNamespaceShort.CARDDAV,depth:s,headers:u(o,n),fetchOptions:c})},_=async e=>{const{url:t,props:r,objectUrls:a,depth:s,headers:o,headersToExclude:n,fetchOptions:c={}}=e;return b({url:t,body:{"addressbook-multiget":p({_attributes:l([exports.DAVNamespace.DAV,exports.DAVNamespace.CARDDAV]),[`${exports.DAVNamespaceShort.DAV}:prop`]:r,[`${exports.DAVNamespaceShort.DAV}:href`]:a})},defaultNamespace:exports.DAVNamespaceShort.CARDDAV,depth:s,headers:u(o,n),fetchOptions:c})},R=async e=>{const{account:t,headers:r,props:a,headersToExclude:s,fetchOptions:o={}}=null!=e?e:{},n=["homeUrl","rootUrl"];if(!t||!x(t,n)){if(!t)throw new Error("no account for fetchAddressBooks");throw new Error(`account must have ${C(t,n)} before fetchAddressBooks`)}const c=await v({url:t.homeUrl,props:null!=a?a:{[`${exports.DAVNamespaceShort.DAV}:displayname`]:{},[`${exports.DAVNamespaceShort.CALENDAR_SERVER}:getctag`]:{},[`${exports.DAVNamespaceShort.DAV}:resourcetype`]:{},[`${exports.DAVNamespaceShort.DAV}:sync-token`]:{}},depth:"1",headers:u(r,s),fetchOptions:o});return Promise.all(c.filter((e=>{var t,r;return Object.keys(null!==(r=null===(t=e.props)||void 0===t?void 0:t.resourcetype)&&void 0!==r?r:{}).includes("addressbook")})).map((e=>{var r,a,s,o,n,c,d,i,l;const p=null!==(s=null===(a=null===(r=e.props)||void 0===r?void 0:r.displayname)||void 0===a?void 0:a._cdata)&&void 0!==s?s:null===(o=e.props)||void 0===o?void 0:o.displayname;return k(`Found address book named ${"string"==typeof p?p:""},\n props: ${JSON.stringify(e.props)}`),{url:new URL(null!==(n=e.href)&&void 0!==n?n:"",null!==(c=t.rootUrl)&&void 0!==c?c:"").href,ctag:null===(d=e.props)||void 0===d?void 0:d.getctag,displayName:"string"==typeof p?p:"",resourcetype:Object.keys(null===(i=e.props)||void 0===i?void 0:i.resourcetype),syncToken:null===(l=e.props)||void 0===l?void 0:l.syncToken}})).map((async e=>({...e,reports:await S({collection:e,headers:u(r,s),fetchOptions:o})}))))},j=async e=>{const{addressBook:t,headers:r,objectUrls:a,headersToExclude:s,urlFilter:o=e=>e,useMultiGet:n=!0,fetchOptions:c={}}=e;k(`Fetching vcards from ${null==t?void 0:t.url}`);const d=["url"];if(!t||!x(t,d)){if(!t)throw new Error("cannot fetchVCards for undefined addressBook");throw new Error(`addressBook must have ${C(t,d)} before fetchVCards`)}const i=(null!=a?a:(await U({url:t.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{}},depth:"1",headers:u(r,s),fetchOptions:c})).map((e=>{var t;return e.ok&&null!==(t=e.href)&&void 0!==t?t:""}))).map((e=>e.startsWith("http")||!e?e:new URL(e,t.url).href)).filter(o).map((e=>new URL(e).pathname));let l=[];return i.length>0&&(l=n?await _({url:t.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{},[`${exports.DAVNamespaceShort.CARDDAV}:address-data`]:{}},objectUrls:i,depth:"1",headers:u(r,s),fetchOptions:c}):await U({url:t.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{},[`${exports.DAVNamespaceShort.CARDDAV}:address-data`]:{}},depth:"1",headers:u(r,s),fetchOptions:c})),l.map((e=>{var r,a,s,o,n,c;return{url:new URL(null!==(r=e.href)&&void 0!==r?r:"",t.url).href,etag:null===(a=e.props)||void 0===a?void 0:a.getetag,data:null!==(n=null===(o=null===(s=e.props)||void 0===s?void 0:s.addressData)||void 0===o?void 0:o._cdata)&&void 0!==n?n:null===(c=e.props)||void 0===c?void 0:c.addressData}}))},L=async e=>{const{addressBook:t,vCardString:r,filename:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e;return D({url:new URL(a,t.url).href,data:r,headers:u({"content-type":"text/vcard; charset=utf-8","If-None-Match":"*",...s},o),fetchOptions:n})},H=async e=>{const{vCard:t,headers:r,headersToExclude:a,fetchOptions:s={}}=e;return y({url:t.url,data:t.data,etag:t.etag,headers:u({"content-type":"text/vcard; charset=utf-8",...r},a),fetchOptions:s})},P=async e=>{const{vCard:t,headers:r,headersToExclude:a,fetchOptions:s={}}=e;return O({url:t.url,etag:t.etag,headers:u(r,a),fetchOptions:s})};var B=Object.freeze({__proto__:null,addressBookMultiGet:_,addressBookQuery:U,createVCard:L,deleteVCard:P,fetchAddressBooks:R,fetchVCards:j,updateVCard:H});const F=t("tsdav:calendar"),M=async e=>{var t,r,a;const{account:s,headers:o,headersToExclude:n,fetchOptions:c={}}=e,d=["principalUrl","rootUrl"];if(!x(s,d))throw new Error(`account must have ${C(s,d)} before fetchUserAddresses`);F(`Fetch user addresses from ${s.principalUrl}`);const l=(await v({url:s.principalUrl,props:{[`${exports.DAVNamespaceShort.CALDAV}:calendar-user-address-set`]:{}},depth:"0",headers:u(o,n),fetchOptions:c})).find((e=>i(s.principalUrl,e.href)));if(!l||!l.ok)throw new Error("cannot find calendarUserAddresses");const p=(null===(a=null===(r=null===(t=null==l?void 0:l.props)||void 0===t?void 0:t.calendarUserAddressSet)||void 0===r?void 0:r.href)||void 0===a?void 0:a.filter(Boolean))||[];return F(`Fetched calendar user addresses ${p}`),p},I=async e=>{const{url:t,props:r,filters:a,timezone:s,depth:o,headers:n,headersToExclude:c,fetchOptions:d={}}=e;return b({url:t,body:{"calendar-query":p({_attributes:l([exports.DAVNamespace.CALDAV,exports.DAVNamespace.CALENDAR_SERVER,exports.DAVNamespace.CALDAV_APPLE,exports.DAVNamespace.DAV]),[`${exports.DAVNamespaceShort.DAV}:prop`]:r,filter:a,timezone:s})},defaultNamespace:exports.DAVNamespaceShort.CALDAV,depth:o,headers:u(n,c),fetchOptions:d})},z=async e=>{const{url:t,props:r,objectUrls:a,filters:s,timezone:o,depth:n,headers:c,headersToExclude:d,fetchOptions:i={}}=e;return b({url:t,body:{"calendar-multiget":p({_attributes:l([exports.DAVNamespace.DAV,exports.DAVNamespace.CALDAV]),[`${exports.DAVNamespaceShort.DAV}:prop`]:r,[`${exports.DAVNamespaceShort.DAV}:href`]:a,filter:s,timezone:o})},defaultNamespace:exports.DAVNamespaceShort.CALDAV,depth:n,headers:u(c,d),fetchOptions:i})},Z=async e=>{const{url:t,props:r,depth:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e;return A({url:t,init:{method:"MKCALENDAR",headers:u(p({depth:a,...s}),o),namespace:exports.DAVNamespaceShort.DAV,body:{[`${exports.DAVNamespaceShort.CALDAV}:mkcalendar`]:{_attributes:l([exports.DAVNamespace.DAV,exports.DAVNamespace.CALDAV,exports.DAVNamespace.CALDAV_APPLE]),set:{prop:r}}}},fetchOptions:n})},q=async e=>{const{headers:t,account:r,props:a,projectedProps:s,headersToExclude:o,fetchOptions:c={}}=null!=e?e:{},d=["homeUrl","rootUrl"];if(!r||!x(r,d)){if(!r)throw new Error("no account for fetchCalendars");throw new Error(`account must have ${C(r,d)} before fetchCalendars`)}const i=await v({url:r.homeUrl,props:null!=a?a:{[`${exports.DAVNamespaceShort.CALDAV}:calendar-description`]:{},[`${exports.DAVNamespaceShort.CALDAV}:calendar-timezone`]:{},[`${exports.DAVNamespaceShort.DAV}:displayname`]:{},[`${exports.DAVNamespaceShort.CALDAV_APPLE}:calendar-color`]:{},[`${exports.DAVNamespaceShort.CALENDAR_SERVER}:getctag`]:{},[`${exports.DAVNamespaceShort.DAV}:resourcetype`]:{},[`${exports.DAVNamespaceShort.CALDAV}:supported-calendar-component-set`]:{},[`${exports.DAVNamespaceShort.DAV}:sync-token`]:{}},depth:"1",headers:u(t,o),fetchOptions:c});return Promise.all(i.filter((e=>{var t,r;return Object.keys(null!==(r=null===(t=e.props)||void 0===t?void 0:t.resourcetype)&&void 0!==r?r:{}).includes("calendar")})).filter((e=>{var t,r,a,s;return(Array.isArray(null===(t=e.props)||void 0===t?void 0:t.supportedCalendarComponentSet.comp)?null===(r=e.props)||void 0===r?void 0:r.supportedCalendarComponentSet.comp.map((e=>e._attributes.name)):[null===(s=null===(a=e.props)||void 0===a?void 0:a.supportedCalendarComponentSet.comp)||void 0===s?void 0:s._attributes.name]).some((e=>Object.values(n).includes(e)))})).map((e=>{var t,a,o,n,c,d,i,l,p,u,f,m,A,v,D,y;const O=null===(t=e.props)||void 0===t?void 0:t.calendarDescription,V=null===(a=e.props)||void 0===a?void 0:a.calendarTimezone;return{description:"string"==typeof O?O:"",timezone:"string"==typeof V?V:"",url:new URL(null!==(o=e.href)&&void 0!==o?o:"",null!==(n=r.rootUrl)&&void 0!==n?n:"").href,ctag:null===(c=e.props)||void 0===c?void 0:c.getctag,calendarColor:null===(d=e.props)||void 0===d?void 0:d.calendarColor,displayName:null!==(l=null===(i=e.props)||void 0===i?void 0:i.displayname._cdata)&&void 0!==l?l:null===(p=e.props)||void 0===p?void 0:p.displayname,components:Array.isArray(null===(u=e.props)||void 0===u?void 0:u.supportedCalendarComponentSet.comp)?null===(f=e.props)||void 0===f?void 0:f.supportedCalendarComponentSet.comp.map((e=>e._attributes.name)):[null===(A=null===(m=e.props)||void 0===m?void 0:m.supportedCalendarComponentSet.comp)||void 0===A?void 0:A._attributes.name],resourcetype:Object.keys(null===(v=e.props)||void 0===v?void 0:v.resourcetype),syncToken:null===(D=e.props)||void 0===D?void 0:D.syncToken,...h("projectedProps",Object.fromEntries(Object.entries(null!==(y=e.props)&&void 0!==y?y:{}).filter((([e])=>null==s?void 0:s[e]))))}})).map((async e=>({...e,reports:await S({collection:e,headers:u(t,o),fetchOptions:c})}))))},Q=async e=>{const{calendar:t,objectUrls:r,filters:a,timeRange:s,headers:o,expand:n,urlFilter:c=e=>Boolean(null==e?void 0:e.includes(".ics")),useMultiGet:d=!0,headersToExclude:i,fetchOptions:l={}}=e;if(s){const e=/^\d{4}(-\d\d(-\d\d(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?)?)?$/i,t=/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$/i;if(!(e.test(s.start)&&e.test(s.end)||t.test(s.start)&&t.test(s.end)))throw new Error("invalid timeRange format, not in ISO8601")}F(`Fetching calendar objects from ${null==t?void 0:t.url}`);const p=["url"];if(!t||!x(t,p)){if(!t)throw new Error("cannot fetchCalendarObjects for undefined calendar");throw new Error(`calendar must have ${C(t,p)} before fetchCalendarObjects`)}const h=null!=a?a:[{"comp-filter":{_attributes:{name:"VCALENDAR"},"comp-filter":{_attributes:{name:"VEVENT"},...s?{"time-range":{_attributes:{start:`${new Date(s.start).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`,end:`${new Date(s.end).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`}}}:{}}}}],f=(null!=r?r:(await I({url:t.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{...n&&s?{[`${exports.DAVNamespaceShort.CALDAV}:expand`]:{_attributes:{start:`${new Date(s.start).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`,end:`${new Date(s.end).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`}}}:{}}},filters:h,depth:"1",headers:u(o,i),fetchOptions:l})).map((e=>{var t;return null!==(t=e.href)&&void 0!==t?t:""}))).map((e=>e.startsWith("http")||!e?e:new URL(e,t.url).href)).filter(c).map((e=>new URL(e).pathname));let m=[];return f.length>0&&(m=!d||n?await I({url:t.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{},[`${exports.DAVNamespaceShort.CALDAV}:calendar-data`]:{...n&&s?{[`${exports.DAVNamespaceShort.CALDAV}:expand`]:{_attributes:{start:`${new Date(s.start).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`,end:`${new Date(s.end).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`}}}:{}}},filters:h,depth:"1",headers:u(o,i),fetchOptions:l}):await z({url:t.url,props:{[`${exports.DAVNamespaceShort.DAV}:getetag`]:{},[`${exports.DAVNamespaceShort.CALDAV}:calendar-data`]:{...n&&s?{[`${exports.DAVNamespaceShort.CALDAV}:expand`]:{_attributes:{start:`${new Date(s.start).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`,end:`${new Date(s.end).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`}}}:{}}},objectUrls:f,depth:"1",headers:u(o,i),fetchOptions:l})),m.map((e=>{var r,a,s,o,n,c;return{url:new URL(null!==(r=e.href)&&void 0!==r?r:"",t.url).href,etag:`${null===(a=e.props)||void 0===a?void 0:a.getetag}`,data:null!==(n=null===(o=null===(s=e.props)||void 0===s?void 0:s.calendarData)||void 0===o?void 0:o._cdata)&&void 0!==n?n:null===(c=e.props)||void 0===c?void 0:c.calendarData}}))},G=async e=>{const{calendar:t,iCalString:r,filename:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e;return D({url:new URL(a,t.url).href,data:r,headers:u({"content-type":"text/calendar; charset=utf-8","If-None-Match":"*",...s},o),fetchOptions:n})},J=async e=>{const{calendarObject:t,headers:r,headersToExclude:a,fetchOptions:s={}}=e;return y({url:t.url,data:t.data,etag:t.etag,headers:u({"content-type":"text/calendar; charset=utf-8",...r},a),fetchOptions:s})},K=async e=>{const{calendarObject:t,headers:r,headersToExclude:a,fetchOptions:s={}}=e;return O({url:t.url,etag:t.etag,headers:u(r,a),fetchOptions:s})},W=async e=>{var t;const{oldCalendars:r,account:a,detailedResult:s,headers:o,headersToExclude:n,fetchOptions:c={}}=e;if(!a)throw new Error("Must have account before syncCalendars");const d=null!==(t=null!=r?r:a.calendars)&&void 0!==t?t:[],l=await q({account:a,headers:u(o,n),fetchOptions:c}),p=l.filter((e=>d.every((t=>!i(t.url,e.url)))));F(`new calendars: ${p.map((e=>e.displayName))}`);const h=d.reduce(((e,t)=>{const r=l.find((e=>i(e.url,t.url)));return r&&(r.syncToken&&`${r.syncToken}`!=`${t.syncToken}`||r.ctag&&`${r.ctag}`!=`${t.ctag}`)?[...e,r]:e}),[]);F(`updated calendars: ${h.map((e=>e.displayName))}`);const f=await Promise.all(h.map((async e=>await E({collection:{...e,objectMultiGet:z},method:"webdav",headers:u(o,n),account:a,fetchOptions:c})))),m=d.filter((e=>l.every((t=>!i(t.url,e.url)))));F(`deleted calendars: ${m.map((e=>e.displayName))}`);const A=d.filter((e=>l.some((t=>i(t.url,e.url)&&(t.syncToken&&`${t.syncToken}`!=`${e.syncToken}`||t.ctag&&`${t.ctag}`!=`${e.ctag}`)))));return s?{created:p,updated:h,deleted:m}:[...A,...p,...f]},Y=async e=>{const{url:t,timeRange:r,depth:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e;if(!r)throw new Error("timeRange is required");{const e=/^\d{4}(-\d\d(-\d\d(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?)?)?$/i,t=/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$/i;if(!(e.test(r.start)&&e.test(r.end)||t.test(r.start)&&t.test(r.end)))throw new Error("invalid timeRange format, not in ISO8601")}return(await b({url:t,body:{"free-busy-query":p({_attributes:l([exports.DAVNamespace.CALDAV]),[`${exports.DAVNamespaceShort.CALDAV}:time-range`]:{_attributes:{start:`${new Date(r.start).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`,end:`${new Date(r.end).toISOString().slice(0,19).replace(/[-:.]/g,"")}Z`}}})},defaultNamespace:exports.DAVNamespaceShort.CALDAV,depth:a,headers:u(s,o),fetchOptions:n}))[0]};var X=Object.freeze({__proto__:null,calendarMultiGet:z,calendarQuery:I,createCalendarObject:G,deleteCalendarObject:K,fetchCalendarObjects:Q,fetchCalendarUserAddresses:M,fetchCalendars:q,freeBusyQuery:Y,makeCalendar:Z,syncCalendars:W,updateCalendarObject:J});const ee=t("tsdav:account"),te=async e=>{var t,r;ee("Service discovery...");const{account:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e,c=new URL(a.serverUrl),d=new URL(`/.well-known/${a.accountType}`,c);d.protocol=null!==(t=c.protocol)&&void 0!==t?t:"http";try{const e=await fetch(d.href,{headers:u(s,o),method:"PROPFIND",redirect:"manual",...n});if(e.status>=300&&e.status<400){const t=e.headers.get("Location");if("string"==typeof t&&t.length){ee(`Service discovery redirected to ${t}`);const e=new URL(t,c);return e.hostname===d.hostname&&d.port&&!e.port&&(e.port=d.port),e.protocol=null!==(r=c.protocol)&&void 0!==r?r:"http",e.href}}}catch(e){ee(`Service discovery failed: ${e.stack}`)}return c.href},re=async e=>{var t,r,a,s,o;const{account:n,headers:c,headersToExclude:d,fetchOptions:i={}}=e,l=["rootUrl"];if(!x(n,l))throw new Error(`account must have ${C(n,l)} before fetchPrincipalUrl`);ee(`Fetching principal url from path ${n.rootUrl}`);const[p]=await v({url:n.rootUrl,props:{[`${exports.DAVNamespaceShort.DAV}:current-user-principal`]:{}},depth:"0",headers:u(c,d),fetchOptions:i});if(!p.ok&&(ee(`Fetch principal url failed: ${p.statusText}`),401===p.status))throw new Error("Invalid credentials");return ee(`Fetched principal url ${null===(r=null===(t=p.props)||void 0===t?void 0:t.currentUserPrincipal)||void 0===r?void 0:r.href}`),new URL(null!==(o=null===(s=null===(a=p.props)||void 0===a?void 0:a.currentUserPrincipal)||void 0===s?void 0:s.href)&&void 0!==o?o:"",n.rootUrl).href},ae=async e=>{var t,r;const{account:a,headers:s,headersToExclude:o,fetchOptions:n={}}=e,c=["principalUrl","rootUrl"];if(!x(a,c))throw new Error(`account must have ${C(a,c)} before fetchHomeUrl`);ee(`Fetch home url from ${a.principalUrl}`);const d=(await v({url:a.principalUrl,props:"caldav"===a.accountType?{[`${exports.DAVNamespaceShort.CALDAV}:calendar-home-set`]:{}}:{[`${exports.DAVNamespaceShort.CARDDAV}:addressbook-home-set`]:{}},depth:"0",headers:u(s,o),fetchOptions:n})).find((e=>i(a.principalUrl,e.href)));if(!d||!d.ok)throw new Error("cannot find homeUrl");const l=new URL("caldav"===a.accountType?null===(t=null==d?void 0:d.props)||void 0===t?void 0:t.calendarHomeSet.href:null===(r=null==d?void 0:d.props)||void 0===r?void 0:r.addressbookHomeSet.href,a.rootUrl).href;return ee(`Fetched home url ${l}`),l},se=async e=>{const{account:t,headers:r,loadCollections:a=!1,loadObjects:s=!1,headersToExclude:o,fetchOptions:n={}}=e,c={...t};return c.rootUrl=await te({account:t,headers:u(r,o),fetchOptions:n}),c.principalUrl=await re({account:c,headers:u(r,o),fetchOptions:n}),c.homeUrl=await ae({account:c,headers:u(r,o),fetchOptions:n}),(a||s)&&("caldav"===t.accountType?c.calendars=await q({headers:u(r,o),account:c,fetchOptions:n}):"carddav"===t.accountType&&(c.addressBooks=await R({headers:u(r,o),account:c,fetchOptions:n}))),s&&("caldav"===t.accountType&&c.calendars?c.calendars=await Promise.all(c.calendars.map((async e=>({...e,objects:await Q({calendar:e,headers:u(r,o),fetchOptions:n})})))):"carddav"===t.accountType&&c.addressBooks&&(c.addressBooks=await Promise.all(c.addressBooks.map((async e=>({...e,objects:await j({addressBook:e,headers:u(r,o),fetchOptions:n})})))))),c};var oe=Object.freeze({__proto__:null,createAccount:se,fetchHomeUrl:ae,fetchPrincipalUrl:re,serviceDiscovery:te});const ne=t("tsdav:authHelper"),ce=(e,t)=>(...r)=>e({...t,...r[0]}),de=e=>(ne(`Basic auth token generated: ${a.encode(`${e.username}:${e.password}`)}`),{authorization:`Basic ${a.encode(`${e.username}:${e.password}`)}`}),ie=async(e,t)=>{const r=["authorizationCode","redirectUrl","clientId","clientSecret","tokenUrl"];if(!x(e,r))throw new Error(`Oauth credentials missing: ${C(e,r)}`);const a=new URLSearchParams({grant_type:"authorization_code",code:e.authorizationCode,redirect_uri:e.redirectUrl,client_id:e.clientId,client_secret:e.clientSecret});ne(e.tokenUrl),ne(a.toString());const s=await fetch(e.tokenUrl,{method:"POST",body:a.toString(),headers:{"content-length":`${a.toString().length}`,"content-type":"application/x-www-form-urlencoded"},...null!=t?t:{}});if(s.ok){return await s.json()}return ne(`Fetch Oauth tokens failed: ${await s.text()}`),{}},le=async(e,t)=>{const r=["refreshToken","clientId","clientSecret","tokenUrl"];if(!x(e,r))throw new Error(`Oauth credentials missing: ${C(e,r)}`);const a=new URLSearchParams({client_id:e.clientId,client_secret:e.clientSecret,refresh_token:e.refreshToken,grant_type:"refresh_token"}),s=await fetch(e.tokenUrl,{method:"POST",body:a.toString(),headers:{"Content-Type":"application/x-www-form-urlencoded"},...null!=t?t:{}});if(s.ok){return await s.json()}return ne(`Refresh access token failed: ${await s.text()}`),{}},pe=async(e,t)=>{var r;ne("Fetching oauth headers");let a={};return e.refreshToken?(e.refreshToken&&!e.accessToken||Date.now()>(null!==(r=e.expiration)&&void 0!==r?r:0))&&(a=await le(e,t)):a=await ie(e,t),ne(`Oauth tokens fetched: ${a.access_token}`),{tokens:a,headers:{authorization:`Bearer ${a.access_token}`}}};var he=Object.freeze({__proto__:null,defaultParam:ce,fetchOauthTokens:ie,getBasicAuthHeaders:de,getOauthHeaders:pe,refreshAccessToken:le});const ue=async e=>{var t;const{serverUrl:r,credentials:a,authMethod:s,defaultAccountType:o,authFunction:n}=e;let c={};switch(s){case"Basic":c=de(a);break;case"Oauth":c=(await pe(a)).headers;break;case"Digest":c={Authorization:`Digest ${a.digestString}`};break;case"Custom":c=null!==(t=await(null==n?void 0:n(a)))&&void 0!==t?t:{};break;default:throw new Error("Invalid auth method")}const d=o?await se({account:{serverUrl:r,credentials:a,accountType:o},headers:c}):void 0,i=ce(D,{url:r,headers:c}),l=ce(y,{headers:c,url:r}),p=ce(O,{headers:c,url:r}),h=ce(v,{headers:c}),u=ce(b,{headers:c}),f=ce(w,{headers:c}),m=ce($,{headers:c}),V=ce(S,{headers:c}),x=ce(N,{headers:c}),C=ce(E,{headers:c,account:d}),g=ce(I,{headers:c}),T=ce(z,{headers:c}),k=ce(Z,{headers:c}),B=ce(q,{headers:c,account:d}),F=ce(M,{headers:c,account:d}),Y=ce(Q,{headers:c}),X=ce(G,{headers:c}),ee=ce(J,{headers:c}),te=ce(K,{headers:c}),re=ce(W,{account:d,headers:c}),ae=ce(U,{headers:c}),oe=ce(_,{headers:c});return{davRequest:async e=>{const{init:t,...r}=e,{headers:a,...s}=t;return A({...r,init:{...s,headers:{...c,...a}}})},propfind:h,createAccount:async e=>{const{account:t,headers:s,loadCollections:o,loadObjects:n}=e;return se({account:{serverUrl:r,credentials:a,...t},headers:{...c,...s},loadCollections:o,loadObjects:n})},createObject:i,updateObject:l,deleteObject:p,calendarQuery:g,addressBookQuery:ae,collectionQuery:u,makeCollection:f,calendarMultiGet:T,makeCalendar:k,syncCollection:m,supportedReportSet:V,isCollectionDirty:x,smartCollectionSync:C,fetchCalendars:B,fetchCalendarUserAddresses:F,fetchCalendarObjects:Y,createCalendarObject:X,updateCalendarObject:ee,deleteCalendarObject:te,syncCalendars:re,fetchAddressBooks:ce(R,{account:d,headers:c}),addressBookMultiGet:oe,fetchVCards:ce(j,{headers:c}),createVCard:ce(L,{headers:c}),updateVCard:ce(H,{headers:c}),deleteVCard:ce(P,{headers:c})}};class fe{constructor(e){var t,r,a;this.serverUrl=e.serverUrl,this.credentials=e.credentials,this.authMethod=null!==(t=e.authMethod)&&void 0!==t?t:"Basic",this.accountType=null!==(r=e.defaultAccountType)&&void 0!==r?r:"caldav",this.authFunction=e.authFunction,this.fetchOptions=null!==(a=e.fetchOptions)&&void 0!==a?a:{}}async login(){var e;switch(this.authMethod){case"Basic":this.authHeaders=de(this.credentials);break;case"Oauth":this.authHeaders=(await pe(this.credentials,this.fetchOptions)).headers;break;case"Digest":this.authHeaders={Authorization:`Digest ${this.credentials.digestString}`};break;case"Custom":this.authHeaders=await(null===(e=this.authFunction)||void 0===e?void 0:e.call(this,this.credentials));break;default:throw new Error("Invalid auth method")}this.account=this.accountType?await se({account:{serverUrl:this.serverUrl,credentials:this.credentials,accountType:this.accountType},headers:this.authHeaders,fetchOptions:this.fetchOptions}):void 0}async davRequest(e){const{init:t,...r}=e,{headers:a,...s}=t;return A({...r,init:{...s,headers:{...this.authHeaders,...a}},fetchOptions:this.fetchOptions})}async createObject(...e){return ce(D,{url:this.serverUrl,headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async updateObject(...e){return ce(y,{url:this.serverUrl,headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async deleteObject(...e){return ce(O,{url:this.serverUrl,headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async propfind(...e){return ce(v,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async createAccount(e){const{account:t,headers:r,loadCollections:a,loadObjects:s,fetchOptions:o}=e;return se({account:{serverUrl:this.serverUrl,credentials:this.credentials,...t},headers:{...this.authHeaders,...r},loadCollections:a,loadObjects:s,fetchOptions:null!=o?o:this.fetchOptions})}async collectionQuery(...e){return ce(b,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async makeCollection(...e){return ce(w,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async syncCollection(...e){return ce($,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async supportedReportSet(...e){return ce(S,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async isCollectionDirty(...e){return ce(N,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async smartCollectionSync(...e){return ce(E,{headers:this.authHeaders,fetchOptions:this.fetchOptions,account:this.account})(e[0])}async calendarQuery(...e){return ce(I,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async makeCalendar(...e){return ce(Z,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async calendarMultiGet(...e){return ce(z,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async fetchCalendars(...e){return ce(q,{headers:this.authHeaders,account:this.account,fetchOptions:this.fetchOptions})(null==e?void 0:e[0])}async fetchCalendarUserAddresses(...e){return ce(M,{headers:this.authHeaders,account:this.account,fetchOptions:this.fetchOptions})(null==e?void 0:e[0])}async fetchCalendarObjects(...e){return ce(Q,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async createCalendarObject(...e){return ce(G,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async updateCalendarObject(...e){return ce(J,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async deleteCalendarObject(...e){return ce(K,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async syncCalendars(...e){return ce(W,{headers:this.authHeaders,account:this.account,fetchOptions:this.fetchOptions})(e[0])}async addressBookQuery(...e){return ce(U,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async addressBookMultiGet(...e){return ce(_,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async fetchAddressBooks(...e){return ce(R,{headers:this.authHeaders,account:this.account,fetchOptions:this.fetchOptions})(null==e?void 0:e[0])}async fetchVCards(...e){return ce(j,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async createVCard(...e){return ce(L,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async updateVCard(...e){return ce(H,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}async deleteVCard(...e){return ce(P,{headers:this.authHeaders,fetchOptions:this.fetchOptions})(e[0])}}var me=Object.freeze({__proto__:null,DAVClient:fe,createDAVClient:ue}),Ae={DAVNamespace:exports.DAVNamespace,DAVNamespaceShort:exports.DAVNamespaceShort,DAVAttributeMap:s,...me,...V,...T,...oe,...B,...X,...he,...f};exports.DAVAttributeMap=s,exports.DAVClient=fe,exports.addressBookQuery=U,exports.calendarMultiGet=z,exports.calendarQuery=I,exports.cleanupFalsy=p,exports.collectionQuery=b,exports.createAccount=se,exports.createCalendarObject=G,exports.createDAVClient=ue,exports.createObject=D,exports.createVCard=L,exports.davRequest=A,exports.default=Ae,exports.deleteCalendarObject=K,exports.deleteObject=O,exports.deleteVCard=P,exports.fetchAddressBooks=R,exports.fetchCalendarObjects=Q,exports.fetchCalendarUserAddresses=M,exports.fetchCalendars=q,exports.fetchOauthTokens=ie,exports.fetchVCards=j,exports.freeBusyQuery=Y,exports.getBasicAuthHeaders=de,exports.getDAVAttribute=l,exports.getOauthHeaders=pe,exports.isCollectionDirty=N,exports.makeCalendar=Z,exports.propfind=v,exports.refreshAccessToken=le,exports.smartCollectionSync=E,exports.supportedReportSet=S,exports.syncCalendars=W,exports.syncCollection=$,exports.updateCalendarObject=J,exports.updateObject=y,exports.updateVCard=H,exports.urlContains=i,exports.urlEquals=d;