@timesheet/sdk 1.0.6 → 1.1.0

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.
Files changed (76) hide show
  1. package/CHANGELOG.md +67 -1
  2. package/README.md +103 -16
  3. package/dist/http/ApiClient.d.ts +1 -1
  4. package/dist/http/ApiClient.d.ts.map +1 -1
  5. package/dist/index.d.ts +5 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -2
  8. package/dist/index.js.map +4 -4
  9. package/dist/index.mjs +2 -2
  10. package/dist/index.mjs.map +4 -4
  11. package/dist/models/Absence.d.ts +136 -0
  12. package/dist/models/Absence.d.ts.map +1 -0
  13. package/dist/models/Automation.d.ts +6 -1
  14. package/dist/models/Automation.d.ts.map +1 -1
  15. package/dist/models/Contract.d.ts +141 -0
  16. package/dist/models/Contract.d.ts.map +1 -0
  17. package/dist/models/Document.d.ts +192 -87
  18. package/dist/models/Document.d.ts.map +1 -1
  19. package/dist/models/Expense.d.ts +4 -3
  20. package/dist/models/Expense.d.ts.map +1 -1
  21. package/dist/models/Note.d.ts +3 -2
  22. package/dist/models/Note.d.ts.map +1 -1
  23. package/dist/models/Organization.d.ts +58 -1
  24. package/dist/models/Organization.d.ts.map +1 -1
  25. package/dist/models/Pause.d.ts +2 -2
  26. package/dist/models/Pause.d.ts.map +1 -1
  27. package/dist/models/Profile.d.ts +13 -1
  28. package/dist/models/Profile.d.ts.map +1 -1
  29. package/dist/models/Project.d.ts +52 -27
  30. package/dist/models/Project.d.ts.map +1 -1
  31. package/dist/models/Rate.d.ts +7 -6
  32. package/dist/models/Rate.d.ts.map +1 -1
  33. package/dist/models/Reports.d.ts +32 -15
  34. package/dist/models/Reports.d.ts.map +1 -1
  35. package/dist/models/Tag.d.ts +6 -2
  36. package/dist/models/Tag.d.ts.map +1 -1
  37. package/dist/models/Task.d.ts +14 -22
  38. package/dist/models/Task.d.ts.map +1 -1
  39. package/dist/models/Team.d.ts +55 -11
  40. package/dist/models/Team.d.ts.map +1 -1
  41. package/dist/models/Timer.d.ts +4 -0
  42. package/dist/models/Timer.d.ts.map +1 -1
  43. package/dist/models/Todo.d.ts +8 -7
  44. package/dist/models/Todo.d.ts.map +1 -1
  45. package/dist/models/Webhook.d.ts +3 -0
  46. package/dist/models/Webhook.d.ts.map +1 -1
  47. package/dist/models/common.d.ts +2 -0
  48. package/dist/models/common.d.ts.map +1 -1
  49. package/dist/models/index.d.ts +2 -0
  50. package/dist/models/index.d.ts.map +1 -1
  51. package/dist/resources/AbsenceResource.d.ts +18 -0
  52. package/dist/resources/AbsenceResource.d.ts.map +1 -0
  53. package/dist/resources/AbsenceTypeResource.d.ts +14 -0
  54. package/dist/resources/AbsenceTypeResource.d.ts.map +1 -0
  55. package/dist/resources/ContractResource.d.ts +18 -0
  56. package/dist/resources/ContractResource.d.ts.map +1 -0
  57. package/dist/resources/ContractTemplateResource.d.ts +14 -0
  58. package/dist/resources/ContractTemplateResource.d.ts.map +1 -0
  59. package/dist/resources/DocumentResource.d.ts.map +1 -1
  60. package/dist/resources/ExpenseResource.d.ts +1 -1
  61. package/dist/resources/ExpenseResource.d.ts.map +1 -1
  62. package/dist/resources/OrganizationResource.d.ts +6 -1
  63. package/dist/resources/OrganizationResource.d.ts.map +1 -1
  64. package/dist/resources/ProjectResource.d.ts +9 -1
  65. package/dist/resources/ProjectResource.d.ts.map +1 -1
  66. package/dist/resources/TagResource.d.ts.map +1 -1
  67. package/dist/resources/TaskResource.d.ts +4 -1
  68. package/dist/resources/TaskResource.d.ts.map +1 -1
  69. package/dist/resources/TeamResource.d.ts +8 -2
  70. package/dist/resources/TeamResource.d.ts.map +1 -1
  71. package/dist/resources/TodoResource.d.ts.map +1 -1
  72. package/dist/resources/index.d.ts +4 -0
  73. package/dist/resources/index.d.ts.map +1 -1
  74. package/dist/resources/reports/ExportResource.d.ts +1 -1
  75. package/dist/resources/reports/ExportResource.d.ts.map +1 -1
  76. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import C from"axios";var g=class s extends Error{constructor(e,t,r,i){let o=t?i?`${e} (HTTP ${t}, Code: ${i})`:`${e} (HTTP ${t})`:e;super(o),this.name="TimesheetApiError",this.statusCode=t,this.responseBody=r,this.errorCode=i,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,s)}};var G=class extends g{constructor(e,t=401,r){super(e,t,r,"authentication_error"),this.name="TimesheetAuthError"}};var Y=class extends g{constructor(e,t){super(e,429,void 0,"rate_limit_exceeded"),this.name="TimesheetRateLimitError",this.retryAfter=t}getRetryAfterDate(){if(!this.retryAfter)return null;let e=Number(this.retryAfter);if(!isNaN(e))return new Date(e*1e3);let t=new Date(this.retryAfter);return isNaN(t.getTime())?null:t}};var w=class{constructor(e){this.config=e,this.httpClient=e.httpClient||C.create({baseURL:e.baseUrl,timeout:3e4,headers:{"User-Agent":"Timesheet-TypeScript-SDK/1.0.0","Content-Type":"application/json"}}),this.httpClient.interceptors.request.use(async t=>{if(t.url!=="/oauth/token"&&this.config.authentication){let r=await this.config.authentication.getAuthHeaders();if(r)for(let[i,o]of Object.entries(r))t.headers.set(i,o)}return t})}async request(e){let t=null,r=this.config.retryConfig;for(let i=0;i<=r.maxRetries;i++)try{return(await this.httpClient.request(e)).data}catch(o){if(t=o,C.isAxiosError(o)&&o.response?.status===401){let c=o.response.data;throw new G(c?.message||"Authentication failed",401,JSON.stringify(c))}if(C.isAxiosError(o)&&o.response?.status===429){let c=o.response.headers["retry-after"];throw new Y("Rate limit exceeded",c)}let m=C.isAxiosError(o)?o.response?.status:void 0;if(i<r.maxRetries&&m&&r.retryableStatusCodes.includes(m)){let c=Math.min(r.initialDelay*Math.pow(r.backoffMultiplier,i),r.maxDelay);await this.sleep(c);continue}if(C.isAxiosError(o)){let c=o.response?.data;throw new g(c?.message||o.message,o.response?.status,JSON.stringify(c),c?.code)}else throw o instanceof Error?new g(o.message):new g("Unknown error occurred")}throw t||new Error("Unknown error")}async get(e,t){return this.request({method:"GET",url:e,params:t})}async post(e,t,r){return this.request({method:"POST",url:e,data:t,params:r})}async put(e,t,r){return this.request({method:"PUT",url:e,data:t,params:r})}async delete(e,t){return this.request({method:"DELETE",url:e,params:t})}async postMultipart(e,t){return this.request({method:"POST",url:e,data:t,headers:{"Content-Type":"multipart/form-data"}})}sleep(e){return new Promise(t=>setTimeout(t,e))}getBaseUrl(){return this.config.baseUrl}async getAuthHeaders(){if(this.config.authentication)return this.config.authentication.getAuthHeaders()}};var Z=class{constructor(e){this.apiKey=e;if(e===null)throw new Error("API key cannot be null");if(e===void 0)throw new Error("API key cannot be undefined");if(!e)throw new Error("API key cannot be empty");if(typeof e!="string")throw new Error("API key must be a string");if(e.trim().length===0)throw new Error("API key cannot be empty or whitespace");if(!this.isValidFormat(e))throw new Error("Invalid API key format")}isValidFormat(e){return/^ts_[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/.test(e)}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`ApiKey ${this.apiKey}`}needsRefresh(){return!1}async refresh(){throw new Error("API keys cannot be refreshed")}async getAuthHeaders(){return{Authorization:`ApiKey ${this.apiKey}`}}isValid(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0&&this.isValidFormat(this.apiKey)}};import oe from"axios";import he from"jsonwebtoken";var T=class T{constructor(e,t,r){t&&r?(this.clientId=e,this.clientSecret=t,this.refreshToken=r,this.accessToken=""):(this.accessToken=e,this.parseTokenExpiry())}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+300*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=await oe.post(T.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId,client_secret:this.clientSecret}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=e.data.access_token,e.data.refresh_token&&(this.refreshToken=e.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth2 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e,t,r,i){try{let o=await oe.post(T.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"authorization_code",code:r,redirect_uri:i,client_id:e,client_secret:t}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),m=o.data.access_token,c=o.data.refresh_token;return c?new T(e,t,c):new T(m)}catch(o){let m=o instanceof Error?o.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${m}`)}}static buildAuthorizationUrl(e,t,r){let i=new URLSearchParams({client_id:e,redirect_uri:t,response_type:"code"});return r&&i.append("state",r),`https://api.timesheet.io/oauth2/auth?${i.toString()}`}parseTokenExpiry(){try{let e=he.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+3600*1e3)}}};T.TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token";var E=T;import pe from"axios";import ge from"jsonwebtoken";import{randomBytes as me,createHash as ue}from"crypto";function le(s=64){if(s<43||s>128)throw new Error("Code verifier length must be between 43 and 128 characters");let e=me(Math.ceil(s*3/4));return ne(e).slice(0,s)}function de(s,e="S256"){if(e==="plain")return s;let t=ue("sha256").update(s,"ascii").digest();return ne(t)}function ie(s="S256",e=64){let t=le(e),r=de(t,s);return{codeVerifier:t,codeChallenge:r,codeChallengeMethod:s}}function ae(s){return s.length<43||s.length>128?!1:/^[A-Za-z0-9\-._~]+$/.test(s)}function ne(s){return s.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var f=class f{constructor(e){if(typeof e=="string")this.accessToken=e,this.tokenEndpoint=f.DEFAULT_TOKEN_ENDPOINT,this.parseTokenExpiry();else{let t=e;this.clientId=t.clientId,this.clientSecret=t.clientSecret,this.refreshToken=t.refreshToken,this.resource=t.resource,this.tokenEndpoint=t.tokenEndpoint??f.DEFAULT_TOKEN_ENDPOINT,this.accessToken=""}}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+300*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId});this.clientSecret&&e.append("client_secret",this.clientSecret),this.resource&&e.append("resource",this.resource);let t=await pe.post(this.tokenEndpoint,e,{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=t.data.access_token,t.data.refresh_token&&(this.refreshToken=t.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth 2.1 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e){let{clientId:t,clientSecret:r,authorizationCode:i,redirectUri:o,codeVerifier:m,resource:c,tokenEndpoint:d}=e,h=d??f.DEFAULT_TOKEN_ENDPOINT;if(!ae(m))throw new Error("Invalid code verifier: must be 43-128 characters using only A-Z, a-z, 0-9, -, ., _, ~");try{let u=new URLSearchParams({grant_type:"authorization_code",code:i,redirect_uri:o,client_id:t,code_verifier:m});r&&u.append("client_secret",r),c&&u.append("resource",c);let l=await pe.post(h,u,{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),x=l.data.access_token,y=l.data.refresh_token;return y?new f({clientId:t,clientSecret:r,refreshToken:y,resource:c,tokenEndpoint:h}):new f(x)}catch(u){let l=u instanceof Error?u.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${l}`)}}static buildAuthorizationUrl(e){let{clientId:t,redirectUri:r,codeChallenge:i,codeChallengeMethod:o="S256",state:m,scope:c,resource:d,authorizationEndpoint:h}=e,u=h??f.DEFAULT_AUTH_ENDPOINT,l=new URLSearchParams({response_type:"code",client_id:t,redirect_uri:r,code_challenge:i,code_challenge_method:o});return m&&l.append("state",m),c&&l.append("scope",c),d&&l.append("resource",d),`${u}?${l.toString()}`}static generatePkce(e="S256"){return ie(e)}parseTokenExpiry(){try{let e=ge.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+3600*1e3)}}};f.DEFAULT_TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token",f.DEFAULT_AUTH_ENDPOINT="https://api.timesheet.io/oauth2/auth";var ce=f;import ee from"axios";var b=class b{constructor(e={}){this.cache=new Map;this.options={cacheTtl:e.cacheTtl??b.DEFAULT_CACHE_TTL,timeout:e.timeout??b.DEFAULT_TIMEOUT,fetchOpenIdConfig:e.fetchOpenIdConfig??!1,fetchProtectedResource:e.fetchProtectedResource??!1}}async discover(e){let t=this.normalizeIssuerUrl(e),r=this.getCached(t);if(r)return r;let i=await this.fetchAuthorizationServerMetadata(t),o={issuer:i.issuer,authorizationServer:i,fetchedAt:new Date};if(this.options.fetchOpenIdConfig)try{o.openIdConfiguration=await this.fetchOpenIdConfiguration(t)}catch{}if(this.options.fetchProtectedResource)try{o.protectedResource=await this.fetchProtectedResourceMetadata(t)}catch{}return this.setCache(t,o),o}async fetchAuthorizationServerMetadata(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/oauth-authorization-server`;try{let r=await ee.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateAuthorizationServerMetadata(r.data),r.data}catch(r){let i=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch authorization server metadata from ${t}: ${i}`)}}async fetchOpenIdConfiguration(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/openid-configuration`;try{let r=await ee.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateOpenIdConfiguration(r.data),r.data}catch(r){let i=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch OpenID configuration from ${t}: ${i}`)}}async fetchProtectedResourceMetadata(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/oauth-protected-resource`;try{let r=await ee.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateProtectedResourceMetadata(r.data),r.data}catch(r){let i=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch protected resource metadata from ${t}: ${i}`)}}clearCache(){this.cache.clear()}clearCacheForIssuer(e){this.cache.delete(this.normalizeIssuerUrl(e))}isCached(e){return this.getCached(this.normalizeIssuerUrl(e))!==null}normalizeIssuerUrl(e){return e.replace(/\/+$/,"")}getCached(e){let t=this.cache.get(e);return t?new Date>=t.expiresAt?(this.cache.delete(e),null):t.result:null}setCache(e,t){let r=new Date(Date.now()+this.options.cacheTtl);this.cache.set(e,{result:t,expiresAt:r})}validateAuthorizationServerMetadata(e){if(!e.issuer)throw new Error("Authorization server metadata missing required field: issuer");if(!e.authorization_endpoint)throw new Error("Authorization server metadata missing required field: authorization_endpoint");if(!e.token_endpoint)throw new Error("Authorization server metadata missing required field: token_endpoint");if(!e.response_types_supported||e.response_types_supported.length===0)throw new Error("Authorization server metadata missing required field: response_types_supported")}validateOpenIdConfiguration(e){if(!e.issuer)throw new Error("OpenID configuration missing required field: issuer");if(!e.authorization_endpoint)throw new Error("OpenID configuration missing required field: authorization_endpoint");if(!e.token_endpoint)throw new Error("OpenID configuration missing required field: token_endpoint");if(!e.jwks_uri)throw new Error("OpenID configuration missing required field: jwks_uri")}validateProtectedResourceMetadata(e){if(!e.resource)throw new Error("Protected resource metadata missing required field: resource");if(!e.authorization_servers||e.authorization_servers.length===0)throw new Error("Protected resource metadata missing required field: authorization_servers")}};b.DEFAULT_CACHE_TTL=3600*1e3,b.DEFAULT_TIMEOUT=1e4;var X=b,te=null;function fe(){return te||(te=new X),te}async function Je(s,e){return(e?new X(e):fe()).discover(s)}var Q=class s{constructor(e={}){this.maxRetries=e.maxRetries??3,this.initialDelay=e.initialDelay??100,this.maxDelay=e.maxDelay??1e4,this.backoffMultiplier=e.backoffMultiplier??2,this.retryableStatusCodes=e.retryableStatusCodes??[429,502,503,504]}static default(){return new s}};var p=class{constructor(e,t){this.items=e.items,this.params=e.params,this.nextPageLoader=t}get totalPages(){return Math.ceil((this.params?.count||0)/(this.params?.limit||25))}get hasNextPage(){return(this.params?.page||1)<this.totalPages}async nextPage(){if(!this.hasNextPage)throw new Error("No more pages available");if(!this.nextPageLoader)throw new Error("Next page loader not configured");return this.nextPageLoader((this.params.page||1)+1)}async*[Symbol.asyncIterator](){let e=this;for(;;){for(let t of e.items)yield t;if(!e.hasNextPage)break;e=await e.nextPage()}}async toArray(){let e=[];for await(let t of this)e.push(t);return e}};var pt={TEAM_CREATE:"team.create",TEAM_UPDATE:"team.update",PROJECT_CREATE:"project.create",PROJECT_UPDATE:"project.update",TODO_CREATE:"todo.create",TODO_UPDATE:"todo.update",TASK_CREATE:"task.create",TASK_UPDATE:"task.update",TAG_CREATE:"tag.create",TAG_UPDATE:"tag.update",RATE_CREATE:"rate.create",RATE_UPDATE:"rate.update",TIMER_START:"timer.start",TIMER_STOP:"timer.stop",TIMER_PAUSE:"timer.pause",TIMER_RESUME:"timer.resume"};function ct(...s){return s.join(",")}var a=class{constructor(e,t){this.http=e;typeof t=="string"?this.basePath=t:this.basePath=t.basePath}createNavigablePage(e,t){return new p(e,t)}};var v=class extends a{constructor(e){super(e,"/v1/organizations")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var k=class extends a{constructor(e){super(e,"/v1/teams")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async listMembers(e,t){let r=await this.http.post(`${this.basePath}/${e}/members/list`,t);return this.createNavigablePage(r,i=>this.listMembers(e,{...t,page:i}))}async getMember(e,t){return this.http.get(`${this.basePath}/${e}/members/${t}`)}async getColleagues(e){let t=await this.http.post(`${this.basePath}/getColleagues`,e);return this.createNavigablePage(t,r=>this.getColleagues({...e,page:r}))}};var A=class extends a{constructor(e){super(e,"/v1/projects")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};import R from"dayjs";import Pe from"dayjs/plugin/utc";import Te from"dayjs/plugin/timezone";import ye from"dayjs/plugin/customParseFormat";R.extend(Pe);R.extend(Te);R.extend(ye);var be="YYYY-MM-DDTHH:mm:ssZ",Re=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$/,n={isValidTimestampFormat(s){return Re.test(s)},formatTimestamp(s){return typeof s=="string"&&this.isValidTimestampFormat(s)?s:R(s||new Date).format(be)},parseTimestamp(s){return R(s).toDate()},formatDate(s){return R(s||new Date).format("YYYY-MM-DD")},now(){return this.formatTimestamp()}};var D=class extends a{constructor(e){super(e,"/v1/tasks")}async create(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:t.startDateTime?n.formatTimestamp(t.startDateTime):void 0,endDateTime:t.endDateTime?n.formatTimestamp(t.endDateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async updateStatus(e){return this.http.put(`${this.basePath}/updateStatus`,e)}async updateTimes(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:n.formatTimestamp(e.endDateTime)};return this.http.put(`${this.basePath}/updateTimes`,t)}};var $=class extends a{constructor(e){super(e,"/v1/rates")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var U=class extends a{constructor(e){super(e,"/v1/tags")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var N=class extends a{constructor(e){super(e,"/v1/expenses")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:n.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:t.dateTime?n.formatTimestamp(t.dateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async updateStatus(e,t){return this.http.put(`${this.basePath}/${e}/status`,t)}async uploadFile(e,t){let r=new FormData;return r.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/${encodeURIComponent(e)}/file`,r)}async createWithFile(e){let{file:t,...r}=e,i={...r,dateTime:n.formatTimestamp(r.dateTime)},o=new FormData;return o.append("data",new Blob([JSON.stringify(i)],{type:"application/json"})),t&&o.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/with-file`,o)}async getFileUrl(e){return this.http.get(`${this.basePath}/getFileUrl/${encodeURIComponent(e)}`)}};var I=class extends a{constructor(e){super(e,"/v1/notes")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:n.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:n.formatTimestamp(t.dateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async uploadFile(e,t){let r=new FormData;return r.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/${encodeURIComponent(e)}/file`,r)}async createWithFile(e){let{file:t,...r}=e,i={...r,dateTime:n.formatTimestamp(r.dateTime)},o=new FormData;return o.append("data",new Blob([JSON.stringify(i)],{type:"application/json"})),t&&o.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/with-file`,o)}async getFileUrl(e){return this.http.get(`${this.basePath}/getFileUrl/${encodeURIComponent(e)}`)}};var q=class extends a{constructor(e){super(e,"/v1/pauses")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:n.formatTimestamp(e.endDateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:n.formatTimestamp(t.startDateTime),endDateTime:n.formatTimestamp(t.endDateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var S=class{constructor(e){this.http=e}async getProfile(){return this.http.get("/v1/profiles/me")}async updateProfile(e){return this.http.put("/v1/profiles/me",e)}};var O=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/settings")}async update(e){return this.http.put("/v1/settings",e)}};var _=class extends a{constructor(e){super(e,"/v1/automations")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var L=class extends a{constructor(e){super(e,"/v1/documents")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var M=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/timer")}async start(e){let t={...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):n.formatTimestamp()};return this.http.post("/v1/timer/start",t)}async stop(e){let t=e?{...e,endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):n.formatTimestamp()}:{endDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/stop",t)}async pause(e){let t=e?{...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):n.formatTimestamp()}:{startDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/pause",t)}async resume(e){let t=e?{...e,endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):n.formatTimestamp()}:{endDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/resume",t)}async update(e){let t={...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):void 0};return this.http.put("/v1/timer/update",t)}};var z=class extends a{constructor(e){super(e,"/v1/todos")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dueDate:e.dueDate?n.formatTimestamp(e.dueDate):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dueDate:t.dueDate?n.formatTimestamp(t.dueDate):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var F=class extends a{constructor(e){super(e,"/v1/webhooks")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var j=class extends a{constructor(e){super(e,"/v1/events")}async getStatus(){return this.http.get(`${this.basePath}/status`)}getStreamUrl(){return`${this.http.getBaseUrl()}${this.basePath}/stream`}async subscribe(e){let t=this.getStreamUrl(),i={Accept:"text/event-stream","Cache-Control":"no-cache",...await this.http.getAuthHeaders()},o=new AbortController,m=!1,c=new Map,d={close:()=>{m=!1,o.abort(),e.onClose?.()},get isConnected(){return m},on:(h,u)=>{c.has(h)||c.set(h,new Set),c.get(h).add(u)},off:(h,u)=>{c.get(h)?.delete(u)}};return this.connectSse(t,i,o.signal,{...e,onConnected:h=>{m=!0,e.onConnected?.(h)},onEvent:h=>{e.onEvent?.(h),c.get(h.event)?.forEach(l=>l(h))},onError:h=>{e.onError?.(h),c.get("error")?.forEach(l=>l(h))},onClose:()=>{m=!1,e.onClose?.()}}),d}async connectSse(e,t,r,i){try{let o=await fetch(e,{method:"GET",headers:t,signal:r});if(!o.ok)throw new Error(`SSE connection failed: ${o.status} ${o.statusText}`);if(!o.body)throw new Error("SSE response has no body");let m=o.body.getReader(),c=new TextDecoder,d="",h="",u="",l="",x=!1;for(;!x;){let y=await m.read();if(x=y.done,x||!y.value){i.onClose?.();break}d+=c.decode(y.value,{stream:!0});let se=d.split(`
2
- `);d=se.pop()||"";for(let P of se)P.startsWith("event:")?h=P.slice(6).trim():P.startsWith("data:")?u=P.slice(5).trim():P.startsWith("id:")?l=P.slice(3).trim():P===""&&(u&&this.processEvent(h,u,l,i),h="",u="",l="")}}catch(o){if(r.aborted)return;i.onError?.(o)}}processEvent(e,t,r,i){try{let o=JSON.parse(t);if(e==="connected"){let m=o;i.onConnected?.(m.connectionId)}else i.onEvent?.(o)}catch{i.onError?.(new Error(`Failed to parse event data: ${t}`))}}};var W=class extends a{constructor(e){super(e,"/v1/documents")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}async getXml(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/xml`,headers:{Accept:"application/xml"}})}};var B=class extends a{constructor(e){super(e,"/v1/tasks")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var H=class extends a{constructor(e){super(e,"/v1/expenses")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var K=class extends a{constructor(e){super(e,"/v1/notes")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var J=class extends a{constructor(e){super(e,"/v1/export")}async generate(e){return this.http.post(`${this.basePath}/data`,e)}async send(e){return this.http.post(`${this.basePath}/send`,e)}async generateFromTemplate(e){return this.http.request({method:"POST",url:`${this.basePath}/from-template`,data:e,responseType:"arraybuffer"})}async getFields(e){return this.http.get(`${this.basePath}/fields`,e?{scope:e}:void 0)}async getReportTypes(){return this.http.get(`${this.basePath}/report-types`)}async listTemplates(e){let t=await this.http.get(`${this.basePath}/templates`,e);return new p(t,r=>this.listTemplates({...e,page:r}))}async searchTemplates(e){let t=await this.http.post(`${this.basePath}/templates/search`,e);return this.createNavigablePage(t,r=>this.searchTemplates({...e,page:r}))}async createTemplate(e){return this.http.post(`${this.basePath}/templates`,e)}async getTemplate(e){return this.http.get(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async updateTemplate(e,t){return this.http.put(`${this.basePath}/templates/${encodeURIComponent(e)}`,t)}async deleteTemplate(e){return this.http.delete(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async listCustomFields(e){return this.http.get(`${this.basePath}/custom-fields`,e?{scope:e}:void 0)}async createCustomField(e){return this.http.post(`${this.basePath}/custom-fields`,e)}async getCustomField(e){return this.http.get(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}async updateCustomField(e,t){return this.http.put(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`,t)}async deleteCustomField(e){return this.http.delete(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}};var V=class{constructor(e){this.documents=new W(e),this.tasks=new B(e),this.expenses=new H(e),this.notes=new K(e),this.export=new J(e)}};var re=class{constructor(e){let t=this.createAuthentication(e),r=e.retryConfig||Q.default(),i={baseUrl:e.baseUrl||"https://api.timesheet.io",authentication:t,retryConfig:r,httpClient:e.httpClient};this.apiClient=new w(i);let o={baseUrl:e.reportsBaseUrl||"https://reports.timesheet.io",authentication:t,retryConfig:r,httpClient:e.reportsHttpClient};this.reportsApiClient=new w(o),this.organizations=new v(this.apiClient),this.teams=new k(this.apiClient),this.projects=new A(this.apiClient),this.tasks=new D(this.apiClient),this.rates=new $(this.apiClient),this.tags=new U(this.apiClient),this.expenses=new N(this.apiClient),this.notes=new I(this.apiClient),this.pauses=new q(this.apiClient),this.profile=new S(this.apiClient),this.settings=new O(this.apiClient),this.automations=new _(this.apiClient),this.documents=new L(this.apiClient),this.timer=new M(this.apiClient),this.todos=new z(this.apiClient),this.webhooks=new F(this.apiClient),this.events=new j(this.apiClient),this.reports=new V(this.reportsApiClient)}createAuthentication(e){if(e.apiKey)return new Z(e.apiKey);if(e.oauth2Token)return new E(e.oauth2Token);if(e.oauth2)return new E(e.oauth2.clientId,e.oauth2.clientSecret,e.oauth2.refreshToken);if(e.authentication)return e.authentication;throw new Error("Authentication must be configured")}};function As(s){return new re(s)}export{w as ApiClient,Z as ApiKeyAuth,_ as AutomationResource,W as DocumentReportResource,L as DocumentResource,j as EventResource,H as ExpenseReportResource,N as ExpenseResource,J as ExportResource,p as NavigablePage,K as NoteReportResource,I as NoteResource,ce as OAuth21Auth,E as OAuth2Auth,X as OAuthDiscovery,v as OrganizationResource,q as PauseResource,S as ProfileResource,A as ProjectResource,$ as RateResource,V as ReportsClient,a as Resource,Q as RetryConfig,O as SettingsResource,U as TagResource,B as TaskReportResource,D as TaskResource,k as TeamResource,M as TimerResource,g as TimesheetApiError,G as TimesheetAuthError,re as TimesheetClient,Y as TimesheetRateLimitError,z as TodoResource,pt as WebhookEvents,F as WebhookResource,ct as combineWebhookEvents,As as createClient,Je as discoverOAuth,de as generateCodeChallenge,le as generateCodeVerifier,ie as generatePkceCodePair,fe as getDefaultDiscovery,ae as isValidCodeVerifier};
1
+ import x from"axios";var g=class s extends Error{constructor(e,t,r,o){let a=t?o?`${e} (HTTP ${t}, Code: ${o})`:`${e} (HTTP ${t})`:e;super(a),this.name="TimesheetApiError",this.statusCode=t,this.responseBody=r,this.errorCode=o,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,s)}};var Q=class extends g{constructor(e,t=401,r){super(e,t,r,"authentication_error"),this.name="TimesheetAuthError"}};var ee=class extends g{constructor(e,t){super(e,429,void 0,"rate_limit_exceeded"),this.name="TimesheetRateLimitError",this.retryAfter=t}getRetryAfterDate(){if(!this.retryAfter)return null;let e=Number(this.retryAfter);if(!isNaN(e))return new Date(e*1e3);let t=new Date(this.retryAfter);return isNaN(t.getTime())?null:t}};var v=class{constructor(e){this.config=e,this.httpClient=e.httpClient||x.create({baseURL:e.baseUrl,timeout:3e4,headers:{"User-Agent":"Timesheet-TypeScript-SDK/1.1.0","Content-Type":"application/json"}}),this.httpClient.interceptors.request.use(async t=>{if(t.url!=="/oauth/token"&&this.config.authentication){let r=await this.config.authentication.getAuthHeaders();if(r)for(let[o,a]of Object.entries(r))t.headers.set(o,a)}return t})}async request(e){let t=null,r=this.config.retryConfig;for(let o=0;o<=r.maxRetries;o++)try{return(await this.httpClient.request(e)).data}catch(a){if(t=a,x.isAxiosError(a)&&a.response?.status===401){let c=a.response.data;throw new Q(c?.message||"Authentication failed",401,JSON.stringify(c))}if(x.isAxiosError(a)&&a.response?.status===429){let c=a.response.headers["retry-after"];throw new ee("Rate limit exceeded",c)}let m=x.isAxiosError(a)?a.response?.status:void 0;if(o<r.maxRetries&&m&&r.retryableStatusCodes.includes(m)){let c=Math.min(r.initialDelay*Math.pow(r.backoffMultiplier,o),r.maxDelay);await this.sleep(c);continue}if(x.isAxiosError(a)){let c=a.response?.data;throw new g(c?.message||a.message,a.response?.status,JSON.stringify(c),c?.code)}else throw a instanceof Error?new g(a.message):new g("Unknown error occurred")}throw t||new Error("Unknown error")}async get(e,t){return this.request({method:"GET",url:e,params:t})}async post(e,t,r){return this.request({method:"POST",url:e,data:t,params:r})}async put(e,t,r){return this.request({method:"PUT",url:e,data:t,params:r})}async delete(e,t,r){return this.request({method:"DELETE",url:e,data:r,params:t})}async postMultipart(e,t){return this.request({method:"POST",url:e,data:t,headers:{"Content-Type":"multipart/form-data"}})}sleep(e){return new Promise(t=>setTimeout(t,e))}getBaseUrl(){return this.config.baseUrl}async getAuthHeaders(){if(this.config.authentication)return this.config.authentication.getAuthHeaders()}};var te=class{constructor(e){this.apiKey=e;if(e===null)throw new Error("API key cannot be null");if(e===void 0)throw new Error("API key cannot be undefined");if(!e)throw new Error("API key cannot be empty");if(typeof e!="string")throw new Error("API key must be a string");if(e.trim().length===0)throw new Error("API key cannot be empty or whitespace");if(!this.isValidFormat(e))throw new Error("Invalid API key format")}isValidFormat(e){return/^ts_[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/.test(e)}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`ApiKey ${this.apiKey}`}needsRefresh(){return!1}async refresh(){throw new Error("API keys cannot be refreshed")}async getAuthHeaders(){return{Authorization:`ApiKey ${this.apiKey}`}}isValid(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0&&this.isValidFormat(this.apiKey)}};import pe from"axios";import le from"jsonwebtoken";var b=class b{constructor(e,t,r){t&&r?(this.clientId=e,this.clientSecret=t,this.refreshToken=r,this.accessToken=""):(this.accessToken=e,this.parseTokenExpiry())}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+300*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=await pe.post(b.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId,client_secret:this.clientSecret}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=e.data.access_token,e.data.refresh_token&&(this.refreshToken=e.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth2 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e,t,r,o){try{let a=await pe.post(b.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"authorization_code",code:r,redirect_uri:o,client_id:e,client_secret:t}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),m=a.data.access_token,c=a.data.refresh_token;return c?new b(e,t,c):new b(m)}catch(a){let m=a instanceof Error?a.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${m}`)}}static buildAuthorizationUrl(e,t,r){let o=new URLSearchParams({client_id:e,redirect_uri:t,response_type:"code"});return r&&o.append("state",r),`https://api.timesheet.io/oauth2/auth?${o.toString()}`}parseTokenExpiry(){try{let e=le.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+3600*1e3)}}};b.TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token";var A=b;import ue from"axios";import ye from"jsonwebtoken";import{randomBytes as ge,createHash as Pe}from"crypto";function fe(s=64){if(s<43||s>128)throw new Error("Code verifier length must be between 43 and 128 characters");let e=ge(Math.ceil(s*3/4));return he(e).slice(0,s)}function be(s,e="S256"){if(e==="plain")return s;let t=Pe("sha256").update(s,"ascii").digest();return he(t)}function ce(s="S256",e=64){let t=fe(e),r=be(t,s);return{codeVerifier:t,codeChallenge:r,codeChallengeMethod:s}}function me(s){return s.length<43||s.length>128?!1:/^[A-Za-z0-9\-._~]+$/.test(s)}function he(s){return s.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var P=class P{constructor(e){if(typeof e=="string")this.accessToken=e,this.tokenEndpoint=P.DEFAULT_TOKEN_ENDPOINT,this.parseTokenExpiry();else{let t=e;this.clientId=t.clientId,this.clientSecret=t.clientSecret,this.refreshToken=t.refreshToken,this.resource=t.resource,this.tokenEndpoint=t.tokenEndpoint??P.DEFAULT_TOKEN_ENDPOINT,this.accessToken=""}}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+300*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId});this.clientSecret&&e.append("client_secret",this.clientSecret),this.resource&&e.append("resource",this.resource);let t=await ue.post(this.tokenEndpoint,e,{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=t.data.access_token,t.data.refresh_token&&(this.refreshToken=t.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth 2.1 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e){let{clientId:t,clientSecret:r,authorizationCode:o,redirectUri:a,codeVerifier:m,resource:c,tokenEndpoint:l}=e,h=l??P.DEFAULT_TOKEN_ENDPOINT;if(!me(m))throw new Error("Invalid code verifier: must be 43-128 characters using only A-Z, a-z, 0-9, -, ., _, ~");try{let u=new URLSearchParams({grant_type:"authorization_code",code:o,redirect_uri:a,client_id:t,code_verifier:m});r&&u.append("client_secret",r),c&&u.append("resource",c);let d=await ue.post(h,u,{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),C=d.data.access_token,y=d.data.refresh_token;return y?new P({clientId:t,clientSecret:r,refreshToken:y,resource:c,tokenEndpoint:h}):new P(C)}catch(u){let d=u instanceof Error?u.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${d}`)}}static buildAuthorizationUrl(e){let{clientId:t,redirectUri:r,codeChallenge:o,codeChallengeMethod:a="S256",state:m,scope:c,resource:l,authorizationEndpoint:h}=e,u=h??P.DEFAULT_AUTH_ENDPOINT,d=new URLSearchParams({response_type:"code",client_id:t,redirect_uri:r,code_challenge:o,code_challenge_method:a});return m&&d.append("state",m),c&&d.append("scope",c),l&&d.append("resource",l),`${u}?${d.toString()}`}static generatePkce(e="S256"){return ce(e)}parseTokenExpiry(){try{let e=ye.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+3600*1e3)}}};P.DEFAULT_TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token",P.DEFAULT_AUTH_ENDPOINT="https://api.timesheet.io/oauth2/auth";var de=P;import oe from"axios";var T=class T{constructor(e={}){this.cache=new Map;this.options={cacheTtl:e.cacheTtl??T.DEFAULT_CACHE_TTL,timeout:e.timeout??T.DEFAULT_TIMEOUT,fetchOpenIdConfig:e.fetchOpenIdConfig??!1,fetchProtectedResource:e.fetchProtectedResource??!1}}async discover(e){let t=this.normalizeIssuerUrl(e),r=this.getCached(t);if(r)return r;let o=await this.fetchAuthorizationServerMetadata(t),a={issuer:o.issuer,authorizationServer:o,fetchedAt:new Date};if(this.options.fetchOpenIdConfig)try{a.openIdConfiguration=await this.fetchOpenIdConfiguration(t)}catch{}if(this.options.fetchProtectedResource)try{a.protectedResource=await this.fetchProtectedResourceMetadata(t)}catch{}return this.setCache(t,a),a}async fetchAuthorizationServerMetadata(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/oauth-authorization-server`;try{let r=await oe.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateAuthorizationServerMetadata(r.data),r.data}catch(r){let o=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch authorization server metadata from ${t}: ${o}`)}}async fetchOpenIdConfiguration(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/openid-configuration`;try{let r=await oe.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateOpenIdConfiguration(r.data),r.data}catch(r){let o=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch OpenID configuration from ${t}: ${o}`)}}async fetchProtectedResourceMetadata(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/oauth-protected-resource`;try{let r=await oe.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateProtectedResourceMetadata(r.data),r.data}catch(r){let o=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch protected resource metadata from ${t}: ${o}`)}}clearCache(){this.cache.clear()}clearCacheForIssuer(e){this.cache.delete(this.normalizeIssuerUrl(e))}isCached(e){return this.getCached(this.normalizeIssuerUrl(e))!==null}normalizeIssuerUrl(e){return e.replace(/\/+$/,"")}getCached(e){let t=this.cache.get(e);return t?new Date>=t.expiresAt?(this.cache.delete(e),null):t.result:null}setCache(e,t){let r=new Date(Date.now()+this.options.cacheTtl);this.cache.set(e,{result:t,expiresAt:r})}validateAuthorizationServerMetadata(e){if(!e.issuer)throw new Error("Authorization server metadata missing required field: issuer");if(!e.authorization_endpoint)throw new Error("Authorization server metadata missing required field: authorization_endpoint");if(!e.token_endpoint)throw new Error("Authorization server metadata missing required field: token_endpoint");if(!e.response_types_supported||e.response_types_supported.length===0)throw new Error("Authorization server metadata missing required field: response_types_supported")}validateOpenIdConfiguration(e){if(!e.issuer)throw new Error("OpenID configuration missing required field: issuer");if(!e.authorization_endpoint)throw new Error("OpenID configuration missing required field: authorization_endpoint");if(!e.token_endpoint)throw new Error("OpenID configuration missing required field: token_endpoint");if(!e.jwks_uri)throw new Error("OpenID configuration missing required field: jwks_uri")}validateProtectedResourceMetadata(e){if(!e.resource)throw new Error("Protected resource metadata missing required field: resource");if(!e.authorization_servers||e.authorization_servers.length===0)throw new Error("Protected resource metadata missing required field: authorization_servers")}};T.DEFAULT_CACHE_TTL=3600*1e3,T.DEFAULT_TIMEOUT=1e4;var re=T,ae=null;function Te(){return ae||(ae=new re),ae}async function Ze(s,e){return(e?new re(e):Te()).discover(s)}var se=class s{constructor(e={}){this.maxRetries=e.maxRetries??3,this.initialDelay=e.initialDelay??100,this.maxDelay=e.maxDelay??1e4,this.backoffMultiplier=e.backoffMultiplier??2,this.retryableStatusCodes=e.retryableStatusCodes??[429,502,503,504]}static default(){return new s}};var p=class{constructor(e,t){this.items=e.items,this.params=e.params,this.nextPageLoader=t}get totalPages(){return Math.ceil((this.params?.count||0)/(this.params?.limit||25))}get hasNextPage(){return(this.params?.page||1)<this.totalPages}async nextPage(){if(!this.hasNextPage)throw new Error("No more pages available");if(!this.nextPageLoader)throw new Error("Next page loader not configured");return this.nextPageLoader((this.params.page||1)+1)}async*[Symbol.asyncIterator](){let e=this;for(;;){for(let t of e.items)yield t;if(!e.hasNextPage)break;e=await e.nextPage()}}async toArray(){let e=[];for await(let t of this)e.push(t);return e}};var ut={TEAM_CREATE:"team.create",TEAM_UPDATE:"team.update",PROJECT_CREATE:"project.create",PROJECT_UPDATE:"project.update",TODO_CREATE:"todo.create",TODO_UPDATE:"todo.update",TASK_CREATE:"task.create",TASK_UPDATE:"task.update",TAG_CREATE:"tag.create",TAG_UPDATE:"tag.update",RATE_CREATE:"rate.create",RATE_UPDATE:"rate.update",TIMER_START:"timer.start",TIMER_STOP:"timer.stop",TIMER_PAUSE:"timer.pause",TIMER_RESUME:"timer.resume"};function dt(...s){return s.join(",")}var i=class{constructor(e,t){this.http=e;typeof t=="string"?this.basePath=t:this.basePath=t.basePath}createNavigablePage(e,t){return new p(e,t)}};var w=class extends i{constructor(e){super(e,"/v1/organizations")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async listMembers(e,t){let r=await this.http.post(`${this.basePath}/${encodeURIComponent(e)}/members/list`,t);return this.createNavigablePage(r,o=>this.listMembers(e,{...t,page:o}))}async getMember(e,t){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`)}async addMember(e,t){return this.http.post(`${this.basePath}/${encodeURIComponent(e)}/members`,t)}async updateMember(e,t,r){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`,r)}async removeMember(e,t){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`)}};var E=class extends i{constructor(e){super(e,"/v1/teams")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async listMembers(e,t){let r=await this.http.post(`${this.basePath}/${e}/members/list`,t);return this.createNavigablePage(r,o=>this.listMembers(e,{...t,page:o}))}async getMember(e,t){return this.http.get(`${this.basePath}/${e}/members/${t}`)}async getColleagues(e){let t=await this.http.post(`${this.basePath}/getColleagues`,e);return this.createNavigablePage(t,r=>this.getColleagues({...e,page:r}))}async addMember(e,t){return this.http.post(`${this.basePath}/${e}/members`,t)}async updateMember(e,t,r){return this.http.put(`${this.basePath}/${e}/members/${t}`,r)}async removeMember(e,t){return this.http.delete(`${this.basePath}/${e}/members/${t}`)}async removeInvitedMember(e,t){return this.http.delete(`${this.basePath}/${e}/members/${t}/invited`)}async batchAddMembers(e){return this.http.post(`${this.basePath}/batchTeamMembers`,e)}async getMemberStatus(e){let t=await this.http.post(`${this.basePath}/getMemberStatus`,e);return this.createNavigablePage(t,r=>this.getMemberStatus({...e,page:r}))}};var $=class extends i{constructor(e){super(e,"/v1/projects")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async listMembers(e,t){let r=await this.http.post(`${this.basePath}/${encodeURIComponent(e)}/members/list`,t);return this.createNavigablePage(r,o=>this.listMembers(e,{...t,page:o}))}async addMember(e,t){return this.http.post(`${this.basePath}/${encodeURIComponent(e)}/members`,t)}async getMember(e,t){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`)}async updateMember(e,t,r){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`,r)}async updateMembers(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}/members`,t)}async removeMember(e,t){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`)}async batchAddMembers(e,t){return this.http.post(`${this.basePath}/${encodeURIComponent(e)}/members/batch`,t)}async batchRemoveMembers(e,t){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}/members/batch`,void 0,t)}};import R from"dayjs";import Re from"dayjs/plugin/utc";import Ce from"dayjs/plugin/timezone";import xe from"dayjs/plugin/customParseFormat";R.extend(Re);R.extend(Ce);R.extend(xe);var ve="YYYY-MM-DDTHH:mm:ssZ",Ae=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$/,n={isValidTimestampFormat(s){return Ae.test(s)},formatTimestamp(s){return typeof s=="string"&&this.isValidTimestampFormat(s)?s:R(s||new Date).format(ve)},parseTimestamp(s){return R(s).toDate()},formatDate(s){return R(s||new Date).format("YYYY-MM-DD")},now(){return this.formatTimestamp()}};var k=class extends i{constructor(e){super(e,"/v1/tasks")}async list(e){let t=await this.http.get(this.basePath,e);return this.createNavigablePage(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:t.startDateTime?n.formatTimestamp(t.startDateTime):void 0,endDateTime:t.endDateTime?n.formatTimestamp(t.endDateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async statistics(e){return this.http.post(`${this.basePath}/statistics`,e)}async updateStatus(e){return this.http.put(`${this.basePath}/updateStatus`,e)}async updateTimes(e){let t={...e,start:n.formatTimestamp(e.start),end:n.formatTimestamp(e.end)};return this.http.put(`${this.basePath}/updateTimes`,t)}async print(e){return this.http.request({method:"GET",url:`${this.basePath}/print/${encodeURIComponent(e)}`,responseType:"arraybuffer"})}};var U=class extends i{constructor(e){super(e,"/v1/rates")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var D=class extends i{constructor(e){super(e,"/v1/tags")}async list(e){let t=await this.http.get(this.basePath,e);return new p({items:t??[],params:e??{}},r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var I=class extends i{constructor(e){super(e,"/v1/expenses")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:n.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:t.dateTime?n.formatTimestamp(t.dateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async updateStatus(e){return this.http.put(`${this.basePath}/updateStatus`,e)}async uploadFile(e,t){let r=new FormData;return r.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/${encodeURIComponent(e)}/file`,r)}async createWithFile(e){let{file:t,...r}=e,o={...r,dateTime:n.formatTimestamp(r.dateTime)},a=new FormData;return a.append("data",new Blob([JSON.stringify(o)],{type:"application/json"})),t&&a.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/with-file`,a)}async getFileUrl(e){return this.http.get(`${this.basePath}/getFileUrl/${encodeURIComponent(e)}`)}};var N=class extends i{constructor(e){super(e,"/v1/notes")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:n.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:n.formatTimestamp(t.dateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async uploadFile(e,t){let r=new FormData;return r.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/${encodeURIComponent(e)}/file`,r)}async createWithFile(e){let{file:t,...r}=e,o={...r,dateTime:n.formatTimestamp(r.dateTime)},a=new FormData;return a.append("data",new Blob([JSON.stringify(o)],{type:"application/json"})),t&&a.append("file",t.file,t.fileName),this.http.postMultipart(`${this.basePath}/with-file`,a)}async getFileUrl(e){return this.http.get(`${this.basePath}/getFileUrl/${encodeURIComponent(e)}`)}};var q=class extends i{constructor(e){super(e,"/v1/pauses")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:n.formatTimestamp(e.endDateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:n.formatTimestamp(t.startDateTime),endDateTime:n.formatTimestamp(t.endDateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var M=class{constructor(e){this.http=e}async getProfile(){return this.http.get("/v1/profiles/me")}async updateProfile(e){return this.http.put("/v1/profiles/me",e)}};var S=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/settings")}async update(e){return this.http.put("/v1/settings",e)}};var O=class extends i{constructor(e){super(e,"/v1/automations")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var L=class extends i{constructor(e){super(e,"/v1/documents")}async list(e){let{category:t,...r}=e??{},o=t!==void 0?{...r,type:t}:{...r},a=await this.http.get(this.basePath,o);return new p(a,m=>this.list({...e,page:m}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var _=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/timer")}async start(e){let t={...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):n.formatTimestamp()};return this.http.post("/v1/timer/start",t)}async stop(e){let t=e?{...e,endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):n.formatTimestamp()}:{endDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/stop",t)}async pause(e){let t=e?{...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):n.formatTimestamp()}:{startDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/pause",t)}async resume(e){let t=e?{...e,endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):n.formatTimestamp()}:{endDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/resume",t)}async update(e){let t={...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):void 0};return this.http.put("/v1/timer/update",t)}};var z=class extends i{constructor(e){super(e,"/v1/todos")}async list(e){let t=await this.http.get(this.basePath,e);return new p({items:t??[],params:e??{}},r=>this.list({...e,page:r}))}async create(e){let t={...e,dueDate:e.dueDate?n.formatTimestamp(e.dueDate):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dueDate:t.dueDate?n.formatTimestamp(t.dueDate):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var F=class extends i{constructor(e){super(e,"/v1/webhooks")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var j=class extends i{constructor(e){super(e,"/v1/events")}async getStatus(){return this.http.get(`${this.basePath}/status`)}getStreamUrl(){return`${this.http.getBaseUrl()}${this.basePath}/stream`}async subscribe(e){let t=this.getStreamUrl(),o={Accept:"text/event-stream","Cache-Control":"no-cache",...await this.http.getAuthHeaders()},a=new AbortController,m=!1,c=new Map,l={close:()=>{m=!1,a.abort(),e.onClose?.()},get isConnected(){return m},on:(h,u)=>{c.has(h)||c.set(h,new Set),c.get(h).add(u)},off:(h,u)=>{c.get(h)?.delete(u)}};return this.connectSse(t,o,a.signal,{...e,onConnected:h=>{m=!0,e.onConnected?.(h)},onEvent:h=>{e.onEvent?.(h),c.get(h.event)?.forEach(d=>d(h))},onError:h=>{e.onError?.(h),c.get("error")?.forEach(d=>d(h))},onClose:()=>{m=!1,e.onClose?.()}}),l}async connectSse(e,t,r,o){try{let a=await fetch(e,{method:"GET",headers:t,signal:r});if(!a.ok)throw new Error(`SSE connection failed: ${a.status} ${a.statusText}`);if(!a.body)throw new Error("SSE response has no body");let m=a.body.getReader(),c=new TextDecoder,l="",h="",u="",d="",C=!1;for(;!C;){let y=await m.read();if(C=y.done,C||!y.value){o.onClose?.();break}l+=c.decode(y.value,{stream:!0});let ne=l.split(`
2
+ `);l=ne.pop()||"";for(let f of ne)f.startsWith("event:")?h=f.slice(6).trim():f.startsWith("data:")?u=f.slice(5).trim():f.startsWith("id:")?d=f.slice(3).trim():f===""&&(u&&this.processEvent(h,u,d,o),h="",u="",d="")}}catch(a){if(r.aborted)return;o.onError?.(a)}}processEvent(e,t,r,o){try{let a=JSON.parse(t);if(e==="connected"){let m=a;o.onConnected?.(m.connectionId)}else o.onEvent?.(a)}catch{o.onError?.(new Error(`Failed to parse event data: ${t}`))}}};var W=class extends i{constructor(e){super(e,"/v1/organizations")}orgPath(e){return`${this.basePath}/${encodeURIComponent(e)}/absences`}async list(e,t){let r=await this.http.get(this.orgPath(e),t);return this.createNavigablePage(r,o=>this.list(e,{...t,page:o}))}async search(e,t){let r=await this.http.post(`${this.orgPath(e)}/search`,t);return this.createNavigablePage(r,o=>this.search(e,{...t,page:o}))}async create(e,t){return this.http.post(this.orgPath(e),t)}async get(e,t){return this.http.get(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}async update(e,t,r){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}`,r)}async delete(e,t){return this.http.delete(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}async approve(e,t){return this.http.post(`${this.orgPath(e)}/${encodeURIComponent(t)}/approve`)}async reject(e,t,r){return this.http.post(`${this.orgPath(e)}/${encodeURIComponent(t)}/reject`,r)}async cancel(e,t,r){return this.http.post(`${this.orgPath(e)}/${encodeURIComponent(t)}/cancel`,r)}};var B=class extends i{constructor(e){super(e,"/v1/organizations")}orgPath(e){return`${this.basePath}/${encodeURIComponent(e)}/absence-types`}async list(e,t){let r=await this.http.get(this.orgPath(e),t);return this.createNavigablePage(r,o=>this.list(e,{...t,page:o}))}async create(e,t){return this.http.post(this.orgPath(e),t)}async get(e,t){return this.http.get(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}async update(e,t,r){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}`,r)}async delete(e,t){return this.http.delete(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}};var H=class extends i{constructor(e){super(e,"/v1/organizations")}orgPath(e){return`${this.basePath}/${encodeURIComponent(e)}/contracts`}async list(e,t){let r=await this.http.get(this.orgPath(e),t);return this.createNavigablePage(r,o=>this.list(e,{...t,page:o}))}async create(e,t){return this.http.post(this.orgPath(e),t)}async get(e,t){return this.http.get(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}async update(e,t,r){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}`,r)}async delete(e,t){return this.http.delete(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}async activate(e,t){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}/activate`)}async suspend(e,t){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}/suspend`)}async reactivate(e,t){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}/reactivate`)}async terminate(e,t){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}/terminate`)}};var K=class extends i{constructor(e){super(e,"/v1/organizations")}orgPath(e){return`${this.basePath}/${encodeURIComponent(e)}/contract-templates`}async list(e,t){let r=await this.http.get(this.orgPath(e),t);return this.createNavigablePage(r,o=>this.list(e,{...t,page:o}))}async create(e,t){return this.http.post(this.orgPath(e),t)}async get(e,t){return this.http.get(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}async update(e,t,r){return this.http.put(`${this.orgPath(e)}/${encodeURIComponent(t)}`,r)}async delete(e,t){return this.http.delete(`${this.orgPath(e)}/${encodeURIComponent(t)}`)}};var J=class extends i{constructor(e){super(e,"/v1/documents")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}async getXml(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/xml`,headers:{Accept:"application/xml"}})}};var V=class extends i{constructor(e){super(e,"/v1/tasks")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var G=class extends i{constructor(e){super(e,"/v1/expenses")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var Y=class extends i{constructor(e){super(e,"/v1/notes")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var Z=class extends i{constructor(e){super(e,"/v1/export")}async generate(e){return this.http.post(`${this.basePath}/data`,e)}async send(e){return this.http.post(`${this.basePath}/send`,e)}async generateFromTemplate(e){return this.http.request({method:"POST",url:`${this.basePath}/from-template`,data:e,responseType:"arraybuffer"})}async getFields(e){return this.http.get(`${this.basePath}/fields`,e?{scope:e}:void 0)}async getReportTypes(){return this.http.get(`${this.basePath}/report-types`)}async listTemplates(e){let t=await this.http.get(`${this.basePath}/templates`,e);return new p(t,r=>this.listTemplates({...e,page:r}))}async searchTemplates(e){let t=await this.http.post(`${this.basePath}/templates/search`,e);return this.createNavigablePage(t,r=>this.searchTemplates({...e,page:r}))}async createTemplate(e){return this.http.post(`${this.basePath}/templates`,e)}async getTemplate(e){return this.http.get(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async updateTemplate(e,t){return this.http.put(`${this.basePath}/templates/${encodeURIComponent(e)}`,t)}async deleteTemplate(e){return this.http.delete(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async listCustomFields(e){return this.http.get(`${this.basePath}/custom-fields`,e?{scope:e}:void 0)}async createCustomField(e){return this.http.post(`${this.basePath}/custom-fields`,e)}async getCustomField(e){return this.http.get(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}async updateCustomField(e,t){return this.http.put(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`,t)}async deleteCustomField(e){return this.http.delete(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}};var X=class{constructor(e){this.documents=new J(e),this.tasks=new V(e),this.expenses=new G(e),this.notes=new Y(e),this.export=new Z(e)}};var ie=class{constructor(e){let t=this.createAuthentication(e),r=e.retryConfig||se.default(),o={baseUrl:e.baseUrl||"https://api.timesheet.io",authentication:t,retryConfig:r,httpClient:e.httpClient};this.apiClient=new v(o);let a={baseUrl:e.reportsBaseUrl||"https://reports.timesheet.io",authentication:t,retryConfig:r,httpClient:e.reportsHttpClient};this.reportsApiClient=new v(a),this.organizations=new w(this.apiClient),this.teams=new E(this.apiClient),this.projects=new $(this.apiClient),this.tasks=new k(this.apiClient),this.rates=new U(this.apiClient),this.tags=new D(this.apiClient),this.expenses=new I(this.apiClient),this.notes=new N(this.apiClient),this.pauses=new q(this.apiClient),this.profile=new M(this.apiClient),this.settings=new S(this.apiClient),this.automations=new O(this.apiClient),this.documents=new L(this.apiClient),this.timer=new _(this.apiClient),this.todos=new z(this.apiClient),this.webhooks=new F(this.apiClient),this.events=new j(this.apiClient),this.absences=new W(this.apiClient),this.absenceTypes=new B(this.apiClient),this.contracts=new H(this.apiClient),this.contractTemplates=new K(this.apiClient),this.reports=new X(this.reportsApiClient)}createAuthentication(e){if(e.apiKey)return new te(e.apiKey);if(e.oauth2Token)return new A(e.oauth2Token);if(e.oauth2)return new A(e.oauth2.clientId,e.oauth2.clientSecret,e.oauth2.refreshToken);if(e.authentication)return e.authentication;throw new Error("Authentication must be configured")}};function Ks(s){return new ie(s)}export{W as AbsenceResource,B as AbsenceTypeResource,v as ApiClient,te as ApiKeyAuth,O as AutomationResource,H as ContractResource,K as ContractTemplateResource,J as DocumentReportResource,L as DocumentResource,j as EventResource,G as ExpenseReportResource,I as ExpenseResource,Z as ExportResource,p as NavigablePage,Y as NoteReportResource,N as NoteResource,de as OAuth21Auth,A as OAuth2Auth,re as OAuthDiscovery,w as OrganizationResource,q as PauseResource,M as ProfileResource,$ as ProjectResource,U as RateResource,X as ReportsClient,i as Resource,se as RetryConfig,S as SettingsResource,D as TagResource,V as TaskReportResource,k as TaskResource,E as TeamResource,_ as TimerResource,g as TimesheetApiError,Q as TimesheetAuthError,ie as TimesheetClient,ee as TimesheetRateLimitError,z as TodoResource,ut as WebhookEvents,F as WebhookResource,dt as combineWebhookEvents,Ks as createClient,Ze as discoverOAuth,be as generateCodeChallenge,fe as generateCodeVerifier,ce as generatePkceCodePair,Te as getDefaultDiscovery,me as isValidCodeVerifier};
3
3
  //# sourceMappingURL=index.mjs.map