@lumeweb/pinner 0.1.1 → 0.1.4
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 +162 -0
- package/dist/esm/_virtual/{rolldown_runtime.js → _rolldown/runtime.js} +2 -2
- package/dist/esm/adapters/pinata/index.d.ts +1 -4
- package/dist/esm/adapters/pinata/legacy/adapter.d.ts +0 -1
- package/dist/esm/adapters/pinata/legacy/adapter.js +42 -1
- package/dist/esm/adapters/pinata/legacy/adapter.js.map +1 -1
- package/dist/esm/adapters/pinata/shared/index.d.ts +1 -2
- package/dist/esm/adapters/pinata/v2/adapter-interface.d.ts +0 -1
- package/dist/esm/adapters/pinata/v2/adapter.d.ts +0 -1
- package/dist/esm/adapters/pinata/v2/adapter.js +3 -3
- package/dist/esm/adapters/pinata/v2/adapter.js.map +1 -1
- package/dist/esm/api/generated/schemas/iPNSKeyListResponse.d.ts +46 -0
- package/dist/esm/api/generated/schemas/iPNSKeyListResponseResponse.d.ts +10 -0
- package/dist/esm/api/generated/schemas/iPNSKeyRequest.d.ts +43 -0
- package/dist/esm/api/generated/schemas/iPNSKeyResponse.d.ts +46 -0
- package/dist/esm/api/generated/schemas/iPNSPublishRequest.d.ts +44 -0
- package/dist/esm/api/generated/schemas/iPNSPublishResponse.d.ts +46 -0
- package/dist/esm/api/generated/schemas/iPNSResolveResponse.d.ts +47 -0
- package/dist/esm/api/generated/schemas/sSLStatusInfo.d.ts +45 -0
- package/dist/esm/api/generated/schemas/websiteConfigResponse.d.ts +43 -0
- package/dist/esm/api/generated/schemas/websiteItem.d.ts +23 -0
- package/dist/esm/api/generated/schemas/websiteItemResponse.d.ts +10 -0
- package/dist/esm/api/generated/schemas/websiteRequest.d.ts +45 -0
- package/dist/esm/api/generated/schemas/websiteResponse.d.ts +23 -0
- package/dist/esm/api/generated/schemas/websiteUpdateRequest.d.ts +45 -0
- package/dist/esm/api/generated/schemas/websiteValidateResponse.d.ts +45 -0
- package/dist/esm/api/ipns.d.ts +28 -0
- package/dist/esm/api/ipns.js +83 -0
- package/dist/esm/api/ipns.js.map +1 -0
- package/dist/esm/api/websites.d.ts +48 -0
- package/dist/esm/api/websites.js +168 -0
- package/dist/esm/api/websites.js.map +1 -0
- package/dist/esm/blockstore/unstorage-base.d.ts +4 -1
- package/dist/esm/blockstore/unstorage-base.js +3 -3
- package/dist/esm/blockstore/unstorage-base.js.map +1 -1
- package/dist/esm/blockstore/unstorage.d.ts +3 -31
- package/dist/esm/blockstore/unstorage.js +2 -2
- package/dist/esm/blockstore/unstorage.js.map +1 -1
- package/dist/esm/encoder/base64.js.map +1 -1
- package/dist/esm/encoder/csv/row-formatter.js.map +1 -1
- package/dist/esm/encoder/csv.js.map +1 -1
- package/dist/esm/encoder/json.js.map +1 -1
- package/dist/esm/encoder/text.js.map +1 -1
- package/dist/esm/encoder/url.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +3 -1
- package/dist/esm/pin/client.js +3 -2
- package/dist/esm/pin/client.js.map +1 -1
- package/dist/esm/pinner.d.ts +12 -0
- package/dist/esm/pinner.js +18 -0
- package/dist/esm/pinner.js.map +1 -1
- package/dist/esm/types/pin.d.ts +0 -1
- package/dist/esm/types/type-guards.d.ts +0 -1
- package/dist/esm/types/upload.d.ts +0 -1
- package/dist/esm/upload/base-upload.js +3 -3
- package/dist/esm/upload/base-upload.js.map +1 -1
- package/dist/esm/upload/builder.d.ts +0 -1
- package/dist/esm/upload/car.js +3 -3
- package/dist/esm/upload/car.js.map +1 -1
- package/dist/esm/upload/manager.js +5 -5
- package/dist/esm/upload/manager.js.map +1 -1
- package/dist/esm/upload/normalize.js +1 -1
- package/dist/esm/upload/normalize.js.map +1 -1
- package/dist/esm/utils/stream.d.ts +0 -3
- package/dist/esm/utils/tus-patch.js +2 -2
- package/dist/esm/utils/tus-patch.js.map +1 -1
- package/dist/esm/utils/validation.js.map +1 -1
- package/package.json +34 -32
- package/dist/cjs/_virtual/rolldown_runtime.cjs +0 -29
- package/dist/cjs/adapters/pinata/index.cjs +0 -6
- package/dist/cjs/adapters/pinata/legacy/adapter.cjs +0 -83
- package/dist/cjs/adapters/pinata/legacy/adapter.cjs.map +0 -1
- package/dist/cjs/adapters/pinata/legacy/adapter.d.cts +0 -74
- package/dist/cjs/adapters/pinata/legacy/index.cjs +0 -1
- package/dist/cjs/adapters/pinata/shared/index.cjs +0 -1
- package/dist/cjs/adapters/pinata/shared/types.d.cts +0 -218
- package/dist/cjs/adapters/pinata/shared/utils.cjs +0 -83
- package/dist/cjs/adapters/pinata/shared/utils.cjs.map +0 -1
- package/dist/cjs/adapters/pinata/v2/adapter-interface.d.cts +0 -198
- package/dist/cjs/adapters/pinata/v2/adapter.cjs +0 -636
- package/dist/cjs/adapters/pinata/v2/adapter.cjs.map +0 -1
- package/dist/cjs/adapters/pinata/v2/adapter.d.cts +0 -17
- package/dist/cjs/adapters/pinata/v2/index.cjs +0 -1
- package/dist/cjs/adapters/pinata/v2/types.d.cts +0 -308
- package/dist/cjs/blockstore/index.cjs +0 -2
- package/dist/cjs/blockstore/unstorage-base.cjs +0 -240
- package/dist/cjs/blockstore/unstorage-base.cjs.map +0 -1
- package/dist/cjs/blockstore/unstorage-base.d.cts +0 -23
- package/dist/cjs/blockstore/unstorage.cjs +0 -39
- package/dist/cjs/blockstore/unstorage.cjs.map +0 -1
- package/dist/cjs/blockstore/unstorage.d.cts +0 -36
- package/dist/cjs/config.d.cts +0 -51
- package/dist/cjs/encoder/base64.cjs +0 -38
- package/dist/cjs/encoder/base64.cjs.map +0 -1
- package/dist/cjs/encoder/csv/csv-formatter.cjs +0 -81
- package/dist/cjs/encoder/csv/csv-formatter.cjs.map +0 -1
- package/dist/cjs/encoder/csv/field-formatter.cjs +0 -76
- package/dist/cjs/encoder/csv/field-formatter.cjs.map +0 -1
- package/dist/cjs/encoder/csv/row-formatter.cjs +0 -159
- package/dist/cjs/encoder/csv/row-formatter.cjs.map +0 -1
- package/dist/cjs/encoder/csv.cjs +0 -44
- package/dist/cjs/encoder/csv.cjs.map +0 -1
- package/dist/cjs/encoder/error.cjs +0 -19
- package/dist/cjs/encoder/error.cjs.map +0 -1
- package/dist/cjs/encoder/index.cjs +0 -6
- package/dist/cjs/encoder/json.cjs +0 -36
- package/dist/cjs/encoder/json.cjs.map +0 -1
- package/dist/cjs/encoder/text.cjs +0 -35
- package/dist/cjs/encoder/text.cjs.map +0 -1
- package/dist/cjs/encoder/url.cjs +0 -39
- package/dist/cjs/encoder/url.cjs.map +0 -1
- package/dist/cjs/errors/index.cjs +0 -104
- package/dist/cjs/errors/index.cjs.map +0 -1
- package/dist/cjs/errors/index.d.cts +0 -47
- package/dist/cjs/index.cjs +0 -44
- package/dist/cjs/index.d.cts +0 -16
- package/dist/cjs/pin/client.cjs +0 -98
- package/dist/cjs/pin/client.cjs.map +0 -1
- package/dist/cjs/pin/index.cjs +0 -1
- package/dist/cjs/pinner.cjs +0 -132
- package/dist/cjs/pinner.cjs.map +0 -1
- package/dist/cjs/pinner.d.cts +0 -81
- package/dist/cjs/types/constants.cjs +0 -39
- package/dist/cjs/types/constants.cjs.map +0 -1
- package/dist/cjs/types/mime-types.cjs +0 -11
- package/dist/cjs/types/mime-types.cjs.map +0 -1
- package/dist/cjs/types/mime-types.d.cts +0 -7
- package/dist/cjs/types/pin.d.cts +0 -78
- package/dist/cjs/types/type-guards.cjs +0 -20
- package/dist/cjs/types/type-guards.cjs.map +0 -1
- package/dist/cjs/types/type-guards.d.cts +0 -15
- package/dist/cjs/types/upload.cjs +0 -18
- package/dist/cjs/types/upload.cjs.map +0 -1
- package/dist/cjs/types/upload.d.cts +0 -189
- package/dist/cjs/upload/base-upload.cjs +0 -135
- package/dist/cjs/upload/base-upload.cjs.map +0 -1
- package/dist/cjs/upload/builder.cjs +0 -174
- package/dist/cjs/upload/builder.cjs.map +0 -1
- package/dist/cjs/upload/builder.d.cts +0 -60
- package/dist/cjs/upload/car.cjs +0 -129
- package/dist/cjs/upload/car.cjs.map +0 -1
- package/dist/cjs/upload/car.d.cts +0 -19
- package/dist/cjs/upload/constants.cjs +0 -9
- package/dist/cjs/upload/constants.cjs.map +0 -1
- package/dist/cjs/upload/index.cjs +0 -8
- package/dist/cjs/upload/manager.cjs +0 -249
- package/dist/cjs/upload/manager.cjs.map +0 -1
- package/dist/cjs/upload/manager.d.cts +0 -35
- package/dist/cjs/upload/normalize.cjs +0 -28
- package/dist/cjs/upload/normalize.cjs.map +0 -1
- package/dist/cjs/upload/tus-upload.cjs +0 -74
- package/dist/cjs/upload/tus-upload.cjs.map +0 -1
- package/dist/cjs/upload/xhr-upload.cjs +0 -41
- package/dist/cjs/upload/xhr-upload.cjs.map +0 -1
- package/dist/cjs/utils/env.cjs +0 -12
- package/dist/cjs/utils/env.cjs.map +0 -1
- package/dist/cjs/utils/stream.cjs +0 -141
- package/dist/cjs/utils/stream.cjs.map +0 -1
- package/dist/cjs/utils/stream.d.cts +0 -23
- package/dist/cjs/utils/tus-patch.cjs +0 -50
- package/dist/cjs/utils/tus-patch.cjs.map +0 -1
- package/dist/cjs/utils/validation.cjs +0 -62
- package/dist/cjs/utils/validation.cjs.map +0 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { PinnerConfig } from "../config.js";
|
|
2
|
+
import { SSLStatusInfo } from "./generated/schemas/sSLStatusInfo.js";
|
|
3
|
+
import { WebsiteConfigResponse } from "./generated/schemas/websiteConfigResponse.js";
|
|
4
|
+
import { WebsiteItemResponse } from "./generated/schemas/websiteItemResponse.js";
|
|
5
|
+
import { WebsiteRequest } from "./generated/schemas/websiteRequest.js";
|
|
6
|
+
import { WebsiteResponse } from "./generated/schemas/websiteResponse.js";
|
|
7
|
+
import { WebsiteUpdateRequest } from "./generated/schemas/websiteUpdateRequest.js";
|
|
8
|
+
import { WebsiteValidateResponse } from "./generated/schemas/websiteValidateResponse.js";
|
|
9
|
+
|
|
10
|
+
//#region src/api/websites.d.ts
|
|
11
|
+
interface WebsitesClientOptions {
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
declare class WebsitesClient {
|
|
15
|
+
private config;
|
|
16
|
+
constructor(config: PinnerConfig);
|
|
17
|
+
private getEndpoint;
|
|
18
|
+
private request;
|
|
19
|
+
listWebsites(options?: WebsitesClientOptions): Promise<WebsiteItemResponse>;
|
|
20
|
+
createWebsite(request: WebsiteRequest, options?: WebsitesClientOptions): Promise<WebsiteResponse>;
|
|
21
|
+
getWebsite(id: number, options?: WebsitesClientOptions): Promise<WebsiteResponse>;
|
|
22
|
+
updateWebsite(id: number, request: WebsiteUpdateRequest, options?: WebsitesClientOptions): Promise<WebsiteResponse>;
|
|
23
|
+
deleteWebsite(id: number, options?: WebsitesClientOptions): Promise<void>;
|
|
24
|
+
validateWebsite(id: number, options?: WebsitesClientOptions): Promise<WebsiteValidateResponse>;
|
|
25
|
+
getSSLStatus(domain: string, options?: WebsitesClientOptions): Promise<SSLStatusInfo>;
|
|
26
|
+
getWebsiteConfig(options?: WebsitesClientOptions): Promise<WebsiteConfigResponse>;
|
|
27
|
+
watchSSL(domain: string, options?: WatchOptions): SSLWatcher;
|
|
28
|
+
}
|
|
29
|
+
interface WatchOptions {
|
|
30
|
+
interval?: number;
|
|
31
|
+
timeout?: number;
|
|
32
|
+
}
|
|
33
|
+
interface SSLCallbacks {
|
|
34
|
+
onReady?: (status: SSLStatusInfo) => void;
|
|
35
|
+
onError?: (error: SSLError) => void;
|
|
36
|
+
onStatus?: (status: SSLStatusInfo) => void;
|
|
37
|
+
}
|
|
38
|
+
interface SSLWatcher {
|
|
39
|
+
start(callbacks: SSLCallbacks): Promise<void>;
|
|
40
|
+
stop(): void;
|
|
41
|
+
}
|
|
42
|
+
interface SSLError extends Error {
|
|
43
|
+
type: 'timeout' | 'error';
|
|
44
|
+
details?: string;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { WebsitesClient };
|
|
48
|
+
//# sourceMappingURL=websites.d.ts.map
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { AuthenticationError, ConfigurationError, NetworkError, NotFoundError, ValidationError } from "../errors/index.js";
|
|
2
|
+
import ky, { HTTPError } from "ky";
|
|
3
|
+
import { createNanoEvents } from "nanoevents";
|
|
4
|
+
|
|
5
|
+
//#region src/api/websites.ts
|
|
6
|
+
const SSLStatus = {
|
|
7
|
+
PENDING: "pending",
|
|
8
|
+
VALIDATING: "validating",
|
|
9
|
+
VALID: "valid",
|
|
10
|
+
READY: "ready",
|
|
11
|
+
FAILED: "failed",
|
|
12
|
+
ERROR: "error"
|
|
13
|
+
};
|
|
14
|
+
var WebsitesClient = class {
|
|
15
|
+
config;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
if (!config.jwt) throw new ConfigurationError("JWT token is required");
|
|
18
|
+
this.config = config;
|
|
19
|
+
}
|
|
20
|
+
getEndpoint() {
|
|
21
|
+
return this.config.endpoint ?? "https://ipfs.pinner.xyz";
|
|
22
|
+
}
|
|
23
|
+
async request(path, options) {
|
|
24
|
+
if (!this.config.jwt) throw new ConfigurationError("JWT token is required");
|
|
25
|
+
try {
|
|
26
|
+
const response = await ky(path, {
|
|
27
|
+
prefix: this.getEndpoint(),
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: `Bearer ${this.config.jwt}`,
|
|
30
|
+
"Content-Type": "application/json"
|
|
31
|
+
},
|
|
32
|
+
...options
|
|
33
|
+
});
|
|
34
|
+
if (response.status === 204) return;
|
|
35
|
+
const text = await response.text();
|
|
36
|
+
if (!text) return;
|
|
37
|
+
return JSON.parse(text);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error instanceof HTTPError) {
|
|
40
|
+
const status = error.response.status;
|
|
41
|
+
const body = await error.response.json().catch(() => ({}));
|
|
42
|
+
if (status === 401) throw new AuthenticationError(body.error || "Authentication failed");
|
|
43
|
+
if (status === 403) throw new AuthenticationError(body.error || "Access forbidden");
|
|
44
|
+
if (status === 404) throw new NotFoundError(body.error || "Resource not found");
|
|
45
|
+
if (status === 400) throw new ValidationError(body.error || "Invalid request");
|
|
46
|
+
if (status === 410) throw new ValidationError(body.error || "Target is broken or gone");
|
|
47
|
+
throw new NetworkError(body.error || `HTTP error: ${status}`);
|
|
48
|
+
}
|
|
49
|
+
if (error instanceof Error) throw new NetworkError(error.message);
|
|
50
|
+
throw new NetworkError("Unknown error occurred");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async listWebsites(options) {
|
|
54
|
+
return this.request("api/websites", { signal: options?.signal });
|
|
55
|
+
}
|
|
56
|
+
async createWebsite(request, options) {
|
|
57
|
+
return this.request("api/websites", {
|
|
58
|
+
method: "POST",
|
|
59
|
+
body: JSON.stringify(request),
|
|
60
|
+
signal: options?.signal
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async getWebsite(id, options) {
|
|
64
|
+
return this.request(`api/websites/${id}`, { signal: options?.signal });
|
|
65
|
+
}
|
|
66
|
+
async updateWebsite(id, request, options) {
|
|
67
|
+
return this.request(`api/websites/${id}`, {
|
|
68
|
+
method: "PUT",
|
|
69
|
+
body: JSON.stringify(request),
|
|
70
|
+
signal: options?.signal
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async deleteWebsite(id, options) {
|
|
74
|
+
await this.request(`api/websites/${id}`, {
|
|
75
|
+
method: "DELETE",
|
|
76
|
+
signal: options?.signal
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async validateWebsite(id, options) {
|
|
80
|
+
return this.request(`api/websites/${id}/validate`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
signal: options?.signal
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async getSSLStatus(domain, options) {
|
|
86
|
+
return this.request(`api/websites/${encodeURIComponent(domain)}/ssl-status`, { signal: options?.signal });
|
|
87
|
+
}
|
|
88
|
+
async getWebsiteConfig(options) {
|
|
89
|
+
return this.request("api/websites/config", { signal: options?.signal });
|
|
90
|
+
}
|
|
91
|
+
watchSSL(domain, options) {
|
|
92
|
+
return new SSLWatcherImpl(this, domain, options);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const DEFAULT_INTERVAL = 5e3;
|
|
96
|
+
const DEFAULT_TIMEOUT = 3e5;
|
|
97
|
+
var SSLWatcherImpl = class {
|
|
98
|
+
emitter = createNanoEvents();
|
|
99
|
+
unbind = [];
|
|
100
|
+
intervalId = null;
|
|
101
|
+
timeoutId = null;
|
|
102
|
+
stopped = false;
|
|
103
|
+
options;
|
|
104
|
+
runId = 0;
|
|
105
|
+
constructor(client, domain, options = {}) {
|
|
106
|
+
this.client = client;
|
|
107
|
+
this.domain = domain;
|
|
108
|
+
this.options = {
|
|
109
|
+
interval: options.interval ?? DEFAULT_INTERVAL,
|
|
110
|
+
timeout: options.timeout ?? DEFAULT_TIMEOUT
|
|
111
|
+
};
|
|
112
|
+
if (this.options.interval <= 0) this.options.interval = DEFAULT_INTERVAL;
|
|
113
|
+
if (this.options.timeout <= 0) this.options.timeout = DEFAULT_TIMEOUT;
|
|
114
|
+
}
|
|
115
|
+
emitError(message, type = "error", details) {
|
|
116
|
+
const error = new Error(message);
|
|
117
|
+
error.type = type;
|
|
118
|
+
error.details = details;
|
|
119
|
+
this.emitter.emit("error", error);
|
|
120
|
+
this.stop();
|
|
121
|
+
}
|
|
122
|
+
async start(callbacks = {}) {
|
|
123
|
+
this.stop();
|
|
124
|
+
this.stopped = false;
|
|
125
|
+
const currentRunId = ++this.runId;
|
|
126
|
+
if (callbacks.onReady) this.unbind.push(this.emitter.on("ready", callbacks.onReady));
|
|
127
|
+
if (callbacks.onError) this.unbind.push(this.emitter.on("error", callbacks.onError));
|
|
128
|
+
if (callbacks.onStatus) this.unbind.push(this.emitter.on("status", callbacks.onStatus));
|
|
129
|
+
const checkStatus = async () => {
|
|
130
|
+
if (this.stopped || this.runId !== currentRunId) return;
|
|
131
|
+
try {
|
|
132
|
+
const status = await this.client.getSSLStatus(this.domain);
|
|
133
|
+
if (this.stopped || this.runId !== currentRunId) return;
|
|
134
|
+
this.emitter.emit("status", status);
|
|
135
|
+
if (status.status === SSLStatus.VALID || status.status === SSLStatus.READY) {
|
|
136
|
+
this.emitter.emit("ready", status);
|
|
137
|
+
this.stop();
|
|
138
|
+
} else if (status.status === SSLStatus.FAILED || status.status === SSLStatus.ERROR) this.emitError(status.error || "SSL provisioning failed", "error", status.error);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
if (this.stopped || this.runId !== currentRunId) return;
|
|
141
|
+
this.emitError(err instanceof Error ? err.message : "Failed to check SSL status", "error");
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
await checkStatus();
|
|
145
|
+
if (this.stopped || this.runId !== currentRunId) return;
|
|
146
|
+
this.intervalId = setInterval(checkStatus, this.options.interval);
|
|
147
|
+
this.timeoutId = setTimeout(() => {
|
|
148
|
+
if (!this.stopped && this.runId === currentRunId) this.emitError("SSL provisioning timeout", "timeout");
|
|
149
|
+
}, this.options.timeout);
|
|
150
|
+
}
|
|
151
|
+
stop() {
|
|
152
|
+
this.stopped = true;
|
|
153
|
+
this.unbind.forEach((unbind) => unbind());
|
|
154
|
+
this.unbind = [];
|
|
155
|
+
if (this.intervalId) {
|
|
156
|
+
clearInterval(this.intervalId);
|
|
157
|
+
this.intervalId = null;
|
|
158
|
+
}
|
|
159
|
+
if (this.timeoutId) {
|
|
160
|
+
clearTimeout(this.timeoutId);
|
|
161
|
+
this.timeoutId = null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
//#endregion
|
|
167
|
+
export { WebsitesClient };
|
|
168
|
+
//# sourceMappingURL=websites.js.map
|
|
@@ -0,0 +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];\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,3 +1,4 @@
|
|
|
1
|
+
import { BaseBlockstore } from "blockstore-core";
|
|
1
2
|
import { Driver, Storage } from "unstorage";
|
|
2
3
|
import { Datastore } from "interface-datastore";
|
|
3
4
|
|
|
@@ -18,6 +19,8 @@ interface UnstorageBlockstoreOptions {
|
|
|
18
19
|
*/
|
|
19
20
|
type DriverFactory = () => Driver | Promise<Driver>;
|
|
20
21
|
declare function setDriverFactory(factory: DriverFactory | null): void;
|
|
22
|
+
declare function createUnstorageBlockstore(getDefaultDriver: (base?: string) => Driver | Promise<Driver>): new (options?: UnstorageBlockstoreOptions) => InstanceType<typeof BaseBlockstore>;
|
|
23
|
+
declare function createUnstorageDatastore(getDefaultDriver: (base?: string) => Driver | Promise<Driver>): new (options?: UnstorageBlockstoreOptions) => Datastore;
|
|
21
24
|
//#endregion
|
|
22
|
-
export { UnstorageBlockstoreOptions, setDriverFactory };
|
|
25
|
+
export { UnstorageBlockstoreOptions, createUnstorageBlockstore, createUnstorageDatastore, setDriverFactory };
|
|
23
26
|
//# sourceMappingURL=unstorage-base.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { collectAsyncIterable } from "../utils/stream.js";
|
|
2
2
|
import { DEFAULT_BLOCKSTORE_PREFIX } from "../types/constants.js";
|
|
3
|
-
import { BaseBlockstore } from "
|
|
3
|
+
import { BaseBlockstore } from "blockstore-core";
|
|
4
4
|
import { CID } from "multiformats/cid";
|
|
5
5
|
import { createStorage } from "unstorage";
|
|
6
6
|
import { Key } from "interface-datastore";
|
|
@@ -61,7 +61,7 @@ function createUnstorageBlockstore(getDefaultDriver) {
|
|
|
61
61
|
base;
|
|
62
62
|
constructor(options = {}) {
|
|
63
63
|
super();
|
|
64
|
-
this.prefix = options.prefix ??
|
|
64
|
+
this.prefix = options.prefix ?? "pinner-helia-blocks";
|
|
65
65
|
this.base = createUnstorageBase(options, getDefaultDriver);
|
|
66
66
|
}
|
|
67
67
|
keyToStorageKey(key) {
|
|
@@ -123,7 +123,7 @@ function createUnstorageDatastore(getDefaultDriver) {
|
|
|
123
123
|
prefix;
|
|
124
124
|
base;
|
|
125
125
|
constructor(options = {}) {
|
|
126
|
-
this.prefix = options.datastorePrefix ?? options.prefix ??
|
|
126
|
+
this.prefix = options.datastorePrefix ?? options.prefix ?? "pinner-helia-blocks";
|
|
127
127
|
this.base = createUnstorageBase(options, getDefaultDriver);
|
|
128
128
|
}
|
|
129
129
|
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 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":";;;;;;;;AAmCA,IAAW,gBAAsC;AAEjD,SAAgB,iBAAiB,SAAqC;AACpE,iBAAgB;;AAGlB,SAAS,yBACP,SACS;AACT,QAAO,QAAQ,UACX,QAAQ,UACR,cAAc,EAAE,QAAQ,QAAQ,QAAQ,CAAC;;AAG/C,eAAe,kBACb,SACA,SACA,kBACe;AACf,KAAI,QAAQ,WAAW,QAAQ,OAC7B;CAGF,MAAM,SAAS,MAAM,iBAAiB,QAAQ,KAAK;AACnD,QAAO,OAAO,SAAS,cAAc,EAAE,QAAQ,CAAC,CAAC;;AAGnD,SAAS,oBACP,SACA,kBACA;CACA,MAAM,UAAU,yBAAyB,QAAQ;CACjD,MAAM,cAAc,kBAAkB,SAAS,SAAS,iBAAiB;CAEzE,eAAe,oBAAmC;AAChD,QAAM;;CAGR,eAAe,QAAQ,KAA+B;AACpD,QAAM,mBAAmB;AACzB,SAAO,MAAM,QAAQ,QAAQ,IAAI;;CAGnC,eAAe,QAAQ,KAAkC;AACvD,QAAM,mBAAmB;EACzB,MAAM,QAAQ,MAAM,QAAQ,WAAuB,IAAI;AAEvD,MAAI,UAAU,KACZ,OAAM,IAAI,MAAM,mBAAmB,MAAM;AAG3C,SAAO;;CAGT,eAAe,QAAQ,KAAa,OAAkC;AACpE,QAAM,mBAAmB;AACzB,QAAM,QAAQ,WAAW,KAAK,MAAM;;CAGtC,eAAe,WAAW,KAA4B;AACpD,QAAM,mBAAmB;AACzB,QAAM,QAAQ,WAAW,IAAI;;CAG/B,eAAe,aAAgC;AAC7C,QAAM,mBAAmB;AACzB,SAAO,MAAM,QAAQ,SAAS;;AAGhC,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD;;AAGH,SAAgB,0BACd,kBAGuC;AACvC,QAAO,MAAM,4BAA4B,eAAe;EACtD,AAAQ;EACR,AAAQ;EAER,YAAY,UAAsC,EAAE,EAAE;AACpD,UAAO;AACP,QAAK,SAAS,QAAQ;AACtB,QAAK,OAAO,oBAAoB,SAAS,iBAAiB;;EAG5D,AAAQ,gBAAgB,KAAkB;AACxC,UAAO,GAAG,KAAK,OAAO,GAAG,IAAI,UAAU;;EAGzC,MAAM,IAAI,KAAU,GAAoC;AACtD,UAAO,MAAM,KAAK,KAAK,QAAQ,KAAK,gBAAgB,IAAI,CAAC;;EAG3D,MAAM,IACJ,KACA,KACA,GACc;GACd,MAAM,aAAa,KAAK,gBAAgB,IAAI;GAC5C,MAAM,QACJ,eAAe,aAAa,MAAM,MAAM,qBAAqB,IAAI;AACnE,SAAM,KAAK,KAAK,QAAQ,YAAY,MAAM;AAC1C,UAAO;;EAGT,OAAO,QACL,QACA,SACqB;AACrB,cAAW,MAAM,EAAE,KAAK,WAAW,OACjC,OAAM,MAAM,KAAK,IAAI,KAAK,OAAO,QAAQ;;EAI7C,OAAO,IAAI,KAAU,GAA8C;GACjE,MAAM,aAAa,KAAK,gBAAgB,IAAI;AAE5C,SAAM,MADc,KAAK,KAAK,QAAQ,WAAW;;EAInD,OAAO,QACL,QACA,SACgC;AAChC,cAAW,MAAM,OAAO,OACtB,OAAM;IACJ;IACA,OAAQ,mBAAmB;AACzB,YAAO,MAAM,KAAK,IAAI,KAAK,QAAQ;MACnC,KAAK,KAAK;IACb;;EAIL,MAAM,OAAO,KAAU,GAAiC;AACtD,SAAM,KAAK,KAAK,WAAW,KAAK,gBAAgB,IAAI,CAAC;;EAGvD,OAAO,WACL,QACA,SACqB;AACrB,cAAW,MAAM,OAAO,QAAQ;AAC9B,UAAM,KAAK,OAAO,KAAK,QAAQ;AAC/B,UAAM;;;EAIV,OAAO,OAAO,GAAkD;GAC9D,MAAM,OAAO,MAAM,KAAK,KAAK,YAAY;AAEzC,QAAK,MAAM,OAAO,KAChB,KAAI,IAAI,WAAW,KAAK,SAAS,IAAI,EAAE;IACrC,MAAM,YAAY,IAAI,MAAM,KAAK,OAAO,SAAS,EAAE;AACnD,QAAI;KACF,MAAM,MAAM,IAAI,MAAM,UAAU;KAChC,MAAM,QAAQ,MAAM,KAAK,KAAK,QAAQ,IAAI;AAE1C,WAAM;MACJ;MACA,QAAQ,mBAAmB;AACzB,aAAM;UACJ;MACL;YACK;;;;;AASlB,SAAgB,yBACd,kBACyD;AACzD,QAAO,MAAM,mBAAwC;EACnD,AAAQ;EACR,AAAQ;EAER,YAAY,UAAsC,EAAE,EAAE;AACpD,QAAK,SACH,QAAQ,mBAAmB,QAAQ;AACrC,QAAK,OAAO,oBAAoB,SAAS,iBAAiB;;EAG5D,AAAQ,gBAAgB,KAAkB;AACxC,UAAO,GAAG,KAAK,OAAO,GAAG,IAAI,UAAU;;EAGzC,AAAQ,gBAAgB,YAAyB;AAC/C,UAAO,IAAI,IAAI,WAAW,MAAM,KAAK,OAAO,SAAS,EAAE,CAAC;;EAG1D,MAAM,IAAI,KAAU,GAAoC;AACtD,UAAO,MAAM,KAAK,KAAK,QAAQ,KAAK,gBAAgB,IAAI,CAAC;;EAG3D,MAAM,IAAI,KAAU,KAAiB,GAAgC;AACnE,SAAM,KAAK,KAAK,QAAQ,KAAK,gBAAgB,IAAI,EAAE,IAAI;AACvD,UAAO;;EAGT,OAAO,QACL,QACA,SACqB;AACrB,cAAW,MAAM,EAAE,KAAK,WAAW,OACjC,OAAM,MAAM,KAAK,IAAI,KAAK,OAAO,QAAQ;;EAI7C,MAAM,IAAI,KAAU,GAAuC;GACzD,MAAM,aAAa,KAAK,gBAAgB,IAAI;AAC5C,OAAI;AACF,WAAO,MAAM,KAAK,KAAK,QAAQ,WAAW;YACnC,OAAO;AACd,UAAM,IAAI,MAAM,6BAA6B,IAAI,UAAU,GAAG;;;EAIlE,OAAO,QACL,QACA,SACsB;AACtB,cAAW,MAAM,OAAO,OACtB,OAAM;IACJ;IACA,OAAO,MAAM,KAAK,IAAI,KAAK,QAAQ;IACpC;;EAIL,MAAM,OAAO,KAAU,GAAiC;AACtD,SAAM,KAAK,KAAK,WAAW,KAAK,gBAAgB,IAAI,CAAC;;EAGvD,OAAO,WACL,QACA,SACqB;AACrB,cAAW,MAAM,OAAO,QAAQ;AAC9B,UAAM,KAAK,OAAO,KAAK,QAAQ;AAC/B,UAAM;;;EAIV,QAAe;GACb,MAAM,aAID,EAAE;GACP,MAAM,OAAO,KAAK;GAClB,MAAM,kBAAkB,KAAK,gBAAgB,KAAK,KAAK;AAEvD,UAAO;IACL,IAAI,KAAU,OAAyB;AACrC,gBAAW,KAAK;MAAE,MAAM;MAAO;MAAK;MAAO,CAAC;;IAE9C,OAAO,KAAgB;AACrB,gBAAW,KAAK;MAAE,MAAM;MAAU;MAAK,CAAC;;IAE1C,MAAM,SAAwB;AAC5B,UAAK,MAAM,MAAM,WACf,KAAI,GAAG,SAAS,SAAS,GAAG,UAAU,OACpC,OAAM,KAAK,QAAQ,gBAAgB,GAAG,IAAI,EAAE,GAAG,MAAM;cAC5C,GAAG,SAAS,SACrB,OAAM,KAAK,WAAW,gBAAgB,GAAG,IAAI,CAAC;AAGlD,gBAAW,SAAS;;IAEvB;;EAGH,OAAO,MAAM,OAAc,GAAwC;GACjE,MAAM,OAAO,MAAM,KAAK,KAAK,YAAY;AAEzC,QAAK,MAAM,OAAO,MAAM;AACtB,QAAI,CAAC,IAAI,WAAW,KAAK,SAAS,IAAI,CACpC;IAGF,MAAM,eAAe,KAAK,gBAAgB,IAAI;AAE9C,QACE,MAAM,UACN,CAAC,aAAa,UAAU,CAAC,WAAW,MAAM,OAAO,UAAU,CAAC,CAE5D;IAGF,MAAM,QAAQ,MAAM,KAAK,KAAK,QAAQ,IAAI;AAE1C,QAAI,MAAM,SAAS;KACjB,IAAI,QAAQ;AACZ,UAAK,MAAM,UAAU,MAAM,QACzB,KAAI,CAAC,OAAO;MAAE,KAAK;MAAc;MAAO,CAAC,EAAE;AACzC,cAAQ;AACR;;AAGJ,SAAI,CAAC,MAAO;;AAGd,UAAM;KACJ,KAAK;KACL;KACD;;;EAIL,OAAO,UAAU,OAAiB,GAAuC;GACvE,MAAM,OAAO,MAAM,KAAK,KAAK,YAAY;AAEzC,QAAK,MAAM,OAAO,MAAM;AACtB,QAAI,CAAC,IAAI,WAAW,KAAK,SAAS,IAAI,CACpC;IAGF,MAAM,eAAe,KAAK,gBAAgB,IAAI;AAE9C,QACE,MAAM,UACN,CAAC,aAAa,UAAU,CAAC,WAAW,MAAM,OAAO,UAAU,CAAC,CAE5D;AAGF,UAAM"}
|
|
@@ -1,36 +1,8 @@
|
|
|
1
|
-
import { UnstorageBlockstoreOptions, setDriverFactory } from "./unstorage-base.js";
|
|
2
|
-
import * as interface_datastore0 from "interface-datastore";
|
|
3
|
-
import * as multiformats0 from "multiformats";
|
|
4
|
-
import * as interface_store0 from "interface-store";
|
|
5
|
-
import * as interface_blockstore0 from "interface-blockstore";
|
|
1
|
+
import { UnstorageBlockstoreOptions, createUnstorageBlockstore, createUnstorageDatastore, setDriverFactory } from "./unstorage-base.js";
|
|
6
2
|
|
|
7
3
|
//#region src/blockstore/unstorage.d.ts
|
|
8
|
-
declare function createBlockstore(options?: UnstorageBlockstoreOptions):
|
|
9
|
-
|
|
10
|
-
has(key: multiformats0.CID, options?: interface_store0.AbortOptions): interface_store0.Await<boolean>;
|
|
11
|
-
put(key: multiformats0.CID, val: Uint8Array | interface_store0.AwaitIterable<Uint8Array>, options?: interface_store0.AbortOptions): interface_store0.Await<multiformats0.CID>;
|
|
12
|
-
putMany(source: interface_store0.AwaitIterable<interface_blockstore0.InputPair>, options?: interface_store0.AbortOptions): interface_store0.AwaitGenerator<multiformats0.CID>;
|
|
13
|
-
get(key: multiformats0.CID, options?: interface_store0.AbortOptions): interface_store0.AwaitGenerator<Uint8Array>;
|
|
14
|
-
getMany(source: interface_store0.AwaitIterable<multiformats0.CID>, options?: interface_store0.AbortOptions): interface_store0.AwaitGenerator<interface_blockstore0.Pair>;
|
|
15
|
-
delete(key: multiformats0.CID, options?: interface_store0.AbortOptions): interface_store0.Await<void>;
|
|
16
|
-
deleteMany(source: interface_store0.AwaitIterable<multiformats0.CID>, options?: interface_store0.AbortOptions): interface_store0.AwaitGenerator<multiformats0.CID>;
|
|
17
|
-
getAll(options?: interface_store0.AbortOptions): interface_store0.AwaitGenerator<interface_blockstore0.Pair>;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
declare function createDatastore(options?: UnstorageBlockstoreOptions): {
|
|
21
|
-
new (instanceOptions?: UnstorageBlockstoreOptions): {
|
|
22
|
-
batch(): interface_datastore0.Batch<{}>;
|
|
23
|
-
query(query: interface_datastore0.Query, options?: interface_store0.AbortOptions | undefined): interface_store0.AwaitGenerator<interface_datastore0.Pair>;
|
|
24
|
-
queryKeys(query: interface_datastore0.KeyQuery, options?: interface_store0.AbortOptions | undefined): interface_store0.AwaitGenerator<interface_datastore0.Key>;
|
|
25
|
-
has(key: interface_datastore0.Key, options?: interface_store0.AbortOptions | undefined): interface_store0.Await<boolean>;
|
|
26
|
-
put(key: interface_datastore0.Key, val: Uint8Array<ArrayBufferLike>, options?: interface_store0.AbortOptions | undefined): interface_store0.Await<interface_datastore0.Key>;
|
|
27
|
-
putMany(source: interface_store0.AwaitIterable<interface_datastore0.Pair>, options?: interface_store0.AbortOptions | undefined): interface_store0.AwaitGenerator<interface_datastore0.Key, any, any>;
|
|
28
|
-
get(key: interface_datastore0.Key, options?: interface_store0.AbortOptions | undefined): interface_store0.Await<Uint8Array<ArrayBufferLike>>;
|
|
29
|
-
getMany(source: interface_store0.AwaitIterable<interface_datastore0.Key>, options?: interface_store0.AbortOptions | undefined): interface_store0.AwaitGenerator<interface_datastore0.Pair, any, any>;
|
|
30
|
-
delete(key: interface_datastore0.Key, options?: interface_store0.AbortOptions | undefined): interface_store0.Await<void>;
|
|
31
|
-
deleteMany(source: interface_store0.AwaitIterable<interface_datastore0.Key>, options?: interface_store0.AbortOptions | undefined): interface_store0.AwaitGenerator<interface_datastore0.Key, any, any>;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
4
|
+
declare function createBlockstore(options?: UnstorageBlockstoreOptions): new (options?: UnstorageBlockstoreOptions) => InstanceType<ReturnType<typeof createUnstorageBlockstore>>;
|
|
5
|
+
declare function createDatastore(options?: UnstorageBlockstoreOptions): new (options?: UnstorageBlockstoreOptions) => InstanceType<ReturnType<typeof createUnstorageDatastore>>;
|
|
34
6
|
//#endregion
|
|
35
7
|
export { createBlockstore, createDatastore };
|
|
36
8
|
//# sourceMappingURL=unstorage.d.ts.map
|
|
@@ -7,8 +7,8 @@ function isBrowser() {
|
|
|
7
7
|
}
|
|
8
8
|
async function getDefaultDriver(base) {
|
|
9
9
|
if (driverFactory) return await driverFactory();
|
|
10
|
-
if (isBrowser()) return (await import("unstorage/drivers/indexedb")).default({ base: base ??
|
|
11
|
-
else return (await import("unstorage/drivers/fs-lite")).default({ base: base ??
|
|
10
|
+
if (isBrowser()) return (await import("unstorage/drivers/indexedb")).default({ base: base ?? "pinner:" });
|
|
11
|
+
else return (await import("unstorage/drivers/fs-lite")).default({ base: base ?? "./.pinner-blocks" });
|
|
12
12
|
}
|
|
13
13
|
function createBlockstore(options) {
|
|
14
14
|
const BlockstoreClass = createUnstorageBlockstore(getDefaultDriver);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unstorage.js","names":[],"sources":["../../../src/blockstore/unstorage.ts"],"sourcesContent":["import {\n createUnstorageBlockstore,\n createUnstorageDatastore,\n driverFactory,\n setDriverFactory,\n type UnstorageBlockstoreOptions,\n} from \"./unstorage-base\";\nimport {\n DEFAULT_BLOCKSTORE_BASE,\n DEFAULT_BLOCKSTORE_FS_BASE,\n} from \"@/types/constants\";\n\nfunction isBrowser(): boolean {\n return (\n typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\"\n );\n}\n\nasync function getDefaultDriver(base?: string) {\n // Use driverFactory override if set (typically by tests to inject in-memory driver)\n if (driverFactory) {\n return await driverFactory();\n }\n\n if (isBrowser()) {\n return (await import(\"unstorage/drivers/indexedb\")).default({\n base: base ?? DEFAULT_BLOCKSTORE_BASE,\n });\n } else {\n return (await import(\"unstorage/drivers/fs-lite\")).default({\n base: base ?? DEFAULT_BLOCKSTORE_FS_BASE,\n });\n }\n}\n\nexport function createBlockstore(options?: UnstorageBlockstoreOptions) {\n const BlockstoreClass = createUnstorageBlockstore(getDefaultDriver);\n return class extends BlockstoreClass {\n constructor(instanceOptions?: UnstorageBlockstoreOptions) {\n super({ ...options, ...instanceOptions });\n }\n };\n}\n\nexport function createDatastore(options?: UnstorageBlockstoreOptions) {\n const DatastoreClass = createUnstorageDatastore(getDefaultDriver);\n return class extends DatastoreClass {\n constructor(instanceOptions?: UnstorageBlockstoreOptions) {\n super({ ...options, ...instanceOptions });\n }\n };\n}\n\nexport { setDriverFactory };\nexport type { UnstorageBlockstoreOptions } from \"./unstorage-base\";\n"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"unstorage.js","names":[],"sources":["../../../src/blockstore/unstorage.ts"],"sourcesContent":["import {\n createUnstorageBlockstore,\n createUnstorageDatastore,\n driverFactory,\n setDriverFactory,\n type UnstorageBlockstoreOptions,\n} from \"./unstorage-base\";\nimport {\n DEFAULT_BLOCKSTORE_BASE,\n DEFAULT_BLOCKSTORE_FS_BASE,\n} from \"@/types/constants\";\nimport type { AbortOptions, AwaitGenerator } from \"interface-store\";\n\nfunction isBrowser(): boolean {\n return (\n typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\"\n );\n}\n\nasync function getDefaultDriver(base?: string) {\n // Use driverFactory override if set (typically by tests to inject in-memory driver)\n if (driverFactory) {\n return await driverFactory();\n }\n\n if (isBrowser()) {\n return (await import(\"unstorage/drivers/indexedb\")).default({\n base: base ?? DEFAULT_BLOCKSTORE_BASE,\n });\n } else {\n return (await import(\"unstorage/drivers/fs-lite\")).default({\n base: base ?? DEFAULT_BLOCKSTORE_FS_BASE,\n });\n }\n}\n\nexport function createBlockstore(\n options?: UnstorageBlockstoreOptions,\n): new (options?: UnstorageBlockstoreOptions) => InstanceType<\n ReturnType<typeof createUnstorageBlockstore>\n> {\n const BlockstoreClass = createUnstorageBlockstore(getDefaultDriver);\n return class extends BlockstoreClass {\n constructor(instanceOptions?: UnstorageBlockstoreOptions) {\n super({ ...options, ...instanceOptions });\n }\n };\n}\n\nexport function createDatastore(\n options?: UnstorageBlockstoreOptions,\n): new (options?: UnstorageBlockstoreOptions) => InstanceType<\n ReturnType<typeof createUnstorageDatastore>\n> {\n const DatastoreClass = createUnstorageDatastore(getDefaultDriver);\n return class extends DatastoreClass {\n constructor(instanceOptions?: UnstorageBlockstoreOptions) {\n super({ ...options, ...instanceOptions });\n }\n };\n}\n\nexport { setDriverFactory };\nexport type { UnstorageBlockstoreOptions } from \"./unstorage-base\";\n"],"mappings":";;;;AAaA,SAAS,YAAqB;AAC5B,QACE,OAAO,WAAW,eAAe,OAAO,OAAO,iBAAiB;;AAIpE,eAAe,iBAAiB,MAAe;AAE7C,KAAI,cACF,QAAO,MAAM,eAAe;AAG9B,KAAI,WAAW,CACb,SAAQ,MAAM,OAAO,+BAA+B,QAAQ,EAC1D,MAAM,mBACP,CAAC;KAEF,SAAQ,MAAM,OAAO,8BAA8B,QAAQ,EACzD,MAAM,4BACP,CAAC;;AAIN,SAAgB,iBACd,SAGA;CACA,MAAM,kBAAkB,0BAA0B,iBAAiB;AACnE,QAAO,cAAc,gBAAgB;EACnC,YAAY,iBAA8C;AACxD,SAAM;IAAE,GAAG;IAAS,GAAG;IAAiB,CAAC;;;;AAK/C,SAAgB,gBACd,SAGA;CACA,MAAM,iBAAiB,yBAAyB,iBAAiB;AACjE,QAAO,cAAc,eAAe;EAClC,YAAY,iBAA8C;AACxD,SAAM;IAAE,GAAG;IAAS,GAAG;IAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base64.js","names":[],"sources":["../../../src/encoder/base64.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * Base64 encoder - converts base64 strings to File objects.\n */\nexport class Base64Encoder implements Encoder<string> {\n async encode(\n base64String: string,\n options?: UploadOptions,\n ): Promise<EncoderResult> {\n try {\n const binaryString = atob(base64String);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n const blob = new Blob([bytes], { type: \"application/octet-stream\" });\n const filename = options?.name || \"file.bin\";\n const file = new File([blob], filename, {\n type: \"application/octet-stream\",\n });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new EncoderError(\n `Base64 encoding failed: ${error.message}`,\n \"INVALID_BASE64\",\n error,\n );\n }\n throw new EncoderError(\n \"Base64 encoding failed: unknown error\",\n \"INVALID_BASE64\",\n );\n }\n }\n}\n\n/**\n * Encode a base64 string to a File object.\n */\nexport async function base64ToFile(\n base64String: string,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new Base64Encoder();\n return encoder.encode(base64String, options);\n}\n"],"mappings":";;;;;;AAMA,IAAa,gBAAb,MAAsD;CACpD,MAAM,OACJ,cACA,SACwB;AACxB,MAAI;GACF,MAAM,eAAe,KAAK,aAAa;GACvC,MAAM,QAAQ,IAAI,WAAW,aAAa,OAAO;AACjD,QAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,IACvC,OAAM,KAAK,aAAa,WAAW,EAAE;GAEvC,MAAM,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,4BAA4B,CAAC;GACpE,MAAM,WAAW,SAAS,QAAQ;AAKlC,UAAO;IACL,
|
|
1
|
+
{"version":3,"file":"base64.js","names":[],"sources":["../../../src/encoder/base64.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * Base64 encoder - converts base64 strings to File objects.\n */\nexport class Base64Encoder implements Encoder<string> {\n async encode(\n base64String: string,\n options?: UploadOptions,\n ): Promise<EncoderResult> {\n try {\n const binaryString = atob(base64String);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n const blob = new Blob([bytes], { type: \"application/octet-stream\" });\n const filename = options?.name || \"file.bin\";\n const file = new File([blob], filename, {\n type: \"application/octet-stream\",\n });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new EncoderError(\n `Base64 encoding failed: ${error.message}`,\n \"INVALID_BASE64\",\n error,\n );\n }\n throw new EncoderError(\n \"Base64 encoding failed: unknown error\",\n \"INVALID_BASE64\",\n );\n }\n }\n}\n\n/**\n * Encode a base64 string to a File object.\n */\nexport async function base64ToFile(\n base64String: string,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new Base64Encoder();\n return encoder.encode(base64String, options);\n}\n"],"mappings":";;;;;;AAMA,IAAa,gBAAb,MAAsD;CACpD,MAAM,OACJ,cACA,SACwB;AACxB,MAAI;GACF,MAAM,eAAe,KAAK,aAAa;GACvC,MAAM,QAAQ,IAAI,WAAW,aAAa,OAAO;AACjD,QAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,IACvC,OAAM,KAAK,aAAa,WAAW,EAAE;GAEvC,MAAM,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,4BAA4B,CAAC;GACpE,MAAM,WAAW,SAAS,QAAQ;AAKlC,UAAO;IACL,UALe,KAAK,CAAC,KAAK,EAAE,UAAU,EACtC,MAAM,4BACP,CAGK;IACJ,SAAS;KACP,MAAM,SAAS;KACf,WAAW,SAAS;KACrB;IACF;WACM,OAAO;AACd,OAAI,iBAAiB,MACnB,OAAM,IAAI,aACR,2BAA2B,MAAM,WACjC,kBACA,MACD;AAEH,SAAM,IAAI,aACR,yCACA,iBACD;;;;;;;AAQP,eAAsB,aACpB,cACA,SACwB;AAExB,QAAO,IADa,eACN,CAAC,OAAO,cAAc,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"row-formatter.js","names":[],"sources":["../../../../src/encoder/csv/row-formatter.ts"],"sourcesContent":["import type {\n CsvFormatterOptions,\n RowTransform,\n RowTransformCallback,\n} from \"./csv-options\";\nimport { FieldFormatter } from \"./field-formatter\";\n\n/**\n * Handles formatting of CSV rows including headers and column extraction.\n *\n * This implementation is derived from @fast-csv/format (https://github.com/C2FO/fast-csv)\n * Copyright (c) 2011 C2FO Labs, LLC\n * Licensed under the MIT License\n */\nexport class RowFormatter {\n private options: CsvFormatterOptions;\n private fieldFormatter: FieldFormatter;\n private shouldWriteHeaders: boolean;\n private rowTransform: RowTransformCallback | null = null;\n private headers: string[] | null = null;\n private hasWrittenHeaders = false;\n private rowCount = 0;\n\n constructor(options: CsvFormatterOptions) {\n this.options = options;\n this.fieldFormatter = new FieldFormatter(options);\n this.headers = Array.isArray(options.headers) ? options.headers : null;\n this.shouldWriteHeaders =\n options.writeHeaders ??\n (Array.isArray(options.headers) || options.headers === true);\n\n if (this.headers !== null) {\n this.fieldFormatter.headers = this.headers;\n }\n\n if (options.transform) {\n this.rowTransform = this.createTransform(options.transform);\n }\n }\n\n /**\n * Create a transform function that handles both sync and async transforms.\n */\n private createTransform(transformFn: RowTransform): RowTransformCallback {\n // Check if it's a sync transform (arity 1)\n if (transformFn.length === 1) {\n return (row: unknown, cb: RowTransformCallback) => {\n try {\n const transformedRow = (transformFn as (row: unknown) => unknown)(\n row,\n );\n cb(null, transformedRow);\n } catch (e) {\n cb(e instanceof Error ? e : new Error(String(e)));\n }\n };\n }\n\n return transformFn as RowTransformCallback;\n }\n\n /**\n * Check if the transform is synchronous (arity 1).\n */\n private isSyncTransform(): boolean {\n if (!this.options.transform) {\n return true;\n }\n return this.options.transform.length === 1;\n }\n\n /**\n * Format a single row.\n */\n format(row: unknown): string[] {\n let transformedRow: unknown;\n\n // Apply transform if present\n if (this.rowTransform) {\n transformedRow = this.applyTransformSync(row);\n } else {\n transformedRow = row;\n }\n\n if (!transformedRow) {\n return [];\n }\n\n const rows: string[] = [];\n\n // Check headers\n const { shouldFormatColumns, headers } = this.checkHeaders(transformedRow);\n\n // Write headers if needed\n if (this.shouldWriteHeaders && headers && !this.hasWrittenHeaders) {\n rows.push(this.formatColumns(headers, true));\n this.hasWrittenHeaders = true;\n }\n\n // Format data row\n if (shouldFormatColumns) {\n const columns = this.gatherColumns(transformedRow);\n rows.push(this.formatColumns(columns, false));\n }\n\n return rows;\n }\n\n /**\n * Apply transform synchronously.\n * Note: This only supports sync transforms. Async transforms are not supported\n * in the synchronous format() method.\n */\n private applyTransformSync(row: unknown): unknown {\n if (!this.options.transform) {\n return row;\n }\n\n // Only sync transforms (arity 1) are supported\n if (this.isSyncTransform()) {\n try {\n return (this.options.transform as (row: unknown) => unknown)(row);\n } catch (e) {\n throw e instanceof Error ? e : new Error(String(e));\n }\n }\n\n throw new Error(\n \"Async transforms are not supported in synchronous CSV formatting\",\n );\n }\n\n /**\n * Finish formatting and return any trailing content.\n */\n finish(): string[] {\n const rows: string[] = [];\n\n // Write headers if alwaysWriteHeaders is true and no rows were written\n if (this.options.alwaysWriteHeaders && this.rowCount === 0) {\n if (!this.headers) {\n throw new Error(\n \"`alwaysWriteHeaders` option is set to true but `headers` option not provided.\",\n );\n }\n rows.push(this.formatColumns(this.headers, true));\n }\n\n // Add end row delimiter if configured\n if (this.options.includeEndRowDelimiter) {\n rows.push(this.options.rowDelimiter || \"\\n\");\n }\n\n return rows;\n }\n\n /**\n * Check if headers need to be written.\n */\n private checkHeaders(row: unknown): {\n shouldFormatColumns: boolean;\n headers: string[] | null;\n } {\n if (this.headers) {\n return { shouldFormatColumns: true, headers: this.headers };\n }\n\n const headers = this.gatherHeaders(row);\n this.headers = headers;\n this.fieldFormatter.headers = headers;\n\n if (!this.shouldWriteHeaders) {\n return { shouldFormatColumns: true, headers: null };\n }\n\n // If the row is equal to headers, don't format (it's the header row itself)\n if (Array.isArray(row) && headers.every((header, i) => header === row[i])) {\n return { shouldFormatColumns: false, headers };\n }\n\n return { shouldFormatColumns: true, headers };\n }\n\n /**\n * Extract headers from a row.\n */\n private gatherHeaders(row: unknown): string[] {\n if (this.isRowHashArray(row)) {\n // Multi-dimensional array with item 0 being the header\n return (row as unknown[][]).map((it) => String(it[0]));\n }\n\n if (Array.isArray(row)) {\n return row.map(String);\n }\n\n return Object.keys(row as object);\n }\n\n /**\n * Check if row is a hash array (multi-dimensional array with [key, value] pairs).\n */\n private isRowHashArray(row: unknown): boolean {\n if (!Array.isArray(row)) {\n return false;\n }\n return Array.isArray(row[0]) && row[0].length === 2;\n }\n\n /**\n * Extract column values from a row.\n */\n private gatherColumns(row: unknown): unknown[] {\n if (this.headers === null) {\n throw new Error(\"Headers is currently null\");\n }\n\n if (!Array.isArray(row)) {\n // Object: use headers to get values\n return this.headers.map(\n (header) => (row as Record<string, unknown>)[header],\n );\n }\n\n if (this.isRowHashArray(row)) {\n // Hash array: extract values\n return this.headers.map((header, i) => {\n const col = (row as unknown[][])[i];\n return col ? col[1] : \"\";\n });\n }\n\n // Regular array\n if (!this.shouldWriteHeaders) {\n // If headers weren't written, return the row as-is\n return row;\n }\n\n // Map by header index\n return this.headers.map((_, i) => row[i]);\n }\n\n /**\n * Format columns into a CSV row string.\n */\n private formatColumns(columns: unknown[], isHeadersRow: boolean): string {\n const formattedCols = columns\n .map((field, i) => this.fieldFormatter.format(field, i, isHeadersRow))\n .join(this.options.delimiter || \",\");\n\n const { rowCount } = this;\n this.rowCount += 1;\n\n // Add row delimiter before all rows except the first\n if (rowCount > 0) {\n return [this.options.rowDelimiter || \"\\n\", formattedCols].join(\"\");\n }\n\n return formattedCols;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"row-formatter.js","names":[],"sources":["../../../../src/encoder/csv/row-formatter.ts"],"sourcesContent":["import type {\n CsvFormatterOptions,\n RowTransform,\n RowTransformCallback,\n} from \"./csv-options\";\nimport { FieldFormatter } from \"./field-formatter\";\n\n/**\n * Handles formatting of CSV rows including headers and column extraction.\n *\n * This implementation is derived from @fast-csv/format (https://github.com/C2FO/fast-csv)\n * Copyright (c) 2011 C2FO Labs, LLC\n * Licensed under the MIT License\n */\nexport class RowFormatter {\n private options: CsvFormatterOptions;\n private fieldFormatter: FieldFormatter;\n private shouldWriteHeaders: boolean;\n private rowTransform: RowTransformCallback | null = null;\n private headers: string[] | null = null;\n private hasWrittenHeaders = false;\n private rowCount = 0;\n\n constructor(options: CsvFormatterOptions) {\n this.options = options;\n this.fieldFormatter = new FieldFormatter(options);\n this.headers = Array.isArray(options.headers) ? options.headers : null;\n this.shouldWriteHeaders =\n options.writeHeaders ??\n (Array.isArray(options.headers) || options.headers === true);\n\n if (this.headers !== null) {\n this.fieldFormatter.headers = this.headers;\n }\n\n if (options.transform) {\n this.rowTransform = this.createTransform(options.transform);\n }\n }\n\n /**\n * Create a transform function that handles both sync and async transforms.\n */\n private createTransform(transformFn: RowTransform): RowTransformCallback {\n // Check if it's a sync transform (arity 1)\n if (transformFn.length === 1) {\n return (row: unknown, cb: RowTransformCallback) => {\n try {\n const transformedRow = (transformFn as (row: unknown) => unknown)(\n row,\n );\n cb(null, transformedRow);\n } catch (e) {\n cb(e instanceof Error ? e : new Error(String(e)));\n }\n };\n }\n\n return transformFn as RowTransformCallback;\n }\n\n /**\n * Check if the transform is synchronous (arity 1).\n */\n private isSyncTransform(): boolean {\n if (!this.options.transform) {\n return true;\n }\n return this.options.transform.length === 1;\n }\n\n /**\n * Format a single row.\n */\n format(row: unknown): string[] {\n let transformedRow: unknown;\n\n // Apply transform if present\n if (this.rowTransform) {\n transformedRow = this.applyTransformSync(row);\n } else {\n transformedRow = row;\n }\n\n if (!transformedRow) {\n return [];\n }\n\n const rows: string[] = [];\n\n // Check headers\n const { shouldFormatColumns, headers } = this.checkHeaders(transformedRow);\n\n // Write headers if needed\n if (this.shouldWriteHeaders && headers && !this.hasWrittenHeaders) {\n rows.push(this.formatColumns(headers, true));\n this.hasWrittenHeaders = true;\n }\n\n // Format data row\n if (shouldFormatColumns) {\n const columns = this.gatherColumns(transformedRow);\n rows.push(this.formatColumns(columns, false));\n }\n\n return rows;\n }\n\n /**\n * Apply transform synchronously.\n * Note: This only supports sync transforms. Async transforms are not supported\n * in the synchronous format() method.\n */\n private applyTransformSync(row: unknown): unknown {\n if (!this.options.transform) {\n return row;\n }\n\n // Only sync transforms (arity 1) are supported\n if (this.isSyncTransform()) {\n try {\n return (this.options.transform as (row: unknown) => unknown)(row);\n } catch (e) {\n throw e instanceof Error ? e : new Error(String(e));\n }\n }\n\n throw new Error(\n \"Async transforms are not supported in synchronous CSV formatting\",\n );\n }\n\n /**\n * Finish formatting and return any trailing content.\n */\n finish(): string[] {\n const rows: string[] = [];\n\n // Write headers if alwaysWriteHeaders is true and no rows were written\n if (this.options.alwaysWriteHeaders && this.rowCount === 0) {\n if (!this.headers) {\n throw new Error(\n \"`alwaysWriteHeaders` option is set to true but `headers` option not provided.\",\n );\n }\n rows.push(this.formatColumns(this.headers, true));\n }\n\n // Add end row delimiter if configured\n if (this.options.includeEndRowDelimiter) {\n rows.push(this.options.rowDelimiter || \"\\n\");\n }\n\n return rows;\n }\n\n /**\n * Check if headers need to be written.\n */\n private checkHeaders(row: unknown): {\n shouldFormatColumns: boolean;\n headers: string[] | null;\n } {\n if (this.headers) {\n return { shouldFormatColumns: true, headers: this.headers };\n }\n\n const headers = this.gatherHeaders(row);\n this.headers = headers;\n this.fieldFormatter.headers = headers;\n\n if (!this.shouldWriteHeaders) {\n return { shouldFormatColumns: true, headers: null };\n }\n\n // If the row is equal to headers, don't format (it's the header row itself)\n if (Array.isArray(row) && headers.every((header, i) => header === row[i])) {\n return { shouldFormatColumns: false, headers };\n }\n\n return { shouldFormatColumns: true, headers };\n }\n\n /**\n * Extract headers from a row.\n */\n private gatherHeaders(row: unknown): string[] {\n if (this.isRowHashArray(row)) {\n // Multi-dimensional array with item 0 being the header\n return (row as unknown[][]).map((it) => String(it[0]));\n }\n\n if (Array.isArray(row)) {\n return row.map(String);\n }\n\n return Object.keys(row as object);\n }\n\n /**\n * Check if row is a hash array (multi-dimensional array with [key, value] pairs).\n */\n private isRowHashArray(row: unknown): boolean {\n if (!Array.isArray(row)) {\n return false;\n }\n return Array.isArray(row[0]) && row[0].length === 2;\n }\n\n /**\n * Extract column values from a row.\n */\n private gatherColumns(row: unknown): unknown[] {\n if (this.headers === null) {\n throw new Error(\"Headers is currently null\");\n }\n\n if (!Array.isArray(row)) {\n // Object: use headers to get values\n return this.headers.map(\n (header) => (row as Record<string, unknown>)[header],\n );\n }\n\n if (this.isRowHashArray(row)) {\n // Hash array: extract values\n return this.headers.map((header, i) => {\n const col = (row as unknown[][])[i];\n return col ? col[1] : \"\";\n });\n }\n\n // Regular array\n if (!this.shouldWriteHeaders) {\n // If headers weren't written, return the row as-is\n return row;\n }\n\n // Map by header index\n return this.headers.map((_, i) => row[i]);\n }\n\n /**\n * Format columns into a CSV row string.\n */\n private formatColumns(columns: unknown[], isHeadersRow: boolean): string {\n const formattedCols = columns\n .map((field, i) => this.fieldFormatter.format(field, i, isHeadersRow))\n .join(this.options.delimiter || \",\");\n\n const { rowCount } = this;\n this.rowCount += 1;\n\n // Add row delimiter before all rows except the first\n if (rowCount > 0) {\n return [this.options.rowDelimiter || \"\\n\", formattedCols].join(\"\");\n }\n\n return formattedCols;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csv.js","names":["#arrayToCsv"],"sources":["../../../src/encoder/csv.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\nimport {\n createCsvFormatter,\n type CsvFormatterOptions,\n} from \"./csv/csv-formatter\";\n\n/**\n * CSV encoder - converts CSV strings, arrays of objects, or arrays of arrays to File objects.\n * Uses a simplified CSV formatter without streaming support.\n *\n * This implementation is derived from @fast-csv/format (https://github.com/C2FO/fast-csv)\n * Copyright (c) 2011 C2FO Labs, LLC\n * Licensed under the MIT License\n */\n\n/**\n * Extended upload options for CSV encoder.\n * Extends base UploadOptions with CSV formatting options.\n */\nexport interface CsvUploadOptions extends UploadOptions {\n /**\n * CSV formatting options.\n */\n csv?: CsvFormatterOptions;\n}\n\n/**\n * CSV encoder - converts CSV strings, arrays of objects, or arrays of arrays to File objects.\n * Uses a simplified CSV formatter without streaming support.\n */\nexport class CsvEncoder implements Encoder<string | object[] | any[][]> {\n async encode(\n input: string | object[] | any[][],\n options?: CsvUploadOptions,\n ): Promise<EncoderResult> {\n try {\n let csvContent: string;\n\n if (typeof input === \"string\") {\n // Raw CSV string - use as-is\n csvContent = input;\n } else if (Array.isArray(input)) {\n // Convert array to CSV using our formatter\n csvContent = this.#arrayToCsv(input, options?.csv);\n } else {\n throw new EncoderError(\n \"Invalid CSV input: must be string or array\",\n \"INVALID_CSV\",\n );\n }\n\n const blob = new Blob([csvContent], { type: \"text/csv\" });\n const file = new File([blob], options?.name || \"data.csv\", {\n type: \"text/csv\",\n });\n\n return {\n file,\n options: options || {},\n };\n } catch (error) {\n if (error instanceof EncoderError) {\n throw error;\n }\n if (error instanceof Error) {\n throw new EncoderError(\n `CSV encoding failed: ${error.message}`,\n \"INVALID_CSV\",\n error,\n );\n }\n throw new EncoderError(\n \"CSV encoding failed: unknown error\",\n \"INVALID_CSV\",\n );\n }\n }\n\n #arrayToCsv(\n data: any[] | object[][],\n csvOptions?: CsvFormatterOptions,\n ): string {\n const formatter = createCsvFormatter({\n headers: true,\n ...csvOptions,\n });\n\n return formatter.format(data);\n }\n}\n\n/**\n * Encode CSV data to a File object.\n */\nexport async function csvToFile(\n data: string | object[] | any[][],\n options?: CsvUploadOptions,\n): Promise<EncoderResult> {\n const encoder = new CsvEncoder();\n return encoder.encode(data, options);\n}\n"],"mappings":";;;;;;;;AA+BA,IAAa,aAAb,MAAwE;CACtE,MAAM,OACJ,OACA,SACwB;AACxB,MAAI;GACF,IAAI;AAEJ,OAAI,OAAO,UAAU,SAEnB,cAAa;YACJ,MAAM,QAAQ,MAAM,CAE7B,cAAa,MAAKA,WAAY,OAAO,SAAS,IAAI;OAElD,OAAM,IAAI,aACR,8CACA,cACD;GAGH,MAAM,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,MAAM,YAAY,CAAC;AAKzD,UAAO;IACL,
|
|
1
|
+
{"version":3,"file":"csv.js","names":["#arrayToCsv"],"sources":["../../../src/encoder/csv.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\nimport {\n createCsvFormatter,\n type CsvFormatterOptions,\n} from \"./csv/csv-formatter\";\n\n/**\n * CSV encoder - converts CSV strings, arrays of objects, or arrays of arrays to File objects.\n * Uses a simplified CSV formatter without streaming support.\n *\n * This implementation is derived from @fast-csv/format (https://github.com/C2FO/fast-csv)\n * Copyright (c) 2011 C2FO Labs, LLC\n * Licensed under the MIT License\n */\n\n/**\n * Extended upload options for CSV encoder.\n * Extends base UploadOptions with CSV formatting options.\n */\nexport interface CsvUploadOptions extends UploadOptions {\n /**\n * CSV formatting options.\n */\n csv?: CsvFormatterOptions;\n}\n\n/**\n * CSV encoder - converts CSV strings, arrays of objects, or arrays of arrays to File objects.\n * Uses a simplified CSV formatter without streaming support.\n */\nexport class CsvEncoder implements Encoder<string | object[] | any[][]> {\n async encode(\n input: string | object[] | any[][],\n options?: CsvUploadOptions,\n ): Promise<EncoderResult> {\n try {\n let csvContent: string;\n\n if (typeof input === \"string\") {\n // Raw CSV string - use as-is\n csvContent = input;\n } else if (Array.isArray(input)) {\n // Convert array to CSV using our formatter\n csvContent = this.#arrayToCsv(input, options?.csv);\n } else {\n throw new EncoderError(\n \"Invalid CSV input: must be string or array\",\n \"INVALID_CSV\",\n );\n }\n\n const blob = new Blob([csvContent], { type: \"text/csv\" });\n const file = new File([blob], options?.name || \"data.csv\", {\n type: \"text/csv\",\n });\n\n return {\n file,\n options: options || {},\n };\n } catch (error) {\n if (error instanceof EncoderError) {\n throw error;\n }\n if (error instanceof Error) {\n throw new EncoderError(\n `CSV encoding failed: ${error.message}`,\n \"INVALID_CSV\",\n error,\n );\n }\n throw new EncoderError(\n \"CSV encoding failed: unknown error\",\n \"INVALID_CSV\",\n );\n }\n }\n\n #arrayToCsv(\n data: any[] | object[][],\n csvOptions?: CsvFormatterOptions,\n ): string {\n const formatter = createCsvFormatter({\n headers: true,\n ...csvOptions,\n });\n\n return formatter.format(data);\n }\n}\n\n/**\n * Encode CSV data to a File object.\n */\nexport async function csvToFile(\n data: string | object[] | any[][],\n options?: CsvUploadOptions,\n): Promise<EncoderResult> {\n const encoder = new CsvEncoder();\n return encoder.encode(data, options);\n}\n"],"mappings":";;;;;;;;AA+BA,IAAa,aAAb,MAAwE;CACtE,MAAM,OACJ,OACA,SACwB;AACxB,MAAI;GACF,IAAI;AAEJ,OAAI,OAAO,UAAU,SAEnB,cAAa;YACJ,MAAM,QAAQ,MAAM,CAE7B,cAAa,MAAKA,WAAY,OAAO,SAAS,IAAI;OAElD,OAAM,IAAI,aACR,8CACA,cACD;GAGH,MAAM,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,MAAM,YAAY,CAAC;AAKzD,UAAO;IACL,UALe,KAAK,CAAC,KAAK,EAAE,SAAS,QAAQ,YAAY,EACzD,MAAM,YACP,CAGK;IACJ,SAAS,WAAW,EAAE;IACvB;WACM,OAAO;AACd,OAAI,iBAAiB,aACnB,OAAM;AAER,OAAI,iBAAiB,MACnB,OAAM,IAAI,aACR,wBAAwB,MAAM,WAC9B,eACA,MACD;AAEH,SAAM,IAAI,aACR,sCACA,cACD;;;CAIL,YACE,MACA,YACQ;AAMR,SALkB,mBAAmB;GACnC,SAAS;GACT,GAAG;GACJ,CAEe,CAAC,OAAO,KAAK;;;;;;AAOjC,eAAsB,UACpB,MACA,SACwB;AAExB,QAAO,IADa,YACN,CAAC,OAAO,MAAM,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.js","names":[],"sources":["../../../src/encoder/json.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * JSON encoder - converts JSON objects to File objects.\n */\nexport class JsonEncoder implements Encoder<object> {\n async encode(data: object, options?: UploadOptions): Promise<EncoderResult> {\n try {\n const json = JSON.stringify(data, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n const filename = options?.name || \"data.json\";\n const file = new File([blob], filename, { type: \"application/json\" });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new EncoderError(\n `JSON encoding failed: ${error.message}`,\n \"INVALID_JSON\",\n error,\n );\n }\n throw new EncoderError(\n \"JSON encoding failed: unknown error\",\n \"INVALID_JSON\",\n );\n }\n }\n}\n\n/**\n * Encode a JSON object to a File object.\n */\nexport async function jsonToFile(\n data: object,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new JsonEncoder();\n return encoder.encode(data, options);\n}\n"],"mappings":";;;;;;AAMA,IAAa,cAAb,MAAoD;CAClD,MAAM,OAAO,MAAc,SAAiD;AAC1E,MAAI;GACF,MAAM,OAAO,KAAK,UAAU,MAAM,MAAM,EAAE;GAC1C,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,oBAAoB,CAAC;GAC3D,MAAM,WAAW,SAAS,QAAQ;AAGlC,UAAO;IACL,
|
|
1
|
+
{"version":3,"file":"json.js","names":[],"sources":["../../../src/encoder/json.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * JSON encoder - converts JSON objects to File objects.\n */\nexport class JsonEncoder implements Encoder<object> {\n async encode(data: object, options?: UploadOptions): Promise<EncoderResult> {\n try {\n const json = JSON.stringify(data, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n const filename = options?.name || \"data.json\";\n const file = new File([blob], filename, { type: \"application/json\" });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new EncoderError(\n `JSON encoding failed: ${error.message}`,\n \"INVALID_JSON\",\n error,\n );\n }\n throw new EncoderError(\n \"JSON encoding failed: unknown error\",\n \"INVALID_JSON\",\n );\n }\n }\n}\n\n/**\n * Encode a JSON object to a File object.\n */\nexport async function jsonToFile(\n data: object,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new JsonEncoder();\n return encoder.encode(data, options);\n}\n"],"mappings":";;;;;;AAMA,IAAa,cAAb,MAAoD;CAClD,MAAM,OAAO,MAAc,SAAiD;AAC1E,MAAI;GACF,MAAM,OAAO,KAAK,UAAU,MAAM,MAAM,EAAE;GAC1C,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,oBAAoB,CAAC;GAC3D,MAAM,WAAW,SAAS,QAAQ;AAGlC,UAAO;IACL,UAHe,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAG9D;IACJ,SAAS;KACP,MAAM,SAAS;KACf,WAAW,SAAS;KACrB;IACF;WACM,OAAO;AACd,OAAI,iBAAiB,MACnB,OAAM,IAAI,aACR,yBAAyB,MAAM,WAC/B,gBACA,MACD;AAEH,SAAM,IAAI,aACR,uCACA,eACD;;;;;;;AAQP,eAAsB,WACpB,MACA,SACwB;AAExB,QAAO,IADa,aACN,CAAC,OAAO,MAAM,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../../../src/encoder/text.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * Text encoder - converts text strings to File objects.\n */\nexport class TextEncoder implements Encoder<string> {\n async encode(data: string, options?: UploadOptions): Promise<EncoderResult> {\n try {\n const blob = new Blob([data], { type: \"text/plain\" });\n const filename = options?.name || \"data.txt\";\n const file = new File([blob], filename, { type: \"text/plain\" });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new EncoderError(\n `Text encoding failed: ${error.message}`,\n \"INVALID_TEXT\",\n error,\n );\n }\n throw new EncoderError(\n \"Text encoding failed: unknown error\",\n \"INVALID_TEXT\",\n );\n }\n }\n}\n\n/**\n * Encode a text string to a File object.\n */\nexport async function textToFile(\n data: string,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new TextEncoder();\n return encoder.encode(data, options);\n}\n"],"mappings":";;;;;;AAMA,IAAa,cAAb,MAAoD;CAClD,MAAM,OAAO,MAAc,SAAiD;AAC1E,MAAI;GACF,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;GACrD,MAAM,WAAW,SAAS,QAAQ;AAGlC,UAAO;IACL,
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../../../src/encoder/text.ts"],"sourcesContent":["import type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * Text encoder - converts text strings to File objects.\n */\nexport class TextEncoder implements Encoder<string> {\n async encode(data: string, options?: UploadOptions): Promise<EncoderResult> {\n try {\n const blob = new Blob([data], { type: \"text/plain\" });\n const filename = options?.name || \"data.txt\";\n const file = new File([blob], filename, { type: \"text/plain\" });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new EncoderError(\n `Text encoding failed: ${error.message}`,\n \"INVALID_TEXT\",\n error,\n );\n }\n throw new EncoderError(\n \"Text encoding failed: unknown error\",\n \"INVALID_TEXT\",\n );\n }\n }\n}\n\n/**\n * Encode a text string to a File object.\n */\nexport async function textToFile(\n data: string,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new TextEncoder();\n return encoder.encode(data, options);\n}\n"],"mappings":";;;;;;AAMA,IAAa,cAAb,MAAoD;CAClD,MAAM,OAAO,MAAc,SAAiD;AAC1E,MAAI;GACF,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;GACrD,MAAM,WAAW,SAAS,QAAQ;AAGlC,UAAO;IACL,UAHe,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAGxD;IACJ,SAAS;KACP,MAAM,SAAS;KACf,WAAW,SAAS;KACrB;IACF;WACM,OAAO;AACd,OAAI,iBAAiB,MACnB,OAAM,IAAI,aACR,yBAAyB,MAAM,WAC/B,gBACA,MACD;AAEH,SAAM,IAAI,aACR,uCACA,eACD;;;;;;;AAQP,eAAsB,WACpB,MACA,SACwB;AAExB,QAAO,IADa,aACN,CAAC,OAAO,MAAM,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","names":[],"sources":["../../../src/encoder/url.ts"],"sourcesContent":["import ky, { isHTTPError, isTimeoutError } from \"ky\";\nimport type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * URL encoder - fetches content from URLs and converts to File objects.\n */\nexport class UrlEncoder implements Encoder<string> {\n async encode(\n urlString: string,\n options?: UploadOptions,\n ): Promise<EncoderResult> {\n try {\n const blob = await ky(urlString, { fetch: options?.fetch }).blob();\n const filename =\n options?.name || new URL(urlString).pathname.split(\"/\").pop() || \"file\";\n const file = new File([blob], filename, { type: blob.type });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (isHTTPError(error) || isTimeoutError(error)) {\n throw new EncoderError(\n `URL encoding failed: ${error.message}`,\n \"NETWORK_ERROR\",\n error,\n );\n }\n\n if (error instanceof Error) {\n throw new EncoderError(\n `URL encoding failed: ${error.message}`,\n \"NETWORK_ERROR\",\n error,\n );\n }\n\n throw new EncoderError(\"URL encoding failed: unknown error\", \"UNKNOWN\");\n }\n }\n}\n\n/**\n * Encode a URL to a File object by fetching the content.\n */\nexport async function urlToFile(\n urlString: string,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new UrlEncoder();\n return encoder.encode(urlString, options);\n}\n"],"mappings":";;;;;;;AAOA,IAAa,aAAb,MAAmD;CACjD,MAAM,OACJ,WACA,SACwB;AACxB,MAAI;GACF,MAAM,OAAO,MAAM,GAAG,WAAW,EAAE,OAAO,SAAS,OAAO,CAAC,CAAC,MAAM;GAClE,MAAM,WACJ,SAAS,QAAQ,IAAI,IAAI,UAAU,CAAC,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI;AAGnE,UAAO;IACL,
|
|
1
|
+
{"version":3,"file":"url.js","names":[],"sources":["../../../src/encoder/url.ts"],"sourcesContent":["import ky, { isHTTPError, isTimeoutError } from \"ky\";\nimport type { Encoder, EncoderResult, UploadOptions } from \"./types\";\nimport { EncoderError } from \"./error\";\n\n/**\n * URL encoder - fetches content from URLs and converts to File objects.\n */\nexport class UrlEncoder implements Encoder<string> {\n async encode(\n urlString: string,\n options?: UploadOptions,\n ): Promise<EncoderResult> {\n try {\n const blob = await ky(urlString, { fetch: options?.fetch }).blob();\n const filename =\n options?.name || new URL(urlString).pathname.split(\"/\").pop() || \"file\";\n const file = new File([blob], filename, { type: blob.type });\n\n return {\n file,\n options: {\n name: options?.name,\n keyvalues: options?.keyvalues,\n },\n };\n } catch (error) {\n if (isHTTPError(error) || isTimeoutError(error)) {\n throw new EncoderError(\n `URL encoding failed: ${error.message}`,\n \"NETWORK_ERROR\",\n error,\n );\n }\n\n if (error instanceof Error) {\n throw new EncoderError(\n `URL encoding failed: ${error.message}`,\n \"NETWORK_ERROR\",\n error,\n );\n }\n\n throw new EncoderError(\"URL encoding failed: unknown error\", \"UNKNOWN\");\n }\n }\n}\n\n/**\n * Encode a URL to a File object by fetching the content.\n */\nexport async function urlToFile(\n urlString: string,\n options?: UploadOptions,\n): Promise<EncoderResult> {\n const encoder = new UrlEncoder();\n return encoder.encode(urlString, options);\n}\n"],"mappings":";;;;;;;AAOA,IAAa,aAAb,MAAmD;CACjD,MAAM,OACJ,WACA,SACwB;AACxB,MAAI;GACF,MAAM,OAAO,MAAM,GAAG,WAAW,EAAE,OAAO,SAAS,OAAO,CAAC,CAAC,MAAM;GAClE,MAAM,WACJ,SAAS,QAAQ,IAAI,IAAI,UAAU,CAAC,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI;AAGnE,UAAO;IACL,UAHe,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,MAAM,CAGrD;IACJ,SAAS;KACP,MAAM,SAAS;KACf,WAAW,SAAS;KACrB;IACF;WACM,OAAO;AACd,OAAI,YAAY,MAAM,IAAI,eAAe,MAAM,CAC7C,OAAM,IAAI,aACR,wBAAwB,MAAM,WAC9B,iBACA,MACD;AAGH,OAAI,iBAAiB,MACnB,OAAM,IAAI,aACR,wBAAwB,MAAM,WAC9B,iBACA,MACD;AAGH,SAAM,IAAI,aAAa,sCAAsC,UAAU;;;;;;;AAQ7E,eAAsB,UACpB,WACA,SACwB;AAExB,QAAO,IADa,YACN,CAAC,OAAO,WAAW,QAAQ"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { PinnerConfig } from "./config.js";
|
|
2
|
+
import { IpnsClient } from "./api/ipns.js";
|
|
3
|
+
import { WebsitesClient } from "./api/websites.js";
|
|
2
4
|
import { UploadInput, UploadOperation, UploadOptions, UploadProgress, UploadResult } from "./types/upload.js";
|
|
3
5
|
import { AbortOptions, RemoteAddOptions, RemoteLsOptions, RemotePin, RemotePins } from "./types/pin.js";
|
|
4
6
|
import { Pinner } from "./pinner.js";
|
|
@@ -9,10 +11,8 @@ import { isAuthenticationError, isRetryable } from "./types/type-guards.js";
|
|
|
9
11
|
import { FILE_EXTENSION_CAR, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM } from "./types/mime-types.js";
|
|
10
12
|
import { UnstorageBlockstoreOptions, setDriverFactory } from "./blockstore/unstorage-base.js";
|
|
11
13
|
import { createBlockstore, createDatastore } from "./blockstore/unstorage.js";
|
|
12
|
-
import "./blockstore/index.js";
|
|
13
14
|
import { asyncGeneratorToReadableStream, calculateStreamSize, readableStreamToAsyncIterable, streamToBlob } from "./utils/stream.js";
|
|
14
15
|
import { PinataAdapter } from "./adapters/pinata/v2/adapter-interface.js";
|
|
15
16
|
import { pinataAdapter } from "./adapters/pinata/v2/adapter.js";
|
|
16
17
|
import { PinataLegacyAdapter, pinataLegacyAdapter } from "./adapters/pinata/legacy/adapter.js";
|
|
17
|
-
|
|
18
|
-
export { type AbortOptions, AuthenticationError, type CarPreprocessOptions, type CarPreprocessResult, ConfigurationError, EmptyFileError, FILE_EXTENSION_CAR, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM, NetworkError, NotFoundError, PinError, type PinataAdapter, type PinataLegacyAdapter, Pinner, type PinnerConfig, PinnerError, RateLimitError, type RemoteAddOptions, type RemoteLsOptions, type RemotePin, type RemotePins, TimeoutError, type UnstorageBlockstoreOptions, UploadError, type UploadInput, UploadManager, type UploadOperation, type UploadOptions, type UploadProgress, type UploadResult, ValidationError, asyncGeneratorToReadableStream, calculateStreamSize, createBlockstore, createDatastore, destroyCarPreprocessor, isAuthenticationError, isCarFile, isRetryable, pinataAdapter, pinataLegacyAdapter, preprocessToCar, readableStreamToAsyncIterable, setDriverFactory, streamToBlob };
|
|
18
|
+
export { type AbortOptions, AuthenticationError, type CarPreprocessOptions, type CarPreprocessResult, ConfigurationError, EmptyFileError, FILE_EXTENSION_CAR, IpnsClient, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM, NetworkError, NotFoundError, PinError, type PinataAdapter, type PinataLegacyAdapter, Pinner, type PinnerConfig, PinnerError, RateLimitError, type RemoteAddOptions, type RemoteLsOptions, type RemotePin, type RemotePins, TimeoutError, type UnstorageBlockstoreOptions, UploadError, type UploadInput, UploadManager, type UploadOperation, type UploadOptions, type UploadProgress, type UploadResult, ValidationError, WebsitesClient, asyncGeneratorToReadableStream, calculateStreamSize, createBlockstore, createDatastore, destroyCarPreprocessor, isAuthenticationError, isCarFile, isRetryable, pinataAdapter, pinataLegacyAdapter, preprocessToCar, readableStreamToAsyncIterable, setDriverFactory, streamToBlob };
|
package/dist/esm/index.js
CHANGED
|
@@ -6,10 +6,12 @@ import "./blockstore/index.js";
|
|
|
6
6
|
import { destroyCarPreprocessor, isCarFile, preprocessToCar } from "./upload/car.js";
|
|
7
7
|
import { AuthenticationError, ConfigurationError, EmptyFileError, NetworkError, NotFoundError, PinError, PinnerError, RateLimitError, TimeoutError, UploadError, ValidationError } from "./errors/index.js";
|
|
8
8
|
import { UploadManager } from "./upload/manager.js";
|
|
9
|
+
import { IpnsClient } from "./api/ipns.js";
|
|
10
|
+
import { WebsitesClient } from "./api/websites.js";
|
|
9
11
|
import { Pinner } from "./pinner.js";
|
|
10
12
|
import { isAuthenticationError, isRetryable } from "./types/type-guards.js";
|
|
11
13
|
import { pinataAdapter } from "./adapters/pinata/v2/adapter.js";
|
|
12
14
|
import { pinataLegacyAdapter } from "./adapters/pinata/legacy/adapter.js";
|
|
13
15
|
import "./adapters/pinata/index.js";
|
|
14
16
|
|
|
15
|
-
export { AuthenticationError, ConfigurationError, EmptyFileError, FILE_EXTENSION_CAR, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM, NetworkError, NotFoundError, PinError, Pinner, PinnerError, RateLimitError, TimeoutError, UploadError, UploadManager, ValidationError, asyncGeneratorToReadableStream, calculateStreamSize, createBlockstore, createDatastore, destroyCarPreprocessor, isAuthenticationError, isCarFile, isRetryable, pinataAdapter, pinataLegacyAdapter, preprocessToCar, readableStreamToAsyncIterable, setDriverFactory, streamToBlob };
|
|
17
|
+
export { AuthenticationError, ConfigurationError, EmptyFileError, FILE_EXTENSION_CAR, IpnsClient, MIME_TYPE_CAR, MIME_TYPE_OCTET_STREAM, NetworkError, NotFoundError, PinError, Pinner, PinnerError, RateLimitError, TimeoutError, UploadError, UploadManager, ValidationError, WebsitesClient, asyncGeneratorToReadableStream, calculateStreamSize, createBlockstore, createDatastore, destroyCarPreprocessor, isAuthenticationError, isCarFile, isRetryable, pinataAdapter, pinataLegacyAdapter, preprocessToCar, readableStreamToAsyncIterable, setDriverFactory, streamToBlob };
|