1 | type Asana = { |
2 | token: string; |
3 | }; |
4 | |
5 | * Create a custom field |
6 | * Creates a new custom field in a workspace. Every custom field is required |
7 | to be created in a specific workspace, and this workspace cannot be |
8 | changed once set. |
9 |
|
10 | A custom field’s name must be unique within a workspace and not conflict |
11 | with names of existing task properties such as `Due Date` or `Assignee`. |
12 | A custom field’s type must be one of `text`, `enum`, `multi_enum`, `number`, |
13 | `date`, or `people`. |
14 |
|
15 | Returns the full record of the newly created custom field. |
16 | */ |
17 | export async function main( |
18 | auth: Asana, |
19 | opt_pretty: string | undefined, |
20 | opt_fields: string | undefined, |
21 | limit: string | undefined, |
22 | offset: string | undefined, |
23 | body: { |
24 | data?: (({ gid?: string; resource_type?: string; [k: string]: unknown } & { |
25 | date_value?: { date?: string; date_time?: string; [k: string]: unknown }; |
26 | display_value?: string; |
27 | enabled?: boolean; |
28 | enum_options?: ({ |
29 | gid?: string; |
30 | resource_type?: string; |
31 | [k: string]: unknown; |
32 | } & { |
33 | color?: string; |
34 | enabled?: boolean; |
35 | name?: string; |
36 | [k: string]: unknown; |
37 | })[]; |
38 | enum_value?: ({ |
39 | gid?: string; |
40 | resource_type?: string; |
41 | [k: string]: unknown; |
42 | } & { |
43 | color?: string; |
44 | enabled?: boolean; |
45 | name?: string; |
46 | [k: string]: unknown; |
47 | }) & { [k: string]: unknown }; |
48 | multi_enum_values?: ({ |
49 | gid?: string; |
50 | resource_type?: string; |
51 | [k: string]: unknown; |
52 | } & { |
53 | color?: string; |
54 | enabled?: boolean; |
55 | name?: string; |
56 | [k: string]: unknown; |
57 | })[]; |
58 | name?: string; |
59 | number_value?: number; |
60 | resource_subtype?: |
61 | | "text" |
62 | | "enum" |
63 | | "multi_enum" |
64 | | "number" |
65 | | "date" |
66 | | "people"; |
67 | text_value?: string; |
68 | type?: "text" | "enum" | "multi_enum" | "number"; |
69 | [k: string]: unknown; |
70 | }) & { |
71 | asana_created_field?: |
72 | | "a_v_requirements" |
73 | | "account_name" |
74 | | "actionable" |
75 | | "align_shipping_link" |
76 | | "align_status" |
77 | | "allotted_time" |
78 | | "appointment" |
79 | | "approval_stage" |
80 | | "approved" |
81 | | "article_series" |
82 | | "board_committee" |
83 | | "browser" |
84 | | "campaign_audience" |
85 | | "campaign_project_status" |
86 | | "campaign_regions" |
87 | | "channel_primary" |
88 | | "client_topic_type" |
89 | | "complete_by" |
90 | | "contact" |
91 | | "contact_email_address" |
92 | | "content_channels" |
93 | | "content_channels_needed" |
94 | | "content_stage" |
95 | | "content_type" |
96 | | "contract" |
97 | | "contract_status" |
98 | | "cost" |
99 | | "creation_stage" |
100 | | "creative_channel" |
101 | | "creative_needed" |
102 | | "creative_needs" |
103 | | "data_sensitivity" |
104 | | "deal_size" |
105 | | "delivery_appt" |
106 | | "delivery_appt_date" |
107 | | "department" |
108 | | "department_responsible" |
109 | | "design_request_needed" |
110 | | "design_request_type" |
111 | | "discussion_category" |
112 | | "do_this_task" |
113 | | "editorial_content_status" |
114 | | "editorial_content_tag" |
115 | | "editorial_content_type" |
116 | | "effort" |
117 | | "effort_level" |
118 | | "est_completion_date" |
119 | | "estimated_time" |
120 | | "estimated_value" |
121 | | "expected_cost" |
122 | | "external_steps_needed" |
123 | | "favorite_idea" |
124 | | "feedback_type" |
125 | | "financial" |
126 | | "funding_amount" |
127 | | "grant_application_process" |
128 | | "hiring_candidate_status" |
129 | | "idea_status" |
130 | | "ids_link" |
131 | | "ids_patient_link" |
132 | | "implementation_stage" |
133 | | "insurance" |
134 | | "interview_area" |
135 | | "interview_question_score" |
136 | | "itero_scan_link" |
137 | | "job_s_applied_to" |
138 | | "lab" |
139 | | "launch_status" |
140 | | "lead_status" |
141 | | "localization_language" |
142 | | "localization_market_team" |
143 | | "localization_status" |
144 | | "meeting_minutes" |
145 | | "meeting_needed" |
146 | | "minutes" |
147 | | "mrr" |
148 | | "must_localize" |
149 | | "name_of_foundation" |
150 | | "need_to_follow_up" |
151 | | "next_appointment" |
152 | | "next_steps_sales" |
153 | | "num_people" |
154 | | "number_of_user_reports" |
155 | | "office_location" |
156 | | "onboarding_activity" |
157 | | "owner" |
158 | | "participants_needed" |
159 | | "patient_date_of_birth" |
160 | | "patient_email" |
161 | | "patient_phone" |
162 | | "patient_status" |
163 | | "phone_number" |
164 | | "planning_category" |
165 | | "point_of_contact" |
166 | | "position" |
167 | | "post_format" |
168 | | "prescription" |
169 | | "priority" |
170 | | "priority_level" |
171 | | "product" |
172 | | "product_stage" |
173 | | "progress" |
174 | | "project_size" |
175 | | "project_status" |
176 | | "proposed_budget" |
177 | | "publish_status" |
178 | | "reason_for_scan" |
179 | | "referral" |
180 | | "request_type" |
181 | | "research_status" |
182 | | "responsible_department" |
183 | | "responsible_team" |
184 | | "risk_assessment_status" |
185 | | "room_name" |
186 | | "sales_counterpart" |
187 | | "sentiment" |
188 | | "shipping_link" |
189 | | "social_channels" |
190 | | "stage" |
191 | | "status" |
192 | | "status_design" |
193 | | "status_of_initiative" |
194 | | "system_setup" |
195 | | "task_progress" |
196 | | "team" |
197 | | "team_marketing" |
198 | | "team_responsible" |
199 | | "time_it_takes_to_complete_tasks" |
200 | | "timeframe" |
201 | | "treatment_type" |
202 | | "type_work_requests_it" |
203 | | "use_agency" |
204 | | "user_name" |
205 | | "vendor_category" |
206 | | "vendor_type" |
207 | | "word_count"; |
208 | currency_code?: string; |
209 | custom_label?: string; |
210 | custom_label_position?: "prefix" | "suffix"; |
211 | description?: string; |
212 | enum_options?: ({ |
213 | gid?: string; |
214 | resource_type?: string; |
215 | [k: string]: unknown; |
216 | } & { |
217 | color?: string; |
218 | enabled?: boolean; |
219 | name?: string; |
220 | [k: string]: unknown; |
221 | })[]; |
222 | format?: "currency" | "identifier" | "percentage" | "custom" | "none"; |
223 | has_notifications_enabled?: boolean; |
224 | is_global_to_workspace?: boolean; |
225 | precision?: number; |
226 | [k: string]: unknown; |
227 | }) & { people_value?: string[]; workspace: string; [k: string]: unknown }; |
228 | [k: string]: unknown; |
229 | } |
230 | ) { |
231 | const url = new URL(`https://app.asana.com/api/1.0/custom_fields`); |
232 | for (const [k, v] of [ |
233 | ["opt_pretty", opt_pretty], |
234 | ["opt_fields", opt_fields], |
235 | ["limit", limit], |
236 | ["offset", offset], |
237 | ]) { |
238 | if (v !== undefined && v !== "") { |
239 | url.searchParams.append(k, v); |
240 | } |
241 | } |
242 | const response = await fetch(url, { |
243 | method: "POST", |
244 | headers: { |
245 | "Content-Type": "application/json", |
246 | Authorization: "Bearer " + auth.token, |
247 | }, |
248 | body: JSON.stringify(body), |
249 | }); |
250 | if (!response.ok) { |
251 | const text = await response.text(); |
252 | throw new Error(`${response.status} ${text}`); |
253 | } |
254 | return await response.json(); |
255 | } |
256 |
|