@bsv/sdk 1.6.23 → 1.6.25
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/README.md +4 -0
- package/dist/cjs/package.json +3 -2
- package/dist/cjs/src/identity/ContactsManager.js +298 -0
- package/dist/cjs/src/identity/ContactsManager.js.map +1 -0
- package/dist/cjs/src/identity/IdentityClient.js +26 -0
- package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
- package/dist/cjs/src/script/Script.js +2 -1
- package/dist/cjs/src/script/Script.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +3 -0
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/identity/ContactsManager.js +295 -0
- package/dist/esm/src/identity/ContactsManager.js.map +1 -0
- package/dist/esm/src/identity/IdentityClient.js +27 -0
- package/dist/esm/src/identity/IdentityClient.js.map +1 -1
- package/dist/esm/src/script/Script.js +2 -1
- package/dist/esm/src/script/Script.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +3 -0
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/identity/ContactsManager.d.ts +28 -0
- package/dist/types/src/identity/ContactsManager.d.ts.map +1 -0
- package/dist/types/src/identity/IdentityClient.d.ts +21 -1
- package/dist/types/src/identity/IdentityClient.d.ts.map +1 -1
- package/dist/types/src/script/Script.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/identity.md +144 -4
- package/package.json +3 -2
- package/src/identity/ContactsManager.ts +332 -0
- package/src/identity/IdentityClient.ts +31 -0
- package/src/identity/__tests/IdentityClient.test.ts +326 -2
- package/src/script/Script.ts +3 -2
- package/src/script/__tests/Script.test.ts +9 -0
- package/src/transaction/Transaction.ts +2 -0
- package/dist/cjs/src/storage/__test/StorageDownloader.test.js +0 -171
- package/dist/cjs/src/storage/__test/StorageDownloader.test.js.map +0 -1
- package/dist/cjs/src/storage/__test/StorageUploader.test.js +0 -163
- package/dist/cjs/src/storage/__test/StorageUploader.test.js.map +0 -1
- package/dist/cjs/src/storage/__test/StorageUtils.test.js +0 -97
- package/dist/cjs/src/storage/__test/StorageUtils.test.js.map +0 -1
- package/dist/esm/src/storage/__test/StorageDownloader.test.js +0 -166
- package/dist/esm/src/storage/__test/StorageDownloader.test.js.map +0 -1
- package/dist/esm/src/storage/__test/StorageUploader.test.js +0 -135
- package/dist/esm/src/storage/__test/StorageUploader.test.js.map +0 -1
- package/dist/esm/src/storage/__test/StorageUtils.test.js +0 -72
- package/dist/esm/src/storage/__test/StorageUtils.test.js.map +0 -1
- package/dist/types/src/storage/__test/StorageDownloader.test.d.ts +0 -2
- package/dist/types/src/storage/__test/StorageDownloader.test.d.ts.map +0 -1
- package/dist/types/src/storage/__test/StorageUploader.test.d.ts +0 -2
- package/dist/types/src/storage/__test/StorageUploader.test.d.ts.map +0 -1
- package/dist/types/src/storage/__test/StorageUtils.test.d.ts +0 -2
- package/dist/types/src/storage/__test/StorageUtils.test.d.ts.map +0 -1
- /package/src/storage/{__test → __tests}/StorageDownloader.test.ts +0 -0
- /package/src/storage/{__test → __tests}/StorageUploader.test.ts +0 -0
- /package/src/storage/{__test → __tests}/StorageUtils.test.ts +0 -0
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
const StorageUploader_js_1 = require("../StorageUploader.js");
|
|
30
|
-
const StorageUtils = __importStar(require("../StorageUtils.js"));
|
|
31
|
-
const WalletClient_js_1 = __importDefault(require("../../wallet/WalletClient.js"));
|
|
32
|
-
/**
|
|
33
|
-
* A helper for converting a string to a number[] of UTF-8 bytes
|
|
34
|
-
*/
|
|
35
|
-
function stringToUtf8Array(str) {
|
|
36
|
-
return Array.from(new TextEncoder().encode(str));
|
|
37
|
-
}
|
|
38
|
-
describe('StorageUploader Tests', () => {
|
|
39
|
-
let uploader;
|
|
40
|
-
let walletClient;
|
|
41
|
-
// We'll have TWO spies:
|
|
42
|
-
let authFetchSpy;
|
|
43
|
-
let globalFetchSpy;
|
|
44
|
-
beforeEach(() => {
|
|
45
|
-
walletClient = new WalletClient_js_1.default('json-api', 'non-admin.com');
|
|
46
|
-
uploader = new StorageUploader_js_1.StorageUploader({
|
|
47
|
-
storageURL: 'https://example.test.system',
|
|
48
|
-
wallet: walletClient
|
|
49
|
-
});
|
|
50
|
-
// 1) Spy on the "authFetch.fetch" calls for /find, /list, /renew
|
|
51
|
-
authFetchSpy = jest
|
|
52
|
-
.spyOn(uploader['authFetch'], 'fetch')
|
|
53
|
-
.mockResolvedValue(new Response(null, { status: 200 }));
|
|
54
|
-
// 2) Spy on the global "fetch" calls for file upload (uploadFile)
|
|
55
|
-
globalFetchSpy = jest
|
|
56
|
-
.spyOn(global, 'fetch')
|
|
57
|
-
.mockResolvedValue(new Response(null, { status: 200 }));
|
|
58
|
-
});
|
|
59
|
-
afterEach(() => {
|
|
60
|
-
jest.restoreAllMocks();
|
|
61
|
-
});
|
|
62
|
-
it('should upload a file, produce a valid UHRP URL, and decode it to the known SHA-256', async () => {
|
|
63
|
-
const data = stringToUtf8Array('Hello, world!');
|
|
64
|
-
// Mock out getUploadInfo so we can control the returned upload/public URLs
|
|
65
|
-
jest.spyOn(uploader, 'getUploadInfo').mockResolvedValue({
|
|
66
|
-
uploadURL: 'https://example-upload.com/put'
|
|
67
|
-
});
|
|
68
|
-
const result = await uploader.publishFile({
|
|
69
|
-
file: { data, type: 'text/plain' },
|
|
70
|
-
retentionPeriod: 7
|
|
71
|
-
});
|
|
72
|
-
// This direct upload uses global.fetch, not authFetch
|
|
73
|
-
expect(globalFetchSpy).toHaveBeenCalledTimes(1);
|
|
74
|
-
// Check the result
|
|
75
|
-
expect(StorageUtils.isValidURL(result.uhrpURL)).toBe(true);
|
|
76
|
-
expect(result.published).toBe(true);
|
|
77
|
-
const url = StorageUtils.getHashFromURL(result.uhrpURL);
|
|
78
|
-
const firstFour = url.slice(0, 4)
|
|
79
|
-
.map(b => b.toString(16).padStart(2, '0'))
|
|
80
|
-
.join('');
|
|
81
|
-
expect(firstFour).toHaveLength(8);
|
|
82
|
-
});
|
|
83
|
-
it('should throw if the upload fails with HTTP 500', async () => {
|
|
84
|
-
// Force the direct upload (global fetch) to fail
|
|
85
|
-
globalFetchSpy.mockResolvedValueOnce(new Response(null, { status: 500 }));
|
|
86
|
-
// Also mock getUploadInfo
|
|
87
|
-
jest.spyOn(uploader, 'getUploadInfo').mockResolvedValue({
|
|
88
|
-
uploadURL: 'https://example-upload.com/put'
|
|
89
|
-
});
|
|
90
|
-
const failingData = stringToUtf8Array('failing data');
|
|
91
|
-
await expect(uploader.publishFile({
|
|
92
|
-
file: { data: failingData, type: 'text/plain' },
|
|
93
|
-
retentionPeriod: 30
|
|
94
|
-
})).rejects.toThrow('File upload failed: HTTP 500');
|
|
95
|
-
});
|
|
96
|
-
it('should find a file and return metadata', async () => {
|
|
97
|
-
// This route goes through authFetch, not global fetch
|
|
98
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
99
|
-
status: 'success',
|
|
100
|
-
data: {
|
|
101
|
-
name: 'cdn/abc123',
|
|
102
|
-
size: '1024',
|
|
103
|
-
mimeType: 'text/plain',
|
|
104
|
-
expiryTime: 123456
|
|
105
|
-
}
|
|
106
|
-
}), { status: 200 }));
|
|
107
|
-
const fileData = await uploader.findFile('uhrp://some-hash');
|
|
108
|
-
expect(authFetchSpy).toHaveBeenCalledTimes(1);
|
|
109
|
-
expect(fileData.name).toBe('cdn/abc123');
|
|
110
|
-
expect(fileData.size).toBe('1024');
|
|
111
|
-
expect(fileData.mimeType).toBe('text/plain');
|
|
112
|
-
expect(fileData.expiryTime).toBe(123456);
|
|
113
|
-
});
|
|
114
|
-
it('should throw an error if findFile returns an error status', async () => {
|
|
115
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'error', code: 'ERR_NOT_FOUND', description: 'File not found' }), { status: 200 }));
|
|
116
|
-
await expect(uploader.findFile('uhrp://unknown-hash'))
|
|
117
|
-
.rejects
|
|
118
|
-
.toThrow('findFile returned an error: ERR_NOT_FOUND - File not found');
|
|
119
|
-
});
|
|
120
|
-
it('should list user uploads successfully', async () => {
|
|
121
|
-
// /list uses authFetch
|
|
122
|
-
const mockUploads = [
|
|
123
|
-
{ uhrpUrl: 'uhrp://hash1', expiryTime: 111111 },
|
|
124
|
-
{ uhrpUrl: 'uhrp://hash2', expiryTime: 222222 }
|
|
125
|
-
];
|
|
126
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'success', uploads: mockUploads }), { status: 200 }));
|
|
127
|
-
const result = await uploader.listUploads();
|
|
128
|
-
expect(authFetchSpy).toHaveBeenCalledTimes(1);
|
|
129
|
-
expect(result).toEqual(mockUploads);
|
|
130
|
-
});
|
|
131
|
-
it('should throw an error if listUploads returns an error', async () => {
|
|
132
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'error', code: 'ERR_INTERNAL', description: 'Something broke' }), { status: 200 }));
|
|
133
|
-
await expect(uploader.listUploads()).rejects.toThrow('listUploads returned an error: ERR_INTERNAL - Something broke');
|
|
134
|
-
});
|
|
135
|
-
it('should renew a file and return the new expiry info', async () => {
|
|
136
|
-
// /renew uses authFetch
|
|
137
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
138
|
-
status: 'success',
|
|
139
|
-
prevExpiryTime: 123,
|
|
140
|
-
newExpiryTime: 456,
|
|
141
|
-
amount: 99
|
|
142
|
-
}), { status: 200 }));
|
|
143
|
-
const renewal = await uploader.renewFile('uhrp://some-hash', 30);
|
|
144
|
-
expect(authFetchSpy).toHaveBeenCalledTimes(1);
|
|
145
|
-
expect(renewal.status).toBe('success');
|
|
146
|
-
expect(renewal.prevExpiryTime).toBe(123);
|
|
147
|
-
expect(renewal.newExpiryTime).toBe(456);
|
|
148
|
-
expect(renewal.amount).toBe(99);
|
|
149
|
-
});
|
|
150
|
-
it('should throw an error if renewFile returns error status JSON', async () => {
|
|
151
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'error', code: 'ERR_CANT_RENEW', description: 'Failed to renew' }), { status: 200 }));
|
|
152
|
-
await expect(uploader.renewFile('uhrp://some-other-hash', 15))
|
|
153
|
-
.rejects
|
|
154
|
-
.toThrow('renewFile returned an error: ERR_CANT_RENEW - Failed to renew');
|
|
155
|
-
});
|
|
156
|
-
it('should throw if renewFile request fails with non-200 status', async () => {
|
|
157
|
-
authFetchSpy.mockResolvedValueOnce(new Response(null, { status: 404 }));
|
|
158
|
-
await expect(uploader.renewFile('uhrp://ghost', 10))
|
|
159
|
-
.rejects
|
|
160
|
-
.toThrow('renewFile request failed: HTTP 404');
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
//# sourceMappingURL=StorageUploader.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StorageUploader.test.js","sourceRoot":"","sources":["../../../../../src/storage/__test/StorageUploader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
const index_js_1 = require("../index.js");
|
|
27
|
-
const Utils = __importStar(require("../../primitives/utils.js"));
|
|
28
|
-
const Hash = __importStar(require("../..//primitives/Hash.js"));
|
|
29
|
-
// Example data
|
|
30
|
-
const exampleHashHex = '1a5ec49a3f32cd56d19732e89bde5d81755ddc0fd8515dc8b226d47654139dca';
|
|
31
|
-
const exampleHash = Utils.toArray(exampleHashHex, 'hex');
|
|
32
|
-
const exampleFileHex = '687da27f04a112aa48f1cab2e7949f1eea4f7ba28319c1e999910cd561a634a05a3516e6db';
|
|
33
|
-
const exampleFile = Utils.toArray(exampleFileHex, 'hex');
|
|
34
|
-
const exampleURL = 'XUT6PqWb3GP3LR7dmBMCJwZ3oo5g1iGCF3CrpzyuJCemkGu1WGoq';
|
|
35
|
-
describe('StorageUtils', () => {
|
|
36
|
-
describe('getURLForHash', () => {
|
|
37
|
-
it('Creates the correct URL for the hash', () => {
|
|
38
|
-
const url = index_js_1.StorageUtils.getURLForHash(exampleHash);
|
|
39
|
-
expect(url).toBe(exampleURL);
|
|
40
|
-
});
|
|
41
|
-
it('Throws an error if hash length is invalid', () => {
|
|
42
|
-
// Get the length of a FILE (not a hash — wrong length!)
|
|
43
|
-
expect(() => index_js_1.StorageUtils.getURLForHash(exampleFile)).toThrow(new Error('Hash length must be 32 bytes (sha256)'));
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
describe('getURLForFile', () => {
|
|
47
|
-
it('Creates the correct URL for the file', () => {
|
|
48
|
-
const url = index_js_1.StorageUtils.getURLForFile(exampleFile);
|
|
49
|
-
expect(url).toEqual(exampleURL);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
describe('getHashFromURL', () => {
|
|
53
|
-
it('Decodes the URL to the correct hash', () => {
|
|
54
|
-
const hash = index_js_1.StorageUtils.getHashFromURL(exampleURL);
|
|
55
|
-
expect(Utils.toHex(hash)).toEqual(exampleHashHex);
|
|
56
|
-
});
|
|
57
|
-
it('Gets the same hash as getting one directly from the file', () => {
|
|
58
|
-
const hashA = index_js_1.StorageUtils.getHashFromURL(exampleURL);
|
|
59
|
-
const hashB = Hash.sha256(exampleFile);
|
|
60
|
-
expect(hashA).toEqual(hashB);
|
|
61
|
-
});
|
|
62
|
-
it('Throws an error if checksum is invalid', () => {
|
|
63
|
-
const badURL = 'XUU7cTfy6fA6q2neLDmzPqJnGB6o18PXKoGaWLPrH1SeWLKgdCKq';
|
|
64
|
-
expect(() => index_js_1.StorageUtils.getHashFromURL(badURL)).toThrow(new Error('Invalid checksum'));
|
|
65
|
-
});
|
|
66
|
-
it('Throws an error if URL length is invalid', () => {
|
|
67
|
-
const badURL = 'SomeBase58CheckTooShortOrTooLong';
|
|
68
|
-
expect(() => index_js_1.StorageUtils.getHashFromURL(badURL)).toThrow();
|
|
69
|
-
});
|
|
70
|
-
it('Throws an error if prefix is invalid', () => {
|
|
71
|
-
const invalidPrefixURL1 = 'AInvalidPrefixTestString1';
|
|
72
|
-
const invalidPrefixURL2 = 'AInvalidPrefixTestString2';
|
|
73
|
-
expect(() => index_js_1.StorageUtils.getHashFromURL(invalidPrefixURL1)).toThrow();
|
|
74
|
-
expect(() => index_js_1.StorageUtils.getHashFromURL(invalidPrefixURL2)).toThrow();
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
describe('isValidURL', () => {
|
|
78
|
-
it('Returns true when URL is valid', () => {
|
|
79
|
-
expect(index_js_1.StorageUtils.isValidURL(exampleURL)).toBe(true);
|
|
80
|
-
});
|
|
81
|
-
it('Returns false if checksum is invalid', () => {
|
|
82
|
-
const badURL = 'XUU7cTfy6fA6q2neLDmzPqJnGB6o18PXKoGaWLPrH1SeWLKgdCKq';
|
|
83
|
-
expect(index_js_1.StorageUtils.isValidURL(badURL)).toBe(false);
|
|
84
|
-
});
|
|
85
|
-
it('Returns false if URL length is invalid', () => {
|
|
86
|
-
const badURL = 'SomeBase58CheckTooShortOrTooLong';
|
|
87
|
-
expect(index_js_1.StorageUtils.isValidURL(badURL)).toBe(false);
|
|
88
|
-
});
|
|
89
|
-
it('Returns false if prefix is invalid', () => {
|
|
90
|
-
const badURL1 = 'AnotherInvalidPrefixTestString';
|
|
91
|
-
const badURL2 = 'YetAnotherInvalidPrefixTestString';
|
|
92
|
-
expect(index_js_1.StorageUtils.isValidURL(badURL1)).toBe(false);
|
|
93
|
-
expect(index_js_1.StorageUtils.isValidURL(badURL2)).toBe(false);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
//# sourceMappingURL=StorageUtils.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StorageUtils.test.js","sourceRoot":"","sources":["../../../../../src/storage/__test/StorageUtils.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { StorageDownloader } from '../StorageDownloader.js';
|
|
2
|
-
import { StorageUtils } from '../index.js';
|
|
3
|
-
import { LookupResolver } from '../../overlay-tools/index.js';
|
|
4
|
-
import Transaction from '../../transaction/Transaction.js';
|
|
5
|
-
import PushDrop from '../../script/templates/PushDrop.js';
|
|
6
|
-
import { Utils } from '../../primitives/index.js';
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
jest.restoreAllMocks();
|
|
9
|
-
});
|
|
10
|
-
describe('StorageDownloader', () => {
|
|
11
|
-
let downloader;
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
// Create a fresh instance
|
|
14
|
-
downloader = new StorageDownloader();
|
|
15
|
-
});
|
|
16
|
-
describe('resolve()', () => {
|
|
17
|
-
it('throws if the lookup response is not "output-list"', async () => {
|
|
18
|
-
// Mock the LookupResolver to return something invalid
|
|
19
|
-
jest.spyOn(LookupResolver.prototype, 'query').mockResolvedValue({
|
|
20
|
-
type: 'something-else',
|
|
21
|
-
outputs: []
|
|
22
|
-
});
|
|
23
|
-
await expect(downloader.resolve('fakeUhrpUrl'))
|
|
24
|
-
.rejects
|
|
25
|
-
.toThrow('Lookup answer must be an output list');
|
|
26
|
-
});
|
|
27
|
-
it('decodes each output with Transaction.fromBEEF and PushDrop.decode', async () => {
|
|
28
|
-
// 1) Mock lookup response
|
|
29
|
-
jest.spyOn(LookupResolver.prototype, 'query').mockResolvedValue({
|
|
30
|
-
type: 'output-list',
|
|
31
|
-
outputs: [
|
|
32
|
-
{ beef: 'fake-beef-a', outputIndex: 0 },
|
|
33
|
-
{ beef: 'fake-beef-b', outputIndex: 1 }
|
|
34
|
-
]
|
|
35
|
-
});
|
|
36
|
-
// 2) Mock Transaction.fromBEEF -> returns a dummy transaction
|
|
37
|
-
jest.spyOn(Transaction, 'fromBEEF').mockImplementation(() => {
|
|
38
|
-
// Each transaction might have multiple outputs; we only care about `outputIndex`
|
|
39
|
-
return {
|
|
40
|
-
outputs: [
|
|
41
|
-
{ lockingScript: {} },
|
|
42
|
-
{ lockingScript: {} } // index 1
|
|
43
|
-
]
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
// 3) Mock PushDrop.decode -> returns { fields: number[][] }
|
|
47
|
-
jest.spyOn(PushDrop, 'decode').mockImplementation(() => {
|
|
48
|
-
// The decode function returns an object with `fields`,
|
|
49
|
-
return {
|
|
50
|
-
lockingPublicKey: {},
|
|
51
|
-
fields: [
|
|
52
|
-
[11],
|
|
53
|
-
[22],
|
|
54
|
-
[104, 116, 116, 112, 58, 47, 47, 97, 46, 99, 111, 109]
|
|
55
|
-
]
|
|
56
|
-
};
|
|
57
|
-
});
|
|
58
|
-
// 4) Mock Utils.toUTF8 to convert that number[] to a string
|
|
59
|
-
jest.spyOn(Utils, 'toUTF8').mockReturnValue('http://a.com');
|
|
60
|
-
const resolved = await downloader.resolve('fakeUhrpUrl');
|
|
61
|
-
expect(resolved).toEqual(['http://a.com', 'http://a.com']);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
describe('download()', () => {
|
|
65
|
-
it('throws if UHRP URL is invalid', async () => {
|
|
66
|
-
jest.spyOn(StorageUtils, 'isValidURL').mockReturnValue(false);
|
|
67
|
-
await expect(downloader.download('invalidUrl'))
|
|
68
|
-
.rejects
|
|
69
|
-
.toThrow('Invalid parameter UHRP url');
|
|
70
|
-
});
|
|
71
|
-
it('throws if no hosts are found', async () => {
|
|
72
|
-
// Valid UHRP URL
|
|
73
|
-
jest.spyOn(StorageUtils, 'isValidURL').mockReturnValue(true);
|
|
74
|
-
// Return some random 32-byte hash so we can pass the check
|
|
75
|
-
jest.spyOn(StorageUtils, 'getHashFromURL').mockReturnValue(new Array(32).fill(0));
|
|
76
|
-
// Force resolve() to return an empty array
|
|
77
|
-
jest.spyOn(downloader, 'resolve').mockResolvedValue([]);
|
|
78
|
-
await expect(downloader.download('validButUnhostedUrl'))
|
|
79
|
-
.rejects
|
|
80
|
-
.toThrow('No one currently hosts this file!');
|
|
81
|
-
});
|
|
82
|
-
it('downloads successfully from the first working host', async () => {
|
|
83
|
-
jest.spyOn(StorageUtils, 'isValidURL').mockReturnValue(true);
|
|
84
|
-
const knownHash = [
|
|
85
|
-
102, 104, 122, 173, 248, 98, 189, 119, 108, 143,
|
|
86
|
-
193, 139, 142, 159, 142, 32, 8, 151, 20, 133,
|
|
87
|
-
110, 226, 51, 179, 144, 42, 89, 29, 13, 95,
|
|
88
|
-
41, 37
|
|
89
|
-
];
|
|
90
|
-
jest.spyOn(StorageUtils, 'getHashFromURL').mockReturnValue(knownHash);
|
|
91
|
-
// Suppose two possible download URLs
|
|
92
|
-
jest.spyOn(downloader, 'resolve').mockResolvedValue([
|
|
93
|
-
'http://host1/404',
|
|
94
|
-
'http://host2/ok'
|
|
95
|
-
]);
|
|
96
|
-
// The first fetch -> 404, second fetch -> success
|
|
97
|
-
const fetchSpy = jest.spyOn(global, 'fetch')
|
|
98
|
-
.mockResolvedValueOnce(new Response(null, { status: 404 }))
|
|
99
|
-
.mockResolvedValueOnce(new Response(new Uint8Array(32).fill(0), {
|
|
100
|
-
status: 200,
|
|
101
|
-
headers: { 'Content-Type': 'application/test' }
|
|
102
|
-
}));
|
|
103
|
-
const result = await downloader.download('validUrl');
|
|
104
|
-
expect(fetchSpy).toHaveBeenCalledTimes(2);
|
|
105
|
-
expect(result).toEqual({
|
|
106
|
-
data: new Array(32).fill(0),
|
|
107
|
-
mimeType: 'application/test'
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
it('throws if content hash mismatches the UHRP hash', async () => {
|
|
111
|
-
jest.spyOn(StorageUtils, 'isValidURL').mockReturnValue(true);
|
|
112
|
-
// The expected hash is all zeros
|
|
113
|
-
jest.spyOn(StorageUtils, 'getHashFromURL').mockReturnValue(new Array(32).fill(0));
|
|
114
|
-
// One potential host
|
|
115
|
-
jest.spyOn(downloader, 'resolve').mockResolvedValue([
|
|
116
|
-
'http://bad-content.test'
|
|
117
|
-
]);
|
|
118
|
-
// The fetch returns 32 bytes of all 1's => hash mismatch
|
|
119
|
-
jest.spyOn(global, 'fetch').mockResolvedValue(new Response(new Uint8Array(32).fill(1), { status: 200 }));
|
|
120
|
-
await expect(downloader.download('validButBadHashUrl'))
|
|
121
|
-
.rejects
|
|
122
|
-
.toThrow();
|
|
123
|
-
});
|
|
124
|
-
it('throws if all hosts fail or mismatch', async () => {
|
|
125
|
-
jest.spyOn(StorageUtils, 'isValidURL').mockReturnValue(true);
|
|
126
|
-
jest.spyOn(StorageUtils, 'getHashFromURL').mockReturnValue(new Array(32).fill(0));
|
|
127
|
-
jest.spyOn(downloader, 'resolve').mockResolvedValue([
|
|
128
|
-
'http://host1.test',
|
|
129
|
-
'http://host2.test'
|
|
130
|
-
]);
|
|
131
|
-
// Both fetches fail with 500 or something >=400
|
|
132
|
-
jest.spyOn(global, 'fetch').mockResolvedValue(new Response(null, { status: 500 }));
|
|
133
|
-
await expect(downloader.download('validButNoGoodHostUrl'))
|
|
134
|
-
.rejects
|
|
135
|
-
.toThrow('Unable to download content from validButNoGoodHostUrl');
|
|
136
|
-
});
|
|
137
|
-
it('throws if all entries are expired', async () => {
|
|
138
|
-
const currentTime = Math.floor(Date.now());
|
|
139
|
-
jest.spyOn(LookupResolver.prototype, 'query').mockResolvedValue({
|
|
140
|
-
type: 'output-list',
|
|
141
|
-
outputs: [
|
|
142
|
-
{ beef: 'fake-beef-a', outputIndex: 0 },
|
|
143
|
-
{ beef: 'fake-beef-b', outputIndex: 1 }
|
|
144
|
-
]
|
|
145
|
-
});
|
|
146
|
-
jest.spyOn(Transaction, 'fromBEEF').mockImplementation(() => {
|
|
147
|
-
return {
|
|
148
|
-
outputs: [
|
|
149
|
-
{ lockingScript: {} },
|
|
150
|
-
{ lockingScript: {} }
|
|
151
|
-
]
|
|
152
|
-
};
|
|
153
|
-
});
|
|
154
|
-
jest.spyOn(PushDrop, 'decode').mockImplementation(() => {
|
|
155
|
-
return {
|
|
156
|
-
lockingPublicKey: {},
|
|
157
|
-
fields: [[], [], [], [currentTime - 100]]
|
|
158
|
-
};
|
|
159
|
-
});
|
|
160
|
-
await expect(downloader.resolve('expiredUhrpUrl'))
|
|
161
|
-
.resolves
|
|
162
|
-
.toEqual(["", ""]);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
//# sourceMappingURL=StorageDownloader.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StorageDownloader.test.js","sourceRoot":"","sources":["../../../../../src/storage/__test/StorageDownloader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { StorageUploader } from '../StorageUploader.js';
|
|
2
|
-
import * as StorageUtils from '../StorageUtils.js';
|
|
3
|
-
import WalletClient from '../../wallet/WalletClient.js';
|
|
4
|
-
/**
|
|
5
|
-
* A helper for converting a string to a number[] of UTF-8 bytes
|
|
6
|
-
*/
|
|
7
|
-
function stringToUtf8Array(str) {
|
|
8
|
-
return Array.from(new TextEncoder().encode(str));
|
|
9
|
-
}
|
|
10
|
-
describe('StorageUploader Tests', () => {
|
|
11
|
-
let uploader;
|
|
12
|
-
let walletClient;
|
|
13
|
-
// We'll have TWO spies:
|
|
14
|
-
let authFetchSpy;
|
|
15
|
-
let globalFetchSpy;
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
walletClient = new WalletClient('json-api', 'non-admin.com');
|
|
18
|
-
uploader = new StorageUploader({
|
|
19
|
-
storageURL: 'https://example.test.system',
|
|
20
|
-
wallet: walletClient
|
|
21
|
-
});
|
|
22
|
-
// 1) Spy on the "authFetch.fetch" calls for /find, /list, /renew
|
|
23
|
-
authFetchSpy = jest
|
|
24
|
-
.spyOn(uploader['authFetch'], 'fetch')
|
|
25
|
-
.mockResolvedValue(new Response(null, { status: 200 }));
|
|
26
|
-
// 2) Spy on the global "fetch" calls for file upload (uploadFile)
|
|
27
|
-
globalFetchSpy = jest
|
|
28
|
-
.spyOn(global, 'fetch')
|
|
29
|
-
.mockResolvedValue(new Response(null, { status: 200 }));
|
|
30
|
-
});
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
jest.restoreAllMocks();
|
|
33
|
-
});
|
|
34
|
-
it('should upload a file, produce a valid UHRP URL, and decode it to the known SHA-256', async () => {
|
|
35
|
-
const data = stringToUtf8Array('Hello, world!');
|
|
36
|
-
// Mock out getUploadInfo so we can control the returned upload/public URLs
|
|
37
|
-
jest.spyOn(uploader, 'getUploadInfo').mockResolvedValue({
|
|
38
|
-
uploadURL: 'https://example-upload.com/put'
|
|
39
|
-
});
|
|
40
|
-
const result = await uploader.publishFile({
|
|
41
|
-
file: { data, type: 'text/plain' },
|
|
42
|
-
retentionPeriod: 7
|
|
43
|
-
});
|
|
44
|
-
// This direct upload uses global.fetch, not authFetch
|
|
45
|
-
expect(globalFetchSpy).toHaveBeenCalledTimes(1);
|
|
46
|
-
// Check the result
|
|
47
|
-
expect(StorageUtils.isValidURL(result.uhrpURL)).toBe(true);
|
|
48
|
-
expect(result.published).toBe(true);
|
|
49
|
-
const url = StorageUtils.getHashFromURL(result.uhrpURL);
|
|
50
|
-
const firstFour = url.slice(0, 4)
|
|
51
|
-
.map(b => b.toString(16).padStart(2, '0'))
|
|
52
|
-
.join('');
|
|
53
|
-
expect(firstFour).toHaveLength(8);
|
|
54
|
-
});
|
|
55
|
-
it('should throw if the upload fails with HTTP 500', async () => {
|
|
56
|
-
// Force the direct upload (global fetch) to fail
|
|
57
|
-
globalFetchSpy.mockResolvedValueOnce(new Response(null, { status: 500 }));
|
|
58
|
-
// Also mock getUploadInfo
|
|
59
|
-
jest.spyOn(uploader, 'getUploadInfo').mockResolvedValue({
|
|
60
|
-
uploadURL: 'https://example-upload.com/put'
|
|
61
|
-
});
|
|
62
|
-
const failingData = stringToUtf8Array('failing data');
|
|
63
|
-
await expect(uploader.publishFile({
|
|
64
|
-
file: { data: failingData, type: 'text/plain' },
|
|
65
|
-
retentionPeriod: 30
|
|
66
|
-
})).rejects.toThrow('File upload failed: HTTP 500');
|
|
67
|
-
});
|
|
68
|
-
it('should find a file and return metadata', async () => {
|
|
69
|
-
// This route goes through authFetch, not global fetch
|
|
70
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
71
|
-
status: 'success',
|
|
72
|
-
data: {
|
|
73
|
-
name: 'cdn/abc123',
|
|
74
|
-
size: '1024',
|
|
75
|
-
mimeType: 'text/plain',
|
|
76
|
-
expiryTime: 123456
|
|
77
|
-
}
|
|
78
|
-
}), { status: 200 }));
|
|
79
|
-
const fileData = await uploader.findFile('uhrp://some-hash');
|
|
80
|
-
expect(authFetchSpy).toHaveBeenCalledTimes(1);
|
|
81
|
-
expect(fileData.name).toBe('cdn/abc123');
|
|
82
|
-
expect(fileData.size).toBe('1024');
|
|
83
|
-
expect(fileData.mimeType).toBe('text/plain');
|
|
84
|
-
expect(fileData.expiryTime).toBe(123456);
|
|
85
|
-
});
|
|
86
|
-
it('should throw an error if findFile returns an error status', async () => {
|
|
87
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'error', code: 'ERR_NOT_FOUND', description: 'File not found' }), { status: 200 }));
|
|
88
|
-
await expect(uploader.findFile('uhrp://unknown-hash'))
|
|
89
|
-
.rejects
|
|
90
|
-
.toThrow('findFile returned an error: ERR_NOT_FOUND - File not found');
|
|
91
|
-
});
|
|
92
|
-
it('should list user uploads successfully', async () => {
|
|
93
|
-
// /list uses authFetch
|
|
94
|
-
const mockUploads = [
|
|
95
|
-
{ uhrpUrl: 'uhrp://hash1', expiryTime: 111111 },
|
|
96
|
-
{ uhrpUrl: 'uhrp://hash2', expiryTime: 222222 }
|
|
97
|
-
];
|
|
98
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'success', uploads: mockUploads }), { status: 200 }));
|
|
99
|
-
const result = await uploader.listUploads();
|
|
100
|
-
expect(authFetchSpy).toHaveBeenCalledTimes(1);
|
|
101
|
-
expect(result).toEqual(mockUploads);
|
|
102
|
-
});
|
|
103
|
-
it('should throw an error if listUploads returns an error', async () => {
|
|
104
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'error', code: 'ERR_INTERNAL', description: 'Something broke' }), { status: 200 }));
|
|
105
|
-
await expect(uploader.listUploads()).rejects.toThrow('listUploads returned an error: ERR_INTERNAL - Something broke');
|
|
106
|
-
});
|
|
107
|
-
it('should renew a file and return the new expiry info', async () => {
|
|
108
|
-
// /renew uses authFetch
|
|
109
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({
|
|
110
|
-
status: 'success',
|
|
111
|
-
prevExpiryTime: 123,
|
|
112
|
-
newExpiryTime: 456,
|
|
113
|
-
amount: 99
|
|
114
|
-
}), { status: 200 }));
|
|
115
|
-
const renewal = await uploader.renewFile('uhrp://some-hash', 30);
|
|
116
|
-
expect(authFetchSpy).toHaveBeenCalledTimes(1);
|
|
117
|
-
expect(renewal.status).toBe('success');
|
|
118
|
-
expect(renewal.prevExpiryTime).toBe(123);
|
|
119
|
-
expect(renewal.newExpiryTime).toBe(456);
|
|
120
|
-
expect(renewal.amount).toBe(99);
|
|
121
|
-
});
|
|
122
|
-
it('should throw an error if renewFile returns error status JSON', async () => {
|
|
123
|
-
authFetchSpy.mockResolvedValueOnce(new Response(JSON.stringify({ status: 'error', code: 'ERR_CANT_RENEW', description: 'Failed to renew' }), { status: 200 }));
|
|
124
|
-
await expect(uploader.renewFile('uhrp://some-other-hash', 15))
|
|
125
|
-
.rejects
|
|
126
|
-
.toThrow('renewFile returned an error: ERR_CANT_RENEW - Failed to renew');
|
|
127
|
-
});
|
|
128
|
-
it('should throw if renewFile request fails with non-200 status', async () => {
|
|
129
|
-
authFetchSpy.mockResolvedValueOnce(new Response(null, { status: 404 }));
|
|
130
|
-
await expect(uploader.renewFile('uhrp://ghost', 10))
|
|
131
|
-
.rejects
|
|
132
|
-
.toThrow('renewFile request failed: HTTP 404');
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
//# sourceMappingURL=StorageUploader.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StorageUploader.test.js","sourceRoot":"","sources":["../../../../../src/storage/__test/StorageUploader.test.ts"],"names":[],"mappings":"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"}
|