@pipedream/linear_app 0.4.6 → 0.5.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.
@@ -5,7 +5,7 @@ export default {
5
5
  key: "linear_app-create-issue",
6
6
  name: "Create Issue",
7
7
  description: "Create an issue (API Key). See the docs [here](https://developers.linear.app/docs/graphql/working-with-the-graphql-api#creating-and-editing-issues)",
8
- version: "0.3.7",
8
+ version: "0.4.0",
9
9
  props: {
10
10
  linearApp,
11
11
  teamId: {
@@ -32,6 +32,15 @@ export default {
32
32
  "assigneeId",
33
33
  ],
34
34
  },
35
+ stateId: {
36
+ propDefinition: [
37
+ linearApp,
38
+ "stateId",
39
+ ({ teamId }) => ({
40
+ teamId,
41
+ }),
42
+ ],
43
+ },
35
44
  },
36
45
  async run({ $ }) {
37
46
  const {
@@ -39,6 +48,7 @@ export default {
39
48
  description,
40
49
  teamId,
41
50
  assigneeId,
51
+ stateId,
42
52
  } = this;
43
53
 
44
54
  const response =
@@ -47,6 +57,7 @@ export default {
47
57
  title,
48
58
  description,
49
59
  assigneeId,
60
+ stateId,
50
61
  });
51
62
 
52
63
  const summary = response.success
@@ -4,7 +4,7 @@ export default {
4
4
  key: "linear_app-get-issue",
5
5
  name: "Get Issue",
6
6
  description: "Get an issue by ID (API Key). See the docs [here](https://developers.linear.app/docs/graphql/working-with-the-graphql-api)",
7
- version: "0.0.4",
7
+ version: "0.1.0",
8
8
  type: "action",
9
9
  props: {
10
10
  linearApp,
@@ -4,7 +4,7 @@ export default {
4
4
  key: "linear_app-get-teams",
5
5
  name: "Get Teams",
6
6
  description: "Get all the teams (API Key). See the docs [here](https://developers.linear.app/docs/graphql/working-with-the-graphql-api)",
7
- version: "0.1.6",
7
+ version: "0.2.0",
8
8
  type: "action",
9
9
  props: {
10
10
  linearApp,
@@ -6,7 +6,7 @@ export default {
6
6
  name: "Search Issues",
7
7
  description: "Search issues (API Key). See the docs [here](https://developers.linear.app/docs/graphql/working-with-the-graphql-api)",
8
8
  type: "action",
9
- version: "0.1.5",
9
+ version: "0.2.0",
10
10
  props: {
11
11
  linearApp,
12
12
  query: {
@@ -5,13 +5,23 @@ export default {
5
5
  name: "Update Issue",
6
6
  description: "Update an issue (API Key). See the docs [here](https://developers.linear.app/docs/graphql/working-with-the-graphql-api#creating-and-editing-issues)",
7
7
  type: "action",
8
- version: "0.0.7",
8
+ version: "0.1.0",
9
9
  props: {
10
10
  linearApp,
11
+ teamId: {
12
+ label: "Current Team",
13
+ propDefinition: [
14
+ linearApp,
15
+ "teamId",
16
+ ],
17
+ },
11
18
  issueId: {
12
19
  propDefinition: [
13
20
  linearApp,
14
21
  "issueId",
22
+ ({ teamId }) => ({
23
+ teamId,
24
+ }),
15
25
  ],
16
26
  },
17
27
  title: {
@@ -28,13 +38,25 @@ export default {
28
38
  "issueDescription",
29
39
  ],
30
40
  },
31
- teamId: {
41
+ teamIdToUpdate: {
42
+ description: "The identifier or key of the team to update the issue to",
32
43
  optional: true,
33
44
  propDefinition: [
34
45
  linearApp,
35
46
  "teamId",
36
47
  ],
37
48
  },
49
+ stateId: {
50
+ propDefinition: [
51
+ linearApp,
52
+ "stateId",
53
+ ({
54
+ teamId, teamIdToUpdate,
55
+ }) => ({
56
+ teamId: teamIdToUpdate || teamId,
57
+ }),
58
+ ],
59
+ },
38
60
  assigneeId: {
39
61
  propDefinition: [
40
62
  linearApp,
@@ -47,7 +69,8 @@ export default {
47
69
  issueId,
48
70
  title,
49
71
  description,
50
- teamId,
72
+ teamIdToUpdate,
73
+ stateId,
51
74
  assigneeId,
52
75
  } = this;
53
76
 
@@ -55,10 +78,11 @@ export default {
55
78
  await this.linearApp.updateIssue({
56
79
  issueId,
57
80
  input: {
58
- teamId,
81
+ teamId: teamIdToUpdate,
59
82
  title,
60
83
  description,
61
84
  assigneeId,
85
+ stateId,
62
86
  },
63
87
  });
64
88
 
@@ -1,39 +1,51 @@
1
1
  import { LinearClient } from "@linear/sdk";
2
2
  import constants from "./common/constants.mjs";
3
+ import { axios } from "@pipedream/platform";
3
4
 
4
5
  export default {
5
6
  type: "app",
6
7
  app: "linear_app",
7
8
  propDefinitions: {
8
- issueId: {
9
+ teamId: {
9
10
  type: "string",
10
- label: "Issue ID",
11
- description: "The issue ID to update",
11
+ label: "Team",
12
+ description: "The identifier or key of the team associated with the issue",
12
13
  async options({ prevContext }) {
13
14
  return this.listResourcesOptions({
14
15
  prevContext,
15
- resourcesFn: this.listIssues,
16
+ resourcesFn: this.listTeams,
16
17
  resouceMapper: ({
17
- id, title,
18
+ id, name,
18
19
  }) => ({
19
- label: title,
20
+ label: name,
20
21
  value: id,
21
22
  }),
22
23
  });
23
24
  },
24
25
  },
25
- teamId: {
26
+ issueId: {
26
27
  type: "string",
27
- label: "Team ID",
28
- description: "The identifier or key of the team associated with the issue",
29
- async options({ prevContext }) {
28
+ label: "Issue",
29
+ description: "The issue to update",
30
+ async options({
31
+ teamId, prevContext,
32
+ }) {
30
33
  return this.listResourcesOptions({
31
34
  prevContext,
32
- resourcesFn: this.listTeams,
35
+ resourcesFn: this.listIssues,
36
+ resourcesArgs: teamId && {
37
+ filter: {
38
+ team: {
39
+ id: {
40
+ eq: teamId,
41
+ },
42
+ },
43
+ },
44
+ },
33
45
  resouceMapper: ({
34
- id, name,
46
+ id, title,
35
47
  }) => ({
36
- label: name,
48
+ label: title,
37
49
  value: id,
38
50
  }),
39
51
  });
@@ -41,7 +53,7 @@ export default {
41
53
  },
42
54
  projectId: {
43
55
  type: "string",
44
- label: "Project ID",
56
+ label: "Project",
45
57
  description: "The identifier or key of the project associated with the issue",
46
58
  optional: true,
47
59
  async options({ prevContext }) {
@@ -64,8 +76,8 @@ export default {
64
76
  },
65
77
  assigneeId: {
66
78
  type: "string",
67
- label: "Assignee ID",
68
- description: "The identifier of the user to assign the issue to",
79
+ label: "Assignee",
80
+ description: "The user to assign to the issue",
69
81
  optional: true,
70
82
  async options({ prevContext }) {
71
83
  return this.listResourcesOptions({
@@ -80,6 +92,35 @@ export default {
80
92
  });
81
93
  },
82
94
  },
95
+ stateId: {
96
+ type: "string",
97
+ label: "State (Status)",
98
+ description: "The state (status) to assign to the issue",
99
+ optional: true,
100
+ async options({
101
+ teamId, prevContext,
102
+ }) {
103
+ return this.listResourcesOptions({
104
+ prevContext,
105
+ resourcesFn: this.listStates,
106
+ resourcesArgs: teamId && {
107
+ filter: {
108
+ team: {
109
+ id: {
110
+ eq: teamId,
111
+ },
112
+ },
113
+ },
114
+ },
115
+ resouceMapper: ({
116
+ id: value, name: label,
117
+ }) => ({
118
+ label,
119
+ value,
120
+ }),
121
+ });
122
+ },
123
+ },
83
124
  boardOrder: {
84
125
  type: "string",
85
126
  label: "Board order",
@@ -125,6 +166,20 @@ export default {
125
166
  },
126
167
  },
127
168
  methods: {
169
+ getAxiosHeaders() {
170
+ return {
171
+ Authorization: `${this.$auth.api_key}`,
172
+ };
173
+ },
174
+ async makeAxiosRequest({
175
+ $ = this, ...args
176
+ }) {
177
+ return axios($, {
178
+ url: "https://api.linear.app/graphql",
179
+ headers: this.getAxiosHeaders(),
180
+ ...args,
181
+ });
182
+ },
128
183
  getClientOptions(options = {}) {
129
184
  return {
130
185
  apiKey: this.$auth.api_key,
@@ -157,12 +212,21 @@ export default {
157
212
  async listTeams(variables = {}) {
158
213
  return this.client().teams(variables);
159
214
  },
160
- async listProjects(variables = {}) {
161
- return this.client().projects(variables);
215
+ async listProjects() {
216
+ const { data: { projects } } = await this.makeAxiosRequest({
217
+ method: "POST",
218
+ data: {
219
+ query: "{ projects { nodes { id name } } }",
220
+ },
221
+ });
222
+ return projects;
162
223
  },
163
224
  async listUsers(variables = {}) {
164
225
  return this.client().users(variables);
165
226
  },
227
+ async listStates(variables = {}) {
228
+ return this.client().workflowStates(variables);
229
+ },
166
230
  async listIssues(variables = {}) {
167
231
  return this.client().issues(variables);
168
232
  },
@@ -173,8 +237,8 @@ export default {
173
237
  return this.client().comments(variables);
174
238
  },
175
239
  async listResourcesOptions({
176
- prevContext, resourcesFn, resouceMapper,
177
- }) {
240
+ prevContext, resourcesFn, resourcesArgs, resouceMapper,
241
+ } = {}) {
178
242
  const {
179
243
  after,
180
244
  hasNextPage,
@@ -191,13 +255,14 @@ export default {
191
255
  await resourcesFn({
192
256
  after,
193
257
  first: constants.DEFAULT_LIMIT,
258
+ ...resourcesArgs,
194
259
  });
195
260
 
196
261
  return {
197
262
  options: nodes.map(resouceMapper),
198
263
  context: {
199
- after: pageInfo.endCursor,
200
- hasNextPage: pageInfo.hasNextPage,
264
+ after: pageInfo?.endCursor,
265
+ hasNextPage: pageInfo?.hasNextPage,
201
266
  },
202
267
  };
203
268
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/linear_app",
3
- "version": "0.4.6",
3
+ "version": "0.5.0",
4
4
  "description": "Pipedream Linear_app Components",
5
5
  "main": "linear_app.app.mjs",
6
6
  "keywords": [
@@ -14,6 +14,7 @@
14
14
  "access": "public"
15
15
  },
16
16
  "dependencies": {
17
- "@linear/sdk": "^2.0.0"
17
+ "@linear/sdk": "^2.6.0",
18
+ "@pipedream/platform": "^1.3.0"
18
19
  }
19
20
  }
@@ -7,7 +7,7 @@ export default {
7
7
  name: "New Created Comment (Instant)",
8
8
  description: "Emit new event when a new comment is created. See the docs [here](https://developers.linear.app/docs/graphql/webhooks)",
9
9
  type: "source",
10
- version: "0.0.6",
10
+ version: "0.1.0",
11
11
  dedupe: "unique",
12
12
  methods: {
13
13
  ...common.methods,
@@ -32,6 +32,12 @@ export default {
32
32
  isWebhookValid(clientIp) {
33
33
  return constants.CLIENT_IPS.includes(clientIp);
34
34
  },
35
+ isFromProject(body) {
36
+ return !this.projectId || body?.data?.projectId == this.projectId;
37
+ },
38
+ isRelevant() {
39
+ return true;
40
+ },
35
41
  getResourceTypes() {
36
42
  throw new Error("getResourceTypes is not implemented");
37
43
  },
@@ -107,6 +113,10 @@ export default {
107
113
  return;
108
114
  }
109
115
 
116
+ if (!this.isFromProject(body) || !this.isRelevant(body)) {
117
+ return;
118
+ }
119
+
110
120
  const meta = this.getMetadata(resource);
111
121
  this.$emit(body, meta);
112
122
  },
@@ -7,7 +7,7 @@ export default {
7
7
  name: "New Created Issue (Instant)",
8
8
  description: "Emit new event when a new issue is created. See the docs [here](https://developers.linear.app/docs/graphql/webhooks)",
9
9
  type: "source",
10
- version: "0.2.5",
10
+ version: "0.3.0",
11
11
  dedupe: "unique",
12
12
  methods: {
13
13
  ...common.methods,
@@ -39,6 +39,9 @@ export default {
39
39
  },
40
40
  };
41
41
  },
42
+ isRelevant(body) {
43
+ return body?.action === "create";
44
+ },
42
45
  getMetadata(resource) {
43
46
  const {
44
47
  delivery,
@@ -7,7 +7,7 @@ export default {
7
7
  name: "New Updated Issue (Instant)",
8
8
  description: "Emit new event when an issue is updated. See the docs [here](https://developers.linear.app/docs/graphql/webhooks)",
9
9
  type: "source",
10
- version: "0.2.5",
10
+ version: "0.3.0",
11
11
  dedupe: "unique",
12
12
  methods: {
13
13
  ...common.methods,
@@ -0,0 +1,59 @@
1
+ import common from "../common/webhook.mjs";
2
+ import constants from "../../common/constants.mjs";
3
+
4
+ export default {
5
+ ...common,
6
+ key: "linear_app-new-issue-status-updated",
7
+ name: "New Issue Status Updated (Instant)",
8
+ description: "Emit new event when the status of an issue is updated. See the docs [here](https://developers.linear.app/docs/graphql/webhooks)",
9
+ type: "source",
10
+ version: "0.1.0",
11
+ dedupe: "unique",
12
+ methods: {
13
+ ...common.methods,
14
+ getResourceTypes() {
15
+ return [
16
+ constants.RESOURCE_TYPE.ISSUE,
17
+ ];
18
+ },
19
+ getWebhookLabel() {
20
+ return "Issue status updated";
21
+ },
22
+ getResourcesFn() {
23
+ return this.linearApp.listIssues;
24
+ },
25
+ getResourcesFnArgs() {
26
+ return {
27
+ sortBy: "updatedAt",
28
+ filter: {
29
+ team: {
30
+ id: {
31
+ in: this.teamIds,
32
+ },
33
+ },
34
+ project: {
35
+ id: {
36
+ eq: this.projectId,
37
+ },
38
+ },
39
+ },
40
+ };
41
+ },
42
+ isRelevant(body) {
43
+ return body?.updatedFrom?.stateId;
44
+ },
45
+ getMetadata(resource) {
46
+ const {
47
+ delivery,
48
+ title,
49
+ data,
50
+ updatedAt,
51
+ } = resource;
52
+ return {
53
+ id: delivery || resource.id,
54
+ summary: `Issue status updated: ${data?.title || title}`,
55
+ ts: Date.parse(updatedAt),
56
+ };
57
+ },
58
+ },
59
+ };