@pipedream/navan 0.0.1 → 0.2.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.
@@ -0,0 +1,159 @@
1
+ import app from "../../navan.app.mjs";
2
+
3
+ export default {
4
+ key: "navan-create-user",
5
+ name: "Create User",
6
+ description: "Creates a new user in the system. [See the documentation](https://u.pcloud.link/publink/show?code=XZ7Bww5ZoKb93VNf7ISOdR5UzVo6JzBLs7AX)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ annotations: {
10
+ readOnlyHint: false,
11
+ destructiveHint: false,
12
+ openWorldHint: true,
13
+ },
14
+ props: {
15
+ app,
16
+ userName: {
17
+ propDefinition: [
18
+ app,
19
+ "userName",
20
+ ],
21
+ },
22
+ firstName: {
23
+ propDefinition: [
24
+ app,
25
+ "firstName",
26
+ ],
27
+ },
28
+ lastName: {
29
+ propDefinition: [
30
+ app,
31
+ "lastName",
32
+ ],
33
+ },
34
+ active: {
35
+ propDefinition: [
36
+ app,
37
+ "active",
38
+ ],
39
+ },
40
+ title: {
41
+ propDefinition: [
42
+ app,
43
+ "title",
44
+ ],
45
+ },
46
+ employeeNumber: {
47
+ propDefinition: [
48
+ app,
49
+ "employeeNumber",
50
+ ],
51
+ },
52
+ department: {
53
+ propDefinition: [
54
+ app,
55
+ "department",
56
+ ],
57
+ },
58
+ costCenter: {
59
+ propDefinition: [
60
+ app,
61
+ "costCenter",
62
+ ],
63
+ },
64
+ division: {
65
+ propDefinition: [
66
+ app,
67
+ "division",
68
+ ],
69
+ },
70
+ region: {
71
+ propDefinition: [
72
+ app,
73
+ "region",
74
+ ],
75
+ },
76
+ travelPolicy: {
77
+ propDefinition: [
78
+ app,
79
+ "travelPolicy",
80
+ ],
81
+ },
82
+ },
83
+ async run({ $ }) {
84
+ const {
85
+ app,
86
+ userName,
87
+ firstName,
88
+ lastName,
89
+ active,
90
+ title,
91
+ employeeNumber,
92
+ department,
93
+ costCenter,
94
+ division,
95
+ region,
96
+ travelPolicy,
97
+ } = this;
98
+
99
+ const data = {
100
+ schemas: [
101
+ "urn:ietf:params:scim:schemas:core:2.0:User",
102
+ ],
103
+ userName,
104
+ name: {
105
+ givenName: firstName,
106
+ familyName: lastName,
107
+ },
108
+ active,
109
+ title,
110
+ emails: [
111
+ {
112
+ value: userName,
113
+ type: "work",
114
+ primary: true,
115
+ },
116
+ ],
117
+ };
118
+
119
+ const enterpriseExtension = {};
120
+ if (employeeNumber) {
121
+ enterpriseExtension.employeeNumber = employeeNumber;
122
+ }
123
+ if (department) {
124
+ enterpriseExtension.department = department;
125
+ }
126
+ if (costCenter) {
127
+ enterpriseExtension.costCenter = costCenter;
128
+ }
129
+ if (division) {
130
+ enterpriseExtension.division = division;
131
+ }
132
+
133
+ if (Object.keys(enterpriseExtension).length > 0) {
134
+ data.schemas.push("urn:ietf:params:scim:schemas:extension:enterprise:2.0:User");
135
+ data["urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"] = enterpriseExtension;
136
+ }
137
+
138
+ const navanExtension = {};
139
+ if (region) {
140
+ navanExtension.region = region;
141
+ }
142
+ if (travelPolicy) {
143
+ navanExtension.travelPolicy = travelPolicy;
144
+ }
145
+
146
+ if (Object.keys(navanExtension).length > 0) {
147
+ data.schemas.push("urn:ietf:params:scim:schemas:extension:navan:2.0:User");
148
+ data["urn:ietf:params:scim:schemas:extension:navan:2.0:User"] = navanExtension;
149
+ }
150
+
151
+ const response = await app.createUser({
152
+ $,
153
+ data,
154
+ });
155
+
156
+ $.export("$summary", `Successfully created user \`${response.userName}\``);
157
+ return response;
158
+ },
159
+ };
@@ -0,0 +1,36 @@
1
+ import app from "../../navan.app.mjs";
2
+
3
+ export default {
4
+ key: "navan-get-user",
5
+ name: "Get User",
6
+ description: "Retrieves a specific user by their unique identifier. [See the documentation](https://u.pcloud.link/publink/show?code=XZ7Bww5ZoKb93VNf7ISOdR5UzVo6JzBLs7AX)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ annotations: {
10
+ readOnlyHint: true,
11
+ destructiveHint: false,
12
+ openWorldHint: true,
13
+ },
14
+ props: {
15
+ app,
16
+ userId: {
17
+ propDefinition: [
18
+ app,
19
+ "userId",
20
+ ],
21
+ },
22
+ },
23
+ async run({ $ }) {
24
+ const {
25
+ app, userId,
26
+ } = this;
27
+
28
+ const response = await app.getUser({
29
+ $,
30
+ userId,
31
+ });
32
+
33
+ $.export("$summary", `Successfully retrieved user with ID \`${response.id}\``);
34
+ return response;
35
+ },
36
+ };
@@ -0,0 +1,33 @@
1
+ import navan from "../../navan.app.mjs";
2
+
3
+ export default {
4
+ key: "navan-list-user-id-options",
5
+ name: "List User ID Options",
6
+ description: "Retrieves available options for the User ID field.",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ annotations: {
10
+ destructiveHint: false,
11
+ openWorldHint: true,
12
+ readOnlyHint: true,
13
+ },
14
+ props: {
15
+ navan,
16
+ page: {
17
+ type: "integer",
18
+ label: "Page",
19
+ description: "The page of results to retrieve.",
20
+ min: 0,
21
+ default: 0,
22
+ },
23
+ },
24
+ async run({ $ }) {
25
+ const options = await navan.propDefinitions.userId.options.call(this.navan, {
26
+ page: this.page,
27
+ });
28
+ $.export("$summary", `Successfully retrieved ${options.length} option${options.length === 1
29
+ ? ""
30
+ : "s"}`);
31
+ return options;
32
+ },
33
+ };
@@ -0,0 +1,55 @@
1
+ import app from "../../navan.app.mjs";
2
+
3
+ export default {
4
+ key: "navan-list-users",
5
+ name: "List Users",
6
+ description: "Retrieves a paginated list of all users in the company. [See the documentation](https://u.pcloud.link/publink/show?code=XZ7Bww5ZoKb93VNf7ISOdR5UzVo6JzBLs7AX)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ annotations: {
10
+ readOnlyHint: true,
11
+ destructiveHint: false,
12
+ openWorldHint: true,
13
+ },
14
+ props: {
15
+ app,
16
+ startIndex: {
17
+ type: "integer",
18
+ label: "Start Index",
19
+ description: "0-based index of first result. Default is 0.",
20
+ optional: true,
21
+ },
22
+ count: {
23
+ type: "integer",
24
+ label: "Count",
25
+ description: "Number of resources to return per page. Default is `10`.",
26
+ optional: true,
27
+ },
28
+ filter: {
29
+ type: "string",
30
+ label: "Filter",
31
+ description: "SCIM filter expression. Supported filters like `userName eq \"email@example.com\"`",
32
+ optional: true,
33
+ },
34
+ },
35
+ async run({ $ }) {
36
+ const {
37
+ app,
38
+ startIndex,
39
+ count,
40
+ filter,
41
+ } = this;
42
+
43
+ const response = await app.listUsers({
44
+ $,
45
+ params: {
46
+ startIndex,
47
+ count,
48
+ filter,
49
+ },
50
+ });
51
+
52
+ $.export("$summary", `Successfully retrieved ${response.Resources?.length || 0} user(s) out of ${response.totalResults} total`);
53
+ return response;
54
+ },
55
+ };
@@ -0,0 +1,170 @@
1
+ import app from "../../navan.app.mjs";
2
+
3
+ export default {
4
+ key: "navan-replace-user",
5
+ name: "Replace User",
6
+ description: "Replaces an entire user resource (full update). [See the documentation](https://u.pcloud.link/publink/show?code=XZ7Bww5ZoKb93VNf7ISOdR5UzVo6JzBLs7AX)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ annotations: {
10
+ readOnlyHint: false,
11
+ destructiveHint: true,
12
+ openWorldHint: true,
13
+ },
14
+ props: {
15
+ app,
16
+ userId: {
17
+ propDefinition: [
18
+ app,
19
+ "userId",
20
+ ],
21
+ },
22
+ userName: {
23
+ propDefinition: [
24
+ app,
25
+ "userName",
26
+ ],
27
+ },
28
+ firstName: {
29
+ propDefinition: [
30
+ app,
31
+ "firstName",
32
+ ],
33
+ },
34
+ lastName: {
35
+ propDefinition: [
36
+ app,
37
+ "lastName",
38
+ ],
39
+ },
40
+ active: {
41
+ propDefinition: [
42
+ app,
43
+ "active",
44
+ ],
45
+ },
46
+ title: {
47
+ propDefinition: [
48
+ app,
49
+ "title",
50
+ ],
51
+ },
52
+ employeeNumber: {
53
+ propDefinition: [
54
+ app,
55
+ "employeeNumber",
56
+ ],
57
+ },
58
+ department: {
59
+ propDefinition: [
60
+ app,
61
+ "department",
62
+ ],
63
+ },
64
+ costCenter: {
65
+ propDefinition: [
66
+ app,
67
+ "costCenter",
68
+ ],
69
+ },
70
+ division: {
71
+ propDefinition: [
72
+ app,
73
+ "division",
74
+ ],
75
+ },
76
+ region: {
77
+ propDefinition: [
78
+ app,
79
+ "region",
80
+ ],
81
+ },
82
+ travelPolicy: {
83
+ propDefinition: [
84
+ app,
85
+ "travelPolicy",
86
+ ],
87
+ },
88
+ },
89
+ async run({ $ }) {
90
+ const {
91
+ app,
92
+ userId,
93
+ userName,
94
+ firstName,
95
+ lastName,
96
+ active,
97
+ title,
98
+ employeeNumber,
99
+ department,
100
+ costCenter,
101
+ division,
102
+ region,
103
+ travelPolicy,
104
+ } = this;
105
+
106
+ const data = {
107
+ schemas: [
108
+ "urn:ietf:params:scim:schemas:core:2.0:User",
109
+ ],
110
+ userName,
111
+ name: {
112
+ givenName: firstName,
113
+ familyName: lastName,
114
+ },
115
+ emails: [
116
+ {
117
+ value: userName,
118
+ type: "work",
119
+ primary: true,
120
+ },
121
+ ],
122
+ active,
123
+ };
124
+
125
+ if (title) {
126
+ data.title = title;
127
+ }
128
+
129
+ const enterpriseExtension = {};
130
+ if (employeeNumber) {
131
+ enterpriseExtension.employeeNumber = employeeNumber;
132
+ }
133
+ if (department) {
134
+ enterpriseExtension.department = department;
135
+ }
136
+ if (costCenter) {
137
+ enterpriseExtension.costCenter = costCenter;
138
+ }
139
+ if (division) {
140
+ enterpriseExtension.division = division;
141
+ }
142
+
143
+ if (Object.keys(enterpriseExtension).length > 0) {
144
+ data.schemas.push("urn:ietf:params:scim:schemas:extension:enterprise:2.0:User");
145
+ data["urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"] = enterpriseExtension;
146
+ }
147
+
148
+ const navanExtension = {};
149
+ if (region) {
150
+ navanExtension.region = region;
151
+ }
152
+ if (travelPolicy) {
153
+ navanExtension.travelPolicy = travelPolicy;
154
+ }
155
+
156
+ if (Object.keys(navanExtension).length > 0) {
157
+ data.schemas.push("urn:ietf:params:scim:schemas:extension:navan:2.0:User");
158
+ data["urn:ietf:params:scim:schemas:extension:navan:2.0:User"] = navanExtension;
159
+ }
160
+
161
+ const response = await app.replaceUser({
162
+ $,
163
+ userId,
164
+ data,
165
+ });
166
+
167
+ $.export("$summary", `Successfully replaced user \`${response.userName}\``);
168
+ return response;
169
+ },
170
+ };
@@ -0,0 +1,167 @@
1
+ import app from "../../navan.app.mjs";
2
+
3
+ export default {
4
+ key: "navan-update-user",
5
+ name: "Update User",
6
+ description: "Performs partial updates to a user using SCIM patch operations. [See the documentation](https://u.pcloud.link/publink/show?code=XZ7Bww5ZoKb93VNf7ISOdR5UzVo6JzBLs7AX)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ annotations: {
10
+ readOnlyHint: false,
11
+ destructiveHint: false,
12
+ openWorldHint: true,
13
+ },
14
+ props: {
15
+ app,
16
+ userId: {
17
+ propDefinition: [
18
+ app,
19
+ "userId",
20
+ ],
21
+ },
22
+ firstName: {
23
+ propDefinition: [
24
+ app,
25
+ "firstName",
26
+ ],
27
+ optional: true,
28
+ },
29
+ lastName: {
30
+ propDefinition: [
31
+ app,
32
+ "lastName",
33
+ ],
34
+ optional: true,
35
+ },
36
+ active: {
37
+ propDefinition: [
38
+ app,
39
+ "active",
40
+ ],
41
+ },
42
+ title: {
43
+ propDefinition: [
44
+ app,
45
+ "title",
46
+ ],
47
+ },
48
+ employeeNumber: {
49
+ propDefinition: [
50
+ app,
51
+ "employeeNumber",
52
+ ],
53
+ },
54
+ department: {
55
+ propDefinition: [
56
+ app,
57
+ "department",
58
+ ],
59
+ },
60
+ costCenter: {
61
+ propDefinition: [
62
+ app,
63
+ "costCenter",
64
+ ],
65
+ },
66
+ division: {
67
+ propDefinition: [
68
+ app,
69
+ "division",
70
+ ],
71
+ },
72
+ },
73
+ async run({ $ }) {
74
+ const {
75
+ app,
76
+ userId,
77
+ firstName,
78
+ lastName,
79
+ active,
80
+ title,
81
+ employeeNumber,
82
+ department,
83
+ costCenter,
84
+ division,
85
+ } = this;
86
+
87
+ const operations = [];
88
+
89
+ if (firstName) {
90
+ operations.push({
91
+ op: "replace",
92
+ path: "name.givenName",
93
+ value: firstName,
94
+ });
95
+ }
96
+
97
+ if (lastName) {
98
+ operations.push({
99
+ op: "replace",
100
+ path: "name.familyName",
101
+ value: lastName,
102
+ });
103
+ }
104
+
105
+ if (active) {
106
+ operations.push({
107
+ op: "replace",
108
+ path: "active",
109
+ value: active,
110
+ });
111
+ }
112
+
113
+ if (title) {
114
+ operations.push({
115
+ op: "replace",
116
+ path: "title",
117
+ value: title,
118
+ });
119
+ }
120
+
121
+ if (employeeNumber) {
122
+ operations.push({
123
+ op: "replace",
124
+ path: "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber",
125
+ value: employeeNumber,
126
+ });
127
+ }
128
+
129
+ if (department) {
130
+ operations.push({
131
+ op: "replace",
132
+ path: "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department",
133
+ value: department,
134
+ });
135
+ }
136
+
137
+ if (costCenter) {
138
+ operations.push({
139
+ op: "replace",
140
+ path: "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:costCenter",
141
+ value: costCenter,
142
+ });
143
+ }
144
+
145
+ if (division) {
146
+ operations.push({
147
+ op: "replace",
148
+ path: "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:division",
149
+ value: division,
150
+ });
151
+ }
152
+
153
+ const response = await app.updateUser({
154
+ $,
155
+ userId,
156
+ data: {
157
+ schemas: [
158
+ "urn:ietf:params:scim:api:messages:2.0:PatchOp",
159
+ ],
160
+ Operations: operations,
161
+ },
162
+ });
163
+
164
+ $.export("$summary", `Successfully updated user \`${response.userName}\``);
165
+ return response;
166
+ },
167
+ };
@@ -0,0 +1,5 @@
1
+ const DEFAULT_LIMIT = 10;
2
+
3
+ export default {
4
+ DEFAULT_LIMIT,
5
+ };
package/navan.app.mjs CHANGED
@@ -1,11 +1,148 @@
1
+ import { axios } from "@pipedream/platform";
2
+ import constants from "./common/constants.mjs";
3
+
1
4
  export default {
2
5
  type: "app",
3
6
  app: "navan",
4
- propDefinitions: {},
7
+ propDefinitions: {
8
+ userId: {
9
+ type: "string",
10
+ label: "User ID",
11
+ description: "The unique identifier (UUID) of the user",
12
+ async options({ page }) {
13
+ const { Resources } = await this.listUsers({
14
+ params: {
15
+ startIndex: page * constants.DEFAULT_LIMIT,
16
+ count: constants.DEFAULT_LIMIT,
17
+ },
18
+ });
19
+ return Resources?.map(({
20
+ id: value, userName: label,
21
+ }) => ({
22
+ label,
23
+ value,
24
+ })) || [];
25
+ },
26
+ },
27
+ userName: {
28
+ type: "string",
29
+ label: "Email",
30
+ description: "User's email address",
31
+ },
32
+ firstName: {
33
+ type: "string",
34
+ label: "First Name",
35
+ description: "User's first name",
36
+ },
37
+ lastName: {
38
+ type: "string",
39
+ label: "Last Name",
40
+ description: "User's last name",
41
+ },
42
+ active: {
43
+ type: "boolean",
44
+ label: "Active",
45
+ description: "User status",
46
+ optional: true,
47
+ },
48
+ title: {
49
+ type: "string",
50
+ label: "Job Title",
51
+ description: "User's job title",
52
+ optional: true,
53
+ },
54
+ employeeNumber: {
55
+ type: "string",
56
+ label: "Employee Number",
57
+ description: "Employee ID",
58
+ optional: true,
59
+ },
60
+ department: {
61
+ type: "string",
62
+ label: "Department",
63
+ description: "Department name",
64
+ optional: true,
65
+ },
66
+ costCenter: {
67
+ type: "string",
68
+ label: "Cost Center",
69
+ description: "Cost center identifier",
70
+ optional: true,
71
+ },
72
+ division: {
73
+ type: "string",
74
+ label: "Division",
75
+ description: "Subsidiary in Navan",
76
+ optional: true,
77
+ },
78
+ region: {
79
+ type: "string",
80
+ label: "Region",
81
+ description: "Geographic region",
82
+ optional: true,
83
+ },
84
+ travelPolicy: {
85
+ type: "string",
86
+ label: "Travel Policy",
87
+ description: "Travel policy assignment",
88
+ optional: true,
89
+ },
90
+ },
5
91
  methods: {
6
- // this.$auth contains connected account data
7
- authKeys() {
8
- console.log(Object.keys(this.$auth));
92
+ getUrl(path) {
93
+ return `${this.$auth.api_url}${path}`;
94
+ },
95
+ _makeRequest({
96
+ $ = this, path, ...opts
97
+ }) {
98
+ return axios($, {
99
+ url: this.getUrl(path),
100
+ headers: {
101
+ "Authorization": `Bearer ${this.$auth.scim_token}`,
102
+ "Content-Type": "application/json",
103
+ "Accept": "application/json",
104
+ },
105
+ ...opts,
106
+ });
107
+ },
108
+ listUsers(opts = {}) {
109
+ return this._makeRequest({
110
+ path: "/Users",
111
+ ...opts,
112
+ });
113
+ },
114
+ getUser({
115
+ userId, ...opts
116
+ }) {
117
+ return this._makeRequest({
118
+ path: `/Users/${userId}`,
119
+ ...opts,
120
+ });
121
+ },
122
+ createUser(opts = {}) {
123
+ return this._makeRequest({
124
+ method: "POST",
125
+ path: "/Users",
126
+ ...opts,
127
+ });
128
+ },
129
+ updateUser({
130
+ userId, ...opts
131
+ }) {
132
+ return this._makeRequest({
133
+ method: "PATCH",
134
+ path: `/Users/${userId}`,
135
+ ...opts,
136
+ });
137
+ },
138
+ replaceUser({
139
+ userId, ...opts
140
+ }) {
141
+ return this._makeRequest({
142
+ method: "PUT",
143
+ path: `/Users/${userId}`,
144
+ ...opts,
145
+ });
9
146
  },
10
147
  },
11
- };
148
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/navan",
3
- "version": "0.0.1",
3
+ "version": "0.2.0",
4
4
  "description": "Pipedream Navan Components",
5
5
  "main": "navan.app.mjs",
6
6
  "keywords": [
@@ -11,5 +11,8 @@
11
11
  "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
12
12
  "publishConfig": {
13
13
  "access": "public"
14
+ },
15
+ "dependencies": {
16
+ "@pipedream/platform": "^3.1.1"
14
17
  }
15
18
  }