@forge/teamwork-graph 1.0.1-next.0 → 1.1.0-next.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.
- package/out/__test__/entities.test.d.ts +2 -0
- package/out/__test__/entities.test.d.ts.map +1 -0
- package/out/__test__/entities.test.js +149 -0
- package/out/__test__/graph.test.js +0 -110
- package/out/__test__/user-operations.test.d.ts +2 -0
- package/out/__test__/user-operations.test.d.ts.map +1 -0
- package/out/__test__/user-operations.test.js +177 -0
- package/out/graph.d.ts +6 -3
- package/out/graph.d.ts.map +1 -1
- package/out/graph.js +72 -11
- package/out/types/common.d.ts +5 -22
- package/out/types/common.d.ts.map +1 -1
- package/out/types/entities/document.d.ts +14 -2
- package/out/types/entities/document.d.ts.map +1 -1
- package/out/types/entities/index.d.ts +4 -9
- package/out/types/entities/index.d.ts.map +1 -1
- package/out/types/entities/message.d.ts +18 -0
- package/out/types/entities/message.d.ts.map +1 -0
- package/out/types/entities/message.js +2 -0
- package/out/types/graph.d.ts +5 -3
- package/out/types/graph.d.ts.map +1 -1
- package/out/types/index.d.ts +1 -0
- package/out/types/index.d.ts.map +1 -1
- package/out/types/index.js +1 -0
- package/out/types/requests.d.ts +32 -6
- package/out/types/requests.d.ts.map +1 -1
- package/out/types/users.d.ts +52 -0
- package/out/types/users.d.ts.map +1 -0
- package/out/types/users.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entities.test.d.ts","sourceRoot":"","sources":["../../src/__test__/entities.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const api_1 = require("@forge/api");
|
|
4
|
+
const graph_1 = require("../graph");
|
|
5
|
+
jest.mock('@forge/api');
|
|
6
|
+
describe('TeamWorkGraphClient - setEntities', () => {
|
|
7
|
+
let graphClient;
|
|
8
|
+
let mockFetch;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
graphClient = new graph_1.TeamWorkGraphClient();
|
|
11
|
+
mockFetch = jest.fn();
|
|
12
|
+
api_1.__fetchProduct.mockReturnValue(mockFetch);
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
it('throws if entities array is empty', async () => {
|
|
16
|
+
const req = { entities: [] };
|
|
17
|
+
await expect(graphClient.setEntities(req)).rejects.toThrow('entities array cannot be empty');
|
|
18
|
+
});
|
|
19
|
+
it('throws if more than 100 entities', async () => {
|
|
20
|
+
const documentEntity = {
|
|
21
|
+
schemaVersion: '1.0',
|
|
22
|
+
id: 'my-document',
|
|
23
|
+
updateSequenceNumber: 123,
|
|
24
|
+
displayName: 'My Document',
|
|
25
|
+
url: 'https://document.com',
|
|
26
|
+
createdAt: '2024-04-16T09:01:32+00:00',
|
|
27
|
+
lastUpdatedAt: '2024-04-16T09:01:32+00:00',
|
|
28
|
+
permissions: {
|
|
29
|
+
accessControls: [
|
|
30
|
+
{
|
|
31
|
+
principals: [
|
|
32
|
+
{
|
|
33
|
+
type: 'EVERYONE'
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
'atlassian:document': {
|
|
40
|
+
type: {
|
|
41
|
+
category: 'document',
|
|
42
|
+
iconUrl: 'http://icon.com'
|
|
43
|
+
},
|
|
44
|
+
content: {
|
|
45
|
+
mimeType: 'text/plain',
|
|
46
|
+
text: 'Really large content here...'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const req = {
|
|
51
|
+
entities: Array(101).fill(documentEntity)
|
|
52
|
+
};
|
|
53
|
+
await expect(graphClient.setEntities(req)).rejects.toThrow('Bulk ingestion supports maximum 100 entities');
|
|
54
|
+
});
|
|
55
|
+
it('posts to /api/v1/entities/bulk and returns response', async () => {
|
|
56
|
+
const documentEntity = {
|
|
57
|
+
schemaVersion: '1.0',
|
|
58
|
+
id: 'my-document',
|
|
59
|
+
updateSequenceNumber: 123,
|
|
60
|
+
displayName: 'My Document',
|
|
61
|
+
url: 'https://document.com',
|
|
62
|
+
createdAt: '2024-04-16T09:01:32+00:00',
|
|
63
|
+
lastUpdatedAt: '2024-04-16T09:01:32+00:00',
|
|
64
|
+
permissions: {
|
|
65
|
+
accessControls: [
|
|
66
|
+
{
|
|
67
|
+
principals: [
|
|
68
|
+
{
|
|
69
|
+
type: 'EVERYONE'
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
'atlassian:document': {
|
|
76
|
+
type: {
|
|
77
|
+
category: 'document',
|
|
78
|
+
iconUrl: 'http://icon.com'
|
|
79
|
+
},
|
|
80
|
+
content: {
|
|
81
|
+
mimeType: 'text/plain',
|
|
82
|
+
text: 'Really large content here...'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const req = { entities: [documentEntity] };
|
|
87
|
+
const expected = { success: true, results: [{ entityId: 'my-document', success: true }] };
|
|
88
|
+
mockFetch.mockResolvedValueOnce({
|
|
89
|
+
ok: true,
|
|
90
|
+
json: () => Promise.resolve(expected)
|
|
91
|
+
});
|
|
92
|
+
const result = await graphClient.setEntities(req);
|
|
93
|
+
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/entities/bulk', expect.objectContaining({ method: 'POST' }));
|
|
94
|
+
expect(result).toEqual(expected);
|
|
95
|
+
});
|
|
96
|
+
it('posts message entities to /api/v1/entities/bulk and returns response', async () => {
|
|
97
|
+
const messageEntity = {
|
|
98
|
+
schemaVersion: '2.0',
|
|
99
|
+
id: 'message-1',
|
|
100
|
+
updateSequenceNumber: 1,
|
|
101
|
+
description: 'Hello everyone!',
|
|
102
|
+
url: 'https://atlassian.slack.com/archives/C03DZ3WCN94/p1722400000000000',
|
|
103
|
+
createdAt: '2024-07-09T14:27:37.000Z',
|
|
104
|
+
lastUpdatedAt: '2024-07-09T14:27:37.000Z',
|
|
105
|
+
permissions: {
|
|
106
|
+
accessControls: [
|
|
107
|
+
{
|
|
108
|
+
principals: [
|
|
109
|
+
{
|
|
110
|
+
type: 'EVERYONE'
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
containerKey: {
|
|
117
|
+
type: 'atlassian:conversation',
|
|
118
|
+
value: {
|
|
119
|
+
entityId: 'CFG3W7TKJ'
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
'atlassian:message': {
|
|
123
|
+
hidden: false,
|
|
124
|
+
isPinned: false,
|
|
125
|
+
attachments: [
|
|
126
|
+
{
|
|
127
|
+
url: 'https://atlassian.enterprise.slack.com/files/U02S327DT62/F07FAUT3L00/img_4659.png',
|
|
128
|
+
mimeType: 'image/png',
|
|
129
|
+
byteSize: 140288
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
lastActive: '2024-07-09T15:27:37.000Z'
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const req = { entities: [messageEntity] };
|
|
136
|
+
const expected = { success: true, results: [{ entityId: 'message-1', success: true }] };
|
|
137
|
+
mockFetch.mockResolvedValueOnce({
|
|
138
|
+
ok: true,
|
|
139
|
+
json: () => Promise.resolve(expected)
|
|
140
|
+
});
|
|
141
|
+
const result = await graphClient.setEntities(req);
|
|
142
|
+
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/entities/bulk', expect.objectContaining({ method: 'POST' }));
|
|
143
|
+
expect(result).toEqual(expected);
|
|
144
|
+
});
|
|
145
|
+
it('throws if entities is not an array', async () => {
|
|
146
|
+
const req = { entities: null };
|
|
147
|
+
await expect(graphClient.setEntities(req)).rejects.toThrow('entities must be an array');
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -21,9 +21,6 @@ describe('Teamwork Graph Client', () => {
|
|
|
21
21
|
jest.clearAllMocks();
|
|
22
22
|
});
|
|
23
23
|
describe('Context Validation', () => {
|
|
24
|
-
const userPayload = {
|
|
25
|
-
externalId: 'user-123'
|
|
26
|
-
};
|
|
27
24
|
const groupPayload = {
|
|
28
25
|
id: 'group-123',
|
|
29
26
|
name: 'Test Group'
|
|
@@ -32,12 +29,6 @@ describe('Teamwork Graph Client', () => {
|
|
|
32
29
|
it('should throw error when context is missing for deleteEntity', async () => {
|
|
33
30
|
await expect(graphClient.deleteEntity(undefined, 'entity-123')).rejects.toThrow(errorMessage);
|
|
34
31
|
});
|
|
35
|
-
it('should throw error when context is missing for setUser', async () => {
|
|
36
|
-
await expect(graphClient.setUser(undefined, userPayload)).rejects.toThrow(errorMessage);
|
|
37
|
-
});
|
|
38
|
-
it('should throw error when context is missing for deleteUser', async () => {
|
|
39
|
-
await expect(graphClient.deleteUser(undefined, 'user-123')).rejects.toThrow(errorMessage);
|
|
40
|
-
});
|
|
41
32
|
it('should throw error when context is missing for setGroup', async () => {
|
|
42
33
|
await expect(graphClient.setGroup(undefined, groupPayload)).rejects.toThrow(errorMessage);
|
|
43
34
|
});
|
|
@@ -60,107 +51,6 @@ describe('Teamwork Graph Client', () => {
|
|
|
60
51
|
})).rejects.toThrow(errorMessage);
|
|
61
52
|
});
|
|
62
53
|
});
|
|
63
|
-
describe('setUser', () => {
|
|
64
|
-
const userPayload = {
|
|
65
|
-
externalId: 'user-123',
|
|
66
|
-
accountId: 'acc-123',
|
|
67
|
-
displayName: 'Test User',
|
|
68
|
-
userName: 'testuser',
|
|
69
|
-
nickname: 'tester',
|
|
70
|
-
name: {
|
|
71
|
-
formatted: 'Test User',
|
|
72
|
-
familyName: 'User',
|
|
73
|
-
givenName: 'Test'
|
|
74
|
-
},
|
|
75
|
-
photos: ['https://example.com/avatar.jpg'],
|
|
76
|
-
emails: [
|
|
77
|
-
{ value: 'test@example.com', primary: true },
|
|
78
|
-
{ value: 'backup@example.com', primary: false }
|
|
79
|
-
]
|
|
80
|
-
};
|
|
81
|
-
it('should successfully post user data', async () => {
|
|
82
|
-
const expectedResponse = { success: true, user: userPayload };
|
|
83
|
-
mockFetch.mockResolvedValueOnce({
|
|
84
|
-
ok: true,
|
|
85
|
-
json: () => Promise.resolve(expectedResponse)
|
|
86
|
-
});
|
|
87
|
-
const result = await graphClient.setUser(mockContext, userPayload);
|
|
88
|
-
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/user', {
|
|
89
|
-
method: 'POST',
|
|
90
|
-
body: JSON.stringify(userPayload),
|
|
91
|
-
redirect: 'follow',
|
|
92
|
-
headers: { 'Content-Type': 'application/json' }
|
|
93
|
-
});
|
|
94
|
-
expect(result).toEqual(expectedResponse);
|
|
95
|
-
});
|
|
96
|
-
it('should throw ForgeGraphAPIError when request fails', async () => {
|
|
97
|
-
const errorResponse = {
|
|
98
|
-
ok: false,
|
|
99
|
-
status: 400,
|
|
100
|
-
statusText: 'Bad Request',
|
|
101
|
-
headers: {
|
|
102
|
-
get: () => null
|
|
103
|
-
},
|
|
104
|
-
text: () => Promise.resolve(JSON.stringify({
|
|
105
|
-
code: errors_1.errorCodes.INVALID_REQUEST_BODY,
|
|
106
|
-
message: 'Invalid user data'
|
|
107
|
-
}))
|
|
108
|
-
};
|
|
109
|
-
mockFetch.mockResolvedValueOnce(errorResponse);
|
|
110
|
-
await expect(graphClient.setUser(mockContext, userPayload)).rejects.toThrow(errors_1.ForgeGraphAPIError);
|
|
111
|
-
});
|
|
112
|
-
it('should handle minimal user object with only required fields', async () => {
|
|
113
|
-
const minimalUser = {
|
|
114
|
-
externalId: 'min-user-123'
|
|
115
|
-
};
|
|
116
|
-
const expectedResponse = { success: true, user: minimalUser };
|
|
117
|
-
mockFetch.mockResolvedValueOnce({
|
|
118
|
-
ok: true,
|
|
119
|
-
json: () => Promise.resolve(expectedResponse)
|
|
120
|
-
});
|
|
121
|
-
const result = await graphClient.setUser(mockContext, minimalUser);
|
|
122
|
-
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/user', {
|
|
123
|
-
method: 'POST',
|
|
124
|
-
body: JSON.stringify(minimalUser),
|
|
125
|
-
redirect: 'follow',
|
|
126
|
-
headers: { 'Content-Type': 'application/json' }
|
|
127
|
-
});
|
|
128
|
-
expect(result).toEqual(expectedResponse);
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
describe('deleteUser', () => {
|
|
132
|
-
const userId = 'user-Folder/user-123';
|
|
133
|
-
it('should successfully delete a user', async () => {
|
|
134
|
-
const expectedResponse = { success: true };
|
|
135
|
-
mockFetch.mockResolvedValueOnce({
|
|
136
|
-
ok: true,
|
|
137
|
-
json: () => Promise.resolve(expectedResponse)
|
|
138
|
-
});
|
|
139
|
-
const result = await graphClient.deleteUser(mockContext, userId);
|
|
140
|
-
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/user/?resourceId=user-Folder/user-123', {
|
|
141
|
-
method: 'DELETE',
|
|
142
|
-
redirect: 'follow',
|
|
143
|
-
headers: { 'Content-Type': 'application/json' }
|
|
144
|
-
});
|
|
145
|
-
expect(result).toEqual(expectedResponse);
|
|
146
|
-
});
|
|
147
|
-
it('should throw ForgeGraphAPIError when delete request fails', async () => {
|
|
148
|
-
const errorResponse = {
|
|
149
|
-
ok: false,
|
|
150
|
-
status: 404,
|
|
151
|
-
statusText: 'Not Found',
|
|
152
|
-
headers: {
|
|
153
|
-
get: () => null
|
|
154
|
-
},
|
|
155
|
-
text: () => Promise.resolve(JSON.stringify({
|
|
156
|
-
code: 'USER_NOT_FOUND',
|
|
157
|
-
message: 'User not found'
|
|
158
|
-
}))
|
|
159
|
-
};
|
|
160
|
-
mockFetch.mockResolvedValueOnce(errorResponse);
|
|
161
|
-
await expect(graphClient.deleteUser(mockContext, userId)).rejects.toThrow(errors_1.ForgeGraphAPIError);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
54
|
describe('deleteEntity', () => {
|
|
165
55
|
const entityId = 'entity-123';
|
|
166
56
|
it('should successfully delete an entity', async () => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-operations.test.d.ts","sourceRoot":"","sources":["../../src/__test__/user-operations.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const api_1 = require("@forge/api");
|
|
4
|
+
const graph_1 = require("../graph");
|
|
5
|
+
jest.mock('@forge/api');
|
|
6
|
+
describe('TeamWorkGraphClient - User Operations', () => {
|
|
7
|
+
let graphClient;
|
|
8
|
+
let mockFetch;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
graphClient = new graph_1.TeamWorkGraphClient();
|
|
11
|
+
mockFetch = jest.fn();
|
|
12
|
+
api_1.__fetchProduct.mockReturnValue(mockFetch);
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
describe('setUsers', () => {
|
|
16
|
+
const userPayload = {
|
|
17
|
+
externalId: 'user-123',
|
|
18
|
+
displayName: 'Test User',
|
|
19
|
+
userName: 'testuser',
|
|
20
|
+
nickname: 'tester',
|
|
21
|
+
name: {
|
|
22
|
+
formatted: 'Test User',
|
|
23
|
+
familyName: 'User',
|
|
24
|
+
givenName: 'Test'
|
|
25
|
+
},
|
|
26
|
+
photos: [
|
|
27
|
+
{
|
|
28
|
+
value: 'https://example.com/avatar.jpg',
|
|
29
|
+
type: 'photo'
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
emails: [
|
|
33
|
+
{ value: 'test@example.com', primary: true },
|
|
34
|
+
{ value: 'backup@example.com', primary: false }
|
|
35
|
+
],
|
|
36
|
+
extendedProfile: {
|
|
37
|
+
jobTitle: 'Software Engineer',
|
|
38
|
+
department: 'Engineering',
|
|
39
|
+
organization: 'Tech Corp',
|
|
40
|
+
location: 'San Francisco'
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
it('should successfully create users in bulk', async () => {
|
|
44
|
+
const expectedResponse = {
|
|
45
|
+
success: true,
|
|
46
|
+
results: [{ externalId: 'user-123', success: true, resourceId: 'ari:cloud:identity:third-party-user/123' }]
|
|
47
|
+
};
|
|
48
|
+
mockFetch.mockResolvedValueOnce({
|
|
49
|
+
ok: true,
|
|
50
|
+
json: () => Promise.resolve(expectedResponse)
|
|
51
|
+
});
|
|
52
|
+
const result = await graphClient.setUsers({
|
|
53
|
+
users: [userPayload]
|
|
54
|
+
});
|
|
55
|
+
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/users/bulk', {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
body: JSON.stringify({ users: [userPayload] }),
|
|
58
|
+
redirect: 'follow',
|
|
59
|
+
headers: { 'Content-Type': 'application/json' }
|
|
60
|
+
});
|
|
61
|
+
expect(result).toEqual(expectedResponse);
|
|
62
|
+
});
|
|
63
|
+
it('should throw error when users array is empty', async () => {
|
|
64
|
+
await expect(graphClient.setUsers({
|
|
65
|
+
users: []
|
|
66
|
+
})).rejects.toThrow('users array cannot be empty');
|
|
67
|
+
});
|
|
68
|
+
it('should throw error when users array exceeds limit', async () => {
|
|
69
|
+
const manyUsers = Array(101).fill(userPayload);
|
|
70
|
+
await expect(graphClient.setUsers({
|
|
71
|
+
users: manyUsers
|
|
72
|
+
})).rejects.toThrow('Bulk user ingestion supports maximum 100 users');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('deleteUsersByExternalId', () => {
|
|
76
|
+
it('should successfully delete users in bulk', async () => {
|
|
77
|
+
const expectedResponse = {
|
|
78
|
+
success: true,
|
|
79
|
+
results: [
|
|
80
|
+
{ externalId: 'user-123', success: true },
|
|
81
|
+
{ externalId: 'user-456', success: true }
|
|
82
|
+
]
|
|
83
|
+
};
|
|
84
|
+
mockFetch.mockResolvedValueOnce({
|
|
85
|
+
ok: true,
|
|
86
|
+
json: () => Promise.resolve(expectedResponse)
|
|
87
|
+
});
|
|
88
|
+
const result = await graphClient.deleteUsersByExternalId({
|
|
89
|
+
externalIds: ['user-123', 'user-456']
|
|
90
|
+
});
|
|
91
|
+
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/users/bulk/delete', {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
body: JSON.stringify({ externalIds: ['user-123', 'user-456'] }),
|
|
94
|
+
redirect: 'follow',
|
|
95
|
+
headers: { 'Content-Type': 'application/json' }
|
|
96
|
+
});
|
|
97
|
+
expect(result).toEqual(expectedResponse);
|
|
98
|
+
});
|
|
99
|
+
it('should throw error when externalIds array is empty', async () => {
|
|
100
|
+
await expect(graphClient.deleteUsersByExternalId({
|
|
101
|
+
externalIds: []
|
|
102
|
+
})).rejects.toThrow('externalIds array cannot be empty');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('getUserByExternalId', () => {
|
|
106
|
+
const expectedUser = {
|
|
107
|
+
id: 'ari:cloud:identity:third-party-user/123',
|
|
108
|
+
externalId: 'user-123',
|
|
109
|
+
displayName: 'Test User',
|
|
110
|
+
userName: 'testuser',
|
|
111
|
+
nickname: 'tester',
|
|
112
|
+
name: {
|
|
113
|
+
formatted: 'Test User',
|
|
114
|
+
familyName: 'User',
|
|
115
|
+
givenName: 'Test'
|
|
116
|
+
},
|
|
117
|
+
photos: [
|
|
118
|
+
{
|
|
119
|
+
value: 'https://example.com/avatar.jpg',
|
|
120
|
+
type: 'photo'
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
emails: [{ value: 'test@example.com', primary: true }],
|
|
124
|
+
meta: {
|
|
125
|
+
resourceType: 'User',
|
|
126
|
+
created: '2024-01-01T00:00:00Z',
|
|
127
|
+
lastModified: '2024-01-01T00:00:00Z',
|
|
128
|
+
location: 'https://example.com/v2/Users/123'
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
it('should successfully get user by external ID', async () => {
|
|
132
|
+
mockFetch.mockResolvedValueOnce({
|
|
133
|
+
ok: true,
|
|
134
|
+
json: () => Promise.resolve(expectedUser)
|
|
135
|
+
});
|
|
136
|
+
const result = await graphClient.getUserByExternalId({
|
|
137
|
+
externalId: 'user-123'
|
|
138
|
+
});
|
|
139
|
+
expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/users?externalId=user-123', {
|
|
140
|
+
method: 'GET',
|
|
141
|
+
redirect: 'follow',
|
|
142
|
+
headers: { 'Content-Type': 'application/json' }
|
|
143
|
+
});
|
|
144
|
+
expect(result).toEqual({
|
|
145
|
+
success: true,
|
|
146
|
+
user: expectedUser
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
it('should handle user not found', async () => {
|
|
150
|
+
const errorResponse = {
|
|
151
|
+
ok: false,
|
|
152
|
+
status: 404,
|
|
153
|
+
statusText: 'Not Found',
|
|
154
|
+
headers: {
|
|
155
|
+
get: () => null
|
|
156
|
+
},
|
|
157
|
+
text: () => Promise.resolve(JSON.stringify({
|
|
158
|
+
code: 'USER_NOT_FOUND',
|
|
159
|
+
message: 'User not found'
|
|
160
|
+
}))
|
|
161
|
+
};
|
|
162
|
+
mockFetch.mockResolvedValueOnce(errorResponse);
|
|
163
|
+
const result = await graphClient.getUserByExternalId({
|
|
164
|
+
externalId: 'nonexistent-user'
|
|
165
|
+
});
|
|
166
|
+
expect(result).toEqual({
|
|
167
|
+
success: false,
|
|
168
|
+
error: 'User not found'
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
it('should throw error when externalId is missing', async () => {
|
|
172
|
+
await expect(graphClient.getUserByExternalId({
|
|
173
|
+
externalId: ''
|
|
174
|
+
})).rejects.toThrow('externalId is required');
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
package/out/graph.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Result } from '@forge/api';
|
|
2
|
-
import { TeamWorkGraph, ForgeExtendedContext, GroupObject, RequestConfig,
|
|
2
|
+
import { TeamWorkGraph, ForgeExtendedContext, GroupObject, RequestConfig, BulkEntityRequest, BulkEntityResponse, BulkUsersRequest, BulkUsersResponse, DeleteUsersByExternalIdRequest, DeleteUsersByExternalIdResponse, GetUserByExternalIdRequest, GetUserByExternalIdResponse } from './types';
|
|
3
3
|
export declare class TeamWorkGraphClient implements TeamWorkGraph {
|
|
4
|
+
setEntities: (request: BulkEntityRequest) => Promise<BulkEntityResponse>;
|
|
4
5
|
deleteEntity: (context: ForgeExtendedContext, entityId: string) => Promise<Result>;
|
|
5
|
-
setUser: (context: ForgeExtendedContext, user: UserObject) => Promise<Result>;
|
|
6
|
-
deleteUser: (context: ForgeExtendedContext, userId: string) => Promise<Result>;
|
|
7
6
|
setGroup: (context: ForgeExtendedContext, group: GroupObject) => Promise<Result>;
|
|
8
7
|
deleteGroup: (context: ForgeExtendedContext, groupId: string) => Promise<Result>;
|
|
8
|
+
setUsers: (request: BulkUsersRequest) => Promise<BulkUsersResponse>;
|
|
9
|
+
deleteUsersByExternalId: (request: DeleteUsersByExternalIdRequest) => Promise<DeleteUsersByExternalIdResponse>;
|
|
10
|
+
getUserByExternalId: (request: GetUserByExternalIdRequest) => Promise<GetUserByExternalIdResponse>;
|
|
9
11
|
fetchData: (context: ForgeExtendedContext, requestConfig: RequestConfig, onResult: (data: any) => any) => Promise<any>;
|
|
10
12
|
transformData: (context: ForgeExtendedContext, data: any, transformMethod: (data: any) => any) => Promise<any>;
|
|
11
13
|
private saveToStage;
|
|
@@ -13,6 +15,7 @@ export declare class TeamWorkGraphClient implements TeamWorkGraph {
|
|
|
13
15
|
private validateContext;
|
|
14
16
|
private sendPostRequest;
|
|
15
17
|
private sendDeleteRequest;
|
|
18
|
+
private sendGetRequest;
|
|
16
19
|
private sendRequest;
|
|
17
20
|
}
|
|
18
21
|
export declare const teamworkgraph: TeamWorkGraphClient;
|
package/out/graph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,MAAM,EAAsB,MAAM,YAAY,CAAC;AAErF,OAAO,
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,MAAM,EAAsB,MAAM,YAAY,CAAC;AAErF,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,8BAA8B,EAC9B,+BAA+B,EAC/B,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,SAAS,CAAC;AAMjB,qBAAa,mBAAoB,YAAW,aAAa;IACvD,WAAW,YAAmB,iBAAiB,KAAG,QAAQ,kBAAkB,CAAC,CAiB3E;IAEF,YAAY,YAAmB,oBAAoB,YAAY,MAAM,KAAG,QAAQ,MAAM,CAAC,CAIrF;IAEF,QAAQ,YAAmB,oBAAoB,SAAS,WAAW,KAAG,QAAQ,MAAM,CAAC,CAGnF;IAEF,WAAW,YAAmB,oBAAoB,WAAW,MAAM,KAAG,QAAQ,MAAM,CAAC,CAInF;IAEF,QAAQ,YAAmB,gBAAgB,KAAG,QAAQ,iBAAiB,CAAC,CAetE;IAEF,uBAAuB,YACZ,8BAA8B,KACtC,QAAQ,+BAA+B,CAAC,CAazC;IAEF,mBAAmB,YAAmB,0BAA0B,KAAG,QAAQ,2BAA2B,CAAC,CAoBrG;IAEF,SAAS,YAAmB,oBAAoB,iBAAiB,aAAa,mBAAmB,GAAG,KAAK,GAAG,kBAuB1G;IAEF,aAAa,YAAmB,oBAAoB,QAAQ,GAAG,0BAA0B,GAAG,KAAK,GAAG,kBAIlG;YAEY,WAAW;YAIX,YAAY;IAI1B,OAAO,CAAC,eAAe;YAQT,eAAe;YAaf,iBAAiB;YAajB,cAAc;YAYd,WAAW;CAY1B;AAED,eAAO,MAAM,aAAa,qBAA4B,CAAC"}
|
package/out/graph.js
CHANGED
|
@@ -3,22 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.teamworkgraph = exports.TeamWorkGraphClient = void 0;
|
|
4
4
|
const api_1 = require("@forge/api");
|
|
5
5
|
const error_handling_1 = require("./error-handling");
|
|
6
|
-
const
|
|
6
|
+
const STARGATE_BASE = '/graph/connector';
|
|
7
|
+
const MAX_BULK_ENTITIES = 100;
|
|
8
|
+
const MAX_BULK_USERS = 100;
|
|
7
9
|
class TeamWorkGraphClient {
|
|
10
|
+
setEntities = async (request) => {
|
|
11
|
+
if (!Array.isArray(request.entities)) {
|
|
12
|
+
throw new Error('entities must be an array');
|
|
13
|
+
}
|
|
14
|
+
if (request.entities.length === 0) {
|
|
15
|
+
throw new Error('entities array cannot be empty');
|
|
16
|
+
}
|
|
17
|
+
if (request.entities.length > MAX_BULK_ENTITIES) {
|
|
18
|
+
throw new Error(`Bulk ingestion supports maximum ${MAX_BULK_ENTITIES} entities. Received ${request.entities.length}`);
|
|
19
|
+
}
|
|
20
|
+
const response = await this.sendPostRequest('/api/v1/entities/bulk', { entities: request.entities });
|
|
21
|
+
return response;
|
|
22
|
+
};
|
|
8
23
|
deleteEntity = async (context, entityId) => {
|
|
9
24
|
this.validateContext(context);
|
|
10
25
|
const path = '/api/v1/entity/?resourceId=' + entityId;
|
|
11
26
|
return this.sendDeleteRequest(path);
|
|
12
27
|
};
|
|
13
|
-
setUser = async (context, user) => {
|
|
14
|
-
this.validateContext(context);
|
|
15
|
-
return this.sendPostRequest('/api/v1/user', user);
|
|
16
|
-
};
|
|
17
|
-
deleteUser = async (context, userId) => {
|
|
18
|
-
this.validateContext(context);
|
|
19
|
-
const path = '/api/v1/user/?resourceId=' + userId;
|
|
20
|
-
return this.sendDeleteRequest(path);
|
|
21
|
-
};
|
|
22
28
|
setGroup = async (context, group) => {
|
|
23
29
|
this.validateContext(context);
|
|
24
30
|
return this.sendPostRequest('/api/v1/group', group);
|
|
@@ -28,6 +34,52 @@ class TeamWorkGraphClient {
|
|
|
28
34
|
const path = '/api/v1/group/?resourceId=' + groupId;
|
|
29
35
|
return this.sendDeleteRequest(path);
|
|
30
36
|
};
|
|
37
|
+
setUsers = async (request) => {
|
|
38
|
+
if (!Array.isArray(request.users)) {
|
|
39
|
+
throw new Error('users must be an array');
|
|
40
|
+
}
|
|
41
|
+
if (request.users.length === 0) {
|
|
42
|
+
throw new Error('users array cannot be empty');
|
|
43
|
+
}
|
|
44
|
+
if (request.users.length > MAX_BULK_USERS) {
|
|
45
|
+
throw new Error(`Bulk user ingestion supports maximum ${MAX_BULK_USERS} users. Received ${request.users.length}`);
|
|
46
|
+
}
|
|
47
|
+
const response = await this.sendPostRequest('/api/v1/users/bulk', { users: request.users });
|
|
48
|
+
return response;
|
|
49
|
+
};
|
|
50
|
+
deleteUsersByExternalId = async (request) => {
|
|
51
|
+
if (!Array.isArray(request.externalIds)) {
|
|
52
|
+
throw new Error('externalIds must be an array');
|
|
53
|
+
}
|
|
54
|
+
if (request.externalIds.length === 0) {
|
|
55
|
+
throw new Error('externalIds array cannot be empty');
|
|
56
|
+
}
|
|
57
|
+
const response = await this.sendPostRequest('/api/v1/users/bulk/delete', {
|
|
58
|
+
externalIds: request.externalIds
|
|
59
|
+
});
|
|
60
|
+
return response;
|
|
61
|
+
};
|
|
62
|
+
getUserByExternalId = async (request) => {
|
|
63
|
+
if (!request.externalId) {
|
|
64
|
+
throw new Error('externalId is required');
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const url = new URL('/api/v1/users', 'https://example.com');
|
|
68
|
+
url.searchParams.set('externalId', request.externalId);
|
|
69
|
+
const path = url.pathname + url.search;
|
|
70
|
+
const response = await this.sendGetRequest(path);
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
user: response
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return {
|
|
78
|
+
success: false,
|
|
79
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
};
|
|
31
83
|
fetchData = async (context, requestConfig, onResult) => {
|
|
32
84
|
this.validateContext(context);
|
|
33
85
|
const { url, method, headers } = requestConfig;
|
|
@@ -77,8 +129,17 @@ class TeamWorkGraphClient {
|
|
|
77
129
|
}
|
|
78
130
|
return response.json();
|
|
79
131
|
}
|
|
132
|
+
async sendGetRequest(path) {
|
|
133
|
+
const response = await this.sendRequest(path, {
|
|
134
|
+
method: 'GET'
|
|
135
|
+
});
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
await (0, error_handling_1.handleResponseError)(response, `Error getting from ${path}`);
|
|
138
|
+
}
|
|
139
|
+
return response.json();
|
|
140
|
+
}
|
|
80
141
|
async sendRequest(path, options) {
|
|
81
|
-
const reqPath =
|
|
142
|
+
const reqPath = STARGATE_BASE + path;
|
|
82
143
|
const response = await (0, api_1.__fetchProduct)({ provider: 'app', remote: 'stargate', type: 'fpp' })(reqPath, {
|
|
83
144
|
...options,
|
|
84
145
|
redirect: 'follow',
|
package/out/types/common.d.ts
CHANGED
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
accountId?: string;
|
|
3
|
-
id?: string;
|
|
4
|
-
externalId: string;
|
|
5
|
-
userName?: string;
|
|
6
|
-
displayName?: string;
|
|
7
|
-
nickname?: string;
|
|
8
|
-
name?: {
|
|
9
|
-
formatted: string;
|
|
10
|
-
familyName: string;
|
|
11
|
-
givenName: string;
|
|
12
|
-
};
|
|
13
|
-
photos?: string[];
|
|
14
|
-
emails?: {
|
|
15
|
-
value: string;
|
|
16
|
-
primary: boolean;
|
|
17
|
-
}[];
|
|
18
|
-
};
|
|
1
|
+
import { User } from './';
|
|
19
2
|
export declare type Thumbnail = {
|
|
20
3
|
externalUrl: string;
|
|
21
4
|
};
|
|
@@ -49,14 +32,14 @@ export declare type BaseEntityProperties = {
|
|
|
49
32
|
schemaVersion: string;
|
|
50
33
|
id: string;
|
|
51
34
|
updateSequenceNumber: number;
|
|
52
|
-
displayName
|
|
35
|
+
displayName?: string;
|
|
53
36
|
description?: string;
|
|
54
37
|
url: string;
|
|
55
38
|
createdAt: string;
|
|
56
|
-
createdBy?: Partial<
|
|
39
|
+
createdBy?: Partial<User>;
|
|
57
40
|
lastUpdatedAt?: string;
|
|
58
|
-
lastUpdatedBy?: Partial<
|
|
59
|
-
owners?: Partial<
|
|
41
|
+
lastUpdatedBy?: Partial<User>;
|
|
42
|
+
owners?: Partial<User>[];
|
|
60
43
|
thumbnail?: Thumbnail;
|
|
61
44
|
parentKey?: ParentKeyObject | string;
|
|
62
45
|
containerKey?: ContainerKeyObject | string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/types/common.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/types/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseEntityProperties, User } from '../';
|
|
2
2
|
export declare type DocumentCategory = 'folder' | 'document' | 'presentation' | 'spreadsheet' | 'image' | 'audio' | 'video' | 'pdf' | 'shortcut' | 'code' | 'archive' | 'form' | 'web-page' | 'other';
|
|
3
3
|
export declare type DocumentType = {
|
|
4
4
|
category?: DocumentCategory;
|
|
@@ -15,11 +15,23 @@ export declare type ExportLink = {
|
|
|
15
15
|
mimeType: string;
|
|
16
16
|
url: string;
|
|
17
17
|
};
|
|
18
|
+
export declare type Reaction = {
|
|
19
|
+
type: string;
|
|
20
|
+
total?: number;
|
|
21
|
+
};
|
|
18
22
|
export declare type DocumentAttributes = {
|
|
19
|
-
collaborators?: Partial<UserObject>[];
|
|
20
23
|
type: DocumentType;
|
|
21
24
|
content: DocumentContent;
|
|
22
25
|
byteSize?: number;
|
|
23
26
|
exportLinks?: ExportLink[];
|
|
27
|
+
collaborators?: Partial<User>[];
|
|
28
|
+
labels?: string[];
|
|
29
|
+
reactions?: Reaction[];
|
|
30
|
+
};
|
|
31
|
+
export declare type DocumentEntity = BaseEntityProperties & {
|
|
32
|
+
displayName: string;
|
|
33
|
+
permissions: NonNullable<BaseEntityProperties['permissions']>;
|
|
34
|
+
lastUpdatedAt: string;
|
|
35
|
+
'atlassian:document': DocumentAttributes;
|
|
24
36
|
};
|
|
25
37
|
//# sourceMappingURL=document.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../src/types/entities/document.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../src/types/entities/document.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEjD,oBAAY,gBAAgB,GACxB,QAAQ,GACR,UAAU,GACV,cAAc,GACd,aAAa,GACb,OAAO,GACP,OAAO,GACP,OAAO,GACP,KAAK,GACL,UAAU,GACV,MAAM,GACN,SAAS,GACT,MAAM,GACN,UAAU,GACV,OAAO,CAAC;AAEZ,oBAAY,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,oBAAY,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,oBAAY,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,oBAAY,kBAAkB,GAAG;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB,CAAC;AAEF,oBAAY,cAAc,GAAG,oBAAoB,GAAG;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,kBAAkB,CAAC;CAC1C,CAAC"}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
export declare type SupportedEntityType = keyof EntityTypeMap;
|
|
7
|
-
export declare type Entity<T extends SupportedEntityType = SupportedEntityType> = BaseEntityProperties & {
|
|
8
|
-
[K in T]: EntityTypeMap[K];
|
|
9
|
-
};
|
|
1
|
+
import { DocumentEntity } from './document';
|
|
2
|
+
import { MessageEntity } from './message';
|
|
3
|
+
export { DocumentEntity, MessageEntity };
|
|
4
|
+
export declare type Entity = DocumentEntity | MessageEntity;
|
|
10
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/entities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/entities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAGzC,oBAAY,MAAM,GAAG,cAAc,GAAG,aAAa,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseEntityProperties } from '../common';
|
|
2
|
+
export declare type Attachment = {
|
|
3
|
+
url: string;
|
|
4
|
+
mimeType: string;
|
|
5
|
+
byteSize: number;
|
|
6
|
+
};
|
|
7
|
+
export declare type MessageAttributes = {
|
|
8
|
+
hidden?: boolean;
|
|
9
|
+
isPinned?: boolean;
|
|
10
|
+
attachments?: Attachment[];
|
|
11
|
+
lastActive?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare type MessageEntity = Omit<BaseEntityProperties, 'displayName'> & {
|
|
14
|
+
description: string;
|
|
15
|
+
containerKey: NonNullable<BaseEntityProperties['containerKey']>;
|
|
16
|
+
'atlassian:message': MessageAttributes;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/types/entities/message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD,oBAAY,UAAU,GAAG;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,oBAAY,iBAAiB,GAAG;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,oBAAY,aAAa,GAAG,IAAI,CAAC,oBAAoB,EAAE,aAAa,CAAC,GAAG;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,WAAW,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC,CAAC;IAChE,mBAAmB,EAAE,iBAAiB,CAAC;CACxC,CAAC"}
|
package/out/types/graph.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Result } from '@forge/api';
|
|
2
|
-
import { ForgeExtendedContext, GroupObject, RequestConfig,
|
|
2
|
+
import { ForgeExtendedContext, GroupObject, RequestConfig, BulkEntityRequest, BulkEntityResponse, BulkUsersRequest, BulkUsersResponse, DeleteUsersByExternalIdRequest, DeleteUsersByExternalIdResponse, GetUserByExternalIdRequest, GetUserByExternalIdResponse } from './';
|
|
3
3
|
export interface TeamWorkGraph {
|
|
4
|
+
setEntities(request: BulkEntityRequest): Promise<BulkEntityResponse>;
|
|
4
5
|
deleteEntity(context: ForgeExtendedContext, entityId: string): Promise<Result>;
|
|
5
|
-
setUser(context: ForgeExtendedContext, user: UserObject): Promise<Result>;
|
|
6
|
-
deleteUser(context: ForgeExtendedContext, userId: string): Promise<Result>;
|
|
7
6
|
setGroup(context: ForgeExtendedContext, group: GroupObject): Promise<Result>;
|
|
8
7
|
deleteGroup(context: ForgeExtendedContext, groupId: string): Promise<Result>;
|
|
9
8
|
fetchData(context: ForgeExtendedContext, requestConfig: RequestConfig, onResult: Function): Promise<Result>;
|
|
10
9
|
transformData(context: ForgeExtendedContext, data: any, transformMethod: Function): Promise<any>;
|
|
10
|
+
setUsers(request: BulkUsersRequest): Promise<BulkUsersResponse>;
|
|
11
|
+
deleteUsersByExternalId(request: DeleteUsersByExternalIdRequest): Promise<DeleteUsersByExternalIdResponse>;
|
|
12
|
+
getUserByExternalId(request: GetUserByExternalIdRequest): Promise<GetUserByExternalIdResponse>;
|
|
11
13
|
}
|
|
12
14
|
//# sourceMappingURL=graph.d.ts.map
|
package/out/types/graph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/types/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/types/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,8BAA8B,EAC9B,+BAA+B,EAC/B,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,IAAI,CAAC;AAEZ,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrE,YAAY,CAAC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/E,QAAQ,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,WAAW,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,SAAS,CAAC,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5G,aAAa,CAAC,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAGjG,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAChE,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;IAC3G,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;CAChG"}
|
package/out/types/index.d.ts
CHANGED
package/out/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AAGzB,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AAGzB,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,SAAS,CAAC;AAExB,cAAc,SAAS,CAAC"}
|
package/out/types/index.js
CHANGED
|
@@ -4,4 +4,5 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
tslib_1.__exportStar(require("./common"), exports);
|
|
5
5
|
tslib_1.__exportStar(require("./entities"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./requests"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./users"), exports);
|
|
7
8
|
tslib_1.__exportStar(require("./graph"), exports);
|
package/out/types/requests.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Entity, SupportedEntityType } from './entities';
|
|
1
|
+
import { Entity, UserPayload, User } from './';
|
|
3
2
|
export declare type BulkEntityRequest = {
|
|
4
|
-
|
|
5
|
-
entities: Array<{
|
|
6
|
-
entityType: SupportedEntityType;
|
|
7
|
-
} & Entity>;
|
|
3
|
+
entities: Array<Entity>;
|
|
8
4
|
};
|
|
9
5
|
export declare type BulkEntityResponse = {
|
|
10
6
|
success: boolean;
|
|
@@ -14,4 +10,34 @@ export declare type BulkEntityResponse = {
|
|
|
14
10
|
error?: string;
|
|
15
11
|
}>;
|
|
16
12
|
};
|
|
13
|
+
export declare type BulkUsersRequest = {
|
|
14
|
+
users: UserPayload[];
|
|
15
|
+
};
|
|
16
|
+
export declare type BulkUsersResponse = {
|
|
17
|
+
success: boolean;
|
|
18
|
+
results: Array<{
|
|
19
|
+
externalId: string;
|
|
20
|
+
success: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
export declare type DeleteUsersByExternalIdRequest = {
|
|
25
|
+
externalIds: string[];
|
|
26
|
+
};
|
|
27
|
+
export declare type DeleteUsersByExternalIdResponse = {
|
|
28
|
+
success: boolean;
|
|
29
|
+
results: Array<{
|
|
30
|
+
externalId: string;
|
|
31
|
+
success: boolean;
|
|
32
|
+
error?: string;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
export declare type GetUserByExternalIdRequest = {
|
|
36
|
+
externalId: string;
|
|
37
|
+
};
|
|
38
|
+
export declare type GetUserByExternalIdResponse = {
|
|
39
|
+
success: boolean;
|
|
40
|
+
user?: User;
|
|
41
|
+
error?: string;
|
|
42
|
+
};
|
|
17
43
|
//# sourceMappingURL=requests.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/types/requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/types/requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/C,oBAAY,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACzB,CAAC;AAEF,oBAAY,kBAAkB,GAAG;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ,CAAC;AAGF,oBAAY,gBAAgB,GAAG;IAC7B,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB,CAAC;AAEF,oBAAY,iBAAiB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ,CAAC;AAEF,oBAAY,8BAA8B,GAAG;IAC3C,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,oBAAY,+BAA+B,GAAG;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ,CAAC;AAEF,oBAAY,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,oBAAY,2BAA2B,GAAG;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare type UserName = {
|
|
2
|
+
formatted?: string;
|
|
3
|
+
familyName?: string;
|
|
4
|
+
givenName?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare type UserPhoto = {
|
|
7
|
+
value: string;
|
|
8
|
+
type: string;
|
|
9
|
+
};
|
|
10
|
+
export declare type UserEmail = {
|
|
11
|
+
value: string;
|
|
12
|
+
primary: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare type UserPhoneNumber = {
|
|
15
|
+
type?: string;
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
export declare type UserExtendedProfile = {
|
|
19
|
+
jobTitle?: string;
|
|
20
|
+
department?: string;
|
|
21
|
+
organization?: string;
|
|
22
|
+
location?: string;
|
|
23
|
+
phoneNumbers?: UserPhoneNumber[];
|
|
24
|
+
};
|
|
25
|
+
export declare type UserPayload = {
|
|
26
|
+
externalId: string;
|
|
27
|
+
userName?: string;
|
|
28
|
+
name?: UserName;
|
|
29
|
+
nickname?: string;
|
|
30
|
+
displayName?: string;
|
|
31
|
+
photos?: UserPhoto[];
|
|
32
|
+
emails?: UserEmail[];
|
|
33
|
+
extendedProfile?: UserExtendedProfile;
|
|
34
|
+
};
|
|
35
|
+
export declare type User = {
|
|
36
|
+
id: string;
|
|
37
|
+
externalId: string;
|
|
38
|
+
userName?: string;
|
|
39
|
+
name?: UserName;
|
|
40
|
+
nickname?: string;
|
|
41
|
+
displayName?: string;
|
|
42
|
+
photos?: UserPhoto[];
|
|
43
|
+
emails?: UserEmail[];
|
|
44
|
+
extendedProfile?: UserExtendedProfile;
|
|
45
|
+
meta?: {
|
|
46
|
+
resourceType: string;
|
|
47
|
+
created: string;
|
|
48
|
+
lastModified: string;
|
|
49
|
+
location: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=users.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/types/users.ts"],"names":[],"mappings":"AAGA,oBAAY,QAAQ,GAAG;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,oBAAY,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,oBAAY,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,oBAAY,eAAe,GAAG;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,oBAAY,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CAClC,CAAC;AAEF,oBAAY,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,mBAAmB,CAAC;CACvC,CAAC;AAGF,oBAAY,IAAI,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,IAAI,CAAC,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC"}
|