@lumeweb/pinner 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +690 -28
- package/dist/cjs/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/cjs/adapters/pinata/adapter.cjs +88 -0
- package/dist/cjs/adapters/pinata/adapter.cjs.map +1 -0
- package/dist/cjs/adapters/pinata/adapter.d.cts +35 -0
- package/dist/cjs/adapters/pinata/builder.cjs +194 -0
- package/dist/cjs/adapters/pinata/builder.cjs.map +1 -0
- package/dist/cjs/adapters/pinata/index.cjs +3 -0
- package/dist/cjs/adapters/pinata/list-builder.cjs +52 -0
- package/dist/cjs/adapters/pinata/list-builder.cjs.map +1 -0
- package/dist/cjs/blockstore/index.cjs +2 -0
- package/dist/cjs/blockstore/unstorage-base.cjs +240 -0
- package/dist/cjs/blockstore/unstorage-base.cjs.map +1 -0
- package/dist/cjs/blockstore/unstorage-base.d.cts +23 -0
- package/dist/cjs/blockstore/unstorage.cjs +39 -0
- package/dist/cjs/blockstore/unstorage.cjs.map +1 -0
- package/dist/cjs/blockstore/unstorage.d.cts +36 -0
- package/dist/cjs/config.d.cts +51 -0
- package/dist/cjs/encoder/base64.cjs +38 -0
- package/dist/cjs/encoder/base64.cjs.map +1 -0
- package/dist/cjs/encoder/csv/csv-formatter.cjs +81 -0
- package/dist/cjs/encoder/csv/csv-formatter.cjs.map +1 -0
- package/dist/cjs/encoder/csv/field-formatter.cjs +76 -0
- package/dist/cjs/encoder/csv/field-formatter.cjs.map +1 -0
- package/dist/cjs/encoder/csv/row-formatter.cjs +159 -0
- package/dist/cjs/encoder/csv/row-formatter.cjs.map +1 -0
- package/dist/cjs/encoder/csv.cjs +44 -0
- package/dist/cjs/encoder/csv.cjs.map +1 -0
- package/dist/cjs/encoder/error.cjs +19 -0
- package/dist/cjs/encoder/error.cjs.map +1 -0
- package/dist/cjs/encoder/index.cjs +6 -0
- package/dist/cjs/encoder/json.cjs +36 -0
- package/dist/cjs/encoder/json.cjs.map +1 -0
- package/dist/cjs/encoder/text.cjs +35 -0
- package/dist/cjs/encoder/text.cjs.map +1 -0
- package/dist/cjs/encoder/url.cjs +39 -0
- package/dist/cjs/encoder/url.cjs.map +1 -0
- package/dist/cjs/errors/index.cjs +104 -0
- package/dist/cjs/errors/index.cjs.map +1 -0
- package/dist/cjs/errors/index.d.cts +47 -0
- package/dist/cjs/index.cjs +42 -0
- package/dist/cjs/index.d.cts +14 -0
- package/dist/cjs/pin/client.cjs +96 -0
- package/dist/cjs/pin/client.cjs.map +1 -0
- package/dist/cjs/pin/index.cjs +1 -0
- package/dist/cjs/pinner.cjs +126 -0
- package/dist/cjs/pinner.cjs.map +1 -0
- package/dist/cjs/pinner.d.cts +77 -0
- package/dist/cjs/types/constants.cjs +34 -0
- package/dist/cjs/types/constants.cjs.map +1 -0
- package/dist/cjs/types/mime-types.cjs +11 -0
- package/dist/cjs/types/mime-types.cjs.map +1 -0
- package/dist/cjs/types/mime-types.d.cts +7 -0
- package/dist/cjs/types/pin.d.cts +74 -0
- package/dist/cjs/types/pinata.d.cts +99 -0
- package/dist/cjs/types/type-guards.cjs +20 -0
- package/dist/cjs/types/type-guards.cjs.map +1 -0
- package/dist/cjs/types/type-guards.d.cts +15 -0
- package/dist/cjs/types/upload.cjs +18 -0
- package/dist/cjs/types/upload.cjs.map +1 -0
- package/dist/cjs/types/upload.d.cts +189 -0
- package/dist/cjs/upload/base-upload.cjs +135 -0
- package/dist/cjs/upload/base-upload.cjs.map +1 -0
- package/dist/cjs/upload/builder.cjs +174 -0
- package/dist/cjs/upload/builder.cjs.map +1 -0
- package/dist/cjs/upload/builder.d.cts +60 -0
- package/dist/cjs/upload/car.cjs +129 -0
- package/dist/cjs/upload/car.cjs.map +1 -0
- package/dist/cjs/upload/car.d.cts +19 -0
- package/dist/cjs/upload/constants.cjs +9 -0
- package/dist/cjs/upload/constants.cjs.map +1 -0
- package/dist/cjs/upload/index.cjs +8 -0
- package/dist/cjs/upload/manager.cjs +249 -0
- package/dist/cjs/upload/manager.cjs.map +1 -0
- package/dist/cjs/upload/manager.d.cts +35 -0
- package/dist/cjs/upload/normalize.cjs +28 -0
- package/dist/cjs/upload/normalize.cjs.map +1 -0
- package/dist/cjs/upload/tus-upload.cjs +74 -0
- package/dist/cjs/upload/tus-upload.cjs.map +1 -0
- package/dist/cjs/upload/xhr-upload.cjs +41 -0
- package/dist/cjs/upload/xhr-upload.cjs.map +1 -0
- package/dist/cjs/utils/env.cjs +12 -0
- package/dist/cjs/utils/env.cjs.map +1 -0
- package/dist/cjs/utils/stream.cjs +141 -0
- package/dist/cjs/utils/stream.cjs.map +1 -0
- package/dist/cjs/utils/stream.d.cts +23 -0
- package/dist/cjs/utils/tus-patch.cjs +50 -0
- package/dist/cjs/utils/tus-patch.cjs.map +1 -0
- package/dist/cjs/utils/validation.cjs +62 -0
- package/dist/cjs/utils/validation.cjs.map +1 -0
- package/dist/esm/_virtual/rolldown_runtime.js +8 -0
- package/dist/esm/adapters/pinata/adapter.d.ts +35 -0
- package/dist/esm/adapters/pinata/adapter.js +87 -0
- package/dist/esm/adapters/pinata/adapter.js.map +1 -0
- package/dist/esm/adapters/pinata/builder.d.ts +1 -0
- package/dist/esm/adapters/pinata/builder.js +187 -0
- package/dist/esm/adapters/pinata/builder.js.map +1 -0
- package/dist/esm/adapters/pinata/index.d.ts +4 -0
- package/dist/esm/adapters/pinata/index.js +3 -0
- package/dist/esm/adapters/pinata/list-builder.d.ts +1 -0
- package/dist/esm/adapters/pinata/list-builder.js +51 -0
- package/dist/esm/adapters/pinata/list-builder.js.map +1 -0
- package/dist/esm/blockstore/index.d.ts +2 -0
- package/dist/esm/blockstore/index.js +2 -0
- package/dist/esm/blockstore/unstorage-base.d.ts +23 -0
- package/dist/esm/blockstore/unstorage-base.js +231 -0
- package/dist/esm/blockstore/unstorage-base.js.map +1 -0
- package/dist/esm/blockstore/unstorage.d.ts +36 -0
- package/dist/esm/blockstore/unstorage.js +38 -0
- package/dist/esm/blockstore/unstorage.js.map +1 -0
- package/dist/esm/config.d.ts +51 -0
- package/dist/esm/encoder/base64.js +37 -0
- package/dist/esm/encoder/base64.js.map +1 -0
- package/dist/esm/encoder/csv/csv-formatter.js +81 -0
- package/dist/esm/encoder/csv/csv-formatter.js.map +1 -0
- package/dist/esm/encoder/csv/field-formatter.js +75 -0
- package/dist/esm/encoder/csv/field-formatter.js.map +1 -0
- package/dist/esm/encoder/csv/row-formatter.js +159 -0
- package/dist/esm/encoder/csv/row-formatter.js.map +1 -0
- package/dist/esm/encoder/csv.js +43 -0
- package/dist/esm/encoder/csv.js.map +1 -0
- package/dist/esm/encoder/error.js +18 -0
- package/dist/esm/encoder/error.js.map +1 -0
- package/dist/esm/encoder/index.js +6 -0
- package/dist/esm/encoder/json.js +35 -0
- package/dist/esm/encoder/json.js.map +1 -0
- package/dist/esm/encoder/text.js +34 -0
- package/dist/esm/encoder/text.js.map +1 -0
- package/dist/esm/encoder/url.js +36 -0
- package/dist/esm/encoder/url.js.map +1 -0
- package/dist/esm/errors/index.d.ts +47 -0
- package/dist/esm/errors/index.js +93 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.js +14 -0
- package/dist/esm/pin/client.js +95 -0
- package/dist/esm/pin/client.js.map +1 -0
- package/dist/esm/pin/index.js +1 -0
- package/dist/esm/pinner.d.ts +77 -0
- package/dist/esm/pinner.js +125 -0
- package/dist/esm/pinner.js.map +1 -0
- package/dist/esm/types/constants.js +29 -0
- package/dist/esm/types/constants.js.map +1 -0
- package/dist/esm/types/mime-types.d.ts +7 -0
- package/dist/esm/types/mime-types.js +8 -0
- package/dist/esm/types/mime-types.js.map +1 -0
- package/dist/esm/types/pin.d.ts +74 -0
- package/dist/esm/types/pinata.d.ts +99 -0
- package/dist/esm/types/type-guards.d.ts +15 -0
- package/dist/esm/types/type-guards.js +19 -0
- package/dist/esm/types/type-guards.js.map +1 -0
- package/dist/esm/types/upload.d.ts +189 -0
- package/dist/esm/types/upload.js +16 -0
- package/dist/esm/types/upload.js.map +1 -0
- package/dist/esm/upload/base-upload.js +132 -0
- package/dist/esm/upload/base-upload.js.map +1 -0
- package/dist/esm/upload/builder.d.ts +60 -0
- package/dist/esm/upload/builder.js +173 -0
- package/dist/esm/upload/builder.js.map +1 -0
- package/dist/esm/upload/car.d.ts +19 -0
- package/dist/esm/upload/car.js +125 -0
- package/dist/esm/upload/car.js.map +1 -0
- package/dist/esm/upload/constants.js +7 -0
- package/dist/esm/upload/constants.js.map +1 -0
- package/dist/esm/upload/index.js +8 -0
- package/dist/esm/upload/manager.d.ts +35 -0
- package/dist/esm/upload/manager.js +248 -0
- package/dist/esm/upload/manager.js.map +1 -0
- package/dist/esm/upload/normalize.js +28 -0
- package/dist/esm/upload/normalize.js.map +1 -0
- package/dist/esm/upload/tus-upload.js +72 -0
- package/dist/esm/upload/tus-upload.js.map +1 -0
- package/dist/esm/upload/xhr-upload.js +39 -0
- package/dist/esm/upload/xhr-upload.js.map +1 -0
- package/dist/esm/utils/env.js +11 -0
- package/dist/esm/utils/env.js.map +1 -0
- package/dist/esm/utils/stream.d.ts +23 -0
- package/dist/esm/utils/stream.js +134 -0
- package/dist/esm/utils/stream.js.map +1 -0
- package/dist/esm/utils/tus-patch.js +51 -0
- package/dist/esm/utils/tus-patch.js.map +1 -0
- package/dist/esm/utils/validation.js +60 -0
- package/dist/esm/utils/validation.js.map +1 -0
- package/package.json +95 -8
- package/public/mockServiceWorker.js +349 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { OperationPollingOptions } from "@lumeweb/portal-sdk";
|
|
2
|
+
|
|
3
|
+
//#region src/types/upload.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Symbol used to brand UploadResult for type checking
|
|
7
|
+
*/
|
|
8
|
+
declare const UploadResultSymbol: unique symbol;
|
|
9
|
+
interface UploadResult {
|
|
10
|
+
/**
|
|
11
|
+
* Unique identifier for this upload operation.
|
|
12
|
+
*/
|
|
13
|
+
id: string;
|
|
14
|
+
/**
|
|
15
|
+
* IPFS Content Identifier for the uploaded content.
|
|
16
|
+
*/
|
|
17
|
+
cid: string;
|
|
18
|
+
/**
|
|
19
|
+
* User-provided or auto-generated name for the content.
|
|
20
|
+
*/
|
|
21
|
+
name: string;
|
|
22
|
+
/**
|
|
23
|
+
* Total size in bytes.
|
|
24
|
+
*/
|
|
25
|
+
size: number;
|
|
26
|
+
/**
|
|
27
|
+
* MIME type of the content.
|
|
28
|
+
*/
|
|
29
|
+
mimeType: string;
|
|
30
|
+
/**
|
|
31
|
+
* ISO timestamp when content was created.
|
|
32
|
+
*/
|
|
33
|
+
createdAt: Date;
|
|
34
|
+
/**
|
|
35
|
+
* Number of files (1 for single file, N for directory).
|
|
36
|
+
*/
|
|
37
|
+
numberOfFiles: number;
|
|
38
|
+
/**
|
|
39
|
+
* Custom key-value metadata.
|
|
40
|
+
*/
|
|
41
|
+
keyvalues?: Record<string, string>;
|
|
42
|
+
/**
|
|
43
|
+
* Whether this upload is a directory.
|
|
44
|
+
*/
|
|
45
|
+
isDirectory?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Whether this upload is already a valid CAR file.
|
|
48
|
+
* If true, the upload system will skip CAR preprocessing and upload the file as-is.
|
|
49
|
+
* Useful for passthrough of pre-generated CAR files.
|
|
50
|
+
*/
|
|
51
|
+
isCarFile?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Portal operation ID for tracking the pinning operation.
|
|
54
|
+
* Can be used with waitForOperation() to wait for the operation to complete.
|
|
55
|
+
*/
|
|
56
|
+
operationId?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Symbol brand for type checking - used to identify UploadResult objects
|
|
59
|
+
*/
|
|
60
|
+
[UploadResultSymbol]?: true;
|
|
61
|
+
}
|
|
62
|
+
type UploadInput = File | ReadableStream<Uint8Array>;
|
|
63
|
+
interface UploadOptions {
|
|
64
|
+
/**
|
|
65
|
+
* Name for the uploaded content.
|
|
66
|
+
*/
|
|
67
|
+
name?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Custom key-value metadata.
|
|
70
|
+
*/
|
|
71
|
+
keyvalues?: Record<string, string>;
|
|
72
|
+
/**
|
|
73
|
+
* Progress callback invoked during upload.
|
|
74
|
+
*/
|
|
75
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Callback invoked when upload completes successfully.
|
|
78
|
+
*/
|
|
79
|
+
onComplete?: (result: UploadResult) => void;
|
|
80
|
+
/**
|
|
81
|
+
* Callback invoked when upload fails.
|
|
82
|
+
*/
|
|
83
|
+
onError?: (error: Error) => void;
|
|
84
|
+
/**
|
|
85
|
+
* AbortSignal for cancellation.
|
|
86
|
+
*/
|
|
87
|
+
signal?: AbortSignal;
|
|
88
|
+
/**
|
|
89
|
+
* Optional size override for the upload input.
|
|
90
|
+
* Useful for ReadableStream inputs where size detection is difficult.
|
|
91
|
+
*/
|
|
92
|
+
size?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Whether this upload is a directory.
|
|
95
|
+
*/
|
|
96
|
+
isDirectory?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Whether this upload is already a valid CAR file.
|
|
99
|
+
* If true, the upload system will skip CAR preprocessing and upload the file as-is.
|
|
100
|
+
* Useful for passthrough of pre-generated CAR files.
|
|
101
|
+
*/
|
|
102
|
+
isCarFile?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Whether to wait for the pinning operation to complete/fail.
|
|
105
|
+
* When true, the upload will block until the operation reaches a settled state
|
|
106
|
+
* (completed, failed, or error). Default is false (upload only).
|
|
107
|
+
*/
|
|
108
|
+
waitForOperation?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Polling options for waiting on operation completion.
|
|
111
|
+
* Only used when waitForOperation is true.
|
|
112
|
+
*/
|
|
113
|
+
operationPollingOptions?: OperationPollingOptions;
|
|
114
|
+
}
|
|
115
|
+
interface UploadProgress {
|
|
116
|
+
/**
|
|
117
|
+
* Percentage complete (0-100).
|
|
118
|
+
*/
|
|
119
|
+
percentage: number;
|
|
120
|
+
/**
|
|
121
|
+
* Number of bytes uploaded.
|
|
122
|
+
*/
|
|
123
|
+
bytesUploaded: number;
|
|
124
|
+
/**
|
|
125
|
+
* Total bytes to upload.
|
|
126
|
+
*/
|
|
127
|
+
bytesTotal: number;
|
|
128
|
+
/**
|
|
129
|
+
* Upload speed in bytes per second.
|
|
130
|
+
*/
|
|
131
|
+
speed?: number;
|
|
132
|
+
/**
|
|
133
|
+
* Estimated time remaining in seconds.
|
|
134
|
+
*/
|
|
135
|
+
eta?: number;
|
|
136
|
+
}
|
|
137
|
+
interface UploadOperation {
|
|
138
|
+
/**
|
|
139
|
+
* Cancel the ongoing upload.
|
|
140
|
+
*/
|
|
141
|
+
cancel(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Pause the upload (TUS only).
|
|
144
|
+
*/
|
|
145
|
+
pause(): void;
|
|
146
|
+
/**
|
|
147
|
+
* Resume a paused upload (TUS only).
|
|
148
|
+
*/
|
|
149
|
+
resume(): void;
|
|
150
|
+
/**
|
|
151
|
+
* Promise that resolves when upload completes.
|
|
152
|
+
*/
|
|
153
|
+
result: Promise<UploadResult>;
|
|
154
|
+
/**
|
|
155
|
+
* Current progress.
|
|
156
|
+
*/
|
|
157
|
+
progress: Readonly<UploadProgress>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Builder interface for Pinner upload API.
|
|
161
|
+
* Supports chaining name/keyvalues and returns UploadOperation with controls.
|
|
162
|
+
*/
|
|
163
|
+
interface PinnerUploadBuilder {
|
|
164
|
+
/**
|
|
165
|
+
* Set the name for the upload.
|
|
166
|
+
*/
|
|
167
|
+
name(name: string): this;
|
|
168
|
+
/**
|
|
169
|
+
* Set custom key-value metadata.
|
|
170
|
+
*/
|
|
171
|
+
keyvalues(kv: Record<string, string>): this;
|
|
172
|
+
/**
|
|
173
|
+
* Whether to wait for the pinning operation to complete/fail.
|
|
174
|
+
* When true, the upload will block until the operation reaches a settled state.
|
|
175
|
+
*/
|
|
176
|
+
waitForOperation(wait: boolean): this;
|
|
177
|
+
/**
|
|
178
|
+
* Set polling options for waiting on operation completion.
|
|
179
|
+
* Only used when waitForOperation is true.
|
|
180
|
+
*/
|
|
181
|
+
operationPollingOptions(options: OperationPollingOptions): this;
|
|
182
|
+
/**
|
|
183
|
+
* Start the upload and return UploadOperation with controls.
|
|
184
|
+
*/
|
|
185
|
+
pin(): Promise<UploadOperation>;
|
|
186
|
+
}
|
|
187
|
+
//#endregion
|
|
188
|
+
export { PinnerUploadBuilder, UploadInput, UploadOperation, UploadOptions, UploadProgress, UploadResult };
|
|
189
|
+
//# sourceMappingURL=upload.d.cts.map
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_normalize = require('./normalize.cjs');
|
|
3
|
+
const require_env = require('../utils/env.cjs');
|
|
4
|
+
const require_stream = require('../utils/stream.cjs');
|
|
5
|
+
const require_constants = require('./constants.cjs');
|
|
6
|
+
let _uppy_core = require("@uppy/core");
|
|
7
|
+
_uppy_core = require_rolldown_runtime.__toESM(_uppy_core);
|
|
8
|
+
let p_defer = require("p-defer");
|
|
9
|
+
p_defer = require_rolldown_runtime.__toESM(p_defer);
|
|
10
|
+
|
|
11
|
+
//#region src/upload/base-upload.ts
|
|
12
|
+
var BaseUploadHandler = class {
|
|
13
|
+
config;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
async upload(input, options) {
|
|
18
|
+
const normalized = require_normalize.normalizeUploadInput(input, options);
|
|
19
|
+
const uppy = new _uppy_core.default();
|
|
20
|
+
const { fileId, resultPromise, progress } = this.#setupUppyHandlers(uppy, normalized, options);
|
|
21
|
+
await this.#addFileToUppy(uppy, normalized, normalized.size);
|
|
22
|
+
this.#startUpload(uppy, options);
|
|
23
|
+
return this.#createUploadOperation(uppy, fileId, resultPromise, progress);
|
|
24
|
+
}
|
|
25
|
+
#setupUppyHandlers(uppy, normalized, options) {
|
|
26
|
+
let fileId = null;
|
|
27
|
+
let hasRejected = false;
|
|
28
|
+
const progress = {
|
|
29
|
+
percentage: 0,
|
|
30
|
+
bytesUploaded: 0,
|
|
31
|
+
bytesTotal: normalized.size
|
|
32
|
+
};
|
|
33
|
+
const { promise: resultPromise, resolve: resolveResult, reject: rejectResult } = (0, p_defer.default)();
|
|
34
|
+
const handleError = (error) => {
|
|
35
|
+
if (hasRejected) return;
|
|
36
|
+
hasRejected = true;
|
|
37
|
+
options?.onError?.(error);
|
|
38
|
+
rejectResult(error);
|
|
39
|
+
};
|
|
40
|
+
this.configurePlugin(uppy);
|
|
41
|
+
uppy.on("progress", (progressBytes) => {
|
|
42
|
+
progress.bytesUploaded = progressBytes;
|
|
43
|
+
progress.percentage = progressBytes / progress.bytesTotal * 100;
|
|
44
|
+
options?.onProgress?.(progress);
|
|
45
|
+
});
|
|
46
|
+
uppy.on("upload-success", (_file, result) => {
|
|
47
|
+
if (hasRejected) return;
|
|
48
|
+
const uploadResult = this.parseResult(result);
|
|
49
|
+
options?.onComplete?.(uploadResult);
|
|
50
|
+
resolveResult(uploadResult);
|
|
51
|
+
});
|
|
52
|
+
uppy.on("error", (error) => {
|
|
53
|
+
handleError(new Error(this.#extractErrorMessage(error)));
|
|
54
|
+
});
|
|
55
|
+
uppy.on("file-added", (file) => {
|
|
56
|
+
fileId = file.id;
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
fileId,
|
|
60
|
+
resultPromise,
|
|
61
|
+
progress
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
#extractErrorMessage(error) {
|
|
65
|
+
let errorMessage = "Upload fainormalizeDataled";
|
|
66
|
+
if (!error) return errorMessage;
|
|
67
|
+
if (typeof error === "string") errorMessage = error;
|
|
68
|
+
else if (error instanceof Error) errorMessage = error.message;
|
|
69
|
+
else if (error.message) errorMessage = error.message;
|
|
70
|
+
else if (error.toString && typeof error.toString === "function") errorMessage = error.toString();
|
|
71
|
+
const errorObj = error;
|
|
72
|
+
if (errorObj?.xhr?.response) try {
|
|
73
|
+
const response = typeof errorObj.xhr.response === "string" ? JSON.parse(errorObj.xhr.response) : errorObj.xhr.response;
|
|
74
|
+
if (response.error) errorMessage = response.error;
|
|
75
|
+
else if (response.message) errorMessage = response.message;
|
|
76
|
+
} catch {}
|
|
77
|
+
return errorMessage;
|
|
78
|
+
}
|
|
79
|
+
async #normalizeData(data) {
|
|
80
|
+
if (require_env.isNodeEnvironment()) return this.#normalizeDataForNode(data);
|
|
81
|
+
return this.#normalizeDataForBrowser(data);
|
|
82
|
+
}
|
|
83
|
+
async #normalizeDataForBrowser(data) {
|
|
84
|
+
if (this.getUploadSource() === require_constants.UPLOAD_SOURCE_TUS) {
|
|
85
|
+
if (data instanceof ReadableStream) {
|
|
86
|
+
const { streamToBlobViaResponse } = await Promise.resolve().then(() => require("../utils/stream.cjs"));
|
|
87
|
+
return streamToBlobViaResponse(data);
|
|
88
|
+
}
|
|
89
|
+
return data;
|
|
90
|
+
}
|
|
91
|
+
return data;
|
|
92
|
+
}
|
|
93
|
+
async #normalizeDataForNode(data) {
|
|
94
|
+
if (this.getUploadSource() === require_constants.UPLOAD_SOURCE_XHR) return data;
|
|
95
|
+
if (data instanceof File) return await require_stream.readableStreamToNodeStream(require_stream.fileToReadableStream(data));
|
|
96
|
+
if (data instanceof ReadableStream) return await require_stream.readableStreamToNodeStream(data);
|
|
97
|
+
return data;
|
|
98
|
+
}
|
|
99
|
+
async #addFileToUppy(uppy, normalized, size) {
|
|
100
|
+
const fileData = await this.#normalizeData(normalized.data);
|
|
101
|
+
const fileOptions = {
|
|
102
|
+
source: this.getUploadSource(),
|
|
103
|
+
name: normalized.name,
|
|
104
|
+
type: normalized.type,
|
|
105
|
+
data: fileData
|
|
106
|
+
};
|
|
107
|
+
const fileId = uppy.addFile(fileOptions);
|
|
108
|
+
if (this.getUploadSource() === require_constants.UPLOAD_SOURCE_TUS && size !== void 0 && size > 0) uppy.setFileState(fileId, { tus: { uploadSize: size } });
|
|
109
|
+
}
|
|
110
|
+
#startUpload(uppy, options) {
|
|
111
|
+
uppy.upload().catch((error) => {
|
|
112
|
+
options?.onError?.(new Error(this.#extractErrorMessage(error)));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
#createUploadOperation(uppy, fileId, resultPromise, progress) {
|
|
116
|
+
return {
|
|
117
|
+
cancel: () => {
|
|
118
|
+
uppy.cancelAll();
|
|
119
|
+
},
|
|
120
|
+
pause: () => {
|
|
121
|
+
if (fileId) uppy.pauseResume(fileId);
|
|
122
|
+
},
|
|
123
|
+
resume: () => {
|
|
124
|
+
if (fileId) uppy.pauseResume(fileId);
|
|
125
|
+
},
|
|
126
|
+
result: resultPromise,
|
|
127
|
+
progress: Object.freeze({ ...progress })
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
destroy() {}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
//#endregion
|
|
134
|
+
exports.BaseUploadHandler = BaseUploadHandler;
|
|
135
|
+
//# sourceMappingURL=base-upload.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-upload.cjs","names":["normalizeUploadInput","Uppy","#setupUppyHandlers","#addFileToUppy","#startUpload","#createUploadOperation","#extractErrorMessage","#normalizeData","isNodeEnvironment","#normalizeDataForNode","#normalizeDataForBrowser","UPLOAD_SOURCE_TUS","UPLOAD_SOURCE_XHR","readableStreamToNodeStream","fileToReadableStream"],"sources":["../../../src/upload/base-upload.ts"],"sourcesContent":["import Uppy from \"@uppy/core\";\nimport { default as defer } from \"p-defer\";\nimport type { Readable } from \"stream\";\n\nimport type { PinnerConfig } from \"../config\";\nimport type {\n UploadInput,\n UploadOperation,\n UploadOptions,\n UploadProgress,\n UploadResult,\n} from \"@/types/upload\";\nimport { normalizeUploadInput, type UploadInputObject } from \"./normalize\";\nimport {\n fileToReadableStream,\n readableStreamToNodeStream,\n} from \"@/utils/stream\";\nimport { isNodeEnvironment } from \"@/utils/env\";\nimport { UPLOAD_SOURCE_TUS, UPLOAD_SOURCE_XHR } from \"./constants\";\n\n// Node.js Readable stream with size property for Uppy compatibility\ntype NodeStreamWithSize = Readable & { size: number | null };\n\nexport abstract class BaseUploadHandler {\n protected config: Required<PinnerConfig>;\n\n constructor(config: PinnerConfig) {\n this.config = config as Required<PinnerConfig>;\n }\n\n async upload(\n input: UploadInput | UploadInputObject,\n options?: UploadOptions,\n ): Promise<UploadOperation> {\n const normalized = normalizeUploadInput(input, options);\n const uppy = new Uppy();\n const { fileId, resultPromise, progress } = this.#setupUppyHandlers(\n uppy,\n normalized,\n options,\n );\n\n await this.#addFileToUppy(uppy, normalized, normalized.size);\n this.#startUpload(uppy, options);\n\n return this.#createUploadOperation(uppy, fileId, resultPromise, progress);\n }\n\n #setupUppyHandlers(\n uppy: Uppy,\n normalized: { size: number },\n options?: UploadOptions,\n ): {\n fileId: string | null;\n resultPromise: Promise<UploadResult>;\n progress: UploadProgress;\n } {\n let fileId: string | null = null;\n let hasRejected = false;\n\n const progress: UploadProgress = {\n percentage: 0,\n bytesUploaded: 0,\n bytesTotal: normalized.size,\n };\n\n const {\n promise: resultPromise,\n resolve: resolveResult,\n reject: rejectResult,\n } = defer<UploadResult>();\n\n const handleError = (error: Error) => {\n if (hasRejected) return;\n hasRejected = true;\n options?.onError?.(error);\n rejectResult(error);\n };\n\n this.configurePlugin(uppy);\n\n uppy.on(\"progress\", (progressBytes) => {\n progress.bytesUploaded = progressBytes;\n progress.percentage = (progressBytes / progress.bytesTotal) * 100;\n options?.onProgress?.(progress);\n });\n\n uppy.on(\"upload-success\", (_file, result) => {\n if (hasRejected) return;\n const uploadResult = this.parseResult(result);\n options?.onComplete?.(uploadResult);\n resolveResult(uploadResult);\n });\n\n uppy.on(\"error\", (error) => {\n handleError(new Error(this.#extractErrorMessage(error)));\n });\n\n uppy.on(\"file-added\", (file) => {\n fileId = file.id;\n });\n\n return { fileId, resultPromise, progress };\n }\n\n #extractErrorMessage(error: unknown): string {\n let errorMessage = \"Upload fainormalizeDataled\";\n\n if (!error) return errorMessage;\n\n if (typeof error === \"string\") {\n errorMessage = error;\n } else if (error instanceof Error) {\n errorMessage = error.message;\n } else if ((error as any).message) {\n errorMessage = (error as any).message;\n } else if (\n (error as any).toString &&\n typeof (error as any).toString === \"function\"\n ) {\n errorMessage = (error as any).toString();\n }\n\n // Try to extract error from response (XHRUpload/TusPlugin)\n const errorObj = error as any;\n if (errorObj?.xhr?.response) {\n try {\n const response =\n typeof errorObj.xhr.response === \"string\"\n ? JSON.parse(errorObj.xhr.response)\n : errorObj.xhr.response;\n if (response.error) {\n errorMessage = response.error;\n } else if (response.message) {\n errorMessage = response.message;\n }\n } catch {\n // If parsing fails, use the original error message\n }\n }\n\n return errorMessage;\n }\n\n async #normalizeData(\n data: File | ReadableStream<Uint8Array>,\n ): Promise<File | ReadableStream<Uint8Array> | NodeStreamWithSize | Blob> {\n if (isNodeEnvironment()) {\n return this.#normalizeDataForNode(data);\n }\n return this.#normalizeDataForBrowser(data);\n }\n\n async #normalizeDataForBrowser(\n data: File | ReadableStream<Uint8Array>,\n ): Promise<File | Blob | ReadableStream<Uint8Array>> {\n // TUS plugin requires File, Blob, or Reader in browser\n if (this.getUploadSource() === UPLOAD_SOURCE_TUS) {\n if (data instanceof ReadableStream) {\n const { streamToBlobViaResponse } = await import(\"@/utils/stream\");\n return streamToBlobViaResponse(data);\n }\n return data;\n }\n\n // XHRUpload handles File/Blob directly\n return data;\n }\n\n async #normalizeDataForNode(\n data: File | ReadableStream<Uint8Array>,\n ): Promise<NodeStreamWithSize | File | Blob | ReadableStream<Uint8Array>> {\n // XHRUpload with formData: true requires Blob/File for FormData.append()\n // Do not convert to Node.js stream for XHRUpload\n if (this.getUploadSource() === UPLOAD_SOURCE_XHR) {\n return data;\n }\n\n // Convert File to ReadableStream without loading entire blob into memory\n if (data instanceof File) {\n const stream = fileToReadableStream(data);\n // Convert to Node.js stream for tus-js-client\n const nodeStream = await readableStreamToNodeStream(stream);\n return nodeStream as NodeStreamWithSize;\n }\n\n // In Node.js, convert ReadableStream to Node.js stream.Readable for tus-js-client's NodeFileReader\n if (data instanceof ReadableStream) {\n const nodeStream = await readableStreamToNodeStream(data);\n // Add size property to satisfy Uppy's type requirements\n return nodeStream as NodeStreamWithSize;\n }\n\n return data;\n }\n\n async #addFileToUppy(\n uppy: Uppy,\n normalized: {\n data: File | ReadableStream<Uint8Array>;\n name: string;\n type: string;\n },\n size?: number,\n ): Promise<void> {\n const fileData = await this.#normalizeData(normalized.data);\n const fileOptions = {\n source: this.getUploadSource(),\n name: normalized.name,\n type: normalized.type,\n data: fileData as any,\n };\n\n // Add file to Uppy first\n // Note: Uppy accepts any data type as it defers to the drivers\n const fileId = uppy.addFile(fileOptions);\n\n // Set TUS upload size if provided\n // In Node.js, streams need explicit size for tus-js-client\n // In browser, Uppy's TUS plugin may not derive size from Blob automatically\n if (\n this.getUploadSource() === UPLOAD_SOURCE_TUS &&\n size !== undefined &&\n size > 0\n ) {\n uppy.setFileState(fileId, {\n tus: { uploadSize: size },\n });\n }\n }\n\n #startUpload(uppy: Uppy, options?: UploadOptions): void {\n uppy.upload().catch((error) => {\n options?.onError?.(new Error(this.#extractErrorMessage(error)));\n });\n }\n\n #createUploadOperation(\n uppy: Uppy,\n fileId: string | null,\n resultPromise: Promise<UploadResult>,\n progress: UploadProgress,\n ): UploadOperation {\n return {\n cancel: () => {\n uppy.cancelAll();\n },\n pause: () => {\n if (fileId) {\n uppy.pauseResume(fileId);\n }\n },\n resume: () => {\n if (fileId) {\n uppy.pauseResume(fileId);\n }\n },\n result: resultPromise,\n progress: Object.freeze({ ...progress }),\n };\n }\n\n destroy(): void {\n // No-op since each upload creates its own Uppy instance\n }\n\n protected abstract configurePlugin(uppy: Uppy): void;\n protected abstract parseResult(result: unknown): UploadResult;\n protected abstract getUploadSource(): string;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
const require_json = require('../encoder/json.cjs');
|
|
2
|
+
const require_base64 = require('../encoder/base64.cjs');
|
|
3
|
+
const require_url = require('../encoder/url.cjs');
|
|
4
|
+
const require_csv = require('../encoder/csv.cjs');
|
|
5
|
+
const require_text = require('../encoder/text.cjs');
|
|
6
|
+
require('../encoder/index.cjs');
|
|
7
|
+
const require_validation = require('../utils/validation.cjs');
|
|
8
|
+
|
|
9
|
+
//#region src/upload/builder.ts
|
|
10
|
+
/**
|
|
11
|
+
* Base upload builder with common name/keyvalues functionality.
|
|
12
|
+
*/
|
|
13
|
+
var BaseUploadBuilder = class {
|
|
14
|
+
_name;
|
|
15
|
+
_keyvalues;
|
|
16
|
+
_waitForOperation;
|
|
17
|
+
_operationPollingOptions;
|
|
18
|
+
constructor(pinner) {
|
|
19
|
+
this.pinner = pinner;
|
|
20
|
+
}
|
|
21
|
+
name(name) {
|
|
22
|
+
this._name = name;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
keyvalues(kv) {
|
|
26
|
+
this._keyvalues = kv;
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
waitForOperation(wait = true) {
|
|
30
|
+
this._waitForOperation = wait;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
operationPollingOptions(options) {
|
|
34
|
+
this._operationPollingOptions = options;
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
buildOptions() {
|
|
38
|
+
const options = {};
|
|
39
|
+
if (this._name !== void 0) options.name = this._name;
|
|
40
|
+
if (this._keyvalues !== void 0) options.keyvalues = this._keyvalues;
|
|
41
|
+
if (this._waitForOperation !== void 0) options.waitForOperation = this._waitForOperation;
|
|
42
|
+
if (this._operationPollingOptions !== void 0) options.operationPollingOptions = this._operationPollingOptions;
|
|
43
|
+
return options;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* File upload builder.
|
|
48
|
+
*/
|
|
49
|
+
var FileUploadBuilder = class extends BaseUploadBuilder {
|
|
50
|
+
constructor(pinner, file) {
|
|
51
|
+
super(pinner);
|
|
52
|
+
this.file = file;
|
|
53
|
+
}
|
|
54
|
+
async pin() {
|
|
55
|
+
return this.pinner.upload(this.file, this.buildOptions());
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Encoded upload builder - handles JSON, Base64, and URL uploads using encoders.
|
|
60
|
+
*/
|
|
61
|
+
var EncodedUploadBuilder = class extends BaseUploadBuilder {
|
|
62
|
+
constructor(pinner, encoderFn) {
|
|
63
|
+
super(pinner);
|
|
64
|
+
this.encoderFn = encoderFn;
|
|
65
|
+
}
|
|
66
|
+
async pin() {
|
|
67
|
+
const encoded = await this.encoderFn(this._name, this._keyvalues);
|
|
68
|
+
return this.pinner.upload(encoded.file, encoded.options);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Raw CAR upload builder - handles raw CAR file uploads without preprocessing.
|
|
73
|
+
*/
|
|
74
|
+
var RawUploadBuilder = class extends BaseUploadBuilder {
|
|
75
|
+
constructor(pinner, carInput) {
|
|
76
|
+
super(pinner);
|
|
77
|
+
this.carInput = carInput;
|
|
78
|
+
}
|
|
79
|
+
async pin() {
|
|
80
|
+
return this.pinner.uploadCar(this.carInput, this.buildOptions());
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Pinner upload builder namespace.
|
|
85
|
+
* Provides fluent API for file, JSON, Base64, and URL uploads.
|
|
86
|
+
*/
|
|
87
|
+
var UploadBuilderNamespace = class {
|
|
88
|
+
constructor(pinner) {
|
|
89
|
+
this.pinner = pinner;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Upload a file.
|
|
93
|
+
* Returns a builder for chaining name/keyvalues.
|
|
94
|
+
*/
|
|
95
|
+
file(file) {
|
|
96
|
+
return new FileUploadBuilder(this.pinner, file);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Upload JSON data (encoded as JSON file).
|
|
100
|
+
* Returns a builder for chaining name/keyvalues.
|
|
101
|
+
*/
|
|
102
|
+
json(data) {
|
|
103
|
+
return new EncodedUploadBuilder(this.pinner, (name, keyvalues) => require_json.jsonToFile(data, {
|
|
104
|
+
name,
|
|
105
|
+
keyvalues
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Upload Base64 encoded content (decoded and uploaded as file).
|
|
110
|
+
* Returns a builder for chaining name/keyvalues.
|
|
111
|
+
*/
|
|
112
|
+
base64(base64String) {
|
|
113
|
+
return new EncodedUploadBuilder(this.pinner, (name, keyvalues) => require_base64.base64ToFile(base64String, {
|
|
114
|
+
name,
|
|
115
|
+
keyvalues
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Upload content from a URL (fetched and uploaded as file).
|
|
120
|
+
* Returns a builder for chaining name/keyvalues.
|
|
121
|
+
*/
|
|
122
|
+
url(urlString) {
|
|
123
|
+
require_validation.validateUrl(urlString);
|
|
124
|
+
return new EncodedUploadBuilder(this.pinner, (name, keyvalues) => require_url.urlToFile(urlString, {
|
|
125
|
+
name,
|
|
126
|
+
keyvalues
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Upload CSV data (string, array of objects, or array of arrays).
|
|
131
|
+
* Returns a builder for chaining name/keyvalues.
|
|
132
|
+
*/
|
|
133
|
+
csv(data) {
|
|
134
|
+
return new EncodedUploadBuilder(this.pinner, (name, keyvalues) => require_csv.csvToFile(data, {
|
|
135
|
+
name,
|
|
136
|
+
keyvalues
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Upload raw CAR data without preprocessing.
|
|
141
|
+
* Useful for passthrough of pre-generated CAR files.
|
|
142
|
+
* Returns a builder for chaining name/keyvalues.
|
|
143
|
+
*/
|
|
144
|
+
raw(carInput) {
|
|
145
|
+
return new RawUploadBuilder(this.pinner, carInput);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Upload text content (encoded as text file).
|
|
149
|
+
* Returns a builder for chaining name/keyvalues.
|
|
150
|
+
*/
|
|
151
|
+
text(textData) {
|
|
152
|
+
return new EncodedUploadBuilder(this.pinner, (name, keyvalues) => require_text.textToFile(textData, {
|
|
153
|
+
name,
|
|
154
|
+
keyvalues
|
|
155
|
+
}));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Alias for text() - upload text content.
|
|
159
|
+
*/
|
|
160
|
+
get content() {
|
|
161
|
+
return (textData) => this.text(textData);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Create a Pinner upload builder namespace.
|
|
166
|
+
*/
|
|
167
|
+
function createUploadBuilderNamespace(pinner) {
|
|
168
|
+
return new UploadBuilderNamespace(pinner);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//#endregion
|
|
172
|
+
exports.UploadBuilderNamespace = UploadBuilderNamespace;
|
|
173
|
+
exports.createUploadBuilderNamespace = createUploadBuilderNamespace;
|
|
174
|
+
//# sourceMappingURL=builder.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.cjs","names":["jsonToFile","base64ToFile","urlToFile","csvToFile","textToFile"],"sources":["../../../src/upload/builder.ts"],"sourcesContent":["import type { Pinner } from \"@/pinner\";\nimport type {\n PinnerUploadBuilder,\n UploadOperation,\n UploadOptions,\n} from \"@/types/upload\";\nimport type { OperationPollingOptions } from \"@lumeweb/portal-sdk\";\nimport {\n base64ToFile,\n csvToFile,\n jsonToFile,\n textToFile,\n urlToFile,\n} from \"@/encoder\";\nimport { validateUrl } from \"@/utils/validation\";\n\n/**\n * Base upload builder with common name/keyvalues functionality.\n */\nabstract class BaseUploadBuilder implements PinnerUploadBuilder {\n protected _name?: string;\n protected _keyvalues?: Record<string, string>;\n protected _waitForOperation?: boolean;\n protected _operationPollingOptions?: OperationPollingOptions;\n\n constructor(protected pinner: Pinner) {}\n\n name(name: string): this {\n this._name = name;\n return this;\n }\n\n keyvalues(kv: Record<string, string>): this {\n this._keyvalues = kv;\n return this;\n }\n\n waitForOperation(wait: boolean = true): this {\n this._waitForOperation = wait;\n return this;\n }\n\n operationPollingOptions(options: OperationPollingOptions): this {\n this._operationPollingOptions = options;\n return this;\n }\n\n abstract pin(): Promise<UploadOperation>;\n\n protected buildOptions(): UploadOptions {\n const options: UploadOptions = {};\n if (this._name !== undefined) {\n options.name = this._name;\n }\n if (this._keyvalues !== undefined) {\n options.keyvalues = this._keyvalues;\n }\n if (this._waitForOperation !== undefined) {\n options.waitForOperation = this._waitForOperation;\n }\n if (this._operationPollingOptions !== undefined) {\n options.operationPollingOptions = this._operationPollingOptions;\n }\n return options;\n }\n}\n\n/**\n * File upload builder.\n */\nclass FileUploadBuilder extends BaseUploadBuilder {\n constructor(\n pinner: Pinner,\n private file: File,\n ) {\n super(pinner);\n }\n\n async pin(): Promise<UploadOperation> {\n return this.pinner.upload(this.file, this.buildOptions());\n }\n}\n\n/**\n * Encoded upload builder - handles JSON, Base64, and URL uploads using encoders.\n */\nclass EncodedUploadBuilder extends BaseUploadBuilder {\n constructor(\n pinner: Pinner,\n private encoderFn: (\n name?: string,\n keyvalues?: Record<string, string>,\n ) => Promise<{ file: File; options: UploadOptions }>,\n ) {\n super(pinner);\n }\n\n async pin(): Promise<UploadOperation> {\n const encoded = await this.encoderFn(this._name, this._keyvalues);\n return this.pinner.upload(encoded.file, encoded.options);\n }\n}\n\n/**\n * Raw CAR upload builder - handles raw CAR file uploads without preprocessing.\n */\nclass RawUploadBuilder extends BaseUploadBuilder {\n constructor(\n pinner: Pinner,\n private carInput: File | ReadableStream<Uint8Array>,\n ) {\n super(pinner);\n }\n\n async pin(): Promise<UploadOperation> {\n return this.pinner.uploadCar(this.carInput, this.buildOptions());\n }\n}\n\n/**\n * Pinner upload builder namespace.\n * Provides fluent API for file, JSON, Base64, and URL uploads.\n */\nexport class UploadBuilderNamespace {\n constructor(private pinner: Pinner) {}\n\n /**\n * Upload a file.\n * Returns a builder for chaining name/keyvalues.\n */\n file(file: File): PinnerUploadBuilder {\n return new FileUploadBuilder(this.pinner, file);\n }\n\n /**\n * Upload JSON data (encoded as JSON file).\n * Returns a builder for chaining name/keyvalues.\n */\n json(data: object): PinnerUploadBuilder {\n return new EncodedUploadBuilder(this.pinner, (name, keyvalues) =>\n jsonToFile(data, { name, keyvalues }),\n );\n }\n\n /**\n * Upload Base64 encoded content (decoded and uploaded as file).\n * Returns a builder for chaining name/keyvalues.\n */\n base64(base64String: string): PinnerUploadBuilder {\n return new EncodedUploadBuilder(this.pinner, (name, keyvalues) =>\n base64ToFile(base64String, { name, keyvalues }),\n );\n }\n\n /**\n * Upload content from a URL (fetched and uploaded as file).\n * Returns a builder for chaining name/keyvalues.\n */\n url(urlString: string): PinnerUploadBuilder {\n // Validate URL to prevent SSRF attacks\n validateUrl(urlString);\n\n return new EncodedUploadBuilder(this.pinner, (name, keyvalues) =>\n urlToFile(urlString, { name, keyvalues }),\n );\n }\n\n /**\n * Upload CSV data (string, array of objects, or array of arrays).\n * Returns a builder for chaining name/keyvalues.\n */\n csv(data: string | object[] | any[][]): PinnerUploadBuilder {\n return new EncodedUploadBuilder(this.pinner, (name, keyvalues) =>\n csvToFile(data, { name, keyvalues }),\n );\n }\n\n /**\n * Upload raw CAR data without preprocessing.\n * Useful for passthrough of pre-generated CAR files.\n * Returns a builder for chaining name/keyvalues.\n */\n raw(carInput: File | ReadableStream<Uint8Array>): PinnerUploadBuilder {\n return new RawUploadBuilder(this.pinner, carInput);\n }\n\n /**\n * Upload text content (encoded as text file).\n * Returns a builder for chaining name/keyvalues.\n */\n text(textData: string): PinnerUploadBuilder {\n return new EncodedUploadBuilder(this.pinner, (name, keyvalues) =>\n textToFile(textData, { name, keyvalues }),\n );\n }\n\n /**\n * Alias for text() - upload text content.\n */\n get content(): (textData: string) => PinnerUploadBuilder {\n return (textData: string) => this.text(textData);\n }\n}\n\n/**\n * Create a Pinner upload builder namespace.\n */\nexport function createUploadBuilderNamespace(\n pinner: Pinner,\n): UploadBuilderNamespace {\n return new UploadBuilderNamespace(pinner);\n}\n\n/**\n * Combined interface for upload that works as both a method and a builder namespace.\n */\nexport type UploadMethodAndBuilder = ((\n file: File,\n options?: UploadOptions,\n) => Promise<UploadOperation>) &\n UploadBuilderNamespace;\n\n/**\n * Export PinnerUploadBuilder for external use.\n */\nexport type { PinnerUploadBuilder };\n"],"mappings":";;;;;;;;;;;;AAmBA,IAAe,oBAAf,MAAgE;CAC9D,AAAU;CACV,AAAU;CACV,AAAU;CACV,AAAU;CAEV,YAAY,AAAU,QAAgB;EAAhB;;CAEtB,KAAK,MAAoB;AACvB,OAAK,QAAQ;AACb,SAAO;;CAGT,UAAU,IAAkC;AAC1C,OAAK,aAAa;AAClB,SAAO;;CAGT,iBAAiB,OAAgB,MAAY;AAC3C,OAAK,oBAAoB;AACzB,SAAO;;CAGT,wBAAwB,SAAwC;AAC9D,OAAK,2BAA2B;AAChC,SAAO;;CAKT,AAAU,eAA8B;EACtC,MAAM,UAAyB,EAAE;AACjC,MAAI,KAAK,UAAU,OACjB,SAAQ,OAAO,KAAK;AAEtB,MAAI,KAAK,eAAe,OACtB,SAAQ,YAAY,KAAK;AAE3B,MAAI,KAAK,sBAAsB,OAC7B,SAAQ,mBAAmB,KAAK;AAElC,MAAI,KAAK,6BAA6B,OACpC,SAAQ,0BAA0B,KAAK;AAEzC,SAAO;;;;;;AAOX,IAAM,oBAAN,cAAgC,kBAAkB;CAChD,YACE,QACA,AAAQ,MACR;AACA,QAAM,OAAO;EAFL;;CAKV,MAAM,MAAgC;AACpC,SAAO,KAAK,OAAO,OAAO,KAAK,MAAM,KAAK,cAAc,CAAC;;;;;;AAO7D,IAAM,uBAAN,cAAmC,kBAAkB;CACnD,YACE,QACA,AAAQ,WAIR;AACA,QAAM,OAAO;EALL;;CAQV,MAAM,MAAgC;EACpC,MAAM,UAAU,MAAM,KAAK,UAAU,KAAK,OAAO,KAAK,WAAW;AACjE,SAAO,KAAK,OAAO,OAAO,QAAQ,MAAM,QAAQ,QAAQ;;;;;;AAO5D,IAAM,mBAAN,cAA+B,kBAAkB;CAC/C,YACE,QACA,AAAQ,UACR;AACA,QAAM,OAAO;EAFL;;CAKV,MAAM,MAAgC;AACpC,SAAO,KAAK,OAAO,UAAU,KAAK,UAAU,KAAK,cAAc,CAAC;;;;;;;AAQpE,IAAa,yBAAb,MAAoC;CAClC,YAAY,AAAQ,QAAgB;EAAhB;;;;;;CAMpB,KAAK,MAAiC;AACpC,SAAO,IAAI,kBAAkB,KAAK,QAAQ,KAAK;;;;;;CAOjD,KAAK,MAAmC;AACtC,SAAO,IAAI,qBAAqB,KAAK,SAAS,MAAM,cAClDA,wBAAW,MAAM;GAAE;GAAM;GAAW,CAAC,CACtC;;;;;;CAOH,OAAO,cAA2C;AAChD,SAAO,IAAI,qBAAqB,KAAK,SAAS,MAAM,cAClDC,4BAAa,cAAc;GAAE;GAAM;GAAW,CAAC,CAChD;;;;;;CAOH,IAAI,WAAwC;AAE1C,iCAAY,UAAU;AAEtB,SAAO,IAAI,qBAAqB,KAAK,SAAS,MAAM,cAClDC,sBAAU,WAAW;GAAE;GAAM;GAAW,CAAC,CAC1C;;;;;;CAOH,IAAI,MAAwD;AAC1D,SAAO,IAAI,qBAAqB,KAAK,SAAS,MAAM,cAClDC,sBAAU,MAAM;GAAE;GAAM;GAAW,CAAC,CACrC;;;;;;;CAQH,IAAI,UAAkE;AACpE,SAAO,IAAI,iBAAiB,KAAK,QAAQ,SAAS;;;;;;CAOpD,KAAK,UAAuC;AAC1C,SAAO,IAAI,qBAAqB,KAAK,SAAS,MAAM,cAClDC,wBAAW,UAAU;GAAE;GAAM;GAAW,CAAC,CAC1C;;;;;CAMH,IAAI,UAAqD;AACvD,UAAQ,aAAqB,KAAK,KAAK,SAAS;;;;;;AAOpD,SAAgB,6BACd,QACwB;AACxB,QAAO,IAAI,uBAAuB,OAAO"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { PinnerUploadBuilder, UploadOperation, UploadOptions } from "../types/upload.cjs";
|
|
2
|
+
import { Pinner } from "../pinner.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/upload/builder.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Pinner upload builder namespace.
|
|
8
|
+
* Provides fluent API for file, JSON, Base64, and URL uploads.
|
|
9
|
+
*/
|
|
10
|
+
declare class UploadBuilderNamespace {
|
|
11
|
+
private pinner;
|
|
12
|
+
constructor(pinner: Pinner);
|
|
13
|
+
/**
|
|
14
|
+
* Upload a file.
|
|
15
|
+
* Returns a builder for chaining name/keyvalues.
|
|
16
|
+
*/
|
|
17
|
+
file(file: File): PinnerUploadBuilder;
|
|
18
|
+
/**
|
|
19
|
+
* Upload JSON data (encoded as JSON file).
|
|
20
|
+
* Returns a builder for chaining name/keyvalues.
|
|
21
|
+
*/
|
|
22
|
+
json(data: object): PinnerUploadBuilder;
|
|
23
|
+
/**
|
|
24
|
+
* Upload Base64 encoded content (decoded and uploaded as file).
|
|
25
|
+
* Returns a builder for chaining name/keyvalues.
|
|
26
|
+
*/
|
|
27
|
+
base64(base64String: string): PinnerUploadBuilder;
|
|
28
|
+
/**
|
|
29
|
+
* Upload content from a URL (fetched and uploaded as file).
|
|
30
|
+
* Returns a builder for chaining name/keyvalues.
|
|
31
|
+
*/
|
|
32
|
+
url(urlString: string): PinnerUploadBuilder;
|
|
33
|
+
/**
|
|
34
|
+
* Upload CSV data (string, array of objects, or array of arrays).
|
|
35
|
+
* Returns a builder for chaining name/keyvalues.
|
|
36
|
+
*/
|
|
37
|
+
csv(data: string | object[] | any[][]): PinnerUploadBuilder;
|
|
38
|
+
/**
|
|
39
|
+
* Upload raw CAR data without preprocessing.
|
|
40
|
+
* Useful for passthrough of pre-generated CAR files.
|
|
41
|
+
* Returns a builder for chaining name/keyvalues.
|
|
42
|
+
*/
|
|
43
|
+
raw(carInput: File | ReadableStream<Uint8Array>): PinnerUploadBuilder;
|
|
44
|
+
/**
|
|
45
|
+
* Upload text content (encoded as text file).
|
|
46
|
+
* Returns a builder for chaining name/keyvalues.
|
|
47
|
+
*/
|
|
48
|
+
text(textData: string): PinnerUploadBuilder;
|
|
49
|
+
/**
|
|
50
|
+
* Alias for text() - upload text content.
|
|
51
|
+
*/
|
|
52
|
+
get content(): (textData: string) => PinnerUploadBuilder;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Combined interface for upload that works as both a method and a builder namespace.
|
|
56
|
+
*/
|
|
57
|
+
type UploadMethodAndBuilder = ((file: File, options?: UploadOptions) => Promise<UploadOperation>) & UploadBuilderNamespace;
|
|
58
|
+
//#endregion
|
|
59
|
+
export { UploadMethodAndBuilder };
|
|
60
|
+
//# sourceMappingURL=builder.d.cts.map
|