@twin.org/blob-storage-connector-ipfs 0.0.3-next.13 → 0.0.3-next.15
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 +1 -1
- package/dist/es/ipfsBlobStorageConnector.js +7 -13
- package/dist/es/ipfsBlobStorageConnector.js.map +1 -1
- package/dist/types/ipfsBlobStorageConnector.d.ts +1 -1
- package/docs/changelog.md +28 -0
- package/docs/reference/classes/IpfsBlobStorageConnector.md +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npm install @twin.org/blob-storage-connector-ipfs
|
|
|
13
13
|
To perform testing of this component it may be necessary to launch a local instance to communicate with.
|
|
14
14
|
|
|
15
15
|
```shell
|
|
16
|
-
docker run -d --name twin-blob-storage-ipfs -p
|
|
16
|
+
docker run -d --name twin-blob-storage-ipfs -p 24001:4001 -p 24001:4001/udp -p 28080:8080 -p 25001:5001 ipfs/kubo:latest
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Examples
|
|
@@ -150,14 +150,9 @@ export class IpfsBlobStorageConnector {
|
|
|
150
150
|
}
|
|
151
151
|
};
|
|
152
152
|
this.addSecurity(fetchOptions);
|
|
153
|
-
const
|
|
154
|
-
if (!
|
|
155
|
-
|
|
156
|
-
if (Is.object(resp) &&
|
|
157
|
-
Is.stringValue(resp.Message) &&
|
|
158
|
-
resp.Message.includes("not found")) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
153
|
+
const pinResponse = await fetch(`${this._config.apiUrl}/pin/ls?arg=${ipfsHash}`, fetchOptions);
|
|
154
|
+
if (!pinResponse.ok) {
|
|
155
|
+
return undefined;
|
|
161
156
|
}
|
|
162
157
|
const response = await fetch(`${this._config.apiUrl}/cat?arg=${ipfsHash}`, fetchOptions);
|
|
163
158
|
if (response.ok) {
|
|
@@ -224,7 +219,7 @@ export class IpfsBlobStorageConnector {
|
|
|
224
219
|
}
|
|
225
220
|
/**
|
|
226
221
|
* Remove all blobs from the storage.
|
|
227
|
-
* @returns
|
|
222
|
+
* @returns A promise that resolves when all pinned blobs have been unpinned and garbage collected.
|
|
228
223
|
*/
|
|
229
224
|
async empty() {
|
|
230
225
|
try {
|
|
@@ -297,16 +292,15 @@ export class IpfsBlobStorageConnector {
|
|
|
297
292
|
if (response.ok) {
|
|
298
293
|
return true;
|
|
299
294
|
}
|
|
300
|
-
|
|
301
|
-
throw new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, "fetchFail", error);
|
|
295
|
+
return false;
|
|
302
296
|
}
|
|
303
297
|
catch (err) {
|
|
304
298
|
throw new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, "removeBlobFailed", undefined, err);
|
|
305
299
|
}
|
|
306
300
|
}
|
|
307
301
|
/**
|
|
308
|
-
* Add the security to the request.
|
|
309
|
-
* @param requestInit The request options.
|
|
302
|
+
* Add the security headers to the request if a bearer token is configured.
|
|
303
|
+
* @param requestInit The request options to augment with security headers.
|
|
310
304
|
* @internal
|
|
311
305
|
*/
|
|
312
306
|
addSecurity(requestInit) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipfsBlobStorageConnector.js","sourceRoot":"","sources":["../../src/ipfsBlobStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IBlobStorageConnector } from \"@twin.org/blob-storage-models\";\nimport { ContextIdHelper, ContextIdStore } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tHealthStatus,\n\tIs,\n\tStringHelper,\n\tUrn,\n\ttype IHealth\n} from \"@twin.org/core\";\nimport { Blake2b } from \"@twin.org/crypto\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HeaderHelper, HeaderTypes, HttpMethod, MimeTypes } from \"@twin.org/web\";\nimport type { IIpfsBlobStorageConnectorConfig } from \"./models/IIpfsBlobStorageConnectorConfig.js\";\nimport type { IIpfsBlobStorageConnectorConstructorOptions } from \"./models/IIpfsBlobStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing blob storage operations on IPFS.\n * See https://docs.ipfs.tech/reference/kubo/rpc/ for more information.\n */\nexport class IpfsBlobStorageConnector implements IBlobStorageConnector {\n\t/**\n\t * The namespace for the items.\n\t */\n\tpublic static readonly NAMESPACE: string = \"ipfs\";\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<IpfsBlobStorageConnector>();\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: IIpfsBlobStorageConnectorConfig;\n\n\t/**\n\t * The keys to use from the context ids to create partitions.\n\t * @internal\n\t */\n\tprivate readonly _partitionContextIds?: string[];\n\n\t/**\n\t * Create a new instance of IpfsBlobStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IIpfsBlobStorageConnectorConstructorOptions) {\n\t\tGuards.object(IpfsBlobStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.object<IIpfsBlobStorageConnectorConfig>(\n\t\t\tIpfsBlobStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tIpfsBlobStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.apiUrl),\n\t\t\toptions.config.apiUrl\n\t\t);\n\n\t\tthis._config = options.config;\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\t\tthis._config.apiUrl = StringHelper.trimTrailingSlashes(this._config.apiUrl);\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn IpfsBlobStorageConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Returns the health status of the component.\n\t * @returns The health status of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(fetchOptions);\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/version`, fetchOptions);\n\t\t\tif (response.ok) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tapiUrl: this._config.apiUrl\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t}\n\t\t} catch {}\n\t\treturn [\n\t\t\t{\n\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\tmessage: \"healthCheckFailed\",\n\t\t\t\tdata: {\n\t\t\t\t\tapiUrl: this._config.apiUrl\n\t\t\t\t}\n\t\t\t}\n\t\t];\n\t}\n\n\t/**\n\t * Set the blob.\n\t * @param blob The data for the blob.\n\t * @returns The id of the stored blob in urn format.\n\t */\n\tpublic async set(blob: Uint8Array): Promise<string> {\n\t\tGuards.uint8Array(IpfsBlobStorageConnector.CLASS_NAME, nameof(blob), blob);\n\n\t\ttry {\n\t\t\tconst formBlob = new Blob([new Uint8Array(blob)], { type: MimeTypes.OctetStream });\n\t\t\tconst formData = new FormData();\n\t\t\tformData.append(\"file\", formBlob);\n\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\tbody: formData,\n\t\t\t\theaders: {\n\t\t\t\t\t[HeaderTypes.Accept]: MimeTypes.Json,\n\t\t\t\t\t[HeaderTypes.ContentDisposition]: \"form-data\"\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/add?pin=true`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = (await response.json()) as {\n\t\t\t\t\tName: string;\n\t\t\t\t\tHash: string;\n\t\t\t\t\tSize: string;\n\t\t\t\t};\n\n\t\t\t\tconst partitionSegment = await this.buildPartitionSegment();\n\t\t\t\tconst urnParts = Is.stringValue(partitionSegment)\n\t\t\t\t\t? [result.Hash, partitionSegment]\n\t\t\t\t\t: [result.Hash];\n\n\t\t\t\treturn `blob:${new Urn(IpfsBlobStorageConnector.NAMESPACE, urnParts).toString()}`;\n\t\t\t}\n\n\t\t\tconst error = await response.json();\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"fetchFail\", error);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"setBlobFailed\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Get the blob.\n\t * @param id The id of the blob to get in urn format.\n\t * @returns The data for the blob if it can be found or undefined.\n\t */\n\tpublic async get(id: string): Promise<Uint8Array | undefined> {\n\t\tUrn.guard(IpfsBlobStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tconst urnParsed = Urn.fromValidString(id);\n\n\t\tif (urnParsed.namespaceMethod() !== IpfsBlobStorageConnector.NAMESPACE) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"namespaceMismatch\", {\n\t\t\t\tnamespace: IpfsBlobStorageConnector.NAMESPACE,\n\t\t\t\tid\n\t\t\t});\n\t\t}\n\n\t\tconst partitionSegment = await this.buildPartitionSegment();\n\t\tconst storedPartitionSegment = Is.stringValue(urnParsed.namespaceSpecific(2))\n\t\t\t? urnParsed.namespaceSpecific(2)\n\t\t\t: undefined;\n\n\t\tif (partitionSegment !== storedPartitionSegment) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst ipfsHash = urnParsed.namespaceSpecific(1).split(\":\")[0];\n\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst responseStat = await fetch(\n\t\t\t\t`${this._config.apiUrl}/block/stat?arg=${ipfsHash}&local=true`,\n\t\t\t\tfetchOptions\n\t\t\t);\n\n\t\t\tif (!responseStat.ok) {\n\t\t\t\tconst resp = await responseStat.json();\n\t\t\t\tif (\n\t\t\t\t\tIs.object<{ Message: string }>(resp) &&\n\t\t\t\t\tIs.stringValue(resp.Message) &&\n\t\t\t\t\tresp.Message.includes(\"not found\")\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/cat?arg=${ipfsHash}`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = await response.arrayBuffer();\n\t\t\t\treturn new Uint8Array(result);\n\t\t\t}\n\n\t\t\tconst error = await response.json();\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"fetchFail\", error);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"getBlobFailed\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Teardown the component and remove any resources it created.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the teardown process was successful.\n\t */\n\tpublic async teardown(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tawait nodeLogging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\tmessage: \"storeTearingDown\"\n\t\t});\n\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/pin/ls`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = (await response.json()) as { Keys: { [cid: string]: unknown } };\n\n\t\t\t\tfor (const cid of Object.keys(result.Keys)) {\n\t\t\t\t\tconst unpinFetchOptions: RequestInit = {\n\t\t\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tthis.addSecurity(unpinFetchOptions);\n\t\t\t\t\tawait fetch(`${this._config.apiUrl}/pin/rm?arg=${cid}`, unpinFetchOptions);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\tmessage: \"storeTornDown\"\n\t\t\t});\n\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\tmessage: \"teardownFailed\",\n\t\t\t\terror: BaseError.fromError(err)\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Remove all blobs from the storage.\n\t * @returns Nothing.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/pin/ls`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = (await response.json()) as { Keys: { [cid: string]: unknown } };\n\n\t\t\t\tfor (const cid of Object.keys(result.Keys)) {\n\t\t\t\t\tconst unpinFetchOptions: RequestInit = {\n\t\t\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tthis.addSecurity(unpinFetchOptions);\n\t\t\t\t\tawait fetch(`${this._config.apiUrl}/pin/rm?arg=${cid}`, unpinFetchOptions);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst gcFetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(gcFetchOptions);\n\t\t\tconst gcResponse = await fetch(`${this._config.apiUrl}/repo/gc`, gcFetchOptions);\n\t\t\tawait gcResponse.text();\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"emptyFailed\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Remove the blob.\n\t * @param id The id of the blob to remove in urn format.\n\t * @returns True if the blob was found.\n\t */\n\tpublic async remove(id: string): Promise<boolean> {\n\t\tUrn.guard(IpfsBlobStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tconst urnParsed = Urn.fromValidString(id);\n\n\t\tif (urnParsed.namespaceMethod() !== IpfsBlobStorageConnector.NAMESPACE) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"namespaceMismatch\", {\n\t\t\t\tnamespace: IpfsBlobStorageConnector.NAMESPACE,\n\t\t\t\tid\n\t\t\t});\n\t\t}\n\n\t\tconst partitionSegment = await this.buildPartitionSegment();\n\t\tconst storedPartitionSegment = Is.stringValue(urnParsed.namespaceSpecific(2))\n\t\t\t? urnParsed.namespaceSpecific(2)\n\t\t\t: undefined;\n\n\t\tif (partitionSegment !== storedPartitionSegment) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst ipfsHash = urnParsed.namespaceSpecific(1).split(\":\")[0];\n\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/pin/rm?arg=${ipfsHash}`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst error = await response.json();\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"fetchFail\", error);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\t\"removeBlobFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Add the security to the request.\n\t * @param requestInit The request options.\n\t * @internal\n\t */\n\tprivate addSecurity(requestInit: RequestInit): void {\n\t\tif (Is.stringValue(this._config.bearerToken)) {\n\t\t\trequestInit.headers = {\n\t\t\t\t...requestInit.headers,\n\t\t\t\t[HeaderTypes.Authorization]: HeaderHelper.createBearer(this._config.bearerToken)\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Build the partition segment from the current context.\n\t * @returns The hex-encoded Blake2b hash of the partition key, or undefined if no partition applies.\n\t * @internal\n\t */\n\tprivate async buildPartitionSegment(): Promise<string | undefined> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tif (Is.stringValue(partitionKey)) {\n\t\t\treturn Converter.bytesToHex(Blake2b.sum256(Converter.utf8ToBytes(partitionKey)));\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ipfsBlobStorageConnector.js","sourceRoot":"","sources":["../../src/ipfsBlobStorageConnector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,EAAE,EACF,YAAY,EACZ,GAAG,EAEH,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAIjF;;;GAGG;AACH,MAAM,OAAO,wBAAwB;IACpC;;OAEG;IACI,MAAM,CAAU,SAAS,GAAW,MAAM,CAAC;IAElD;;OAEG;IACI,MAAM,CAAU,UAAU,8BAA8C;IAE/E;;;OAGG;IACc,OAAO,CAAkC;IAE1D;;;OAGG;IACc,oBAAoB,CAAY;IAEjD;;;OAGG;IACH,YAAY,OAAoD;QAC/D,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,UAAU,aAAmB,OAAO,CAAC,CAAC;QAC7E,MAAM,CAAC,MAAM,CACZ,wBAAwB,CAAC,UAAU,oBAEnC,OAAO,CAAC,MAAM,CACd,CAAC;QACF,MAAM,CAAC,WAAW,CACjB,wBAAwB,CAAC,UAAU,2BAEnC,OAAO,CAAC,MAAM,CAAC,MAAM,CACrB,CAAC;QAEF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,wBAAwB,CAAC,UAAU,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,MAAM;QAClB,IAAI,CAAC;YACJ,MAAM,YAAY,GAAgB;gBACjC,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,OAAO,EAAE;oBACR,MAAM,EAAE,SAAS,CAAC,IAAI;iBACtB;aACD,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,UAAU,EAAE,YAAY,CAAC,CAAC;YAC7E,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO;oBACN;wBACC,MAAM,EAAE,wBAAwB,CAAC,UAAU;wBAC3C,MAAM,EAAE,YAAY,CAAC,EAAE;wBACvB,WAAW,EAAE,mBAAmB;wBAChC,IAAI,EAAE;4BACL,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;yBAC3B;qBACD;iBACD,CAAC;YACH,CAAC;QACF,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,OAAO;YACN;gBACC,MAAM,EAAE,wBAAwB,CAAC,UAAU;gBAC3C,MAAM,EAAE,YAAY,CAAC,KAAK;gBAC1B,WAAW,EAAE,mBAAmB;gBAChC,OAAO,EAAE,mBAAmB;gBAC5B,IAAI,EAAE;oBACL,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;iBAC3B;aACD;SACD,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,GAAG,CAAC,IAAgB;QAChC,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,UAAU,UAAgB,IAAI,CAAC,CAAC;QAE3E,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;YACnF,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;YAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAElC,MAAM,YAAY,GAAgB;gBACjC,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE;oBACR,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI;oBACpC,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,WAAW;iBAC7C;aACD,CAAC;YAEF,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAE/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,eAAe,EAAE,YAAY,CAAC,CAAC;YAElF,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAIpC,CAAC;gBAEF,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC5D,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,CAAC,gBAAgB,CAAC;oBAChD,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC;oBACjC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAEjB,OAAO,QAAQ,IAAI,GAAG,CAAC,wBAAwB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;YACnF,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,YAAY,CAAC,wBAAwB,CAAC,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,YAAY,CAAC,wBAAwB,CAAC,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9F,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,GAAG,CAAC,EAAU;QAC1B,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,UAAU,QAAc,EAAE,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAE1C,IAAI,SAAS,CAAC,eAAe,EAAE,KAAK,wBAAwB,CAAC,SAAS,EAAE,CAAC;YACxE,MAAM,IAAI,YAAY,CAAC,wBAAwB,CAAC,UAAU,EAAE,mBAAmB,EAAE;gBAChF,SAAS,EAAE,wBAAwB,CAAC,SAAS;gBAC7C,EAAE;aACF,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC5D,MAAM,sBAAsB,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YAC5E,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAChC,CAAC,CAAC,SAAS,CAAC;QAEb,IAAI,gBAAgB,KAAK,sBAAsB,EAAE,CAAC;YACjD,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9D,IAAI,CAAC;YACJ,MAAM,YAAY,GAAgB;gBACjC,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,OAAO,EAAE;oBACR,MAAM,EAAE,SAAS,CAAC,IAAI;iBACtB;aACD,CAAC;YAEF,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAE/B,MAAM,WAAW,GAAG,MAAM,KAAK,CAC9B,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,eAAe,QAAQ,EAAE,EAC/C,YAAY,CACZ,CAAC;YAEF,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;gBACrB,OAAO,SAAS,CAAC;YAClB,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,YAAY,QAAQ,EAAE,EAAE,YAAY,CAAC,CAAC;YAEzF,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAC5C,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,YAAY,CAAC,wBAAwB,CAAC,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,YAAY,CAAC,wBAAwB,CAAC,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9F,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,QAAQ,CAAC,wBAAiC;QACtD,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,CAAoB,wBAAwB,CAAC,CAAC;QAE9F,MAAM,WAAW,EAAE,GAAG,CAAC;YACtB,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,wBAAwB,CAAC,UAAU;YAC3C,OAAO,EAAE,kBAAkB;SAC3B,CAAC,CAAC;QAEH,IAAI,CAAC;YACJ,MAAM,YAAY,GAAgB;gBACjC,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,OAAO,EAAE;oBACR,MAAM,EAAE,SAAS,CAAC,IAAI;iBACtB;aACD,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAE/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,SAAS,EAAE,YAAY,CAAC,CAAC;YAE5E,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyC,CAAC;gBAE/E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5C,MAAM,iBAAiB,GAAgB;wBACtC,MAAM,EAAE,UAAU,CAAC,IAAI;wBACvB,OAAO,EAAE;4BACR,MAAM,EAAE,SAAS,CAAC,IAAI;yBACtB;qBACD,CAAC;oBACF,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;oBACpC,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,eAAe,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;gBAC5E,CAAC;YACF,CAAC;YAED,MAAM,WAAW,EAAE,GAAG,CAAC;gBACtB,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,wBAAwB,CAAC,UAAU;gBAC3C,OAAO,EAAE,eAAe;aACxB,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,WAAW,EAAE,GAAG,CAAC;gBACtB,KAAK,EAAE,OAAO;gBACd,MAAM,EAAE,wBAAwB,CAAC,UAAU;gBAC3C,OAAO,EAAE,gBAAgB;gBACzB,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC;aAC/B,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,KAAK;QACjB,IAAI,CAAC;YACJ,MAAM,YAAY,GAAgB;gBACjC,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,OAAO,EAAE;oBACR,MAAM,EAAE,SAAS,CAAC,IAAI;iBACtB;aACD,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAE/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,SAAS,EAAE,YAAY,CAAC,CAAC;YAE5E,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyC,CAAC;gBAE/E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5C,MAAM,iBAAiB,GAAgB;wBACtC,MAAM,EAAE,UAAU,CAAC,IAAI;wBACvB,OAAO,EAAE;4BACR,MAAM,EAAE,SAAS,CAAC,IAAI;yBACtB;qBACD,CAAC;oBACF,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;oBACpC,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,eAAe,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;gBAC5E,CAAC;YACF,CAAC;YAED,MAAM,cAAc,GAAgB;gBACnC,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,OAAO,EAAE;oBACR,MAAM,EAAE,SAAS,CAAC,IAAI;iBACtB;aACD,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;YACjC,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,UAAU,EAAE,cAAc,CAAC,CAAC;YACjF,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,YAAY,CAAC,wBAAwB,CAAC,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC5F,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,MAAM,CAAC,EAAU;QAC7B,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,UAAU,QAAc,EAAE,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAE1C,IAAI,SAAS,CAAC,eAAe,EAAE,KAAK,wBAAwB,CAAC,SAAS,EAAE,CAAC;YACxE,MAAM,IAAI,YAAY,CAAC,wBAAwB,CAAC,UAAU,EAAE,mBAAmB,EAAE;gBAChF,SAAS,EAAE,wBAAwB,CAAC,SAAS;gBAC7C,EAAE;aACF,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC5D,MAAM,sBAAsB,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YAC5E,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAChC,CAAC,CAAC,SAAS,CAAC;QAEb,IAAI,gBAAgB,KAAK,sBAAsB,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9D,IAAI,CAAC;YACJ,MAAM,YAAY,GAAgB;gBACjC,MAAM,EAAE,UAAU,CAAC,IAAI;gBACvB,OAAO,EAAE;oBACR,MAAM,EAAE,SAAS,CAAC,IAAI;iBACtB;aACD,CAAC;YAEF,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAE/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,eAAe,QAAQ,EAAE,EAAE,YAAY,CAAC,CAAC;YAE5F,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,IAAI,CAAC;YACb,CAAC;YAED,OAAO,KAAK,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,YAAY,CACrB,wBAAwB,CAAC,UAAU,EACnC,kBAAkB,EAClB,SAAS,EACT,GAAG,CACH,CAAC;QACH,CAAC;IACF,CAAC;IAED;;;;OAIG;IACK,WAAW,CAAC,WAAwB;QAC3C,IAAI,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9C,WAAW,CAAC,OAAO,GAAG;gBACrB,GAAG,WAAW,CAAC,OAAO;gBACtB,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;aAChF,CAAC;QACH,CAAC;IACF,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,qBAAqB;QAClC,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;QACxD,MAAM,YAAY,GAAG,eAAe,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC/F,IAAI,EAAE,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,OAAO,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IBlobStorageConnector } from \"@twin.org/blob-storage-models\";\nimport { ContextIdHelper, ContextIdStore } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tHealthStatus,\n\tIs,\n\tStringHelper,\n\tUrn,\n\ttype IHealth\n} from \"@twin.org/core\";\nimport { Blake2b } from \"@twin.org/crypto\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { HeaderHelper, HeaderTypes, HttpMethod, MimeTypes } from \"@twin.org/web\";\nimport type { IIpfsBlobStorageConnectorConfig } from \"./models/IIpfsBlobStorageConnectorConfig.js\";\nimport type { IIpfsBlobStorageConnectorConstructorOptions } from \"./models/IIpfsBlobStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing blob storage operations on IPFS.\n * See https://docs.ipfs.tech/reference/kubo/rpc/ for more information.\n */\nexport class IpfsBlobStorageConnector implements IBlobStorageConnector {\n\t/**\n\t * The namespace for the items.\n\t */\n\tpublic static readonly NAMESPACE: string = \"ipfs\";\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<IpfsBlobStorageConnector>();\n\n\t/**\n\t * The configuration for the connector.\n\t * @internal\n\t */\n\tprivate readonly _config: IIpfsBlobStorageConnectorConfig;\n\n\t/**\n\t * The keys to use from the context ids to create partitions.\n\t * @internal\n\t */\n\tprivate readonly _partitionContextIds?: string[];\n\n\t/**\n\t * Create a new instance of IpfsBlobStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: IIpfsBlobStorageConnectorConstructorOptions) {\n\t\tGuards.object(IpfsBlobStorageConnector.CLASS_NAME, nameof(options), options);\n\t\tGuards.object<IIpfsBlobStorageConnectorConfig>(\n\t\t\tIpfsBlobStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config),\n\t\t\toptions.config\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tIpfsBlobStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.config.apiUrl),\n\t\t\toptions.config.apiUrl\n\t\t);\n\n\t\tthis._config = options.config;\n\t\tthis._partitionContextIds = options.partitionContextIds;\n\t\tthis._config.apiUrl = StringHelper.trimTrailingSlashes(this._config.apiUrl);\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn IpfsBlobStorageConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Returns the health status of the component.\n\t * @returns The health status of the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(fetchOptions);\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/version`, fetchOptions);\n\t\t\tif (response.ok) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tapiUrl: this._config.apiUrl\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t}\n\t\t} catch {}\n\t\treturn [\n\t\t\t{\n\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\tdescription: \"healthDescription\",\n\t\t\t\tmessage: \"healthCheckFailed\",\n\t\t\t\tdata: {\n\t\t\t\t\tapiUrl: this._config.apiUrl\n\t\t\t\t}\n\t\t\t}\n\t\t];\n\t}\n\n\t/**\n\t * Set the blob.\n\t * @param blob The data for the blob.\n\t * @returns The id of the stored blob in urn format.\n\t */\n\tpublic async set(blob: Uint8Array): Promise<string> {\n\t\tGuards.uint8Array(IpfsBlobStorageConnector.CLASS_NAME, nameof(blob), blob);\n\n\t\ttry {\n\t\t\tconst formBlob = new Blob([new Uint8Array(blob)], { type: MimeTypes.OctetStream });\n\t\t\tconst formData = new FormData();\n\t\t\tformData.append(\"file\", formBlob);\n\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\tbody: formData,\n\t\t\t\theaders: {\n\t\t\t\t\t[HeaderTypes.Accept]: MimeTypes.Json,\n\t\t\t\t\t[HeaderTypes.ContentDisposition]: \"form-data\"\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/add?pin=true`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = (await response.json()) as {\n\t\t\t\t\tName: string;\n\t\t\t\t\tHash: string;\n\t\t\t\t\tSize: string;\n\t\t\t\t};\n\n\t\t\t\tconst partitionSegment = await this.buildPartitionSegment();\n\t\t\t\tconst urnParts = Is.stringValue(partitionSegment)\n\t\t\t\t\t? [result.Hash, partitionSegment]\n\t\t\t\t\t: [result.Hash];\n\n\t\t\t\treturn `blob:${new Urn(IpfsBlobStorageConnector.NAMESPACE, urnParts).toString()}`;\n\t\t\t}\n\n\t\t\tconst error = await response.json();\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"fetchFail\", error);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"setBlobFailed\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Get the blob.\n\t * @param id The id of the blob to get in urn format.\n\t * @returns The data for the blob if it can be found or undefined.\n\t */\n\tpublic async get(id: string): Promise<Uint8Array | undefined> {\n\t\tUrn.guard(IpfsBlobStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tconst urnParsed = Urn.fromValidString(id);\n\n\t\tif (urnParsed.namespaceMethod() !== IpfsBlobStorageConnector.NAMESPACE) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"namespaceMismatch\", {\n\t\t\t\tnamespace: IpfsBlobStorageConnector.NAMESPACE,\n\t\t\t\tid\n\t\t\t});\n\t\t}\n\n\t\tconst partitionSegment = await this.buildPartitionSegment();\n\t\tconst storedPartitionSegment = Is.stringValue(urnParsed.namespaceSpecific(2))\n\t\t\t? urnParsed.namespaceSpecific(2)\n\t\t\t: undefined;\n\n\t\tif (partitionSegment !== storedPartitionSegment) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst ipfsHash = urnParsed.namespaceSpecific(1).split(\":\")[0];\n\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst pinResponse = await fetch(\n\t\t\t\t`${this._config.apiUrl}/pin/ls?arg=${ipfsHash}`,\n\t\t\t\tfetchOptions\n\t\t\t);\n\n\t\t\tif (!pinResponse.ok) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/cat?arg=${ipfsHash}`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = await response.arrayBuffer();\n\t\t\t\treturn new Uint8Array(result);\n\t\t\t}\n\n\t\t\tconst error = await response.json();\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"fetchFail\", error);\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"getBlobFailed\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Teardown the component and remove any resources it created.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns True if the teardown process was successful.\n\t */\n\tpublic async teardown(nodeLoggingComponentType?: string): Promise<boolean> {\n\t\tconst nodeLogging = ComponentFactory.getIfExists<ILoggingComponent>(nodeLoggingComponentType);\n\n\t\tawait nodeLogging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\tmessage: \"storeTearingDown\"\n\t\t});\n\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/pin/ls`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = (await response.json()) as { Keys: { [cid: string]: unknown } };\n\n\t\t\t\tfor (const cid of Object.keys(result.Keys)) {\n\t\t\t\t\tconst unpinFetchOptions: RequestInit = {\n\t\t\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tthis.addSecurity(unpinFetchOptions);\n\t\t\t\t\tawait fetch(`${this._config.apiUrl}/pin/rm?arg=${cid}`, unpinFetchOptions);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\tmessage: \"storeTornDown\"\n\t\t\t});\n\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tawait nodeLogging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tsource: IpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\tmessage: \"teardownFailed\",\n\t\t\t\terror: BaseError.fromError(err)\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Remove all blobs from the storage.\n\t * @returns A promise that resolves when all pinned blobs have been unpinned and garbage collected.\n\t */\n\tpublic async empty(): Promise<void> {\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/pin/ls`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\tconst result = (await response.json()) as { Keys: { [cid: string]: unknown } };\n\n\t\t\t\tfor (const cid of Object.keys(result.Keys)) {\n\t\t\t\t\tconst unpinFetchOptions: RequestInit = {\n\t\t\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tthis.addSecurity(unpinFetchOptions);\n\t\t\t\t\tawait fetch(`${this._config.apiUrl}/pin/rm?arg=${cid}`, unpinFetchOptions);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst gcFetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.addSecurity(gcFetchOptions);\n\t\t\tconst gcResponse = await fetch(`${this._config.apiUrl}/repo/gc`, gcFetchOptions);\n\t\t\tawait gcResponse.text();\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"emptyFailed\", undefined, err);\n\t\t}\n\t}\n\n\t/**\n\t * Remove the blob.\n\t * @param id The id of the blob to remove in urn format.\n\t * @returns True if the blob was found.\n\t */\n\tpublic async remove(id: string): Promise<boolean> {\n\t\tUrn.guard(IpfsBlobStorageConnector.CLASS_NAME, nameof(id), id);\n\t\tconst urnParsed = Urn.fromValidString(id);\n\n\t\tif (urnParsed.namespaceMethod() !== IpfsBlobStorageConnector.NAMESPACE) {\n\t\t\tthrow new GeneralError(IpfsBlobStorageConnector.CLASS_NAME, \"namespaceMismatch\", {\n\t\t\t\tnamespace: IpfsBlobStorageConnector.NAMESPACE,\n\t\t\t\tid\n\t\t\t});\n\t\t}\n\n\t\tconst partitionSegment = await this.buildPartitionSegment();\n\t\tconst storedPartitionSegment = Is.stringValue(urnParsed.namespaceSpecific(2))\n\t\t\t? urnParsed.namespaceSpecific(2)\n\t\t\t: undefined;\n\n\t\tif (partitionSegment !== storedPartitionSegment) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst ipfsHash = urnParsed.namespaceSpecific(1).split(\":\")[0];\n\n\t\ttry {\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\theaders: {\n\t\t\t\t\taccept: MimeTypes.Json\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.addSecurity(fetchOptions);\n\n\t\t\tconst response = await fetch(`${this._config.apiUrl}/pin/rm?arg=${ipfsHash}`, fetchOptions);\n\n\t\t\tif (response.ok) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIpfsBlobStorageConnector.CLASS_NAME,\n\t\t\t\t\"removeBlobFailed\",\n\t\t\t\tundefined,\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Add the security headers to the request if a bearer token is configured.\n\t * @param requestInit The request options to augment with security headers.\n\t * @internal\n\t */\n\tprivate addSecurity(requestInit: RequestInit): void {\n\t\tif (Is.stringValue(this._config.bearerToken)) {\n\t\t\trequestInit.headers = {\n\t\t\t\t...requestInit.headers,\n\t\t\t\t[HeaderTypes.Authorization]: HeaderHelper.createBearer(this._config.bearerToken)\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Build the partition segment from the current context.\n\t * @returns The hex-encoded Blake2b hash of the partition key, or undefined if no partition applies.\n\t * @internal\n\t */\n\tprivate async buildPartitionSegment(): Promise<string | undefined> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tconst partitionKey = ContextIdHelper.combinedContextKey(contextIds, this._partitionContextIds);\n\t\tif (Is.stringValue(partitionKey)) {\n\t\t\treturn Converter.bytesToHex(Blake2b.sum256(Converter.utf8ToBytes(partitionKey)));\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
@@ -49,7 +49,7 @@ export declare class IpfsBlobStorageConnector implements IBlobStorageConnector {
|
|
|
49
49
|
teardown(nodeLoggingComponentType?: string): Promise<boolean>;
|
|
50
50
|
/**
|
|
51
51
|
* Remove all blobs from the storage.
|
|
52
|
-
* @returns
|
|
52
|
+
* @returns A promise that resolves when all pinned blobs have been unpinned and garbage collected.
|
|
53
53
|
*/
|
|
54
54
|
empty(): Promise<void>;
|
|
55
55
|
/**
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.15](https://github.com/iotaledger/twin-blob-storage/compare/blob-storage-connector-ipfs-v0.0.3-next.14...blob-storage-connector-ipfs-v0.0.3-next.15) (2026-06-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* async getStore ([#59](https://github.com/iotaledger/twin-blob-storage/issues/59)) ([2de1ae5](https://github.com/iotaledger/twin-blob-storage/commit/2de1ae5c274b84a2320f75ac4628b81e9459c540))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/blob-storage-models bumped from 0.0.3-next.14 to 0.0.3-next.15
|
|
16
|
+
|
|
17
|
+
## [0.0.3-next.14](https://github.com/iotaledger/twin-blob-storage/compare/blob-storage-connector-ipfs-v0.0.3-next.13...blob-storage-connector-ipfs-v0.0.3-next.14) (2026-06-11)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Miscellaneous Chores
|
|
21
|
+
|
|
22
|
+
* **blob-storage-connector-ipfs:** Synchronize repo versions
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Dependencies
|
|
26
|
+
|
|
27
|
+
* The following workspace dependencies were updated
|
|
28
|
+
* dependencies
|
|
29
|
+
* @twin.org/blob-storage-models bumped from 0.0.3-next.13 to 0.0.3-next.14
|
|
30
|
+
|
|
3
31
|
## [0.0.3-next.13](https://github.com/iotaledger/twin-blob-storage/compare/blob-storage-connector-ipfs-v0.0.3-next.12...blob-storage-connector-ipfs-v0.0.3-next.13) (2026-05-20)
|
|
4
32
|
|
|
5
33
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/blob-storage-connector-ipfs",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.15",
|
|
4
4
|
"description": "Stores and retrieves blobs through IPFS for content-addressed and distributed workflows.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/iotaledger/blob-storage.git",
|
|
7
|
+
"url": "git+https://github.com/iotaledger/twin-blob-storage.git",
|
|
8
8
|
"directory": "packages/blob-storage-connector-ipfs"
|
|
9
9
|
},
|
|
10
10
|
"author": "martyn.janes@iota.org",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=20.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/blob-storage-models": "0.0.3-next.
|
|
17
|
+
"@twin.org/blob-storage-models": "0.0.3-next.15",
|
|
18
18
|
"@twin.org/context": "next",
|
|
19
19
|
"@twin.org/core": "next",
|
|
20
20
|
"@twin.org/crypto": "next",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"integration"
|
|
55
55
|
],
|
|
56
56
|
"bugs": {
|
|
57
|
-
"url": "git+https://github.com/iotaledger/blob-storage/issues"
|
|
57
|
+
"url": "git+https://github.com/iotaledger/twin-blob-storage/issues"
|
|
58
58
|
},
|
|
59
59
|
"homepage": "https://twindev.org"
|
|
60
60
|
}
|