node-paymo-api 0.0.3 → 0.0.5

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 (194) hide show
  1. package/.prettierrc +6 -0
  2. package/README.md +24 -1
  3. package/dist/abstract.d.ts +23 -0
  4. package/dist/abstract.js +210 -0
  5. package/dist/index.d.ts +6 -0
  6. package/dist/index.js +18 -0
  7. package/dist/remote.d.ts +9 -0
  8. package/dist/remote.js +80 -0
  9. package/dist/resources/_template_/index.d.ts +18 -0
  10. package/dist/resources/_template_/index.js +34 -0
  11. package/dist/resources/_template_/types.d.ts +25 -0
  12. package/dist/resources/_template_/types.js +2 -0
  13. package/dist/resources/bookings/index.d.ts +18 -0
  14. package/dist/resources/bookings/index.js +49 -0
  15. package/dist/resources/bookings/types.d.ts +49 -0
  16. package/dist/resources/bookings/types.js +2 -0
  17. package/dist/resources/clientcontacts/index.d.ts +18 -0
  18. package/dist/resources/clientcontacts/index.js +34 -0
  19. package/dist/resources/clientcontacts/types.d.ts +59 -0
  20. package/dist/resources/clientcontacts/types.js +2 -0
  21. package/dist/resources/clients/index.d.ts +18 -0
  22. package/dist/resources/clients/index.js +34 -0
  23. package/dist/resources/clients/types.d.ts +71 -0
  24. package/dist/resources/clients/types.js +2 -0
  25. package/dist/resources/comments/Comments.d.ts +18 -0
  26. package/dist/resources/comments/Comments.js +34 -0
  27. package/dist/resources/comments/Threads.d.ts +28 -0
  28. package/dist/resources/comments/Threads.js +25 -0
  29. package/dist/resources/comments/index.d.ts +2 -0
  30. package/dist/resources/comments/index.js +7 -0
  31. package/dist/resources/comments/types.d.ts +77 -0
  32. package/dist/resources/comments/types.js +2 -0
  33. package/dist/resources/company/index.d.ts +12 -0
  34. package/dist/resources/company/index.js +25 -0
  35. package/dist/resources/company/types.d.ts +44 -0
  36. package/dist/resources/company/types.js +2 -0
  37. package/dist/resources/discussions/index.d.ts +18 -0
  38. package/dist/resources/discussions/index.js +34 -0
  39. package/dist/resources/discussions/types.d.ts +43 -0
  40. package/dist/resources/discussions/types.js +2 -0
  41. package/dist/resources/entries/index.d.ts +18 -0
  42. package/dist/resources/entries/index.js +47 -0
  43. package/dist/resources/entries/types.d.ts +53 -0
  44. package/dist/resources/entries/types.js +2 -0
  45. package/dist/resources/estimates/EstimateItem.d.ts +3 -0
  46. package/dist/resources/estimates/EstimateItem.js +5 -0
  47. package/dist/resources/estimates/Estimates.d.ts +18 -0
  48. package/dist/resources/estimates/Estimates.js +34 -0
  49. package/dist/resources/estimates/index.d.ts +2 -0
  50. package/dist/resources/estimates/index.js +7 -0
  51. package/dist/resources/estimates/types.d.ts +76 -0
  52. package/dist/resources/estimates/types.js +2 -0
  53. package/dist/resources/estimatetemplates/index.d.ts +18 -0
  54. package/dist/resources/estimatetemplates/index.js +34 -0
  55. package/dist/resources/estimatetemplates/types.d.ts +34 -0
  56. package/dist/resources/estimatetemplates/types.js +2 -0
  57. package/dist/resources/expenses/index.d.ts +18 -0
  58. package/dist/resources/expenses/index.js +34 -0
  59. package/dist/resources/expenses/types.d.ts +46 -0
  60. package/dist/resources/expenses/types.js +2 -0
  61. package/dist/resources/files/index.d.ts +18 -0
  62. package/dist/resources/files/index.js +45 -0
  63. package/dist/resources/files/types.d.ts +44 -0
  64. package/dist/resources/files/types.js +2 -0
  65. package/dist/resources/index.d.ts +117 -0
  66. package/dist/resources/index.js +200 -0
  67. package/dist/resources/invoices/InvoiceItem.d.ts +3 -0
  68. package/dist/resources/invoices/InvoiceItem.js +5 -0
  69. package/dist/resources/invoices/Invoices.d.ts +18 -0
  70. package/dist/resources/invoices/Invoices.js +34 -0
  71. package/dist/resources/invoices/index.d.ts +2 -0
  72. package/dist/resources/invoices/index.js +7 -0
  73. package/dist/resources/invoices/types.d.ts +87 -0
  74. package/dist/resources/invoices/types.js +2 -0
  75. package/dist/resources/invoicetemplates/index.d.ts +18 -0
  76. package/dist/resources/invoicetemplates/index.js +34 -0
  77. package/dist/resources/invoicetemplates/types.d.ts +34 -0
  78. package/dist/resources/invoicetemplates/types.js +2 -0
  79. package/dist/resources/milestones/index.d.ts +18 -0
  80. package/dist/resources/milestones/index.js +34 -0
  81. package/dist/resources/milestones/types.d.ts +40 -0
  82. package/dist/resources/milestones/types.js +2 -0
  83. package/dist/resources/projects/index.d.ts +20 -0
  84. package/dist/resources/projects/index.js +39 -0
  85. package/dist/resources/projects/types.d.ts +86 -0
  86. package/dist/resources/projects/types.js +14 -0
  87. package/dist/resources/projectstatuses/index.d.ts +18 -0
  88. package/dist/resources/projectstatuses/index.js +34 -0
  89. package/dist/resources/projectstatuses/types.d.ts +32 -0
  90. package/dist/resources/projectstatuses/types.js +2 -0
  91. package/dist/resources/projecttemplates/index.d.ts +18 -0
  92. package/dist/resources/projecttemplates/index.js +34 -0
  93. package/dist/resources/projecttemplates/types.d.ts +29 -0
  94. package/dist/resources/projecttemplates/types.js +2 -0
  95. package/dist/resources/reports/index.d.ts +18 -0
  96. package/dist/resources/reports/index.js +34 -0
  97. package/dist/resources/reports/types.d.ts +90 -0
  98. package/dist/resources/reports/types.js +2 -0
  99. package/dist/resources/sessions/index.d.ts +18 -0
  100. package/dist/resources/sessions/index.js +35 -0
  101. package/dist/resources/sessions/types.d.ts +28 -0
  102. package/dist/resources/sessions/types.js +2 -0
  103. package/dist/resources/tasklists/index.d.ts +18 -0
  104. package/dist/resources/tasklists/index.js +34 -0
  105. package/dist/resources/tasklists/types.d.ts +35 -0
  106. package/dist/resources/tasklists/types.js +2 -0
  107. package/dist/resources/tasks/index.d.ts +18 -0
  108. package/dist/resources/tasks/index.js +34 -0
  109. package/dist/resources/tasks/types.d.ts +64 -0
  110. package/dist/resources/tasks/types.js +2 -0
  111. package/dist/resources/users/index.d.ts +22 -0
  112. package/dist/resources/users/index.js +40 -0
  113. package/dist/resources/users/types.d.ts +86 -0
  114. package/dist/resources/users/types.js +2 -0
  115. package/dist/resources/usertasks/index.d.ts +18 -0
  116. package/dist/resources/usertasks/index.js +41 -0
  117. package/dist/resources/usertasks/types.d.ts +31 -0
  118. package/dist/resources/usertasks/types.js +2 -0
  119. package/dist/resources/workflows/index.d.ts +18 -0
  120. package/dist/resources/workflows/index.js +34 -0
  121. package/dist/resources/workflows/types.d.ts +31 -0
  122. package/dist/resources/workflows/types.js +2 -0
  123. package/dist/resources/workflowstatuses/index.d.ts +18 -0
  124. package/dist/resources/workflowstatuses/index.js +34 -0
  125. package/dist/resources/workflowstatuses/types.d.ts +35 -0
  126. package/dist/resources/workflowstatuses/types.js +2 -0
  127. package/dist/types.d.ts +25 -0
  128. package/dist/types.js +2 -0
  129. package/package.json +13 -3
  130. package/src/abstract.ts +220 -0
  131. package/src/index.ts +23 -0
  132. package/src/remote.ts +77 -0
  133. package/src/resources/_template_/index.ts +38 -0
  134. package/src/resources/_template_/types.ts +40 -0
  135. package/src/resources/bookings/index.ts +61 -0
  136. package/src/resources/bookings/types.ts +60 -0
  137. package/src/resources/clientcontacts/index.ts +38 -0
  138. package/src/resources/clientcontacts/types.ts +69 -0
  139. package/src/resources/clients/index.ts +38 -0
  140. package/src/resources/clients/types.ts +100 -0
  141. package/src/resources/comments/Comments.ts +38 -0
  142. package/src/resources/comments/Threads.ts +28 -0
  143. package/src/resources/comments/index.ts +2 -0
  144. package/src/resources/comments/types.ts +105 -0
  145. package/src/resources/company/index.ts +23 -0
  146. package/src/resources/company/types.ts +52 -0
  147. package/src/resources/discussions/index.ts +38 -0
  148. package/src/resources/discussions/types.ts +53 -0
  149. package/src/resources/entries/index.ts +52 -0
  150. package/src/resources/entries/types.ts +67 -0
  151. package/src/resources/estimates/EstimateItem.ts +6 -0
  152. package/src/resources/estimates/Estimates.ts +38 -0
  153. package/src/resources/estimates/index.ts +2 -0
  154. package/src/resources/estimates/types.ts +89 -0
  155. package/src/resources/estimatetemplates/index.ts +38 -0
  156. package/src/resources/estimatetemplates/types.ts +46 -0
  157. package/src/resources/expenses/index.ts +38 -0
  158. package/src/resources/expenses/types.ts +58 -0
  159. package/src/resources/files/index.ts +50 -0
  160. package/src/resources/files/types.ts +58 -0
  161. package/src/resources/index.ts +289 -0
  162. package/src/resources/invoices/InvoiceItem.ts +6 -0
  163. package/src/resources/invoices/Invoices.ts +38 -0
  164. package/src/resources/invoices/index.ts +2 -0
  165. package/src/resources/invoices/types.ts +102 -0
  166. package/src/resources/invoicetemplates/index.ts +38 -0
  167. package/src/resources/invoicetemplates/types.ts +46 -0
  168. package/src/resources/milestones/index.ts +38 -0
  169. package/src/resources/milestones/types.ts +52 -0
  170. package/src/resources/projects/index.ts +47 -0
  171. package/src/resources/projects/types.ts +134 -0
  172. package/src/resources/projectstatuses/index.ts +38 -0
  173. package/src/resources/projectstatuses/types.ts +44 -0
  174. package/src/resources/projecttemplates/index.ts +40 -0
  175. package/src/resources/projecttemplates/types.ts +43 -0
  176. package/src/resources/reports/index.ts +38 -0
  177. package/src/resources/reports/types.ts +104 -0
  178. package/src/resources/sessions/index.ts +39 -0
  179. package/src/resources/sessions/types.ts +43 -0
  180. package/src/resources/tasklists/index.ts +38 -0
  181. package/src/resources/tasklists/types.ts +48 -0
  182. package/src/resources/tasks/index.ts +38 -0
  183. package/src/resources/tasks/types.ts +76 -0
  184. package/src/resources/users/index.ts +48 -0
  185. package/src/resources/users/types.ts +124 -0
  186. package/src/resources/usertasks/index.ts +46 -0
  187. package/src/resources/usertasks/types.ts +43 -0
  188. package/src/resources/workflows/index.ts +38 -0
  189. package/src/resources/workflows/types.ts +43 -0
  190. package/src/resources/workflowstatuses/index.ts +38 -0
  191. package/src/resources/workflowstatuses/types.ts +47 -0
  192. package/src/types.ts +40 -0
  193. package/tsconfig.json +12 -0
  194. package/lib/index.ts +0 -6
