@openfn/language-asana 3.0.1 → 3.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/README.md +1 -0
- package/ast.json +82 -5
- package/dist/index.cjs +171 -131
- package/dist/index.js +149 -113
- package/package.json +2 -3
- package/types/Adaptor.d.ts +123 -29
- package/types/Utils.d.ts +2 -0
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ definition.
|
|
|
16
16
|
Using Asana's API requires having an API token. To generate that token, head to
|
|
17
17
|
the [Asana developer console](https://app.asana.com/0/developer-console) and
|
|
18
18
|
enter the **Personal access tokens** section.
|
|
19
|
+
[For API Reference docs](https://developers.asana.com/docs/api-explorer)
|
|
19
20
|
|
|
20
21
|
There you can click on **+New access token**. A prompt will be opened allowing
|
|
21
22
|
you to give the token a name and then create it.
|
package/ast.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"title": "example",
|
|
20
|
-
"description": "getTask(\"
|
|
20
|
+
"description": "getTask(\"1206933955023739\", {\n opt_fields: \"name,notes,assignee\",\n});"
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"title": "function",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"title": "example",
|
|
83
|
-
"description": "getTasks(\"
|
|
83
|
+
"description": "getTasks(\"1206933955023739\", {\n opt_fields: \"name,notes,assignee\",\n});"
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
"title": "function",
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
"title": "example",
|
|
146
|
-
"description": "updateTask(\"
|
|
146
|
+
"description": "updateTask(\"1206933955023739\", {\n name: \"test\",\n approval_status: \"pending\",\n assignee: \"12345\",\n});"
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"title": "function",
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
207
|
"title": "example",
|
|
208
|
-
"description": "createTask(
|
|
208
|
+
"description": "createTask({\n name: \"test\",\n approval_status: \"pending\",\n assignee: \"12345\",\n projects: [\"1206933955023739\"],\n});"
|
|
209
209
|
},
|
|
210
210
|
{
|
|
211
211
|
"title": "function",
|
|
@@ -259,7 +259,7 @@
|
|
|
259
259
|
},
|
|
260
260
|
{
|
|
261
261
|
"title": "example",
|
|
262
|
-
"description": "upsertTask(\
|
|
262
|
+
"description": "upsertTask(\"1201382240880\", {\n externalId: \"name\",\n data: {\n name: \"test\",\n approval_status: \"pending\",\n projects: [\"1201382240880\"],\n assignee: \"12345\",\n },\n});"
|
|
263
263
|
},
|
|
264
264
|
{
|
|
265
265
|
"title": "function",
|
|
@@ -724,6 +724,83 @@
|
|
|
724
724
|
]
|
|
725
725
|
},
|
|
726
726
|
"valid": true
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
"name": "cursor",
|
|
730
|
+
"params": [
|
|
731
|
+
"value",
|
|
732
|
+
"options"
|
|
733
|
+
],
|
|
734
|
+
"docs": {
|
|
735
|
+
"description": "Sets a cursor property on state.\nSupports natural language dates like `now`, `today`, `yesterday`, `n hours ago`, `n days ago`, and `start`,\nwhich will be converted relative to the environment (ie, the Lightning or CLI locale). Custom timezones \nare not yet supported.\nSee the usage guide at @{link https://docs.openfn.org/documentation/jobs/job-writing-guide#using-cursors}",
|
|
736
|
+
"tags": [
|
|
737
|
+
{
|
|
738
|
+
"title": "public",
|
|
739
|
+
"description": null,
|
|
740
|
+
"type": null
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
"title": "example",
|
|
744
|
+
"description": "cursor($.cursor, { defaultValue: 'today' })",
|
|
745
|
+
"caption": "Use a cursor from state if present, or else use the default value"
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
"title": "example",
|
|
749
|
+
"description": "cursor(22)",
|
|
750
|
+
"caption": "Use a pagination cursor"
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
"title": "function",
|
|
754
|
+
"description": null,
|
|
755
|
+
"name": null
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
"title": "param",
|
|
759
|
+
"description": "the cursor value. Usually an ISO date, natural language date, or page number",
|
|
760
|
+
"type": {
|
|
761
|
+
"type": "NameExpression",
|
|
762
|
+
"name": "any"
|
|
763
|
+
},
|
|
764
|
+
"name": "value"
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"title": "param",
|
|
768
|
+
"description": "options to control the cursor.",
|
|
769
|
+
"type": {
|
|
770
|
+
"type": "NameExpression",
|
|
771
|
+
"name": "object"
|
|
772
|
+
},
|
|
773
|
+
"name": "options"
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
"title": "param",
|
|
777
|
+
"description": "set the cursor key. Will persist through the whole run.",
|
|
778
|
+
"type": {
|
|
779
|
+
"type": "NameExpression",
|
|
780
|
+
"name": "string"
|
|
781
|
+
},
|
|
782
|
+
"name": "options.key"
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
"title": "param",
|
|
786
|
+
"description": "the value to use if value is falsy",
|
|
787
|
+
"type": {
|
|
788
|
+
"type": "NameExpression",
|
|
789
|
+
"name": "any"
|
|
790
|
+
},
|
|
791
|
+
"name": "options.defaultValue"
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
"title": "returns",
|
|
795
|
+
"description": null,
|
|
796
|
+
"type": {
|
|
797
|
+
"type": "NameExpression",
|
|
798
|
+
"name": "Operation"
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
]
|
|
802
|
+
},
|
|
803
|
+
"valid": false
|
|
727
804
|
}
|
|
728
805
|
]
|
|
729
806
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -19,23 +19,26 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
// src/index.js
|
|
20
20
|
var src_exports = {};
|
|
21
21
|
__export(src_exports, {
|
|
22
|
-
alterState: () =>
|
|
22
|
+
alterState: () => import_language_common3.alterState,
|
|
23
23
|
createTask: () => createTask,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
createTaskStory: () => createTaskStory,
|
|
25
|
+
cursor: () => import_language_common3.cursor,
|
|
26
|
+
dataPath: () => import_language_common3.dataPath,
|
|
27
|
+
dataValue: () => import_language_common3.dataValue,
|
|
28
|
+
dateFns: () => import_language_common3.dateFns,
|
|
27
29
|
default: () => src_default,
|
|
28
|
-
each: () =>
|
|
30
|
+
each: () => import_language_common3.each,
|
|
29
31
|
execute: () => execute,
|
|
30
|
-
field: () =>
|
|
31
|
-
fields: () =>
|
|
32
|
-
fn: () =>
|
|
32
|
+
field: () => import_language_common3.field,
|
|
33
|
+
fields: () => import_language_common3.fields,
|
|
34
|
+
fn: () => import_language_common3.fn,
|
|
33
35
|
getTask: () => getTask,
|
|
34
36
|
getTasks: () => getTasks,
|
|
35
|
-
http: () =>
|
|
36
|
-
lastReferenceValue: () =>
|
|
37
|
-
merge: () =>
|
|
38
|
-
|
|
37
|
+
http: () => import_language_common3.http,
|
|
38
|
+
lastReferenceValue: () => import_language_common3.lastReferenceValue,
|
|
39
|
+
merge: () => import_language_common3.merge,
|
|
40
|
+
request: () => request2,
|
|
41
|
+
sourceValue: () => import_language_common3.sourceValue,
|
|
39
42
|
updateTask: () => updateTask,
|
|
40
43
|
upsertTask: () => upsertTask
|
|
41
44
|
});
|
|
@@ -44,34 +47,74 @@ module.exports = __toCommonJS(src_exports);
|
|
|
44
47
|
// src/Adaptor.js
|
|
45
48
|
var Adaptor_exports = {};
|
|
46
49
|
__export(Adaptor_exports, {
|
|
47
|
-
alterState: () =>
|
|
50
|
+
alterState: () => import_language_common3.alterState,
|
|
48
51
|
createTask: () => createTask,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
createTaskStory: () => createTaskStory,
|
|
53
|
+
cursor: () => import_language_common3.cursor,
|
|
54
|
+
dataPath: () => import_language_common3.dataPath,
|
|
55
|
+
dataValue: () => import_language_common3.dataValue,
|
|
56
|
+
dateFns: () => import_language_common3.dateFns,
|
|
57
|
+
each: () => import_language_common3.each,
|
|
53
58
|
execute: () => execute,
|
|
54
|
-
field: () =>
|
|
55
|
-
fields: () =>
|
|
56
|
-
fn: () =>
|
|
59
|
+
field: () => import_language_common3.field,
|
|
60
|
+
fields: () => import_language_common3.fields,
|
|
61
|
+
fn: () => import_language_common3.fn,
|
|
57
62
|
getTask: () => getTask,
|
|
58
63
|
getTasks: () => getTasks,
|
|
59
|
-
http: () =>
|
|
60
|
-
lastReferenceValue: () =>
|
|
61
|
-
merge: () =>
|
|
62
|
-
|
|
64
|
+
http: () => import_language_common3.http,
|
|
65
|
+
lastReferenceValue: () => import_language_common3.lastReferenceValue,
|
|
66
|
+
merge: () => import_language_common3.merge,
|
|
67
|
+
request: () => request2,
|
|
68
|
+
sourceValue: () => import_language_common3.sourceValue,
|
|
63
69
|
updateTask: () => updateTask,
|
|
64
70
|
upsertTask: () => upsertTask
|
|
65
71
|
});
|
|
66
|
-
var import_language_common = require("@openfn/language-common");
|
|
67
72
|
var import_language_common2 = require("@openfn/language-common");
|
|
73
|
+
var import_util2 = require("@openfn/language-common/util");
|
|
74
|
+
|
|
75
|
+
// src/Utils.js
|
|
76
|
+
var import_language_common = require("@openfn/language-common");
|
|
77
|
+
var import_util = require("@openfn/language-common/util");
|
|
78
|
+
function addAuth(headers, configuration = {}) {
|
|
79
|
+
const { token } = configuration;
|
|
80
|
+
if (token) {
|
|
81
|
+
Object.assign(headers, { Authorization: `Bearer ${token}` });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function request(state, path, params, callback = (s) => s) {
|
|
85
|
+
var _a;
|
|
86
|
+
let { body, headers = {}, method = "GET", ...rest } = params;
|
|
87
|
+
const baseUrl = `https://app.asana.com/api/${(_a = state.configuration) == null ? void 0 : _a.apiVersion}`;
|
|
88
|
+
addAuth(headers, state.configuration);
|
|
89
|
+
const options = {
|
|
90
|
+
...rest,
|
|
91
|
+
headers,
|
|
92
|
+
baseUrl,
|
|
93
|
+
body
|
|
94
|
+
};
|
|
95
|
+
return (0, import_util.request)(method, path, options).then((response) => {
|
|
96
|
+
(0, import_util.logResponse)(response);
|
|
97
|
+
const { body: body2, ...responseWithoutBody } = response;
|
|
98
|
+
return {
|
|
99
|
+
...(0, import_language_common.composeNextState)(state, body2 == null ? void 0 : body2.data),
|
|
100
|
+
response: responseWithoutBody
|
|
101
|
+
};
|
|
102
|
+
}).then(callback).catch((err) => {
|
|
103
|
+
console.log("Asana says:");
|
|
104
|
+
(0, import_util.logResponse)(err);
|
|
105
|
+
throw err;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/Adaptor.js
|
|
110
|
+
var import_language_common3 = require("@openfn/language-common");
|
|
68
111
|
function execute(...operations) {
|
|
69
112
|
const initialState = {
|
|
70
113
|
references: [],
|
|
71
114
|
data: null
|
|
72
115
|
};
|
|
73
116
|
return (state) => {
|
|
74
|
-
return (0,
|
|
117
|
+
return (0, import_language_common2.execute)(...operations)({
|
|
75
118
|
...initialState,
|
|
76
119
|
...state
|
|
77
120
|
});
|
|
@@ -79,129 +122,123 @@ function execute(...operations) {
|
|
|
79
122
|
}
|
|
80
123
|
function getTask(taskGid, params, callback) {
|
|
81
124
|
return (state) => {
|
|
82
|
-
const resolvedTaskGid = (0,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return import_language_common.http.get(config)(state).then((response) => {
|
|
94
|
-
const nextState = {
|
|
95
|
-
...(0, import_language_common.composeNextState)(state, response.data),
|
|
96
|
-
response
|
|
97
|
-
};
|
|
98
|
-
if (callback)
|
|
99
|
-
return callback(nextState);
|
|
100
|
-
return nextState;
|
|
101
|
-
});
|
|
125
|
+
const [resolvedTaskGid, resolvedParams] = (0, import_util2.expandReferences)(
|
|
126
|
+
state,
|
|
127
|
+
taskGid,
|
|
128
|
+
params
|
|
129
|
+
);
|
|
130
|
+
return request(
|
|
131
|
+
state,
|
|
132
|
+
`tasks/${resolvedTaskGid}`,
|
|
133
|
+
{ query: resolvedParams },
|
|
134
|
+
callback
|
|
135
|
+
);
|
|
102
136
|
};
|
|
103
137
|
}
|
|
104
138
|
function getTasks(projectGid, params, callback) {
|
|
105
139
|
return (state) => {
|
|
106
|
-
const resolvedProjectGid = (0,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return import_language_common.http.get(config)(state).then((response) => {
|
|
118
|
-
const nextState = {
|
|
119
|
-
...(0, import_language_common.composeNextState)(state, response.data),
|
|
120
|
-
response
|
|
121
|
-
};
|
|
122
|
-
if (callback)
|
|
123
|
-
return callback(nextState);
|
|
124
|
-
return nextState;
|
|
125
|
-
});
|
|
140
|
+
const [resolvedProjectGid, resolvedParams] = (0, import_util2.expandReferences)(
|
|
141
|
+
state,
|
|
142
|
+
projectGid,
|
|
143
|
+
params
|
|
144
|
+
);
|
|
145
|
+
return request(
|
|
146
|
+
state,
|
|
147
|
+
`projects/${resolvedProjectGid}/tasks`,
|
|
148
|
+
{ query: resolvedParams },
|
|
149
|
+
callback
|
|
150
|
+
);
|
|
126
151
|
};
|
|
127
152
|
}
|
|
128
153
|
function updateTask(taskGid, params, callback) {
|
|
129
154
|
return (state) => {
|
|
130
|
-
const resolvedTaskGid = (0,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
...(0, import_language_common.composeNextState)(state, response.data),
|
|
142
|
-
response
|
|
143
|
-
};
|
|
144
|
-
if (callback)
|
|
145
|
-
return callback(nextState);
|
|
146
|
-
return nextState;
|
|
147
|
-
}).catch((e) => {
|
|
148
|
-
console.log("Asana says:", e.response.data);
|
|
149
|
-
throw e;
|
|
150
|
-
});
|
|
155
|
+
const [resolvedTaskGid, resolvedParams] = (0, import_util2.expandReferences)(
|
|
156
|
+
state,
|
|
157
|
+
taskGid,
|
|
158
|
+
params
|
|
159
|
+
);
|
|
160
|
+
return request(
|
|
161
|
+
state,
|
|
162
|
+
`tasks/${resolvedTaskGid}`,
|
|
163
|
+
{ body: { data: resolvedParams }, method: "PUT" },
|
|
164
|
+
callback
|
|
165
|
+
);
|
|
151
166
|
};
|
|
152
167
|
}
|
|
153
168
|
function createTask(params, callback) {
|
|
154
169
|
return (state) => {
|
|
155
|
-
const resolvedParams = (0,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
};
|
|
163
|
-
return import_language_common.http.post(config)(state).then((response) => {
|
|
164
|
-
const nextState = {
|
|
165
|
-
...(0, import_language_common.composeNextState)(state, response.data),
|
|
166
|
-
response
|
|
167
|
-
};
|
|
168
|
-
if (callback)
|
|
169
|
-
return callback(nextState);
|
|
170
|
-
return nextState;
|
|
171
|
-
}).catch((e) => {
|
|
172
|
-
console.log("Asana says:", e.response.data);
|
|
173
|
-
throw e;
|
|
174
|
-
});
|
|
170
|
+
const [resolvedParams] = (0, import_util2.expandReferences)(state, params);
|
|
171
|
+
return request(
|
|
172
|
+
state,
|
|
173
|
+
"tasks",
|
|
174
|
+
{ body: { data: resolvedParams }, method: "POST" },
|
|
175
|
+
callback
|
|
176
|
+
);
|
|
175
177
|
};
|
|
176
178
|
}
|
|
177
179
|
function upsertTask(projectGid, params, callback) {
|
|
178
180
|
return (state) => {
|
|
179
|
-
const resolvedProjectGid = (0,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
181
|
+
const [resolvedProjectGid, { externalId, data }] = (0, import_util2.expandReferences)(
|
|
182
|
+
state,
|
|
183
|
+
projectGid,
|
|
184
|
+
params
|
|
185
|
+
);
|
|
186
|
+
return request(
|
|
187
|
+
state,
|
|
188
|
+
`projects/${resolvedProjectGid}/tasks`,
|
|
189
|
+
{ query: { opt_fields: `${externalId}` } },
|
|
190
|
+
(next) => {
|
|
191
|
+
const matchingTask = next.data.find(
|
|
192
|
+
(task) => task[externalId] === data[externalId]
|
|
193
|
+
);
|
|
194
|
+
if (matchingTask) {
|
|
195
|
+
console.log("Matching task found. Performing update.");
|
|
196
|
+
console.log("Data to update", data);
|
|
197
|
+
const { projects, workspace, ...remainingData } = data;
|
|
198
|
+
return updateTask(matchingTask.gid, remainingData, callback)(state);
|
|
199
|
+
} else {
|
|
200
|
+
console.log("No matching task found. Performing create.");
|
|
201
|
+
return createTask(data, callback)(state);
|
|
202
|
+
}
|
|
188
203
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
);
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function createTaskStory(taskGid, params, callback) {
|
|
208
|
+
return (state) => {
|
|
209
|
+
const [
|
|
210
|
+
resolvedTaskGid,
|
|
211
|
+
{
|
|
212
|
+
text,
|
|
213
|
+
html_text,
|
|
214
|
+
sticker_name,
|
|
215
|
+
is_pinned = false,
|
|
216
|
+
opt_pretty = false,
|
|
217
|
+
opt_fields = []
|
|
203
218
|
}
|
|
204
|
-
|
|
219
|
+
] = (0, import_util2.expandReferences)(state, taskGid, params);
|
|
220
|
+
const story = { text, html_text, is_pinned, sticker_name };
|
|
221
|
+
return request(
|
|
222
|
+
state,
|
|
223
|
+
`tasks/${resolvedTaskGid}/stories`,
|
|
224
|
+
{
|
|
225
|
+
body: { data: story },
|
|
226
|
+
query: { opt_fields, opt_pretty },
|
|
227
|
+
method: "POST"
|
|
228
|
+
},
|
|
229
|
+
callback
|
|
230
|
+
);
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function request2(path, params, callback) {
|
|
234
|
+
return (state) => {
|
|
235
|
+
const [resolvedPath, { body = {}, query = {}, method = "GET" }] = (0, import_util2.expandReferences)(state, path, params);
|
|
236
|
+
return request(
|
|
237
|
+
state,
|
|
238
|
+
resolvedPath,
|
|
239
|
+
{ method, body, query },
|
|
240
|
+
callback
|
|
241
|
+
);
|
|
205
242
|
};
|
|
206
243
|
}
|
|
207
244
|
|
|
@@ -211,6 +248,8 @@ var src_default = Adaptor_exports;
|
|
|
211
248
|
0 && (module.exports = {
|
|
212
249
|
alterState,
|
|
213
250
|
createTask,
|
|
251
|
+
createTaskStory,
|
|
252
|
+
cursor,
|
|
214
253
|
dataPath,
|
|
215
254
|
dataValue,
|
|
216
255
|
dateFns,
|
|
@@ -224,6 +263,7 @@ var src_default = Adaptor_exports;
|
|
|
224
263
|
http,
|
|
225
264
|
lastReferenceValue,
|
|
226
265
|
merge,
|
|
266
|
+
request,
|
|
227
267
|
sourceValue,
|
|
228
268
|
updateTask,
|
|
229
269
|
upsertTask
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ var Adaptor_exports = {};
|
|
|
9
9
|
__export(Adaptor_exports, {
|
|
10
10
|
alterState: () => alterState,
|
|
11
11
|
createTask: () => createTask,
|
|
12
|
+
createTaskStory: () => createTaskStory,
|
|
13
|
+
cursor: () => cursor,
|
|
12
14
|
dataPath: () => dataPath,
|
|
13
15
|
dataValue: () => dataValue,
|
|
14
16
|
dateFns: () => dateFns,
|
|
@@ -19,21 +21,58 @@ __export(Adaptor_exports, {
|
|
|
19
21
|
fn: () => fn,
|
|
20
22
|
getTask: () => getTask,
|
|
21
23
|
getTasks: () => getTasks,
|
|
22
|
-
http: () =>
|
|
24
|
+
http: () => http,
|
|
23
25
|
lastReferenceValue: () => lastReferenceValue,
|
|
24
26
|
merge: () => merge,
|
|
27
|
+
request: () => request2,
|
|
25
28
|
sourceValue: () => sourceValue,
|
|
26
29
|
updateTask: () => updateTask,
|
|
27
30
|
upsertTask: () => upsertTask
|
|
28
31
|
});
|
|
32
|
+
import { execute as commonExecute } from "@openfn/language-common";
|
|
33
|
+
import { expandReferences } from "@openfn/language-common/util";
|
|
34
|
+
|
|
35
|
+
// src/Utils.js
|
|
36
|
+
import { composeNextState } from "@openfn/language-common";
|
|
29
37
|
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
38
|
+
request as commonRequest,
|
|
39
|
+
logResponse
|
|
40
|
+
} from "@openfn/language-common/util";
|
|
41
|
+
function addAuth(headers, configuration = {}) {
|
|
42
|
+
const { token } = configuration;
|
|
43
|
+
if (token) {
|
|
44
|
+
Object.assign(headers, { Authorization: `Bearer ${token}` });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function request(state, path, params, callback = (s) => s) {
|
|
48
|
+
var _a;
|
|
49
|
+
let { body, headers = {}, method = "GET", ...rest } = params;
|
|
50
|
+
const baseUrl = `https://app.asana.com/api/${(_a = state.configuration) == null ? void 0 : _a.apiVersion}`;
|
|
51
|
+
addAuth(headers, state.configuration);
|
|
52
|
+
const options = {
|
|
53
|
+
...rest,
|
|
54
|
+
headers,
|
|
55
|
+
baseUrl,
|
|
56
|
+
body
|
|
57
|
+
};
|
|
58
|
+
return commonRequest(method, path, options).then((response) => {
|
|
59
|
+
logResponse(response);
|
|
60
|
+
const { body: body2, ...responseWithoutBody } = response;
|
|
61
|
+
return {
|
|
62
|
+
...composeNextState(state, body2 == null ? void 0 : body2.data),
|
|
63
|
+
response: responseWithoutBody
|
|
64
|
+
};
|
|
65
|
+
}).then(callback).catch((err) => {
|
|
66
|
+
console.log("Asana says:");
|
|
67
|
+
logResponse(err);
|
|
68
|
+
throw err;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/Adaptor.js
|
|
35
73
|
import {
|
|
36
74
|
alterState,
|
|
75
|
+
cursor,
|
|
37
76
|
dataPath,
|
|
38
77
|
dataValue,
|
|
39
78
|
dateFns,
|
|
@@ -41,7 +80,7 @@ import {
|
|
|
41
80
|
field,
|
|
42
81
|
fields,
|
|
43
82
|
fn,
|
|
44
|
-
http
|
|
83
|
+
http,
|
|
45
84
|
lastReferenceValue,
|
|
46
85
|
merge,
|
|
47
86
|
sourceValue
|
|
@@ -60,129 +99,123 @@ function execute(...operations) {
|
|
|
60
99
|
}
|
|
61
100
|
function getTask(taskGid, params, callback) {
|
|
62
101
|
return (state) => {
|
|
63
|
-
const resolvedTaskGid = expandReferences(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return http.get(config)(state).then((response) => {
|
|
75
|
-
const nextState = {
|
|
76
|
-
...composeNextState(state, response.data),
|
|
77
|
-
response
|
|
78
|
-
};
|
|
79
|
-
if (callback)
|
|
80
|
-
return callback(nextState);
|
|
81
|
-
return nextState;
|
|
82
|
-
});
|
|
102
|
+
const [resolvedTaskGid, resolvedParams] = expandReferences(
|
|
103
|
+
state,
|
|
104
|
+
taskGid,
|
|
105
|
+
params
|
|
106
|
+
);
|
|
107
|
+
return request(
|
|
108
|
+
state,
|
|
109
|
+
`tasks/${resolvedTaskGid}`,
|
|
110
|
+
{ query: resolvedParams },
|
|
111
|
+
callback
|
|
112
|
+
);
|
|
83
113
|
};
|
|
84
114
|
}
|
|
85
115
|
function getTasks(projectGid, params, callback) {
|
|
86
116
|
return (state) => {
|
|
87
|
-
const resolvedProjectGid = expandReferences(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return http.get(config)(state).then((response) => {
|
|
99
|
-
const nextState = {
|
|
100
|
-
...composeNextState(state, response.data),
|
|
101
|
-
response
|
|
102
|
-
};
|
|
103
|
-
if (callback)
|
|
104
|
-
return callback(nextState);
|
|
105
|
-
return nextState;
|
|
106
|
-
});
|
|
117
|
+
const [resolvedProjectGid, resolvedParams] = expandReferences(
|
|
118
|
+
state,
|
|
119
|
+
projectGid,
|
|
120
|
+
params
|
|
121
|
+
);
|
|
122
|
+
return request(
|
|
123
|
+
state,
|
|
124
|
+
`projects/${resolvedProjectGid}/tasks`,
|
|
125
|
+
{ query: resolvedParams },
|
|
126
|
+
callback
|
|
127
|
+
);
|
|
107
128
|
};
|
|
108
129
|
}
|
|
109
130
|
function updateTask(taskGid, params, callback) {
|
|
110
131
|
return (state) => {
|
|
111
|
-
const resolvedTaskGid = expandReferences(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
...composeNextState(state, response.data),
|
|
123
|
-
response
|
|
124
|
-
};
|
|
125
|
-
if (callback)
|
|
126
|
-
return callback(nextState);
|
|
127
|
-
return nextState;
|
|
128
|
-
}).catch((e) => {
|
|
129
|
-
console.log("Asana says:", e.response.data);
|
|
130
|
-
throw e;
|
|
131
|
-
});
|
|
132
|
+
const [resolvedTaskGid, resolvedParams] = expandReferences(
|
|
133
|
+
state,
|
|
134
|
+
taskGid,
|
|
135
|
+
params
|
|
136
|
+
);
|
|
137
|
+
return request(
|
|
138
|
+
state,
|
|
139
|
+
`tasks/${resolvedTaskGid}`,
|
|
140
|
+
{ body: { data: resolvedParams }, method: "PUT" },
|
|
141
|
+
callback
|
|
142
|
+
);
|
|
132
143
|
};
|
|
133
144
|
}
|
|
134
145
|
function createTask(params, callback) {
|
|
135
146
|
return (state) => {
|
|
136
|
-
const resolvedParams = expandReferences(params)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
};
|
|
144
|
-
return http.post(config)(state).then((response) => {
|
|
145
|
-
const nextState = {
|
|
146
|
-
...composeNextState(state, response.data),
|
|
147
|
-
response
|
|
148
|
-
};
|
|
149
|
-
if (callback)
|
|
150
|
-
return callback(nextState);
|
|
151
|
-
return nextState;
|
|
152
|
-
}).catch((e) => {
|
|
153
|
-
console.log("Asana says:", e.response.data);
|
|
154
|
-
throw e;
|
|
155
|
-
});
|
|
147
|
+
const [resolvedParams] = expandReferences(state, params);
|
|
148
|
+
return request(
|
|
149
|
+
state,
|
|
150
|
+
"tasks",
|
|
151
|
+
{ body: { data: resolvedParams }, method: "POST" },
|
|
152
|
+
callback
|
|
153
|
+
);
|
|
156
154
|
};
|
|
157
155
|
}
|
|
158
156
|
function upsertTask(projectGid, params, callback) {
|
|
159
157
|
return (state) => {
|
|
160
|
-
const resolvedProjectGid = expandReferences(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
158
|
+
const [resolvedProjectGid, { externalId, data }] = expandReferences(
|
|
159
|
+
state,
|
|
160
|
+
projectGid,
|
|
161
|
+
params
|
|
162
|
+
);
|
|
163
|
+
return request(
|
|
164
|
+
state,
|
|
165
|
+
`projects/${resolvedProjectGid}/tasks`,
|
|
166
|
+
{ query: { opt_fields: `${externalId}` } },
|
|
167
|
+
(next) => {
|
|
168
|
+
const matchingTask = next.data.find(
|
|
169
|
+
(task) => task[externalId] === data[externalId]
|
|
170
|
+
);
|
|
171
|
+
if (matchingTask) {
|
|
172
|
+
console.log("Matching task found. Performing update.");
|
|
173
|
+
console.log("Data to update", data);
|
|
174
|
+
const { projects, workspace, ...remainingData } = data;
|
|
175
|
+
return updateTask(matchingTask.gid, remainingData, callback)(state);
|
|
176
|
+
} else {
|
|
177
|
+
console.log("No matching task found. Performing create.");
|
|
178
|
+
return createTask(data, callback)(state);
|
|
179
|
+
}
|
|
169
180
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function createTaskStory(taskGid, params, callback) {
|
|
185
|
+
return (state) => {
|
|
186
|
+
const [
|
|
187
|
+
resolvedTaskGid,
|
|
188
|
+
{
|
|
189
|
+
text,
|
|
190
|
+
html_text,
|
|
191
|
+
sticker_name,
|
|
192
|
+
is_pinned = false,
|
|
193
|
+
opt_pretty = false,
|
|
194
|
+
opt_fields = []
|
|
184
195
|
}
|
|
185
|
-
|
|
196
|
+
] = expandReferences(state, taskGid, params);
|
|
197
|
+
const story = { text, html_text, is_pinned, sticker_name };
|
|
198
|
+
return request(
|
|
199
|
+
state,
|
|
200
|
+
`tasks/${resolvedTaskGid}/stories`,
|
|
201
|
+
{
|
|
202
|
+
body: { data: story },
|
|
203
|
+
query: { opt_fields, opt_pretty },
|
|
204
|
+
method: "POST"
|
|
205
|
+
},
|
|
206
|
+
callback
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function request2(path, params, callback) {
|
|
211
|
+
return (state) => {
|
|
212
|
+
const [resolvedPath, { body = {}, query = {}, method = "GET" }] = expandReferences(state, path, params);
|
|
213
|
+
return request(
|
|
214
|
+
state,
|
|
215
|
+
resolvedPath,
|
|
216
|
+
{ method, body, query },
|
|
217
|
+
callback
|
|
218
|
+
);
|
|
186
219
|
};
|
|
187
220
|
}
|
|
188
221
|
|
|
@@ -191,6 +224,8 @@ var src_default = Adaptor_exports;
|
|
|
191
224
|
export {
|
|
192
225
|
alterState,
|
|
193
226
|
createTask,
|
|
227
|
+
createTaskStory,
|
|
228
|
+
cursor,
|
|
194
229
|
dataPath,
|
|
195
230
|
dataValue,
|
|
196
231
|
dateFns,
|
|
@@ -202,9 +237,10 @@ export {
|
|
|
202
237
|
fn,
|
|
203
238
|
getTask,
|
|
204
239
|
getTasks,
|
|
205
|
-
|
|
240
|
+
http,
|
|
206
241
|
lastReferenceValue,
|
|
207
242
|
merge,
|
|
243
|
+
request2 as request,
|
|
208
244
|
sourceValue,
|
|
209
245
|
updateTask,
|
|
210
246
|
upsertTask
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/language-asana",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "An adaptor to access objects in Asana",
|
|
5
5
|
"homepage": "https://docs.openfn.org",
|
|
6
6
|
"repository": {
|
|
@@ -23,10 +23,9 @@
|
|
|
23
23
|
"configuration-schema.json"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@openfn/language-common": "^1.
|
|
26
|
+
"@openfn/language-common": "^1.13.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@openfn/buildtools": "^1.0.2",
|
|
30
29
|
"@openfn/simple-ast": "0.4.1",
|
|
31
30
|
"assertion-error": "2.0.0",
|
|
32
31
|
"chai": "4.3.6",
|
package/types/Adaptor.d.ts
CHANGED
|
@@ -15,10 +15,9 @@ export function execute(...operations: Operations): Operation;
|
|
|
15
15
|
* Get a single task of a given project.
|
|
16
16
|
* @public
|
|
17
17
|
* @example
|
|
18
|
-
* getTask("
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* })
|
|
18
|
+
* getTask("1206933955023739", {
|
|
19
|
+
* opt_fields: "name,notes,assignee",
|
|
20
|
+
* });
|
|
22
21
|
* @function
|
|
23
22
|
* @param {string} taskGid - Globally unique identifier for the task
|
|
24
23
|
* @param {object} params - Query params to include.
|
|
@@ -30,10 +29,9 @@ export function getTask(taskGid: string, params: object, callback: Function): Op
|
|
|
30
29
|
* Get the list of tasks for a given project.
|
|
31
30
|
* @public
|
|
32
31
|
* @example
|
|
33
|
-
* getTasks("
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* })
|
|
32
|
+
* getTasks("1206933955023739", {
|
|
33
|
+
* opt_fields: "name,notes,assignee",
|
|
34
|
+
* });
|
|
37
35
|
* @function
|
|
38
36
|
* @param {string} projectGid - Globally unique identifier for the project
|
|
39
37
|
* @param {object} params - Query params to include.
|
|
@@ -45,11 +43,11 @@ export function getTasks(projectGid: string, params: object, callback: Function)
|
|
|
45
43
|
* Update a specific task.
|
|
46
44
|
* @public
|
|
47
45
|
* @example
|
|
48
|
-
* updateTask("
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* )
|
|
46
|
+
* updateTask("1206933955023739", {
|
|
47
|
+
* name: "test",
|
|
48
|
+
* approval_status: "pending",
|
|
49
|
+
* assignee: "12345",
|
|
50
|
+
* });
|
|
53
51
|
* @function
|
|
54
52
|
* @param {string} taskGid - Globally unique identifier for the task
|
|
55
53
|
* @param {object} params - Body parameters
|
|
@@ -61,11 +59,12 @@ export function updateTask(taskGid: string, params: object, callback: Function):
|
|
|
61
59
|
* Create a task.
|
|
62
60
|
* @public
|
|
63
61
|
* @example
|
|
64
|
-
* createTask(
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
62
|
+
* createTask({
|
|
63
|
+
* name: "test",
|
|
64
|
+
* approval_status: "pending",
|
|
65
|
+
* assignee: "12345",
|
|
66
|
+
* projects: ["1206933955023739"],
|
|
67
|
+
* });
|
|
69
68
|
* @function
|
|
70
69
|
* @param {object} params - Body parameters
|
|
71
70
|
* @param {function} callback - (Optional) callback function
|
|
@@ -76,16 +75,15 @@ export function createTask(params: object, callback: Function): Operation;
|
|
|
76
75
|
* Update or create a task.
|
|
77
76
|
* @public
|
|
78
77
|
* @example
|
|
79
|
-
* upsertTask(
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* )
|
|
78
|
+
* upsertTask("1201382240880", {
|
|
79
|
+
* externalId: "name",
|
|
80
|
+
* data: {
|
|
81
|
+
* name: "test",
|
|
82
|
+
* approval_status: "pending",
|
|
83
|
+
* projects: ["1201382240880"],
|
|
84
|
+
* assignee: "12345",
|
|
85
|
+
* },
|
|
86
|
+
* });
|
|
89
87
|
* @function
|
|
90
88
|
* @param {string} projectGid - Globally unique identifier for the project
|
|
91
89
|
* @param {object} params - an object with an externalId and some task data.
|
|
@@ -93,4 +91,100 @@ export function createTask(params: object, callback: Function): Operation;
|
|
|
93
91
|
* @returns {Operation}
|
|
94
92
|
*/
|
|
95
93
|
export function upsertTask(projectGid: string, params: object, callback: Function): Operation;
|
|
96
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Options provided to the createTaskStory request
|
|
96
|
+
* @typedef {Object} StoryOptions
|
|
97
|
+
* @property {string} text - The plain text of the comment to add. Cannot be used with html_text.
|
|
98
|
+
* @property {string} html_text - Opt In. HTML formatted text for a comment. This will not include the name of the creator.
|
|
99
|
+
* @property {boolean} is_pinned - Default to `false`. Whether the story should be pinned on the resource.
|
|
100
|
+
* @property {string} sticker_name - The name of the sticker in this story. `null` if there is no sticker.
|
|
101
|
+
* @property {array} opt_fields - Opt In. This endpoint returns a compact resource, which excludes some properties by default. To include those optional properties, set this query parameter to a comma-separated list of the properties you wish to include.
|
|
102
|
+
* @property {boolean} opt_pretty - Defaults to `false`. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.
|
|
103
|
+
*/
|
|
104
|
+
/**
|
|
105
|
+
* Create a story to a specific task.
|
|
106
|
+
* @public
|
|
107
|
+
* @example <caption>Create a plain text comment</caption>
|
|
108
|
+
* createTaskStory("1206933955023739", {
|
|
109
|
+
* text: "This is a comment",
|
|
110
|
+
* });
|
|
111
|
+
* @example <caption>Create a HTML formatted text comment</caption>
|
|
112
|
+
* createTaskStory("1206933955023739", {
|
|
113
|
+
* html_text: "<body>This is a comment</body>",
|
|
114
|
+
* });
|
|
115
|
+
* @function
|
|
116
|
+
* @param {string} taskGid - Globally unique identifier for the task
|
|
117
|
+
* @param {StoryOptions} params - Story parameters
|
|
118
|
+
* @param {function} callback - (Optional) callback function
|
|
119
|
+
* @returns {Operation}
|
|
120
|
+
*/
|
|
121
|
+
export function createTaskStory(taskGid: string, params: StoryOptions, callback: Function): Operation;
|
|
122
|
+
/**
|
|
123
|
+
* Options provided to the Asana API request
|
|
124
|
+
* @typedef {Object} RequestOptions
|
|
125
|
+
* @property {object} body - Body data to append to the request.
|
|
126
|
+
* @property {object} query - An object of query parameters to be encoded into the URL.
|
|
127
|
+
* @property {string} method - The HTTP method to use. Defaults to `GET`
|
|
128
|
+
*/
|
|
129
|
+
/**
|
|
130
|
+
* Make a request in Asana API
|
|
131
|
+
* @public
|
|
132
|
+
* @example
|
|
133
|
+
* request("/asanaEndpoint", {
|
|
134
|
+
* method: "POST",
|
|
135
|
+
* query: { foo: "bar", a: 1 },
|
|
136
|
+
* });
|
|
137
|
+
* @function
|
|
138
|
+
* @param {string} path - Path to resource
|
|
139
|
+
* @param {RequestOptions} params - Query, body and method parameters
|
|
140
|
+
* @param {function} callback - (Optional) Callback function
|
|
141
|
+
* @returns {Operation}
|
|
142
|
+
*/
|
|
143
|
+
export function request(path: string, params: RequestOptions, callback: Function): Operation;
|
|
144
|
+
/**
|
|
145
|
+
* Options provided to the createTaskStory request
|
|
146
|
+
*/
|
|
147
|
+
export type StoryOptions = {
|
|
148
|
+
/**
|
|
149
|
+
* - The plain text of the comment to add. Cannot be used with html_text.
|
|
150
|
+
*/
|
|
151
|
+
text: string;
|
|
152
|
+
/**
|
|
153
|
+
* - Opt In. HTML formatted text for a comment. This will not include the name of the creator.
|
|
154
|
+
*/
|
|
155
|
+
html_text: string;
|
|
156
|
+
/**
|
|
157
|
+
* - Default to `false`. Whether the story should be pinned on the resource.
|
|
158
|
+
*/
|
|
159
|
+
is_pinned: boolean;
|
|
160
|
+
/**
|
|
161
|
+
* - The name of the sticker in this story. `null` if there is no sticker.
|
|
162
|
+
*/
|
|
163
|
+
sticker_name: string;
|
|
164
|
+
/**
|
|
165
|
+
* - Opt In. This endpoint returns a compact resource, which excludes some properties by default. To include those optional properties, set this query parameter to a comma-separated list of the properties you wish to include.
|
|
166
|
+
*/
|
|
167
|
+
opt_fields: any[];
|
|
168
|
+
/**
|
|
169
|
+
* - Defaults to `false`. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.
|
|
170
|
+
*/
|
|
171
|
+
opt_pretty: boolean;
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Options provided to the Asana API request
|
|
175
|
+
*/
|
|
176
|
+
export type RequestOptions = {
|
|
177
|
+
/**
|
|
178
|
+
* - Body data to append to the request.
|
|
179
|
+
*/
|
|
180
|
+
body: object;
|
|
181
|
+
/**
|
|
182
|
+
* - An object of query parameters to be encoded into the URL.
|
|
183
|
+
*/
|
|
184
|
+
query: object;
|
|
185
|
+
/**
|
|
186
|
+
* - The HTTP method to use. Defaults to `GET`
|
|
187
|
+
*/
|
|
188
|
+
method: string;
|
|
189
|
+
};
|
|
190
|
+
export { alterState, cursor, dataPath, dataValue, dateFns, each, field, fields, fn, http, lastReferenceValue, merge, sourceValue } from "@openfn/language-common";
|
package/types/Utils.d.ts
ADDED