@plotday/tool-asana 0.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/LICENSE.md +21 -0
- package/dist/asana.d.ts +89 -0
- package/dist/asana.js +347 -0
- package/dist/asana.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Plot Technologies Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/asana.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type ActivityLink, type NewActivityWithNotes } from "@plotday/twister";
|
|
2
|
+
import type { Project, ProjectAuth, ProjectSyncOptions, ProjectTool } from "@plotday/twister/common/projects";
|
|
3
|
+
import { Tool, type ToolBuilder } from "@plotday/twister/tool";
|
|
4
|
+
import { Callbacks } from "@plotday/twister/tools/callbacks";
|
|
5
|
+
import { Integrations } from "@plotday/twister/tools/integrations";
|
|
6
|
+
import { Network } from "@plotday/twister/tools/network";
|
|
7
|
+
import { Plot } from "@plotday/twister/tools/plot";
|
|
8
|
+
import { Tasks } from "@plotday/twister/tools/tasks";
|
|
9
|
+
/**
|
|
10
|
+
* Asana project management tool
|
|
11
|
+
*
|
|
12
|
+
* Implements the ProjectTool interface for syncing Asana projects and tasks
|
|
13
|
+
* with Plot activities.
|
|
14
|
+
*/
|
|
15
|
+
export declare class Asana extends Tool<Asana> implements ProjectTool {
|
|
16
|
+
build(build: ToolBuilder): {
|
|
17
|
+
integrations: Promise<Integrations>;
|
|
18
|
+
network: Promise<Network>;
|
|
19
|
+
callbacks: Promise<Callbacks>;
|
|
20
|
+
tasks: Promise<Tasks>;
|
|
21
|
+
plot: Promise<Plot>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Create Asana API client with auth token
|
|
25
|
+
*/
|
|
26
|
+
private getClient;
|
|
27
|
+
/**
|
|
28
|
+
* Request Asana OAuth authorization
|
|
29
|
+
*/
|
|
30
|
+
requestAuth<TCallback extends (auth: ProjectAuth, ...args: any[]) => any>(callback: TCallback, ...extraArgs: TCallback extends (auth: any, ...rest: infer R) => any ? R : []): Promise<ActivityLink>;
|
|
31
|
+
/**
|
|
32
|
+
* Handle successful OAuth authorization
|
|
33
|
+
*/
|
|
34
|
+
private onAuthSuccess;
|
|
35
|
+
/**
|
|
36
|
+
* Get list of Asana projects
|
|
37
|
+
*/
|
|
38
|
+
getProjects(authToken: string): Promise<Project[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Start syncing tasks from an Asana project
|
|
41
|
+
*/
|
|
42
|
+
startSync<TCallback extends (task: NewActivityWithNotes, ...args: any[]) => any>(authToken: string, projectId: string, callback: TCallback, options?: ProjectSyncOptions, ...extraArgs: TCallback extends (task: any, ...rest: infer R) => any ? R : []): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Setup Asana webhook for real-time updates
|
|
45
|
+
* Note: Asana webhook API requires special permissions, so we skip for now
|
|
46
|
+
*/
|
|
47
|
+
private setupAsanaWebhook;
|
|
48
|
+
/**
|
|
49
|
+
* Initialize batch sync process
|
|
50
|
+
*/
|
|
51
|
+
private startBatchSync;
|
|
52
|
+
/**
|
|
53
|
+
* Process a batch of tasks
|
|
54
|
+
*/
|
|
55
|
+
private syncBatch;
|
|
56
|
+
/**
|
|
57
|
+
* Convert an Asana task to a Plot Activity
|
|
58
|
+
*/
|
|
59
|
+
private convertTaskToActivity;
|
|
60
|
+
/**
|
|
61
|
+
* Update task with new values
|
|
62
|
+
*
|
|
63
|
+
* @param authToken - Authorization token
|
|
64
|
+
* @param update - ActivityUpdate with changed fields
|
|
65
|
+
*/
|
|
66
|
+
updateIssue(authToken: string, update: import("@plotday/twister").ActivityUpdate): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Add a comment (story) to an Asana task
|
|
69
|
+
*
|
|
70
|
+
* @param authToken - Authorization token
|
|
71
|
+
* @param issueId - Asana task GID
|
|
72
|
+
* @param body - Comment text (markdown not directly supported, plain text)
|
|
73
|
+
*/
|
|
74
|
+
addIssueComment(authToken: string, issueId: string, body: string): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Verify Asana webhook signature
|
|
77
|
+
* Asana uses HMAC-SHA256 with a shared secret
|
|
78
|
+
*/
|
|
79
|
+
private verifyAsanaSignature;
|
|
80
|
+
/**
|
|
81
|
+
* Handle incoming webhook events from Asana
|
|
82
|
+
*/
|
|
83
|
+
private onWebhook;
|
|
84
|
+
/**
|
|
85
|
+
* Stop syncing an Asana project
|
|
86
|
+
*/
|
|
87
|
+
stopSync(authToken: string, projectId: string): Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
export default Asana;
|
package/dist/asana.js
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import * as asana from "asana";
|
|
2
|
+
import { ActivityType, } from "@plotday/twister";
|
|
3
|
+
import { Tool } from "@plotday/twister/tool";
|
|
4
|
+
import { Callbacks } from "@plotday/twister/tools/callbacks";
|
|
5
|
+
import { AuthLevel, AuthProvider, Integrations, } from "@plotday/twister/tools/integrations";
|
|
6
|
+
import { Network } from "@plotday/twister/tools/network";
|
|
7
|
+
import { ContactAccess, Plot } from "@plotday/twister/tools/plot";
|
|
8
|
+
import { Tasks } from "@plotday/twister/tools/tasks";
|
|
9
|
+
/**
|
|
10
|
+
* Asana project management tool
|
|
11
|
+
*
|
|
12
|
+
* Implements the ProjectTool interface for syncing Asana projects and tasks
|
|
13
|
+
* with Plot activities.
|
|
14
|
+
*/
|
|
15
|
+
export class Asana extends Tool {
|
|
16
|
+
build(build) {
|
|
17
|
+
return {
|
|
18
|
+
integrations: build(Integrations),
|
|
19
|
+
network: build(Network, { urls: ["https://app.asana.com/*"] }),
|
|
20
|
+
callbacks: build(Callbacks),
|
|
21
|
+
tasks: build(Tasks),
|
|
22
|
+
plot: build(Plot, { contact: { access: ContactAccess.Write } }),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create Asana API client with auth token
|
|
27
|
+
*/
|
|
28
|
+
async getClient(authToken) {
|
|
29
|
+
const authorization = await this.get(`authorization:${authToken}`);
|
|
30
|
+
if (!authorization) {
|
|
31
|
+
throw new Error("Authorization no longer available");
|
|
32
|
+
}
|
|
33
|
+
const token = await this.tools.integrations.get(authorization);
|
|
34
|
+
if (!token) {
|
|
35
|
+
throw new Error("Authorization no longer available");
|
|
36
|
+
}
|
|
37
|
+
return asana.Client.create().useAccessToken(token.token);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Request Asana OAuth authorization
|
|
41
|
+
*/
|
|
42
|
+
async requestAuth(callback, ...extraArgs) {
|
|
43
|
+
const asanaScopes = ["default"];
|
|
44
|
+
// Generate opaque token for authorization
|
|
45
|
+
const authToken = crypto.randomUUID();
|
|
46
|
+
const callbackToken = await this.tools.callbacks.createFromParent(callback, ...extraArgs);
|
|
47
|
+
// Request auth and return the activity link
|
|
48
|
+
return await this.tools.integrations.request({
|
|
49
|
+
provider: AuthProvider.Asana,
|
|
50
|
+
level: AuthLevel.User,
|
|
51
|
+
scopes: asanaScopes,
|
|
52
|
+
}, this.onAuthSuccess, authToken, callbackToken);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Handle successful OAuth authorization
|
|
56
|
+
*/
|
|
57
|
+
async onAuthSuccess(authorization, authToken, callbackToken) {
|
|
58
|
+
// Store authorization for later use
|
|
59
|
+
await this.set(`authorization:${authToken}`, authorization);
|
|
60
|
+
// Execute the callback with the auth token
|
|
61
|
+
await this.run(callbackToken, { authToken });
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get list of Asana projects
|
|
65
|
+
*/
|
|
66
|
+
async getProjects(authToken) {
|
|
67
|
+
const client = await this.getClient(authToken);
|
|
68
|
+
// Get user's workspaces first
|
|
69
|
+
const workspaces = await client.workspaces.getWorkspaces();
|
|
70
|
+
const allProjects = [];
|
|
71
|
+
// Get projects from each workspace
|
|
72
|
+
for (const workspace of workspaces.data) {
|
|
73
|
+
const projects = await client.projects.findByWorkspace(workspace.gid, {
|
|
74
|
+
limit: 100,
|
|
75
|
+
});
|
|
76
|
+
for (const project of projects.data) {
|
|
77
|
+
allProjects.push({
|
|
78
|
+
id: project.gid,
|
|
79
|
+
name: project.name,
|
|
80
|
+
description: null, // Asana doesn't return description in list
|
|
81
|
+
key: null, // Asana doesn't have project keys
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return allProjects;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Start syncing tasks from an Asana project
|
|
89
|
+
*/
|
|
90
|
+
async startSync(authToken, projectId, callback, options, ...extraArgs) {
|
|
91
|
+
// Setup webhook for real-time updates
|
|
92
|
+
await this.setupAsanaWebhook(authToken, projectId);
|
|
93
|
+
// Store callback for webhook processing
|
|
94
|
+
const callbackToken = await this.tools.callbacks.createFromParent(callback, ...extraArgs);
|
|
95
|
+
await this.set(`callback_${projectId}`, callbackToken);
|
|
96
|
+
// Start initial batch sync
|
|
97
|
+
await this.startBatchSync(authToken, projectId, options);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Setup Asana webhook for real-time updates
|
|
101
|
+
* Note: Asana webhook API requires special permissions, so we skip for now
|
|
102
|
+
*/
|
|
103
|
+
async setupAsanaWebhook(authToken, projectId) {
|
|
104
|
+
// TODO: Implement Asana webhooks once we confirm the correct API
|
|
105
|
+
// The asana SDK webhook API may require special app permissions
|
|
106
|
+
console.log(`Asana webhooks not yet implemented for project ${projectId}`);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Initialize batch sync process
|
|
110
|
+
*/
|
|
111
|
+
async startBatchSync(authToken, projectId, options) {
|
|
112
|
+
// Initialize sync state
|
|
113
|
+
await this.set(`sync_state_${projectId}`, {
|
|
114
|
+
offset: 0,
|
|
115
|
+
batchNumber: 1,
|
|
116
|
+
tasksProcessed: 0,
|
|
117
|
+
initialSync: true,
|
|
118
|
+
});
|
|
119
|
+
// Queue first batch
|
|
120
|
+
const batchCallback = await this.callback(this.syncBatch, authToken, projectId, options);
|
|
121
|
+
await this.tools.tasks.runTask(batchCallback);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Process a batch of tasks
|
|
125
|
+
*/
|
|
126
|
+
async syncBatch(authToken, projectId, options) {
|
|
127
|
+
const state = await this.get(`sync_state_${projectId}`);
|
|
128
|
+
if (!state) {
|
|
129
|
+
throw new Error(`Sync state not found for project ${projectId}`);
|
|
130
|
+
}
|
|
131
|
+
// Retrieve callback token from storage
|
|
132
|
+
const callbackToken = await this.get(`callback_${projectId}`);
|
|
133
|
+
if (!callbackToken) {
|
|
134
|
+
throw new Error(`Callback token not found for project ${projectId}`);
|
|
135
|
+
}
|
|
136
|
+
const client = await this.getClient(authToken);
|
|
137
|
+
// Build request params
|
|
138
|
+
const batchSize = 50;
|
|
139
|
+
const params = {
|
|
140
|
+
project: projectId,
|
|
141
|
+
limit: batchSize,
|
|
142
|
+
opt_fields: [
|
|
143
|
+
"name",
|
|
144
|
+
"notes",
|
|
145
|
+
"completed",
|
|
146
|
+
"completed_at",
|
|
147
|
+
"created_at",
|
|
148
|
+
"modified_at",
|
|
149
|
+
].join(","),
|
|
150
|
+
};
|
|
151
|
+
if (state.offset > 0) {
|
|
152
|
+
params.offset = state.offset;
|
|
153
|
+
}
|
|
154
|
+
// Fetch batch of tasks using findAll
|
|
155
|
+
const tasksResult = await client.tasks.findAll(params);
|
|
156
|
+
// Process each task
|
|
157
|
+
for (const task of tasksResult.data) {
|
|
158
|
+
// Optionally filter by time
|
|
159
|
+
if (options?.timeMin) {
|
|
160
|
+
const createdAt = new Date(task.created_at);
|
|
161
|
+
if (createdAt < options.timeMin) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const activityWithNotes = await this.convertTaskToActivity(task, projectId);
|
|
166
|
+
// Set unread based on sync type (false for initial sync to avoid notification overload)
|
|
167
|
+
activityWithNotes.unread = !state.initialSync;
|
|
168
|
+
// Execute the callback using the callback token
|
|
169
|
+
await this.tools.callbacks.run(callbackToken, activityWithNotes);
|
|
170
|
+
}
|
|
171
|
+
// Check if more pages by checking if we got a full batch
|
|
172
|
+
const hasMore = tasksResult.data.length === batchSize;
|
|
173
|
+
if (hasMore) {
|
|
174
|
+
await this.set(`sync_state_${projectId}`, {
|
|
175
|
+
offset: state.offset + batchSize,
|
|
176
|
+
batchNumber: state.batchNumber + 1,
|
|
177
|
+
tasksProcessed: state.tasksProcessed + tasksResult.data.length,
|
|
178
|
+
initialSync: state.initialSync,
|
|
179
|
+
});
|
|
180
|
+
// Queue next batch
|
|
181
|
+
const nextBatch = await this.callback(this.syncBatch, authToken, projectId, options);
|
|
182
|
+
await this.tools.tasks.runTask(nextBatch);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// Initial sync is complete - cleanup sync state
|
|
186
|
+
await this.clear(`sync_state_${projectId}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Convert an Asana task to a Plot Activity
|
|
191
|
+
*/
|
|
192
|
+
async convertTaskToActivity(task, projectId) {
|
|
193
|
+
// Build notes array: description
|
|
194
|
+
const notes = [];
|
|
195
|
+
if (task.notes) {
|
|
196
|
+
notes.push({ content: task.notes });
|
|
197
|
+
}
|
|
198
|
+
// Ensure at least one note exists
|
|
199
|
+
if (notes.length === 0) {
|
|
200
|
+
notes.push({ content: "" });
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
type: ActivityType.Action,
|
|
204
|
+
title: task.name,
|
|
205
|
+
source: `asana:task:${projectId}:${task.gid}`,
|
|
206
|
+
doneAt: task.completed ? new Date(task.completed_at || Date.now()) : null,
|
|
207
|
+
notes,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Update task with new values
|
|
212
|
+
*
|
|
213
|
+
* @param authToken - Authorization token
|
|
214
|
+
* @param update - ActivityUpdate with changed fields
|
|
215
|
+
*/
|
|
216
|
+
async updateIssue(authToken, update) {
|
|
217
|
+
// Extract Asana task GID from source
|
|
218
|
+
const taskGid = update.source?.split(":").pop();
|
|
219
|
+
if (!taskGid) {
|
|
220
|
+
throw new Error("Invalid source format for Asana task");
|
|
221
|
+
}
|
|
222
|
+
const client = await this.getClient(authToken);
|
|
223
|
+
const updateFields = {};
|
|
224
|
+
// Handle title
|
|
225
|
+
if (update.title !== undefined) {
|
|
226
|
+
updateFields.name = update.title;
|
|
227
|
+
}
|
|
228
|
+
// Handle assignee
|
|
229
|
+
if (update.assignee !== undefined) {
|
|
230
|
+
updateFields.assignee = update.assignee?.id || null;
|
|
231
|
+
}
|
|
232
|
+
// Handle completion status based on doneAt
|
|
233
|
+
// Asana only has completed boolean (no In Progress state)
|
|
234
|
+
if (update.doneAt !== undefined) {
|
|
235
|
+
updateFields.completed = update.doneAt !== null;
|
|
236
|
+
}
|
|
237
|
+
// Apply updates if any fields changed
|
|
238
|
+
if (Object.keys(updateFields).length > 0) {
|
|
239
|
+
await client.tasks.updateTask(taskGid, updateFields);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Add a comment (story) to an Asana task
|
|
244
|
+
*
|
|
245
|
+
* @param authToken - Authorization token
|
|
246
|
+
* @param issueId - Asana task GID
|
|
247
|
+
* @param body - Comment text (markdown not directly supported, plain text)
|
|
248
|
+
*/
|
|
249
|
+
async addIssueComment(authToken, issueId, body) {
|
|
250
|
+
const client = await this.getClient(authToken);
|
|
251
|
+
await client.tasks.addComment(issueId, {
|
|
252
|
+
text: body,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Verify Asana webhook signature
|
|
257
|
+
* Asana uses HMAC-SHA256 with a shared secret
|
|
258
|
+
*/
|
|
259
|
+
async verifyAsanaSignature(signature, rawBody, secret) {
|
|
260
|
+
if (!signature) {
|
|
261
|
+
console.warn("Asana webhook missing signature header");
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
// Compute HMAC-SHA256 signature
|
|
265
|
+
const encoder = new TextEncoder();
|
|
266
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
267
|
+
const signatureBytes = await crypto.subtle.sign("HMAC", key, encoder.encode(rawBody));
|
|
268
|
+
// Convert to hex string
|
|
269
|
+
const expectedSignature = Array.from(new Uint8Array(signatureBytes))
|
|
270
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
271
|
+
.join("");
|
|
272
|
+
// Constant-time comparison
|
|
273
|
+
return signature === expectedSignature;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Handle incoming webhook events from Asana
|
|
277
|
+
*/
|
|
278
|
+
async onWebhook(request, projectId, authToken) {
|
|
279
|
+
const payload = request.body;
|
|
280
|
+
// Asana webhook handshake
|
|
281
|
+
if (request.headers["x-hook-secret"]) {
|
|
282
|
+
// This is the initial handshake, respond with the secret
|
|
283
|
+
// Note: The network tool should handle this automatically
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// Verify webhook signature
|
|
287
|
+
const webhookId = await this.get(`webhook_id_${projectId}`);
|
|
288
|
+
if (webhookId && request.rawBody) {
|
|
289
|
+
const signature = request.headers["x-hook-signature"];
|
|
290
|
+
// For Asana, the secret is the webhook ID itself
|
|
291
|
+
const isValid = await this.verifyAsanaSignature(signature, request.rawBody, webhookId);
|
|
292
|
+
if (!isValid) {
|
|
293
|
+
console.warn("Asana webhook signature verification failed");
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Process events
|
|
298
|
+
if (payload.events && Array.isArray(payload.events)) {
|
|
299
|
+
const callbackToken = await this.get(`callback_${projectId}`);
|
|
300
|
+
if (!callbackToken)
|
|
301
|
+
return;
|
|
302
|
+
const client = await this.getClient(authToken);
|
|
303
|
+
for (const event of payload.events) {
|
|
304
|
+
if (event.resource?.resource_type === "task") {
|
|
305
|
+
try {
|
|
306
|
+
// Fetch full task details
|
|
307
|
+
const task = await client.tasks.getTask(event.resource.gid, {
|
|
308
|
+
opt_fields: [
|
|
309
|
+
"name",
|
|
310
|
+
"notes",
|
|
311
|
+
"completed",
|
|
312
|
+
"completed_at",
|
|
313
|
+
"created_at",
|
|
314
|
+
"modified_at",
|
|
315
|
+
].join(","),
|
|
316
|
+
});
|
|
317
|
+
const activityWithNotes = await this.convertTaskToActivity(task, projectId);
|
|
318
|
+
// Webhooks are incremental updates - mark as unread
|
|
319
|
+
activityWithNotes.unread = true;
|
|
320
|
+
// Execute stored callback
|
|
321
|
+
await this.tools.callbacks.run(callbackToken, activityWithNotes);
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
console.warn("Failed to process Asana task webhook:", error);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Stop syncing an Asana project
|
|
332
|
+
*/
|
|
333
|
+
async stopSync(authToken, projectId) {
|
|
334
|
+
// TODO: Remove webhook when webhook support is implemented
|
|
335
|
+
await this.clear(`webhook_id_${projectId}`);
|
|
336
|
+
// Cleanup callback
|
|
337
|
+
const callbackToken = await this.get(`callback_${projectId}`);
|
|
338
|
+
if (callbackToken) {
|
|
339
|
+
await this.deleteCallback(callbackToken);
|
|
340
|
+
await this.clear(`callback_${projectId}`);
|
|
341
|
+
}
|
|
342
|
+
// Cleanup sync state
|
|
343
|
+
await this.clear(`sync_state_${projectId}`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
export default Asana;
|
|
347
|
+
//# sourceMappingURL=asana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asana.js","sourceRoot":"","sources":["../src/asana.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAEL,YAAY,GAEb,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EAAE,IAAI,EAAoB,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAiB,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EACL,SAAS,EACT,YAAY,EAEZ,YAAY,GACb,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAuB,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AASrD;;;;;GAKG;AACH,MAAM,OAAO,KAAM,SAAQ,IAAW;IACpC,KAAK,CAAC,KAAkB;QACtB,OAAO;YACL,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC;YACjC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC;YAC9D,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC;YAC3B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;YACnB,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC;SAChE,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CAAC,SAAiB;QACvC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,GAAG,CAClC,iBAAiB,SAAS,EAAE,CAC7B,CAAC;QACF,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC/D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAGf,QAAmB,EACnB,GAAG,SAEG;QAEN,MAAM,WAAW,GAAG,CAAC,SAAS,CAAC,CAAC;QAEhC,0CAA0C;QAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAEtC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAC/D,QAAQ,EACR,GAAG,SAAS,CACb,CAAC;QAEF,4CAA4C;QAC5C,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAC1C;YACE,QAAQ,EAAE,YAAY,CAAC,KAAK;YAC5B,KAAK,EAAE,SAAS,CAAC,IAAI;YACrB,MAAM,EAAE,WAAW;SACpB,EACD,IAAI,CAAC,aAAa,EAClB,SAAS,EACT,aAAa,CACd,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CACzB,aAA4B,EAC5B,SAAiB,EACjB,aAAuB;QAEvB,oCAAoC;QACpC,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAiB,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;QAE5D,2CAA2C;QAC3C,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,SAAiB;QACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAE/C,8BAA8B;QAC9B,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;QAE3D,MAAM,WAAW,GAAc,EAAE,CAAC;QAElC,mCAAmC;QACnC,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,EAAE;gBACpE,KAAK,EAAE,GAAG;aACX,CAAC,CAAC;YAEH,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACpC,WAAW,CAAC,IAAI,CAAC;oBACf,EAAE,EAAE,OAAO,CAAC,GAAG;oBACf,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,WAAW,EAAE,IAAI,EAAE,2CAA2C;oBAC9D,GAAG,EAAE,IAAI,EAAE,kCAAkC;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAMb,SAAiB,EACjB,SAAiB,EACjB,QAAmB,EACnB,OAA4B,EAC5B,GAAG,SAKG;QAEN,sCAAsC;QACtC,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAEnD,wCAAwC;QACxC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAC/D,QAAQ,EACR,GAAG,SAAS,CACb,CAAC;QACF,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;QAEvD,2BAA2B;QAC3B,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,iBAAiB,CAC7B,SAAiB,EACjB,SAAiB;QAEjB,iEAAiE;QACjE,gEAAgE;QAChE,OAAO,CAAC,GAAG,CAAC,kDAAkD,SAAS,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAC1B,SAAiB,EACjB,SAAiB,EACjB,OAA4B;QAE5B,wBAAwB;QACxB,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,SAAS,EAAE,EAAE;YACxC,MAAM,EAAE,CAAC;YACT,WAAW,EAAE,CAAC;YACd,cAAc,EAAE,CAAC;YACjB,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QAEH,oBAAoB;QACpB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,QAAQ,CACvC,IAAI,CAAC,SAAS,EACd,SAAS,EACT,SAAS,EACT,OAAO,CACR,CAAC;QAEF,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CACrB,SAAiB,EACjB,SAAiB,EACjB,OAA4B;QAE5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAY,cAAc,SAAS,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,oCAAoC,SAAS,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,uCAAuC;QACvC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,GAAG,CAAW,YAAY,SAAS,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,wCAAwC,SAAS,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAE/C,uBAAuB;QACvB,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,MAAM,MAAM,GAAQ;YAClB,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE;gBACV,MAAM;gBACN,OAAO;gBACP,WAAW;gBACX,cAAc;gBACd,YAAY;gBACZ,aAAa;aACd,CAAC,IAAI,CAAC,GAAG,CAAC;SACZ,CAAC;QAEF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC/B,CAAC;QAED,qCAAqC;QACrC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEvD,oBAAoB;QACpB,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;YACpC,4BAA4B;YAC5B,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC5C,IAAI,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;oBAChC,SAAS;gBACX,CAAC;YACH,CAAC;YAED,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,qBAAqB,CACxD,IAAI,EACJ,SAAS,CACV,CAAC;YACF,wFAAwF;YACxF,iBAAiB,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC;YAC9C,gDAAgD;YAChD,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAC5B,aAAa,EACb,iBAAiB,CAClB,CAAC;QACJ,CAAC;QAED,yDAAyD;QACzD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;QAEtD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,SAAS,EAAE,EAAE;gBACxC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS;gBAChC,WAAW,EAAE,KAAK,CAAC,WAAW,GAAG,CAAC;gBAClC,cAAc,EAAE,KAAK,CAAC,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM;gBAC9D,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;YAEH,mBAAmB;YACnB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CACnC,IAAI,CAAC,SAAS,EACd,SAAS,EACT,SAAS,EACT,OAAO,CACR,CAAC;YACF,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,gDAAgD;YAChD,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB,CACjC,IAAS,EACT,SAAiB;QAEjB,iCAAiC;QACjC,MAAM,KAAK,GAA+B,EAAE,CAAC;QAE7C,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,kCAAkC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO;YACL,IAAI,EAAE,YAAY,CAAC,MAAM;YACzB,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,MAAM,EAAE,cAAc,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE;YAC7C,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;YACzE,KAAK;SACN,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CACf,SAAiB,EACjB,MAAiD;QAEjD,qCAAqC;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAQ,EAAE,CAAC;QAE7B,eAAe;QACf,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,YAAY,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;QACnC,CAAC;QAED,kBAAkB;QAClB,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAClC,YAAY,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,IAAI,CAAC;QACtD,CAAC;QAED,2CAA2C;QAC3C,0DAA0D;QAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,YAAY,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC;QAClD,CAAC;QAED,sCAAsC;QACtC,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,eAAe,CACnB,SAAiB,EACjB,OAAe,EACf,IAAY;QAEZ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAE/C,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE;YACrC,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,oBAAoB,CAChC,SAA6B,EAC7B,OAAe,EACf,MAAc;QAEd,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EACtB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,CAAC,CACT,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAC7C,MAAM,EACN,GAAG,EACH,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CACxB,CAAC;QAEF,wBAAwB;QACxB,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC;aACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;aAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,2BAA2B;QAC3B,OAAO,SAAS,KAAK,iBAAiB,CAAC;IACzC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CACrB,OAAuB,EACvB,SAAiB,EACjB,SAAiB;QAEjB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAW,CAAC;QAEpC,0BAA0B;QAC1B,IAAI,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YACrC,yDAAyD;YACzD,0DAA0D;YAC1D,OAAO;QACT,CAAC;QAED,2BAA2B;QAC3B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,GAAG,CAAS,cAAc,SAAS,EAAE,CAAC,CAAC;QACpE,IAAI,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YACtD,iDAAiD;YACjD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAC7C,SAAS,EACT,OAAO,CAAC,OAAO,EACf,SAAS,CACV,CAAC;YAEF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;gBAC5D,OAAO;YACT,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,GAAG,CAAW,YAAY,SAAS,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,aAAa;gBAAE,OAAO;YAE3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAE/C,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnC,IAAI,KAAK,CAAC,QAAQ,EAAE,aAAa,KAAK,MAAM,EAAE,CAAC;oBAC7C,IAAI,CAAC;wBACH,0BAA0B;wBAC1B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;4BAC1D,UAAU,EAAE;gCACV,MAAM;gCACN,OAAO;gCACP,WAAW;gCACX,cAAc;gCACd,YAAY;gCACZ,aAAa;6BACd,CAAC,IAAI,CAAC,GAAG,CAAC;yBACZ,CAAC,CAAC;wBAEH,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,qBAAqB,CACxD,IAAI,EACJ,SAAS,CACV,CAAC;wBAEF,oDAAoD;wBACpD,iBAAiB,CAAC,MAAM,GAAG,IAAI,CAAC;wBAEhC,0BAA0B;wBAC1B,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;oBACnE,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,OAAO,CAAC,IAAI,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,SAAiB;QACjD,2DAA2D;QAC3D,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;QAE5C,mBAAmB;QACnB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,GAAG,CAAW,YAAY,SAAS,EAAE,CAAC,CAAC;QACxE,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,SAAS,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,qBAAqB;QACrB,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;IAC9C,CAAC;CACF;AAED,eAAe,KAAK,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@plotday/tool-asana",
|
|
3
|
+
"displayName": "Asana",
|
|
4
|
+
"description": "Sync with Asana project management",
|
|
5
|
+
"author": "Plot <team@plot.day> (https://plot.day)",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"version": "0.2.0",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"@plotday/source": "./src/index.ts",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"asana": "^3.0.10",
|
|
25
|
+
"@plotday/twister": "^0.26.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/asana": "^0.18.17",
|
|
29
|
+
"@types/node": "^25.0.3",
|
|
30
|
+
"typescript": "^5.9.3"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/plotday/plot.git",
|
|
35
|
+
"directory": "tools/asana"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://plot.day",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/plotday/plot/issues"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"plot",
|
|
43
|
+
"tool",
|
|
44
|
+
"asana",
|
|
45
|
+
"project-management"
|
|
46
|
+
],
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc",
|
|
52
|
+
"clean": "rm -rf dist"
|
|
53
|
+
}
|
|
54
|
+
}
|