@@ -0,0 +1,220 @@
1
+ import { AuthInterface, GenericCustomFilterType, GenericFilterType, GenericListConfig } from "./types"
2
+ import XhrWrapper from './remote'
3
+
4
+ export interface AbstractResourceInterface {}
5
+
6
+ export class AbstractResource {
7
+ protected auth: AuthInterface = { userApi: '', password: '' }
8
+ protected resourceKey: string | null = null
9
+ protected responseKey: string | null = null
10
+ protected filterDates: string[] = []
11
+
12
+ constructor(auth: AuthInterface, resourceKey: string, responseKey: string | null = null) {
13
+ this.auth = auth
14
+ this.resourceKey = resourceKey
15
+ this.responseKey = responseKey
16
+ }
17
+
18
+ private constructUrl = (id?: number|null) => {
19
+ return this.resourceKey + (id ? '/' + id : '')
20
+ }
21
+
22
+ private constructAuth = () => {
23
+ return {
24
+ username: this.auth.userApi,
25
+ password: this.auth.password || 'apiKey',
26
+ }
27
+ }
28
+
29
+ private constructHeaders = () => {
30
+ return {
31
+ Accept: 'application/json',
32
+ }
33
+ }
34
+
35
+ private isTimestampKey = (k:string) => {
36
+ return ['created_on', 'updated_on'].findIndex(i=>k===i) > -1
37
+ }
38
+
39
+ private toTimestamp = (dt:string) => {
40
+ return Math.round((new Date(dt)).getTime() / 1000);
41
+ }
42
+
43
+ private processCustomFilters = (filters:GenericCustomFilterType) => {
44
+ const whereVar = Object.keys(filters).map(k=>{
45
+ const f = filters[k]
46
+ const fVal = f.value
47
+ const rKey = f.key ? f.key : k
48
+ const rOp = f.operator ? f.operator : '='
49
+ const rVal =
50
+ this.isTimestampKey(rKey) && typeof fVal === 'string'
51
+ ? this.toTimestamp(fVal)
52
+ : fVal
53
+ switch (f.operator) {
54
+ case 'in':
55
+ case 'not in':
56
+ const v = Array.isArray(rVal) ? rVal : [rVal]
57
+ return rKey + ' ' + rOp + ' (' + v.join(',') + ')'
58
+ case 'like':
59
+ case 'not like':
60
+ return rKey + ' ' + rOp + ' "' + rVal + '"'
61
+ default:
62
+ return rKey + rOp + rVal
63
+ }
64
+ }).filter(s=>s!=='').join(' and ')
65
+ return whereVar.trim()
66
+ }
67
+
68
+ private constructFilter = (
69
+ filters: GenericFilterType
70
+ ): string | null => {
71
+ const whereVar = Object.keys(filters).map(k=>{
72
+ const f = filters[k]
73
+ if (k==='_custom') {
74
+ return this.processCustomFilters(f)
75
+ } else if (Array.isArray(f)) {
76
+ return (k+' in ('+f.join(',')+')')
77
+ } else if (f === null || typeof f === 'string' || typeof f === 'number' || typeof f === 'boolean') {
78
+ const v = this.isTimestampKey(k) && typeof f === 'string' ? this.toTimestamp(f) : f
79
+ return (k+'='+f).trim()
80
+ }
81
+ return ''
82
+ }).filter(s=>s!=='').join(' and ')
83
+ return whereVar.trim()
84
+ }
85
+
86
+ private constructInclude = (includes: string[]): string | null => {
87
+ if (!includes.length) {
88
+ return null
89
+ }
90
+ return includes.join(',')
91
+ }
92
+
93
+ baseGet = async (id: number|null): Promise<object | null> => {
94
+ const response = await XhrWrapper.get({
95
+ url: this.constructUrl(id),
96
+ config: {
97
+ auth: this.constructAuth(),
98
+ headers: this.constructHeaders(),
99
+ },
100
+ })
101
+ const responseKey = this.responseKey!==null? this.responseKey : this.resourceKey
102
+ if (
103
+ responseKey &&
104
+ response &&
105
+ response.status >= 200 &&
106
+ response.status < 300 &&
107
+ response.data.hasOwnProperty(responseKey)
108
+ ) {
109
+ console.log('RESPONSE KEY', responseKey, response.data)
110
+ const data = response.data[responseKey]
111
+ if (Array.isArray(data)) {
112
+ console.log('AXIOS RESPONSE', data[0])
113
+ return data.length > 0 ? data[0] : null
114
+ } else if (data) {
115
+ return data
116
+ }
117
+ }
118
+ return null
119
+ }
120
+
121
+ baseList = async (config: GenericListConfig = {}): Promise<object[]> => {
122
+ const filter = this.constructFilter(config.filter ? config.filter : {})
123
+ const include = this.constructInclude(config.include ? config.include : [])
124
+ const response = await XhrWrapper.get({
125
+ url: this.constructUrl(),
126
+ config: {
127
+ auth: this.constructAuth(),
128
+ headers: this.constructHeaders(),
129
+ params:
130
+ filter || include
131
+ ? {
132
+ where: filter || undefined,
133
+ include: include || undefined,
134
+ }
135
+ : undefined,
136
+ },
137
+ })
138
+ const responseKey = this.responseKey!==null? this.responseKey : this.resourceKey
139
+ if (
140
+ responseKey &&
141
+ response &&
142
+ response.status >= 200 &&
143
+ response.status < 300 &&
144
+ response.data.hasOwnProperty(responseKey)
145
+ ) {
146
+ const data = response.data[responseKey]
147
+ console.log('AXIOS RESPONSE', data)
148
+ return data
149
+ }
150
+ return []
151
+ }
152
+
153
+ baseCreate = async (data: object) => {
154
+ const response = await XhrWrapper.post({
155
+ url: this.constructUrl(),
156
+ config: {
157
+ auth: this.constructAuth(),
158
+ headers: this.constructHeaders(),
159
+ },
160
+ data: data,
161
+ })
162
+ const responseKey = this.responseKey!==null? this.responseKey : this.resourceKey
163
+ if (
164
+ responseKey &&
165
+ response &&
166
+ response.status >= 200 &&
167
+ response.status < 300 &&
168
+ response.data.hasOwnProperty(responseKey)
169
+ ) {
170
+ const data = response.data[responseKey]
171
+ if (Array.isArray(data)) {
172
+ console.log('AXIOS RESPONSE', data[0])
173
+ return data.length > 0 ? data[0] : null
174
+ } else if (data) {
175
+ return data
176
+ }
177
+ }
178
+ return null
179
+ }
180
+
181
+ baseUpdate = async (id: number|null, data: object) => {
182
+ const response = await XhrWrapper.put({
183
+ url: this.constructUrl(id),
184
+ config: {
185
+ auth: this.constructAuth(),
186
+ headers: this.constructHeaders(),
187
+ },
188
+ data: data,
189
+ })
190
+ const responseKey = this.responseKey!==null? this.responseKey : this.resourceKey
191
+ if (
192
+ responseKey &&
193
+ response &&
194
+ response.status >= 200 &&
195
+ response.status < 300 &&
196
+ response.data.hasOwnProperty(responseKey)
197
+ ) {
198
+ const data = response.data[responseKey]
199
+ if (Array.isArray(data)) {
200
+ console.log('AXIOS RESPONSE', data[0])
201
+ return data.length > 0 ? data[0] : null
202
+ } else if (data) {
203
+ return data
204
+ }
205
+ }
206
+ return null
207
+ }
208
+
209
+ baseDelete = async (id: number): Promise<boolean> => {
210
+ const response = await XhrWrapper.delete({
211
+ url: this.constructUrl(id),
212
+ config: {
213
+ auth: this.constructAuth(),
214
+ headers: this.constructHeaders(),
215
+ },
216
+ })
217
+ return !!(response && response.status >= 200 && response.status < 300);
218
+
219
+ }
220
+ }
package/src/index.ts ADDED
@@ -0,0 +1,23 @@
1
+ import PaymoResourceHandler, { PaymoResourceHandlerInterface } from "./resources"
2
+
3
+ class Paymo {
4
+ static instances: PaymoResourceHandlerInterface[] = []
5
+
6
+ static connect = (
7
+ userOrApi: string,
8
+ password: string | null = null
9
+ ): PaymoResourceHandlerInterface => {
10
+ let handler:
11
+ | PaymoResourceHandlerInterface
12
+ | undefined = Paymo.instances.find(i => i.isApiUser(userOrApi))
13
+ if (!handler) {
14
+ handler = new PaymoResourceHandler(userOrApi, password)
15
+ Paymo.instances.push(handler)
16
+ }
17
+ return handler
18
+ }
19
+ }
20
+
21
+ export default Paymo
22
+
23
+
package/src/remote.ts ADDED
@@ -0,0 +1,77 @@
1
+ import axios, { AxiosResponse } from "axios"
2
+ // export interface XhrWrapperInterface {
3
+ // get:()=>void
4
+ // post:()=>void
5
+ // put:()=>void
6
+ // delete:()=>void
7
+ // }
8
+
9
+ const paymoAxios = axios.create({
10
+ baseURL: 'https://app.paymoapp.com/api/',
11
+ headers: { Accept: 'application/json' },
12
+ })
13
+
14
+ class XhrWrapper {
15
+ static get = async (d: any): Promise<AxiosResponse | null> => {
16
+ console.log('AXIOS GET CALL', d)
17
+ return await paymoAxios.get(d.url, d.config).catch((e: Error) => {
18
+ console.log('ERROR:', e.message)
19
+ throw new Error('PAYMO GET FAILED :' + e)
20
+ })
21
+ }
22
+
23
+ static post = async (d: any) => {
24
+ console.log('AXIOS POST CALL', d)
25
+ return await paymoAxios.post(d.url, d.data, d.config).catch((e: Error) => {
26
+ console.log('ERROR:', e.message)
27
+ throw new Error('PAYMO POST FAILED :' + e)
28
+ })
29
+ }
30
+
31
+ static put = async (d: any) => {
32
+ console.log('AXIOS PUT CALL', d)
33
+ return await paymoAxios.put(d.url, d.data, d.config).catch((e: Error) => {
34
+ console.log('ERROR:', e.message)
35
+ throw new Error('PAYMO PUT FAILED :' + e)
36
+ })
37
+ }
38
+
39
+ static delete = async (d: any): Promise<AxiosResponse | null> => {
40
+ console.log('AXIOS DELETE CALL', d)
41
+ return await paymoAxios.delete(d.url, d.config).catch((e: Error) => {
42
+ console.log('ERROR:', e.message)
43
+ throw new Error('PAYMO DELETE FAILED :' + e)
44
+ })
45
+ }
46
+
47
+ static test = async () => {
48
+ const PAYMOAPI = 'YOUR_PAYMO_API_KEY'
49
+ const url = 'projects?include=client,tasks.entries'
50
+
51
+ const d = {
52
+ auth: {
53
+ username: PAYMOAPI,
54
+ password: 'abc123',
55
+ },
56
+ headers: {
57
+ Accept: 'application/json',
58
+ },
59
+ }
60
+
61
+ const instance = axios.create()
62
+ instance.defaults.headers.common = {}
63
+ instance.defaults.headers.common.accept = 'application/json'
64
+
65
+ //const { data } = await instance.get(generatedUrl);
66
+
67
+ console.log('AXIOS DEL CALL', d)
68
+
69
+ const response = await instance.get(url, d).catch((e: Error) => {
70
+ throw new Error('GET PAYMO FAILED :' + e)
71
+ })
72
+
73
+ console.log('DEL PAYMO RESPONSE', response)
74
+ }
75
+ }
76
+
77
+ export default XhrWrapper
@@ -0,0 +1,38 @@
1
+ import { AbstractResource, AbstractResourceInterface } from '../../abstract'
2
+ import { AuthInterface } from "../../types"
3
+ import { _Template_ListConfig, _Template_TypeCreate, _Template_TypeResponse, _Template_TypeUpdate } from "./types"
4
+
5
+ export interface _Template_Handler extends AbstractResourceInterface {
6
+ get: (id: number) => Promise<_Template_TypeResponse | null>
7
+ list: (config?: _Template_ListConfig) => Promise<_Template_TypeResponse[]>
8
+ create: (d: _Template_TypeCreate) => Promise<_Template_TypeResponse | null>
9
+ update: (id: number, data: _Template_TypeUpdate) => Promise<_Template_TypeResponse | null>
10
+ delete: (id: number) => Promise<boolean>
11
+ }
12
+
13
+ export class _Template_ extends AbstractResource implements _Template_Handler {
14
+ constructor(auth: AuthInterface) {
15
+ super(auth, '_template_')
16
+ }
17
+
18
+ get = async (id: number) => {
19
+ return (await this.baseGet(id)) as _Template_TypeResponse | null
20
+ }
21
+
22
+ list = async (config: _Template_ListConfig = {}) => {
23
+ return (await this.baseList(config)) as _Template_TypeResponse[]
24
+ }
25
+
26
+ create = async (data: _Template_TypeCreate) => {
27
+ return (await this.baseCreate(data)) as _Template_TypeResponse | null
28
+ }
29
+
30
+ update = async (id: number, data: _Template_TypeUpdate) => {
31
+ return (await this.baseUpdate(id, data)) as _Template_TypeResponse | null
32
+ }
33
+
34
+ delete = async (id: number) => {
35
+ return await this.baseDelete(id)
36
+ }
37
+
38
+ }
@@ -0,0 +1,40 @@
1
+ import { FilterOperator, GenericListConfig, Merge } from "../../types"
2
+
3
+ // PAYMO API DOCS - 2019-12-11 /_template_ /_template_/####
4
+ // =================================================================================================
5
+
6
+ export interface _Template_TypeRead {
7
+ readonly id: number
8
+ readonly created_on: string
9
+ readonly updated_on: string
10
+ }
11
+
12
+ export interface _Template_TypeUpdate {
13
+
14
+ }
15
+
16
+ export type _Template_TypeResponse = Merge<_Template_TypeUpdate, Merge<_Template_TypeRead, {
17
+
18
+ }>>
19
+
20
+ export interface _Template_TypeCreate extends _Template_TypeUpdate {
21
+
22
+ }
23
+
24
+ export interface _Template_TypeFilter {
25
+
26
+ }
27
+
28
+ export interface _Template_FilterCondition extends _Template_TypeFilter {
29
+ _custom?: {
30
+ [k: string]: {
31
+ key?: Extract<keyof _Template_TypeFilter, string>
32
+ operator?:FilterOperator
33
+ value: string | number | boolean | null | number[]
34
+ }
35
+ }
36
+ }
37
+
38
+ export interface _Template_ListConfig extends GenericListConfig {
39
+ filter?:_Template_FilterCondition
40
+ }
@@ -0,0 +1,61 @@
1
+ import { AbstractResource, AbstractResourceInterface } from '../../abstract'
2
+ import { AuthInterface } from '../../types'
3
+ import {
4
+ BookingsListConfig,
5
+ BookingsTypeCreate,
6
+ BookingsTypeResponse,
7
+ BookingsTypeUpdate,
8
+ } from './types'
9
+
10
+ export interface BookingsHandler extends AbstractResourceInterface {
11
+ get: (id: number) => Promise<BookingsTypeResponse | null>
12
+ list: (config?: BookingsListConfig) => Promise<BookingsTypeResponse[]>
13
+ create: (d: BookingsTypeCreate) => Promise<BookingsTypeResponse | null>
14
+ update: (
15
+ id: number,
16
+ data: BookingsTypeUpdate
17
+ ) => Promise<BookingsTypeResponse | null>
18
+ delete: (id: number) => Promise<boolean>
19
+ }
20
+
21
+ export class Bookings extends AbstractResource implements BookingsHandler {
22
+ constructor(auth: AuthInterface) {
23
+ super(auth, 'bookings')
24
+ this.filterDates = ['start_date', 'end_date']
25
+ }
26
+
27
+ get = async (id: number) => {
28
+ return (await this.baseGet(id)) as BookingsTypeResponse | null
29
+ }
30
+
31
+ list = async (config: BookingsListConfig = {}) => {
32
+ const validConfig =
33
+ !!config &&
34
+ config.filter &&
35
+ (config.filter.user_task_id ||
36
+ config.filter.task_id ||
37
+ config.filter.user_id ||
38
+ config.filter.project_id ||
39
+ (config.filter.date_interval &&
40
+ Array.isArray(config.filter.date_interval) &&
41
+ config.filter.date_interval.length === 2) ||
42
+ (config.filter.start_date && config.filter.end_date))
43
+ if (!validConfig) {
44
+ console.log('Booking list requires at least one valid filter condition')
45
+ return []
46
+ }
47
+ return (await this.baseList(config)) as BookingsTypeResponse[]
48
+ }
49
+
50
+ create = async (data: BookingsTypeCreate) => {
51
+ return (await this.baseCreate(data)) as BookingsTypeResponse | null
52
+ }
53
+
54
+ update = async (id: number, data: BookingsTypeUpdate) => {
55
+ return (await this.baseUpdate(id, data)) as BookingsTypeResponse | null
56
+ }
57
+
58
+ delete = async (id: number) => {
59
+ return await this.baseDelete(id)
60
+ }
61
+ }
@@ -0,0 +1,60 @@
1
+ import { FilterOperator, GenericListConfig, Merge } from "../../types"
2
+
3
+ // PAYMO API DOCS - 2019-12-11 /bookings /bookings/####
4
+ // =================================================================================================
5
+
6
+ export interface BookingsTypeRead {
7
+ readonly id: number
8
+ readonly created_on: string
9
+ readonly updated_on: string
10
+ readonly creator_id: number
11
+ }
12
+
13
+ export interface BookingsTypeUpdate {
14
+ user_task_id?:number
15
+ start_date?:string
16
+ end_date?:string
17
+ hours_per_day?:number
18
+ description?:string
19
+ }
20
+
21
+ export type BookingsTypeResponse = Merge<BookingsTypeUpdate, Merge<BookingsTypeRead, {
22
+ booked_hours:any|null
23
+ start_date: string
24
+ start_time: string|null
25
+ end_date:string
26
+ end_time:string|null
27
+ }>>
28
+
29
+ export interface BookingsTypeCreate extends BookingsTypeUpdate {
30
+ user_task_id:number
31
+ start_date:string
32
+ end_date:string
33
+ hours_per_day:number
34
+ }
35
+
36
+ export interface BookingsTypeFilter {
37
+ user_task_id?:number
38
+ task_id?:number
39
+ user_id?:number
40
+ project_id?:number
41
+ date_interval?:string[]
42
+
43
+ hours_per_day?:number
44
+ start_date?:string
45
+ end_date?:string
46
+ }
47
+
48
+ export interface BookingsFilterCondition extends BookingsTypeFilter {
49
+ _custom?: {
50
+ [k: string]: {
51
+ key?: Extract<keyof BookingsTypeFilter, string>
52
+ operator?:FilterOperator
53
+ value: string | number | boolean | null | number[]
54
+ }
55
+ }
56
+ }
57
+
58
+ export interface BookingsListConfig extends GenericListConfig {
59
+ filter?:BookingsFilterCondition
60
+ }
@@ -0,0 +1,38 @@
1
+ import { AbstractResource, AbstractResourceInterface } from '../../abstract'
2
+ import { AuthInterface } from "../../types"
3
+ import { ClientContactsListConfig, ClientContactsTypeCreate, ClientContactsTypeResponse, ClientContactsTypeUpdate } from "./types"
4
+
5
+ export interface ClientContactsHandler extends AbstractResourceInterface {
6
+ get: (id: number) => Promise<ClientContactsTypeResponse | null>
7
+ list: (config?: ClientContactsListConfig) => Promise<ClientContactsTypeResponse[]>
8
+ create: (d: ClientContactsTypeCreate) => Promise<ClientContactsTypeResponse | null>
9
+ update: (id: number, data: ClientContactsTypeUpdate) => Promise<ClientContactsTypeResponse | null>
10
+ delete: (id: number) => Promise<boolean>
11
+ }
12
+
13
+ export class ClientContacts extends AbstractResource implements ClientContactsHandler {
14
+ constructor(auth: AuthInterface) {
15
+ super(auth, 'clientcontacts')
16
+ }
17
+
18
+ get = async (id: number) => {
19
+ return (await this.baseGet(id)) as ClientContactsTypeResponse | null
20
+ }
21
+
22
+ list = async (config: ClientContactsListConfig = {}) => {
23
+ return (await this.baseList(config)) as ClientContactsTypeResponse[]
24
+ }
25
+
26
+ create = async (data: ClientContactsTypeCreate) => {
27
+ return (await this.baseCreate(data)) as ClientContactsTypeResponse | null
28
+ }
29
+
30
+ update = async (id: number, data: ClientContactsTypeUpdate) => {
31
+ return (await this.baseUpdate(id, data)) as ClientContactsTypeResponse | null
32
+ }
33
+
34
+ delete = async (id: number) => {
35
+ return await this.baseDelete(id)
36
+ }
37
+
38
+ }
@@ -0,0 +1,69 @@
1
+ import { FilterOperator, GenericListConfig, Merge } from "../../types"
2
+
3
+ // PAYMO API DOCS - 2019-12-11 /clientcontacts /clientcontacts/####
4
+ // =================================================================================================
5
+
6
+ export interface ClientContactsTypeRead {
7
+ readonly id: number
8
+ readonly created_on: string
9
+ readonly updated_on: string
10
+ readonly image_thumb_large?: string
11
+ readonly image_thumb_medium?: string
12
+ readonly image_thumb_small?: string
13
+ }
14
+
15
+ export interface ClientContactsTypeUpdate {
16
+ name?: string
17
+ email?: string
18
+ mobile?:string
19
+ phone?: string
20
+ fax?:string
21
+ skype?: string
22
+ notes?:string
23
+ position?: string
24
+ is_main?:boolean
25
+ access?:boolean
26
+ client_id?:number
27
+ password?:string
28
+ }
29
+
30
+ export type ClientContactsTypeResponse = Merge<ClientContactsTypeUpdate, Merge<ClientContactsTypeRead, {
31
+ image:string|null
32
+ phone:string|null
33
+ position:string|null
34
+ skype:string|null
35
+ }>>
36
+
37
+ export interface ClientContactsTypeCreate extends ClientContactsTypeUpdate {
38
+ name: string
39
+ client_id:number
40
+ }
41
+
42
+ export interface ClientContactsTypeFilter {
43
+ id?: number
44
+ created_on?: string
45
+ updated_on?: string
46
+ name?: string
47
+ email?: string
48
+ mobile?:string
49
+ phone?: string
50
+ fax?:string
51
+ skype?: string
52
+ is_main?:boolean
53
+ access?:boolean
54
+ client_id?:number
55
+ }
56
+
57
+ export interface ClientContactsFilterCondition extends ClientContactsTypeFilter {
58
+ _custom?: {
59
+ [k: string]: {
60
+ key?: Extract<keyof ClientContactsTypeFilter, string>
61
+ operator?:FilterOperator
62
+ value: string | number | boolean | null | number[]
63
+ }
64
+ }
65
+ }
66
+
67
+ export interface ClientContactsListConfig extends GenericListConfig {
68
+ filter?:ClientContactsFilterCondition
69
+ }
@@ -0,0 +1,38 @@
1
+ import { AbstractResource, AbstractResourceInterface } from '../../abstract'
2
+ import { AuthInterface } from "../../types"
3
+ import { ClientsListConfig, ClientTypeCreate, ClientTypeResponse, ClientTypeUpdate } from "./types"
4
+
5
+ export interface ClientsHandler extends AbstractResourceInterface {
6
+ get: (id: number) => Promise<ClientTypeResponse | null>
7
+ list: (config?: ClientsListConfig) => Promise<ClientTypeResponse[]>
8
+ create: (d: ClientTypeCreate) => Promise<ClientTypeResponse | null>
9
+ update: (id: number, data: ClientTypeUpdate) => Promise<ClientTypeResponse | null>
10
+ delete: (id: number) => Promise<boolean>
11
+ }
12
+
13
+ export class Clients extends AbstractResource implements ClientsHandler {
14
+ constructor(auth: AuthInterface) {
15
+ super(auth, 'clients')
16
+ }
17
+
18
+ get = async (id: number) => {
19
+ return (await this.baseGet(id)) as ClientTypeResponse | null
20
+ }
21
+
22
+ list = async (config: ClientsListConfig = {}) => {
23
+ return (await this.baseList(config)) as ClientTypeResponse[]
24
+ }
25
+
26
+ create = async (data: ClientTypeCreate) => {
27
+ return (await this.baseCreate(data)) as ClientTypeResponse | null
28
+ }
29
+
30
+ update = async (id: number, data: ClientTypeUpdate) => {
31
+ return (await this.baseUpdate(id, data)) as ClientTypeResponse | null
32
+ }
33
+
34
+ delete = async (id: number) => {
35
+ return await this.baseDelete(id)
36
+ }
37
+
38
+ }