Skip to content

Commit 034fd02

Browse files
committed
pangea-node-sdk: support source-url in Share upload
1 parent 6e8f8c8 commit 034fd02

File tree

8 files changed

+86
-47
lines changed

8 files changed

+86
-47
lines changed

examples/share/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Pangea Store Service Example
1+
# Pangea Secure Share examples
22

33
## Setup
44

@@ -8,5 +8,5 @@ Set up environment variables ([Instructions](https://pangea.cloud/docs/getting-s
88

99
```
1010
yarn install
11-
node folder_create_n_delete.mjs
11+
node folder_create_and_delete.mjs
1212
```

examples/share/folder_create_and_delete.mjs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,13 @@ const folderPath = "/sdk_examples/node/delete/" + time;
1616
(async () => {
1717
try {
1818
console.log("Creating folder...");
19-
const respCreate = await client.folderCreate({
20-
path: folderPath,
21-
});
19+
const respCreate = await client.folderCreate({ folder: folderPath });
2220

2321
const id = respCreate.result.object.id;
2422
console.log(`Folder create success. Folder ID: ${id}`);
2523

2624
console.log("Deleting folder...");
27-
const respDelete = await client.delete({
28-
id: id,
29-
});
25+
const respDelete = await client.delete({ id });
3026

3127
console.log(`Deleted ${respDelete.result.count} item(s)`);
3228
} catch (e) {

examples/share/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"private": true,
66
"author": "Pangea",
77
"license": "MIT",
8+
"packageManager": "yarn@1.22.22",
89
"dependencies": {
910
"citty": "^0.1.6",
1011
"pangea-node-sdk": "file:../../packages/pangea-node-sdk"

examples/share/put_transfer_method_post_url.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable no-console */
22

33
import { PangeaConfig, ShareService, TransferMethod } from "pangea-node-sdk";
4-
import * as fs from "fs";
4+
import { readFileSync } from "node:fs";
55

66
// Load Pangea token and domain from environment variables
77
const token = process.env.PANGEA_SHARE_TOKEN;
@@ -21,7 +21,7 @@ const filepath = "./testfile.pdf";
2121
const name = time + "_file_post_url";
2222

2323
// Read file content as buffer
24-
const data = fs.readFileSync(filepath);
24+
const data = readFileSync(filepath);
2525

2626
// Send Put request setting transfer_method to post-url
2727
// SDK will request an upload url, post the file to that url and then poll the upload result to Share service

examples/share/yarn.lock

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,42 +21,42 @@
2121
tslib "^2.6.2"
2222

2323
"@aws-sdk/types@^3.222.0":
24-
version "3.533.0"
25-
resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.533.0.tgz#4c4ade8f41f153295c69f1dea812dcd6154613e3"
26-
integrity sha512-mFb0701oLRcJ7Y2unlrszzk9rr2P6nt2A4Bdz4K5WOsY4f4hsdbcYkrzA1NPmIUTEttU9JT0YG+8z0XxLEX4Aw==
24+
version "3.664.0"
25+
resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.664.0.tgz#e6de1c0a2cdfe4f1e43271223dc0b55e613ced58"
26+
integrity sha512-+GtXktvVgpreM2b+NJL9OqZGsOzHwlCUrO8jgQUvH/yA6Kd8QO2YFhQCp0C9sSzTteZJVqGBu8E0CQurxJHPbw==
2727
dependencies:
28-
"@smithy/types" "^2.11.0"
29-
tslib "^2.5.0"
28+
"@smithy/types" "^3.5.0"
29+
tslib "^2.6.2"
3030

31-
"@smithy/is-array-buffer@^2.1.1":
32-
version "2.1.1"
33-
resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.1.1.tgz#07b4c77ae67ed58a84400c76edd482271f9f957b"
34-
integrity sha512-xozSQrcUinPpNPNPds4S7z/FakDTh1MZWtRP/2vQtYB/u3HYrX2UXuZs+VhaKBd6Vc7g2XPr2ZtwGBNDN6fNKQ==
31+
"@smithy/is-array-buffer@^2.2.0":
32+
version "2.2.0"
33+
resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz#f84f0d9f9a36601a9ca9381688bd1b726fd39111"
34+
integrity sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==
3535
dependencies:
36-
tslib "^2.5.0"
36+
tslib "^2.6.2"
3737

38-
"@smithy/types@^2.11.0":
39-
version "2.11.0"
40-
resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.11.0.tgz#d40c27302151be243d3a7319a154b7d7d5775021"
41-
integrity sha512-AR0SXO7FuAskfNhyGfSTThpLRntDI5bOrU0xrpVYU0rZyjl3LBXInZFMTP/NNSd7IS6Ksdtar0QvnrPRIhVrLQ==
38+
"@smithy/types@^3.5.0":
39+
version "3.5.0"
40+
resolved "https://registry.yarnpkg.com/@smithy/types/-/types-3.5.0.tgz#9589e154c50d9c5d00feb7d818112ef8fc285d6e"
41+
integrity sha512-QN0twHNfe8mNJdH9unwsCK13GURU7oEAZqkBI+rsvpv1jrmserO+WnLE7jidR9W/1dxwZ0u/CB01mV2Gms/K2Q==
4242
dependencies:
43-
tslib "^2.5.0"
43+
tslib "^2.6.2"
4444

45-
"@smithy/util-buffer-from@^2.1.1":
46-
version "2.1.1"
47-
resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.1.1.tgz#f9346bf8b23c5ba6f6bdb61dd9db779441ba8d08"
48-
integrity sha512-clhNjbyfqIv9Md2Mg6FffGVrJxw7bgK7s3Iax36xnfVj6cg0fUG7I4RH0XgXJF8bxi+saY5HR21g2UPKSxVCXg==
45+
"@smithy/util-buffer-from@^2.2.0":
46+
version "2.2.0"
47+
resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz#6fc88585165ec73f8681d426d96de5d402021e4b"
48+
integrity sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==
4949
dependencies:
50-
"@smithy/is-array-buffer" "^2.1.1"
51-
tslib "^2.5.0"
50+
"@smithy/is-array-buffer" "^2.2.0"
51+
tslib "^2.6.2"
5252

5353
"@smithy/util-utf8@^2.0.0":
54-
version "2.2.0"
55-
resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.2.0.tgz#e352a81adc0491fbdc0086a00950d7e8333e211f"
56-
integrity sha512-hBsKr5BqrDrKS8qy+YcV7/htmMGxriA1PREOf/8AGBhHIZnfilVv1Waf1OyKhSbFW15U/8+gcMUQ9/Kk5qwpHQ==
54+
version "2.3.0"
55+
resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz#dd96d7640363259924a214313c3cf16e7dd329c5"
56+
integrity sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==
5757
dependencies:
58-
"@smithy/util-buffer-from" "^2.1.1"
59-
tslib "^2.5.0"
58+
"@smithy/util-buffer-from" "^2.2.0"
59+
tslib "^2.6.2"
6060

6161
citty@^0.1.6:
6262
version "0.1.6"
@@ -95,6 +95,11 @@ js-sha3@^0.8.0:
9595
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
9696
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
9797

98+
json-canon@^1.0.1:
99+
version "1.0.1"
100+
resolved "https://registry.yarnpkg.com/json-canon/-/json-canon-1.0.1.tgz#ce815a1d02e1b02c97b21154c7a844321e314184"
101+
integrity sha512-PQcj4PFOTAQxE8PgoQ4KrM0DcKWZd7S3ELOON8rmysl9I8JuFMgxu1H9v+oZsTPjjkpeS3IHPwLjr7d+gKygnw==
102+
98103
merkle-tools@^1.4.1:
99104
version "1.4.1"
100105
resolved "https://registry.yarnpkg.com/merkle-tools/-/merkle-tools-1.4.1.tgz#d08799886a6d51f5ee2bf0195f967b3cc3afd62c"
@@ -103,12 +108,13 @@ merkle-tools@^1.4.1:
103108
js-sha3 "^0.8.0"
104109

105110
"pangea-node-sdk@file:../../packages/pangea-node-sdk":
106-
version "3.11.0"
111+
version "4.0.0"
107112
dependencies:
108113
"@aws-crypto/crc32c" "^5.2.0"
109114
crypto-js "^4.2.0"
110115
form-data-encoder "^4.0.2"
111116
formdata-node "^6.0.3"
117+
json-canon "^1.0.1"
112118
merkle-tools "^1.4.1"
113119
promise-retry "^2.0.1"
114120

@@ -125,7 +131,7 @@ retry@^0.12.0:
125131
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
126132
integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==
127133

128-
tslib@^2.5.0, tslib@^2.6.2:
129-
version "2.6.2"
130-
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
131-
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
134+
tslib@^2.6.2:
135+
version "2.8.0"
136+
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b"
137+
integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==

packages/pangea-node-sdk/src/request.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { Buffer } from "node:buffer";
12
import fs from "node:fs";
23
import { FormDataEncoder } from "form-data-encoder";
3-
import { FormData } from "formdata-node";
4+
import { File, FormData } from "formdata-node";
45
import { fileFromPath } from "formdata-node/file-from-path";
56
import promiseRetry from "promise-retry";
7+
68
import PangeaConfig, { version } from "./config.js";
79
import { PangeaErrors } from "./errors.js";
810
import { AttachedFile, PangeaResponse } from "./response.js";
@@ -174,9 +176,14 @@ class PangeaRequest {
174176
return await this.httpPost(url, request);
175177
}
176178

177-
private async getFileToForm(file: Blob | Buffer | string) {
179+
private async getFileToForm(
180+
file: Blob | Buffer | string
181+
): Promise<Blob | File> {
178182
if (typeof file === "string") {
179-
return await fileFromPath(file);
183+
return await fileFromPath(file, "file");
184+
}
185+
if (Buffer.isBuffer(file)) {
186+
return new Blob([file]);
180187
}
181188
return file;
182189
}
@@ -234,7 +241,7 @@ class PangeaRequest {
234241
}
235242

236243
// Right now, only accept the file with name "file"
237-
form.append("file", await this.getFileToForm(fileData.file));
244+
form.append("file", await this.getFileToForm(fileData.file), "file");
238245

239246
const response = await this.httpPost(url, {
240247
body: form,

packages/pangea-node-sdk/src/services/share.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ class ShareService extends BaseService {
131131
return this.post("v1/list", request);
132132
}
133133

134+
put(
135+
request: Share.PutRequest,
136+
fileData: FileData
137+
): Promise<PangeaResponse<Share.PutResult>>;
138+
put(
139+
request: Share.PutRequest & { transfer_method: TransferMethod.SOURCE_URL }
140+
): Promise<PangeaResponse<Share.PutResult>>;
141+
134142
/**
135143
* @summary Upload a file
136144
* @description Upload a file.
@@ -161,8 +169,20 @@ class ShareService extends BaseService {
161169
*/
162170
put(
163171
request: Share.PutRequest,
164-
fileData: FileData
172+
fileData?: FileData
165173
): Promise<PangeaResponse<Share.PutResult>> {
174+
// With `source-url`, no file data is needed.
175+
if (request.transfer_method === TransferMethod.SOURCE_URL) {
176+
return this.post("v1/put", request);
177+
}
178+
179+
// Otherwise, file data is required.
180+
if (!fileData) {
181+
throw new TypeError(
182+
"`fileData` is required when `transfer_method` is not `SOURCE_URL`."
183+
);
184+
}
185+
166186
let fsData = {} as FileUploadParams;
167187

168188
if (
@@ -173,7 +193,7 @@ class ShareService extends BaseService {
173193
request.crc32c = fsData.crc32c;
174194
request.sha256 = fsData.sha256;
175195
request.size = fsData.size;
176-
} else if (getFileSize(fileData.file) == 0) {
196+
} else if (getFileSize(fileData.file) === 0) {
177197
request.size = 0;
178198
}
179199

packages/pangea-node-sdk/tests/integration/share.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,3 +477,12 @@ it("Item life cycle", async () => {
477477
expect(respList.result.count).toBe(2);
478478
expect(respList.result.objects.length).toBe(2);
479479
});
480+
481+
it("transfer via `source-url`", async () => {
482+
const response = await client.put({
483+
transfer_method: TransferMethod.SOURCE_URL,
484+
source_url: "https://www.google.com/robots.txt",
485+
});
486+
expect(response.status).toBe("Success");
487+
expect(response.success).toBeTruthy();
488+
});

0 commit comments

Comments
 (0)