atlas-crm-api-client 1.1.7 → 1.2.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.
- package/lib/cjs/client.cjs +1 -1
- package/lib/cjs/client.d.cts +3 -0
- package/lib/cjs/types.d.cts +8 -0
- package/lib/esm/client.d.ts +3 -0
- package/lib/esm/client.js +97 -69
- package/lib/esm/types.d.ts +8 -0
- package/package.json +1 -1
package/lib/cjs/client.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("axios"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("axios"),E="https://atlascrm.avisi-apps.com",k="CRM";class c extends Error{constructor(e,s,t){super(e),this.message=e,this.status=s,this.data=t,this.name="AtlasCrmError"}}class f{constructor(e){this.accessToken=null,this.tokenExpiry=null,this.baseUrl=(e.baseUrl??E).replace(/\/$/,""),this.clientId=e.clientId,this.clientSecret=e.clientSecret,this.workspace=e.workspace??k,this.companies=this.createEntityNamespace("company"),this.contacts=this.createEntityNamespace("contact"),this.sales=this.createEntityNamespace("sale"),this.comments=this.createCommentsNamespace(),this.issues=this.createIssuesNamespace()}async request(e,s,t={},r=0){var p;const u=await this.getValidToken();let n=`${this.baseUrl}${s}`;if(t.params){const o=new URLSearchParams,a={...t.params};a.sortType!==void 0&&a["sort-type"]===void 0&&(a["sort-type"]=a.sortType),a.sortBy!==void 0&&a["sort-by"]===void 0&&(a["sort-by"]=a.sortBy);const h=a.filters;delete a.sortType,delete a.sortBy,delete a.filters,Object.entries(a).forEach(([y,w])=>{this.appendQueryParam(o,y,w)}),h&&this.appendFilters(o,h);const d=o.toString();d&&(n+=(n.includes("?")?"&":"?")+d)}let i;try{i=await l.request({url:n,method:e,headers:{Authorization:`Bearer ${u}`,Accept:"application/json","Content-Type":"application/json"},data:t.body?t.body:void 0,validateStatus:()=>!0})}catch(o){const a=o;throw new c(a.message||"Request failed",(p=a.response)==null?void 0:p.status)}if(i.status===401&&r<1)return this.accessToken=null,this.request(e,s,t,r+1);if(i.status<200||i.status>=300){const o=i.data&&typeof i.data=="object"?i.data:{message:typeof i.data=="string"?i.data:void 0},a=o.message||`Request failed with status ${i.status}`;throw new c(a,i.status,o)}return i.data}appendQueryParam(e,s,t){if(t!=null){if(Array.isArray(t)){t.forEach(r=>{r!=null&&e.append(s,this.toQueryValue(r))});return}e.append(s,this.toQueryValue(t))}}appendFilters(e,s){s.forEach(t=>{const r=t.operator?`fields.${t.fieldId}[${t.operator}]`:`fields.${t.fieldId}`;this.appendQueryParam(e,r,t.value)})}toQueryValue(e){return e instanceof Date?e.toISOString():String(e)}async authenticate(){var r;const e=Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64");let s;try{s=await l.request({url:`${this.baseUrl}/api/1.0/oauth/token`,method:"POST",headers:{Authorization:`Basic ${e}`,"Content-Type":"application/x-www-form-urlencoded"},data:new URLSearchParams({grant_type:"client_credentials"}).toString(),validateStatus:()=>!0})}catch(u){const n=u;throw new c(n.message||"Authentication failed",(r=n.response)==null?void 0:r.status)}if(s.status<200||s.status>=300)throw new c("Authentication failed",s.status,s.data);const t=s.data;return this.accessToken=t.access_token,this.tokenExpiry=Date.now()+t.expires_in*1e3-3e4,t.access_token}async getValidToken(){return this.accessToken&&this.tokenExpiry&&Date.now()<this.tokenExpiry?this.accessToken:this.authenticate()}createEntityNamespace(e){const s=`/api/1.0/workspace/${this.workspace}/entities`;return{list:(t={})=>this.request("GET",s,{params:{...t,type:e}}),get:t=>this.request("GET",`${s}/${t}`),create:t=>this.request("POST",s,{body:{type:e,fields:t}}),update:(t,r)=>this.request("PUT",`${s}/${t}`,{body:{fields:r}}),delete:t=>this.request("DELETE",`${s}/${t}`),getTemplate:()=>this.request("GET",`/api/1.0/workspace/${this.workspace}/template/${e}`)}}createIssuesNamespace(){return{link:(e,s)=>this.request("POST",`/api/1.0/workspace/${this.workspace}/entities/${e}/issues`,{body:{"issue-ids":s}}),unlink:(e,s)=>this.request("DELETE",`/api/1.0/workspace/${this.workspace}/entities/${e}/issues`,{body:{"issue-ids":s}})}}createCommentsNamespace(){return{create:(e,s,t)=>this.request("POST",`/api/1.0/workspace/${this.workspace}/entities/${e}/comments`,{body:{format:"plain-text",comment:s,"account-id":t}})}}}exports.AtlasCrmClient=f;exports.AtlasCrmError=c;
|
package/lib/cjs/client.d.cts
CHANGED
package/lib/cjs/types.d.cts
CHANGED
|
@@ -37,6 +37,13 @@ export type AtlasCrmConfig = {
|
|
|
37
37
|
clientSecret: string;
|
|
38
38
|
workspace?: string;
|
|
39
39
|
};
|
|
40
|
+
export type FilterOperator = 'eq' | 'contains' | 'gte' | 'lte';
|
|
41
|
+
export type EntityFilterValue = string | number | boolean | Date;
|
|
42
|
+
export type EntityFilter = {
|
|
43
|
+
fieldId: string;
|
|
44
|
+
value: EntityFilterValue | EntityFilterValue[];
|
|
45
|
+
operator?: FilterOperator;
|
|
46
|
+
};
|
|
40
47
|
export type QueryParams = {
|
|
41
48
|
size?: number;
|
|
42
49
|
'sort-type'?: 'asc' | 'desc';
|
|
@@ -44,6 +51,7 @@ export type QueryParams = {
|
|
|
44
51
|
'sort-by'?: string;
|
|
45
52
|
sortBy?: string;
|
|
46
53
|
cursor?: string;
|
|
54
|
+
filters?: EntityFilter[];
|
|
47
55
|
[key: string]: any;
|
|
48
56
|
};
|
|
49
57
|
export type TemplateField = {
|
package/lib/esm/client.d.ts
CHANGED
package/lib/esm/client.js
CHANGED
|
@@ -1,72 +1,100 @@
|
|
|
1
1
|
import l from "axios";
|
|
2
|
-
const
|
|
3
|
-
class
|
|
4
|
-
constructor(s, t
|
|
5
|
-
super(
|
|
2
|
+
const k = "https://atlascrm.avisi-apps.com", E = "CRM";
|
|
3
|
+
class c extends Error {
|
|
4
|
+
constructor(e, s, t) {
|
|
5
|
+
super(e), this.message = e, this.status = s, this.data = t, this.name = "AtlasCrmError";
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
-
class
|
|
9
|
-
constructor(
|
|
10
|
-
this.accessToken = null, this.tokenExpiry = null, this.baseUrl = (
|
|
8
|
+
class $ {
|
|
9
|
+
constructor(e) {
|
|
10
|
+
this.accessToken = null, this.tokenExpiry = null, this.baseUrl = (e.baseUrl ?? k).replace(/\/$/, ""), this.clientId = e.clientId, this.clientSecret = e.clientSecret, this.workspace = e.workspace ?? E, this.companies = this.createEntityNamespace("company"), this.contacts = this.createEntityNamespace("contact"), this.sales = this.createEntityNamespace("sale"), this.comments = this.createCommentsNamespace(), this.issues = this.createIssuesNamespace();
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Internal Request Handler
|
|
14
14
|
*/
|
|
15
|
-
async request(s, t
|
|
15
|
+
async request(e, s, t = {}, r = 0) {
|
|
16
16
|
var u;
|
|
17
|
-
const
|
|
18
|
-
let
|
|
19
|
-
if (
|
|
20
|
-
const o = new URLSearchParams(), a = { ...
|
|
21
|
-
a.sortType !== void 0 && a["sort-type"] === void 0 && (a["sort-type"] = a.sortType), a.sortBy !== void 0 && a["sort-by"] === void 0 && (a["sort-by"] = a.sortBy)
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
const p = await this.getValidToken();
|
|
18
|
+
let n = `${this.baseUrl}${s}`;
|
|
19
|
+
if (t.params) {
|
|
20
|
+
const o = new URLSearchParams(), a = { ...t.params };
|
|
21
|
+
a.sortType !== void 0 && a["sort-type"] === void 0 && (a["sort-type"] = a.sortType), a.sortBy !== void 0 && a["sort-by"] === void 0 && (a["sort-by"] = a.sortBy);
|
|
22
|
+
const h = a.filters;
|
|
23
|
+
delete a.sortType, delete a.sortBy, delete a.filters, Object.entries(a).forEach(([y, w]) => {
|
|
24
|
+
this.appendQueryParam(
|
|
25
|
+
o,
|
|
26
|
+
y,
|
|
27
|
+
w
|
|
28
|
+
);
|
|
29
|
+
}), h && this.appendFilters(o, h);
|
|
30
|
+
const d = o.toString();
|
|
31
|
+
d && (n += (n.includes("?") ? "&" : "?") + d);
|
|
24
32
|
}
|
|
25
|
-
let
|
|
33
|
+
let i;
|
|
26
34
|
try {
|
|
27
|
-
|
|
28
|
-
url:
|
|
29
|
-
method:
|
|
35
|
+
i = await l.request({
|
|
36
|
+
url: n,
|
|
37
|
+
method: e,
|
|
30
38
|
headers: {
|
|
31
|
-
Authorization: `Bearer ${
|
|
39
|
+
Authorization: `Bearer ${p}`,
|
|
32
40
|
Accept: "application/json",
|
|
33
41
|
"Content-Type": "application/json"
|
|
34
42
|
},
|
|
35
|
-
data:
|
|
43
|
+
data: t.body ? t.body : void 0,
|
|
36
44
|
validateStatus: () => !0
|
|
37
45
|
});
|
|
38
46
|
} catch (o) {
|
|
39
47
|
const a = o;
|
|
40
|
-
throw new
|
|
48
|
+
throw new c(
|
|
41
49
|
a.message || "Request failed",
|
|
42
50
|
(u = a.response) == null ? void 0 : u.status
|
|
43
51
|
);
|
|
44
52
|
}
|
|
45
|
-
if (
|
|
46
|
-
return this.accessToken = null, this.request(s, t,
|
|
47
|
-
if (
|
|
48
|
-
const o =
|
|
49
|
-
message: typeof
|
|
50
|
-
}, a = o.message || `Request failed with status ${
|
|
51
|
-
throw new
|
|
53
|
+
if (i.status === 401 && r < 1)
|
|
54
|
+
return this.accessToken = null, this.request(e, s, t, r + 1);
|
|
55
|
+
if (i.status < 200 || i.status >= 300) {
|
|
56
|
+
const o = i.data && typeof i.data == "object" ? i.data : {
|
|
57
|
+
message: typeof i.data == "string" ? i.data : void 0
|
|
58
|
+
}, a = o.message || `Request failed with status ${i.status}`;
|
|
59
|
+
throw new c(a, i.status, o);
|
|
52
60
|
}
|
|
53
|
-
return
|
|
61
|
+
return i.data;
|
|
62
|
+
}
|
|
63
|
+
appendQueryParam(e, s, t) {
|
|
64
|
+
if (t != null) {
|
|
65
|
+
if (Array.isArray(t)) {
|
|
66
|
+
t.forEach((r) => {
|
|
67
|
+
r != null && e.append(s, this.toQueryValue(r));
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
e.append(s, this.toQueryValue(t));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
appendFilters(e, s) {
|
|
75
|
+
s.forEach((t) => {
|
|
76
|
+
const r = t.operator ? `fields.${t.fieldId}[${t.operator}]` : `fields.${t.fieldId}`;
|
|
77
|
+
this.appendQueryParam(e, r, t.value);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
toQueryValue(e) {
|
|
81
|
+
return e instanceof Date ? e.toISOString() : String(e);
|
|
54
82
|
}
|
|
55
83
|
/**
|
|
56
84
|
* OAuth2 Client Credentials Handshake
|
|
57
85
|
*/
|
|
58
86
|
async authenticate() {
|
|
59
|
-
var
|
|
60
|
-
const
|
|
87
|
+
var r;
|
|
88
|
+
const e = Buffer.from(
|
|
61
89
|
`${this.clientId}:${this.clientSecret}`
|
|
62
90
|
).toString("base64");
|
|
63
|
-
let
|
|
91
|
+
let s;
|
|
64
92
|
try {
|
|
65
|
-
|
|
93
|
+
s = await l.request({
|
|
66
94
|
url: `${this.baseUrl}/api/1.0/oauth/token`,
|
|
67
95
|
method: "POST",
|
|
68
96
|
headers: {
|
|
69
|
-
Authorization: `Basic ${
|
|
97
|
+
Authorization: `Basic ${e}`,
|
|
70
98
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
71
99
|
},
|
|
72
100
|
data: new URLSearchParams({
|
|
@@ -74,21 +102,21 @@ class E {
|
|
|
74
102
|
}).toString(),
|
|
75
103
|
validateStatus: () => !0
|
|
76
104
|
});
|
|
77
|
-
} catch (
|
|
78
|
-
const
|
|
79
|
-
throw new
|
|
80
|
-
|
|
81
|
-
(
|
|
105
|
+
} catch (p) {
|
|
106
|
+
const n = p;
|
|
107
|
+
throw new c(
|
|
108
|
+
n.message || "Authentication failed",
|
|
109
|
+
(r = n.response) == null ? void 0 : r.status
|
|
82
110
|
);
|
|
83
111
|
}
|
|
84
|
-
if (
|
|
85
|
-
throw new
|
|
112
|
+
if (s.status < 200 || s.status >= 300)
|
|
113
|
+
throw new c(
|
|
86
114
|
"Authentication failed",
|
|
87
|
-
|
|
88
|
-
|
|
115
|
+
s.status,
|
|
116
|
+
s.data
|
|
89
117
|
);
|
|
90
|
-
const
|
|
91
|
-
return this.accessToken =
|
|
118
|
+
const t = s.data;
|
|
119
|
+
return this.accessToken = t.access_token, this.tokenExpiry = Date.now() + t.expires_in * 1e3 - 3e4, t.access_token;
|
|
92
120
|
}
|
|
93
121
|
async getValidToken() {
|
|
94
122
|
return this.accessToken && this.tokenExpiry && Date.now() < this.tokenExpiry ? this.accessToken : this.authenticate();
|
|
@@ -96,54 +124,54 @@ class E {
|
|
|
96
124
|
/**
|
|
97
125
|
* Generic Entity Operations Factory
|
|
98
126
|
*/
|
|
99
|
-
createEntityNamespace(
|
|
100
|
-
const
|
|
127
|
+
createEntityNamespace(e) {
|
|
128
|
+
const s = `/api/1.0/workspace/${this.workspace}/entities`;
|
|
101
129
|
return {
|
|
102
|
-
list: (
|
|
103
|
-
params: { ...
|
|
130
|
+
list: (t = {}) => this.request("GET", s, {
|
|
131
|
+
params: { ...t, type: e }
|
|
104
132
|
}),
|
|
105
|
-
get: (
|
|
106
|
-
create: (
|
|
107
|
-
body: { type:
|
|
133
|
+
get: (t) => this.request("GET", `${s}/${t}`),
|
|
134
|
+
create: (t) => this.request("POST", s, {
|
|
135
|
+
body: { type: e, fields: t }
|
|
108
136
|
}),
|
|
109
|
-
update: (
|
|
110
|
-
body: { fields:
|
|
137
|
+
update: (t, r) => this.request("PUT", `${s}/${t}`, {
|
|
138
|
+
body: { fields: r }
|
|
111
139
|
}),
|
|
112
|
-
delete: (
|
|
140
|
+
delete: (t) => this.request("DELETE", `${s}/${t}`),
|
|
113
141
|
getTemplate: () => this.request(
|
|
114
142
|
"GET",
|
|
115
|
-
`/api/1.0/workspace/${this.workspace}/template/${
|
|
143
|
+
`/api/1.0/workspace/${this.workspace}/template/${e}`
|
|
116
144
|
)
|
|
117
145
|
};
|
|
118
146
|
}
|
|
119
147
|
createIssuesNamespace() {
|
|
120
148
|
return {
|
|
121
|
-
link: (
|
|
149
|
+
link: (e, s) => this.request(
|
|
122
150
|
"POST",
|
|
123
|
-
`/api/1.0/workspace/${this.workspace}/entities/${
|
|
151
|
+
`/api/1.0/workspace/${this.workspace}/entities/${e}/issues`,
|
|
124
152
|
{
|
|
125
|
-
body: { "issue-ids":
|
|
153
|
+
body: { "issue-ids": s }
|
|
126
154
|
}
|
|
127
155
|
),
|
|
128
|
-
unlink: (
|
|
156
|
+
unlink: (e, s) => this.request(
|
|
129
157
|
"DELETE",
|
|
130
|
-
`/api/1.0/workspace/${this.workspace}/entities/${
|
|
158
|
+
`/api/1.0/workspace/${this.workspace}/entities/${e}/issues`,
|
|
131
159
|
{
|
|
132
|
-
body: { "issue-ids":
|
|
160
|
+
body: { "issue-ids": s }
|
|
133
161
|
}
|
|
134
162
|
)
|
|
135
163
|
};
|
|
136
164
|
}
|
|
137
165
|
createCommentsNamespace() {
|
|
138
166
|
return {
|
|
139
|
-
create: (s, t
|
|
167
|
+
create: (e, s, t) => this.request(
|
|
140
168
|
"POST",
|
|
141
|
-
`/api/1.0/workspace/${this.workspace}/entities/${
|
|
169
|
+
`/api/1.0/workspace/${this.workspace}/entities/${e}/comments`,
|
|
142
170
|
{
|
|
143
171
|
body: {
|
|
144
172
|
format: "plain-text",
|
|
145
|
-
comment:
|
|
146
|
-
"account-id":
|
|
173
|
+
comment: s,
|
|
174
|
+
"account-id": t
|
|
147
175
|
}
|
|
148
176
|
}
|
|
149
177
|
)
|
|
@@ -151,6 +179,6 @@ class E {
|
|
|
151
179
|
}
|
|
152
180
|
}
|
|
153
181
|
export {
|
|
154
|
-
|
|
155
|
-
|
|
182
|
+
$ as AtlasCrmClient,
|
|
183
|
+
c as AtlasCrmError
|
|
156
184
|
};
|
package/lib/esm/types.d.ts
CHANGED
|
@@ -37,6 +37,13 @@ export type AtlasCrmConfig = {
|
|
|
37
37
|
clientSecret: string;
|
|
38
38
|
workspace?: string;
|
|
39
39
|
};
|
|
40
|
+
export type FilterOperator = 'eq' | 'contains' | 'gte' | 'lte';
|
|
41
|
+
export type EntityFilterValue = string | number | boolean | Date;
|
|
42
|
+
export type EntityFilter = {
|
|
43
|
+
fieldId: string;
|
|
44
|
+
value: EntityFilterValue | EntityFilterValue[];
|
|
45
|
+
operator?: FilterOperator;
|
|
46
|
+
};
|
|
40
47
|
export type QueryParams = {
|
|
41
48
|
size?: number;
|
|
42
49
|
'sort-type'?: 'asc' | 'desc';
|
|
@@ -44,6 +51,7 @@ export type QueryParams = {
|
|
|
44
51
|
'sort-by'?: string;
|
|
45
52
|
sortBy?: string;
|
|
46
53
|
cursor?: string;
|
|
54
|
+
filters?: EntityFilter[];
|
|
47
55
|
[key: string]: any;
|
|
48
56
|
};
|
|
49
57
|
export type TemplateField = {
|