@lumeweb/pinner 0.1.12 → 0.1.14
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/dist/esm/adapters/pinata/index.d.ts +1 -1
- package/dist/esm/adapters/pinata/shared/index.d.ts +1 -1
- package/dist/esm/adapters/pinata/shared/types.d.ts +41 -1
- package/dist/esm/adapters/pinata/v2/adapter-interface.d.ts +4 -1
- package/dist/esm/adapters/pinata/v2/index.d.ts +1 -1
- package/dist/esm/adapters/pinata/v2/types.d.ts +58 -1
- package/dist/esm/api/client.d.ts +21 -0
- package/dist/esm/api/client.js +54 -0
- package/dist/esm/api/client.js.map +1 -0
- package/dist/esm/api/generated/content/content.msw.js +30 -37
- package/dist/esm/api/generated/content/content.msw.js.map +1 -1
- package/dist/esm/api/generated/dns/dns.msw.js +30 -44
- package/dist/esm/api/generated/dns/dns.msw.js.map +1 -1
- package/dist/esm/api/generated/files/files.msw.js +30 -33
- package/dist/esm/api/generated/files/files.msw.js.map +1 -1
- package/dist/esm/api/generated/gateway/gateway.msw.js +30 -32
- package/dist/esm/api/generated/gateway/gateway.msw.js.map +1 -1
- package/dist/esm/api/generated/internal/internal.msw.js +30 -31
- package/dist/esm/api/generated/internal/internal.msw.js.map +1 -1
- package/dist/esm/api/generated/ipns/ipns.msw.js +30 -37
- package/dist/esm/api/generated/ipns/ipns.msw.js.map +1 -1
- package/dist/esm/api/generated/pinning/pinning.msw.js +30 -35
- package/dist/esm/api/generated/pinning/pinning.msw.js.map +1 -1
- package/dist/esm/api/generated/schemas/blockMetaResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/component.d.ts +29 -29
- package/dist/esm/api/generated/schemas/errorResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/fileManagerItem.d.ts +29 -29
- package/dist/esm/api/generated/schemas/gatewayWebsiteResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/gatewayWebsiteStatusResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/getBlockMetaBatchRequest.d.ts +42 -0
- package/dist/esm/api/generated/schemas/iPNSKeyListResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/iPNSKeyRequest.d.ts +29 -29
- package/dist/esm/api/generated/schemas/iPNSKeyResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/iPNSPublishRequest.d.ts +29 -29
- package/dist/esm/api/generated/schemas/iPNSPublishResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/iPNSRepublishResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/iPNSResolveResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/infoResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/pinRequestMeta.d.ts +29 -29
- package/dist/esm/api/generated/schemas/pinStatusResponseInfo.d.ts +29 -29
- package/dist/esm/api/generated/schemas/postApiUploadBody.d.ts +42 -0
- package/dist/esm/api/generated/schemas/postUploadResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/recordResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/recordResult.d.ts +29 -29
- package/dist/esm/api/generated/schemas/sSLStatusInfo.d.ts +29 -29
- package/dist/esm/api/generated/schemas/sSLStatusUpdateRequest.d.ts +44 -0
- package/dist/esm/api/generated/schemas/uploadResultResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/validationResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/websiteConfigResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/websiteRequest.d.ts +29 -29
- package/dist/esm/api/generated/schemas/websiteUpdateRequest.d.ts +29 -29
- package/dist/esm/api/generated/schemas/websiteValidateResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/zoneListResponse.d.ts +29 -29
- package/dist/esm/api/generated/schemas/zoneResponse.d.ts +29 -29
- package/dist/esm/api/generated/tus/tus.msw.js +30 -34
- package/dist/esm/api/generated/tus/tus.msw.js.map +1 -1
- package/dist/esm/api/generated/websites/websites.msw.js +30 -38
- package/dist/esm/api/generated/websites/websites.msw.js.map +1 -1
- package/dist/esm/api/ipns.d.ts +47 -6
- package/dist/esm/api/ipns.js +46 -39
- package/dist/esm/api/ipns.js.map +1 -1
- package/dist/esm/api/websites.d.ts +57 -6
- package/dist/esm/api/websites.js +57 -41
- package/dist/esm/api/websites.js.map +1 -1
- package/dist/esm/auth/manager.d.ts +29 -0
- package/dist/esm/auth/manager.js +30 -0
- package/dist/esm/auth/manager.js.map +1 -0
- package/dist/esm/blockstore/index.d.ts +1 -1
- package/dist/esm/blockstore/unstorage-base.d.ts +6 -1
- package/dist/esm/blockstore/unstorage-base.js +9 -6
- package/dist/esm/blockstore/unstorage-base.js.map +1 -1
- package/dist/esm/config.d.ts +13 -1
- package/dist/esm/index.d.ts +31 -6
- package/dist/esm/pin/client.js +7 -7
- package/dist/esm/pin/client.js.map +1 -1
- package/dist/esm/pinner.d.ts +22 -0
- package/dist/esm/pinner.js +28 -4
- package/dist/esm/pinner.js.map +1 -1
- package/dist/esm/types/pin.d.ts +42 -0
- package/dist/esm/upload/base-upload.js +3 -1
- package/dist/esm/upload/base-upload.js.map +1 -1
- package/dist/esm/upload/builder.d.ts +1 -1
- package/dist/esm/upload/car.d.ts +18 -0
- package/dist/esm/upload/car.js.map +1 -1
- package/dist/esm/upload/manager.d.ts +32 -1
- package/dist/esm/upload/manager.js +36 -4
- package/dist/esm/upload/manager.js.map +1 -1
- package/dist/esm/upload/normalize.js.map +1 -1
- package/dist/esm/upload/tus-upload.js +3 -3
- package/dist/esm/upload/tus-upload.js.map +1 -1
- package/dist/esm/upload/xhr-upload.js +3 -1
- package/dist/esm/upload/xhr-upload.js.map +1 -1
- package/package.json +19 -19
package/dist/esm/api/websites.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import ky, { HTTPError } from "ky";
|
|
1
|
+
import { ApiClient } from "./client.js";
|
|
3
2
|
import { createNanoEvents } from "nanoevents";
|
|
4
3
|
|
|
5
4
|
//#region src/api/websites.ts
|
|
@@ -29,48 +28,30 @@ function isValidationReason(response, reason) {
|
|
|
29
28
|
if (!response) return false;
|
|
30
29
|
return response.reason === reason;
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"Content-Type": "application/json"
|
|
49
|
-
},
|
|
50
|
-
...options
|
|
51
|
-
});
|
|
52
|
-
if (response.status === 204) return;
|
|
53
|
-
const text = await response.text();
|
|
54
|
-
if (!text) return;
|
|
55
|
-
return JSON.parse(text);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
if (error instanceof HTTPError) {
|
|
58
|
-
const status = error.response.status;
|
|
59
|
-
const body = await error.response.json().catch(() => ({}));
|
|
60
|
-
if (status === 401) throw new AuthenticationError(body.error || "Authentication failed");
|
|
61
|
-
if (status === 403) throw new AuthenticationError(body.error || "Access forbidden");
|
|
62
|
-
if (status === 404) throw new NotFoundError(body.error || "Resource not found");
|
|
63
|
-
if (status === 400) throw new ValidationError(body.error || "Invalid request");
|
|
64
|
-
if (status === 410) throw new ValidationError(body.error || "Target is broken or gone");
|
|
65
|
-
throw new NetworkError(body.error || `HTTP error: ${status}`);
|
|
66
|
-
}
|
|
67
|
-
if (error instanceof Error) throw new NetworkError(error.message);
|
|
68
|
-
throw new NetworkError("Unknown error occurred");
|
|
69
|
-
}
|
|
70
|
-
}
|
|
31
|
+
/**
|
|
32
|
+
* Client for managing websites hosted on IPFS with custom domains and SSL.
|
|
33
|
+
*/
|
|
34
|
+
var WebsitesClient = class extends ApiClient {
|
|
35
|
+
/**
|
|
36
|
+
* Create a new WebsitesClient.
|
|
37
|
+
* @param config SDK configuration
|
|
38
|
+
* @param auth AuthManager for authentication
|
|
39
|
+
*/
|
|
40
|
+
constructor(config, auth) {
|
|
41
|
+
super(auth, config.endpoint ?? "https://ipfs.pinner.xyz");
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* List all websites.
|
|
45
|
+
* @param options Request options
|
|
46
|
+
*/
|
|
71
47
|
async listWebsites(options) {
|
|
72
48
|
return this.request("api/websites", { signal: options?.signal });
|
|
73
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Create a new website.
|
|
52
|
+
* @param request Website creation parameters
|
|
53
|
+
* @param options Request options
|
|
54
|
+
*/
|
|
74
55
|
async createWebsite(request, options) {
|
|
75
56
|
return this.request("api/websites", {
|
|
76
57
|
method: "POST",
|
|
@@ -78,9 +59,20 @@ var WebsitesClient = class {
|
|
|
78
59
|
signal: options?.signal
|
|
79
60
|
});
|
|
80
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Get website details by ID.
|
|
64
|
+
* @param id Website ID
|
|
65
|
+
* @param options Request options
|
|
66
|
+
*/
|
|
81
67
|
async getWebsite(id, options) {
|
|
82
68
|
return this.request(`api/websites/${id}`, { signal: options?.signal });
|
|
83
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Update a website's configuration.
|
|
72
|
+
* @param id Website ID
|
|
73
|
+
* @param request Update parameters
|
|
74
|
+
* @param options Request options
|
|
75
|
+
*/
|
|
84
76
|
async updateWebsite(id, request, options) {
|
|
85
77
|
return this.request(`api/websites/${id}`, {
|
|
86
78
|
method: "PUT",
|
|
@@ -88,24 +80,48 @@ var WebsitesClient = class {
|
|
|
88
80
|
signal: options?.signal
|
|
89
81
|
});
|
|
90
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Delete a website by ID.
|
|
85
|
+
* @param id Website ID
|
|
86
|
+
* @param options Request options
|
|
87
|
+
*/
|
|
91
88
|
async deleteWebsite(id, options) {
|
|
92
89
|
await this.request(`api/websites/${id}`, {
|
|
93
90
|
method: "DELETE",
|
|
94
91
|
signal: options?.signal
|
|
95
92
|
});
|
|
96
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Validate a website's DNS and SSL configuration.
|
|
96
|
+
* @param id Website ID
|
|
97
|
+
* @param options Request options
|
|
98
|
+
*/
|
|
97
99
|
async validateWebsite(id, options) {
|
|
98
100
|
return this.request(`api/websites/${id}/validate`, {
|
|
99
101
|
method: "POST",
|
|
100
102
|
signal: options?.signal
|
|
101
103
|
});
|
|
102
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Check the SSL certificate status for a domain.
|
|
107
|
+
* @param domain Domain name
|
|
108
|
+
* @param options Request options
|
|
109
|
+
*/
|
|
103
110
|
async getSSLStatus(domain, options) {
|
|
104
111
|
return this.request(`api/websites/${encodeURIComponent(domain)}/ssl-status`, { signal: options?.signal });
|
|
105
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Get the global website configuration.
|
|
115
|
+
* @param options Request options
|
|
116
|
+
*/
|
|
106
117
|
async getWebsiteConfig(options) {
|
|
107
118
|
return this.request("api/websites/config", { signal: options?.signal });
|
|
108
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Watch SSL status until provisioned, failed, or timed out.
|
|
122
|
+
* @param domain Domain name
|
|
123
|
+
* @param options Watch interval and timeout
|
|
124
|
+
*/
|
|
109
125
|
watchSSL(domain, options) {
|
|
110
126
|
return new SSLWatcherImpl(this, domain, options);
|
|
111
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websites.js","names":[],"sources":["../../../src/api/websites.ts"],"sourcesContent":["import ky, { HTTPError } from \"ky\";\nimport { createNanoEvents } from \"nanoevents\";\nimport type { PinnerConfig } from \"../config\";\nimport type {\n WebsiteItemResponse,\n WebsiteRequest,\n WebsiteResponse,\n WebsiteUpdateRequest,\n WebsiteValidateResponse,\n WebsiteConfigResponse,\n SSLStatusInfo,\n} from \"./generated/schemas/index\";\n\n// SSL status constants\nexport const SSLStatus = {\n PENDING: \"pending\",\n VALIDATING: \"validating\",\n VALID: \"valid\",\n READY: \"ready\",\n FAILED: \"failed\",\n ERROR: \"error\",\n} as const;\n\nexport type SSLStatusValue = (typeof SSLStatus)[keyof typeof SSLStatus];\n\n// Website validation reason constants\nexport const WebsiteValidationReason = {\n VALIDATED: \"validated\",\n TOKEN_EXPIRED: \"token_expired\",\n DNS_MISSING: \"dns_missing\",\n DNS_MISMATCH: \"dns_mismatch\",\n TOKEN_MISSING: \"token_missing\",\n} as const;\n\nexport type WebsiteValidationReasonValue = (typeof WebsiteValidationReason)[keyof typeof WebsiteValidationReason];\n\nconst validationReasonValues = Object.values(WebsiteValidationReason) as readonly string[];\n\nexport function getValidationReason(response: WebsiteValidateResponse | null | undefined): WebsiteValidationReasonValue | \"\" {\n if (!response) {\n return \"\";\n }\n const reason = response.reason;\n if (typeof reason === \"string\" && validationReasonValues.includes(reason)) {\n return reason as WebsiteValidationReasonValue;\n }\n return \"\";\n}\n\nexport function isValidationReason(response: WebsiteValidateResponse | null | undefined, reason: WebsiteValidationReasonValue): boolean {\n if (!response) {\n return false;\n }\n return response.reason === reason;\n}\nimport {\n ConfigurationError,\n AuthenticationError,\n NotFoundError,\n NetworkError,\n ValidationError,\n} from \"@/errors\";\n\nexport interface WebsitesClientOptions {\n signal?: AbortSignal;\n}\n\nexport class WebsitesClient {\n private config: PinnerConfig;\n\n constructor(config: PinnerConfig) {\n if (!config.jwt) {\n throw new ConfigurationError(\"JWT token is required\");\n }\n this.config = config;\n }\n\n private getEndpoint(): string {\n return this.config.endpoint ?? \"https://ipfs.pinner.xyz\";\n }\n\n private async request<T>(\n path: string,\n options?: RequestInit & { signal?: AbortSignal },\n ): Promise<T> {\n if (!this.config.jwt) {\n throw new ConfigurationError(\"JWT token is required\");\n }\n\n try {\n const response = await ky(path, {\n prefix: this.getEndpoint(),\n headers: {\n Authorization: `Bearer ${this.config.jwt}`,\n \"Content-Type\": \"application/json\",\n },\n ...options,\n });\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n const text = await response.text();\n if (!text) {\n return undefined as T;\n }\n\n return JSON.parse(text) as T;\n } catch (error) {\n if (error instanceof HTTPError) {\n const status = error.response.status;\n const body = await error.response.json().catch(() => ({}));\n\n if (status === 401) {\n throw new AuthenticationError(\n body.error || \"Authentication failed\",\n );\n }\n if (status === 403) {\n throw new AuthenticationError(\n body.error || \"Access forbidden\",\n );\n }\n if (status === 404) {\n throw new NotFoundError(body.error || \"Resource not found\");\n }\n if (status === 400) {\n throw new ValidationError(body.error || \"Invalid request\");\n }\n if (status === 410) {\n throw new ValidationError(body.error || \"Target is broken or gone\");\n }\n\n throw new NetworkError(\n body.error || `HTTP error: ${status}`,\n );\n }\n\n if (error instanceof Error) {\n throw new NetworkError(error.message);\n }\n\n throw new NetworkError(\"Unknown error occurred\");\n }\n }\n\n async listWebsites(options?: WebsitesClientOptions): Promise<WebsiteItemResponse> {\n return this.request<WebsiteItemResponse>(\"api/websites\", {\n signal: options?.signal,\n });\n }\n\n async createWebsite(\n request: WebsiteRequest,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteResponse> {\n return this.request<WebsiteResponse>(\"api/websites\", {\n method: \"POST\",\n body: JSON.stringify(request),\n signal: options?.signal,\n });\n }\n\n async getWebsite(\n id: number,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteResponse> {\n return this.request<WebsiteResponse>(`api/websites/${id}`, {\n signal: options?.signal,\n });\n }\n\n async updateWebsite(\n id: number,\n request: WebsiteUpdateRequest,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteResponse> {\n return this.request<WebsiteResponse>(`api/websites/${id}`, {\n method: \"PUT\",\n body: JSON.stringify(request),\n signal: options?.signal,\n });\n }\n\n async deleteWebsite(\n id: number,\n options?: WebsitesClientOptions,\n ): Promise<void> {\n await this.request<void>(`api/websites/${id}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n async validateWebsite(\n id: number,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteValidateResponse> {\n return this.request<WebsiteValidateResponse>(\n `api/websites/${id}/validate`,\n {\n method: \"POST\",\n signal: options?.signal,\n },\n );\n }\n\n async getSSLStatus(\n domain: string,\n options?: WebsitesClientOptions,\n ): Promise<SSLStatusInfo> {\n return this.request<SSLStatusInfo>(\n `api/websites/${encodeURIComponent(domain)}/ssl-status`,\n {\n signal: options?.signal,\n },\n );\n }\n\n async getWebsiteConfig(\n options?: WebsitesClientOptions,\n ): Promise<WebsiteConfigResponse> {\n return this.request<WebsiteConfigResponse>(\"api/websites/config\", {\n signal: options?.signal,\n });\n }\n\n watchSSL(\n domain: string,\n options?: WatchOptions,\n ): SSLWatcher {\n return new SSLWatcherImpl(this, domain, options);\n }\n}\n\nexport interface WatchOptions {\n interval?: number;\n timeout?: number;\n}\n\nexport interface SSLEvents {\n ready: (status: SSLStatusInfo) => void;\n error: (error: SSLError) => void;\n status: (status: SSLStatusInfo) => void;\n}\n\nexport interface SSLCallbacks {\n onReady?: (status: SSLStatusInfo) => void;\n onError?: (error: SSLError) => void;\n onStatus?: (status: SSLStatusInfo) => void;\n}\n\nexport interface SSLWatcher {\n start(callbacks: SSLCallbacks): Promise<void>;\n stop(): void;\n}\n\nexport interface SSLError extends Error {\n type: 'timeout' | 'error';\n details?: string;\n}\n\nconst DEFAULT_INTERVAL = 5000;\nconst DEFAULT_TIMEOUT = 300000;\n\nclass SSLWatcherImpl implements SSLWatcher {\n private emitter = createNanoEvents<SSLEvents>();\n private unbind: (() => void)[] = [];\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n private stopped = false;\n private options: WatchOptions;\n private runId = 0;\n\n constructor(\n private client: WebsitesClient,\n private domain: string,\n options: WatchOptions = {},\n ) {\n this.options = {\n interval: options.interval ?? DEFAULT_INTERVAL,\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n };\n\n if (this.options.interval <= 0) {\n this.options.interval = DEFAULT_INTERVAL;\n }\n if (this.options.timeout <= 0) {\n this.options.timeout = DEFAULT_TIMEOUT;\n }\n }\n\n private emitError(\n message: string,\n type: SSLError['type'] = 'error',\n details?: string,\n ): void {\n const error: SSLError = new Error(message) as SSLError;\n error.type = type;\n error.details = details;\n this.emitter.emit('error', error);\n this.stop();\n }\n\n async start(callbacks: SSLCallbacks = {}): Promise<void> {\n this.stop();\n this.stopped = false;\n const currentRunId = ++this.runId;\n\n if (callbacks.onReady) {\n this.unbind.push(this.emitter.on('ready', callbacks.onReady));\n }\n if (callbacks.onError) {\n this.unbind.push(this.emitter.on('error', callbacks.onError));\n }\n if (callbacks.onStatus) {\n this.unbind.push(this.emitter.on('status', callbacks.onStatus));\n }\n\n const checkStatus = async (): Promise<void> => {\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n\n try {\n const status = await this.client.getSSLStatus(this.domain);\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n this.emitter.emit('status', status);\n\n if (status.status === SSLStatus.VALID || status.status === SSLStatus.READY) {\n this.emitter.emit('ready', status);\n this.stop();\n } else if (status.status === SSLStatus.FAILED || status.status === SSLStatus.ERROR) {\n this.emitError(\n status.error || 'SSL provisioning failed',\n 'error',\n status.error,\n );\n }\n } catch (err) {\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n\n this.emitError(\n err instanceof Error ? err.message : 'Failed to check SSL status',\n 'error',\n );\n }\n };\n\n await checkStatus();\n\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n\n this.intervalId = setInterval(checkStatus, this.options.interval);\n\n this.timeoutId = setTimeout(() => {\n if (!this.stopped && this.runId === currentRunId) {\n this.emitError('SSL provisioning timeout', 'timeout');\n }\n }, this.options.timeout);\n }\n\n stop(): void {\n this.stopped = true;\n\n this.unbind.forEach(unbind => unbind());\n this.unbind = [];\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"websites.js","names":[],"sources":["../../../src/api/websites.ts"],"sourcesContent":["import { createNanoEvents } from \"nanoevents\";\nimport type { PinnerConfig } from \"../config\";\nimport type { AuthManager } from \"@/auth\";\nimport { ApiClient } from \"./client\";\nimport type {\n WebsiteItemResponse,\n WebsiteRequest,\n WebsiteResponse,\n WebsiteUpdateRequest,\n WebsiteValidateResponse,\n WebsiteConfigResponse,\n SSLStatusInfo,\n} from \"./generated/schemas/index\";\n\n// SSL status constants\nexport const SSLStatus = {\n PENDING: \"pending\",\n VALIDATING: \"validating\",\n VALID: \"valid\",\n READY: \"ready\",\n FAILED: \"failed\",\n ERROR: \"error\",\n} as const;\n\nexport type SSLStatusValue = (typeof SSLStatus)[keyof typeof SSLStatus];\n\n// Website validation reason constants\nexport const WebsiteValidationReason = {\n VALIDATED: \"validated\",\n TOKEN_EXPIRED: \"token_expired\",\n DNS_MISSING: \"dns_missing\",\n DNS_MISMATCH: \"dns_mismatch\",\n TOKEN_MISSING: \"token_missing\",\n} as const;\n\nexport type WebsiteValidationReasonValue = (typeof WebsiteValidationReason)[keyof typeof WebsiteValidationReason];\n\nconst validationReasonValues = Object.values(WebsiteValidationReason) as readonly string[];\n\nexport function getValidationReason(response: WebsiteValidateResponse | null | undefined): WebsiteValidationReasonValue | \"\" {\n if (!response) {\n return \"\";\n }\n const reason = response.reason;\n if (typeof reason === \"string\" && validationReasonValues.includes(reason)) {\n return reason as WebsiteValidationReasonValue;\n }\n return \"\";\n}\n\nexport function isValidationReason(response: WebsiteValidateResponse | null | undefined, reason: WebsiteValidationReasonValue): boolean {\n if (!response) {\n return false;\n }\n return response.reason === reason;\n}\n\nexport interface WebsitesClientOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Client for managing websites hosted on IPFS with custom domains and SSL.\n */\nexport class WebsitesClient extends ApiClient {\n /**\n * Create a new WebsitesClient.\n * @param config SDK configuration\n * @param auth AuthManager for authentication\n */\n constructor(config: PinnerConfig, auth: AuthManager) {\n super(auth, config.endpoint ?? \"https://ipfs.pinner.xyz\");\n }\n\n /**\n * List all websites.\n * @param options Request options\n */\n async listWebsites(options?: WebsitesClientOptions): Promise<WebsiteItemResponse> {\n return this.request<WebsiteItemResponse>(\"api/websites\", {\n signal: options?.signal,\n });\n }\n\n /**\n * Create a new website.\n * @param request Website creation parameters\n * @param options Request options\n */\n async createWebsite(\n request: WebsiteRequest,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteResponse> {\n return this.request<WebsiteResponse>(\"api/websites\", {\n method: \"POST\",\n body: JSON.stringify(request),\n signal: options?.signal,\n });\n }\n\n /**\n * Get website details by ID.\n * @param id Website ID\n * @param options Request options\n */\n async getWebsite(\n id: number,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteResponse> {\n return this.request<WebsiteResponse>(`api/websites/${id}`, {\n signal: options?.signal,\n });\n }\n\n /**\n * Update a website's configuration.\n * @param id Website ID\n * @param request Update parameters\n * @param options Request options\n */\n async updateWebsite(\n id: number,\n request: WebsiteUpdateRequest,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteResponse> {\n return this.request<WebsiteResponse>(`api/websites/${id}`, {\n method: \"PUT\",\n body: JSON.stringify(request),\n signal: options?.signal,\n });\n }\n\n /**\n * Delete a website by ID.\n * @param id Website ID\n * @param options Request options\n */\n async deleteWebsite(\n id: number,\n options?: WebsitesClientOptions,\n ): Promise<void> {\n await this.request<void>(`api/websites/${id}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n * Validate a website's DNS and SSL configuration.\n * @param id Website ID\n * @param options Request options\n */\n async validateWebsite(\n id: number,\n options?: WebsitesClientOptions,\n ): Promise<WebsiteValidateResponse> {\n return this.request<WebsiteValidateResponse>(\n `api/websites/${id}/validate`,\n {\n method: \"POST\",\n signal: options?.signal,\n },\n );\n }\n\n /**\n * Check the SSL certificate status for a domain.\n * @param domain Domain name\n * @param options Request options\n */\n async getSSLStatus(\n domain: string,\n options?: WebsitesClientOptions,\n ): Promise<SSLStatusInfo> {\n return this.request<SSLStatusInfo>(\n `api/websites/${encodeURIComponent(domain)}/ssl-status`,\n {\n signal: options?.signal,\n },\n );\n }\n\n /**\n * Get the global website configuration.\n * @param options Request options\n */\n async getWebsiteConfig(\n options?: WebsitesClientOptions,\n ): Promise<WebsiteConfigResponse> {\n return this.request<WebsiteConfigResponse>(\"api/websites/config\", {\n signal: options?.signal,\n });\n }\n\n /**\n * Watch SSL status until provisioned, failed, or timed out.\n * @param domain Domain name\n * @param options Watch interval and timeout\n */\n watchSSL(\n domain: string,\n options?: WatchOptions,\n ): SSLWatcher {\n return new SSLWatcherImpl(this, domain, options);\n }\n}\n\nexport interface WatchOptions {\n interval?: number;\n timeout?: number;\n}\n\nexport interface SSLEvents {\n ready: (status: SSLStatusInfo) => void;\n error: (error: SSLError) => void;\n status: (status: SSLStatusInfo) => void;\n}\n\nexport interface SSLCallbacks {\n onReady?: (status: SSLStatusInfo) => void;\n onError?: (error: SSLError) => void;\n onStatus?: (status: SSLStatusInfo) => void;\n}\n\nexport interface SSLWatcher {\n start(callbacks: SSLCallbacks): Promise<void>;\n stop(): void;\n}\n\nexport interface SSLError extends Error {\n type: 'timeout' | 'error';\n details?: string;\n}\n\nconst DEFAULT_INTERVAL = 5000;\nconst DEFAULT_TIMEOUT = 300000;\n\nclass SSLWatcherImpl implements SSLWatcher {\n private emitter = createNanoEvents<SSLEvents>();\n private unbind: (() => void)[] = [];\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n private stopped = false;\n private options: WatchOptions;\n private runId = 0;\n\n constructor(\n private client: WebsitesClient,\n private domain: string,\n options: WatchOptions = {},\n ) {\n this.options = {\n interval: options.interval ?? DEFAULT_INTERVAL,\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n };\n\n if (this.options.interval <= 0) {\n this.options.interval = DEFAULT_INTERVAL;\n }\n if (this.options.timeout <= 0) {\n this.options.timeout = DEFAULT_TIMEOUT;\n }\n }\n\n private emitError(\n message: string,\n type: SSLError['type'] = 'error',\n details?: string,\n ): void {\n const error: SSLError = new Error(message) as SSLError;\n error.type = type;\n error.details = details;\n this.emitter.emit('error', error);\n this.stop();\n }\n\n async start(callbacks: SSLCallbacks = {}): Promise<void> {\n this.stop();\n this.stopped = false;\n const currentRunId = ++this.runId;\n\n if (callbacks.onReady) {\n this.unbind.push(this.emitter.on('ready', callbacks.onReady));\n }\n if (callbacks.onError) {\n this.unbind.push(this.emitter.on('error', callbacks.onError));\n }\n if (callbacks.onStatus) {\n this.unbind.push(this.emitter.on('status', callbacks.onStatus));\n }\n\n const checkStatus = async (): Promise<void> => {\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n\n try {\n const status = await this.client.getSSLStatus(this.domain);\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n this.emitter.emit('status', status);\n\n if (status.status === SSLStatus.VALID || status.status === SSLStatus.READY) {\n this.emitter.emit('ready', status);\n this.stop();\n } else if (status.status === SSLStatus.FAILED || status.status === SSLStatus.ERROR) {\n this.emitError(\n status.error || 'SSL provisioning failed',\n 'error',\n status.error,\n );\n }\n } catch (err) {\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n\n this.emitError(\n err instanceof Error ? err.message : 'Failed to check SSL status',\n 'error',\n );\n }\n };\n\n await checkStatus();\n\n if (this.stopped || this.runId !== currentRunId) {\n return;\n }\n\n this.intervalId = setInterval(checkStatus, this.options.interval);\n\n this.timeoutId = setTimeout(() => {\n if (!this.stopped && this.runId === currentRunId) {\n this.emitError('SSL provisioning timeout', 'timeout');\n }\n }, this.options.timeout);\n }\n\n stop(): void {\n this.stopped = true;\n\n this.unbind.forEach(unbind => unbind());\n this.unbind = [];\n\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/auth/manager.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Interface for authentication management.
|
|
4
|
+
* Provides auth tokens and headers for API requests.
|
|
5
|
+
*
|
|
6
|
+
* This is the single source of truth for auth in the Pinner SDK.
|
|
7
|
+
* All clients receive an AuthManager instance and call getAuthHeaders()
|
|
8
|
+
* or getAuthToken() — never touch config.jwt directly.
|
|
9
|
+
*/
|
|
10
|
+
interface AuthManager {
|
|
11
|
+
/**
|
|
12
|
+
* Get the raw auth token string.
|
|
13
|
+
* Throw ConfigurationError if no token is configured.
|
|
14
|
+
*/
|
|
15
|
+
getAuthToken(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Get the Authorization header object for use in fetch/ky requests.
|
|
18
|
+
* Example: { Authorization: "Bearer eyJ..." }
|
|
19
|
+
*/
|
|
20
|
+
getAuthHeaders(): Record<string, string>;
|
|
21
|
+
/**
|
|
22
|
+
* Get the auth token for use with libraries that expect an accessToken field
|
|
23
|
+
* (e.g. @ipfs-shipyard/pinning-service-client Configuration).
|
|
24
|
+
*/
|
|
25
|
+
getAccessToken(): string;
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { AuthManager };
|
|
29
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ConfigurationError } from "../errors/index.js";
|
|
2
|
+
|
|
3
|
+
//#region src/auth/manager.ts
|
|
4
|
+
/**
|
|
5
|
+
* Default AuthManager implementation that holds a JWT token.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the Go SDK's approach: token is set once at construction time
|
|
8
|
+
* and used for all subsequent requests. If token exchange (API key → login JWT)
|
|
9
|
+
* is needed in the future, it goes here — one place, not scattered across clients.
|
|
10
|
+
*/
|
|
11
|
+
var JwtAuthManager = class {
|
|
12
|
+
token;
|
|
13
|
+
constructor(jwt) {
|
|
14
|
+
if (!jwt) throw new ConfigurationError("JWT token is required");
|
|
15
|
+
this.token = jwt;
|
|
16
|
+
}
|
|
17
|
+
getAuthToken() {
|
|
18
|
+
return this.token;
|
|
19
|
+
}
|
|
20
|
+
getAuthHeaders() {
|
|
21
|
+
return { Authorization: `Bearer ${this.token}` };
|
|
22
|
+
}
|
|
23
|
+
getAccessToken() {
|
|
24
|
+
return this.token;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { JwtAuthManager };
|
|
30
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","names":[],"sources":["../../../src/auth/manager.ts"],"sourcesContent":["import { ConfigurationError } from \"@/errors\";\n\n/**\n * Interface for authentication management.\n * Provides auth tokens and headers for API requests.\n *\n * This is the single source of truth for auth in the Pinner SDK.\n * All clients receive an AuthManager instance and call getAuthHeaders()\n * or getAuthToken() — never touch config.jwt directly.\n */\nexport interface AuthManager {\n /**\n * Get the raw auth token string.\n * Throw ConfigurationError if no token is configured.\n */\n getAuthToken(): string;\n\n /**\n * Get the Authorization header object for use in fetch/ky requests.\n * Example: { Authorization: \"Bearer eyJ...\" }\n */\n getAuthHeaders(): Record<string, string>;\n\n /**\n * Get the auth token for use with libraries that expect an accessToken field\n * (e.g. @ipfs-shipyard/pinning-service-client Configuration).\n */\n getAccessToken(): string;\n}\n\n/**\n * Default AuthManager implementation that holds a JWT token.\n *\n * Mirrors the Go SDK's approach: token is set once at construction time\n * and used for all subsequent requests. If token exchange (API key → login JWT)\n * is needed in the future, it goes here — one place, not scattered across clients.\n */\nexport class JwtAuthManager implements AuthManager {\n private readonly token: string;\n\n constructor(jwt: string) {\n if (!jwt) {\n throw new ConfigurationError(\"JWT token is required\");\n }\n this.token = jwt;\n }\n\n getAuthToken(): string {\n return this.token;\n }\n\n getAuthHeaders(): Record<string, string> {\n return { Authorization: `Bearer ${this.token}` };\n }\n\n getAccessToken(): string {\n return this.token;\n }\n}\n"],"mappings":";;;;;;;;;;AAqCA,IAAa,iBAAb,MAAmD;CACjD,AAAiB;CAEjB,YAAY,KAAa;AACvB,MAAI,CAAC,IACH,OAAM,IAAI,mBAAmB,wBAAwB;AAEvD,OAAK,QAAQ;;CAGf,eAAuB;AACrB,SAAO,KAAK;;CAGd,iBAAyC;AACvC,SAAO,EAAE,eAAe,UAAU,KAAK,SAAS;;CAGlD,iBAAyB;AACvB,SAAO,KAAK"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { UnstorageBlockstoreOptions, setDriverFactory } from "./unstorage-base.js";
|
|
1
|
+
import { DriverFactory, UnstorageBlockstoreOptions, setDriverFactory } from "./unstorage-base.js";
|
|
2
2
|
import { createBlockstore, createDatastore } from "./unstorage.js";
|
|
@@ -4,10 +4,15 @@ import { Datastore } from "interface-datastore";
|
|
|
4
4
|
|
|
5
5
|
//#region src/blockstore/unstorage-base.d.ts
|
|
6
6
|
interface UnstorageBlockstoreOptions {
|
|
7
|
+
/** Unstorage instance to use (bypasses driver creation) */
|
|
7
8
|
storage?: Storage;
|
|
9
|
+
/** Key prefix for blockstore keys */
|
|
8
10
|
prefix?: string;
|
|
11
|
+
/** Unstorage driver name or instance */
|
|
9
12
|
driver?: Driver;
|
|
13
|
+
/** Base path for storage driver */
|
|
10
14
|
base?: string;
|
|
15
|
+
/** Prefix for datastore keys (defaults to prefix) */
|
|
11
16
|
datastorePrefix?: string;
|
|
12
17
|
}
|
|
13
18
|
/**
|
|
@@ -22,5 +27,5 @@ declare function setDriverFactory(factory: DriverFactory | null): void;
|
|
|
22
27
|
declare function createUnstorageBlockstore(getDefaultDriver: (base?: string) => Driver | Promise<Driver>): new (options?: UnstorageBlockstoreOptions) => InstanceType<typeof BaseBlockstore>;
|
|
23
28
|
declare function createUnstorageDatastore(getDefaultDriver: (base?: string) => Driver | Promise<Driver>): new (options?: UnstorageBlockstoreOptions) => Datastore;
|
|
24
29
|
//#endregion
|
|
25
|
-
export { UnstorageBlockstoreOptions, createUnstorageBlockstore, createUnstorageDatastore, setDriverFactory };
|
|
30
|
+
export { DriverFactory, UnstorageBlockstoreOptions, createUnstorageBlockstore, createUnstorageDatastore, setDriverFactory };
|
|
26
31
|
//# sourceMappingURL=unstorage-base.d.ts.map
|
|
@@ -84,12 +84,15 @@ function createUnstorageBlockstore(getDefaultDriver) {
|
|
|
84
84
|
yield await this.base.getItem(storageKey);
|
|
85
85
|
}
|
|
86
86
|
async *getMany(source, options) {
|
|
87
|
-
for await (const cid of source)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
for await (const cid of source) {
|
|
88
|
+
const self = this;
|
|
89
|
+
yield {
|
|
90
|
+
cid,
|
|
91
|
+
bytes: (async function* () {
|
|
92
|
+
yield* await self.get(cid, options);
|
|
93
|
+
})()
|
|
94
|
+
};
|
|
95
|
+
}
|
|
93
96
|
}
|
|
94
97
|
async delete(key, _) {
|
|
95
98
|
await this.base.deleteItem(this.keyToStorageKey(key));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unstorage-base.js","names":[],"sources":["../../../src/blockstore/unstorage-base.ts"],"sourcesContent":["import { BaseBlockstore } from \"blockstore-core\";\nimport type { InputPair, Pair as BlockstorePair } from \"interface-blockstore\";\nimport type {\n AbortOptions,\n Await,\n AwaitGenerator,\n AwaitIterable,\n} from \"interface-store\";\nimport { CID } from \"multiformats/cid\";\nimport { createStorage, type Driver, type Storage } from \"unstorage\";\nimport { DEFAULT_BLOCKSTORE_PREFIX } from \"@/types/constants\";\nimport type { Batch, Datastore, KeyQuery, Query } from \"interface-datastore\";\nimport { Key, Pair } from \"interface-datastore\";\nimport { collectAsyncIterable } from \"@/utils/stream\";\n\n\n\nexport interface UnstorageBlockstoreOptions {\n storage?: Storage;\n prefix?: string;\n driver?: Driver;\n base?: string;\n datastorePrefix?: string;\n}\n\n/**\n * prefix: Key prefix for blockstore keys (e.g., \"blockstore\" or \"pinner-helia-blocks\").\n * This is prepended to CID strings in storage keys.\n *\n * base: Base path for the storage driver (e.g., \"pinner:\" for IndexedDB, \"./.pinner-blocks\" for filesystem).\n * This determines where the storage driver stores data.\n */\n\ntype DriverFactory = () => Driver | Promise<Driver>;\n\nexport let driverFactory: DriverFactory | null = null;\n\nexport function setDriverFactory(factory: DriverFactory | null): void {\n driverFactory = factory;\n}\n\nfunction createStorageWithOptions(\n options: UnstorageBlockstoreOptions,\n): Storage {\n return options.storage\n ? options.storage\n : createStorage({ driver: options.driver });\n}\n\nasync function initializeStorage(\n storage: Storage,\n options: UnstorageBlockstoreOptions,\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n): Promise<void> {\n if (options.storage || options.driver) {\n return;\n }\n\n const driver = await getDefaultDriver(options.base);\n Object.assign(storage, createStorage({ driver }));\n}\n\nfunction createUnstorageBase(\n options: UnstorageBlockstoreOptions,\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n) {\n const storage = createStorageWithOptions(options);\n const initialized = initializeStorage(storage, options, getDefaultDriver);\n\n async function ensureInitialized(): Promise<void> {\n await initialized;\n }\n\n async function hasItem(key: string): Promise<boolean> {\n await ensureInitialized();\n return await storage.hasItem(key);\n }\n\n async function getItem(key: string): Promise<Uint8Array> {\n await ensureInitialized();\n const value = await storage.getItemRaw<Uint8Array>(key);\n\n if (value === null) {\n throw new Error(`Item not found: ${key}`);\n }\n\n return value;\n }\n\n async function putItem(key: string, value: Uint8Array): Promise<void> {\n await ensureInitialized();\n await storage.setItemRaw(key, value);\n }\n\n async function deleteItem(key: string): Promise<void> {\n await ensureInitialized();\n await storage.removeItem(key);\n }\n\n async function getAllKeys(): Promise<string[]> {\n await ensureInitialized();\n return await storage.getKeys();\n }\n\n return {\n storage,\n hasItem,\n getItem,\n putItem,\n deleteItem,\n getAllKeys,\n };\n}\n\nexport function createUnstorageBlockstore(\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n): new (\n options?: UnstorageBlockstoreOptions,\n) => InstanceType<typeof BaseBlockstore> {\n return class UnstorageBlockstore extends BaseBlockstore {\n private prefix: string;\n private base: ReturnType<typeof createUnstorageBase>;\n\n constructor(options: UnstorageBlockstoreOptions = {}) {\n super();\n this.prefix = options.prefix ?? DEFAULT_BLOCKSTORE_PREFIX;\n this.base = createUnstorageBase(options, getDefaultDriver);\n }\n\n private keyToStorageKey(key: CID): string {\n return `${this.prefix}:${key.toString()}`;\n }\n\n async has(key: CID, _?: AbortOptions): Promise<boolean> {\n return await this.base.hasItem(this.keyToStorageKey(key));\n }\n\n async put(\n key: CID,\n val: Uint8Array | AwaitIterable<Uint8Array>,\n _?: AbortOptions,\n ): Promise<CID> {\n const storageKey = this.keyToStorageKey(key);\n const bytes =\n val instanceof Uint8Array ? val : await collectAsyncIterable(val);\n await this.base.putItem(storageKey, bytes);\n return key;\n }\n\n async *putMany(\n source: AwaitIterable<InputPair>,\n options?: AbortOptions,\n ): AwaitGenerator<CID> {\n for await (const { cid, bytes } of source) {\n yield await this.put(cid, bytes, options);\n }\n }\n\n async *get(key: CID, _?: AbortOptions): AsyncGenerator<Uint8Array> {\n const storageKey = this.keyToStorageKey(key);\n const value = await this.base.getItem(storageKey);\n yield value;\n }\n\n async *getMany(\n source: AwaitIterable<CID>,\n options?: AbortOptions,\n ): AwaitGenerator<BlockstorePair> {\n for await (const cid of source) {\n yield {\n cid,\n bytes: (async function* () {\n yield* await this.get(cid, options);\n }.call(this)),\n };\n }\n }\n\n async delete(key: CID, _?: AbortOptions): Promise<void> {\n await this.base.deleteItem(this.keyToStorageKey(key));\n }\n\n async *deleteMany(\n source: AwaitIterable<CID>,\n options?: AbortOptions,\n ): AwaitGenerator<CID> {\n for await (const cid of source) {\n await this.delete(cid, options);\n yield cid;\n }\n }\n\n async *getAll(_?: AbortOptions): AwaitGenerator<BlockstorePair> {\n const keys = await this.base.getAllKeys();\n\n for (const key of keys) {\n if (key.startsWith(this.prefix + \":\")) {\n const cidString = key.slice(this.prefix.length + 1);\n try {\n const cid = CID.parse(cidString);\n const value = await this.base.getItem(key);\n\n yield {\n cid,\n bytes: (async function* () {\n yield value;\n })(),\n };\n } catch {\n // Skip invalid keys\n }\n }\n }\n }\n };\n}\n\nexport function createUnstorageDatastore(\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n): new (options?: UnstorageBlockstoreOptions) => Datastore {\n return class UnstorageDatastore implements Datastore {\n private prefix: string;\n private base: ReturnType<typeof createUnstorageBase>;\n\n constructor(options: UnstorageBlockstoreOptions = {}) {\n this.prefix =\n options.datastorePrefix ?? options.prefix ?? DEFAULT_BLOCKSTORE_PREFIX;\n this.base = createUnstorageBase(options, getDefaultDriver);\n }\n\n private keyToStorageKey(key: Key): string {\n return `${this.prefix}:${key.toString()}`;\n }\n\n private storageKeyToKey(storageKey: string): Key {\n return new Key(storageKey.slice(this.prefix.length + 1));\n }\n\n async has(key: Key, _?: AbortOptions): Promise<boolean> {\n return await this.base.hasItem(this.keyToStorageKey(key));\n }\n\n async put(key: Key, val: Uint8Array, _?: AbortOptions): Promise<Key> {\n await this.base.putItem(this.keyToStorageKey(key), val);\n return key;\n }\n\n async *putMany(\n source: AwaitIterable<Pair>,\n options?: AbortOptions,\n ): AsyncGenerator<Key> {\n for await (const { key, value } of source) {\n yield await this.put(key, value, options);\n }\n }\n\n async get(key: Key, _?: AbortOptions): Promise<Uint8Array> {\n const storageKey = this.keyToStorageKey(key);\n try {\n return await this.base.getItem(storageKey);\n } catch (error) {\n throw new Error(`Datastore item not found: ${key.toString()}`);\n }\n }\n\n async *getMany(\n source: AwaitIterable<Key>,\n options?: AbortOptions,\n ): AsyncGenerator<Pair> {\n for await (const key of source) {\n yield {\n key,\n value: await this.get(key, options),\n };\n }\n }\n\n async delete(key: Key, _?: AbortOptions): Promise<void> {\n await this.base.deleteItem(this.keyToStorageKey(key));\n }\n\n async *deleteMany(\n source: AwaitIterable<Key>,\n options?: AbortOptions,\n ): AsyncGenerator<Key> {\n for await (const key of source) {\n await this.delete(key, options);\n yield key;\n }\n }\n\n batch(): Batch {\n const operations: Array<{\n type: \"put\" | \"delete\";\n key: Key;\n value?: Uint8Array;\n }> = [];\n const base = this.base;\n const keyToStorageKey = this.keyToStorageKey.bind(this);\n\n return {\n put(key: Key, value: Uint8Array): void {\n operations.push({ type: \"put\", key, value });\n },\n delete(key: Key): void {\n operations.push({ type: \"delete\", key });\n },\n async commit(): Promise<void> {\n for (const op of operations) {\n if (op.type === \"put\" && op.value !== undefined) {\n await base.putItem(keyToStorageKey(op.key), op.value);\n } else if (op.type === \"delete\") {\n await base.deleteItem(keyToStorageKey(op.key));\n }\n }\n operations.length = 0;\n },\n };\n }\n\n async *query(query: Query, _?: AbortOptions): AsyncGenerator<Pair> {\n const keys = await this.base.getAllKeys();\n\n for (const key of keys) {\n if (!key.startsWith(this.prefix + \":\")) {\n continue;\n }\n\n const datastoreKey = this.storageKeyToKey(key);\n\n if (\n query.prefix &&\n !datastoreKey.toString().startsWith(query.prefix.toString())\n ) {\n continue;\n }\n\n const value = await this.base.getItem(key);\n\n if (query.filters) {\n let match = true;\n for (const filter of query.filters) {\n if (!filter({ key: datastoreKey, value })) {\n match = false;\n break;\n }\n }\n if (!match) continue;\n }\n\n yield {\n key: datastoreKey,\n value,\n };\n }\n }\n\n async *queryKeys(query: KeyQuery, _?: AbortOptions): AsyncGenerator<Key> {\n const keys = await this.base.getAllKeys();\n\n for (const key of keys) {\n if (!key.startsWith(this.prefix + \":\")) {\n continue;\n }\n\n const datastoreKey = this.storageKeyToKey(key);\n\n if (\n query.prefix &&\n !datastoreKey.toString().startsWith(query.prefix.toString())\n ) {\n continue;\n }\n\n yield datastoreKey;\n }\n }\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"unstorage-base.js","names":[],"sources":["../../../src/blockstore/unstorage-base.ts"],"sourcesContent":["import { BaseBlockstore } from \"blockstore-core\";\nimport type { InputPair, Pair as BlockstorePair } from \"interface-blockstore\";\nimport type {\n AbortOptions,\n Await,\n AwaitGenerator,\n AwaitIterable,\n} from \"interface-store\";\nimport { CID } from \"multiformats/cid\";\nimport { createStorage, type Driver, type Storage } from \"unstorage\";\nimport { DEFAULT_BLOCKSTORE_PREFIX } from \"@/types/constants\";\nimport type { Batch, Datastore, KeyQuery, Query } from \"interface-datastore\";\nimport { Key, Pair } from \"interface-datastore\";\nimport { collectAsyncIterable } from \"@/utils/stream\";\n\n\n\nexport interface UnstorageBlockstoreOptions {\n /** Unstorage instance to use (bypasses driver creation) */\n storage?: Storage;\n /** Key prefix for blockstore keys */\n prefix?: string;\n /** Unstorage driver name or instance */\n driver?: Driver;\n /** Base path for storage driver */\n base?: string;\n /** Prefix for datastore keys (defaults to prefix) */\n datastorePrefix?: string;\n}\n\n/**\n * prefix: Key prefix for blockstore keys (e.g., \"blockstore\" or \"pinner-helia-blocks\").\n * This is prepended to CID strings in storage keys.\n *\n * base: Base path for the storage driver (e.g., \"pinner:\" for IndexedDB, \"./.pinner-blocks\" for filesystem).\n * This determines where the storage driver stores data.\n */\n\nexport type DriverFactory = () => Driver | Promise<Driver>;\n\nexport let driverFactory: DriverFactory | null = null;\n\nexport function setDriverFactory(factory: DriverFactory | null): void {\n driverFactory = factory;\n}\n\nfunction createStorageWithOptions(\n options: UnstorageBlockstoreOptions,\n): Storage {\n return options.storage\n ? options.storage\n : createStorage({ driver: options.driver });\n}\n\nasync function initializeStorage(\n storage: Storage,\n options: UnstorageBlockstoreOptions,\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n): Promise<void> {\n if (options.storage || options.driver) {\n return;\n }\n\n const driver = await getDefaultDriver(options.base);\n Object.assign(storage, createStorage({ driver }));\n}\n\nfunction createUnstorageBase(\n options: UnstorageBlockstoreOptions,\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n) {\n const storage = createStorageWithOptions(options);\n const initialized = initializeStorage(storage, options, getDefaultDriver);\n\n async function ensureInitialized(): Promise<void> {\n await initialized;\n }\n\n async function hasItem(key: string): Promise<boolean> {\n await ensureInitialized();\n return await storage.hasItem(key);\n }\n\n async function getItem(key: string): Promise<Uint8Array> {\n await ensureInitialized();\n const value = await storage.getItemRaw<Uint8Array>(key);\n\n if (value === null) {\n throw new Error(`Item not found: ${key}`);\n }\n\n return value;\n }\n\n async function putItem(key: string, value: Uint8Array): Promise<void> {\n await ensureInitialized();\n await storage.setItemRaw(key, value);\n }\n\n async function deleteItem(key: string): Promise<void> {\n await ensureInitialized();\n await storage.removeItem(key);\n }\n\n async function getAllKeys(): Promise<string[]> {\n await ensureInitialized();\n return await storage.getKeys();\n }\n\n return {\n storage,\n hasItem,\n getItem,\n putItem,\n deleteItem,\n getAllKeys,\n };\n}\n\nexport function createUnstorageBlockstore(\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n): new (\n options?: UnstorageBlockstoreOptions,\n) => InstanceType<typeof BaseBlockstore> {\n return class UnstorageBlockstore extends BaseBlockstore {\n private prefix: string;\n private base: ReturnType<typeof createUnstorageBase>;\n\n constructor(options: UnstorageBlockstoreOptions = {}) {\n super();\n this.prefix = options.prefix ?? DEFAULT_BLOCKSTORE_PREFIX;\n this.base = createUnstorageBase(options, getDefaultDriver);\n }\n\n private keyToStorageKey(key: CID): string {\n return `${this.prefix}:${key.toString()}`;\n }\n\n async has(key: CID, _?: AbortOptions): Promise<boolean> {\n return await this.base.hasItem(this.keyToStorageKey(key));\n }\n\n async put(\n key: CID,\n val: Uint8Array | AwaitIterable<Uint8Array>,\n _?: AbortOptions,\n ): Promise<CID> {\n const storageKey = this.keyToStorageKey(key);\n const bytes =\n val instanceof Uint8Array ? val : await collectAsyncIterable(val);\n await this.base.putItem(storageKey, bytes);\n return key;\n }\n\n async *putMany(\n source: AwaitIterable<InputPair>,\n options?: AbortOptions,\n ): AwaitGenerator<CID> {\n for await (const { cid, bytes } of source) {\n yield await this.put(cid, bytes, options);\n }\n }\n\n async *get(key: CID, _?: AbortOptions): AsyncGenerator<Uint8Array> {\n const storageKey = this.keyToStorageKey(key);\n const value = await this.base.getItem(storageKey);\n yield value;\n }\n\n async *getMany(\n source: AwaitIterable<CID>,\n options?: AbortOptions,\n ): AwaitGenerator<BlockstorePair> {\n for await (const cid of source) {\n const self = this;\n yield {\n cid,\n bytes: (async function* () {\n yield* await self.get(cid, options);\n })(),\n };\n }\n }\n\n async delete(key: CID, _?: AbortOptions): Promise<void> {\n await this.base.deleteItem(this.keyToStorageKey(key));\n }\n\n async *deleteMany(\n source: AwaitIterable<CID>,\n options?: AbortOptions,\n ): AwaitGenerator<CID> {\n for await (const cid of source) {\n await this.delete(cid, options);\n yield cid;\n }\n }\n\n async *getAll(_?: AbortOptions): AwaitGenerator<BlockstorePair> {\n const keys = await this.base.getAllKeys();\n\n for (const key of keys) {\n if (key.startsWith(this.prefix + \":\")) {\n const cidString = key.slice(this.prefix.length + 1);\n try {\n const cid = CID.parse(cidString);\n const value = await this.base.getItem(key);\n\n yield {\n cid,\n bytes: (async function* () {\n yield value;\n })(),\n };\n } catch {\n // Skip invalid keys\n }\n }\n }\n }\n };\n}\n\nexport function createUnstorageDatastore(\n getDefaultDriver: (base?: string) => Driver | Promise<Driver>,\n): new (options?: UnstorageBlockstoreOptions) => Datastore {\n return class UnstorageDatastore implements Datastore {\n private prefix: string;\n private base: ReturnType<typeof createUnstorageBase>;\n\n constructor(options: UnstorageBlockstoreOptions = {}) {\n this.prefix =\n options.datastorePrefix ?? options.prefix ?? DEFAULT_BLOCKSTORE_PREFIX;\n this.base = createUnstorageBase(options, getDefaultDriver);\n }\n\n private keyToStorageKey(key: Key): string {\n return `${this.prefix}:${key.toString()}`;\n }\n\n private storageKeyToKey(storageKey: string): Key {\n return new Key(storageKey.slice(this.prefix.length + 1));\n }\n\n async has(key: Key, _?: AbortOptions): Promise<boolean> {\n return await this.base.hasItem(this.keyToStorageKey(key));\n }\n\n async put(key: Key, val: Uint8Array, _?: AbortOptions): Promise<Key> {\n await this.base.putItem(this.keyToStorageKey(key), val);\n return key;\n }\n\n async *putMany(\n source: AwaitIterable<Pair>,\n options?: AbortOptions,\n ): AsyncGenerator<Key> {\n for await (const { key, value } of source) {\n yield await this.put(key, value, options);\n }\n }\n\n async get(key: Key, _?: AbortOptions): Promise<Uint8Array> {\n const storageKey = this.keyToStorageKey(key);\n try {\n return await this.base.getItem(storageKey);\n } catch (error) {\n throw new Error(`Datastore item not found: ${key.toString()}`);\n }\n }\n\n async *getMany(\n source: AwaitIterable<Key>,\n options?: AbortOptions,\n ): AsyncGenerator<Pair> {\n for await (const key of source) {\n yield {\n key,\n value: await this.get(key, options),\n };\n }\n }\n\n async delete(key: Key, _?: AbortOptions): Promise<void> {\n await this.base.deleteItem(this.keyToStorageKey(key));\n }\n\n async *deleteMany(\n source: AwaitIterable<Key>,\n options?: AbortOptions,\n ): AsyncGenerator<Key> {\n for await (const key of source) {\n await this.delete(key, options);\n yield key;\n }\n }\n\n batch(): Batch {\n const operations: Array<{\n type: \"put\" | \"delete\";\n key: Key;\n value?: Uint8Array;\n }> = [];\n const base = this.base;\n const keyToStorageKey = this.keyToStorageKey.bind(this);\n\n return {\n put(key: Key, value: Uint8Array): void {\n operations.push({ type: \"put\", key, value });\n },\n delete(key: Key): void {\n operations.push({ type: \"delete\", key });\n },\n async commit(): Promise<void> {\n for (const op of operations) {\n if (op.type === \"put\" && op.value !== undefined) {\n await base.putItem(keyToStorageKey(op.key), op.value);\n } else if (op.type === \"delete\") {\n await base.deleteItem(keyToStorageKey(op.key));\n }\n }\n operations.length = 0;\n },\n };\n }\n\n async *query(query: Query, _?: AbortOptions): AsyncGenerator<Pair> {\n const keys = await this.base.getAllKeys();\n\n for (const key of keys) {\n if (!key.startsWith(this.prefix + \":\")) {\n continue;\n }\n\n const datastoreKey = this.storageKeyToKey(key);\n\n if (\n query.prefix &&\n !datastoreKey.toString().startsWith(query.prefix.toString())\n ) {\n continue;\n }\n\n const value = await this.base.getItem(key);\n\n if (query.filters) {\n let match = true;\n for (const filter of query.filters) {\n if (!filter({ key: datastoreKey, value })) {\n match = false;\n break;\n }\n }\n if (!match) continue;\n }\n\n yield {\n key: datastoreKey,\n value,\n };\n }\n }\n\n async *queryKeys(query: KeyQuery, _?: AbortOptions): AsyncGenerator<Key> {\n const keys = await this.base.getAllKeys();\n\n for (const key of keys) {\n if (!key.startsWith(this.prefix + \":\")) {\n continue;\n }\n\n const datastoreKey = this.storageKeyToKey(key);\n\n if (\n query.prefix &&\n !datastoreKey.toString().startsWith(query.prefix.toString())\n ) {\n continue;\n }\n\n yield datastoreKey;\n }\n }\n };\n}\n"],"mappings":"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"}
|
package/dist/esm/config.d.ts
CHANGED
|
@@ -40,11 +40,23 @@ interface PinnerConfig {
|
|
|
40
40
|
storage?: Storage;
|
|
41
41
|
/**
|
|
42
42
|
* Custom base name for Helia storage.
|
|
43
|
-
* Passed as the
|
|
43
|
+
* Passed as the base option to both blockstore and datastore storage instances.
|
|
44
44
|
* Only used when neither datastore nor storage are provided.
|
|
45
45
|
* @default "pinner-helia-data"
|
|
46
46
|
*/
|
|
47
47
|
datastoreName?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Upload request timeout in milliseconds.
|
|
50
|
+
* Applied to XHR uploads. TUS does not expose a timeout option.
|
|
51
|
+
* @default 120_000
|
|
52
|
+
*/
|
|
53
|
+
timeout?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Number of retry attempts for failed uploads.
|
|
56
|
+
* Applied to XHR uploads (TUS uses retryDelays instead).
|
|
57
|
+
* @default 3
|
|
58
|
+
*/
|
|
59
|
+
retries?: number;
|
|
48
60
|
}
|
|
49
61
|
//#endregion
|
|
50
62
|
export { PinnerConfig };
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -3,18 +3,41 @@ import { Component } from "./api/generated/schemas/component.js";
|
|
|
3
3
|
import { ErrorResponse } from "./api/generated/schemas/errorResponse.js";
|
|
4
4
|
import { FileManagerItem } from "./api/generated/schemas/fileManagerItem.js";
|
|
5
5
|
import { FileManagerItemResponse } from "./api/generated/schemas/fileManagerItemResponse.js";
|
|
6
|
+
import { GatewayWebsiteResponse } from "./api/generated/schemas/gatewayWebsiteResponse.js";
|
|
7
|
+
import { GatewayWebsiteStatusResponse } from "./api/generated/schemas/gatewayWebsiteStatusResponse.js";
|
|
8
|
+
import { GetBlockMetaBatchRequest } from "./api/generated/schemas/getBlockMetaBatchRequest.js";
|
|
6
9
|
import { InfoResponse } from "./api/generated/schemas/infoResponse.js";
|
|
10
|
+
import { IPNSKeyListResponse } from "./api/generated/schemas/iPNSKeyListResponse.js";
|
|
11
|
+
import { IPNSKeyListResponseResponse } from "./api/generated/schemas/iPNSKeyListResponseResponse.js";
|
|
12
|
+
import { IPNSKeyRequest } from "./api/generated/schemas/iPNSKeyRequest.js";
|
|
13
|
+
import { IPNSKeyResponse } from "./api/generated/schemas/iPNSKeyResponse.js";
|
|
14
|
+
import { IPNSPublishRequest } from "./api/generated/schemas/iPNSPublishRequest.js";
|
|
15
|
+
import { IPNSPublishResponse } from "./api/generated/schemas/iPNSPublishResponse.js";
|
|
16
|
+
import { IPNSRepublishResponse } from "./api/generated/schemas/iPNSRepublishResponse.js";
|
|
17
|
+
import { IPNSResolveResponse } from "./api/generated/schemas/iPNSResolveResponse.js";
|
|
18
|
+
import { Multiaddr } from "./api/generated/schemas/multiaddr.js";
|
|
7
19
|
import { PinRequestMeta } from "./api/generated/schemas/pinRequestMeta.js";
|
|
8
20
|
import { PinRequest } from "./api/generated/schemas/pinRequest.js";
|
|
9
21
|
import { PinStatusResponseInfo } from "./api/generated/schemas/pinStatusResponseInfo.js";
|
|
10
22
|
import { PinStatusResponse } from "./api/generated/schemas/pinStatusResponse.js";
|
|
11
23
|
import { PinResultsResponse } from "./api/generated/schemas/pinResultsResponse.js";
|
|
24
|
+
import { PostApiUploadBody } from "./api/generated/schemas/postApiUploadBody.js";
|
|
12
25
|
import { PostUploadResponse } from "./api/generated/schemas/postUploadResponse.js";
|
|
26
|
+
import { SSLStatusInfo } from "./api/generated/schemas/sSLStatusInfo.js";
|
|
27
|
+
import { SSLStatusUpdateRequest } from "./api/generated/schemas/sSLStatusUpdateRequest.js";
|
|
13
28
|
import { UploadResultResponse } from "./api/generated/schemas/uploadResultResponse.js";
|
|
29
|
+
import { WebsiteConfigResponse } from "./api/generated/schemas/websiteConfigResponse.js";
|
|
30
|
+
import { WebsiteItem } from "./api/generated/schemas/websiteItem.js";
|
|
31
|
+
import { WebsiteItemResponse } from "./api/generated/schemas/websiteItemResponse.js";
|
|
32
|
+
import { WebsiteRequest } from "./api/generated/schemas/websiteRequest.js";
|
|
33
|
+
import { WebsiteResponse } from "./api/generated/schemas/websiteResponse.js";
|
|
34
|
+
import { WebsiteUpdateRequest } from "./api/generated/schemas/websiteUpdateRequest.js";
|
|
35
|
+
import { WebsiteValidateResponse } from "./api/generated/schemas/websiteValidateResponse.js";
|
|
14
36
|
import { PinnerConfig } from "./config.js";
|
|
15
|
-
import { IpnsClient } from "./api/ipns.js";
|
|
16
|
-
import { WebsiteValidationReason, WebsiteValidationReasonValue, WebsitesClient, getValidationReason, isValidationReason } from "./api/websites.js";
|
|
17
|
-
import { UploadInput, UploadOperation, UploadOptions, UploadProgress, UploadResult } from "./types/upload.js";
|
|
37
|
+
import { IpnsClient, IpnsClientOptions } from "./api/ipns.js";
|
|
38
|
+
import { SSLCallbacks, SSLError, SSLWatcher, WatchOptions, WebsiteValidationReason, WebsiteValidationReasonValue, WebsitesClient, WebsitesClientOptions, getValidationReason, isValidationReason } from "./api/websites.js";
|
|
39
|
+
import { PinnerUploadBuilder, UploadInput, UploadOperation, UploadOptions as UploadOptions$2, UploadProgress, UploadResult } from "./types/upload.js";
|
|
40
|
+
import { UploadBuilderNamespace, UploadMethodAndBuilder } from "./upload/builder.js";
|
|
18
41
|
import { AbortOptions, RemoteAddOptions, RemoteLsOptions, RemotePin, RemotePins } from "./types/pin.js";
|
|
19
42
|
import { Pinner } from "./pinner.js";
|
|
20
43
|
import { UploadManager } from "./upload/manager.js";
|
|
@@ -22,10 +45,12 @@ import { CarPreprocessOptions, CarPreprocessResult, destroyCarPreprocessor, isCa
|
|
|
22
45
|
import { AuthenticationError, ConfigurationError, EmptyFileError, NetworkError, NotFoundError, PinError, PinnerError, RateLimitError, TimeoutError, UploadError, ValidationError } from "./errors/index.js";
|
|
23
46
|
import { isAuthenticationError, isRetryable } from "./types/type-guards.js";
|
|
24
47
|
import { FILE_EXTENSION_CAR, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM } from "./types/mime-types.js";
|
|
25
|
-
import { UnstorageBlockstoreOptions, setDriverFactory } from "./blockstore/unstorage-base.js";
|
|
48
|
+
import { DriverFactory, UnstorageBlockstoreOptions, setDriverFactory } from "./blockstore/unstorage-base.js";
|
|
26
49
|
import { createBlockstore, createDatastore } from "./blockstore/unstorage.js";
|
|
27
50
|
import { asyncGeneratorToReadableStream, calculateStreamSize, readableStreamToAsyncIterable, streamToBlob } from "./utils/stream.js";
|
|
28
|
-
import {
|
|
51
|
+
import { AccessLinkOptions, AnalyticsQuery as AnalyticsQuery$1, CidVersion, ContentType, DeleteResponse as DeleteResponse$1, FileListItem as FileListItem$1, FileListQuery as FileListQuery$1, FileListResponse as FileListResponse$1, GetCIDResponse, GetGroupOptions, GroupCIDOptions, GroupListResponse, GroupOptions, GroupQueryOptions, GroupResponseItem, Network, PinByCIDResponse, PinQueueItem, PinQueueQuery, PinQueueResponse, PinataConfig as PinataConfig$1, PinataMetadata as PinataMetadata$1, SignedUploadUrlOptions, SwapCidOptions as SwapCidOptions$1, SwapCidResponse as SwapCidResponse$1, SwapHistoryOptions as SwapHistoryOptions$1, TimeIntervalAnalyticsQuery as TimeIntervalAnalyticsQuery$1, TimeIntervalAnalyticsResponse as TimeIntervalAnalyticsResponse$1, TimePeriodItem as TimePeriodItem$1, TopAnalyticsItem as TopAnalyticsItem$1, TopAnalyticsQuery as TopAnalyticsQuery$1, TopAnalyticsResponse as TopAnalyticsResponse$1, UpdateFileOptions, UpdateGroupFilesResponse, UpdateGroupOptions, UploadCIDOptions, UploadOptions as UploadOptions$1, UploadResponse as UploadResponse$1, UserPinnedDataResponse } from "./adapters/pinata/v2/types.js";
|
|
52
|
+
import { Analytics, FilterFiles, FilterGroups, FilterQueue, PinataAdapter, PrivateFiles, PrivateGateways, PrivateGroups, PrivateUpload, PublicFiles, PublicGateways, PublicGroups, PublicUpload, UploadBuilder } from "./adapters/pinata/v2/adapter-interface.js";
|
|
29
53
|
import { pinataAdapter } from "./adapters/pinata/v2/adapter.js";
|
|
54
|
+
import { AnalyticsQuery, ContainsCIDResponse, DeleteResponse, FileListItem, FileListQuery, FileListResponse, FileObject, JsonBody, KeyScopes, PinJobItem, PinJobQuery, PinJobResponse, PinataConfig, PinataMetadata, SignedUrlOptions, SwapCidOptions, SwapCidResponse, SwapHistoryOptions, TimeIntervalAnalyticsQuery, TimeIntervalAnalyticsResponse, TimePeriodItem, TopAnalyticsItem, TopAnalyticsQuery, TopAnalyticsResponse, UploadOptions, UploadResponse } from "./adapters/pinata/shared/types.js";
|
|
30
55
|
import { PinataLegacyAdapter, pinataLegacyAdapter } from "./adapters/pinata/legacy/adapter.js";
|
|
31
|
-
export { type AbortOptions, AuthenticationError, type BlockMetaResponse, type CarPreprocessOptions, type CarPreprocessResult, type Component, ConfigurationError, EmptyFileError, type ErrorResponse, FILE_EXTENSION_CAR, type FileManagerItem, type FileManagerItemResponse, type InfoResponse, IpnsClient, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM, NetworkError, NotFoundError, PinError, type PinRequest, type PinRequestMeta, type PinResultsResponse, type PinStatusResponse, type PinStatusResponseInfo, type PinataAdapter, type PinataLegacyAdapter, Pinner, type PinnerConfig, PinnerError, type PostUploadResponse, RateLimitError, type RemoteAddOptions, type RemoteLsOptions, type RemotePin, type RemotePins, TimeoutError, type UnstorageBlockstoreOptions, UploadError, type UploadInput, UploadManager, type UploadOperation, type UploadOptions, type UploadProgress, type UploadResult, type UploadResultResponse, ValidationError, WebsiteValidationReason, type WebsiteValidationReasonValue, WebsitesClient, asyncGeneratorToReadableStream, calculateStreamSize, createBlockstore, createDatastore, destroyCarPreprocessor, getValidationReason, isAuthenticationError, isCarFile, isRetryable, isValidationReason, pinataAdapter, pinataLegacyAdapter, preprocessToCar, readableStreamToAsyncIterable, setDriverFactory, streamToBlob };
|
|
56
|
+
export { type AbortOptions, AuthenticationError, type BlockMetaResponse, type CarPreprocessOptions, type CarPreprocessResult, type Component, ConfigurationError, type DriverFactory, EmptyFileError, type ErrorResponse, FILE_EXTENSION_CAR, type FileManagerItem, type FileManagerItemResponse, type GatewayWebsiteResponse, type GatewayWebsiteStatusResponse, type GetBlockMetaBatchRequest, type IPNSKeyListResponse, type IPNSKeyListResponseResponse, type IPNSKeyRequest, type IPNSKeyResponse, type IPNSPublishRequest, type IPNSPublishResponse, type IPNSRepublishResponse, type IPNSResolveResponse, type InfoResponse, IpnsClient, type IpnsClientOptions, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM, type Multiaddr, NetworkError, NotFoundError, PinError, type PinRequest, type PinRequestMeta, type PinResultsResponse, type PinStatusResponse, type PinStatusResponseInfo, type PinataAdapter, type Analytics as PinataAnalytics, type AnalyticsQuery as PinataAnalyticsQuery, type CidVersion as PinataCidVersion, type ContainsCIDResponse as PinataContainsCIDResponse, type DeleteResponse as PinataDeleteResponse, type FileListItem as PinataFileListItem, type FileListQuery as PinataFileListQuery, type FileListResponse as PinataFileListResponse, type FileObject as PinataFileObject, type FilterFiles as PinataFilterFiles, type FilterGroups as PinataFilterGroups, type FilterQueue as PinataFilterQueue, type JsonBody as PinataJsonBody, type KeyScopes as PinataKeyScopes, type PinataLegacyAdapter, type PinataConfig as PinataLegacyConfig, type PinataMetadata as PinataLegacyMetadata, type Network as PinataNetwork, type PinByCIDResponse as PinataPinByCIDResponse, type PinJobItem as PinataPinJobItem, type PinJobQuery as PinataPinJobQuery, type PinJobResponse as PinataPinJobResponse, type PinQueueItem as PinataPinQueueItem, type PinQueueQuery as PinataPinQueueQuery, type PinQueueResponse as PinataPinQueueResponse, type PrivateFiles as PinataPrivateFiles, type PrivateGateways as PinataPrivateGateways, type PrivateGroups as PinataPrivateGroups, type PrivateUpload as PinataPrivateUpload, type PublicFiles as PinataPublicFiles, type PublicGateways as PinataPublicGateways, type PublicGroups as PinataPublicGroups, type PublicUpload as PinataPublicUpload, type SignedUrlOptions as PinataSignedUrlOptions, type SwapCidOptions as PinataSwapCidOptions, type SwapCidResponse as PinataSwapCidResponse, type SwapHistoryOptions as PinataSwapHistoryOptions, type TimeIntervalAnalyticsQuery as PinataTimeIntervalAnalyticsQuery, type TimeIntervalAnalyticsResponse as PinataTimeIntervalAnalyticsResponse, type TimePeriodItem as PinataTimePeriodItem, type TopAnalyticsItem as PinataTopAnalyticsItem, type TopAnalyticsQuery as PinataTopAnalyticsQuery, type TopAnalyticsResponse as PinataTopAnalyticsResponse, type UploadBuilder as PinataUploadBuilder, type UploadOptions as PinataUploadOptions, type UploadResponse as PinataUploadResponse, type AccessLinkOptions as PinataV2AccessLinkOptions, type AnalyticsQuery$1 as PinataV2AnalyticsQuery, type PinataConfig$1 as PinataV2Config, type ContentType as PinataV2ContentType, type DeleteResponse$1 as PinataV2DeleteResponse, type FileListItem$1 as PinataV2FileListItem, type FileListQuery$1 as PinataV2FileListQuery, type FileListResponse$1 as PinataV2FileListResponse, type GetCIDResponse as PinataV2GetCIDResponse, type GetGroupOptions as PinataV2GetGroupOptions, type GroupCIDOptions as PinataV2GroupCIDOptions, type GroupListResponse as PinataV2GroupListResponse, type GroupOptions as PinataV2GroupOptions, type GroupQueryOptions as PinataV2GroupQueryOptions, type GroupResponseItem as PinataV2GroupResponseItem, type PinataMetadata$1 as PinataV2Metadata, type SignedUploadUrlOptions as PinataV2SignedUploadUrlOptions, type SwapCidOptions$1 as PinataV2SwapCidOptions, type SwapCidResponse$1 as PinataV2SwapCidResponse, type SwapHistoryOptions$1 as PinataV2SwapHistoryOptions, type TimeIntervalAnalyticsQuery$1 as PinataV2TimeIntervalAnalyticsQuery, type TimeIntervalAnalyticsResponse$1 as PinataV2TimeIntervalAnalyticsResponse, type TimePeriodItem$1 as PinataV2TimePeriodItem, type TopAnalyticsItem$1 as PinataV2TopAnalyticsItem, type TopAnalyticsQuery$1 as PinataV2TopAnalyticsQuery, type TopAnalyticsResponse$1 as PinataV2TopAnalyticsResponse, type UpdateFileOptions as PinataV2UpdateFileOptions, type UpdateGroupFilesResponse as PinataV2UpdateGroupFilesResponse, type UpdateGroupOptions as PinataV2UpdateGroupOptions, type UploadCIDOptions as PinataV2UploadCIDOptions, type UploadOptions$1 as PinataV2UploadOptions, type UploadResponse$1 as PinataV2UploadResponse, type UserPinnedDataResponse as PinataV2UserPinnedDataResponse, Pinner, type PinnerConfig, PinnerError, type PinnerUploadBuilder, type PostApiUploadBody, type PostUploadResponse, RateLimitError, type RemoteAddOptions, type RemoteLsOptions, type RemotePin, type RemotePins, type SSLCallbacks, type SSLError, type SSLStatusInfo, type SSLStatusUpdateRequest, type SSLWatcher, TimeoutError, type UnstorageBlockstoreOptions, type UploadBuilderNamespace, UploadError, type UploadInput, UploadManager, type UploadMethodAndBuilder, type UploadOperation, type UploadOptions$2 as UploadOptions, type UploadProgress, type UploadResult, type UploadResultResponse, ValidationError, type WatchOptions, type WebsiteConfigResponse, type WebsiteItem, type WebsiteItemResponse, type WebsiteRequest, type WebsiteResponse, type WebsiteUpdateRequest, type WebsiteValidateResponse, WebsiteValidationReason, type WebsiteValidationReasonValue, WebsitesClient, type WebsitesClientOptions, asyncGeneratorToReadableStream, calculateStreamSize, createBlockstore, createDatastore, destroyCarPreprocessor, getValidationReason, isAuthenticationError, isCarFile, isRetryable, isValidationReason, pinataAdapter, pinataLegacyAdapter, preprocessToCar, readableStreamToAsyncIterable, setDriverFactory, streamToBlob };
|
package/dist/esm/pin/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NotFoundError } from "../errors/index.js";
|
|
2
2
|
import { CID } from "multiformats/cid";
|
|
3
3
|
import { Configuration, RemotePinningServiceClient } from "@ipfs-shipyard/pinning-service-client";
|
|
4
4
|
|
|
@@ -6,18 +6,18 @@ import { Configuration, RemotePinningServiceClient } from "@ipfs-shipyard/pinnin
|
|
|
6
6
|
var PinClient = class {
|
|
7
7
|
client = null;
|
|
8
8
|
config;
|
|
9
|
-
|
|
9
|
+
auth;
|
|
10
|
+
constructor(config, auth) {
|
|
10
11
|
this.config = config;
|
|
12
|
+
this.auth = auth;
|
|
11
13
|
}
|
|
12
14
|
getClient() {
|
|
13
15
|
if (this.client) return this.client;
|
|
14
|
-
|
|
15
|
-
const configuration = new Configuration({
|
|
16
|
+
this.client = new RemotePinningServiceClient(new Configuration({
|
|
16
17
|
endpointUrl: this.config.endpoint,
|
|
17
|
-
accessToken: this.
|
|
18
|
+
accessToken: this.auth.getAccessToken(),
|
|
18
19
|
fetchApi: this.config.fetch ?? fetch
|
|
19
|
-
});
|
|
20
|
-
this.client = new RemotePinningServiceClient(configuration);
|
|
20
|
+
}));
|
|
21
21
|
return this.client;
|
|
22
22
|
}
|
|
23
23
|
async *add(cid, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../../../src/pin/client.ts"],"sourcesContent":["import {\n Configuration,\n type Pin,\n type PinStatus,\n RemotePinningServiceClient,\n} from \"@ipfs-shipyard/pinning-service-client\";\nimport type { PinnerConfig } from \"../config\";\nimport type {\n AbortOptions,\n RemoteAddOptions,\n RemoteLsOptions,\n RemotePin,\n RemotePins,\n} from \"@/types/pin\";\nimport { CID } from \"multiformats/cid\";\nimport { ConfigurationError, NotFoundError } from \"@/errors\";\n\nexport class PinClient implements RemotePins {\n private client: RemotePinningServiceClient | null = null;\n private config: PinnerConfig;\n\n constructor(config: PinnerConfig) {\n this.config = config;\n }\n\n protected getClient(): RemotePinningServiceClient {\n if (this.client) {\n return this.client;\n }\n\n
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../../src/pin/client.ts"],"sourcesContent":["import {\n Configuration,\n type Pin,\n type PinStatus,\n RemotePinningServiceClient,\n} from \"@ipfs-shipyard/pinning-service-client\";\nimport type { PinnerConfig } from \"../config\";\nimport type { AuthManager } from \"@/auth\";\nimport type {\n AbortOptions,\n RemoteAddOptions,\n RemoteLsOptions,\n RemotePin,\n RemotePins,\n} from \"@/types/pin\";\nimport { CID } from \"multiformats/cid\";\nimport { ConfigurationError, NotFoundError } from \"@/errors\";\n\nexport class PinClient implements RemotePins {\n private client: RemotePinningServiceClient | null = null;\n private config: PinnerConfig;\n private readonly auth: AuthManager;\n\n constructor(config: PinnerConfig, auth: AuthManager) {\n this.config = config;\n this.auth = auth;\n }\n\n protected getClient(): RemotePinningServiceClient {\n if (this.client) {\n return this.client;\n }\n\n this.client = new RemotePinningServiceClient(\n new Configuration({\n endpointUrl: this.config.endpoint,\n accessToken: this.auth.getAccessToken(),\n fetchApi: this.config.fetch ?? fetch,\n }),\n );\n return this.client;\n }\n\n async *add(\n cid: CID,\n options?: RemoteAddOptions,\n ): AsyncGenerator<CID, void, undefined> {\n const client = this.getClient();\n\n const pin: Pin = {\n cid: cid.toString(),\n name: options?.name,\n meta: options?.metadata,\n origins: options?.origins,\n };\n\n await client.pinsPost({ pin }, { signal: options?.signal });\n\n yield cid;\n }\n\n async *ls(\n options?: RemoteLsOptions,\n ): AsyncGenerator<RemotePin, void, undefined> {\n const client = this.getClient();\n const response = await client.pinsGet(this.normalizeListOptions(options), {\n signal: options?.signal,\n });\n\n for (const result of response.results) {\n yield this.mapResponse(result);\n }\n }\n\n async isPinned(cid: CID, options?: AbortOptions): Promise<boolean> {\n try {\n await this.get(cid, options);\n return true;\n } catch {\n return false;\n }\n }\n\n async get(cid: CID, options?: AbortOptions): Promise<RemotePin> {\n const client = this.getClient();\n const response = await client.pinsGet(\n { cid: [cid.toString()] },\n {\n signal: options?.signal,\n },\n );\n\n if (response.results.length === 0) {\n throw new NotFoundError(`Pin not found for CID: ${cid.toString()}`);\n }\n\n return this.mapResponse(response.results[0]);\n }\n\n async setMetadata(\n cid: CID,\n metadata: Record<string, string> | undefined,\n options?: AbortOptions,\n ): Promise<void> {\n const client = this.getClient();\n const response = await client.pinsGet(\n { cid: [cid.toString()] },\n {\n signal: options?.signal,\n },\n );\n\n if (response.results.length === 0) {\n throw new NotFoundError(`Pin not found for CID: ${cid.toString()}`);\n }\n\n const pin = response.results[0];\n await client.pinsRequestidPost(\n {\n requestid: pin.requestid,\n pin: {\n cid: pin.pin.cid,\n name: pin.pin.name,\n meta: metadata,\n origins: pin.pin.origins,\n },\n },\n { signal: options?.signal },\n );\n }\n\n async *rm(\n cid: CID,\n options?: AbortOptions,\n ): AsyncGenerator<CID, void, undefined> {\n const client = this.getClient();\n const response = await client.pinsGet(\n { cid: [cid.toString()] },\n { signal: options?.signal },\n );\n\n // Delete all pins for this CID by their request IDs\n await Promise.all(\n [...response.results].map(async (result) => {\n return this.rmByRequestId(result.requestid, options);\n }),\n );\n\n yield cid;\n }\n\n async rmByRequestId(requestId: string, options?: AbortOptions): Promise<void> {\n const client = this.getClient();\n await client.pinsRequestidDelete(\n { requestid: requestId },\n { signal: options?.signal },\n );\n }\n\n private mapResponse(response: PinStatus): RemotePin {\n return {\n cid: CID.parse(response.pin.cid),\n name: response.pin.name,\n status: response.status,\n created: response.created,\n size: response.pin.meta?.size\n ? parseInt(response.pin.meta.size, 10)\n : undefined,\n metadata: response.pin.meta,\n };\n }\n\n private normalizeListOptions(\n options?: RemoteLsOptions,\n ): Record<string, unknown> {\n const request: Record<string, unknown> = {};\n\n if (options?.limit !== undefined) {\n request.limit = options.limit;\n }\n if (options?.cursor !== undefined) {\n request.after = options.cursor;\n }\n if (options?.status !== undefined) {\n request.status = options.status;\n }\n if (options?.name !== undefined) {\n request.name = options.name;\n }\n\n return request;\n }\n}\n"],"mappings":"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"}
|