1 | type Asana = { |
2 | token: string; |
3 | }; |
4 | |
5 | * Create a subtask |
6 | * Creates a new subtask and adds it to the parent task. Returns the full record for the newly created subtask. |
7 | */ |
8 | export async function main( |
9 | auth: Asana, |
10 | task_gid: string, |
11 | opt_pretty: string | undefined, |
12 | opt_fields: string | undefined, |
13 | body: { |
14 | data?: (({ gid?: string; resource_type?: string; [k: string]: unknown } & { |
15 | name?: string; |
16 | resource_subtype?: "default_task" | "milestone" | "section" | "approval"; |
17 | [k: string]: unknown; |
18 | }) & { |
19 | actual_time_minutes?: number; |
20 | approval_status?: |
21 | | "pending" |
22 | | "approved" |
23 | | "rejected" |
24 | | "changes_requested"; |
25 | assignee_status?: "today" | "upcoming" | "later" | "new" | "inbox"; |
26 | completed?: boolean; |
27 | completed_at?: string; |
28 | completed_by?: { |
29 | gid?: string; |
30 | resource_type?: string; |
31 | [k: string]: unknown; |
32 | } & { name?: string; [k: string]: unknown }; |
33 | created_at?: string; |
34 | dependencies?: { |
35 | gid?: string; |
36 | resource_type?: string; |
37 | [k: string]: unknown; |
38 | }[]; |
39 | dependents?: { |
40 | gid?: string; |
41 | resource_type?: string; |
42 | [k: string]: unknown; |
43 | }[]; |
44 | due_at?: string; |
45 | due_on?: string; |
46 | external?: { data?: string; gid?: string; [k: string]: unknown }; |
47 | hearted?: boolean; |
48 | hearts?: { |
49 | gid?: string; |
50 | user?: { |
51 | gid?: string; |
52 | resource_type?: string; |
53 | [k: string]: unknown; |
54 | } & { name?: string; [k: string]: unknown }; |
55 | [k: string]: unknown; |
56 | }[]; |
57 | html_notes?: string; |
58 | is_rendered_as_separator?: boolean; |
59 | liked?: boolean; |
60 | likes?: { |
61 | gid?: string; |
62 | user?: { |
63 | gid?: string; |
64 | resource_type?: string; |
65 | [k: string]: unknown; |
66 | } & { name?: string; [k: string]: unknown }; |
67 | [k: string]: unknown; |
68 | }[]; |
69 | memberships?: { |
70 | project?: { |
71 | gid?: string; |
72 | resource_type?: string; |
73 | [k: string]: unknown; |
74 | } & { name?: string; [k: string]: unknown }; |
75 | section?: { |
76 | gid?: string; |
77 | resource_type?: string; |
78 | [k: string]: unknown; |
79 | } & { name?: string; [k: string]: unknown }; |
80 | [k: string]: unknown; |
81 | }[]; |
82 | modified_at?: string; |
83 | name?: string; |
84 | notes?: string; |
85 | num_hearts?: number; |
86 | num_likes?: number; |
87 | num_subtasks?: number; |
88 | start_at?: string; |
89 | start_on?: string; |
90 | [k: string]: unknown; |
91 | }) & { |
92 | assignee?: string; |
93 | assignee_section?: string; |
94 | custom_fields?: { [k: string]: string }; |
95 | followers?: string[]; |
96 | parent?: string; |
97 | projects?: string[]; |
98 | tags?: string[]; |
99 | workspace?: string; |
100 | [k: string]: unknown; |
101 | }; |
102 | [k: string]: unknown; |
103 | } |
104 | ) { |
105 | const url = new URL( |
106 | `https://app.asana.com/api/1.0/tasks/${task_gid}/subtasks` |
107 | ); |
108 | for (const [k, v] of [ |
109 | ["opt_pretty", opt_pretty], |
110 | ["opt_fields", opt_fields], |
111 | ]) { |
112 | if (v !== undefined && v !== "") { |
113 | url.searchParams.append(k, v); |
114 | } |
115 | } |
116 | const response = await fetch(url, { |
117 | method: "POST", |
118 | headers: { |
119 | "Content-Type": "application/json", |
120 | Authorization: "Bearer " + auth.token, |
121 | }, |
122 | body: JSON.stringify(body), |
123 | }); |
124 | if (!response.ok) { |
125 | const text = await response.text(); |
126 | throw new Error(`${response.status} ${text}`); |
127 | } |
128 | return await response.json(); |
129 | } |
130 |
|