Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit b4d7ab5

Browse files
committed
feat: add label functions
1 parent 8fe2a29 commit b4d7ab5

File tree

8 files changed

+208
-2
lines changed

8 files changed

+208
-2
lines changed

src/TDSClient.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import task from "./submodules/task";
22
import project from "./submodules/project";
33
import section from "./submodules/section";
4+
import label from "./submodules/label";
45
import { ClientConstructor, TDSClient } from "./definitions";
56

67
const TDSClientConstructor: ClientConstructor = (apiToken): TDSClient => {
@@ -13,6 +14,7 @@ const TDSClientConstructor: ClientConstructor = (apiToken): TDSClient => {
1314
task: task(headers),
1415
project: project(headers),
1516
section: section(headers),
17+
label: label(headers),
1618
};
1719
};
1820

src/__tests__/labels.tests.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import TDSClient, { Label } from "..";
2+
import { CreatableLabel } from "../definitions";
3+
4+
const myClient = TDSClient(process.env.TODOIST_TOKEN);
5+
6+
describe("Client-Side Label Creation", () => {
7+
test("Create Empty Label", () => {
8+
const emptyLabel = Label({});
9+
expect(emptyLabel).toMatchObject<CreatableLabel>({
10+
name: "_No_Label_Name_Provided_",
11+
});
12+
});
13+
14+
test("Create Normal Label", () => {
15+
let myLabel = Label({ name: "Label Name" });
16+
17+
expect(myLabel).toMatchObject<CreatableLabel>({ name: "Label Name" });
18+
});
19+
});
20+
21+
describe("API Label Functions", () => {
22+
let labelID: number;
23+
24+
test("Create A Label", async () => {
25+
let apiLabel = await myClient.label.create({ name: "Test Label" });
26+
27+
expect(apiLabel.id).toBeTruthy();
28+
29+
labelID = apiLabel.id;
30+
});
31+
32+
test("Get A Label", async () => {
33+
let apiLabel = await myClient.label.get(labelID);
34+
35+
expect(apiLabel.name).toBe("Test_Label");
36+
});
37+
38+
// 2 active projects now
39+
test("Create Two More Labels", async () => {
40+
return await Promise.all([
41+
myClient.label.create({ name: "Label 2" }),
42+
myClient.label.create({ name: "Label 3" }),
43+
]);
44+
});
45+
46+
test("Get All Labels", async () => {
47+
const responseLabels = await myClient.label.getAllJSON();
48+
const testLabelExists = responseLabels.some(
49+
(labelObj) => labelObj.name === "Test_Label"
50+
);
51+
52+
expect(responseLabels.length).toBe(3);
53+
expect(testLabelExists).toBe(true);
54+
});
55+
56+
test("Get All Label Names", async () => {
57+
const responseLabels = await myClient.label.getAll();
58+
const testLabelExists = responseLabels.some(
59+
(name) => name === "Test_Label"
60+
);
61+
62+
expect(responseLabels.length).toBe(3);
63+
expect(testLabelExists).toBe(true);
64+
});
65+
66+
test("Update a label", async () => {
67+
const repsonse = await myClient.label.update(labelID, {
68+
name: "New label name",
69+
});
70+
71+
expect(repsonse.status).toBe(204);
72+
});
73+
74+
test("Delete All Previous Labels", async () => {
75+
let allLabelsJSON = await myClient.label.getAllJSON();
76+
77+
let responses = await Promise.all(
78+
allLabelsJSON.map(async (label) => myClient.label.delete(label.id))
79+
);
80+
81+
responses.forEach(({ status }) => expect(status).toBe(204));
82+
});
83+
});

src/definitions/Client.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TaskModule, ProjectModule, SectionModule } from ".";
1+
import { TaskModule, ProjectModule, SectionModule, LabelModule } from ".";
22
import { AxiosRequestHeaders } from "axios";
33

