@pipedream/linear_app 0.4.0 → 0.4.2

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.4",
8
+ version: "0.3.6",
9
9
  props: {
10
10
  linearApp,
11
11
  teamId: {
@@ -52,7 +52,7 @@ export default {
52
52
  const summary = response.success
53
53
  ? `Created issue ${response._issue.id}`
54
54
  : "Failed to create issue";
55
- $.export("summary", summary);
55
+ $.export("$summary", summary);
56
56
 
57
57
  return response;
58
58
  },
@@ -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.1",
7
+ version: "0.0.3",
8
8
  type: "action",
9
9
  props: {
10
10
  linearApp,
@@ -18,7 +18,7 @@ export default {
18
18
  },
19
19
  async run({ $ }) {
20
20
  const issue = await this.linearApp.getIssue(this.issueId);
21
- $.export("summary", `Found issue with ID ${this.issueId}`);
21
+ $.export("$summary", `Found issue with ID ${this.issueId}`);
22
22
  return issue;
23
23
  },
24
24
  };
@@ -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.3",
7
+ version: "0.1.5",
8
8
  type: "action",
9
9
  props: {
10
10
  linearApp,
@@ -12,7 +12,7 @@ export default {
12
12
  async run({ $ }) {
13
13
  const { nodes: teams } = await this.linearApp.listTeams();
14
14
 
15
- $.export("summary", `Found ${teams.length} teams(s)`);
15
+ $.export("$summary", `Found ${teams.length} teams(s)`);
16
16
 
17
17
  return teams;
18
18
  },
@@ -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.2",
9
+ version: "0.1.4",
10
10
  props: {
11
11
  linearApp,
12
12
  query: {
@@ -111,7 +111,7 @@ export default {
111
111
  hasNextPage = pageInfo.hasNextPage;
112
112
  } while (hasNextPage);
113
113
 
114
- $.export("summary", `Found ${issues.length} issues`);
114
+ $.export("$summary", `Found ${issues.length} issues`);
115
115
 
116
116
  return issues;
117
117
  },
@@ -5,7 +5,7 @@ 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.3",
8
+ version: "0.0.5",
9
9
  props: {
10
10
  linearApp,
11
11
  issueId: {
@@ -65,7 +65,7 @@ export default {
65
65
  const summary = response.summary
66
66
  ? `Updated issue ${response._issue.id}`
67
67
  : "Failed to update issue";
68
- $.export("summary", summary);
68
+ $.export("$summary", summary);
69
69
 
70
70
  return response;
71
71
  },
@@ -1,6 +1,7 @@
1
1
  const WEBHOOK_ID = "webhookId";
2
2
  const LINEAR_DELIVERY_HEADER = "linear-delivery";
3
- const DEFAULT_LIMIT = 50;
3
+ const DEFAULT_LIMIT = 100;
4
+ const DEFAULT_MAX_RECORDS = 200;
4
5
 
5
6
  const ACTION = {
6
7
  CREATE: "create",
@@ -46,6 +47,7 @@ export default {
46
47
  WEBHOOK_ID,
47
48
  LINEAR_DELIVERY_HEADER,
48
49
  DEFAULT_LIMIT,
50
+ DEFAULT_MAX_RECORDS,
49
51
  ACTION,
50
52
  RESOURCE_TYPE,
51
53
  RESOURCE_TYPES,
@@ -0,0 +1,11 @@
1
+ async function streamIterator(stream) {
2
+ const resources = [];
3
+ for await (const resource of stream) {
4
+ resources.push(resource);
5
+ }
6
+ return resources;
7
+ }
8
+
9
+ export default {
10
+ streamIterator,
11
+ };
@@ -203,25 +203,31 @@ export default {
203
203
  },
204
204
  };
205
205
  },
206
- async *paginateResources({ resourcesFn }) {
207
- const params = {
208
- after: null,
209
- first: constants.DEFAULT_LIMIT,
210
- };
211
- let hasNextPage = true;
206
+ async *paginateResources({
207
+ resourcesFn,
208
+ resourcesFnArgs,
209
+ max = constants.DEFAULT_MAX_RECORDS,
210
+ }) {
211
+ let counter = 0;
212
+ let hasNextPage;
213
+ let endCursor;
212
214
  do {
213
215
  const {
214
216
  nodes,
215
217
  pageInfo,
216
- } = await resourcesFn(params);
217
- for (const d of nodes) {
218
- yield d;
219
- }
220
- hasNextPage = pageInfo.hasNextPage;
221
- if (hasNextPage) {
222
- params.after = pageInfo.endCursor;
218
+ } = await resourcesFn({
219
+ after: endCursor,
220
+ first: constants.DEFAULT_LIMIT,
221
+ ...resourcesFnArgs,
222
+ });
223
+ for (const node of nodes) {
224
+ counter += 1;
225
+ yield node;
223
226
  }
224
- } while (hasNextPage);
227
+ ({
228
+ hasNextPage, endCursor,
229
+ } = pageInfo);
230
+ } while (hasNextPage && counter < max);
225
231
  },
226
232
  },
227
233
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/linear_app",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Pipedream Linear_app Components",
5
5
  "main": "linear_app.app.mjs",
6
6
  "keywords": [
@@ -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.1",
10
+ version: "0.0.4",
11
11
  dedupe: "unique",
12
12
  methods: {
13
13
  ...common.methods,
@@ -19,23 +19,33 @@ export default {
19
19
  getWebhookLabel() {
20
20
  return "Comment created";
21
21
  },
22
- getActions() {
23
- return [
24
- constants.ACTION.CREATE,
25
- ];
26
- },
27
22
  getResourcesFn() {
28
23
  return this.linearApp.listComments;
29
24
  },
25
+ getResourcesFnArgs() {
26
+ return {
27
+ sortBy: "createdAt",
28
+ filter: {
29
+ issue: {
30
+ project: {
31
+ id: {
32
+ eq: this.projectId,
33
+ },
34
+ },
35
+ },
36
+ },
37
+ };
38
+ },
30
39
  getMetadata(resource) {
31
40
  const {
32
41
  delivery,
42
+ body,
33
43
  data,
34
44
  createdAt,
35
45
  } = resource;
36
46
  return {
37
- id: delivery,
38
- summary: `Comment created: ${data.title}`,
47
+ id: delivery || resource.id,
48
+ summary: `New comment event created: ${data?.body || body}`,
39
49
  ts: Date.parse(createdAt),
40
50
  };
41
51
  },
@@ -1,15 +1,17 @@
1
1
  import linearApp from "../../linear_app.app.mjs";
2
2
  import constants from "../../common/constants.mjs";
3
+ import utils from "../../common/utils.mjs";
3
4
 
4
5
  export default {
5
6
  props: {
6
7
  linearApp,
7
- teamId: {
8
+ teamIds: {
9
+ label: "Team IDs",
10
+ type: "string[]",
8
11
  propDefinition: [
9
12
  linearApp,
10
13
  "teamId",
11
14
  ],
12
- optional: true,
13
15
  },
14
16
  projectId: {
15
17
  propDefinition: [
@@ -21,20 +23,11 @@ export default {
21
23
  db: "$.service.db",
22
24
  },
23
25
  methods: {
24
- setWebhookId(id) {
25
- this.db.set(constants.WEBHOOK_ID, id);
26
+ setWebhookId(teamId, id) {
27
+ this.db.set(`webhook-${teamId}`, id);
26
28
  },
27
- getWebhookId() {
28
- return this.db.get(constants.WEBHOOK_ID);
29
- },
30
- isRelevant(body) {
31
- if (!this.getActions().includes(body?.action)) {
32
- return false;
33
- }
34
- if (this.projectId) {
35
- return body.data.projectId === this.projectId;
36
- }
37
- return true;
29
+ getWebhookId(teamId) {
30
+ return this.db.get(`webhook-${teamId}`);
38
31
  },
39
32
  isWebhookValid(clientIp) {
40
33
  return constants.CLIENT_IPS.includes(clientIp);
@@ -45,57 +38,53 @@ export default {
45
38
  getWebhookLabel() {
46
39
  throw new Error("getWebhookLabel is not implemented");
47
40
  },
48
- getActions() {
49
- throw new Error("getActions is not implemented");
50
- },
51
41
  getMetadata() {
52
42
  throw new Error("getMetadata is not implemented");
53
43
  },
54
44
  getResourcesFn() {
55
45
  throw new Error("Get resource function not implemented");
56
46
  },
47
+ getResourcesFnArgs() {
48
+ throw new Error("Get resource function arguments not implemented");
49
+ },
50
+ getLoadedProjectId() {
51
+ throw new Error("Get loaded project ID not implemented");
52
+ },
57
53
  },
58
54
  hooks: {
59
55
  async deploy() {
60
56
  // Retrieve historical events
61
57
  console.log("Retrieving historical events...");
62
- const events = this.linearApp.paginateResources({
58
+ const stream = this.linearApp.paginateResources({
63
59
  resourcesFn: this.getResourcesFn(),
60
+ resourcesFnArgs: this.getResourcesFnArgs(),
64
61
  });
65
- for await (const event of events) {
66
- const [
67
- action,
68
- ] = this.getActions();
69
- const [
70
- resourceType,
71
- ] = this.getResourceTypes();
72
- this.$emit(event, {
73
- id: event.id,
74
- ts: Date.parse(event.updatedAt),
75
- summary: `New ${action} ${resourceType} event: ${event.id}`,
62
+ const resources = await utils.streamIterator(stream);
63
+
64
+ resources
65
+ .reverse()
66
+ .forEach((resource) => {
67
+ this.$emit(resource, this.getMetadata(resource));
76
68
  });
77
- }
78
69
  },
79
70
  async activate() {
80
- const params = {
81
- resourceTypes: this.getResourceTypes(),
82
- url: this.http.endpoint,
83
- label: this.getWebhookLabel(),
84
- };
85
-
86
- if (this.teamId) {
87
- params.teamId = this.teamId;
88
- } else {
89
- params.allPublicTeams = true;
71
+ for (const teamId of this.teamIds) {
72
+ const { _webhook: webhook } =
73
+ await this.linearApp.createWebhook({
74
+ teamId,
75
+ resourceTypes: this.getResourceTypes(),
76
+ url: this.http.endpoint,
77
+ label: this.getWebhookLabel(),
78
+ });
79
+ this.setWebhookId(teamId, webhook.id);
90
80
  }
91
-
92
- const { _webhook: webhook } = await this.linearApp.createWebhook(params);
93
- this.setWebhookId(webhook.id);
94
81
  },
95
82
  async deactivate() {
96
- const webhookId = this.getWebhookId();
97
- if (webhookId) {
98
- await this.linearApp.deleteWebhook(webhookId);
83
+ for (const teamId of this.teamIds) {
84
+ const webhookId = this.getWebhookId(teamId);
85
+ if (webhookId) {
86
+ await this.linearApp.deleteWebhook(webhookId);
87
+ }
99
88
  }
100
89
  },
101
90
  },
@@ -118,9 +107,6 @@ export default {
118
107
  return;
119
108
  }
120
109
 
121
- if (!this.isRelevant(body)) {
122
- return;
123
- }
124
110
  const meta = this.getMetadata(resource);
125
111
  this.$emit(body, meta);
126
112
  },
@@ -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.0",
10
+ version: "0.2.3",
11
11
  dedupe: "unique",
12
12
  methods: {
13
13
  ...common.methods,
@@ -19,23 +19,31 @@ export default {
19
19
  getWebhookLabel() {
20
20
  return "Issue created";
21
21
  },
22
- getActions() {
23
- return [
24
- constants.ACTION.CREATE,
25
- ];
26
- },
27
22
  getResourcesFn() {
28
23
  return this.linearApp.listIssues;
29
24
  },
25
+ getResourcesFnArgs() {
26
+ return {
27
+ sortBy: "createdAt",
28
+ filter: {
29
+ project: {
30
+ id: {
31
+ eq: this.projectId,
32
+ },
33
+ },
34
+ },
35
+ };
36
+ },
30
37
  getMetadata(resource) {
31
38
  const {
32
39
  delivery,
40
+ title,
33
41
  data,
34
42
  createdAt,
35
43
  } = resource;
36
44
  return {
37
- id: delivery,
38
- summary: `Issue created: ${data.title}`,
45
+ id: delivery || resource.id,
46
+ summary: `Issue created: ${data?.title || title}`,
39
47
  ts: Date.parse(createdAt),
40
48
  };
41
49
  },
@@ -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.0",
10
+ version: "0.2.3",
11
11
  dedupe: "unique",
12
12
  methods: {
13
13
  ...common.methods,
@@ -19,23 +19,31 @@ export default {
19
19
  getWebhookLabel() {
20
20
  return "Issue updated";
21
21
  },
22
- getActions() {
23
- return [
24
- constants.ACTION.UPDATE,
25
- ];
26
- },
27
22
  getResourcesFn() {
28
23
  return this.linearApp.listIssues;
29
24
  },
25
+ getResourcesFnArgs() {
26
+ return {
27
+ sortBy: "updatedAt",
28
+ filter: {
29
+ project: {
30
+ id: {
31
+ eq: this.projectId,
32
+ },
33
+ },
34
+ },
35
+ };
36
+ },
30
37
  getMetadata(resource) {
31
38
  const {
32
39
  delivery,
40
+ title,
33
41
  data,
34
42
  updatedAt,
35
43
  } = resource;
36
44
  return {
37
- id: delivery,
38
- summary: `Issue Updated: ${data.title}`,
45
+ id: delivery || resource.id,
46
+ summary: `Issue Updated: ${data?.title || title}`,
39
47
  ts: Date.parse(updatedAt),
40
48
  };
41
49
  },