@pinata/sdk 1.1.26 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinata/sdk",
3
- "version": "1.1.26",
3
+ "version": "1.2.0",
4
4
  "description": "Official SDK for the Pinata IPFS platform",
5
5
  "main": "lib/pinata-sdk.js",
6
6
  "types": "types/index.d.ts",
@@ -36,7 +36,8 @@
36
36
  "devDependencies": {
37
37
  "@babel/cli": "^7.8.4",
38
38
  "@babel/core": "^7.8.4",
39
- "@babel/preset-env": "^7.9.0",
39
+ "@babel/plugin-transform-runtime": "^7.19.1",
40
+ "@babel/preset-env": "^7.19.4",
40
41
  "@babel/register": "^7.8.3",
41
42
  "@types/node": "^15.6.1",
42
43
  "acorn": "^7.1.0",
@@ -0,0 +1,70 @@
1
+ import { validateApiKeys } from '../../../util/validators';
2
+ import pinList from '../pinList/pinList';
3
+
4
+ export default function getFilesByCount(
5
+ pinataApiKey,
6
+ pinataSecretApiKey,
7
+
8
+ filters = {},
9
+ maxCount = -1
10
+ ) {
11
+ validateApiKeys(pinataApiKey, pinataSecretApiKey);
12
+ if (maxCount === 0) {
13
+ throw Error("Max count can't be 0");
14
+ }
15
+
16
+ const asyncIterable = {
17
+ [Symbol.asyncIterator]: () => {
18
+ let i = 0;
19
+ const pageLimit = 10;
20
+ let pageOffset = 0;
21
+ let cache = [];
22
+ let keepLooping = false;
23
+
24
+ return {
25
+ next() {
26
+ return new Promise((resolve, reject) => {
27
+ if (i === 0 || (i % pageLimit === 0 && keepLooping)) {
28
+ resolve(
29
+ pinList(pinataApiKey, pinataSecretApiKey, {
30
+ filters,
31
+ ...{ pageOffset, pageLimit }
32
+ }).then((resp) => {
33
+ cache = resp.rows;
34
+ pageOffset = pageOffset + cache.length;
35
+
36
+ // If the user requested all pins we have to keep looping if the limit page was not fulfill
37
+ keepLooping =
38
+ cache.length !== 0 &&
39
+ (maxCount === -1 ?
40
+ cache.length === pageLimit :
41
+ i < maxCount);
42
+ })
43
+ );
44
+ }
45
+ resolve();
46
+ }).then(() => {
47
+ const valueToReturn = cache[i % pageLimit];
48
+
49
+ const done = !(
50
+ (maxCount === -1 ? i < pageOffset : i < maxCount) &&
51
+ keepLooping
52
+ );
53
+
54
+ i++;
55
+ return Promise.resolve({
56
+ value: valueToReturn,
57
+ done
58
+ });
59
+ });
60
+ },
61
+ return() {
62
+ // This will be reached if the consumer called 'break' or 'return' early in the loop.
63
+ return Promise.resolve({ value: i, done: true });
64
+ }
65
+ };
66
+ }
67
+ };
68
+
69
+ return asyncIterable;
70
+ }
@@ -8,12 +8,14 @@ import queryBuilder from './queryBuilder';
8
8
  * Pin List
9
9
  * @param {string} pinataApiKey
10
10
  * @param {string} pinataSecretApiKey
11
- * @param {string} filters
11
+ * @param {any} filters
12
12
  * @returns {Promise<unknown>}
13
13
  */
14
- export default function pinList(pinataApiKey, pinataSecretApiKey, filters) {
14
+ export default function pinList(pinataApiKey, pinataSecretApiKey, filters = {}) {
15
15
  validateApiKeys(pinataApiKey, pinataSecretApiKey);
16
16
 
17
+ filters = {...filters, ...{includeCount: 'false' }};
18
+
17
19
  const baseEndpoint = `${baseUrl}/data/pinList`;
18
20
  const endpoint = queryBuilder(baseEndpoint, filters);
19
21
 
@@ -35,6 +35,10 @@ export default function queryBuilder(baseUrl, filters) {
35
35
 
36
36
  if (filters) {
37
37
  // now we need to construct the actual URL based on the given filters provided
38
+ if (filters.includeCount) {
39
+ filterQuery = filterQuery + `includeCount=${filters.includeCount}&`;
40
+ }
41
+
38
42
  if (filters.hashContains) {
39
43
  if (typeof filters.hashContains !== 'string') {
40
44
  throw new Error('hashContains value is not a string');
package/src/index.js CHANGED
@@ -7,6 +7,7 @@ import pinJobs from './commands/pinning/pinJobs/pinJobs';
7
7
  import unpin from './commands/pinning/unpin';
8
8
  import testAuthentication from './commands/data/testAuthentication';
9
9
  import pinList from './commands/data/pinList/pinList';
10
+ import getFilesByCount from './commands/data/getFilesByCount/getFilesByCount';
10
11
  import userPinnedDataTotal from './commands/data/userPinnedDataTotal';
11
12
 
12
13
  // OPTIONS
@@ -250,6 +251,10 @@ export default function pinataClient(pinataApiKey, pinataSecretApiKey) {
250
251
  client.pinList = function (filters) {
251
252
  return pinList(pinataApiKey, pinataSecretApiKey, filters);
252
253
  };
254
+
255
+ client.getFilesByCount = function (filters, maxCount,) {
256
+ return getFilesByCount(pinataApiKey, pinataSecretApiKey, filters, maxCount);
257
+ };
253
258
  client.userPinnedDataTotal = function () {
254
259
  return userPinnedDataTotal(pinataApiKey, pinataSecretApiKey);
255
260
  };
@@ -0,0 +1,215 @@
1
+ import getFilesByCount from "../../../../src/commands/data/getFilesByCount/getFilesByCount";
2
+ import axios from "axios";
3
+ import { APIData, pinListAxiosMockPages, fakeHeaders } from "../pinlist-sample-api";
4
+
5
+ jest.mock("axios");
6
+
7
+ const metadataName = (item) => {
8
+ return item.metadata.name;
9
+ };
10
+ const callIterableObject = async (
11
+ pinataKey,
12
+ pinataSecret,
13
+ filterToApply,
14
+ pinsCount
15
+ ) => {
16
+ const pins = [];
17
+ for await (const item of getFilesByCount(
18
+ pinataKey,
19
+ pinataSecret,
20
+ filterToApply,
21
+ pinsCount
22
+ )) {
23
+ pins.push(metadataName(item));
24
+ }
25
+
26
+ return pins;
27
+ };
28
+
29
+ describe("Get Files By Count", () => {
30
+ const filterToApply = {
31
+ status: "pinned",
32
+ };
33
+
34
+ afterEach(() => {
35
+ jest.resetAllMocks();
36
+ });
37
+
38
+ test("Request 17 pins, pins available", async () => {
39
+ const pinsToRequest = 17;
40
+
41
+ axios.get
42
+ .mockResolvedValueOnce(pinListAxiosMockPages.firstPage.response)
43
+ .mockResolvedValueOnce(pinListAxiosMockPages.secondPage.response);
44
+
45
+ const pins = await callIterableObject(
46
+ fakeHeaders.headers.pinata_api_key,
47
+ fakeHeaders.headers.pinata_secret_api_key,
48
+ filterToApply,
49
+ pinsToRequest
50
+ );
51
+
52
+ expect(pins).toEqual(
53
+ APIData.rows.slice(0, pinsToRequest).map(metadataName)
54
+ );
55
+ expect(pins).toHaveLength(pinsToRequest);
56
+ expect(axios.get).toHaveBeenNthCalledWith(
57
+ 1,
58
+ pinListAxiosMockPages.firstPage.url,
59
+ pinListAxiosMockPages.firstPage.headers
60
+ );
61
+ expect(axios.get).toHaveBeenNthCalledWith(
62
+ 2,
63
+ pinListAxiosMockPages.secondPage.url,
64
+ pinListAxiosMockPages.secondPage.headers
65
+ );
66
+
67
+ expect(axios.get).toHaveBeenCalledTimes(2);
68
+ });
69
+
70
+ test("Request 6 pins, pins available", async () => {
71
+ const pinsToRequest = 6;
72
+
73
+ axios.get.mockResolvedValueOnce(
74
+ pinListAxiosMockPages.firstPage.response
75
+ );
76
+ const pins = await callIterableObject(
77
+ fakeHeaders.headers.pinata_api_key,
78
+ fakeHeaders.headers.pinata_secret_api_key,
79
+ filterToApply,
80
+ pinsToRequest
81
+ );
82
+ expect(pins).toEqual(
83
+ APIData.rows.slice(0, pinsToRequest).map(metadataName)
84
+ );
85
+
86
+ expect(pins).toHaveLength(pinsToRequest);
87
+ expect(axios.get).toHaveBeenNthCalledWith(
88
+ 1,
89
+ pinListAxiosMockPages.firstPage.url,
90
+ pinListAxiosMockPages.firstPage.headers
91
+ );
92
+ expect(axios.get).toHaveBeenCalledTimes(1);
93
+ });
94
+
95
+ test("Request 25 pins, pins not available", async () => {
96
+ const pinsToRequest = 25;
97
+
98
+ axios.get
99
+ .mockResolvedValueOnce(pinListAxiosMockPages.firstPage.response)
100
+ .mockResolvedValueOnce(pinListAxiosMockPages.secondPage.response)
101
+ .mockResolvedValueOnce(
102
+ pinListAxiosMockPages.thirdPageEmpty.response
103
+ );
104
+ const pins = await callIterableObject(
105
+ fakeHeaders.headers.pinata_api_key,
106
+ fakeHeaders.headers.pinata_secret_api_key,
107
+ filterToApply,
108
+ pinsToRequest
109
+ );
110
+
111
+ expect(pins).toEqual(
112
+ APIData.rows.slice(0, pinsToRequest).map(metadataName)
113
+ );
114
+
115
+ expect(pins).toHaveLength(20);
116
+ expect(axios.get).toHaveBeenNthCalledWith(
117
+ 1,
118
+ pinListAxiosMockPages.firstPage.url,
119
+ pinListAxiosMockPages.firstPage.headers
120
+ );
121
+ expect(axios.get).toHaveBeenNthCalledWith(
122
+ 2,
123
+ pinListAxiosMockPages.secondPage.url,
124
+ pinListAxiosMockPages.secondPage.headers
125
+ );
126
+ expect(axios.get).toHaveBeenNthCalledWith(
127
+ 3,
128
+ pinListAxiosMockPages.thirdPageEmpty.url,
129
+ pinListAxiosMockPages.thirdPageEmpty.headers
130
+ );
131
+
132
+ expect(axios.get).toHaveBeenCalledTimes(3);
133
+ });
134
+
135
+ test("Request 3 pins, pins not available", async () => {
136
+ const pinsToRequest = 3;
137
+
138
+ axios.get.mockResolvedValueOnce(
139
+ pinListAxiosMockPages.firstPageEmpty.response
140
+ );
141
+ const pins = await callIterableObject(
142
+ fakeHeaders.headers.pinata_api_key,
143
+ fakeHeaders.headers.pinata_secret_api_key,
144
+ filterToApply,
145
+ pinsToRequest
146
+ );
147
+
148
+ expect(pins).toEqual([]);
149
+
150
+ expect(pins).toHaveLength(0);
151
+ expect(axios.get).toHaveBeenNthCalledWith(
152
+ 1,
153
+ pinListAxiosMockPages.firstPageEmpty.url,
154
+ pinListAxiosMockPages.firstPageEmpty.headers
155
+ );
156
+
157
+ expect(axios.get).toHaveBeenCalledTimes(1);
158
+ });
159
+
160
+ test("Request all pins, pins available", async () => {
161
+ axios.get
162
+ .mockResolvedValueOnce(pinListAxiosMockPages.firstPage.response)
163
+ .mockResolvedValueOnce(pinListAxiosMockPages.secondPage.response)
164
+ .mockResolvedValueOnce(
165
+ pinListAxiosMockPages.thirdPageEmpty.response
166
+ );
167
+ const pins = await callIterableObject(
168
+ fakeHeaders.headers.pinata_api_key,
169
+ fakeHeaders.headers.pinata_secret_api_key,
170
+ filterToApply
171
+ );
172
+ expect(pins).toEqual(APIData.rows.map(metadataName));
173
+
174
+ expect(pins).toHaveLength(APIData.rows.length);
175
+ expect(axios.get).toHaveBeenNthCalledWith(
176
+ 1,
177
+ pinListAxiosMockPages.firstPage.url,
178
+ pinListAxiosMockPages.firstPage.headers
179
+ );
180
+ expect(axios.get).toHaveBeenNthCalledWith(
181
+ 2,
182
+ pinListAxiosMockPages.secondPage.url,
183
+ pinListAxiosMockPages.secondPage.headers
184
+ );
185
+ expect(axios.get).toHaveBeenNthCalledWith(
186
+ 3,
187
+ pinListAxiosMockPages.thirdPageEmpty.url,
188
+ pinListAxiosMockPages.thirdPageEmpty.headers
189
+ );
190
+
191
+ expect(axios.get).toHaveBeenCalledTimes(3);
192
+ });
193
+
194
+ test("Request all pins, pins not available", async () => {
195
+ axios.get.mockResolvedValueOnce(
196
+ pinListAxiosMockPages.firstPageEmpty.response
197
+ );
198
+ const pins = await callIterableObject(
199
+ fakeHeaders.headers.pinata_api_key,
200
+ fakeHeaders.headers.pinata_secret_api_key,
201
+ filterToApply
202
+ );
203
+
204
+ expect(pins).toEqual([]);
205
+
206
+ expect(pins).toHaveLength(0);
207
+ expect(axios.get).toHaveBeenNthCalledWith(
208
+ 1,
209
+ pinListAxiosMockPages.firstPageEmpty.url,
210
+ pinListAxiosMockPages.firstPageEmpty.headers
211
+ );
212
+
213
+ expect(axios.get).toHaveBeenCalledTimes(1);
214
+ });
215
+ });
@@ -1,29 +1,98 @@
1
- import axios from 'axios';
2
- import pinList from './../../../../src/commands/data/pinList/pinList';
3
-
4
- jest.mock('axios');
5
-
6
- test('Result other than 200 status is returned', () => {
7
- const badStatus = {
8
- status: 700
9
- };
10
- axios.get.mockResolvedValue(badStatus);
11
- expect.assertions(1);
12
- expect(pinList('test', 'test')).rejects.toEqual(Error(`unknown server response while attempting to retrieve user pin list: ${badStatus}`));
13
- });
1
+ import axios from "axios";
2
+ import pinList from "./../../../../src/commands/data/pinList/pinList";
3
+ import {
4
+ APIData,
5
+ pinListAxiosMockPages,
6
+ fakeHeaders,
7
+ } from "../pinlist-sample-api";
14
8
 
15
- test('200 status is returned', () => {
16
- const goodStatus = {
17
- status: 200,
18
- data: 'testData'
19
- };
20
- axios.get.mockResolvedValue(goodStatus);
21
- expect.assertions(1);
22
- expect(pinList('test', 'test')).resolves.toEqual(goodStatus.data);
23
- });
9
+ jest.mock("axios");
10
+
11
+ describe("Get Files By Count", () => {
12
+ afterEach(() => {
13
+ jest.resetAllMocks();
14
+ });
15
+
16
+ test("Call two pages in a row", async () => {
17
+ axios.get
18
+ .mockResolvedValueOnce(pinListAxiosMockPages.firstPage.response)
19
+ .mockResolvedValueOnce(pinListAxiosMockPages.secondPage.response);
20
+
21
+ const resp = await pinList(
22
+ fakeHeaders.headers.pinata_api_key,
23
+ fakeHeaders.headers.pinata_secret_api_key,
24
+ { pageLimit: 10, pageOffset: 0 }
25
+ );
26
+ const resp2 = await pinList(
27
+ fakeHeaders.headers.pinata_api_key,
28
+ fakeHeaders.headers.pinata_secret_api_key,
29
+ { pageLimit: 10, pageOffset: 10 }
30
+ );
31
+ expect(resp).toEqual(pinListAxiosMockPages.firstPage.response.data);
32
+ expect(resp2).toEqual(pinListAxiosMockPages.secondPage.response.data);
33
+
34
+ expect(axios.get).toHaveBeenNthCalledWith(
35
+ 1,
36
+ pinListAxiosMockPages.firstPage.url,
37
+ pinListAxiosMockPages.firstPage.headers
38
+ );
39
+ expect(axios.get).toHaveBeenNthCalledWith(
40
+ 2,
41
+ pinListAxiosMockPages.secondPage.url,
42
+ pinListAxiosMockPages.secondPage.headers
43
+ );
44
+
45
+ expect(axios.get).toHaveBeenCalledTimes(2);
46
+ });
47
+
48
+ test("Call empty page", async () => {
49
+ axios.get
50
+ .mockResolvedValueOnce(pinListAxiosMockPages.firstPageEmpty.response)
51
+
52
+
53
+ const resp = await pinList(
54
+ fakeHeaders.headers.pinata_api_key,
55
+ fakeHeaders.headers.pinata_secret_api_key,
56
+ { pageLimit: 10, pageOffset: 0 }
57
+ );
58
+
59
+ expect(resp).toEqual({rows: []});
60
+
61
+
62
+ expect(axios.get).toHaveBeenNthCalledWith(
63
+ 1,
64
+ pinListAxiosMockPages.firstPageEmpty.url,
65
+ pinListAxiosMockPages.firstPageEmpty.headers
66
+ );
67
+
68
+ expect(axios.get).toHaveBeenCalledTimes(1);
69
+ });
70
+ test("Result other than 200 status is returned", () => {
71
+ const badStatus = {
72
+ status: 700,
73
+ };
74
+ axios.get.mockResolvedValue(badStatus);
75
+ expect.assertions(1);
76
+ expect(pinList("test", "test")).rejects.toEqual(
77
+ Error(
78
+ `unknown server response while attempting to retrieve user pin list: ${badStatus}`
79
+ )
80
+ );
81
+ });
82
+
83
+ test("200 status is returned", () => {
84
+ const goodStatus = {
85
+ status: 200,
86
+ data: "testData",
87
+ };
88
+ axios.get.mockResolvedValue(goodStatus);
89
+ expect.assertions(1);
90
+ expect(pinList("test", "test")).resolves.toEqual(goodStatus.data);
91
+ });
24
92
 
25
- test('Rejection handled', () => {
26
- axios.get.mockRejectedValue('test error');
27
- expect.assertions(1);
28
- expect(pinList('test', 'test')).rejects.toEqual('test error');
93
+ test("Rejection handled", () => {
94
+ axios.get.mockRejectedValue("test error");
95
+ expect.assertions(1);
96
+ expect(pinList("test", "test")).rejects.toEqual("test error");
97
+ });
29
98
  });