44
export interface AuthHeader extends AxiosRequestHeaders {
@@ -10,6 +10,7 @@ export interface TDSClient {
1010
task: TaskModule;
1111
project: ProjectModule;
1212
section: SectionModule;
13+
label: LabelModule;
1314
}
1415

1516
export interface ClientConstructor {

src/definitions/Labels.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { AxiosResponse } from "axios";
2+
import { ProjectColor } from ".";
3+
4+
export interface LabelModule {
5+
create: (label: CreatableLabel) => Promise<APILabelObject>;
6+
delete: (id: number | string) => Promise<AxiosResponse>;
7+
getAllJSON: () => Promise<APILabelObject[]>;
8+
getAll: () => Promise<string[]>;
9+
get: (id: string | number) => Promise<APILabelObject>;
10+
update: (
11+
id: number | string,
12+
label: LabelUpdatableParameters
13+
) => Promise<AxiosResponse>;
14+
}
15+
16+
/* CLIENT-LEVEL INTERFACES */
17+
18+
export interface UserCreatedLabel {
19+
name?: string;
20+
order?: number;
21+
color?: ProjectColor;
22+
favorite?: boolean;
23+
}
24+
25+
export interface CreatableLabel extends UserCreatedLabel {
26+
name: string;
27+
}
28+
29+
/* API-LEVEL INTERFACES */
30+
31+
export interface APILabelObject {
32+
id: number;
33+
name: string;
34+
color: ProjectColor;
35+
order: number;
36+
favorite: boolean;
37+
}
38+
39+
// See https://developer.todoist.com/rest/v1/#update-a-label
40+
export interface LabelUpdatableParameters {
41+
name?: string;
42+
color?: ProjectColor;
43+
order?: number;
44+
favorite?: boolean;
45+
}

src/definitions/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from "./Client";
22
export * from "./Projects";
33
export * from "./Tasks";
44
export * from "./Sections";
5+
export * from "./Labels";

src/resources/Label.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { CreatableLabel, UserCreatedLabel } from "../definitions";
2+
3+
const Label = (label: UserCreatedLabel): CreatableLabel => {
4+
const { name = "_No_Label_Name_Provided_", ...restOfProperties } = label;
5+
6+
return {
7+
name,
8+
...restOfProperties,
9+
};
10+
};
11+
12+
export default Label;

src/resources/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Task from "./Task";
22
import Project from "./Project";
33
import Section from "./Section";
4+
import Label from "./Label";
45

5-
export { Task, Project, Section };
6+
export { Task, Project, Section, Label };

src/submodules/label.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import axios from "axios";
2+
import { AuthHeader, APILabelObject, LabelModule } from "../definitions";
3+
4+
const labelClientModule = (headers: AuthHeader): LabelModule => {
5+
const getOneJSON = async (id: number | string) => {
6+
let { data } = await axios.get(
7+
`https://api.todoist.com/rest/v1/labels/${id}`,
8+
{ headers }
9+
);
10+
return data as APILabelObject;
11+
};
12+
13+
const getAllJSON = async () => {
14+
let { data } = await axios.get(`https://api.todoist.com/rest/v1/labels`, {
15+
headers,
16+
});
17+
18+
return data as APILabelObject[];
19+
};
20+
21+
return {
22+
create: async (label) => {
23+
let { data } = await axios.post(
24+
`https://api.todoist.com/rest/v1/labels`,
25+
label,
26+
{ headers }
27+
);
28+
return data as APILabelObject;
29+
},
30+
31+
getAll: async () => {
32+
let json = await getAllJSON();
33+
let arrayLabels: string[] = [];
34+
json.forEach((label) => arrayLabels.push(label.name));
35+
return arrayLabels;
36+
},
37+
38+
getAllJSON,
39+
40+
get: async (id) => {
41+
let project = await getOneJSON(id);
42+
return project;
43+
},
44+
45+
delete: async (id) => {
46+
return await axios.delete(
47+
`https://api.todoist.com/rest/v1/labels/${id}`,
48+
{ headers }
49+
);
50+
},
51+
52+
update: async (id, label) => {
53+
return await axios.post(
54+
`https://api.todoist.com/rest/v1/labels/${id}`,
55+
label,
56+
{ headers }
57+
);
58+
},
59+
};
60+
};
61+
export default labelClientModule;

0 commit comments

Comments
 (0)