@forge/teamwork-graph 0.1.0-next.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.
package/LICENSE.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2025 Atlassian
2
+ Permission is hereby granted to use this software in accordance with the terms
3
+ and conditions outlined in the Atlassian Developer Terms, which can be found
4
+ at the following URL:
5
+ https://developer.atlassian.com/platform/marketplace/atlassian-developer-terms/
6
+ By using this software, you agree to comply with these terms and conditions.
7
+ If you do not agree with these terms, you are not permitted to use this software.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # Forge Graph Client
2
+
3
+ A client for interacting with the Forge Graph API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @forge/teamwork-graph
9
+ ```
10
+
11
+ ## Usage Examples
12
+
13
+ ### Document Entity
14
+
15
+ ```typescript
16
+ import { graph } from '@forge/teamwork-graph';
17
+ import type { EntityPayload, DocumentCategory } from '@forge/teamwork-graph';
18
+
19
+ const documentPayload: EntityPayload = {
20
+ // Required base fields
21
+ schemaVersion: '1.0',
22
+ id: 'doc-123',
23
+ updateSequenceNumber: Date.now(),
24
+ displayName: 'Project Requirements Doc',
25
+ url: 'https://example.com/docs/requirements',
26
+
27
+ // Optional base fields
28
+ description: 'Project requirements and specifications',
29
+ createdAt: new Date().toISOString(),
30
+ createdBy: {
31
+ accountId: 'acc-123',
32
+ email: 'creator@example.com'
33
+ },
34
+ lastUpdatedAt: new Date().toISOString(),
35
+ lastUpdatedBy: {
36
+ accountId: 'acc-456',
37
+ email: 'updater@example.com'
38
+ },
39
+
40
+ // Document ownership
41
+ owners: [
42
+ {
43
+ accountId: 'acc-123',
44
+ email: 'owner@example.com'
45
+ }
46
+ ],
47
+
48
+ // Document preview
49
+ thumbnail: {
50
+ externalUrl: 'https://example.com/thumbnail.png'
51
+ },
52
+
53
+ // Hierarchical relationships
54
+ parentKey: {
55
+ type: 'atlassian:document',
56
+ value: {
57
+ entityId: 'parent-folder-id'
58
+ }
59
+ },
60
+ containerKey: {
61
+ type: 'atlassian:space',
62
+ value: {
63
+ entityId: 'space-123'
64
+ }
65
+ },
66
+
67
+ // Access control
68
+ permissions: {
69
+ accessControls: [
70
+ {
71
+ principals: [
72
+ { type: 'USER', id: 'user-123' },
73
+ { type: 'GROUP', id: 'group-456' },
74
+ { type: 'EVERYONE' }
75
+ ]
76
+ }
77
+ ],
78
+ smartLinkViewedBy: [
79
+ {
80
+ principalUser: {
81
+ type: 'USER',
82
+ id: 'user-789'
83
+ }
84
+ }
85
+ ]
86
+ },
87
+
88
+ // Relationships
89
+ associations: {
90
+ set: [
91
+ {
92
+ associationType: 'issueIdOrKeys',
93
+ values: ['PROJ-123', 'PROJ-456']
94
+ }
95
+ ]
96
+ },
97
+
98
+ // Document-specific attributes
99
+ 'atlassian:document': {
100
+ type: {
101
+ category: 'document',
102
+ mimeType: 'text/plain',
103
+ iconUrl: 'https://example.com/icon.png',
104
+ fileExtension: 'txt'
105
+ },
106
+ content: {
107
+ mimeType: 'text/plain',
108
+ text: 'Document content...',
109
+ // binary: 'base64EncodedContent...' // Alternative to text
110
+ },
111
+ byteSize: 1234,
112
+ exportLinks: [
113
+ {
114
+ mimeType: 'application/pdf',
115
+ url: 'https://example.com/export/pdf'
116
+ }
117
+ ],
118
+ collaborators: [
119
+ { email: 'collaborator1@example.com' },
120
+ { email: 'collaborator2@example.com' }
121
+ ]
122
+ }
123
+ };
124
+
125
+ // Send the document to the API
126
+ await graph.setEntity(documentPayload);
127
+ ```
128
+
129
+ ### Delete Operations
130
+
131
+ ```typescript
132
+ // Delete an entity
133
+ await graph.deleteEntity('entity-123', {
134
+ target: 'TargetContainer',
135
+ token: 'auth-token'
136
+ });
137
+
138
+ // Delete a user
139
+ await graph.deleteUser('user-123');
140
+
141
+ // Delete a group
142
+ await graph.deleteGroup('group-123');
143
+ ```
144
+
145
+ ## Error Handling
146
+
147
+ The client throws `ForgeGraphAPIError` for API errors. Error types include:
148
+
149
+ ```typescript
150
+ import { errorCodes } from '@forge/teamwork-graph';
151
+
152
+ // Available error codes
153
+ errorCodes.INVALID_REQUEST_BODY // 400 Bad Request
154
+ errorCodes.INSUFFICIENT_SCOPE // 403 Forbidden
155
+ errorCodes.TOO_MANY_REQUESTS // 429 Rate Limit
156
+ errorCodes.UNKNOWN_ERROR // Other errors
157
+
158
+ try {
159
+ await graph.setEntity(/* ... */);
160
+ } catch (error) {
161
+ if (error instanceof ForgeGraphAPIError) {
162
+ console.error(error.code, error.message);
163
+ }
164
+ }
165
+ ```
166
+
167
+ ## Available Types
168
+
169
+ ```typescript
170
+ import type {
171
+ // Entity-related
172
+ EntityPayload,
173
+ DocumentAttributes,
174
+ DocumentCategory,
175
+ DocumentType,
176
+ DocumentContent,
177
+ ExportLink,
178
+
179
+ // User and Group
180
+ UserObject,
181
+ GroupPayload,
182
+
183
+ // Common types
184
+ Permissions,
185
+ AccessControl,
186
+ Principal,
187
+ Thumbnail,
188
+
189
+ // Relationships
190
+ ParentKeyObject,
191
+ ContainerKeyObject,
192
+ Associations,
193
+ AssociationObject,
194
+
195
+ // Operations
196
+ DeleteContext
197
+ } from '@forge/teamwork-graph';
198
+ ```
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=error-handling.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handling.test.d.ts","sourceRoot":"","sources":["../../src/__test__/error-handling.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_fetch_1 = require("node-fetch");
4
+ const error_handling_1 = require("../error-handling");
5
+ const errors_1 = require("../utils/errors");
6
+ describe('checkResponseError in @forge/teamwork-graph', () => {
7
+ const traceId = 'trace-id';
8
+ describe('when response has JSON body', () => {
9
+ const baseErrorShape = {
10
+ responseDetails: {
11
+ status: 400,
12
+ statusText: 'Bad Request',
13
+ traceId
14
+ }
15
+ };
16
+ it('should use provided code and message', async () => {
17
+ const mockResponse = new node_fetch_1.Response(JSON.stringify({ code: 'CUSTOM_ERROR', message: 'Custom error message' }), {
18
+ status: 400,
19
+ statusText: 'Bad Request',
20
+ headers: { 'x-trace-id': traceId }
21
+ });
22
+ await expect((0, error_handling_1.handleResponseError)(mockResponse)).rejects.toMatchObject({
23
+ ...baseErrorShape,
24
+ code: 'CUSTOM_ERROR',
25
+ message: 'Custom error message'
26
+ });
27
+ });
28
+ it('should use status-based code when no code provided', async () => {
29
+ const mockResponse = new node_fetch_1.Response(JSON.stringify({ message: 'Error message' }), {
30
+ status: 400,
31
+ statusText: 'Bad Request',
32
+ headers: { 'x-trace-id': traceId }
33
+ });
34
+ await expect((0, error_handling_1.handleResponseError)(mockResponse)).rejects.toMatchObject({
35
+ ...baseErrorShape,
36
+ code: errors_1.errorCodes.INVALID_REQUEST_BODY,
37
+ message: 'Error message'
38
+ });
39
+ });
40
+ it('should use default message when no message provided', async () => {
41
+ const mockResponse = new node_fetch_1.Response(JSON.stringify({ code: 'CUSTOM_ERROR' }), {
42
+ status: 400,
43
+ statusText: 'Bad Request',
44
+ headers: { 'x-trace-id': traceId }
45
+ });
46
+ await expect((0, error_handling_1.handleResponseError)(mockResponse, 'Default message')).rejects.toMatchObject({
47
+ ...baseErrorShape,
48
+ code: 'CUSTOM_ERROR',
49
+ message: 'Default message'
50
+ });
51
+ });
52
+ it('should include context if provided', async () => {
53
+ const mockResponse = new node_fetch_1.Response(JSON.stringify({
54
+ code: 'CUSTOM_ERROR',
55
+ message: 'Error message',
56
+ context: { details: 'Additional info' }
57
+ }), {
58
+ status: 400,
59
+ statusText: 'Bad Request',
60
+ headers: { 'x-trace-id': traceId }
61
+ });
62
+ await expect((0, error_handling_1.handleResponseError)(mockResponse)).rejects.toMatchObject({
63
+ ...baseErrorShape,
64
+ code: 'CUSTOM_ERROR',
65
+ message: 'Error message',
66
+ context: { details: 'Additional info' }
67
+ });
68
+ });
69
+ });
70
+ describe('when response has invalid or no body', () => {
71
+ const serverErrorShape = {
72
+ responseDetails: {
73
+ status: 500,
74
+ statusText: 'Internal Server Error',
75
+ traceId
76
+ }
77
+ };
78
+ it('should handle invalid JSON', async () => {
79
+ const mockResponse = new node_fetch_1.Response('Invalid JSON', {
80
+ status: 500,
81
+ statusText: 'Internal Server Error',
82
+ headers: { 'x-trace-id': traceId }
83
+ });
84
+ await expect((0, error_handling_1.handleResponseError)(mockResponse, 'Default message')).rejects.toMatchObject({
85
+ ...serverErrorShape,
86
+ code: errors_1.errorCodes.UNKNOWN_ERROR,
87
+ message: 'Default message',
88
+ context: { responseText: 'Invalid JSON' }
89
+ });
90
+ });
91
+ it('should handle empty response', async () => {
92
+ const mockResponse = new node_fetch_1.Response('', {
93
+ status: 500,
94
+ statusText: 'Internal Server Error',
95
+ headers: { 'x-trace-id': traceId }
96
+ });
97
+ await expect((0, error_handling_1.handleResponseError)(mockResponse)).rejects.toMatchObject({
98
+ ...serverErrorShape,
99
+ code: errors_1.errorCodes.UNKNOWN_ERROR,
100
+ message: 'Failed to parse error response',
101
+ context: { responseText: '' }
102
+ });
103
+ });
104
+ });
105
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=graph.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.test.d.ts","sourceRoot":"","sources":["../../src/__test__/graph.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const api_1 = require("@forge/api");
4
+ const graph_1 = require("../graph");
5
+ const errors_1 = require("../utils/errors");
6
+ jest.mock('@forge/api');
7
+ describe('Teamwork Graph Client', () => {
8
+ let graphClient;
9
+ let mockFetch;
10
+ beforeEach(() => {
11
+ graphClient = new graph_1.TeamWorkGraphClient();
12
+ mockFetch = jest.fn();
13
+ api_1.__fetchProduct.mockReturnValue(mockFetch);
14
+ jest.clearAllMocks();
15
+ });
16
+ describe('setEntity', () => {
17
+ const entityPayload = {
18
+ id: 'test-entity-123',
19
+ type: 'test-type',
20
+ schemaVersion: '1',
21
+ updateSequenceNumber: 1,
22
+ displayName: 'Test Entity',
23
+ url: 'https://example.com/entity/123',
24
+ createdAt: new Date().toISOString(),
25
+ properties: { name: 'Test Entity' }
26
+ };
27
+ it('should successfully post entity data', async () => {
28
+ const expectedResponse = { success: true, entity: entityPayload };
29
+ mockFetch.mockResolvedValueOnce({
30
+ ok: true,
31
+ json: () => Promise.resolve(expectedResponse)
32
+ });
33
+ const result = await graphClient.setEntity(entityPayload);
34
+ expect(mockFetch).toHaveBeenCalledWith('/graph/connector/api/v1/entity', {
35
+ method: 'POST',
36
+ body: JSON.stringify(entityPayload),
37
+ redirect: 'follow',
38
+ headers: { 'Content-Type': 'application/json' }
39
+ });
40
+ expect(result).toEqual(expectedResponse);
41
+ });
42
+ it('should throw ForgeGraphAPIError when request fails', async () => {
43
+ const errorResponse = {
44
+ ok: false,
45
+ status: 400,
46
+ statusText: 'Bad Request',
47
+ headers: {
48
+ get: () => null
49
+ },
50
+ text: () => Promise.resolve(JSON.stringify({
51
+ code: errors_1.errorCodes.INVALID_REQUEST_BODY,
52
+ message: 'Invalid entity payload'
53
+ }))
54
+ };
55
+ mockFetch.mockResolvedValueOnce(errorResponse);
56
+ await expect(graphClient.setEntity(entityPayload)).rejects.toThrow(errors_1.ForgeGraphAPIError);
57
+ });
58
+ });
59
+ });
@@ -0,0 +1,3 @@
1
+ import { APIResponse } from '@forge/api';
2
+ export declare function handleResponseError(response: APIResponse, defaultMessage?: string): Promise<void>;
3
+ //# sourceMappingURL=error-handling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../src/error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAUzC,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBvG"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleResponseError = void 0;
4
+ const errors_1 = require("./utils/errors");
5
+ async function handleResponseError(response, defaultMessage) {
6
+ const details = {
7
+ status: response.status,
8
+ statusText: response.statusText,
9
+ traceId: response.headers.get('x-b3-traceid') || response.headers.get('x-trace-id')
10
+ };
11
+ const responseText = await response.text();
12
+ try {
13
+ const body = JSON.parse(responseText);
14
+ const code = body.code || getErrorCodeFromStatus(response.status);
15
+ const message = body.message || defaultMessage || 'Unknown error occurred';
16
+ throw new errors_1.ForgeGraphAPIError(details, code, message, body.context);
17
+ }
18
+ catch (error) {
19
+ if (error instanceof errors_1.ForgeGraphAPIError)
20
+ throw error;
21
+ throw new errors_1.ForgeGraphAPIError(details, errors_1.errorCodes.UNKNOWN_ERROR, defaultMessage || 'Failed to parse error response', { responseText });
22
+ }
23
+ }
24
+ exports.handleResponseError = handleResponseError;
25
+ function getErrorCodeFromStatus(status) {
26
+ switch (status) {
27
+ case 400:
28
+ return errors_1.errorCodes.INVALID_REQUEST_BODY;
29
+ case 403:
30
+ return errors_1.errorCodes.INSUFFICIENT_SCOPE;
31
+ case 429:
32
+ return errors_1.errorCodes.TOO_MANY_REQUESTS;
33
+ default:
34
+ return errors_1.errorCodes.UNKNOWN_ERROR;
35
+ }
36
+ }
package/out/graph.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { Result } from '@forge/api';
2
+ import { EntityPayload, UserObject, GroupObject, DeleteContext, TeamWorkGraph } from './utils/types';
3
+ export declare class TeamWorkGraphClient implements TeamWorkGraph {
4
+ setEntity: (entity: EntityPayload) => Promise<Result>;
5
+ deleteEntity: (entityId: string, context: DeleteContext) => Promise<Result>;
6
+ setUser: (user: UserObject) => Promise<Result>;
7
+ deleteUser: (userId: string) => Promise<Result>;
8
+ setGroup: (group: GroupObject) => Promise<Result>;
9
+ deleteGroup: (groupId: string) => Promise<Result>;
10
+ private sendPostRequest;
11
+ private sendDeleteRequest;
12
+ private sendRequest;
13
+ }
14
+ export declare const teamworkgraph: TeamWorkGraphClient;
15
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,MAAM,EAAe,MAAM,YAAY,CAAC;AAE9E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGrG,qBAAa,mBAAoB,YAAW,aAAa;IACvD,SAAS,WAAkB,aAAa,KAAG,QAAQ,MAAM,CAAC,CAExD;IAEF,YAAY,aAAoB,MAAM,WAAW,aAAa,KAAG,QAAQ,MAAM,CAAC,CAE9E;IAEF,OAAO,SAAgB,UAAU,KAAG,QAAQ,MAAM,CAAC,CAEjD;IAEF,UAAU,WAAkB,MAAM,KAAG,QAAQ,MAAM,CAAC,CAElD;IAEF,QAAQ,UAAiB,WAAW,KAAG,QAAQ,MAAM,CAAC,CAEpD;IAEF,WAAW,YAAmB,MAAM,KAAG,QAAQ,MAAM,CAAC,CAEpD;YAEY,eAAe;YAaf,iBAAiB;YAajB,WAAW;CAY1B;AAED,eAAO,MAAM,aAAa,qBAA4B,CAAC"}
package/out/graph.js ADDED
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.teamworkgraph = exports.TeamWorkGraphClient = void 0;
4
+ const api_1 = require("@forge/api");
5
+ const error_handling_1 = require("./error-handling");
6
+ const starGateBase = '/graph/connector';
7
+ class TeamWorkGraphClient {
8
+ setEntity = async (entity) => {
9
+ return this.sendPostRequest('/api/v1/entity', entity);
10
+ };
11
+ deleteEntity = async (entityId, context) => {
12
+ return this.sendDeleteRequest('/api/v1/entity', { id: entityId, context });
13
+ };
14
+ setUser = async (user) => {
15
+ return this.sendPostRequest('/api/v1/user', user);
16
+ };
17
+ deleteUser = async (userId) => {
18
+ return this.sendDeleteRequest('/api/v1/user', { id: userId });
19
+ };
20
+ setGroup = async (group) => {
21
+ return this.sendPostRequest('/api/v1/group', group);
22
+ };
23
+ deleteGroup = async (groupId) => {
24
+ return this.sendDeleteRequest('/api/v1/group', { id: groupId });
25
+ };
26
+ async sendPostRequest(path, body) {
27
+ const response = await this.sendRequest(path, {
28
+ method: 'POST',
29
+ body: JSON.stringify(body)
30
+ });
31
+ if (!response.ok) {
32
+ await (0, error_handling_1.handleResponseError)(response, `Error posting to ${path}`);
33
+ }
34
+ return response.json();
35
+ }
36
+ async sendDeleteRequest(path, body) {
37
+ const response = await this.sendRequest(path, {
38
+ method: 'DELETE',
39
+ body: JSON.stringify(body)
40
+ });
41
+ if (!response.ok) {
42
+ await (0, error_handling_1.handleResponseError)(response, `Error deleting from ${path}`);
43
+ }
44
+ return response.json();
45
+ }
46
+ async sendRequest(path, options) {
47
+ const reqPath = starGateBase + path;
48
+ const response = await (0, api_1.__fetchProduct)({ provider: 'app', remote: 'stargate' })(reqPath, {
49
+ ...options,
50
+ redirect: 'follow',
51
+ headers: {
52
+ ...options?.headers,
53
+ 'Content-Type': 'application/json'
54
+ }
55
+ });
56
+ return response;
57
+ }
58
+ }
59
+ exports.TeamWorkGraphClient = TeamWorkGraphClient;
60
+ exports.teamworkgraph = new TeamWorkGraphClient();
package/out/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { teamworkgraph } from './graph';
2
+ import { errorCodes, ForgeGraphAPIError } from './utils/errors';
3
+ export { errorCodes, teamworkgraph as graph, ForgeGraphAPIError };
4
+ export default teamworkgraph;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,UAAU,EAAE,aAAa,IAAI,KAAK,EAAE,kBAAkB,EAAE,CAAC;AAElE,eAAe,aAAa,CAAC"}
package/out/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ForgeGraphAPIError = exports.graph = exports.errorCodes = void 0;
4
+ const graph_1 = require("./graph");
5
+ Object.defineProperty(exports, "graph", { enumerable: true, get: function () { return graph_1.teamworkgraph; } });
6
+ const errors_1 = require("./utils/errors");
7
+ Object.defineProperty(exports, "errorCodes", { enumerable: true, get: function () { return errors_1.errorCodes; } });
8
+ Object.defineProperty(exports, "ForgeGraphAPIError", { enumerable: true, get: function () { return errors_1.ForgeGraphAPIError; } });
9
+ exports.default = graph_1.teamworkgraph;
@@ -0,0 +1,18 @@
1
+ export declare const errorCodes: {
2
+ readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
3
+ readonly INVALID_REQUEST_BODY: "INVALID_REQUEST_BODY";
4
+ readonly INSUFFICIENT_SCOPE: "INSUFFICIENT_SCOPE";
5
+ readonly TOO_MANY_REQUESTS: "TOO_MANY_REQUESTS";
6
+ };
7
+ export interface APIErrorResponseDetails {
8
+ status: number;
9
+ statusText: string;
10
+ traceId?: string | null;
11
+ }
12
+ export declare class ForgeGraphAPIError extends Error {
13
+ readonly responseDetails: APIErrorResponseDetails;
14
+ readonly code: string;
15
+ readonly context?: Record<string, unknown> | undefined;
16
+ constructor(responseDetails: APIErrorResponseDetails, code: string, message: string, context?: Record<string, unknown> | undefined);
17
+ }
18
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AASX,MAAM,WAAW,uBAAuB;IAEtC,MAAM,EAAE,MAAM,CAAC;IAGf,UAAU,EAAE,MAAM,CAAC;IAGnB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAMD,qBAAa,kBAAmB,SAAQ,KAAK;aAEzB,eAAe,EAAE,uBAAuB;aACxC,IAAI,EAAE,MAAM;aAEZ,OAAO,CAAC;gBAHR,eAAe,EAAE,uBAAuB,EACxC,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,OAAO,CAAC,qCAAyB;CAKpD"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ForgeGraphAPIError = exports.errorCodes = void 0;
4
+ exports.errorCodes = {
5
+ UNKNOWN_ERROR: 'UNKNOWN_ERROR',
6
+ INVALID_REQUEST_BODY: 'INVALID_REQUEST_BODY',
7
+ INSUFFICIENT_SCOPE: 'INSUFFICIENT_SCOPE',
8
+ TOO_MANY_REQUESTS: 'TOO_MANY_REQUESTS'
9
+ };
10
+ class ForgeGraphAPIError extends Error {
11
+ responseDetails;
12
+ code;
13
+ context;
14
+ constructor(responseDetails, code, message, context) {
15
+ super(message);
16
+ this.responseDetails = responseDetails;
17
+ this.code = code;
18
+ this.context = context;
19
+ this.name = 'ForgeGraphAPIError';
20
+ }
21
+ }
22
+ exports.ForgeGraphAPIError = ForgeGraphAPIError;
@@ -0,0 +1,110 @@
1
+ import { Result } from '@forge/api';
2
+ export declare type UserObject = {
3
+ accountId?: string;
4
+ id?: string;
5
+ email: string;
6
+ externalId?: string;
7
+ };
8
+ export declare type Thumbnail = {
9
+ externalUrl: string;
10
+ };
11
+ export declare type Principal = {
12
+ type: 'USER' | 'GROUP' | 'EVERYONE' | 'ATLASSIAN_WORKSPACE' | 'CONTAINER';
13
+ id?: string | null;
14
+ };
15
+ export declare type AccessControl = {
16
+ principals: Principal[];
17
+ };
18
+ export declare type SmartLinkViewedByUser = {
19
+ principalUser: Principal;
20
+ };
21
+ export declare type Permissions = {
22
+ accessControls?: AccessControl[];
23
+ smartLinkViewedBy?: SmartLinkViewedByUser[];
24
+ };
25
+ export declare type DocumentCategory = 'folder' | 'document' | 'presentation' | 'spreadsheet' | 'image' | 'audio' | 'video' | 'pdf' | 'shortcut' | 'code' | 'archive' | 'form' | 'web-page' | 'other';
26
+ export declare type DocumentType = {
27
+ category?: DocumentCategory;
28
+ mimeType?: string;
29
+ iconUrl?: string;
30
+ fileExtension?: string;
31
+ };
32
+ export declare type DocumentContent = {
33
+ mimeType?: string;
34
+ text?: string;
35
+ binary?: string;
36
+ };
37
+ export declare type ExportLink = {
38
+ mimeType: string;
39
+ url: string;
40
+ };
41
+ export declare type DocumentAttributes = {
42
+ collaborators?: Partial<UserObject>[];
43
+ type: DocumentType;
44
+ content: DocumentContent;
45
+ byteSize?: number;
46
+ exportLinks?: ExportLink[];
47
+ };
48
+ export declare type ContainerKeyObject = {
49
+ type: string;
50
+ value: {
51
+ entityId: string;
52
+ };
53
+ };
54
+ export declare type ParentKeyObject = {
55
+ type: string;
56
+ value: {
57
+ entityId: string;
58
+ };
59
+ };
60
+ export declare type EntityPayload = {
61
+ schemaVersion: string;
62
+ id: string;
63
+ updateSequenceNumber: number;
64
+ displayName: string;
65
+ description?: string;
66
+ url: string;
67
+ createdAt: string;
68
+ createdBy?: Partial<UserObject>;
69
+ lastUpdatedAt?: string;
70
+ lastUpdatedBy?: Partial<UserObject>;
71
+ owners?: Partial<UserObject>[];
72
+ thumbnail?: Thumbnail;
73
+ parentKey?: ParentKeyObject | string;
74
+ containerKey?: ContainerKeyObject | string;
75
+ permissions?: Permissions;
76
+ associations?: Associations;
77
+ 'atlassian:document'?: DocumentAttributes;
78
+ };
79
+ export declare type GroupObject = {
80
+ id?: string;
81
+ email?: string;
82
+ name?: string;
83
+ description?: string;
84
+ adminCreated?: boolean;
85
+ directMembersCount?: string;
86
+ kind?: string;
87
+ etag?: string;
88
+ aliases?: string[];
89
+ nonEditableAliases?: string[];
90
+ };
91
+ export declare type DeleteContext = {
92
+ target: string;
93
+ token: string;
94
+ };
95
+ export declare type AssociationObject = {
96
+ associationType: string;
97
+ values: string[];
98
+ };
99
+ export declare type Associations = {
100
+ set: AssociationObject[];
101
+ };
102
+ export interface TeamWorkGraph {
103
+ setEntity(entity: EntityPayload): Promise<Result>;
104
+ deleteEntity(entityId: string, context: DeleteContext): Promise<Result>;
105
+ setUser(user: UserObject): Promise<Result>;
106
+ deleteUser(userId: string): Promise<Result>;
107
+ setGroup(group: GroupObject): Promise<Result>;
108
+ deleteGroup(groupId: string): Promise<Result>;
109
+ }
110
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGpC,oBAAY,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,oBAAY,SAAS,GAAG;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,oBAAY,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,qBAAqB,GAAG,WAAW,CAAC;IAC1E,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB,CAAC;AAEF,oBAAY,aAAa,GAAG;IAC1B,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAEF,oBAAY,qBAAqB,GAAG;IAClC,aAAa,EAAE,SAAS,CAAC;CAC1B,CAAC;AAEF,oBAAY,WAAW,GAAG;IACxB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAC7C,CAAC;AAGF,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,kBAAkB,GAAG;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;IACtC,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,CAAC;AAGF,oBAAY,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,oBAAY,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AAGF,oBAAY,aAAa,GAAG;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IACrC,YAAY,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAAC;IAC3C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;CAC3C,CAAC;AAEF,oBAAY,WAAW,GAAG;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,CAAC;AAGF,oBAAY,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,oBAAY,iBAAiB,GAAG;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,GAAG,EAAE,iBAAiB,EAAE,CAAC;CAC1B,CAAC;AAGF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxE,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/C"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@forge/teamwork-graph",
3
+ "version": "0.1.0-next.0",
4
+ "description": "Forge TeamworkGraph SDK",
5
+ "author": "Atlassian",
6
+ "license": "UNLICENSED",
7
+ "main": "out/index.js",
8
+ "types": "out/index.d.ts",
9
+ "files": [
10
+ "out"
11
+ ],
12
+ "scripts": {
13
+ "build": "yarn run clean && yarn run compile",
14
+ "clean": "rm -rf ./out && rm -f tsconfig.tsbuildinfo",
15
+ "compile": "tsc -b -v"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "14.18.63",
19
+ "@types/node-fetch": "^2.6.11",
20
+ "expect-type": "^0.17.3",
21
+ "node-fetch": "2.7.0",
22
+ "jest-when": "^3.6.0"
23
+ },
24
+ "dependencies": {
25
+ "@forge/api": "^5.1.0-next.2"
26
+ }
27
+ }