@forge/os 2.0.5-next.0-experimental-5ae8c1c → 2.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.
@@ -102,7 +102,7 @@ describe('ObjectStoreClient', () => {
102
102
  });
103
103
  });
104
104
  describe('get', () => {
105
- it('should send a GET request with the correct headers and b', async () => {
105
+ it('should send a POST request with the correct headers and body', async () => {
106
106
  const mockResponse = {
107
107
  ok: true,
108
108
  status: 200,
@@ -111,12 +111,16 @@ describe('ObjectStoreClient', () => {
111
111
  mockFetch.mockResolvedValue(mockResponse);
112
112
  const objectId = '1';
113
113
  const response = await osClient.get(objectId);
114
- expect(mockFetch).toHaveBeenCalledWith('api/v1/objects/1', {
115
- method: 'GET',
114
+ expect(mockFetch).toHaveBeenCalledWith('api/v1/metadata', {
115
+ method: 'POST',
116
116
  redirect: 'follow',
117
117
  headers: {
118
- Accept: 'application/json'
119
- }
118
+ Accept: 'application/json',
119
+ 'Content-Type': 'application/json'
120
+ },
121
+ body: JSON.stringify({
122
+ key: objectId
123
+ })
120
124
  });
121
125
  expect(mockResponse.status).toBe(200);
122
126
  expect(mockResponse.text).toHaveBeenCalled();
@@ -124,17 +128,19 @@ describe('ObjectStoreClient', () => {
124
128
  });
125
129
  });
126
130
  describe('delete', () => {
127
- it('should send a DELETE request with the correct headers', async () => {
131
+ it('should send a POST request with the correct headers and body', async () => {
128
132
  const mockResponse = { ok: true, status: 204, text: createMockBody(null) };
129
133
  mockFetch.mockResolvedValue(mockResponse);
130
134
  const objectId = '1';
131
135
  await osClient.delete(objectId);
132
- expect(mockFetch).toHaveBeenCalledWith('api/v1/objects/1', {
133
- method: 'DELETE',
136
+ expect(mockFetch).toHaveBeenCalledWith('api/v1/delete', {
137
+ method: 'POST',
134
138
  redirect: 'follow',
135
139
  headers: {
136
- Accept: 'application/json'
137
- }
140
+ Accept: 'application/json',
141
+ 'Content-Type': 'application/json'
142
+ },
143
+ body: JSON.stringify({ key: objectId })
138
144
  });
139
145
  expect(mockResponse.status).toBe(204);
140
146
  expect(mockResponse.text).toHaveBeenCalled();
@@ -162,4 +168,60 @@ describe('ObjectStoreClient', () => {
162
168
  expect(response?.toString('utf-8')).toEqual('I shall be downloaded as buffer!');
163
169
  });
164
170
  });
171
+ describe('createUploadUrl', () => {
172
+ it('should send a POST request with the correct headers and body, and return a URL', async () => {
173
+ const mockResponse = {
174
+ ok: true,
175
+ status: 200,
176
+ text: createMockBody(JSON.stringify({ url: 'upload-url' }))
177
+ };
178
+ mockFetch.mockResolvedValue(mockResponse);
179
+ const objectId = '1';
180
+ const fileProperties = {
181
+ key: objectId,
182
+ length: 123,
183
+ checksum: 'abc123',
184
+ checksumType: 'SHA1',
185
+ ttlSeconds: 3600,
186
+ overwrite: true
187
+ };
188
+ const response = await osClient.createUploadUrl(fileProperties);
189
+ expect(mockFetch).toHaveBeenCalledWith('api/v1/upload-url', {
190
+ method: 'POST',
191
+ redirect: 'follow',
192
+ headers: {
193
+ Accept: 'application/json',
194
+ 'Content-Type': 'application/json'
195
+ },
196
+ body: JSON.stringify(fileProperties)
197
+ });
198
+ expect(mockResponse.status).toBe(200);
199
+ expect(mockResponse.text).toHaveBeenCalled();
200
+ expect(response).toEqual({ url: 'upload-url' });
201
+ });
202
+ });
203
+ describe('createDownloadUrl', () => {
204
+ it('should send a POST request with the correct headers and body, and return a URL', async () => {
205
+ const mockResponse = {
206
+ ok: true,
207
+ status: 200,
208
+ text: createMockBody(JSON.stringify({ url: 'download-url' }))
209
+ };
210
+ mockFetch.mockResolvedValue(mockResponse);
211
+ const objectId = '1';
212
+ const response = await osClient.createDownloadUrl(objectId);
213
+ expect(mockFetch).toHaveBeenCalledWith('api/v1/download-url', {
214
+ method: 'POST',
215
+ redirect: 'follow',
216
+ headers: {
217
+ Accept: 'application/json',
218
+ 'Content-Type': 'application/json'
219
+ },
220
+ body: JSON.stringify({ key: objectId })
221
+ });
222
+ expect(mockResponse.status).toBe(200);
223
+ expect(mockResponse.text).toHaveBeenCalled();
224
+ expect(response).toEqual({ url: 'download-url' });
225
+ });
226
+ });
165
227
  });
package/out/os.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { ObjectReference } from './types';
3
+ import { ObjectReference, PresignedUrlResponse, UploadUrlBody } from './types';
4
4
  export declare class ObjectStoreClient {
5
5
  private sendRequest;
6
6
  private requestJson;
@@ -8,6 +8,8 @@ export declare class ObjectStoreClient {
8
8
  get(objectId: string): Promise<ObjectReference | undefined>;
9
9
  delete(objectId: string): Promise<void>;
10
10
  download(objectId: string): Promise<Buffer | undefined>;
11
+ createUploadUrl(body: UploadUrlBody): Promise<PresignedUrlResponse | undefined>;
12
+ createDownloadUrl(objectId: string): Promise<PresignedUrlResponse | undefined>;
11
13
  }
12
14
  export declare const os: ObjectStoreClient;
13
15
  //# sourceMappingURL=os.d.ts.map
package/out/os.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"os.d.ts","sourceRoot":"","sources":["../src/os.ts"],"names":[],"mappings":";;AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ1C,qBAAa,iBAAiB;YAEd,WAAW;YASX,WAAW;IAqCZ,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAahG,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAU3D,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAerE;AAED,eAAO,MAAM,EAAE,mBAA0B,CAAC"}
1
+ {"version":3,"file":"os.d.ts","sourceRoot":"","sources":["../src/os.ts"],"names":[],"mappings":";;AAGA,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAS/E,qBAAa,iBAAiB;YAEd,WAAW;YASX,WAAW;IAqCZ,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAahG,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAgB3D,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAavC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAoBvD,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAgB/E,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;CAW5F;AAED,eAAO,MAAM,EAAE,mBAA0B,CAAC"}
package/out/os.js CHANGED
@@ -9,6 +9,7 @@ var ValidHttpMethod;
9
9
  ValidHttpMethod["PUT"] = "PUT";
10
10
  ValidHttpMethod["GET"] = "GET";
11
11
  ValidHttpMethod["DELETE"] = "DELETE";
12
+ ValidHttpMethod["POST"] = "POST";
12
13
  })(ValidHttpMethod || (ValidHttpMethod = {}));
13
14
  class ObjectStoreClient {
14
15
  async sendRequest(path, options) {
@@ -48,12 +49,13 @@ class ObjectStoreClient {
48
49
  return this.requestJson(ValidHttpMethod.PUT, `api/v1/objects/${objectId}`, headers, buffer);
49
50
  }
50
51
  async get(objectId) {
51
- return this.requestJson(ValidHttpMethod.GET, `api/v1/objects/${objectId}`, {
52
- Accept: 'application/json'
53
- });
52
+ return this.requestJson(ValidHttpMethod.POST, `api/v1/metadata`, {
53
+ Accept: 'application/json',
54
+ 'Content-Type': 'application/json'
55
+ }, JSON.stringify({ key: objectId }));
54
56
  }
55
57
  async delete(objectId) {
56
- await this.requestJson(ValidHttpMethod.DELETE, `api/v1/objects/${objectId}`, { Accept: 'application/json' });
58
+ return this.requestJson(ValidHttpMethod.POST, `api/v1/delete`, { Accept: 'application/json', 'Content-Type': 'application/json' }, JSON.stringify({ key: objectId }));
57
59
  }
58
60
  async download(objectId) {
59
61
  const response = await this.sendRequest(`api/v1/objects/${objectId}/download`, {
@@ -68,6 +70,18 @@ class ObjectStoreClient {
68
70
  await (0, error_handling_1.checkResponseError)(response);
69
71
  return await response.arrayBuffer().then((buffer) => Buffer.from(buffer));
70
72
  }
73
+ async createUploadUrl(body) {
74
+ return this.requestJson(ValidHttpMethod.POST, 'api/v1/upload-url', {
75
+ Accept: 'application/json',
76
+ 'Content-Type': 'application/json'
77
+ }, JSON.stringify(body));
78
+ }
79
+ async createDownloadUrl(objectId) {
80
+ return this.requestJson(ValidHttpMethod.POST, `api/v1/download-url`, {
81
+ Accept: 'application/json',
82
+ 'Content-Type': 'application/json'
83
+ }, JSON.stringify({ key: objectId }));
84
+ }
71
85
  }
72
86
  exports.ObjectStoreClient = ObjectStoreClient;
73
87
  exports.os = new ObjectStoreClient();
package/out/types.d.ts CHANGED
@@ -5,4 +5,15 @@ export interface ObjectReference {
5
5
  createdAt?: string;
6
6
  currentVersion?: string;
7
7
  }
8
+ export interface UploadUrlBody {
9
+ key: string;
10
+ length: number;
11
+ checksum: string;
12
+ checksumType: 'SHA1' | 'SHA256' | 'CRC32' | 'CRC32C';
13
+ ttlSeconds?: number;
14
+ overwrite?: boolean;
15
+ }
16
+ export interface PresignedUrlResponse {
17
+ url: string;
18
+ }
8
19
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;CACb"}
@@ -96,7 +96,7 @@ describe('error-handling', () => {
96
96
  }, {
97
97
  code: errorCodes_1.errorCodes.UNKNOWN_ERROR,
98
98
  context: { responseText: '' },
99
- message: 'Unexpected error in Forge SQL API request'
99
+ message: 'Unexpected error in Forge OS API request'
100
100
  }));
101
101
  });
102
102
  it("returns UNKNOWN_ERROR if there is a JSON body that isn't a forge error", async () => {
@@ -113,7 +113,7 @@ describe('error-handling', () => {
113
113
  }, {
114
114
  code: errorCodes_1.errorCodes.UNKNOWN_ERROR,
115
115
  context: { responseText: body },
116
- message: 'Unexpected error in Forge SQL API request'
116
+ message: 'Unexpected error in Forge OS API request'
117
117
  }));
118
118
  });
119
119
  it('returns RATE_LIMIT_EXCEEDED when status is 429', async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAA2B,UAAU,EAA4B,MAAM,WAAW,CAAC;AAG1F,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,UAAU,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAMnE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAEnE;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/F"}
1
+ {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAA2B,UAAU,EAA4B,MAAM,WAAW,CAAC;AAG1F,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,UAAU,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAMnE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAInE;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/F"}
@@ -17,7 +17,7 @@ function safeGetParsedBody(text) {
17
17
  }
18
18
  exports.safeGetParsedBody = safeGetParsedBody;
19
19
  function extractTraceId(response) {
20
- return response.headers.get('x-b3-traceid') || response.headers.get('x-trace-id');
20
+ return (response.headers.get('x-b3-traceid') || response.headers.get('x-trace-id') || response.headers.get('atl-traceid'));
21
21
  }
22
22
  exports.extractTraceId = extractTraceId;
23
23
  async function checkResponseError(response, message) {
@@ -42,7 +42,7 @@ async function checkResponseError(response, message) {
42
42
  }
43
43
  throw new errors_1.ForgeObjectStoreAPIError(details, {
44
44
  code: errorCodes_1.errorCodes.UNKNOWN_ERROR,
45
- message: message || 'Unexpected error in Forge SQL API request',
45
+ message: message || 'Unexpected error in Forge OS API request',
46
46
  context: { responseText }
47
47
  });
48
48
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/os",
3
- "version": "2.0.5-next.0-experimental-5ae8c1c",
3
+ "version": "2.1.0-next.0",
4
4
  "description": "Forge Object Store SDK",
5
5
  "author": "Atlassian",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
@@ -20,7 +20,7 @@
20
20
  "jest-when": "^3.6.0"
21
21
  },
22
22
  "dependencies": {
23
- "@forge/api": "^6.1.1-next.0-experimental-5ae8c1c"
23
+ "@forge/api": "^6.1.1"
24
24
  },
25
25
  "publishConfig": {
26
26
  "registry": "https://packages.atlassian.com/api/npm/npm-public/"